2015-01-25 17:07:51 +00:00
|
|
|
/*
|
|
|
|
bug.n -- tiling window management
|
|
|
|
Copyright (c) 2010-2015 Joshua Fuhs, joten
|
|
|
|
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
GNU General Public License for more details.
|
|
|
|
|
|
|
|
@license GNU General Public License version 3
|
|
|
|
../LICENSE.md or <http://www.gnu.org/licenses/>
|
|
|
|
|
|
|
|
@version 9.0.0
|
|
|
|
*/
|
|
|
|
|
2015-01-25 18:16:30 +00:00
|
|
|
Window_activate(wndId) {
|
|
|
|
If Window_isHung(wndId) {
|
|
|
|
Debug_logMessage("DEBUG[2] Window_activate: Potentially hung window " . wndId, 2)
|
|
|
|
Return, 1
|
|
|
|
} Else {
|
|
|
|
WinActivate, ahk_id %wndId%
|
|
|
|
WinGet, aWndId, ID, A
|
|
|
|
If (wndId != aWndId)
|
|
|
|
Return, 1
|
|
|
|
Else
|
|
|
|
Return, 0
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
Window_close(wndId) {
|
|
|
|
If Window_isHung(wndId) {
|
|
|
|
Debug_logMessage("DEBUG[2] Window_close: Potentially hung window " . wndId, 2)
|
|
|
|
Return, 1
|
|
|
|
} Else {
|
|
|
|
WinClose, ahk_id %wndId%
|
|
|
|
Return, 0
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-01-25 17:07:51 +00:00
|
|
|
;; Given a ghost window, try to find its body. This is only known to work on Windows 7
|
2015-01-25 18:16:30 +00:00
|
|
|
Window_findHung(ghostWndId) {
|
2015-01-25 17:07:51 +00:00
|
|
|
Global Config_ghostWndSubString
|
|
|
|
|
|
|
|
WinGetTitle, ghostWndTitle, ahk_id %ghostWndId%
|
|
|
|
StringReplace, ghostWndTitle, ghostWndTitle, %Config_ghostWndSubString%,
|
|
|
|
WinGetPos, ghostWndX, ghostWndY, ghostWndW, ghostWndH, ahk_id %ghostWndId%
|
|
|
|
|
|
|
|
SetTitleMatchMode, 2
|
|
|
|
WinGet, wndId, List, %ghostWndTitle%
|
|
|
|
Loop, % wndId {
|
|
|
|
If (wndId%A_Index% = ghostWndId)
|
|
|
|
Continue
|
|
|
|
WinGetPos, wndX, wndY, wndW, wndH, % "ahk_id" wndId%A_Index%
|
|
|
|
If (wndX = ghostWndX) And (wndY = ghostWndY) And (wndW = ghostWndW) And (wndH = ghostWndH)
|
|
|
|
Return, wndId%A_Index%
|
|
|
|
}
|
|
|
|
Return, 0
|
|
|
|
}
|
|
|
|
|
2015-01-25 18:16:30 +00:00
|
|
|
Window_hide(wndId) {
|
|
|
|
If Window_isHung(wndId) {
|
|
|
|
Debug_logMessage("DEBUG[2] Window_hide: Potentially hung window " . wndId, 2)
|
|
|
|
Return, 1
|
|
|
|
} Else {
|
|
|
|
WinHide, ahk_id %wndId%
|
|
|
|
Return, 0
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-02-14 12:32:08 +00:00
|
|
|
Window_isChild(wndId) {
|
|
|
|
WS_POPUP = 0x40000000
|
|
|
|
WinGet, wndStyle, Style, ahk_id %wndId%
|
|
|
|
|
2015-02-27 20:57:10 +00:00
|
|
|
Return, wndStyle & WS_POPUP
|
2015-02-14 12:32:08 +00:00
|
|
|
}
|
|
|
|
|
2015-02-12 19:35:41 +00:00
|
|
|
Window_isElevated(wndId) {
|
|
|
|
WinGetTitle, wndTitle, ahk_id %wndId%
|
|
|
|
WinSetTitle, ahk_id %wndId%, , % wndTitle " "
|
|
|
|
WinGetTitle, newWndTitle, ahk_id %wndId%
|
2015-03-01 20:12:33 +00:00
|
|
|
WinSetTitle, ahk_id %wndId%, , % wndTitle
|
2015-02-12 19:35:41 +00:00
|
|
|
Return, (newWndTitle = wndTitle)
|
|
|
|
}
|
|
|
|
|
2015-01-25 18:16:30 +00:00
|
|
|
Window_isGhost(wndId) {
|
2015-01-25 17:07:51 +00:00
|
|
|
Local wndClass, wndProc
|
|
|
|
|
|
|
|
WinGet, wndProc, ProcessName, ahk_id %wndId%
|
|
|
|
WinGetClass, wndClass, ahk_id %wndId%
|
|
|
|
If (wndProc = "dwm.exe") And (wndClass = "Ghost")
|
|
|
|
Return, 1
|
|
|
|
Else
|
|
|
|
Return, 0
|
|
|
|
}
|
|
|
|
|
|
|
|
;; 0 - Not hung
|
|
|
|
;; 1 - Hung
|
2015-01-25 18:16:30 +00:00
|
|
|
Window_isHung(wndId) {
|
2015-01-25 17:07:51 +00:00
|
|
|
Local detectSetting, result, WM_NULL
|
|
|
|
|
|
|
|
WM_NULL = 0
|
|
|
|
detectSetting := A_DetectHiddenWindows
|
|
|
|
DetectHiddenWindows, On
|
|
|
|
SendMessage, WM_NULL, , , , ahk_id %wndId%
|
|
|
|
result := ErrorLevel
|
|
|
|
DetectHiddenWindows, %detectSetting%
|
|
|
|
|
|
|
|
If result
|
|
|
|
Return, 1
|
|
|
|
Else
|
|
|
|
Return, 0
|
|
|
|
}
|
2015-02-28 21:56:18 +00:00
|
|
|
|
|
|
|
Window_isNotVisible(wndId) {
|
|
|
|
WS_VISIBLE = 0x10000000
|
|
|
|
WinGet, wndStyle, Style, ahk_id %wndId%
|
|
|
|
If (wndStyle & WS_VISIBLE) {
|
|
|
|
WinGetPos, wndX, wndY, wndW, wndH, ahk_id %wndId%
|
|
|
|
hasDimensions := wndW And wndH
|
|
|
|
isOnMonitor := Monitor_get(wndX + 5, wndY + 5) Or Monitor_get(wndX + wndW - 5, wndY + 5) Or Monitor_get(wndX + wndW, wndY + wndH - 5) Or Monitor_get(wndX + 5, wndY + wndH - 5)
|
|
|
|
Return, (Not hasDimensions Or Not isOnMonitor)
|
|
|
|
} Else
|
|
|
|
Return, True
|
|
|
|
}
|
2015-01-25 17:07:51 +00:00
|
|
|
|
2015-02-01 19:02:08 +00:00
|
|
|
Window_isPopup(wndId) {
|
|
|
|
WS_POPUP = 0x80000000
|
|
|
|
WinGet, wndStyle, Style, ahk_id %wndId%
|
|
|
|
|
|
|
|
Return, wndStyle & WS_POPUP
|
|
|
|
}
|
|
|
|
|
2015-01-25 17:07:51 +00:00
|
|
|
Window_isProg(wndId) {
|
|
|
|
WinGetClass, wndClass, ahk_id %wndId%
|
|
|
|
WinGetTitle, wndTitle, ahk_id %wndId%
|
|
|
|
If Not (wndClass = "Progman") And Not (wndClass = "WorkerW") And Not (wndClass = "DesktopBackgroundClass")
|
|
|
|
And Not (wndClass = "AutoHotkeyGui" And SubStr(wndTitle, 1, 10) = "bug.n_BAR_")
|
|
|
|
Return, wndId
|
|
|
|
Else
|
|
|
|
Return, 0
|
|
|
|
}
|
|
|
|
|
2015-01-25 18:16:30 +00:00
|
|
|
Window_maximize(wndId) {
|
|
|
|
If Window_isHung(wndId) {
|
|
|
|
Debug_logMessage("DEBUG[2] Window_maximize: Potentially hung window " . wndId, 2)
|
2015-01-25 17:07:51 +00:00
|
|
|
Return, 1
|
|
|
|
} Else {
|
|
|
|
WinMaximize, ahk_id %wndId%
|
|
|
|
Return, 0
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-01-25 18:16:30 +00:00
|
|
|
Window_move(wndId, x, y, width, height) {
|
|
|
|
If Window_isHung(wndId) {
|
|
|
|
Debug_logMessage("DEBUG[2] Window_move: Potentially hung window " . wndId, 2)
|
2015-01-25 17:07:51 +00:00
|
|
|
Return, 1
|
|
|
|
} Else {
|
|
|
|
WinGet, wndMin, MinMax, ahk_id %wndId%
|
|
|
|
If (wndMin = -1)
|
|
|
|
WinRestore, ahk_id %wndId%
|
|
|
|
}
|
|
|
|
|
|
|
|
WM_ENTERSIZEMOVE = 0x0231
|
|
|
|
WM_EXITSIZEMOVE = 0x0232
|
|
|
|
SendMessage, WM_ENTERSIZEMOVE, , , , ahk_id %wndId%
|
|
|
|
If ErrorLevel {
|
2015-01-25 18:16:30 +00:00
|
|
|
Debug_logMessage("DEBUG[2] Window_move: Potentially hung window " . wndId, 1)
|
2015-01-25 17:07:51 +00:00
|
|
|
Return, 1
|
|
|
|
} Else {
|
|
|
|
WinMove, ahk_id %wndId%, , %x%, %y%, %width%, %height%
|
|
|
|
SendMessage, WM_EXITSIZEMOVE, , , , ahk_id %wndId%
|
|
|
|
Return, 0
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-01-25 18:16:30 +00:00
|
|
|
Window_set(wndId, type, value) {
|
|
|
|
If Window_isHung(wndId) {
|
|
|
|
Debug_logMessage("DEBUG[2] Window_set: Potentially hung window " . wndId, 2)
|
2015-01-25 17:07:51 +00:00
|
|
|
Return, 1
|
|
|
|
} Else {
|
|
|
|
WinSet, %type%, %value%, ahk_id %wndId%
|
|
|
|
Return, 0
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-01-25 18:16:30 +00:00
|
|
|
Window_show(wndId) {
|
|
|
|
If Window_isHung(wndId) {
|
|
|
|
Debug_logMessage("DEBUG[2] Window_show: Potentially hung window " . wndId, 2)
|
2015-01-25 17:07:51 +00:00
|
|
|
Return, 1
|
|
|
|
} Else {
|
|
|
|
WinShow, ahk_id %wndId%
|
|
|
|
Return, 0
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-01-25 18:16:30 +00:00
|
|
|
Window_toggleDecor(wndId = 0) {
|
2015-01-25 17:07:51 +00:00
|
|
|
Global
|
|
|
|
|
|
|
|
If (wndId = 0)
|
|
|
|
WinGet, wndId, ID, A
|
|
|
|
|
2015-01-25 18:38:10 +00:00
|
|
|
Window_#%wndId%_isDecorated := Not Window_#%wndId%_isDecorated
|
|
|
|
If Window_#%wndId%_isDecorated
|
2015-01-25 18:16:30 +00:00
|
|
|
Window_set(wndId, "Style", "+0xC00000")
|
2015-01-25 17:07:51 +00:00
|
|
|
Else
|
2015-01-25 18:16:30 +00:00
|
|
|
Window_set(wndId, "Style", "-0xC00000")
|
2015-01-25 17:07:51 +00:00
|
|
|
}
|