Skip to content

Commit a797d5a

Browse files
committed
Add more event hooks
1 parent ebf0f60 commit a797d5a

File tree

2 files changed

+117
-1
lines changed

2 files changed

+117
-1
lines changed

Flow.Launcher.Infrastructure/NativeMethods.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,3 +88,5 @@ BM_CLICK
8888
WM_GETTEXT
8989
OpenProcess
9090
QueryFullProcessImageName
91+
EVENT_OBJECT_HIDE
92+
EVENT_SYSTEM_DIALOGEND

Flow.Launcher.Infrastructure/QuickSwitch/QuickSwitch.cs

Lines changed: 115 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,10 +77,14 @@ public static class QuickSwitch
7777
private static HWINEVENTHOOK _foregroundChangeHook = HWINEVENTHOOK.Null;
7878
private static HWINEVENTHOOK _locationChangeHook = HWINEVENTHOOK.Null;
7979
private static HWINEVENTHOOK _destroyChangeHook = HWINEVENTHOOK.Null;
80+
private static HWINEVENTHOOK _hideChangeHook = HWINEVENTHOOK.Null;
81+
private static HWINEVENTHOOK _dialogEndChangeHook = HWINEVENTHOOK.Null;
8082

8183
private static readonly WINEVENTPROC _fgProc = ForegroundChangeCallback;
8284
private static readonly WINEVENTPROC _locProc = LocationChangeCallback;
8385
private static readonly WINEVENTPROC _desProc = DestroyChangeCallback;
86+
private static readonly WINEVENTPROC _hideProc = HideChangeCallback;
87+
private static readonly WINEVENTPROC _dialogEndProc = DialogEndChangeCallback;
8488

8589
private static DispatcherTimer _dragMoveTimer = null;
8690

@@ -166,6 +170,16 @@ public static void SetupQuickSwitch(bool enabled)
166170
PInvoke.UnhookWinEvent(_destroyChangeHook);
167171
_destroyChangeHook = HWINEVENTHOOK.Null;
168172
}
173+
if (!_hideChangeHook.IsNull)
174+
{
175+
PInvoke.UnhookWinEvent(_hideChangeHook);
176+
_hideChangeHook = HWINEVENTHOOK.Null;
177+
}
178+
if (!_dialogEndChangeHook.IsNull)
179+
{
180+
PInvoke.UnhookWinEvent(_dialogEndChangeHook);
181+
_dialogEndChangeHook = HWINEVENTHOOK.Null;
182+
}
169183

170184
// Hook events
171185
_foregroundChangeHook = PInvoke.SetWinEventHook(
@@ -192,10 +206,28 @@ public static void SetupQuickSwitch(bool enabled)
192206
0,
193207
0,
194208
PInvoke.WINEVENT_OUTOFCONTEXT);
209+
_hideChangeHook = PInvoke.SetWinEventHook(
210+
PInvoke.EVENT_OBJECT_HIDE,
211+
PInvoke.EVENT_OBJECT_HIDE,
212+
PInvoke.GetModuleHandle((PCWSTR)null),
213+
_hideProc,
214+
0,
215+
0,
216+
PInvoke.WINEVENT_OUTOFCONTEXT);
217+
_dialogEndChangeHook = PInvoke.SetWinEventHook(
218+
PInvoke.EVENT_SYSTEM_DIALOGEND,
219+
PInvoke.EVENT_SYSTEM_DIALOGEND,
220+
PInvoke.GetModuleHandle((PCWSTR)null),
221+
_dialogEndProc,
222+
0,
223+
0,
224+
PInvoke.WINEVENT_OUTOFCONTEXT);
195225

196226
if (_foregroundChangeHook.IsNull ||
197227
_locationChangeHook.IsNull ||
198-
_destroyChangeHook.IsNull)
228+
_destroyChangeHook.IsNull ||
229+
_hideChangeHook.IsNull ||
230+
_dialogEndChangeHook.IsNull)
199231
{
200232
Log.Error(ClassName, "Failed to enable QuickSwitch");
201233
return;
@@ -248,6 +280,16 @@ public static void SetupQuickSwitch(bool enabled)
248280
PInvoke.UnhookWinEvent(_destroyChangeHook);
249281
_destroyChangeHook = HWINEVENTHOOK.Null;
250282
}
283+
if (!_hideChangeHook.IsNull)
284+
{
285+
PInvoke.UnhookWinEvent(_hideChangeHook);
286+
_hideChangeHook = HWINEVENTHOOK.Null;
287+
}
288+
if (!_dialogEndChangeHook.IsNull)
289+
{
290+
PInvoke.UnhookWinEvent(_dialogEndChangeHook);
291+
_dialogEndChangeHook = HWINEVENTHOOK.Null;
292+
}
251293

252294
// Stop drag move timer
253295
_dragMoveTimer?.Stop();
@@ -640,6 +682,68 @@ uint dwmsEventTime
640682
}
641683
}
642684

685+
private static void HideChangeCallback(
686+
HWINEVENTHOOK hWinEventHook,
687+
uint eventType,
688+
HWND hwnd,
689+
int idObject,
690+
int idChild,
691+
uint dwEventThread,
692+
uint dwmsEventTime
693+
)
694+
{
695+
// If the dialog window is hidden, set _dialogWindowHandle to null
696+
var dialogWindowExist = false;
697+
lock (_dialogWindowLock)
698+
{
699+
if (_dialogWindow != null && _dialogWindow.Handle == hwnd)
700+
{
701+
Log.Debug(ClassName, $"Hide dialog: {hwnd}");
702+
_dialogWindow = null;
703+
dialogWindowExist = true;
704+
}
705+
}
706+
if (dialogWindowExist)
707+
{
708+
lock (_autoSwitchedDialogsLock)
709+
{
710+
_autoSwitchedDialogs.Remove(hwnd);
711+
}
712+
InvokeResetQuickSwitchWindow();
713+
}
714+
}
715+
716+
private static void DialogEndChangeCallback(
717+
HWINEVENTHOOK hWinEventHook,
718+
uint eventType,
719+
HWND hwnd,
720+
int idObject,
721+
int idChild,
722+
uint dwEventThread,
723+
uint dwmsEventTime
724+
)
725+
{
726+
// If the dialog window is ended, set _dialogWindowHandle to null
727+
var dialogWindowExist = false;
728+
lock (_dialogWindowLock)
729+
{
730+
if (_dialogWindow != null && _dialogWindow.Handle == hwnd)
731+
{
732+
Log.Debug(ClassName, $"Dialog end: {hwnd}");
733+
_dialogWindow = null;
734+
dialogWindowExist = true;
735+
}
736+
}
737+
if (dialogWindowExist)
738+
{
739+
lock (_autoSwitchedDialogsLock)
740+
{
741+
_autoSwitchedDialogs.Remove(hwnd);
742+
}
743+
InvokeResetQuickSwitchWindow();
744+
}
745+
}
746+
643747
#endregion
644748

645749
#endregion
@@ -892,6 +996,16 @@ public static void Dispose()
892996
PInvoke.UnhookWinEvent(_destroyChangeHook);
893997
_destroyChangeHook = HWINEVENTHOOK.Null;
894998
}
999+
if (!_hideChangeHook.IsNull)
1000+
{
1001+
PInvoke.UnhookWinEvent(_hideChangeHook);
1002+
_hideChangeHook = HWINEVENTHOOK.Null;
1003+
}
1004+
if (!_dialogEndChangeHook.IsNull)
1005+
{
1006+
PInvoke.UnhookWinEvent(_dialogEndChangeHook);
1007+
_dialogEndChangeHook = HWINEVENTHOOK.Null;
1008+
}
8951009

8961010
// Dispose explorers
8971011
foreach (var explorer in _quickSwitchExplorers.Keys)

0 commit comments

Comments
 (0)