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