Periodic state save and restore work

This commit is contained in:
Joshua Fuhs 2012-11-25 08:56:35 -05:00
parent be8533624e
commit af151b93a9
4 changed files with 418 additions and 125 deletions

View file

@ -96,8 +96,9 @@ Config_init() {
Config_autoSaveSession := False ; Automatically save the current state of monitors, views, layouts (active view, layout, axes, mfact and msplit) to the configuration file (set below) when quitting bug.n.
If Not Config_filePath ; The file path, to which the configuration and session is saved. This target directory must be writable by the user (%A_ScriptDir% is the diretory, in which "Main.ahk" or the executable of bug.n is saved).
Config_filePath := A_ScriptDir "\Config.ini"
Config_maintenanceInterval := 5000
Config_restore("Config")
Config_restoreConfig(Config_filePath)
Config_getSystemSettings()
Config_initColors()
Loop, % Config_layoutCount {
@ -281,96 +282,103 @@ Config_redirectHotkey(key) {
}
}
Config_restore(section, m = 0) {
Local cmd, i, key, type, val, var
Config_restoreLayout(filename, m) {
Local i, var, val
If Not FileExist(filename)
Return
If FileExist(Config_filePath) {
If (section = "Config") {
Loop, READ, %Config_filePath%
If (SubStr(A_LoopReadLine, 1, 7) = "Config_") {
i := InStr(A_LoopReadLine, "=")
var := SubStr(A_LoopReadLine, 1, i - 1)
val := SubStr(A_LoopReadLine, i + 1)
type := SubStr(var, 1, 13)
If (type = "Config_hotkey") {
i := InStr(val, "::")
key := SubStr(val, 1, i - 1)
cmd := SubStr(val, i + 2)
If Not cmd
Hotkey, %key%, Off
Else {
Config_hotkeyCount += 1
Config_hotkey_#%Config_hotkeyCount%_key := key
Config_hotkey_#%Config_hotkeyCount%_command := cmd
Hotkey, %key%, Config_hotkeyLabel
}
} Else If (type = "Config_rule") {
i := 0
If InStr(var, "Config_rule_#")
i := SubStr(var, 14)
If (i = 0 Or i > Config_ruleCount) {
Config_ruleCount += 1
i := Config_ruleCount
}
var := "Config_rule_#" i
}
%var% := val
}
} Else If (section = "Monitor") {
Loop, READ, %Config_filePath%
If (SubStr(A_LoopReadLine, 1, 10 + StrLen(m)) = "Monitor_#" m "_" Or SubStr(A_LoopReadLine, 1, 8 + StrLen(m)) = "View_#" m "_#") {
i := InStr(A_LoopReadLine, "=")
var := SubStr(A_LoopReadLine, 1, i - 1)
val := SubStr(A_LoopReadLine, i + 1)
%var% := val
}
Loop, READ, %filename%
If (SubStr(A_LoopReadLine, 1, 10 + StrLen(m)) = "Monitor_#" m "_" Or SubStr(A_LoopReadLine, 1, 8 + StrLen(m)) = "View_#" m "_#") {
i := InStr(A_LoopReadLine, "=")
var := SubStr(A_LoopReadLine, 1, i - 1)
val := SubStr(A_LoopReadLine, i + 1)
%var% := val
}
}
}
Config_saveSession() {
Local m, text
Config_restoreConfig(filename) {
Local cmd, i, key, type, val, var
If Not FileExist(filename)
Return
Loop, READ, %filename%
If (SubStr(A_LoopReadLine, 1, 7) = "Config_") {
Log_msg("Processing line: " . A_LoopReadLine)
i := InStr(A_LoopReadLine, "=")
var := SubStr(A_LoopReadLine, 1, i - 1)
val := SubStr(A_LoopReadLine, i + 1)
type := SubStr(var, 1, 13)
If (type = "Config_hotkey") {
i := InStr(val, "::")
key := SubStr(val, 1, i - 1)
cmd := SubStr(val, i + 2)
If Not cmd
Hotkey, %key%, Off
Else {
Config_hotkeyCount += 1
Config_hotkey_#%Config_hotkeyCount%_key := key
Config_hotkey_#%Config_hotkeyCount%_command := cmd
Hotkey, %key%, Config_hotkeyLabel
}
} Else If (type = "Config_rule") {
i := 0
If InStr(var, "Config_rule_#")
i := SubStr(var, 14)
If (i = 0 Or i > Config_ruleCount) {
Config_ruleCount += 1
i := Config_ruleCount
}
var := "Config_rule_#" i
}
%var% := val
}
}
Config_UI_saveSession() {
Config_saveSession(Config_filePath)
}
Config_saveSession(filename) {
Local m, text, tmpfilename
tmpfilename := filename . ".tmp"
FileDelete, %tmpfilename%
text := "; bug.n - tiling window management`n; @version " VERSION "`n`n"
If FileExist(Config_filePath) {
Loop, READ, %Config_filePath%
If FileExist(filename) {
Loop, READ, %filename%
If (SubStr(A_LoopReadLine, 1, 7) = "Config_")
text .= A_LoopReadLine "`n"
text .= "`n"
}
FileDelete, %Config_filePath%
Loop, % Manager_monitorCount {
m := A_Index
If Not (Monitor_#%m%_aView_#1 = 1)
text .= "Monitor_#" m "_aView_#1=" Monitor_#%m%_aView_#1 "`n"
If Not (Monitor_#%m%_aView_#2 = 1)
text .= "Monitor_#" m "_aView_#2=" Monitor_#%m%_aView_#2 "`n"
If Not (Monitor_#%m%_showBar = Config_showBar)
text .= "Monitor_#" m "_showBar=" Monitor_#%m%_showBar "`n"
text .= "Monitor_#" m "_aView_#1=" Monitor_#%m%_aView_#1 "`n"
text .= "Monitor_#" m "_aView_#2=" Monitor_#%m%_aView_#2 "`n"
text .= "Monitor_#" m "_showBar=" Monitor_#%m%_showBar "`n"
Loop, % Config_viewCount {
If Not (View_#%m%_#%A_Index%_layout_#1 = 1)
text .= "View_#" m "_#" A_Index "_layout_#1=" View_#%m%_#%A_Index%_layout_#1 "`n"
If Not (View_#%m%_#%A_Index%_layout_#2 = 1)
text .= "View_#" m "_#" A_Index "_layout_#2=" View_#%m%_#%A_Index%_layout_#2 "`n"
If Not (View_#%m%_#%A_Index%_layoutAxis_#1 = Config_layoutAxis_#1)
text .= "View_#" m "_#" A_Index "_layoutAxis_#1=" View_#%m%_#%A_Index%_layoutAxis_#1 "`n"
If Not (View_#%m%_#%A_Index%_layoutAxis_#2 = Config_layoutAxis_#2)
text .= "View_#" m "_#" A_Index "_layoutAxis_#2=" View_#%m%_#%A_Index%_layoutAxis_#2 "`n"
If Not (View_#%m%_#%A_Index%_layoutAxis_#3 = Config_layoutAxis_#3)
text .= "View_#" m "_#" A_Index "_layoutAxis_#3=" View_#%m%_#%A_Index%_layoutAxis_#3 "`n"
If Not (View_#%m%_#%A_Index%_layoutGapWidth = Config_layoutGapWidth)
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%_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"
text .= "View_#" m "_#" A_Index "_layout_#1=" View_#%m%_#%A_Index%_layout_#1 "`n"
text .= "View_#" m "_#" A_Index "_layout_#2=" View_#%m%_#%A_Index%_layout_#2 "`n"
text .= "View_#" m "_#" A_Index "_layoutAxis_#1=" View_#%m%_#%A_Index%_layoutAxis_#1 "`n"
text .= "View_#" m "_#" A_Index "_layoutAxis_#2=" View_#%m%_#%A_Index%_layoutAxis_#2 "`n"
text .= "View_#" m "_#" A_Index "_layoutAxis_#3=" View_#%m%_#%A_Index%_layoutAxis_#3 "`n"
text .= "View_#" m "_#" A_Index "_layoutGapWidth=" View_#%m%_#%A_Index%_layoutGapWidth "`n"
text .= "View_#" m "_#" A_Index "_layoutMFact=" View_#%m%_#%A_Index%_layoutMFact "`n"
text .= "View_#" m "_#" A_Index "_layoutMX=" View_#%m%_#%A_Index%_layoutMX "`n"
text .= "View_#" m "_#" A_Index "_layoutMY=" View_#%m%_#%A_Index%_layoutMY "`n"
}
}
FileAppend, %text%, %Config_filePath%
FileAppend, %text%, %tmpfilename%
If ErrorLevel {
If FileExist(tmpfilename)
FileDelete, %tmpfilename%
}
Else
FileMove, %tmpfilename%, %filename%, 1
}
/**
@ -457,7 +465,7 @@ Config_saveSession() {
#Space::Monitor_toggleTaskBar() ; Hide / Show the task bar.
#y::Bar_toggleCommandGui() ; Open the command GUI for executing programmes or bug.n functions.
#^e::Run, edit %Config_filePath% ; Open the configuration file in the standard text editor.
#^s::Config_saveSession() ; Save the current state of monitors, views, layouts to the configuration file.
#^s::Config_UI_saveSession() ; Save the current state of monitors, views, layouts to the configuration file.
#^r::Main_reload() ; Reload bug.n (i. e. the configuration and its dependent settings) without deleting the window lists of bug.n and restoring windows.
; It does not reset internal configuration variables, the tray icon or menu, hotkeys (unless set explicitly in Config.ini), individual window settings like Config_showBorder (since windows might be hidden) or hiding the title bar, the monitor count or views.
; It does not reload functions. Changed rules are only applied to new windows.

View file

@ -33,20 +33,9 @@ SetWinDelay, 10
; pseudo main function
Main_setup()
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_init(Main_logFile, False)
Log_msg("====== Initializing ======")
If 0 = 1
@ -71,7 +60,7 @@ Return ; end of the auto-execute section
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()
Config_saveSession(Config_filePath)
Manager_cleanup()
DllCall("CloseHandle", "UInt", Bar_hDrive) ; used in Bar_getDiskLoad
ExitApp
@ -84,6 +73,49 @@ Main_quit:
ExitApp
Return
; Create bug.n-specific directories.
Main_makeDir(dirName) {
IfNotExist, %dirName%
{
FileCreateDir, %dirName%
If ErrorLevel {
MsgBox, Error (%ErrorLevel%) when creating '%dirName%'. Aborting.
ExitApp
}
}
Else {
FileGetAttrib, attrib, %dirName%
IfNotInString, attrib, D
{
MsgBox, The file path '%dirName%' already exists and is not a directory. Aborting.
ExitApp
}
}
}
Main_setup() {
Local winAppDir
Main_appDir := ""
Main_logFile := ""
Main_dataDir := ""
Main_autoLayout := ""
Main_autoWindowState := ""
EnvGet, winAppDir, APPDATA
Main_appDir := winAppDir . "\bug.n"
Main_logFile := Main_appDir . "\bugn_log.txt"
Main_dataDir := Main_appDir . "\data"
Main_autoLayout := Main_dataDir . "\_Layout.ini"
Main_autoWindowState := Main_dataDir . "\_WindowState.ini"
Main_makeDir(Main_appDir)
Main_makeDir(Main_dataDir)
}
Main_reload() {
Local i, ncm, ncmSize

View file

@ -42,6 +42,10 @@ Manager_init() {
}
Bar_getHeight()
; axes, dimensions, percentage, flipped, gapWidth
Manager_layoutDirty := 0
; New/closed windows, active changed,
Manager_windowsDirty := 0
Manager_aMonitor := 1
Manager_taskBarMonitor := ""
Manager_showTaskBar := True
@ -67,9 +71,41 @@ Manager_init() {
}
Manager_registerShellHook()
SetTimer, Manager_maintenance_label, %Config_maintenanceInterval%
SetTimer, Bar_loop, %Config_readinInterval%
}
; Asynchronous management of various WM properties.
; We want to make sure that we can recover the layout and windows in the event of
; unexpected problems.
; Periodically check for changes to these things and save them somewhere (not over
; user-defined files).
Manager_maintenance_label:
Manager_maintenance()
Return
Manager_maintenance() {
Local tmp
;Log_dbg_msg(2, "Manager_maintenance")
; @todo: Check for changes to the layout.
;If Manager_layoutDirty {
;Log_msg("Saving layout state: " . Main_autoLayout)
Config_saveSession(Main_autoLayout)
Manager_layoutDirty := 0
;}
; @todo: Manager_sync
; @todo: Check for changes to windows.
;If Manager_windowsDirty {
;Log_msg("Saving window state: " . Main_autoWindowState)
Manager_saveWindowState(Main_autoWindowState, Manager_monitorCount, Config_viewCount)
Manager_windowsDirty := 0
;}
}
Manager_activateMonitor(d) {
Local aView, aWndClass, aWndHeight, aWndId, aWndWidth, aWndX, aWndY, v, wndId
@ -361,6 +397,42 @@ Manager_loop(index, increment, lowerBound, upperBound) {
Return, index
}
Manager__setWinProperties(wndId, isManaged, m, tags, isDecorated, isFloating, hideTitle ) {
Local a
If Not Instr(Manager_allWndIds, wndId ";")
Manager_allWndIds .= wndId ";"
If (isManaged) {
Manager_managedWndIds .= wndId ";"
Monitor_moveWindow(m, wndId)
Manager_#%wndId%_tags := tags
Manager_#%wndId%_isDecorated := isDecorated
Manager_#%wndId%_isFloating := isFloating
If Not Config_showBorder
Manager_winSet("Style", "-0x40000", wndId)
If Not Manager_#%wndId%_isDecorated
Manager_winSet("Style", "-0xC00000", wndId)
a := Manager_#%wndId%_tags & (1 << (Monitor_#%m%_aView_#1 - 1))
If a {
Manager_aMonitor := m
Manager_winActivate(wndId)
} Else {
Manager_hideShow := True
Manager_winHide(wndId)
Manager_hideShow := False
}
}
If hideTitle
Bar_hideTitleWndIds .= wndId . ";"
Return, a
}
; 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
@ -370,8 +442,10 @@ 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 ";"
; Manage any window only once.
If InStr(Manager_managedWndIds, wndId ";")
Return
body := 0
If Manager_isGhost( wndId ) {
@ -406,6 +480,7 @@ Manager_manage(pm, pv, wndId) {
tags := 1 << (pv - 1)
}
; @todo: Remove this application-specific code.
WinGet, wndProcessName, ProcessName, ahk_id %wndId%
If (wndProcessName = "chrome.exe") {
WinGet, wndControlList, ControlList, ahk_id %wndId%
@ -414,17 +489,12 @@ Manager_manage(pm, pv, wndId) {
isManaged := False
}
a := Manager__setWinProperties( wndId, isManaged, m, tags, isDecorated, isFloating, hideTitle)
; Do view placement.
If isManaged {
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) {
If (Manager_#%wndId%_tags & (1 << (A_Index - 1))) {
If (body) {
; Try to position near the body.
View_ghostWnd(m, A_Index, body, wndId)
@ -433,28 +503,8 @@ Manager_manage(pm, pv, wndId) {
View_addWnd(m, A_Index, wndId)
}
}
If Not Config_showBorder
Manager_winSet("Style", "-0x40000", wndId)
If Not Manager_#%wndId%_isDecorated
Manager_winSet("Style", "-0xC00000", wndId)
a := Manager_#%wndId%_tags & 1 << Monitor_#%m%_aView_#1 - 1
If a {
Manager_aMonitor := m
Manager_winActivate(wndId)
} Else {
Manager_hideShow := True
Manager_winHide(wndId)
Manager_hideShow := False
}
}
If hideTitle And Not InStr(Bar_hideTitleWndIds, wndId)
Bar_hideTitleWndIds .= wndId . ";"
Else If Not hideTitle
StringReplace, Bar_hideTitleWndIds, Bar_hideTitleWndIds, %wndId%`;,
Return, a
}
@ -524,6 +574,7 @@ WINDOW_NOTICE := 32774
; 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
; Windows events can't always be caught.
;
Manager_onShellMessage(wParam, lParam) {
Local a, isChanged, aWndClass, aWndHeight, aWndId, aWndTitle, aWndWidth, aWndX, aWndY, m, t, wndClass, wndId, wndIds, wndPName, wndTitle, x, y
@ -558,6 +609,13 @@ Manager_onShellMessage(wParam, lParam) {
; Window recovered from being hung. Maybe force a redraw.
}
; @todo: There are two problems with the use of Manager_hideShow:
; 1) If Manager_hideShow is set when we hit this block, we won't take some actions that should eventually be taken.
; This _may_ explain why some windows never get picked up when spamming Win+e
; 2) There is a race condition between the time that Manager_hideShow is checked and any other action which we are
; trying to protect against. If another process (hotkey) enters a hideShow block after Manager_hideShow has
; been checked here, bad things could happen. I've personally observed that windows may be permanently hidden.
; Look into the use of AHK synchronization primitives.
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) {
@ -703,6 +761,8 @@ Manager_sizeWindow() {
SendMessage, WM_SYSCOMMAND, SC_SIZE, , , ahk_id %aWndId%
}
; @todo: This constantly tries to re-add windows that are never going to be manageable.
; Manager_manage should probably ignore all windows that are already in Manager_allWndIds.
Manager_sync(ByRef wndIds = "") {
Local a, flag, shownWndIds, v, visibleWndIds, wndId
@ -727,6 +787,7 @@ Manager_sync(ByRef wndIds = "") {
visibleWndIds := visibleWndIds wndId%A_Index% ";"
}
; @todo-future: Find out why this unmanage code exists and if it's still needed.
; check, if a window, that is known to be visible, is actually not visible
StringTrimRight, shownWndIds, shownWndIds, 1
Loop, PARSE, shownWndIds, `;
@ -741,6 +802,189 @@ Manager_sync(ByRef wndIds = "") {
Return, a
}
Manager_saveWindowState(filename, nm, nv) {
Local allWndId, allWndIds, process, title, text, monitor, wndId, view, isManaged, isTitleHidden
text := "; bug.n - tiling window management`n; @version " VERSION "`n`n"
tmpfname := filename . ".tmp"
FileDelete, %tmpfname%
; Dump window ID and process name. If these two don't match an existing process, we won't try
; to recover that window.
StringTrimRight, allWndIds, Manager_allWndIds, 1
StringSplit, allWndId, allWndIds, `;
DetectHiddenWindows, On
Loop, % allWndId0 {
wndId := allWndId%A_Index%
WinGet, process, ProcessName, ahk_id %wndId%
; Include title for informative reasons.
WinGetTitle, title, ahk_id %wndId%
; wndId;process;Tags;Floating;Decorated;HideTitle;Managed;Title
If ( InStr(Manager_managedWndIds, wndId . ";") > 0 ) {
isManaged := 1
}
else {
isManaged := 0
}
If ( InStr(Bar_hideTitleWndIds, wndId . ";") > 0 )
isTitleHidden := 1
Else
isTitleHidden := 0
text .= "Window " . wndId . ";" . process . ";" . Manager_#%wndId%_monitor . ";" . Manager_#%wndId%_tags . ";" . Manager_#%wndId%_isFloating . ";" . Manager_#%wndId%_isDecorated . ";" . isTitleHidden . ";" . isManaged . ";" . title . "`n"
}
DetectHiddenWindows, Off
text .= "`n"
; @todo: Dump window arrangements on every view. If some views or monitors have disappeared, leave their
; corresponding windows alone.
Loop, % nm {
monitor := A_Index
Loop, % nv {
view := A_Index
; @todo: Dump all view window lists
text .= "View_#" . monitor . "_#" . view . "_wndIds=" . View_#%monitor%_#%view%_wndIds . "`n"
}
}
FileAppend, %text%, %tmpfname%
If ErrorLevel {
If FileExist(tmpfname)
FileDelete, %tmpfname%
}
Else
FileMove, %tmpfname%, %filename%, 1
}
; Restore previously saved window state.
; If the state is completely different, this function won't do much. However, if restoring from a crash
; or simply restarting bug.n, it should completely recover the window state.
Manager__restoreWindowState(filename) {
Local vidx, widx, i, j, m, v, candidate_set, view_set, excluded_view_set, view_m0, view_v0, view_list0, wnds0, items0, wndProc, view_var, isManaged, isFloating, isDecorated, hideTitle
If Not FileExist(filename)
Return
widx := 1
vidx := 1
view_set := ""
excluded_view_set := ""
; Read all interesting things from the file.
Loop, READ, %filename%
If (SubStr(A_LoopReadLine, 1, 5) = "View_") {
i := InStr(A_LoopReadLine, "#")
j := InStr(A_LoopReadLine, "_", false, i)
m := SubStr(A_LoopReadLine, i + 1, j - i - 1)
i := InStr(A_LoopReadLine, "#", false, j)
j := InStr(A_LoopReadLine, "_", false, i)
v := SubStr(A_LoopReadLine, i + 1, j - i - 1)
i := InStr(A_LoopReadLine, "=", j + 1)
If (m <= Manager_monitorCount) And ( v <= Config_viewCount ) {
view_list%vidx% := SubStr(A_LoopReadLine, i + 1)
view_m%vidx% := m
view_v%vidx% := v
view_set := view_set . view_list%vidx%
vidx := vidx + 1
}
Else {
excluded_view_set := excluded_view_set . view_list%vidx%
Log_msg("View (" . m . ", " . v . ") is no longer available (" . vidx . ")")
}
}
Else If (SubStr(A_LoopReadLine, 1, 7) = "Window ") {
wnds%widx% := SubStr(A_LoopReadLine, 8)
widx := widx + 1
}
;Log_msg("view_set: " . view_set)
;Log_msg("excluded_view_set: " . excluded_view_set)
candidate_set := List_new()
; Scan through all defined windows. Create a candidate set of windows based on whether the properties of existing windows match.
Loop, % (widx - 1) {
StringSplit, items, wnds%A_Index%, `;
If ( items0 < 9 ) {
Log_msg("Window '" . wnds%A_Index% . "' could not be processed due to parse error")
Continue
}
i := 1
i := items%i%
j := 2
DetectHiddenWindows, On
WinGet, wndProc, ProcessName, ahk_id %i%
DetectHiddenWindows, Off
If Not ( items%j% = wndProc ) {
Log_msg("Window ahk_id " . i . " process '" . wndProc . "' doesn't match expected '" . items%j% . "', forgetting this window")
Continue
}
j := 8
isManaged := items%j%
; If Managed
If ( items%j% )
If ( InStr(view_set, i) = 0) {
If ( InStr(excluded_view_set, i) ) {
Log_msg("Window ahk_id " . i . " is being ignored because it no longer belongs to an active view")
}
Else {
Log_msg("Window ahk_id " . i . " is being ignored because it doesn't exist in any views")
}
Continue
}
; Set up the window.
j := 3
m := items%j%
j := 4
v := items%j%
j := 5
isFloating := items%j%
j := 6
isDecorated := items%j%
j := 7
hideTitle := items%j%
Manager__setWinProperties(i, isManaged, m, v, isDecorated, isFloating, hideTitle )
;Manager_winHide(i)
List_append(candidate_set, i)
}
;Log_msg("candidate_set: " . candidate_set)
; Set up all views. Must filter the window list by those from the candidate set.
Loop, % (vidx - 1) {
StringSplit, items, view_list%A_Index%, `;
view_set := ""
Loop, % items0 - 1 {
If ( InStr(candidate_set, items%A_Index% ) > 0 )
view_set := view_set . items%A_Index% . ";"
}
view_var := "View_#" . view_m%A_Index% . "_#" . view_v%A_Index% . "_wndIds"
%view_var% := view_set
}
}
; No windows are known to the system yet.
; Try to do something smart with the initial layout.
Manager_initial_sync() {
@ -751,9 +995,14 @@ Manager_initial_sync() {
Loop, % Manager_monitorCount
Manager_initial_sync_m#%A_Index%_wndList := List_new()
; check all visible windows against the known windows
; Use saved window placement settings to first determine
; which monitor/view a window should be attached to.
Manager__restoreWindowState(Main_autoWindowState)
; check all remaining 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.
@ -769,8 +1018,8 @@ Manager_initial_sync() {
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)
; @todo-future: What percentage of the monitor area is it occupying? (Suggest layout)
; @todo-future: What part of the monitor is it on? (Ordering of windows)
}
Loop, % Manager_monitorCount {
@ -795,6 +1044,8 @@ Manager_toggleDecor() {
Manager_unmanage(wndId) {
Local a
; Do our best to make sure that any unmanaged windows are left visible.
Manager_winShow(wndId)
a := Manager_#%wndId%_tags & 1 << Monitor_#%Manager_aMonitor%_aView_#1 - 1
Loop, % Config_viewCount
If (Manager_#%wndId%_tags & 1 << A_Index - 1) {
@ -887,6 +1138,8 @@ Manager_winClose(wndId) {
Return 1
}
Else {
; @todo: Identify the next active window, activate it, then close the window to
; be closed.
WinClose, ahk_id %wndId%
Return 0
}
@ -908,7 +1161,7 @@ Manager_winSet(type, value, wndId) {
; 1 - Hung
Manager_isHung(wndId) {
Local result, detect_setting, WM_NULL
WM_NULL := 0
WM_NULL = 0
detect_setting := A_DetectHiddenWindows
DetectHiddenWindows, On
SendMessage, WM_NULL, , , , ahk_id %wndId%

View file

@ -26,7 +26,7 @@ Monitor_init(m) {
Monitor_#%m%_showBar := Config_showBar
Loop, % Config_viewCount
View_init(m, A_Index)
Config_restore("Monitor", m)
Config_restoreLayout(Main_autoLayout, m)
Monitor_getWorkArea(m)
Bar_init(m)
}