From 7517f6f3bafdfe4ac898cd2d8e834a8772f9defd Mon Sep 17 00:00:00 2001 From: imawizard Date: Wed, 10 Apr 2024 18:48:40 +0200 Subject: [PATCH 1/2] feat: Add config for which window to focus on close When the active window was closed, this setting decides which window is then to be focused (so kind of like the opposite of tilingInsertion). --- lib/miguru/miguru.ahk | 24 +++++++++++++++++++++--- lib/miguru/workspaces.ahk | 6 ++++++ 2 files changed, 27 insertions(+), 3 deletions(-) diff --git a/lib/miguru/miguru.ahk b/lib/miguru/miguru.ahk index 2ef8d7c..b52f332 100644 --- a/lib/miguru/miguru.ahk +++ b/lib/miguru/miguru.ahk @@ -68,6 +68,7 @@ class MiguruWM extends WMEvents { tilingMinWidth: 500, tilingMinHeight: 500, tilingInsertion: "last", + focusAfterClose: "previous", floatingAlwaysOnTop: false, focusFollowsMouse: false, @@ -142,6 +143,12 @@ class MiguruWM extends WMEvents { "first", "last", ) + ExpectInSet(o, "focusAfterClose", + "previous", + "next", + "first", + "last", + ) ExpectInSet(o, "floatingAlwaysOnTop", true, false) ExpectInSet(o, "focusFollowsMouse", true, false) ExpectInSet(o, "mouseFollowsFocus", true, false) @@ -1069,9 +1076,20 @@ class MiguruWM extends WMEvents { ;; Because of the focus-switch the destroyed window is not the ;; active one anymore and Remove() won't return a window that were ;; to be activated. - next := window.workspace.Remove(hwnd) - if next && window.workspace.Index == this.activeWsIdx { - this._focusWindow(next, false) + ws := window.workspace + if ws.ActiveWindow == hwnd { + wasActive := true + next := ws.GetWindow(this._opts.focusAfterClose, hwnd) + } else { + wasActive := false + } + ws.Remove(hwnd) + if wasActive { + if ws.Index == this.activeWsIdx { + this._focusWindow(next, false) + } else { + ws.ActiveWindow := next + } } } else { this._unpinWindow(hwnd, window) diff --git a/lib/miguru/workspaces.ahk b/lib/miguru/workspaces.ahk index e78b26d..67b8d94 100644 --- a/lib/miguru/workspaces.ahk +++ b/lib/miguru/workspaces.ahk @@ -334,6 +334,12 @@ class WorkspaceList { return this._nextWindow(hwnd) case "previous": return this._previousWindow(hwnd) + case "first": + return this._tiled.First ? this._tiled.First.data + : this._floating.Get(1, "") + case "last": + first := this._tiled.First ? this._tiled.First.data : "" + return this._previousWindow(first) case "": return hwnd default: From f56fd20e467187c56eccfff23864480a8606d48f Mon Sep 17 00:00:00 2001 From: imawizard Date: Wed, 10 Apr 2024 18:51:25 +0200 Subject: [PATCH 2/2] fix: Possibly still treat as active after hide-close sequence MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit There seem to be cases where – when closing e.g. an active explorer window – a "hidden" event occurs first, then a "focus" event according to z-order and eventually a "destroyed" event. Because of the focus-switch in between the destroyed window is not the active one anymore and no window is actively set as the new active one with respects to focusAfterClose. This commit adds remembering a hidden window if it was active, and in case said window gets closed within a specific duration after being hidden, it'll be treated as a regular close event of the active window. --- lib/miguru/miguru.ahk | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/lib/miguru/miguru.ahk b/lib/miguru/miguru.ahk index b52f332..23d7a01 100644 --- a/lib/miguru/miguru.ahk +++ b/lib/miguru/miguru.ahk @@ -97,6 +97,7 @@ class MiguruWM extends WMEvents { sendMonitorRetile: 100, pinnedWindowFocused: 100, onDisplayChange: 1000, + hideCloseSequence: 200, }, }, opts) @@ -112,6 +113,7 @@ class MiguruWM extends WMEvents { this._delayed := Timeouts() this._maybeActiveWindow := "" + this._maybeClosed := {hwnd: 0, ticks: 0} this._focusIndicator.SetMonitorList(this._monitors) windowTracking := GetSpiInt(SPI_GETACTIVEWINDOWTRACKING) @@ -1070,14 +1072,9 @@ class MiguruWM extends WMEvents { window := this._managed.Delete(hwnd) if !this._pinned.Has(hwnd) { - ;; FIXME: There seems to be cases where – when closing e.g. an - ;; explorer window – a "hidden" event occurs first, then a "focus" - ;; event according to z-order and lastly a "destroyed" event. - ;; Because of the focus-switch the destroyed window is not the - ;; active one anymore and Remove() won't return a window that were - ;; to be activated. ws := window.workspace - if ws.ActiveWindow == hwnd { + if ws.ActiveWindow == hwnd || this._maybeClosed.hwnd == hwnd + && A_TickCount - this._maybeClosed.ticks <= this._delays.hideCloseSequence { wasActive := true next := ws.GetWindow(this._opts.focusAfterClose, hwnd) } else { @@ -1129,7 +1126,15 @@ class MiguruWM extends WMEvents { return } + window := this._managed[hwnd] + if wait { + if window.workspace.ActiveWindow == hwnd { + this._maybeClosed := { + hwnd: hwnd, + ticks: A_TickCount, + } + } this._delayed.Replace( this._hide.Bind(this, event, hwnd, false), this._delays.windowHidden, @@ -1138,7 +1143,6 @@ class MiguruWM extends WMEvents { return } - window := this._managed[hwnd] if !this._pinned.Has(hwnd) { window.workspace.Remove(hwnd) } else {