StrokesPlus Forum
                       
StrokesPlus Forum
Home | Profile | Register | Active Topics
Members | Search | FAQ
Username:
Password:
Save Password
Forgot your Password?

 All Forums
 Lua Scripts
 General Action Scripts
 Show Desktop on Monitor containing mouse
 New Topic  Reply to Topic
 Printer Friendly
Author Previous Topic Topic Next Topic  

Noesis

25 Posts

Posted - 05/03/2013 :  11:41:13  Show Profile  Reply with Quote
Figured I'd share this script with anyone that might want to use it. Works on Windows 7 but I don't know if it will work for Win8 as I don't have it, and apparently some metro apps are returned with the acGetAllWindows() command, and I don't know if those apps can be minimized/restored.

I have this set as a hotkey but would work as a gesture too. Also in case it isn't clear it only minimizes windows on the monitor which has the mouse pointer on it and leaves windows on other monitors as they were.


-------------------------------------------------
----------In gesture/shorcut Lua Script----------
-------------------------------------------------

-- Show/Restore Desktop on Monitor containing the mouse

-- Mode is the mode of operation, either -1,0 or 'x' (change value to suit your preferred method)
-- (-1)	"Area mode" - Only windows with a majority of area showing on the current monitor will be
--		minimized. This is the default operation of the Win 7 systems standard hotkey "Win+M" only
--		this will work on monitors other than primary monitor and remember which windows were minimized.
-- (0+)	"Set mode" - all windows that have more than 8 pixels on the current monitor will be
--		minimized. (8 pixels to ignore maximized windows on adjacent monitors). Setting this to a
-- 		value will increase the number of pixels to ignore.
--
-- Notes: Mode only operates on windows which occupy space on more than one monitor, if part of the window
-- 	is sitting in "void" space (i.e. partially on one monitor and not on another adjoining monitor)
--	then it will be minimized as per normal operation.
--
--	Data stored for minimized windows will be lost when S+ config is started/edited and Ok/Apply is clicked in the
--	settings window or when Reload Config and Lua Engine is clicked from the tray menu.

local Mode = -1
local mon = {}
local win = {}
local minimize = true
local indx = 0

mon = fn_GetMonitorInfo()
for i=1, #minimized_windows do
	if minimized_windows[i][0] == mon[0].H then
		minimize = false
		indx = i
	end
end
if minimize then
	win = fn_GetWindows(mon, Mode)
	if #win ~= 0 then
		table.insert(minimized_windows, {})
		indx = #minimized_windows

		for i=1, #win do
			acMinimizeWindow(win[i].H, nil, nil)
			table.insert(minimized_windows[indx], win[i].H)
		end
		minimized_windows[indx][0] = mon[0].H
	end
else -- restore
	local tmp = acGetForegroundWindow()
	for i = #minimized_windows[indx], 1, -1 do
		if acGetWindowLeft(minimized_windows[indx][i]) < 31000 and acGetWindowTop(minimized_windows[indx][i]) < 31000 then
			acRestoreWindow(minimized_windows[indx][i], nil, nil)
		end
	end
	table.remove(minimized_windows, indx)
	acActivateWindow(tmp, nil, nil, 0)
end


-------------------------------------------------
---------------- Global Lua Tab -----------------
-------------------------------------------------

minimized_windows = {} -- Global table used to store minimized window handles and determine if command should minimize or restore

function fn_GetMonitorInfo(monHndl, i, getJoining)
	if monHndl == nil then
		monHndl = acGetMonitorFromPoint(acGetMouseLocationX(),acGetMouseLocationY())
	end
	if i == nil then i = 0 end
	if getJoining == nil then getJoining = true end
	if tMon == nil then	tMon = {} end

	local monL = acGetMonitorLeft(monHndl, 0)
	local monT = acGetMonitorTop(monHndl, 0)
	local monR = acGetMonitorRight(monHndl, 0)
	local monB = acGetMonitorBottom(monHndl, 0)

	tMon[i] = {H=monHndl, T=monT, B=monB, L=monL, R=monR}
	
	if getJoining then -- Get Adjoining Monitors
		local mon={} -- Top, Right, Bottom, Left == (1,2,3,4)
		mon[1] = acGetMonitorFromPoint((tMon[i].R - tMon[i].L)/2 + tMon[i].L,tMon[i].T - 10) --Above
		mon[2] = acGetMonitorFromPoint(tMon[i].R + 10,(tMon[i].B - tMon[i].T)/2 + tMon[i].T) --Right
		mon[3] = acGetMonitorFromPoint((tMon[i].R - tMon[i].L)/2 + tMon[i].L,tMon[i].B + 10) --Below
		mon[4] = acGetMonitorFromPoint(tMon[i].L - 10,(tMon[i].B - tMon[i].T)/2 + tMon[i].T) --Left
		mon[5] = acGetMonitorFromPoint(tMon[i].R + 10, tMon[i].T - 10) -- Above Right Diagnal
		mon[6] = acGetMonitorFromPoint(tMon[i].R + 10, tMon[i].B + 10) -- Below Right Diagnal
		mon[7] = acGetMonitorFromPoint(tMon[i].L - 10, tMon[i].B + 10) -- Below Left Diagnal
		mon[8 ] = acGetMonitorFromPoint(tMon[i].L - 10, tMon[i].T - 10) -- Above Left Diagnal

		for index, value in ipairs(mon) do
			if monHndl ~= value then -- Only store handles not same as current handle
				local flag = true
				for ind=0, #tMon do -- Flag handles already in table so not stored again
					if value == tMon[ind].H then flag = false end
				end
				if flag then
					tMon = fn_GetMonitorInfo(value, i+1, false)
				end
			end
		end
	end
	return tMon
end

function fn_GetWindows(mon, limit)
	local tWin = {}
	local count = 1
	acGetAllWindows(1)
	for i = 0, #sp_all_windows do
		local winL = acGetWindowLeft(sp_all_windows[i], nil, nil)
		local winT = acGetWindowTop(sp_all_windows[i], nil, nil)
		local winR = acGetWindowRight(sp_all_windows[i], nil, nil)
		local winB = acGetWindowBottom(sp_all_windows[i], nil, nil)

		-- check window has any relevance on the screen
		if mon[0].T < winB and mon[0].B > winT and mon[0].L < winR and mon[0].R > winL then
			tWin[count] = {H=sp_all_windows[i], T=winT, B=winB, L=winL, R=winR}
			count = count + 1
		end
	end
	tWin = fn_WindowAreaLimitCheck(mon, tWin, limit)
	return tWin
end

function fn_WindowAreaLimitCheck(mon, win, limit)
	local tWin = {}
	local Index = 1

	for wi=1, #win do
		local wmArea = {}
		local winArea = 0
		local count = 1
		local winInclude = true
		local maxwmArea = 0

		winArea = fn_wmAreaCalc(mon[0], win[wi])
		for mi=1, #mon do
			--check window has any relevance on this adjoining screen
			if mon[mi].T < win[wi].B and mon[mi].B > win[wi].T and mon[mi].L < win[wi].R and mon[mi].R > win[wi].L then
				wmArea[count] = fn_wmAreaCalc(mon[mi], win[wi])
				count = count + 1
			end
		end
		for i=1, #wmArea do
			if maxwmArea < wmArea[i] then
				maxwmArea = wmArea[i]
			end
			if wmArea[i] > winArea and limit == -1 then
				winInclude = false
			end
		end
		if limit >= 0 then
			if maxwmArea > 0 then
				if fn_wmAreaCalc(mon[0], win[wi], "ht") - limit < 9 and	fn_wmAreaCalc(mon[0], win[wi], "wd") - limit < 9 then
					winInclude = false
				end
			end
		end
		if winInclude then
			tWin[Index] = win[wi]
			Index= Index + 1
		end
	end
	return tWin
end

function fn_wmAreaCalc(mon, win, check)
	if check == nil then check = "" end
	local height = 0
	local width = 0
	local area = 0

	if win.T <= mon.T and win.B >= mon.B then
		height = math.abs(mon.B - mon.T)
	elseif win.T <= mon.T then
		height = math.abs(win.B - mon.T)
	elseif win.B >= mon.B then
		height = math.abs(mon.B - win.T)
	else
		height = math.abs(win.B - win.T)
	end

	if win.L <= mon.L and win.R >= mon.R then
		width = math.abs(mon.R - mon.L)
	elseif win.R >= mon.R then
		width = math.abs(mon.R - win.L)
	elseif win.L <= mon.L then
		width = math.abs(win.R - mon.L)
	else
		width = math.abs(win.R - win.L)
	end

	if height > 8 and width > 8 then
		if check == "ht" then
			area = height
		elseif check == "wd" then
			area = width
		else
			area = height * width
		end
	else
		area = 0
	end
	return area
end


Rob

USA
2516 Posts

Posted - 05/03/2013 :  19:07:24  Show Profile  Visit Rob's Homepage  Reply with Quote
Nice work!
Go to Top of Page
  Previous Topic Topic Next Topic  
 New Topic  Reply to Topic
 Printer Friendly
Jump To:
StrokesPlus Forum © 2011-2018 Rob Yapchanyk Go To Top Of Page
Snitz Forums 2000