Can declare a hotkey in Config.ini that exits the app
This commit is contained in:
commit
9449b1a93f
14 changed files with 1369 additions and 314 deletions
BIN
bugn.exe
BIN
bugn.exe
Binary file not shown.
77
src/Bar.ahk
77
src/Bar.ahk
|
@ -61,7 +61,7 @@ Bar_init(m) {
|
|||
}
|
||||
; layout
|
||||
i := Config_viewCount + 1
|
||||
text := " ??? "
|
||||
text := " 1x9|=- "
|
||||
w := Bar_getTextWidth(text)
|
||||
Gui, Add, Text, x%x1% y%y1% w%w% h%h1% BackgroundTrans vBar_#%m%_#%i%_layout gBar_GuiClick,
|
||||
Gui, Add, Progress, x%x1% y%y1% w%w% h%h1% Background%Config_normBgColor2%
|
||||
|
@ -214,8 +214,10 @@ Bar_initCmdGui() {
|
|||
TV_Add("rotate master axis", itemId20)
|
||||
TV_Add("rotate stack axis", itemId20)
|
||||
TV_Add("mirror tile layout", itemId20)
|
||||
TV_Add("increase master split", itemId20)
|
||||
TV_Add("decrease master split", itemId20)
|
||||
TV_Add("increase master X", itemId20)
|
||||
TV_Add("decrease master X", itemId20)
|
||||
TV_Add("increase master Y", itemId20)
|
||||
TV_Add("decrease master Y", itemId20)
|
||||
TV_Add("increase master factor", itemId20)
|
||||
TV_Add("decrease master factor", itemId20)
|
||||
itemId30 := TV_Add("View")
|
||||
|
@ -229,6 +231,12 @@ Bar_initCmdGui() {
|
|||
TV_Add("toggle task bar", itemId40)
|
||||
TV_Add("activate next", itemId40)
|
||||
TV_Add("activate prev", itemId40)
|
||||
;itemId50 := TV_add("Log")
|
||||
; TV_Add("increment debug level", itemId50)
|
||||
; TV_Add("decrement debug level", itemId50)
|
||||
; TV_Add("log help info", itemId50)
|
||||
; TV_Add("log view window info", itemId50)
|
||||
; TV_Add("log managed window info", itemId50)
|
||||
TV_Add("Reload")
|
||||
TV_Add("Quit")
|
||||
GuiControl, +Redraw, Bar_#0_#0
|
||||
|
@ -320,10 +328,14 @@ Bar_evaluateCommand() {
|
|||
View_rotateLayoutAxis(3, +1)
|
||||
Else If (Bar_command_#1 = "mirror tile layout")
|
||||
View_rotateLayoutAxis(1, +2)
|
||||
Else If (Bar_command_#1 = "increase master split")
|
||||
View_setMSplit(+1)
|
||||
Else If (Bar_command_#1 = "decrease master split")
|
||||
View_setMSplit(-1)
|
||||
Else If (Bar_command_#1 = "increase master X")
|
||||
View_setMX(+1)
|
||||
Else If (Bar_command_#1 = "decrease master X")
|
||||
View_setMX(-1)
|
||||
Else If (Bar_command_#1 = "increase master Y")
|
||||
View_setMY(+1)
|
||||
Else If (Bar_command_#1 = "decrease master Y")
|
||||
View_setMY(-1)
|
||||
Else If (Bar_command_#1 = "increase master factor")
|
||||
View_setMFactor(+0.05)
|
||||
Else If (Bar_command_#1 = "decrease master factor")
|
||||
|
@ -349,6 +361,17 @@ Bar_evaluateCommand() {
|
|||
Manager_activateMonitor(+1)
|
||||
Else If (Bar_command_#1 = "activate prev")
|
||||
Manager_activateMonitor(-1)
|
||||
} Else If (Bar_command_#2 = "Log") {
|
||||
If (Bar_command_#1 = "increment debug level")
|
||||
Log_incDebugLevel()
|
||||
If (Bar_command_#1 = "decrement debug level")
|
||||
Log_decDebugLevel()
|
||||
If (Bar_command_#1 = "log help info")
|
||||
Manager_logHelp()
|
||||
If (Bar_command_#1 = "log view window info")
|
||||
Manager_logViewWindowList()
|
||||
If (Bar_command_#1 = "log managed window info")
|
||||
Manager_logManagedWindowList()
|
||||
} Else If (Bar_command_#1 = "Reload")
|
||||
Main_reload()
|
||||
Else If (Bar_command_#1 = "Quit")
|
||||
|
@ -697,28 +720,34 @@ Bar_updateTitle(debugMsg = "") {
|
|||
Bar_aWndId := aWndId
|
||||
}
|
||||
|
||||
; Update the view portion of the status bar.
|
||||
Bar_updateView(m, v) {
|
||||
Local managedWndId0, wndId0, wndIds
|
||||
Local IdsLen, ViewIdsLen
|
||||
|
||||
StringTrimRight, wndIds, Manager_managedWndIds, 1
|
||||
StringSplit, managedWndId, wndIds, `;
|
||||
GuiN := (m - 1) + 1
|
||||
Gui, %GuiN%: Default
|
||||
|
||||
IdsLen := StrLen(Manager_managedWndIds)
|
||||
|
||||
If (v = Monitor_#%m%_aView_#1) {
|
||||
; Set foreground/background colors if the view is the current view.
|
||||
GuiControl, +Background%Config_selBgColor1% +c%Config_selFgColor2%, Bar_#%m%_#%v%_tagged
|
||||
GuiControl, +c%Config_selFgColor1%, Bar_#%m%_#%v%
|
||||
} Else If StrLen(View_#%m%_#%v%_wndIds) > 0 {
|
||||
; Set foreground/background colors if the view contains windows.
|
||||
GuiControl, +Background%Config_normBgColor5% +c%Config_normFgColor8%, Bar_#%m%_#%v%_tagged
|
||||
GuiControl, +c%Config_normFgColor7%, Bar_#%m%_#%v%
|
||||
} Else {
|
||||
; Set foreground/background colors if the view is empty.
|
||||
GuiControl, +Background%Config_normBgColor1% +c%Config_normFgColor8%, Bar_#%m%_#%v%_tagged
|
||||
GuiControl, +c%Config_normFgColor1%, Bar_#%m%_#%v%
|
||||
}
|
||||
|
||||
Loop, %Config_viewCount% {
|
||||
StringTrimRight, wndIds, View_#%m%_#%A_Index%_wndIds, 1
|
||||
StringSplit, wndId, wndIds, `;
|
||||
If (A_Index = v)
|
||||
If (v = Monitor_#%m%_aView_#1) {
|
||||
GuiControl, +Background%Config_selBgColor1% +c%Config_selFgColor2%, Bar_#%m%_#%v%_tagged
|
||||
GuiControl, +c%Config_selFgColor1%, Bar_#%m%_#%v%
|
||||
} Else If wndId0 {
|
||||
GuiControl, +Background%Config_normBgColor5% +c%Config_normFgColor8%, Bar_#%m%_#%v%_tagged
|
||||
GuiControl, +c%Config_normFgColor7%, Bar_#%m%_#%v%
|
||||
} Else {
|
||||
GuiControl, +Background%Config_normBgColor1% +c%Config_normFgColor8%, Bar_#%m%_#%v%_tagged
|
||||
GuiControl, +c%Config_normFgColor1%, Bar_#%m%_#%v%
|
||||
}
|
||||
GuiControl, , Bar_#%m%_#%A_Index%_tagged, % wndId0 / managedWndId0 * 100
|
||||
ViewIdsLen := StrLen( View_#%m%_#%A_Index%_wndIds )
|
||||
; Update the percentage fill for the view.
|
||||
GuiControl, , Bar_#%m%_#%A_Index%_tagged, % ViewIdsLen / IdsLen * 100
|
||||
; Refresh the number on the bar.
|
||||
GuiControl, , Bar_#%m%_#%A_Index%, %A_Index%
|
||||
}
|
||||
}
|
||||
|
|
|
@ -23,11 +23,11 @@ Config_init() {
|
|||
|
||||
; status bar
|
||||
Config_showBar := True ; If false, the bar is hidden. It can be made visible or hidden by hotkey (see below).
|
||||
Config_horizontalBarPos := "left" ; The horizontal position of the bar: "center", "left" or "right" side of the monitor or an offset in pixel (px) from the left (>= 0) or right (< 0).
|
||||
Config_verticalBarPos := "top" ; The vertical position of the bar: "top" or "bottom" of the monitor, "tray" = sub-window of the task bar.
|
||||
Config_barWidth := "100%" ; The width of the bar in pixel (px) or with a per cent sign (%) as a percentage.
|
||||
Config_singleRowBar := True ; If false, the bar will have to rows, one for the window title and one for all other GUI controls.
|
||||
Config_spaciousBar := False ; If true, the height of the bar will be set to a value equal to the height of an edit control, else it will be set to the text height.
|
||||
Config_horizontalBarPos := "left" ; The horizontal position of the bar: "center", "left" or "right" side of the monitor or an offset in pixel (px) from the left (>= 0) or right (< 0).
|
||||
Config_verticalBarPos := "top" ; The vertical position of the bar: "top" or "bottom" of the monitor, "tray" = sub-window of the task bar.
|
||||
Config_barWidth := "100%" ; The width of the bar in pixel (px) or with a per cent sign (%) as a percentage.
|
||||
Config_singleRowBar := True ; If false, the bar will have to rows, one for the window title and one for all other GUI controls.
|
||||
Config_spaciousBar := False ; If true, the height of the bar will be set to a value equal to the height of an edit control, else it will be set to the text height.
|
||||
Config_fontName := "Lucida Console" ; A monospace font is preferable for bug.n to calculate the correct width of the bar and its elements (sub-windows).
|
||||
Config_fontSize :=
|
||||
Config_normBgColor :=
|
||||
|
@ -37,7 +37,7 @@ Config_init() {
|
|||
Config_readinBat := False ; If true, the system battery status is read in and displayed in the status bar. This only makes sense, if you have a system battery (notebook).
|
||||
Config_readinCpu := False ; If true, the current CPU load is read in and displayed in the status bar.
|
||||
Config_readinDate := True ; If true, the current date is read in (format: "WW, DD. MMM. YYYY") and displayed in the status bar.
|
||||
Config_readinDiskLoad := False ; If true, the current disk load (read and write) is read in and displayed in the status bar.
|
||||
Config_readinDiskLoad := False ; If true, the current disk load (read and write) is read in and displayed in the status bar.
|
||||
Config_readinMemoryUsage := False ; If true, the system memory usage is read in and displayed in the status bar.
|
||||
Config_readinNetworkLoad := False ; If true, the current network load (up and down) is read in and displayed in the status bar.
|
||||
Config_readinTime := True ; If true, the current time is read in (format: "HH:MM") and displayed in the status bar.
|
||||
|
@ -60,13 +60,13 @@ Config_init() {
|
|||
Config_layoutAxis_#1 := 1 ; The layout axis: 1 = x, 2 = y; negative values mirror the layout, setting the master area to the right / bottom instead of left / top.
|
||||
Config_layoutAxis_#2 := 2 ; The master axis: 1 = x (from left to right), 2 = y (from top to bottom), 3 = z (monocle).
|
||||
Config_layoutAxis_#3 := 2 ; The stack axis: 1 = x (from left to right), 2 = y (from top to bottom), 3 = z (monocle).
|
||||
Config_layoutGapWidth := 0 ; The default gap width in px (only even numbers) of the "tile" layout, i. e. the space between windows and around the layout.
|
||||
Config_layoutGapWidth := 0 ; The default gap width in px (only even numbers) of the "tile" layout, i. e. the space between windows and around the layout.
|
||||
Config_layoutMFactor := 0.6 ; The factor for the size of the master area, which is multiplied by the monitor size.
|
||||
Config_mouseFollowsFocus := True ; If true, the mouse pointer is set over the focused window, if a window is activated by bug.n.
|
||||
Config_onActiveHiddenWnds := "view" ; The action, which will be taken, if a window e. g. should be activated, but is not visible; "view": show the view accordng to the first tag of the window in question, "tag": add the window in question to the current visible view, "hide": hide the window again ignoring the activation.
|
||||
Config_newWndPosition := "top" ; The position of a new window in a view; "top": at the beginning of the window list and the master area (default), "masterBottom": at the end of the master area, "stackTop": on top of the stack area, "bottom": at the end of the window list and the stack area.
|
||||
Config_newWndPosition := "top" ; The position of a new window in a view; "top": at the beginning of the window list and the master area (default), "masterBottom": at the end of the master area, "stackTop": on top of the stack area, "bottom": at the end of the window list and the stack area.
|
||||
Config_shellMsgDelay := 350 ; The time bug.n waits after a shell message (a window is opened, closed or the focus has been changed); if there are any problems recognizing, when windows are opened or closed, try to increase this number.
|
||||
Config_syncMonitorViews := 0 ; The number of monitors (2 or more), for which views should be activated, when using the accordant hotkey. If set to 1, the views are actiated for all monitors. If set to 0, views are activated independently (only on the active monitor).
|
||||
Config_syncMonitorViews := 0 ; The number of monitors (2 or more), for which views should be activated, when using the accordant hotkey. If set to 1, the views are activated for all monitors. If set to 0, views are activated independently (only on the active monitor).
|
||||
Config_viewFollowsTagged := False ; If true and a window is tagged with a single tag, the view is correspondingly set to the tag.
|
||||
|
||||
; Config_rule_#i := "<class (regular expression string)>;<title (regular expression string)>;<window style (hexadecimal number or blank)>;
|
||||
|
@ -363,8 +363,10 @@ Config_saveSession() {
|
|||
text .= "View_#" m "_#" A_Index "_layoutGapWidth=" View_#%m%_#%A_Index%_layoutGapWidth "`n"
|
||||
If Not (View_#%m%_#%A_Index%_layoutMFact = Config_layoutMFactor)
|
||||
text .= "View_#" m "_#" A_Index "_layoutMFact=" View_#%m%_#%A_Index%_layoutMFact "`n"
|
||||
If Not (View_#%m%_#%A_Index%_layoutMSplit = 1)
|
||||
text .= "View_#" m "_#" A_Index "_layoutMSplit=" View_#%m%_#%A_Index%_layoutMSplit "`n"
|
||||
If Not (View_#%m%_#%A_Index%_layoutMX = 1)
|
||||
text .= "View_#" m "_#" A_Index "_layoutMX=" View_#%m%_#%A_Index%_layoutMX "`n"
|
||||
If Not (View_#%m%_#%A_Index%_layoutMY = 1)
|
||||
text .= "View_#" m "_#" A_Index "_layoutMY=" View_#%m%_#%A_Index%_layoutMY "`n"
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -390,6 +392,11 @@ Config_saveSession() {
|
|||
#+x::Manager_maximizeWindow() ; Move and resize the active window to the size of the work area (only floating windows).
|
||||
#i::Manager_getWindowInfo() ; Get information for the active window (id, title, class, process name, style, geometry, tags and floating state).
|
||||
#+i::Manager_getWindowList() ; Get a window list for the active view (id, title and class).
|
||||
#^i::Manager_logViewWindowList() ; Dump window information for the active view.
|
||||
#+^i::Manager_logManagedWindowList() ; Dump window information for every managed window.
|
||||
#^h::Manager_logHelp() ; Dump to the log an explanation of some of the other more cryptic log messages.
|
||||
#^[::Log_decDebugLevel() ; Decrement the log debug level.
|
||||
#^]::Log_incDebugLevel() ; Increment the log debug level.
|
||||
|
||||
#Tab::View_setLayout(-1) ; Set the previously set layout. You may also use View_setLayout(">") for setting the next layout in the layout array.
|
||||
#f::View_setLayout(3) ; Set the 3rd defined layout (i. e. floating layout in the default configuration).
|
||||
|
@ -401,10 +408,13 @@ Config_saveSession() {
|
|||
#^Enter::View_rotateLayoutAxis(1, +2) ; Mirror the layout axis (i. e. -1 -> 1 / 1 -> -1 = master on the left / right side, -2 -> 2 / 2 -> -2 = master at top / bottom, only for the "tile" layout).
|
||||
#^Tab::View_rotateLayoutAxis(2, +1) ; Rotate the master axis (i. e. 3 -> 1 = x-axis = horizontal stack, 1 -> 2 = y-axis = vertical stack, 2 -> 3 = z-axis = monocle, only for the "tile" layout).
|
||||
#^+Tab::View_rotateLayoutAxis(3, +1) ; Rotate the stack axis (i. e. 3 -> 1 = x-axis = horizontal stack, 1 -> 2 = y-axis = vertical stack, 2 -> 3 = z-axis = monocle, only for the "tile" layout).
|
||||
#^Left::View_setMSplit(+1) ; Move the master splitter, i. e. decrease the number of windows in the master area (only for the "tile" layout).
|
||||
#^Right::View_setMSplit(-1) ; Move the master splitter, i. e. increase the number of windows in the master area (only for the "tile" layout).
|
||||
#<::View_setGapWidth(-2) ; Decrease the gap width by 2 px (only for the "tile" layout and even numbers; see the variable "Config_layoutGapWidth").
|
||||
#+<::View_setGapWidth(+2) ; Increase the gap width by 2 px (only for the "tile" layout and even numbers; see the variable "Config_layoutGapWidth").
|
||||
#^Up::View_setMY(+1) ; Increase the master Y dimension [1,9] (only for the "tile" layout).
|
||||
#^Down::View_setMY(-1) ; Decrease the master Y dimension [1,9] (only for the "tile" layout).
|
||||
#^Right::View_setMX(+1) ; Increase the master X dimension [1,9] (only for the "tile" layout).
|
||||
#^Left::View_setMX(-1) ; Decrease the master X dimension [1,9] (only for the "tile" layout).
|
||||
#+Left::View_setGapWidth(-2) ; Decrease the gap width by 2 px (only for the "tile" layout and even numbers; see the variable "Config_layoutGapWidth").
|
||||
#+Right::View_setGapWidth(+2) ; Increase the gap width by 2 px (only for the "tile" layout and even numbers; see the variable "Config_layoutGapWidth").
|
||||
|
||||
|
||||
#BackSpace::Monitor_activateView(-1) ; Activate the previously activated view. You may also use Monitor_activateView("<") or Monitor_activateView(">") for activating the previous or next adjacent view.
|
||||
#+0::Monitor_setWindowTag(0) ; Tag the active window with all tags (1 ... Config_viewCount). You may also use Monitor_setWindowTag("<") or Monitor_setWindowTag(">") for setting the tag of the previous or next adjacent to the current view.
|
||||
|
|
111
src/List.ahk
Normal file
111
src/List.ahk
Normal file
|
@ -0,0 +1,111 @@
|
|||
/**
|
||||
* AHK List implementation
|
||||
* Copyright (c) 2012 Joshua Fuhs
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* This is an admittedly poor list implementation, but I was new to AHK,
|
||||
* and I had seen several examples of this already used.
|
||||
* The lists being operated on should not be larger than a few hundred,
|
||||
* and preferably no larger than one hundred.
|
||||
*/
|
||||
|
||||
|
||||
List_new() {
|
||||
Global
|
||||
Return ""
|
||||
}
|
||||
|
||||
List_prepend( ByRef l, e ) {
|
||||
l := e . "`;" . l
|
||||
Return
|
||||
}
|
||||
|
||||
List_append(ByRef l, e) {
|
||||
l := l . e . "`;"
|
||||
Return
|
||||
}
|
||||
|
||||
; Insert at position immediately preceding index p
|
||||
List_insert(ByRef l, e, p) {
|
||||
Local arr, search, replace
|
||||
If ( p = 0)
|
||||
return List_prepend(l, e)
|
||||
StringSplit arr, l, `;
|
||||
if ( p >= arr0 - 1 )
|
||||
return List_append(l, e)
|
||||
p += 1
|
||||
search := arr%p% . ";"
|
||||
replace := e . ";" . search
|
||||
StringReplace, l, l, %search%, %replace%
|
||||
}
|
||||
|
||||
List_remove(ByRef l, e) {
|
||||
Local search
|
||||
search := "" . e . ";"
|
||||
StringReplace, l, l, %search%,
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
List_removeAt(ByRef l, p) {
|
||||
Local arr, search
|
||||
StringSplit arr, l, `;
|
||||
if( p >= arr0 - 1)
|
||||
Return
|
||||
p += 1
|
||||
search := arr%p% . ";"
|
||||
StringReplace, l, l, %search%,
|
||||
}
|
||||
|
||||
List_find(ByRef l, e) {
|
||||
Local arr, arr0
|
||||
StringSplit arr, l, `;
|
||||
Loop, % (arr0 - 1) {
|
||||
If arr%A_Index% = %e%
|
||||
Return (A_Index - 1)
|
||||
}
|
||||
Return -1
|
||||
}
|
||||
|
||||
List_dump(l) {
|
||||
Local result
|
||||
StringReplace, result, l, `;, %A_Space%, All
|
||||
Return result
|
||||
}
|
||||
|
||||
List_get(l, p) {
|
||||
Local arr
|
||||
StringSplit arr, l, `;
|
||||
If( p >= arr0 )
|
||||
Return ""
|
||||
p += 1
|
||||
Return arr%p%
|
||||
}
|
||||
|
||||
List_size(l) {
|
||||
Local arr, arr0
|
||||
StringSplit arr, l, `;
|
||||
Return (arr0 - 1)
|
||||
}
|
||||
|
||||
List_toArray(l, arrName) {
|
||||
Local trimmedList
|
||||
StringTrimRight, trimmedList, l, 1
|
||||
StringSplit %arrName%, trimmedList, `;
|
||||
Return (%arrName%0)
|
||||
}
|
84
src/List.test.ahk
Normal file
84
src/List.test.ahk
Normal file
|
@ -0,0 +1,84 @@
|
|||
|
||||
Test_check(Condition, msg) {
|
||||
Global
|
||||
If Condition
|
||||
Return
|
||||
Log_bare(msg)
|
||||
Exit, 1
|
||||
}
|
||||
|
||||
|
||||
Log_init("List.test.txt", True)
|
||||
|
||||
testlist := List_new()
|
||||
Log_bare("new list: " . List_dump(testlist))
|
||||
Test_check(List_dump(testlist) = "", "Test 1 failure")
|
||||
If Not (List_dump(testlist) = "" )
|
||||
Log_bare("Test 1 failure")
|
||||
List_append(testlist, "abc")
|
||||
Log_bare("appended 'abc': " . List_dump(testlist))
|
||||
If Not (List_dump(testlist) = "abc " )
|
||||
Log_bare("Test 2 failure")
|
||||
List_append(testlist, "def")
|
||||
Log_bare("appended 'def': " . List_dump(testlist))
|
||||
If Not (List_dump(testlist) = "abc def " )
|
||||
Log_bare("Test 3 failure")
|
||||
List_append(testlist, "ghi")
|
||||
List_remove(testlist, "abc")
|
||||
Log_bare("removed 'abc': " . List_dump(testlist))
|
||||
If Not (List_dump(testlist) = "def ghi " )
|
||||
Log_bare("Test 4 failure")
|
||||
List_append(testlist, "jkl")
|
||||
List_remove(testlist, "ghi")
|
||||
Log_bare("add 'jkl', remove 'ghi': " . List_dump(testlist))
|
||||
If Not (List_dump(testlist) = "def jkl " )
|
||||
Log_bare("Test 5 failure")
|
||||
List_append(testlist, "mno")
|
||||
List_remove(testlist, "mno")
|
||||
Log_bare("add and remove 'mno': " . List_dump(testlist))
|
||||
If Not (List_dump(testlist) = "def jkl " )
|
||||
Log_bare("Test 6 failure")
|
||||
List_prepend(testlist, "12345")
|
||||
Log_bare("prepend '12345': " . List_dump(testlist))
|
||||
If Not (List_dump(testlist) = "12345 def jkl ")
|
||||
Log_bare("Test 7 failure")
|
||||
List_insert(testlist, "xyz", 0)
|
||||
List_insert(testlist, "Happy", 1)
|
||||
List_insert(testlist, "Blah", 5)
|
||||
List_insert(testlist, "10", 10)
|
||||
Log_bare("Attempt multiple inserts by index: " . List_dump(testlist))
|
||||
If Not (List_dump(testlist) = "xyz Happy 12345 def jkl Blah 10 ")
|
||||
Log_bare("Test 8 failure")
|
||||
List_removeAt(testlist, 0)
|
||||
List_removeAt(testlist, 1)
|
||||
List_removeAt(testlist, 2)
|
||||
List_removeAt(testlist, 3)
|
||||
List_removeAt(testlist, 10)
|
||||
Log_bare("Attempt multiple removals by index: " . List_dump(testlist))
|
||||
If Not (List_dump(testlist) = "Happy def Blah ")
|
||||
Log_bare("Test 9 failure")
|
||||
If Not (List_find(testlist, "Happy") = 0)
|
||||
Log_bare("Test 10 failure")
|
||||
If Not (List_find(testlist, "def") = 1)
|
||||
Log_bare("Test 11 failure")
|
||||
If Not (List_find(testlist, "Blah") = 2)
|
||||
Log_bare("Test 12 failure")
|
||||
If Not (List_find(testlist, "nonexistent") = -1)
|
||||
Log_bare("Test 13 failure")
|
||||
If Not (List_size(testlist) = 3)
|
||||
Log_bare("Test 14 failure")
|
||||
If Not (List_get(testlist, 0) = "Happy")
|
||||
Log_bare("Test 15 failure")
|
||||
If Not (List_get(testlist, 1) = "def")
|
||||
Log_bare("Test 16 failure")
|
||||
If Not (List_get(testlist, 2) = "Blah")
|
||||
Log_bare("Test 17 failure")
|
||||
If Not (List_get(testlist, 3) = "")
|
||||
Log_bare("Test 18 failure")
|
||||
|
||||
|
||||
|
||||
Return
|
||||
|
||||
#Include Log.ahk
|
||||
#Include List.ahk
|
82
src/Log.ahk
Executable file
82
src/Log.ahk
Executable file
|
@ -0,0 +1,82 @@
|
|||
/**
|
||||
* AHK Debug log implementation
|
||||
* Copyright (c) 2012 Joshua Fuhs
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* @version 8.3.0
|
||||
*/
|
||||
|
||||
Log_debug_level := 0
|
||||
|
||||
Log_init(name, truncate) {
|
||||
Global
|
||||
If truncate
|
||||
IfExist, %name%
|
||||
FileDelete, %name%
|
||||
Log_name := name
|
||||
}
|
||||
|
||||
Log_msg( message ) {
|
||||
Local CurrentTime
|
||||
If Not Log_name
|
||||
Return
|
||||
FormatTime, CurrentTime, , yyyyMMddHHmmss
|
||||
FileAppend, %CurrentTime% %message%`r`n, %Log_name%
|
||||
}
|
||||
|
||||
Log_bare( message ) {
|
||||
Local padded_message
|
||||
If Not Log_name
|
||||
Return
|
||||
padded_message := " " . message . "`r`n"
|
||||
FileAppend, %padded_message% , %Log_name%
|
||||
}
|
||||
|
||||
Log_incDebugLevel() {
|
||||
Global
|
||||
If Not Log_name
|
||||
Return
|
||||
If ( Log_debug_level < 9 )
|
||||
{
|
||||
Log_debug_level += 1
|
||||
Log_msg("Debug logging level incremented to " . Log_debug_level )
|
||||
}
|
||||
}
|
||||
|
||||
Log_decDebugLevel() {
|
||||
Global
|
||||
If Not Log_name
|
||||
Return
|
||||
If ( Log_debug_level > 0 ) {
|
||||
Log_debug_level -= 1
|
||||
If ( Log_debug_level = 0 )
|
||||
Log_msg("Debug logging is disabled")
|
||||
Else
|
||||
Log_msg("Debug logging level decremented to " . Log_debug_level)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Log_dbg_msg( level, message ) {
|
||||
Global
|
||||
If (level > 0 And Log_debug_level >= level)
|
||||
Log_msg( "DBG " . level . ": " . message )
|
||||
}
|
||||
|
||||
Log_dbg_bare( level, message ) {
|
||||
Global
|
||||
If (level > 0 And Log_debug_level >= level)
|
||||
Log_bare( "DBG " . level . ": " . message )
|
||||
}
|
20
src/Main.ahk
20
src/Main.ahk
|
@ -32,6 +32,23 @@ SetWinDelay, 10
|
|||
#WinActivateForce
|
||||
|
||||
; pseudo main function
|
||||
|
||||
|
||||
EnvGet, appDir, APPDATA
|
||||
bugnDir := appDir . "\bug.n"
|
||||
IfNotExist, %bugnDir%
|
||||
FileCreateDir, %bugnDir%
|
||||
FileGetAttrib, attrib, %bugnDir%
|
||||
IfNotInString, attrib, D
|
||||
{
|
||||
MsgBox, The file path '%appDir%' already exists and is not a directory. Aborting.
|
||||
Return
|
||||
}
|
||||
logFile := bugnDir . "\bugn_log.txt"
|
||||
Log_init(logFile, False)
|
||||
|
||||
|
||||
Log_msg("====== Initializing ======")
|
||||
If 0 = 1
|
||||
Config_filePath = %1%
|
||||
Config_init()
|
||||
|
@ -52,6 +69,7 @@ Return ; end of the auto-execute section
|
|||
* function & label definitions
|
||||
*/
|
||||
Main_cleanup: ; The labels with "ExitApp" or "Return" at the end and hotkeys have to be after the auto-execute section.
|
||||
Log_msg("====== Cleaning up ======")
|
||||
If Config_autoSaveSession
|
||||
Config_saveSession()
|
||||
Manager_cleanup()
|
||||
|
@ -129,6 +147,8 @@ Main_toggleBar:
|
|||
Monitor_toggleBar()
|
||||
Return
|
||||
|
||||
#Include Log.ahk
|
||||
#Include List.ahk
|
||||
#Include Bar.ahk
|
||||
#Include Config.ahk
|
||||
#Include Manager.ahk
|
||||
|
|
479
src/Manager.ahk
479
src/Manager.ahk
|
@ -57,7 +57,7 @@ Manager_init() {
|
|||
Bar_hideTitleWndIds := ""
|
||||
Manager_allWndIds := ""
|
||||
Manager_managedWndIds := ""
|
||||
Manager_sync()
|
||||
Manager_initial_sync()
|
||||
|
||||
Bar_updateStatus()
|
||||
Bar_updateTitle()
|
||||
|
@ -125,12 +125,6 @@ Manager_applyRules(wndId, ByRef isManaged, ByRef m, ByRef tags, ByRef isFloating
|
|||
hideTitle := rule9
|
||||
}
|
||||
}
|
||||
If (m = 0)
|
||||
m := Manager_aMonitor
|
||||
If (m > Manager_monitorCount) ; If the specified monitor is out of scope, set it to the max. monitor.
|
||||
m := Manager_monitorCount
|
||||
If (tags = 0)
|
||||
tags := 1 << Monitor_#%m%_aView_#1 - 1
|
||||
} Else {
|
||||
isManaged := False
|
||||
If wndTitle
|
||||
|
@ -162,10 +156,10 @@ Manager_cleanup() {
|
|||
Manager_hideShow := True
|
||||
Loop, PARSE, wndIds, `;
|
||||
{
|
||||
WinShow, ahk_id %A_LoopField%
|
||||
Manager_winShow(A_LoopField)
|
||||
If Not Config_showBorder
|
||||
WinSet, Style, +0x40000, ahk_id %A_LoopField%
|
||||
WinSet, Style, +0xC00000, ahk_id %A_LoopField%
|
||||
Manager_winSet("Style", "+0x40000", A_LoopField)
|
||||
Manager_winSet("Style", "+0xC00000", A_LoopField)
|
||||
}
|
||||
|
||||
; Show the task bar.
|
||||
|
@ -182,8 +176,8 @@ Manager_cleanup() {
|
|||
Loop, % Config_viewCount
|
||||
View_arrange(m, A_Index)
|
||||
}
|
||||
WinSet, AlwaysOnTop, On, ahk_id %aWndId%
|
||||
WinSet, AlwaysOnTop, Off, ahk_id %aWndId%
|
||||
Manager_winSet("AlwaysOnTop", "On", aWndId)
|
||||
Manager_winSet("AlwaysOnTop", "Off", aWndId)
|
||||
|
||||
DllCall("Shell32.dll\SHAppBarMessage", "UInt", (ABM_REMOVE := 0x1), "UInt", &Bar_appBarData)
|
||||
; SKAN: Crazy Scripting : Quick Launcher for Portable Apps (http://www.autohotkey.com/forum/topic22398.html)
|
||||
|
@ -194,7 +188,7 @@ Manager_closeWindow() {
|
|||
WinGetClass, aWndClass, ahk_id %aWndId%
|
||||
WinGetTitle, aWndTitle, ahk_id %aWndId%
|
||||
If Not (aWndClass = "AutoHotkeyGUI" And RegExMatch(aWndTitle, "bug.n_BAR_[0-9]+"))
|
||||
WinClose, ahk_id %aWndId%
|
||||
Manager_winClose(aWndId)
|
||||
}
|
||||
|
||||
Manager_getWindowInfo() {
|
||||
|
@ -238,6 +232,112 @@ Manager_getWindowList() {
|
|||
Clipboard := text
|
||||
}
|
||||
|
||||
Manager_logViewLayout() {
|
||||
|
||||
}
|
||||
|
||||
Manager_logWindowInfo( w ) {
|
||||
Local v, wndId, isWinFocus, isBugnActive, isFloating, isHidden, isDecorated, isResponsive, isGhost, wndTitle, wndProc, wndClass, wndStyle, wndX, wndY, wndW, wndH, detect_state
|
||||
|
||||
detect_state := A_DetectHiddenWindows
|
||||
DetectHiddenWindows, On
|
||||
WinGet, wndId, ID, A
|
||||
If wndId = %w%
|
||||
isWinFocus := "*"
|
||||
Else
|
||||
isWinFocus := " "
|
||||
v := Monitor_#%Manager_aMonitor%_aView_#1
|
||||
If View_#%Manager_aMonitor%_#%v%_aWndId = %w%
|
||||
isBugnActive := "*"
|
||||
Else
|
||||
isBugnActive := " "
|
||||
WinGetTitle, wndTitle, ahk_id %w%
|
||||
WinGetClass, wndClass, ahk_id %w%
|
||||
WinGet, wndProc, ProcessName, ahk_id %w%
|
||||
If InStr(Bar_hiddenWndIds, w)
|
||||
isHidden := "*"
|
||||
Else
|
||||
isHidden := " "
|
||||
If Manager_#%w%_isFloating
|
||||
isFloating := "*"
|
||||
Else
|
||||
isFloating := " "
|
||||
If Manager_#%w%_isDecorated
|
||||
isDecorated := "*"
|
||||
Else
|
||||
isDecorated := " "
|
||||
WinGet, wndStyle, Style, ahk_id %w%
|
||||
WinGetPos, wndX, wndY, wndW, wndH, ahk_id %w%
|
||||
|
||||
If Manager_isGhost(w)
|
||||
isGhost := "*"
|
||||
Else
|
||||
isGhost := " "
|
||||
|
||||
DetectHiddenWindows, %detect_state%
|
||||
|
||||
; Intentionally don't detect hidden windows here to see what Manager_hungTest does
|
||||
If Manager_isHung(w)
|
||||
isResponsive := " "
|
||||
Else
|
||||
isResponsive := "*"
|
||||
|
||||
|
||||
Log_bare(w . "`t" . isHidden . " " isWinFocus . " " . isBugnActive . " " . isFloating . " " . isDecorated . " " . isResponsive . " " . isGhost . " " . Manager_#%w%_monitor . "`t" . Manager_#%w%_tags . "`t" . wndX . "`t" . wndY . "`t" . wndW . "`t" . wndH . "`t" . wndStyle . "`t" . wndProc . " / " . wndClass . " / " . wndTitle)
|
||||
}
|
||||
|
||||
Manager_logHeader() {
|
||||
Log_bare( "ID`t`tH W A F D R G M`tTags`tX`tY`tW`tH`tStyle`t`tProc / Class / Title")
|
||||
}
|
||||
|
||||
Manager_logViewWindowList() {
|
||||
Local text, v, aWndId, wndIds, aWndTitle
|
||||
|
||||
v := Monitor_#%Manager_aMonitor%_aView_#1
|
||||
Log_msg( "Window dump for active view (" . Manager_aMonitor . ", " . v . ")" )
|
||||
Manager_logHeader()
|
||||
|
||||
StringTrimRight, wndIds, View_#%Manager_aMonitor%_#%v%_wndIds, 1
|
||||
Loop, PARSE, wndIds, `;
|
||||
{
|
||||
Manager_logWindowInfo( A_LoopField )
|
||||
}
|
||||
}
|
||||
|
||||
Manager_logManagedWindowList() {
|
||||
Local wndIds
|
||||
|
||||
Log_msg( "Window dump for manager" )
|
||||
Manager_logHeader()
|
||||
|
||||
StringTrimRight, wndIds, Manager_managedWndIds, 1
|
||||
Loop, PARSE, wndIds, `;
|
||||
{
|
||||
Manager_logWindowInfo( A_LoopField)
|
||||
}
|
||||
}
|
||||
|
||||
Manager_logHelp() {
|
||||
Log_msg("Help Display")
|
||||
Log_bare("Window list columns")
|
||||
Log_bare(" ID - Windows ID. Unique, OS-assigned ID")
|
||||
Log_bare(" H - Hidden. Whether bug.n thinks this window is hidden.")
|
||||
Log_bare(" W - Windows active. This window is active according to Windows.")
|
||||
Log_bare(" A - View active. This window is active according to bug.n.")
|
||||
Log_bare(" F - Floating. This window should not be positioned and resized by the layout.")
|
||||
Log_bare(" D - Decorated. Does the window have a title bar?")
|
||||
Log_bare(" R - Responsive. Is responding to messages?")
|
||||
Log_bare(" G - Ghost. Is this window a ghost of another hung window?")
|
||||
Log_bare(" M - Monitor number.")
|
||||
Log_bare(" Tags - Bit-mask of the views in which the window is active.")
|
||||
Log_bare(" X - Windows X position.")
|
||||
Log_bare(" Y - Windows Y position.")
|
||||
Log_bare(" W - Windows width.")
|
||||
Log_bare(" H - Windows height.")
|
||||
Log_bare(" Style - Windows style.")
|
||||
Log_bare(" Proc / Class / Title - Process/Class/Title of the window.")
|
||||
}
|
||||
|
||||
Manager_lockWorkStation() {
|
||||
Global Config_shellMsgDelay
|
||||
|
||||
|
@ -261,13 +361,50 @@ Manager_loop(index, increment, lowerBound, upperBound) {
|
|||
Return, index
|
||||
}
|
||||
|
||||
Manager_manage(wndId) {
|
||||
Local a, c0, hideTitle, i, isDecorated, isFloating, isManaged, l, m, n, replace, search, tags
|
||||
; Accept a window to be added to the system for management.
|
||||
; Provide a monitor, view preference, but don't override the config.
|
||||
; pm - Preferred monitor
|
||||
; pv - Preferred view
|
||||
; wndId - Window to add to the manager.
|
||||
Manager_manage(pm, pv, wndId) {
|
||||
Local a, c0, hideTitle, i, isDecorated, isFloating, isManaged, l, m, n, replace, search, tags, body
|
||||
Local wndControlList0, wndId0, wndIds, wndX, wndY, wndWidth, wndHeight, wndProcessName
|
||||
|
||||
If Not InStr(Manager_allWndIds, wndId ";")
|
||||
Manager_allWndIds .= wndId ";"
|
||||
Manager_applyRules(wndId, isManaged, m, tags, isFloating, isDecorated, hideTitle)
|
||||
|
||||
body := 0
|
||||
If Manager_isGhost( wndId ) {
|
||||
Log_dbg_msg(2, "A window has given up the ghost (Ghost wndId: " . wndId . ")")
|
||||
; Ghosts need special attention.
|
||||
; Say a quick prayer and try to reattach it to its body.
|
||||
body := Manager_findHung( wndId )
|
||||
If body {
|
||||
isManaged := InStr(Manager_managedWndIds, body ";")
|
||||
m := Manager_#%body%_monitor
|
||||
tags := Manager_#%body%_tags
|
||||
isDecorated := Manager_#%body%_isDecorated
|
||||
isFloating := Manager_#%body%_isFloating
|
||||
hideTitle := InStr(Bar_hideTitleWndIds, body ";")
|
||||
}
|
||||
Else {
|
||||
Log_dbg_msg(1, "No body could be found for ghost wndId: " . wndId)
|
||||
}
|
||||
}
|
||||
|
||||
; Apply rules if the window is either a normal window or a ghost without a body.
|
||||
If ( body = 0 ) {
|
||||
Manager_applyRules(wndId, isManaged, m, tags, isFloating, isDecorated, hideTitle)
|
||||
|
||||
If (m = 0)
|
||||
m := pm
|
||||
If (m < 0)
|
||||
m := 1
|
||||
If (m > Manager_monitorCount) ; If the specified monitor is out of scope, set it to the max. monitor.
|
||||
m := Manager_monitorCount
|
||||
If (tags = 0)
|
||||
tags := 1 << (pv - 1)
|
||||
}
|
||||
|
||||
WinGet, wndProcessName, ProcessName, ahk_id %wndId%
|
||||
If (wndProcessName = "chrome.exe") {
|
||||
|
@ -281,38 +418,26 @@ Manager_manage(wndId) {
|
|||
Monitor_moveWindow(m, wndId)
|
||||
|
||||
Manager_managedWndIds .= wndId ";"
|
||||
Manager_#%wndId%_monitor := m
|
||||
Manager_#%wndId%_tags := tags
|
||||
Manager_#%wndId%_isDecorated := isDecorated
|
||||
Manager_#%wndId%_isFloating := isFloating
|
||||
|
||||
Loop, % Config_viewCount
|
||||
If (Manager_#%wndId%_tags & 1 << A_Index - 1) {
|
||||
l := View_#%m%_#%A_Index%_layout_#1
|
||||
If (Config_layoutFunction_#%l% = "tile") And ((Config_newWndPosition = "masterBottom") Or (Config_newWndPosition = "stackTop")) {
|
||||
n := View_getTiledWndIds(m, A_Index, wndIds)
|
||||
If (n > 1) {
|
||||
StringSplit, wndId, wndIds, `;
|
||||
If (wndId0 < View_#%m%_#%A_Index%_layoutMSplit)
|
||||
View_#%m%_#%A_Index%_layoutMSplit := wndId0
|
||||
i := View_#%m%_#%A_Index%_layoutMSplit
|
||||
search := wndId%i% ";"
|
||||
replace := search wndId ";"
|
||||
StringReplace, View_#%m%_#%A_Index%_wndIds, View_#%m%_#%A_Index%_wndIds, %search%, %replace%
|
||||
} Else
|
||||
View_#%m%_#%A_Index%_wndIds .= wndId ";"
|
||||
If (Config_newWndPosition = "masterBottom") And (n > 0)
|
||||
View_#%m%_#%A_Index%_layoutMSplit += 1
|
||||
} Else If (Config_newWndPosition = "bottom")
|
||||
View_#%m%_#%A_Index%_wndIds .= wndId ";"
|
||||
Else
|
||||
View_#%m%_#%A_Index%_wndIds := wndId ";" View_#%m%_#%A_Index%_wndIds
|
||||
Bar_updateView(m, A_Index)
|
||||
If (body) {
|
||||
; Try to position near the body.
|
||||
View_ghostWnd(m, A_Index, body, wndId)
|
||||
}
|
||||
Else {
|
||||
View_addWnd(m, A_Index, wndId)
|
||||
}
|
||||
}
|
||||
|
||||
If Not Config_showBorder
|
||||
WinSet, Style, -0x40000, ahk_id %wndId%
|
||||
Manager_winSet("Style", "-0x40000", wndId)
|
||||
If Not Manager_#%wndId%_isDecorated
|
||||
WinSet, Style, -0xC00000, ahk_id %wndId%
|
||||
Manager_winSet("Style", "-0xC00000", wndId)
|
||||
|
||||
a := Manager_#%wndId%_tags & 1 << Monitor_#%m%_aView_#1 - 1
|
||||
If a {
|
||||
|
@ -320,7 +445,7 @@ Manager_manage(wndId) {
|
|||
Manager_winActivate(wndId)
|
||||
} Else {
|
||||
Manager_hideShow := True
|
||||
WinHide, ahk_id %wndId%
|
||||
Manager_winHide(wndId)
|
||||
Manager_hideShow := False
|
||||
}
|
||||
}
|
||||
|
@ -341,7 +466,7 @@ Manager_maximizeWindow() {
|
|||
l := View_#%Manager_aMonitor%_#%v%_layout_#1
|
||||
If Not Manager_#%aWndId%_isFloating And Not (Config_layoutFunction_#%l% = "")
|
||||
View_toggleFloating()
|
||||
WinSet, Top,, ahk_id %aWndId%
|
||||
Manager_winSet("Top", "", aWndId)
|
||||
|
||||
Manager_winMove(aWndId, Monitor_#%Manager_aMonitor%_x, Monitor_#%Manager_aMonitor%_y, Monitor_#%Manager_aMonitor%_width, Monitor_#%Manager_aMonitor%_height)
|
||||
}
|
||||
|
@ -354,19 +479,61 @@ Manager_moveWindow() {
|
|||
l := View_#%Manager_aMonitor%_#%v%_layout_#1
|
||||
If Not Manager_#%aWndId%_isFloating And Not (Config_layoutFunction_#%l% = "")
|
||||
View_toggleFloating()
|
||||
WinSet, Top,, ahk_id %aWndId%
|
||||
Manager_winSet("Top", "", aWndId)
|
||||
|
||||
WM_SYSCOMMAND = 0x112
|
||||
SC_MOVE = 0xF010
|
||||
SendMessage, WM_SYSCOMMAND, SC_MOVE, , , ahk_id %aWndId%
|
||||
}
|
||||
|
||||
HSHELL_WINDOWCREATED := 1
|
||||
; Seems to get sent sometimes when windows are deactivated.
|
||||
HSHELL_WINDOWDESTROYED := 2
|
||||
HSHELL_WINDOWACTIVATED := 4
|
||||
; At least title change.
|
||||
HSHELL_REDRAW := 6
|
||||
; The following two are seen when a hung window recovers.
|
||||
; lParam notes the ghost process
|
||||
HSHELL_WINDOWREPLACED := 13
|
||||
; lParam notes the recovered process
|
||||
;14
|
||||
; Full-screen app activated? Root-privileged window activated?
|
||||
HSHELL_RUDEAPPACTIVATED := 32772
|
||||
; When a window is signalling an application update.
|
||||
WINDOW_NOTICE := 32774
|
||||
|
||||
;
|
||||
; Reliable messages and their meanings (note that any message may be missed if bug.n is hung):
|
||||
; 1 - Window shown (shown ID)
|
||||
; 2 - Window destroyed or hidden, same message for both (destroyed or hidden ID)
|
||||
; 4 - Window activated via mouse, alt+tab, or hotkey (sometimes 32772, but always one of them)
|
||||
; 6 - Window title change (ID of redrawn window)
|
||||
; 13 - Hung window recovers and replaces ghost window (ghost window ID is provided)
|
||||
; 14 - Hung window recovered (ID of previously hung window)
|
||||
; 32772 - Window activated via mouse, alt+tab, or hotkey (sometimes 4, but always one of them)
|
||||
; 32774 - Window is flashing due to some event, one message for each flash
|
||||
;
|
||||
; Indications of:
|
||||
; New windows - cmd/shell may be starting a new window on message 6
|
||||
; Win+e indicates a new window with message 6 as long as the button
|
||||
; presses are below a certain frequency.
|
||||
; Message 1 may indicate a new window started from Windows Explorer
|
||||
; There doesn't seem to be a reliable way to get all application starts.
|
||||
; Closed windows - 13 always indicates closed ghost window
|
||||
; 2 always indicates closed standard window
|
||||
; Focus change - 4 or 32772 always catch this
|
||||
; Window event - 6 indicates when title changes which can be used
|
||||
; in the case of some applications, 32774 works for others
|
||||
;
|
||||
Manager_onShellMessage(wParam, lParam) {
|
||||
Local a, aWndClass, aWndHeight, aWndId, aWndTitle, aWndWidth, aWndX, aWndY, flag, m, t, wndClass, wndId, wndIds, wndPName, wndTitle, x, y
|
||||
Local a, isChanged, aWndClass, aWndHeight, aWndId, aWndTitle, aWndWidth, aWndX, aWndY, m, t, wndClass, wndId, wndIds, wndPName, wndTitle, x, y
|
||||
|
||||
SetFormat, Integer, hex
|
||||
lParam := lParam+0
|
||||
SetFormat, Integer, d
|
||||
|
||||
Log_dbg_msg(2, "Manager_onShellMessage( wParam: " . wParam . ", lParam: " . lParam . " )")
|
||||
|
||||
WinGetClass, wndClass, ahk_id %lParam%
|
||||
WinGetTitle, wndTitle, ahk_id %lParam%
|
||||
WinGet, wndPName, ProcessName, ahk_id %lParam%
|
||||
|
@ -382,6 +549,15 @@ Manager_onShellMessage(wParam, lParam) {
|
|||
Bar_updateTitle()
|
||||
}
|
||||
|
||||
If ( wParam = HSHELL_WINDOWREPLACED ) {
|
||||
; This shouldn't need a redraw because the window was supposedly replaced.
|
||||
Manager_unmanage(lParam)
|
||||
}
|
||||
|
||||
If ( wParam = 14 ) {
|
||||
; Window recovered from being hung. Maybe force a redraw.
|
||||
}
|
||||
|
||||
If (wParam = 1 Or wParam = 2 Or wParam = 4 Or wParam = 6 Or wParam = 32772) And lParam And Not Manager_hideShow And Not Manager_focus {
|
||||
If Not (wParam = 4 Or wParam = 32772)
|
||||
If Not wndClass And Not (wParam = 2) {
|
||||
|
@ -393,42 +569,41 @@ Manager_onShellMessage(wParam, lParam) {
|
|||
Sleep, %Config_shellMsgDelay%
|
||||
}
|
||||
|
||||
If (wParam = 1 Or wParam = 6) And Not InStr(Manager_allWndIds, lParam ";") And Not InStr(Manager_managedWndIds, lParam ";")
|
||||
a := Manager_manage(lParam)
|
||||
Else {
|
||||
flag := True
|
||||
a := Manager_sync(wndIds)
|
||||
If wndIds
|
||||
a := False
|
||||
}
|
||||
If a {
|
||||
isChanged := Manager_sync(wndIds)
|
||||
If wndIds
|
||||
isChanged := False
|
||||
|
||||
If a Or isChanged {
|
||||
View_arrange(Manager_aMonitor, Monitor_#%Manager_aMonitor%_aView_#1)
|
||||
Bar_updateView(Manager_aMonitor, Monitor_#%Manager_aMonitor%_aView_#1)
|
||||
}
|
||||
|
||||
If flag
|
||||
If (Manager_monitorCount > 1) {
|
||||
WinGetPos, aWndX, aWndY, aWndWidth, aWndHeight, ahk_id %aWndId%
|
||||
m := Monitor_get(aWndX + aWndWidth / 2, aWndY + aWndHeight / 2)
|
||||
If m
|
||||
Manager_aMonitor := m
|
||||
}
|
||||
If (Manager_monitorCount > 1) {
|
||||
WinGetPos, aWndX, aWndY, aWndWidth, aWndHeight, ahk_id %aWndId%
|
||||
m := Monitor_get(aWndX + aWndWidth / 2, aWndY + aWndHeight / 2)
|
||||
If m
|
||||
Manager_aMonitor := m
|
||||
}
|
||||
|
||||
If wndIds {
|
||||
If (Config_onActiveHiddenWnds = "view") {
|
||||
wndId := SubStr(wndIds, 1, InStr(wndIds, ";") - 1)
|
||||
Loop, % Config_viewCount
|
||||
If (Manager_#%wndId%_tags & 1 << A_Index - 1) {
|
||||
Log_dbg_msg(3, "Switching views because " . wndId . " is considered hidden and active")
|
||||
Manager_aMonitor := Manager_#%wndId%_monitor
|
||||
Monitor_activateView(A_Index)
|
||||
Break
|
||||
}
|
||||
} Else {
|
||||
StringTrimRight, wndIds, wndIds, 1
|
||||
StringSplit, wndId, wndIds, `;
|
||||
; Otherwise re-hide them.
|
||||
If (Config_onActiveHiddenWnds = "hide") {
|
||||
Loop, % wndId0
|
||||
WinHide, % "ahk_id " wndId%A_Index%
|
||||
Manager_winHide(wndId%A_Index%)
|
||||
} Else If (Config_onActiveHiddenWnds = "tag") {
|
||||
; Or tag all of them for the current view.
|
||||
t := Monitor_#%Manager_aMonitor%_aView_#1
|
||||
Loop, % wndId0 {
|
||||
wndId := wndId%A_Index%
|
||||
|
@ -521,7 +696,7 @@ Manager_sizeWindow() {
|
|||
l := View_#%Manager_aMonitor%_#%v%_layout_#1
|
||||
If Not Manager_#%aWndId%_isFloating And Not (Config_layoutFunction_#%l% = "")
|
||||
View_toggleFloating()
|
||||
WinSet, Top,, ahk_id %aWndId%
|
||||
Manager_winSet("Top", "", aWndId)
|
||||
|
||||
WM_SYSCOMMAND = 0x112
|
||||
SC_SIZE = 0xF000
|
||||
|
@ -540,11 +715,14 @@ Manager_sync(ByRef wndIds = "") {
|
|||
Loop, % wndId {
|
||||
If Not InStr(shownWndIds, wndId%A_Index% ";") {
|
||||
If Not InStr(Manager_managedWndIds, wndId%A_Index% ";") {
|
||||
flag := Manager_manage(wndId%A_Index%)
|
||||
flag := Manager_manage(Manager_aMonitor, Monitor_#%Manager_aMonitor%_aView_#1, wndId%A_Index%)
|
||||
If flag
|
||||
a := flag
|
||||
} Else
|
||||
} Else If Not Manager_isHung(wndId%A_Index%) {
|
||||
; This is a window that is already managed but was brought into focus by something. Maybe it
|
||||
; would be useful to do something with it.
|
||||
wndIds .= wndId%A_Index% ";"
|
||||
}
|
||||
}
|
||||
visibleWndIds := visibleWndIds wndId%A_Index% ";"
|
||||
}
|
||||
|
@ -563,15 +741,55 @@ Manager_sync(ByRef wndIds = "") {
|
|||
Return, a
|
||||
}
|
||||
|
||||
; No windows are known to the system yet.
|
||||
; Try to do something smart with the initial layout.
|
||||
Manager_initial_sync() {
|
||||
Local wndId0, wnd, wndX, wndY, wndW, wndH, x, y, m, len
|
||||
|
||||
; Initialize lists
|
||||
; Note that these variables make this function non-reentrant.
|
||||
Loop, % Manager_monitorCount
|
||||
Manager_initial_sync_m#%A_Index%_wndList := List_new()
|
||||
|
||||
; check all visible windows against the known windows
|
||||
WinGet, wndId, List, , ,
|
||||
Loop, % wndId {
|
||||
; Based on some analysis here, determine which monitors and layouts would best
|
||||
; serve existing windows. Do not override configuration settings.
|
||||
|
||||
; Which monitor is it on?
|
||||
|
||||
wnd := wndId%A_Index%
|
||||
WinGetPos, wndX, wndY, wndW, wndH, ahk_id %wnd%
|
||||
|
||||
x := wndX + wndW/2
|
||||
y := wndY + wndH/2
|
||||
|
||||
m := Monitor_get(x, y)
|
||||
If m > 0
|
||||
List_append(Manager_initial_sync_m#%m%_wndList, wndId%A_index%)
|
||||
|
||||
; @todo: What percentage of the monitor area is it occupying? (Suggest layout)
|
||||
; @todo: What part of the monitor is it on? (Ordering of windows)
|
||||
}
|
||||
|
||||
Loop, % Manager_monitorCount {
|
||||
m := A_Index
|
||||
len := List_toArray(Manager_initial_sync_m#%m%_wndList, "Manager_initial_sync_tmpArray")
|
||||
Loop, % len
|
||||
Manager_manage(m, 1, Manager_initial_sync_tmpArray%A_Index%)
|
||||
}
|
||||
}
|
||||
|
||||
Manager_toggleDecor() {
|
||||
Local aWndId
|
||||
|
||||
WinGet, aWndId, ID, A
|
||||
Manager_#%aWndId%_isDecorated := Not Manager_#%aWndId%_isDecorated
|
||||
If Manager_#%aWndId%_isDecorated
|
||||
WinSet, Style, +0xC00000, ahk_id %aWndId%
|
||||
Manager_winSet("Style", "+0xC00000", aWndId)
|
||||
Else
|
||||
WinSet, Style, -0xC00000, ahk_id %aWndId%
|
||||
Manager_winSet("Style", "-0xC00000", aWndId)
|
||||
}
|
||||
|
||||
Manager_unmanage(wndId) {
|
||||
|
@ -580,9 +798,10 @@ Manager_unmanage(wndId) {
|
|||
a := Manager_#%wndId%_tags & 1 << Monitor_#%Manager_aMonitor%_aView_#1 - 1
|
||||
Loop, % Config_viewCount
|
||||
If (Manager_#%wndId%_tags & 1 << A_Index - 1) {
|
||||
StringReplace, View_#%Manager_aMonitor%_#%A_Index%_wndIds, View_#%Manager_aMonitor%_#%A_Index%_wndIds, %wndId%`;,
|
||||
View_delWnd( Manager_aMonitor, A_Index, wndId )
|
||||
Bar_updateView(Manager_aMonitor, A_Index)
|
||||
}
|
||||
Manager_#%wndId%_monitor :=
|
||||
Manager_#%wndId%_tags :=
|
||||
Manager_#%wndId%_isDecorated :=
|
||||
Manager_#%wndId%_isFloating :=
|
||||
|
@ -594,7 +813,7 @@ Manager_unmanage(wndId) {
|
|||
}
|
||||
|
||||
Manager_winActivate(wndId) {
|
||||
Local wndHeight, wndWidth, wndX, wndY
|
||||
Local wndHeight, wndWidth, wndX, wndY, newWnd
|
||||
|
||||
If Config_mouseFollowsFocus {
|
||||
If wndId {
|
||||
|
@ -603,15 +822,135 @@ Manager_winActivate(wndId) {
|
|||
} Else
|
||||
DllCall("SetCursorPos", "Int", Round(Monitor_#%Manager_aMonitor%_x + Monitor_#%Manager_aMonitor%_width / 2), "Int", Round(Monitor_#%Manager_aMonitor%_y + Monitor_#%Manager_aMonitor%_height / 2))
|
||||
}
|
||||
WinActivate, ahk_id %wndId%
|
||||
If Manager_isHung(wndId) {
|
||||
Log_dbg_msg(2, "Manager_winActivate: Potentially hung window " . wndId)
|
||||
Return 1
|
||||
}
|
||||
Else {
|
||||
WinActivate, ahk_id %wndId%
|
||||
WinGet, newWin, ID, A
|
||||
If (wndId != newWin)
|
||||
Return 1
|
||||
}
|
||||
Bar_updateTitle()
|
||||
Return 0
|
||||
}
|
||||
|
||||
Manager_winMove(wndId, x, y, width, height) {
|
||||
WinRestore, ahk_id %wndId%
|
||||
If Manager_isHung(wndId) {
|
||||
Log_dbg_msg(2, "Manager_winMove: Potentially hung window " . wndId)
|
||||
Return 1
|
||||
}
|
||||
Else
|
||||
WinRestore, ahk_id %wndId%
|
||||
WM_ENTERSIZEMOVE = 0x0231
|
||||
WM_EXITSIZEMOVE = 0x0232
|
||||
SendMessage, WM_ENTERSIZEMOVE, , , , ahk_id %wndId%
|
||||
WinMove, ahk_id %wndId%, , %x%, %y%, %width%, %height%
|
||||
SendMessage, WM_EXITSIZEMOVE, , , , ahk_id %wndId%
|
||||
If ErrorLevel {
|
||||
Log_dbg_msg(2, "Manager_winMove: Potentially hung window " . wndId)
|
||||
Return 1
|
||||
}
|
||||
Else {
|
||||
WinMove, ahk_id %wndId%, , %x%, %y%, %width%, %height%
|
||||
SendMessage, WM_EXITSIZEMOVE, , , , ahk_id %wndId%
|
||||
}
|
||||
}
|
||||
|
||||
Manager_winHide(wndId) {
|
||||
|
||||
If Manager_isHung(wndId) {
|
||||
Log_dbg_msg(2, "Manager_winHide: Potentially hung window " . wndId)
|
||||
Return 1
|
||||
}
|
||||
Else {
|
||||
WinHide, ahk_id %wndId%
|
||||
Return 0
|
||||
}
|
||||
}
|
||||
|
||||
Manager_winShow(wndId) {
|
||||
|
||||
If Manager_isHung(wndId) {
|
||||
Log_dbg_msg(2, "Manager_winShow: Potentially hung window " . wndId)
|
||||
Return 1
|
||||
}
|
||||
Else {
|
||||
WinShow, ahk_id %wndId%
|
||||
Return 0
|
||||
}
|
||||
}
|
||||
|
||||
Manager_winClose(wndId) {
|
||||
|
||||
If Manager_isHung(wndId) {
|
||||
Log_dbg_msg(2, "Manager_winClose: Potentially hung window " . wndId)
|
||||
Return 1
|
||||
}
|
||||
Else {
|
||||
WinClose, ahk_id %wndId%
|
||||
Return 0
|
||||
}
|
||||
}
|
||||
|
||||
Manager_winSet(type, value, wndId) {
|
||||
|
||||
If Manager_isHung(wndId) {
|
||||
Log_dbg_msg(2, "Manager_winSet: Potentially hung window " . wndId)
|
||||
Return 1
|
||||
}
|
||||
Else {
|
||||
WinSet, %type%, %value%, ahk_id %wndId%
|
||||
Return 0
|
||||
}
|
||||
}
|
||||
|
||||
; 0 - Not hung
|
||||
; 1 - Hung
|
||||
Manager_isHung(wndId) {
|
||||
Local result, detect_setting, WM_NULL
|
||||
WM_NULL := 0
|
||||
detect_setting := A_DetectHiddenWindows
|
||||
DetectHiddenWindows, On
|
||||
SendMessage, WM_NULL, , , , ahk_id %wndId%
|
||||
result := ErrorLevel
|
||||
DetectHiddenWindows, %detect_setting%
|
||||
|
||||
If result
|
||||
Return 1
|
||||
Else
|
||||
Return 0
|
||||
}
|
||||
|
||||
; Given a ghost window, try to find its body.
|
||||
; This is only known to work on Windows 7
|
||||
Manager_findHung( ghostWnd ) {
|
||||
Local expectedTitle, expectedX, expectedY, expectedW, expectedH, wndTitle, wndX, wndY, wndW, wndH, wndIds
|
||||
;Log_dbg_msg(3, "Manager_findHung(" . ghostWnd . ")")
|
||||
WinGetTitle, expectedTitle, ahk_id %ghostWnd%
|
||||
StringReplace, expectedTitle, expectedTitle, " (Not Responding)", ""
|
||||
WinGetPos, expectedX, expectedY, expectedW, expectedH, ahk_id %ghostWnd%
|
||||
|
||||
SetTitleMatchMode, 2
|
||||
WinGet, wndIds, List, %expectedTitle%
|
||||
Loop, % wndIds {
|
||||
If (A_Index = ghostWnd)
|
||||
Continue
|
||||
WinGetPos, wndX, wndY, wndW, wndH, % "ahk_id" wndIDs%A_Index%
|
||||
|
||||
If (wndX = expectedX) And (wndY = expectedY) And (wndW = expectedW) And (wndH = expectedH)
|
||||
Return wndIds%A_Index%
|
||||
}
|
||||
Return 0
|
||||
}
|
||||
|
||||
Manager_isGhost(wndId) {
|
||||
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
|
||||
}
|
131
src/Monitor.ahk
131
src/Monitor.ahk
|
@ -40,56 +40,71 @@ Monitor_activateView(v) {
|
|||
v := Manager_loop(Monitor_#%Manager_aMonitor%_aView_#1, +1, 1, Config_viewCount)
|
||||
Else If (v = "<")
|
||||
v := Manager_loop(Monitor_#%Manager_aMonitor%_aView_#1, -1, 1, Config_viewCount)
|
||||
If (v > 0) And (v <= Config_viewCount) And Not Manager_hideShow And Not (v = Monitor_#%Manager_aMonitor%_aView_#1) {
|
||||
aView := Monitor_#%Manager_aMonitor%_aView_#1
|
||||
WinGet, aWndId, ID, A
|
||||
If WinExist("ahk_id" aWndId) And InStr(View_#%Manager_aMonitor%_#%aView%_wndIds, aWndId ";") {
|
||||
WinGetClass, aWndClass, ahk_id %aWndId%
|
||||
WinGetTitle, aWndTitle, ahk_id %aWndId%
|
||||
If Not (aWndClass = "Progman") And Not (aWndClass = "AutoHotkeyGui" And SubStr(aWndTitle, 1, 10) = "bug.n_BAR_") And Not (aWndClass = "DesktopBackgroundClass")
|
||||
View_#%Manager_aMonitor%_#%aView%_aWndId := aWndId
|
||||
}
|
||||
|
||||
n := Config_syncMonitorViews
|
||||
If (n = 1)
|
||||
n := Manager_monitorCount
|
||||
Else If (n < 1)
|
||||
n := 1
|
||||
Loop, % n {
|
||||
If (n = 1)
|
||||
m := Manager_aMonitor
|
||||
Else
|
||||
m := A_Index
|
||||
|
||||
Monitor_#%m%_aView_#2 := aView
|
||||
Monitor_#%m%_aView_#1 := v
|
||||
|
||||
Manager_hideShow := True
|
||||
StringTrimRight, wndIds, View_#%m%_#%aView%_wndIds, 1
|
||||
Loop, PARSE, wndIds, `;
|
||||
If Not (Manager_#%A_LoopField%_tags & (1 << v - 1))
|
||||
WinHide, ahk_id %A_LoopField%
|
||||
StringTrimRight, wndIds, View_#%m%_#%v%_wndIds, 1
|
||||
Loop, PARSE, wndIds, `;
|
||||
WinShow, ahk_id %A_LoopField%
|
||||
Manager_hideShow := False
|
||||
|
||||
Bar_updateView(m, aView)
|
||||
Bar_updateView(m, v)
|
||||
|
||||
View_arrange(m, v)
|
||||
}
|
||||
|
||||
wndId := View_#%Manager_aMonitor%_#%v%_aWndId
|
||||
If Not (wndId And WinExist("ahk_id" wndId)) {
|
||||
If View_#%Manager_aMonitor%_#%v%_wndIds {
|
||||
wndId := SubStr(View_#%Manager_aMonitor%_#%v%_wndIds, 1, InStr(View_#%Manager_aMonitor%_#%v%_wndIds, ";")-1)
|
||||
View_#%Manager_aMonitor%_#%v%_aWndId := wndId
|
||||
} Else
|
||||
wndId := 0
|
||||
}
|
||||
Manager_winActivate(wndId)
|
||||
|
||||
Log_dbg_msg(1, "Monitor_activateView(" . v . ") Manager_aMonitor: " . Manager_aMonitor . "; wndIds: " . View_#%m%_#%aView%_wndIds)
|
||||
|
||||
If (v <= 0) Or (v > Config_viewCount) Or Manager_hideShow
|
||||
Return
|
||||
; Re-arrange the windows on the view.
|
||||
If (v = Monitor_#%Manager_aMonitor%_aView_#1) {
|
||||
View_arrange(Manager_aMonitor, v)
|
||||
Return
|
||||
}
|
||||
|
||||
aView := Monitor_#%Manager_aMonitor%_aView_#1
|
||||
WinGet, aWndId, ID, A
|
||||
If WinExist("ahk_id" aWndId) And InStr(View_#%Manager_aMonitor%_#%aView%_wndIds, aWndId ";") {
|
||||
WinGetClass, aWndClass, ahk_id %aWndId%
|
||||
WinGetTitle, aWndTitle, ahk_id %aWndId%
|
||||
If Not (aWndClass = "Progman") And Not (aWndClass = "AutoHotkeyGui" And SubStr(aWndTitle, 1, 10) = "bug.n_BAR_") And Not (aWndClass = "DesktopBackgroundClass")
|
||||
View_#%Manager_aMonitor%_#%aView%_aWndId := aWndId
|
||||
}
|
||||
|
||||
n := 1
|
||||
If (Config_syncMonitorViews > 0)
|
||||
n := Manager_monitorCount
|
||||
Loop, % n {
|
||||
If (n = 1)
|
||||
m := Manager_aMonitor
|
||||
Else
|
||||
m := A_Index
|
||||
|
||||
Monitor_#%m%_aView_#2 := aView
|
||||
Monitor_#%m%_aView_#1 := v
|
||||
|
||||
Manager_hideShow := True
|
||||
; Most of the operations here are dispersed to multiple _different_ windows.
|
||||
; Delays in this part of the code are extremely noticeable and the users
|
||||
; do a lot of view switching.
|
||||
SetWinDelay, 0
|
||||
StringTrimRight, wndIds, View_#%m%_#%aView%_wndIds, 1
|
||||
Loop, PARSE, wndIds, `;
|
||||
If Not (Manager_#%A_LoopField%_tags & (1 << v - 1))
|
||||
Manager_winHide(A_LoopField)
|
||||
SetWinDelay, 10
|
||||
DetectHiddenWindows, On
|
||||
View_arrange(m, v)
|
||||
DetectHiddenWindows, Off
|
||||
StringTrimRight, wndIds, View_#%m%_#%v%_wndIds, 1
|
||||
SetWinDelay, 0
|
||||
Loop, PARSE, wndIds, `;
|
||||
Manager_winShow(A_LoopField)
|
||||
SetWinDelay, 10
|
||||
Manager_hideShow := False
|
||||
|
||||
Bar_updateView(m, aView)
|
||||
Bar_updateView(m, v)
|
||||
}
|
||||
|
||||
wndId := View_#%Manager_aMonitor%_#%v%_aWndId
|
||||
If Not (wndId And WinExist("ahk_id" wndId)) {
|
||||
If View_#%Manager_aMonitor%_#%v%_wndIds {
|
||||
wndId := SubStr(View_#%Manager_aMonitor%_#%v%_wndIds, 1, InStr(View_#%Manager_aMonitor%_#%v%_wndIds, ";")-1)
|
||||
View_#%Manager_aMonitor%_#%v%_aWndId := wndId
|
||||
} Else
|
||||
wndId := 0
|
||||
}
|
||||
Manager_winActivate(wndId)
|
||||
}
|
||||
|
||||
Monitor_get(x, y) {
|
||||
|
@ -164,19 +179,9 @@ Monitor_getWorkArea(m) {
|
|||
}
|
||||
|
||||
Monitor_moveWindow(m, wndId) {
|
||||
Local fX, fY, monitor, wndHeight, wndWidth, wndX, wndY
|
||||
Global
|
||||
|
||||
WinGetPos, wndX, wndY, wndWidth, wndHeight, ahk_id %wndId%
|
||||
monitor := Monitor_get(wndX+wndWidth/2, wndY+wndHeight/2)
|
||||
If Not (m = monitor) {
|
||||
; move the window to the target monitor and scale it, if it does not fit on the monitor
|
||||
fX := Monitor_#%m%_width / Monitor_#%monitor%_width
|
||||
fY := Monitor_#%m%_height / Monitor_#%monitor%_height
|
||||
If (wndX-Monitor_#%monitor%_x+wndWidth > Monitor_#%m%_width) Or (wndY-Monitor_#%monitor%_y+wndHeight > Monitor_#%m%_height)
|
||||
Manager_winMove(wndId, Monitor_#%m%_x+fX*(wndX-Monitor_#%monitor%_x), Monitor_#%m%_y+fY*(wndY-Monitor_#%monitor%_y), fX*wndWidth, fY*wndHeight)
|
||||
Else
|
||||
Manager_winMove(wndId, Monitor_#%m%_x+(wndX-Monitor_#%monitor%_x), Monitor_#%m%_y+(wndY-Monitor_#%monitor%_y), wndWidth, wndHeight)
|
||||
}
|
||||
Manager_#%wndId%_monitor = m
|
||||
}
|
||||
|
||||
Monitor_setWindowTag(t) {
|
||||
|
@ -220,7 +225,7 @@ Monitor_setWindowTag(t) {
|
|||
Monitor_activateView(t)
|
||||
Else {
|
||||
Manager_hideShow := True
|
||||
WinHide, ahk_id %aWndId%
|
||||
Manager_winHide(aWndId)
|
||||
Manager_hideShow := False
|
||||
View_arrange(Manager_aMonitor, aView)
|
||||
Bar_updateView(Manager_aMonitor, t)
|
||||
|
@ -273,7 +278,7 @@ Monitor_toggleWindowTag(t) {
|
|||
Bar_updateView(Manager_aMonitor, t)
|
||||
If (t = Monitor_#%Manager_aMonitor%_aView_#1) {
|
||||
Manager_hideShow := True
|
||||
WinHide, ahk_id %aWndId%
|
||||
Manager_winHide(aWndId)
|
||||
Manager_hideShow := False
|
||||
wndId := SubStr(View_#%Manager_aMonitor%_#%t%_wndIds, 1, InStr(View_#%Manager_aMonitor%_#%t%_wndIds, ";")-1)
|
||||
Manager_winActivate(wndId)
|
||||
|
|
514
src/View.ahk
514
src/View.ahk
|
@ -29,44 +29,122 @@ View_init(m, v) {
|
|||
View_#%m%_#%v%_layoutAxis_#3 := Config_layoutAxis_#3
|
||||
View_#%m%_#%v%_layoutGapWidth := Config_layoutGapWidth
|
||||
View_#%m%_#%v%_layoutMFact := Config_layoutMFactor
|
||||
View_#%m%_#%v%_layoutMSplit := 1
|
||||
View_#%m%_#%v%_layoutMX := 1
|
||||
View_#%m%_#%v%_layoutMY := 1
|
||||
View_#%m%_#%v%_layoutSymbol := Config_layoutSymbol_#1
|
||||
View_#%m%_#%v%_wndIds := ""
|
||||
}
|
||||
|
||||
View_activateWindow(d) {
|
||||
Local aWndId, i, j, v, wndId, wndId0, wndIds
|
||||
Local aWndId, i, j, v, wndId, wndId0, wndIds, failure, direction
|
||||
|
||||
Log_dbg_msg(1, "View_activateWindow(" . d . ")")
|
||||
|
||||
If (d = 0)
|
||||
Return
|
||||
|
||||
WinGet, aWndId, ID, A
|
||||
Log_dbg_bare(2, "Active Windows ID: " . aWndId)
|
||||
v := Monitor_#%Manager_aMonitor%_aView_#1
|
||||
Log_dbg_bare(2, "View (" . v . ") wndIds: " . View_#%Manager_aMonitor%_#%v%_wndIds)
|
||||
StringTrimRight, wndIds, View_#%Manager_aMonitor%_#%v%_wndIds, 1
|
||||
StringSplit, wndId, wndIds, `;
|
||||
Log_dbg_bare(2, "wndId count: " . wndId0)
|
||||
If (wndId0 > 1) {
|
||||
If Manager_#%aWndId%_isFloating
|
||||
Manager_winSet("Bottom", "", aWndId)
|
||||
Loop, % wndId0
|
||||
If (wndId%A_Index% = aWndId) {
|
||||
i := A_Index
|
||||
Break
|
||||
}
|
||||
If (d > 0)
|
||||
direction = 1
|
||||
Else
|
||||
direction = -1
|
||||
Log_dbg_bare(2, "Current wndId index: " . i)
|
||||
j := Manager_loop(i, d, 1, wndId0)
|
||||
wndId := wndId%j%
|
||||
WinSet, AlwaysOnTop, On, ahk_id %wndId%
|
||||
WinSet, AlwaysOnTop, Off, ahk_id %wndId%
|
||||
If Manager_#%aWndId%_isFloating
|
||||
WinSet, Bottom, , ahk_id %aWndId%
|
||||
Manager_winActivate(wndId)
|
||||
Loop, % wndId0 {
|
||||
Log_dbg_bare(2, "Next wndId index: " . j)
|
||||
wndId := wndId%j%
|
||||
Manager_winSet("AlwaysOnTop", "On", wndId)
|
||||
Manager_winSet("AlwaysOnTop", "Off", wndId)
|
||||
; This is a lot of extra work in case there are hung windows on the screen.
|
||||
; We still want to be able to cycle through them.
|
||||
failure := Manager_winActivate(wndId)
|
||||
If Not failure {
|
||||
Break
|
||||
}
|
||||
|
||||
j := Manager_loop(j, direction, 1, wndId0)
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
View_updateLayout(m, v) {
|
||||
Local fn, l, wndIds
|
||||
l := View_#%m%_#%v%_layout_#1
|
||||
fn := Config_layoutFunction_#%l%
|
||||
View_updateLayout_%fn%(m, v)
|
||||
}
|
||||
|
||||
; Add a window to the view in question.
|
||||
View_addWnd(m, v, wndId) {
|
||||
Local l, msplit, i, wndIds, n
|
||||
|
||||
l := View_#%m%_#%v%_layout_#1
|
||||
If (Config_layoutFunction_#%l% = "tile") And ((Config_newWndPosition = "masterBottom") Or (Config_newWndPosition = "stackTop")) {
|
||||
n := View_getTiledWndIds(m, v, wndIds)
|
||||
msplit := View_#%m%_#%v%_layoutMX * View_#%m%_#%v%_layoutMY
|
||||
If ( msplit = 1 And Config_newWndPosition="masterBottom" ) {
|
||||
View_#%m%_#%v%_wndIds := wndId ";" . View_#%m%_#%v%_wndIds
|
||||
}
|
||||
Else If ( (Config_newWndPosition="masterBottom" And n < msplit) Or (Config_newWndPosition="stackTop" And n <= msplit) ) {
|
||||
View_#%m%_#%v%_wndIds .= wndId ";"
|
||||
}
|
||||
Else {
|
||||
If (Config_newWndPosition="masterBottom")
|
||||
i := msplit - 1
|
||||
Else
|
||||
i := msplit
|
||||
StringSplit, wndId, wndIds, `;
|
||||
search := wndId%i% ";"
|
||||
replace := search wndId ";"
|
||||
StringReplace, View_#%m%_#%v%_wndIds, View_#%m%_#%v%_wndIds, %search%, %replace%
|
||||
}
|
||||
}
|
||||
Else If (Config_newWndPosition = "bottom")
|
||||
View_#%m%_#%v%_wndIds .= wndId ";"
|
||||
Else
|
||||
View_#%m%_#%v%_wndIds := wndId ";" View_#%m%_#%v%_wndIds
|
||||
}
|
||||
|
||||
View_ghostWnd(m, v, bodyWndId, ghostWndId) {
|
||||
Local search, replace
|
||||
|
||||
search := bodyWndId ";"
|
||||
replace := search ghostWndId ";"
|
||||
StringReplace, View_#%m%_#%v%_wndIds, View_#%m%_#%v%_wndIds, %search%, %replace%
|
||||
}
|
||||
|
||||
; Remove a window from the view in question.
|
||||
View_delWnd(m, v, wndId) {
|
||||
StringReplace, View_#%m%_#%v%_wndIds, View_#%m%_#%v%_wndIds, %wndId%`;,
|
||||
}
|
||||
|
||||
View_arrange(m, v) {
|
||||
Local fn, l, wndIds
|
||||
|
||||
Log_dbg_msg(1, "View_arrange(" . m . ", " . v . ")")
|
||||
; All window actions are performed on independent windows. A delay won't help.
|
||||
SetWinDelay, 0
|
||||
l := View_#%m%_#%v%_layout_#1
|
||||
fn := Config_layoutFunction_#%l%
|
||||
If fn And (View_getTiledWndIds(m, v, wndIds) Or fn = "tile")
|
||||
View_%fn%(m, v, wndIds)
|
||||
Else
|
||||
View_#%m%_#%v%_layoutSymbol := Config_layoutSymbol_#%l%
|
||||
View_getTiledWndIds(m, v, wndIds)
|
||||
View_arrange_%fn%(m, v, wndIds)
|
||||
View_updateLayout(m, v)
|
||||
Bar_updateLayout(m)
|
||||
SetWinDelay, 10
|
||||
}
|
||||
|
||||
View_getTiledWndIds(m, v, ByRef tiledWndIds) {
|
||||
|
@ -75,7 +153,7 @@ View_getTiledWndIds(m, v, ByRef tiledWndIds) {
|
|||
StringTrimRight, wndIds, View_#%m%_#%v%_wndIds, 1
|
||||
Loop, PARSE, wndIds, `;
|
||||
{
|
||||
If Not Manager_#%A_LoopField%_isFloating And WinExist("ahk_id " A_LoopField) {
|
||||
If Not Manager_#%A_LoopField%_isFloating And WinExist("ahk_id " A_LoopField) and Not Manager_isHung(A_LoopField) {
|
||||
n += 1
|
||||
tiledWndIds .= A_LoopField ";"
|
||||
}
|
||||
|
@ -84,18 +162,36 @@ View_getTiledWndIds(m, v, ByRef tiledWndIds) {
|
|||
Return, n
|
||||
}
|
||||
|
||||
View_monocle(m, v, wndIds) {
|
||||
Local wndId0
|
||||
|
||||
StringTrimRight, wndIds, wndIds, 1
|
||||
View_updateLayout_(m, v)
|
||||
{
|
||||
View_#%m%_#%v%_layoutSymbol := "><>"
|
||||
}
|
||||
|
||||
View_arrange_(m, v)
|
||||
{
|
||||
; Place-holder
|
||||
}
|
||||
|
||||
View_updateLayout_monocle(m, v)
|
||||
{
|
||||
Local wndIds, wndId, wndId0
|
||||
StringTrimRight, wndIds, View_#%m%_#%v%_wndIds, 1
|
||||
StringSplit, wndId, wndIds, `;
|
||||
Loop, % wndId0
|
||||
Manager_winMove(wndId%A_Index%, Monitor_#%m%_x, Monitor_#%m%_y, Monitor_#%m%_width, Monitor_#%m%_height)
|
||||
View_#%m%_#%v%_layoutSymbol := "[" wndId0 "]"
|
||||
}
|
||||
|
||||
View_arrange_monocle(m, v, wndIds) {
|
||||
Local gw
|
||||
|
||||
gw := View_#%m%_#%v%_layoutGapWidth
|
||||
|
||||
StringTrimRight, wndIds, wndIds, 1
|
||||
StringSplit, View_arrange_monocle_wndId, wndIds, `;
|
||||
View_draw_stack("View_arrange_monocle_wndId", 1, View_arrange_monocle_wndId0, 0, Monitor_#%m%_x, Monitor_#%m%_y, Monitor_#%m%_width, Monitor_#%m%_height, gw/2)
|
||||
}
|
||||
|
||||
View_rotateLayoutAxis(i, d) {
|
||||
Local f, l, v
|
||||
Local f, l, v, n, tmp
|
||||
|
||||
v := Monitor_#%Manager_aMonitor%_aView_#1
|
||||
l := View_#%Manager_aMonitor%_#%v%_layout_#1
|
||||
|
@ -107,8 +203,16 @@ View_rotateLayoutAxis(i, d) {
|
|||
f := View_#%Manager_aMonitor%_#%v%_layoutAxis_#%i% / Abs(View_#%Manager_aMonitor%_#%v%_layoutAxis_#%i%)
|
||||
View_#%Manager_aMonitor%_#%v%_layoutAxis_#%i% := f * Manager_loop(Abs(View_#%Manager_aMonitor%_#%v%_layoutAxis_#%i%), d, 1, 2)
|
||||
}
|
||||
} Else
|
||||
View_#%Manager_aMonitor%_#%v%_layoutAxis_#%i% := Manager_loop(View_#%Manager_aMonitor%_#%v%_layoutAxis_#%i%, d, 1, 3)
|
||||
} Else {
|
||||
n := Manager_loop(View_#%Manager_aMonitor%_#%v%_layoutAxis_#%i%, d, 1, 3)
|
||||
; When we rotate the axis, we may need to swap the X and Y dimensions.
|
||||
If Not (n = View_#%Manager_aMonitor%_#%v%_layoutAxis_#%i%) And (n = 1) Or (View_#%Manager_aMonitor%_#%v%_layoutAxis_#%i% = 1) {
|
||||
tmp := View_#%Manager_aMonitor%_#%v%_layoutMX
|
||||
View_#%Manager_aMonitor%_#%v%_layoutMX := View_#%Manager_aMonitor%_#%v%_layoutMY
|
||||
View_#%Manager_aMonitor%_#%v%_layoutMY := tmp
|
||||
}
|
||||
View_#%Manager_aMonitor%_#%v%_layoutAxis_#%i% := n
|
||||
}
|
||||
View_arrange(Manager_aMonitor, v)
|
||||
}
|
||||
}
|
||||
|
@ -124,7 +228,7 @@ View_setGapWidth(d) {
|
|||
Else
|
||||
d := Ceil(d / 2) * 2
|
||||
w := View_#%Manager_aMonitor%_#%v%_layoutGapWidth + d
|
||||
If (w >= 0 And w < Monitor_#%Manager_aMonitor%_height And w < Monitor_#%Manager_aMonitor%_width) {
|
||||
If (w < Monitor_#%Manager_aMonitor%_height And w < Monitor_#%Manager_aMonitor%_width) {
|
||||
View_#%Manager_aMonitor%_#%v%_layoutGapWidth := w
|
||||
View_arrange(Manager_aMonitor, v)
|
||||
}
|
||||
|
@ -154,11 +258,7 @@ View_setMFactor(d) {
|
|||
v := Monitor_#%Manager_aMonitor%_aView_#1
|
||||
l := View_#%Manager_aMonitor%_#%v%_layout_#1
|
||||
If (Config_layoutFunction_#%l% = "tile") {
|
||||
mfact := 0
|
||||
If (d >= 1.05)
|
||||
mfact := d
|
||||
Else
|
||||
mfact := View_#%Manager_aMonitor%_#%v%_layoutMFact + d
|
||||
mfact := View_#%Manager_aMonitor%_#%v%_layoutMFact + d
|
||||
If (mfact >= 0.05 And mfact <= 0.95) {
|
||||
View_#%Manager_aMonitor%_#%v%_layoutMFact := mfact
|
||||
View_arrange(Manager_aMonitor, v)
|
||||
|
@ -166,15 +266,35 @@ View_setMFactor(d) {
|
|||
}
|
||||
}
|
||||
|
||||
View_setMSplit(d) {
|
||||
Local l, n, v, wndIds
|
||||
View_setMX(d) {
|
||||
Local l, n, m, v
|
||||
|
||||
v := Monitor_#%Manager_aMonitor%_aView_#1
|
||||
l := View_#%Manager_aMonitor%_#%v%_layout_#1
|
||||
If (Config_layoutFunction_#%l% = "tile") {
|
||||
n := View_getTiledWndIds(Manager_aMonitor, v, wndIds)
|
||||
View_#%Manager_aMonitor%_#%v%_layoutMSplit := Manager_loop(View_#%Manager_aMonitor%_#%v%_layoutMSplit, d, 1, n)
|
||||
View_arrange(Manager_aMonitor, v)
|
||||
m := Manager_aMonitor
|
||||
v := Monitor_#%m%_aView_#1
|
||||
l := View_#%m%_#%v%_layout_#1
|
||||
If Not (Config_layoutFunction_#%l% = "tile")
|
||||
Return
|
||||
|
||||
n := View_#%m%_#%v%_layoutMX + d
|
||||
If (n >= 1) And (n <= 9) {
|
||||
View_#%m%_#%v%_layoutMX := n
|
||||
View_arrange(m, v)
|
||||
}
|
||||
}
|
||||
|
||||
View_setMY(d) {
|
||||
Local l, n, m, v
|
||||
|
||||
m := Manager_aMonitor
|
||||
v := Monitor_#%m%_aView_#1
|
||||
l := View_#%m%_#%v%_layout_#1
|
||||
If Not (Config_layoutFunction_#%l% = "tile")
|
||||
Return
|
||||
|
||||
n := View_#%m%_#%v%_layoutMY + d
|
||||
If (n >= 1) And (n <= 9) {
|
||||
View_#%m%_#%v%_layoutMY := n
|
||||
View_arrange(m, v)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -219,117 +339,241 @@ View_shuffleWindow(d) {
|
|||
}
|
||||
}
|
||||
|
||||
View_tile(m, v, wndIds) {
|
||||
Local axis1, axis2, axis3, gapW, h1, h2, i, mfact, msplit, n1, n2, sym1, sym3, w1, w2, wndId0, x1, x2, y1, y2
|
||||
View_updateLayout_tile(m, v) {
|
||||
Local axis1, axis2, axis3, mp, ms, sym1, sym3, master_div, master_dim, master_sym, stack_sym
|
||||
|
||||
; Main axis
|
||||
; 1 - vertical divider, master left
|
||||
; 2 - horizontal divider, master top
|
||||
; -1 - vertical divider, master right
|
||||
; -2 - horizontal divider, master bottom
|
||||
axis1 := View_#%m%_#%v%_layoutAxis_#1
|
||||
; Master axis
|
||||
; 1 - vertical divider
|
||||
; 2 - horizontal divider
|
||||
; 3 - monocle
|
||||
axis2 := View_#%m%_#%v%_layoutAxis_#2
|
||||
; Stack axis
|
||||
; 1 - vertical divider
|
||||
; 2 - horizontal divider
|
||||
; 3 - monocle
|
||||
axis3 := View_#%m%_#%v%_layoutAxis_#3
|
||||
gapW := View_#%m%_#%v%_layoutGapWidth
|
||||
mfact := View_#%m%_#%v%_layoutMFact
|
||||
msplit := View_#%m%_#%v%_layoutMSplit
|
||||
mx := View_#%m%_#%v%_layoutMX
|
||||
my := View_#%m%_#%v%_layoutMY
|
||||
|
||||
If ( Abs(axis1) = 1 )
|
||||
master_div := "|"
|
||||
Else
|
||||
master_div := "="
|
||||
|
||||
If ( axis2 = 1 ) {
|
||||
master_sym := "|"
|
||||
master_dim := mx . "x" . my
|
||||
}
|
||||
Else If ( axis2 = 2 ) {
|
||||
master_sym := "-"
|
||||
master_dim := mx . "x" . my
|
||||
}
|
||||
Else
|
||||
master_sym := "[" . (mx * my) . "]"
|
||||
|
||||
If ( axis3 = 1 )
|
||||
stack_sym := "|"
|
||||
Else If ( axis3 = 2 )
|
||||
stack_sym := "-"
|
||||
Else
|
||||
stack_sym := "o"
|
||||
|
||||
If ( axis1 > 0 )
|
||||
View_#%m%_#%v%_layoutSymbol := master_dim . master_sym . master_div . stack_sym
|
||||
Else
|
||||
View_#%m%_#%v%_layoutSymbol := stack_sym . master_div . master_sym . master_dim
|
||||
}
|
||||
|
||||
; Stack a bunch of windows on top of each other.
|
||||
;
|
||||
; arrName - Name of a globally stored array of windows:
|
||||
; %arrName%1, %arrName%2, ...
|
||||
; off - Offset into the array from which to start drawing.
|
||||
; len - Number of windows from the array to draw.
|
||||
; dir - Determines the direction through which we traverse arrName
|
||||
; x - View x-position
|
||||
; y - View y-position
|
||||
; w - View width
|
||||
; h - View height
|
||||
; margin - Number of pixels to put between the windows.
|
||||
View_draw_stack( arrName, off, len, dir, x, y, w, h, margin ) {
|
||||
Local base, inc
|
||||
If (dir = 0) {
|
||||
base := off
|
||||
inc := 1
|
||||
}
|
||||
Else {
|
||||
base := off + len - 1
|
||||
inc := -1
|
||||
}
|
||||
x += margin
|
||||
y += margin
|
||||
w -= 2 * margin
|
||||
h -= 2 * margin
|
||||
|
||||
Loop, % len {
|
||||
Manager_winMove(%arrName%%base%, x, y, w, h)
|
||||
base += inc
|
||||
}
|
||||
}
|
||||
|
||||
; Draw a row of windows.
|
||||
;
|
||||
; arrName - Name of a globally stored array of windows:
|
||||
; %arrName%1, %arrName%2, ...
|
||||
; off - Offset into the array from which to start drawing.
|
||||
; len - Number of windows from the array to draw.
|
||||
; dir - Determines the direction through which we traverse arrName
|
||||
; axis - X/Y <=> 0/1
|
||||
; x - View x-position
|
||||
; y - View y-position
|
||||
; w - View width
|
||||
; h - View height
|
||||
; margin - Number of pixels to put between the windows.
|
||||
View_draw_row( arrName, off, len, dir, axis, x, y, w, h, margin ) {
|
||||
Local base, inc, x_inc, y_inc, wHeight, wWidth
|
||||
;Log_bare("View_draw_row(" . arrName . ", " . off . ", " . len . ", " . dir . ", " . axis . ", " . x . ", " . y . ", " . w . ", " . h . ", " . margin . ")")
|
||||
If (dir = 0) {
|
||||
; Left-to-right and top-to-bottom, depending on axis
|
||||
base := off
|
||||
inc := 1
|
||||
}
|
||||
Else {
|
||||
; Right-to-left and bottom-to-top, depending on axis
|
||||
base := off + len - 1
|
||||
inc := -1
|
||||
}
|
||||
If (axis = 0) {
|
||||
; Create row along X
|
||||
x_inc := w / len
|
||||
y_inc := 0
|
||||
wWidth := x_inc - 2 * margin
|
||||
wHeight := h - 2 * margin
|
||||
}
|
||||
Else {
|
||||
; Create row along Y
|
||||
x_inc := 0
|
||||
y_inc := h / len
|
||||
wWidth := w - 2 * margin
|
||||
wHeight := y_inc - 2 * margin
|
||||
}
|
||||
|
||||
; Set original positions with respect to the margins.
|
||||
x += margin
|
||||
y += margin
|
||||
|
||||
Loop, % len {
|
||||
Manager_winMove(%arrName%%base%, x, y, wWidth, wHeight)
|
||||
x += x_inc
|
||||
y += y_inc
|
||||
base += inc
|
||||
}
|
||||
}
|
||||
|
||||
View_arrange_tile_action(arrName, off, len, bugn_axis, x, y, w, h, m) {
|
||||
; 161 is a magic number determined somewhere. Maybe make this configurable.
|
||||
; Same with 2*Bar_height.
|
||||
If (bugn_axis = 3 Or (bugn_axis = 1 And w/len < 161) Or (bugn_axis = 2 And h/len < (2*Bar_height)))
|
||||
View_draw_stack(arrName, off, len, 0, x, y, w, h, m)
|
||||
Else
|
||||
View_draw_row(arrName, off, len, 0, bugn_axis - 1, x, y, w, h, m)
|
||||
}
|
||||
|
||||
View_split_region(axis, split_point, x, y, w, h, ByRef x1, ByRef y1, ByRef w1, ByRef h1, ByRef x2, ByRef y2, ByRef w2, ByRef h2) {
|
||||
x1 := x
|
||||
y1 := y
|
||||
If(axis = 0) {
|
||||
w1 := w * split_point
|
||||
w2 := w - w1
|
||||
h1 := h
|
||||
h2 := h
|
||||
x2 := x + w1
|
||||
y2 := y
|
||||
}
|
||||
Else
|
||||
{
|
||||
w1 := w
|
||||
w2 := w
|
||||
h1 := h * split_point
|
||||
h2 := h - h1
|
||||
x2 := x
|
||||
y2 := y + h1
|
||||
}
|
||||
}
|
||||
|
||||
View_arrange_tile(m, v, wndIds) {
|
||||
Local axis1, axis2, axis3, gapW_2, h1, h2, i, mfact, mp, ms, mx2, my2, mw2, mh2, msplit, n1, n2, w1, w2, x1, x2, y1, y2, flipped, stack_len, secondary_areas, areas_remaining, draw_windows
|
||||
|
||||
StringTrimRight, wndIds, wndIds, 1
|
||||
StringSplit, wndId, wndIds, `;
|
||||
If (msplit > wndId0) {
|
||||
If (wndId0 < 1)
|
||||
View_#%m%_#%v%_layoutMSplit := 1
|
||||
Else
|
||||
View_#%m%_#%v%_layoutMSplit := wndId0
|
||||
msplit := View_#%m%_#%v%_layoutMSplit
|
||||
StringSplit, View_arrange_tile_wndId, wndIds, `;
|
||||
Log_dbg_msg(1, "View_arrange_tile: (" . View_arrange_tile_wndId0 . ") " . wndIds)
|
||||
If (View_arrange_tile_wndId0 = 0)
|
||||
Return
|
||||
|
||||
axis1 := Abs(View_#%m%_#%v%_layoutAxis_#1)
|
||||
axis2 := View_#%m%_#%v%_layoutAxis_#2
|
||||
axis3 := View_#%m%_#%v%_layoutAxis_#3
|
||||
flipped := View_#%m%_#%v%_layoutAxis_#1 < 0
|
||||
gapW_2 := View_#%m%_#%v%_layoutGapWidth/2
|
||||
mfact := View_#%m%_#%v%_layoutMFact
|
||||
dimAligned := (axis2 = 1) ? View_#%m%_#%v%_layoutMX : View_#%m%_#%v%_layoutMY
|
||||
dimOrtho := (axis2 = 1) ? View_#%m%_#%v%_layoutMY : View_#%m%_#%v%_layoutMX
|
||||
msplit := dimAligned * dimOrtho
|
||||
|
||||
If (msplit > View_arrange_tile_wndId0) {
|
||||
msplit := View_arrange_tile_wndId0
|
||||
}
|
||||
|
||||
; layout symbol
|
||||
sym1 := "="
|
||||
If (axis2 = Abs(axis1))
|
||||
sym1 := "|"
|
||||
If (axis2 = 3)
|
||||
If (wndId0 = 0)
|
||||
sym1 := 0
|
||||
; master and stack area
|
||||
If( View_arrange_tile_wndId0 > msplit) {
|
||||
If( flipped = 0)
|
||||
View_split_region( axis1 - 1, mfact, Monitor_#%m%_x, Monitor_#%m%_y, Monitor_#%m%_width, Monitor_#%m%_height, x1, y1, w1, h1, x2, y2, w2, h2)
|
||||
Else
|
||||
sym1 := msplit
|
||||
sym3 := "="
|
||||
If (axis3 = Abs(axis1))
|
||||
sym3 := "|"
|
||||
If (axis3 = 3)
|
||||
If (wndId0 = 0)
|
||||
sym3 := 0
|
||||
Else
|
||||
sym3 := wndId0 - msplit
|
||||
If (axis1 < 0)
|
||||
If (msplit = 1)
|
||||
View_#%m%_#%v%_layoutSymbol := sym3 "[]"
|
||||
Else
|
||||
View_#%m%_#%v%_layoutSymbol := sym3 "[" sym1
|
||||
View_split_region( axis1 - 1, 1 - mfact, Monitor_#%m%_x, Monitor_#%m%_y, Monitor_#%m%_width, Monitor_#%m%_height, x2, y2, w2, h2, x1, y1, w1, h1)
|
||||
}
|
||||
Else {
|
||||
x1 := Monitor_#%m%_x
|
||||
y1 := Monitor_#%m%_y
|
||||
w1 := Monitor_#%m%_width
|
||||
h1 := Monitor_#%m%_height
|
||||
}
|
||||
|
||||
; master
|
||||
; Number
|
||||
If( axis2 = 3 )
|
||||
{
|
||||
View_draw_stack("View_arrange_tile_wndId", 1, msplit, 0, x1, y1, w1, h1, gapW_2)
|
||||
}
|
||||
Else
|
||||
If (msplit = 1)
|
||||
View_#%m%_#%v%_layoutSymbol := "[]" sym3
|
||||
Else
|
||||
View_#%m%_#%v%_layoutSymbol := sym1 "]" sym3
|
||||
|
||||
If (wndId0 > 0) {
|
||||
; master and stack area
|
||||
h1 := Monitor_#%m%_height - gapW
|
||||
h2 := Monitor_#%m%_height - gapW
|
||||
w1 := Monitor_#%m%_width - gapW
|
||||
w2 := Monitor_#%m%_width - gapW
|
||||
x1 := Monitor_#%m%_x + gapW / 2
|
||||
x2 := Monitor_#%m%_x + gapW / 2
|
||||
y1 := Monitor_#%m%_y + gapW / 2
|
||||
y2 := Monitor_#%m%_y + gapW / 2
|
||||
If (Abs(axis1) = 1 And wndId0 > msplit) {
|
||||
w1 *= mfact
|
||||
w2 -= w1
|
||||
If (axis1 < 0)
|
||||
x1 += w2
|
||||
Else
|
||||
x2 += w1
|
||||
} Else If (Abs(axis1) = 2 And wndId0 > msplit) {
|
||||
h1 *= mfact
|
||||
h2 -= h1
|
||||
If (axis1 < 0)
|
||||
y1 += h2
|
||||
Else
|
||||
y2 += h1
|
||||
}
|
||||
|
||||
; master
|
||||
If (axis2 != 1 Or w1 / msplit < 161)
|
||||
n1 := 1
|
||||
Else
|
||||
n1 := msplit
|
||||
If (axis2 != 2 Or h1 / msplit < Bar_height)
|
||||
n2 := 1
|
||||
Else
|
||||
n2 := msplit
|
||||
Loop, % msplit {
|
||||
Manager_winMove(wndId%A_Index%, x1 + gapW / 2, y1 + gapW / 2, w1 / n1 - gapW, h1 / n2 - gapW)
|
||||
If (n1 > 1)
|
||||
x1 += w1 / n1
|
||||
If (n2 > 1)
|
||||
y1 += h1 / n2
|
||||
}
|
||||
|
||||
; stack
|
||||
If (wndId0 > msplit) {
|
||||
If (axis3 != 1 Or w2 / (wndId0 - msplit) < 161)
|
||||
n1 := 1
|
||||
Else
|
||||
n1 := wndId0 - msplit
|
||||
If (axis3 != 2 Or h2 / (wndId0 - msplit) < Bar_height)
|
||||
n2 := 1
|
||||
Else
|
||||
n2 := wndId0 - msplit
|
||||
Loop, % wndId0 - msplit {
|
||||
i := msplit + A_Index
|
||||
Manager_winMove(wndId%i%, x2 + gapW / 2, y2 + gapW / 2, w2 / n1 - gapW, h2 / n2 - gapW)
|
||||
If (n1 > 1)
|
||||
x2 += w2 / n1
|
||||
If (n2 > 1)
|
||||
y2 += h2 / n2
|
||||
{
|
||||
secondary_areas := Ceil(msplit / dimAligned)
|
||||
areas_remaining := secondary_areas
|
||||
windows_remaining := msplit
|
||||
;Log_bare("msplit: " . msplit . "; layoutMX/Y: " . dimAligned . "; secondary_areas: " . secondary_areas . "; areas_remaining: " . areas_remaining . "; windows_remaining: " . windows_remaining)
|
||||
Loop, % secondary_areas {
|
||||
View_split_region(Not (axis2 - 1), (1/areas_remaining), x1, y1, w1, h1, mx1, my1, mw1, mh1, x1, y1, w1, h1)
|
||||
draw_windows := dimAligned
|
||||
If (windows_remaining < dimAligned) {
|
||||
draw_windows := windows_remaining
|
||||
}
|
||||
View_draw_row("View_arrange_tile_wndId", msplit - windows_remaining + 1, draw_windows, 0, axis2 - 1, mx1, my1, mw1, mh1, gapW_2)
|
||||
windows_remaining -= draw_windows
|
||||
areas_remaining -= 1
|
||||
}
|
||||
}
|
||||
|
||||
; stack
|
||||
If (View_arrange_tile_wndId0 <= msplit)
|
||||
Return
|
||||
|
||||
stack_len := View_arrange_tile_wndId0 - msplit
|
||||
View_arrange_tile_action("View_arrange_tile_wndId", msplit + 1, stack_len, axis3, x2, y2, w2, h2, gapW_2)
|
||||
}
|
||||
|
||||
View_toggleFloating() {
|
||||
|
|
|
@ -10,6 +10,23 @@
|
|||
(~) changed
|
||||
(+) added
|
||||
|
||||
=8.2.2(?)=
|
||||
|
||||
(+) Multi-dimensional tiling of the master area. The user may now specify
|
||||
X and Y dimensions independently up to 9 x 9.
|
||||
(+) Initially assign windows to the monitor on which they appear if
|
||||
nothing is specified in the configuration.
|
||||
(~) Improved view arranging runtime.
|
||||
(+) Created bug.n log to record major and debugging events.
|
||||
(~) Fixed bug #18641: Freezing problem. In most cases, bug.n will no
|
||||
longer hang when one of its managed windows hangs.
|
||||
(~) Fixed bug: Sometimes cycling through the windows in a view would
|
||||
get stuck on a particular window.
|
||||
(~) Fixed bug: Activating a window on a non-active view on
|
||||
a non-active monitor could cause both monitors to change views.
|
||||
(~) Gap widths are now treated identically on both "tile" and "monocle"
|
||||
layouts.
|
||||
|
||||
|
||||
=8.2.1=
|
||||
|
||||
|
|
|
@ -71,7 +71,7 @@ There are three layouts.
|
|||
A master area for the main window(s) and a stacking area for the rest,
|
||||
all windows are shown at any time. This layout can be further changed
|
||||
in the following respects:
|
||||
- the number of windows in the master area (1 ... all)
|
||||
- the dimensions of the master area (1x1 ... 9x9)
|
||||
- the stacking direction of the master and stacking area (from left to
|
||||
right, from top to bottom or monocle)
|
||||
- the position of the master area (left, top, right or bottom)
|
||||
|
|
|
@ -134,13 +134,21 @@ pressing the left Windows key and the shift key and the q key
|
|||
1 -> 2 = y-axis = vertical stack, 2 -> 3 = z-axis = monocle, only for
|
||||
the "tile" layout).
|
||||
|
||||
: #^Left::**View_setMSplit(+1)**
|
||||
Move the master splitter, i. e. decrease the number of windows in the
|
||||
master area (only for the "tile" layout).
|
||||
: #^Left::**View_setMX(-1)**
|
||||
Decrease the master X dimension by 1, i. e. decrease the number of
|
||||
windows in the master area by Y. Minimum of 1.
|
||||
|
||||
: #^Right::**View_setMSplit(-1)**
|
||||
Move the master splitter, i. e. increase the number of windows in the
|
||||
master area (only for the "tile" layout).
|
||||
: #^Right::**View_setMX(+1)
|
||||
Increase the master X dimension by 1, i. e. increase the number of
|
||||
windows in the master area by Y. Maximum of 9.
|
||||
|
||||
: #^Down::**View_setMY(-1)**
|
||||
Decrease the master Y dimension by 1, i.e. decrease the number of
|
||||
windows in the master area by X. Minimum of 1.
|
||||
|
||||
: #^Up::**View_setMY(+1)**
|
||||
Increase the master Y dimension by 1, i.e. increase the number of
|
||||
windows in the master area by X. Maximum of 9.
|
||||
|
||||
|
||||
=== Tag / View related hotkeys ===
|
||||
|
@ -197,6 +205,25 @@ pressing the left Windows key and the shift key and the q key
|
|||
Hide / Show the task bar.
|
||||
|
||||
|
||||
=== Logging/Debugging related hotkeys ===
|
||||
|
||||
: #^i::**Manager_logViewWindowList()**
|
||||
Dump the contents of the current view to the bug.n log.
|
||||
|
||||
: #+^i::**Manager_logManagedWindowList()**
|
||||
Dump the contents of the managed window list to the bug.n log.
|
||||
|
||||
: #^h::**Manager_logHelp()**
|
||||
Print to the log a description of the formatting used in the
|
||||
previous two log messages.
|
||||
|
||||
: #^[::**Log_decDebugLevel()**
|
||||
Decrement the debug log level. Show fewer debug messages.
|
||||
|
||||
: #^]::**Log_incDebugLevel()**
|
||||
Increment the debug log level. Show more debug messages.
|
||||
|
||||
|
||||
=== Application related hotkeys ===
|
||||
|
||||
: #y::**Bar_toggleCommandGui()**
|
||||
|
|
87
test/hang.cpp
Normal file
87
test/hang.cpp
Normal file
|
@ -0,0 +1,87 @@
|
|||
/**
|
||||
* Intended to be built with MinGW.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
|
||||
char *AppTitle="Win1";
|
||||
LRESULT CALLBACK WindowProc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam);
|
||||
|
||||
|
||||
int WinMain(HINSTANCE hInst,HINSTANCE,LPSTR,int nCmdShow)
|
||||
{
|
||||
WNDCLASS wc;
|
||||
HWND hwnd;
|
||||
MSG msg;
|
||||
|
||||
wc.style=CS_HREDRAW | CS_VREDRAW;
|
||||
wc.lpfnWndProc=WindowProc;
|
||||
wc.cbClsExtra=0;
|
||||
wc.cbWndExtra=0;
|
||||
wc.hInstance=hInst;
|
||||
wc.hIcon=LoadIcon(NULL,IDI_WINLOGO);
|
||||
wc.hCursor=LoadCursor(NULL,IDC_ARROW);
|
||||
wc.hbrBackground=(HBRUSH)COLOR_WINDOWFRAME;
|
||||
wc.lpszMenuName=NULL;
|
||||
wc.lpszClassName=AppTitle;
|
||||
|
||||
if (!RegisterClass(&wc))
|
||||
return 0;
|
||||
|
||||
hwnd = CreateWindow(AppTitle,AppTitle,
|
||||
WS_OVERLAPPEDWINDOW,
|
||||
CW_USEDEFAULT,CW_USEDEFAULT,100,100,
|
||||
NULL,NULL,hInst,NULL);
|
||||
|
||||
if (!hwnd)
|
||||
return 0;
|
||||
|
||||
ShowWindow(hwnd,nCmdShow);
|
||||
UpdateWindow(hwnd);
|
||||
|
||||
while (GetMessage(&msg,NULL,0,0) > 0)
|
||||
{
|
||||
TranslateMessage(&msg);
|
||||
DispatchMessage(&msg);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int maintain_bomb = 60;
|
||||
int activate_bomb = 5;
|
||||
|
||||
LRESULT CALLBACK WindowProc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam)
|
||||
{
|
||||
switch (msg)
|
||||
{
|
||||
case WM_PAINT:
|
||||
{
|
||||
PAINTSTRUCT ps;
|
||||
HDC dc;
|
||||
RECT r;
|
||||
GetClientRect(hwnd,&r);
|
||||
dc=BeginPaint(hwnd,&ps);
|
||||
DrawText(dc,"This window intentionally hangs",-1,&r,DT_SINGLELINE|DT_CENTER|DT_VCENTER);
|
||||
EndPaint(hwnd,&ps);
|
||||
break;
|
||||
}
|
||||
|
||||
case WM_DESTROY:
|
||||
PostQuitMessage(0);
|
||||
break;
|
||||
case WM_SHOWWINDOW:
|
||||
case WM_ACTIVATE:
|
||||
if(activate_bomb == 0)
|
||||
while(maintain_bomb) {
|
||||
Sleep(1000);
|
||||
maintain_bomb--;
|
||||
}
|
||||
activate_bomb--;
|
||||
|
||||
default:
|
||||
return DefWindowProc(hwnd, msg, wparam, lparam);
|
||||
}
|
||||
return 0;
|
||||
}
|
Loading…
Reference in a new issue