Skip to content

Commit f73e768

Browse files
committed
Use hook to check timer
1 parent 5ae1c4b commit f73e768

File tree

1 file changed

+54
-35
lines changed

1 file changed

+54
-35
lines changed

Flow.Launcher.Infrastructure/QuickSwitch/QuickSwitch.cs

Lines changed: 54 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -39,32 +39,30 @@ public static class QuickSwitch
3939

4040
private static readonly Settings _settings = Ioc.Default.GetRequiredService<Settings>();
4141

42+
private static IWebBrowser2 _lastExplorerView = null;
4243
private static readonly object _lastExplorerViewLock = new();
4344

44-
private static readonly object _dialogWindowHandleLock = new();
45+
private static HWND _mainWindowHandle = HWND.Null;
4546

46-
private static IWebBrowser2 _lastExplorerView = null;
47+
private static HWND _dialogWindowHandle = HWND.Null;
48+
private static readonly object _dialogWindowHandleLock = new();
4749

4850
private static HWINEVENTHOOK _foregroundChangeHook = HWINEVENTHOOK.Null;
49-
5051
private static HWINEVENTHOOK _locationChangeHook = HWINEVENTHOOK.Null;
51-
52-
/*private static HWINEVENTHOOK _moveSizeHook = HWINEVENTHOOK.Null;*/
53-
5452
private static HWINEVENTHOOK _destroyChangeHook = HWINEVENTHOOK.Null;
5553

5654
private static DispatcherTimer _dragMoveTimer = null;
5755

5856
// A list of all file dialog windows that are auto switched already
5957
private static readonly List<HWND> _autoSwitchedDialogs = new();
60-
6158
private static readonly object _autoSwitchedDialogsLock = new();
6259

6360
private static readonly SemaphoreSlim _navigationLock = new(1, 1);
6461

65-
private static HWND _mainWindowHandle = HWND.Null;
62+
private static HWINEVENTHOOK _moveSizeHook = HWINEVENTHOOK.Null;
6663

67-
private static HWND _dialogWindowHandle = HWND.Null;
64+
private static HWND _hookedDialogWindowHandle = HWND.Null;
65+
private static readonly object _hookedDialogWindowHandleLock = new();
6866

6967
private static bool _isInitialized = false;
7068

@@ -124,16 +122,6 @@ public static void Initialize()
124122
0,
125123
PInvoke.WINEVENT_OUTOFCONTEXT);
126124

127-
// Call MoveSizeCallBack when the window is moved or resized
128-
/*_moveSizeHook = PInvoke.SetWinEventHook(
129-
PInvoke.EVENT_SYSTEM_MOVESIZESTART,
130-
PInvoke.EVENT_SYSTEM_MOVESIZEEND,
131-
PInvoke.GetModuleHandle((PCWSTR)null),
132-
MoveSizeCallBack,
133-
0,
134-
0,
135-
PInvoke.WINEVENT_OUTOFCONTEXT);*/
136-
137125
// Call DestroyChange when the window is destroyed
138126
_destroyChangeHook = PInvoke.SetWinEventHook(
139127
PInvoke.EVENT_OBJECT_DESTROY,
@@ -146,7 +134,6 @@ public static void Initialize()
146134

147135
if (_foregroundChangeHook.IsNull ||
148136
_locationChangeHook.IsNull ||
149-
/*_moveSizeHook.IsNull ||*/
150137
_destroyChangeHook.IsNull)
151138
{
152139
Log.Error(ClassName, "Failed to initialize QuickSwitch");
@@ -170,13 +157,41 @@ public static void Initialize()
170157

171158
#region Invoke Property Events
172159

173-
private static void InvokeShowQuickSwitchWindow()
160+
private static unsafe void InvokeShowQuickSwitchWindow()
174161
{
175162
// Show quick switch window
176163
if (_settings.ShowQuickSwitchWindow)
177164
{
178165
ShowQuickSwitchWindow?.Invoke(_dialogWindowHandle.Value);
179-
_dragMoveTimer?.Start();
166+
167+
lock (_hookedDialogWindowHandleLock)
168+
{
169+
var needHook = _hookedDialogWindowHandle == HWND.Null ||
170+
_hookedDialogWindowHandle != _dialogWindowHandle;
171+
172+
if (needHook)
173+
{
174+
if (!_moveSizeHook.IsNull)
175+
{
176+
PInvoke.UnhookWinEvent(_moveSizeHook);
177+
_moveSizeHook = HWINEVENTHOOK.Null;
178+
}
179+
180+
// Call MoveSizeCallBack when the window is moved or resized
181+
uint processId;
182+
var threadId = PInvoke.GetWindowThreadProcessId(_dialogWindowHandle, &processId);
183+
_moveSizeHook = PInvoke.SetWinEventHook(
184+
PInvoke.EVENT_SYSTEM_MOVESIZESTART,
185+
PInvoke.EVENT_SYSTEM_MOVESIZEEND,
186+
PInvoke.GetModuleHandle((PCWSTR)null),
187+
MoveSizeCallBack,
188+
processId,
189+
threadId,
190+
PInvoke.WINEVENT_OUTOFCONTEXT);
191+
}
192+
193+
_hookedDialogWindowHandle = _dialogWindowHandle;
194+
}
180195
}
181196
}
182197

@@ -190,15 +205,24 @@ private static void InvokeResetQuickSwitchWindow()
190205
{
191206
// Reset quick switch window
192207
ResetQuickSwitchWindow?.Invoke();
193-
_dragMoveTimer?.Stop();
208+
209+
lock (_hookedDialogWindowHandleLock)
210+
{
211+
if (!_moveSizeHook.IsNull)
212+
{
213+
PInvoke.UnhookWinEvent(_moveSizeHook);
214+
_moveSizeHook = HWINEVENTHOOK.Null;
215+
}
216+
217+
_hookedDialogWindowHandle = HWND.Null;
218+
}
194219
}
195220

196221
private static void InvokeHideQuickSwitchWindow()
197222
{
198223
// Neither quick switch window nor file dialog window is foreground
199224
// Hide quick switch window until the file dialog window is brought to the foreground
200225
HideQuickSwitchWindow?.Invoke();
201-
_dragMoveTimer?.Stop();
202226
}
203227

204228
#endregion
@@ -255,10 +279,7 @@ uint dwmsEventTime
255279
// Show quick switch window after navigating the path
256280
else
257281
{
258-
NavigateDialogPath(hwnd, () =>
259-
{
260-
InvokeShowQuickSwitchWindow();
261-
});
282+
NavigateDialogPath(hwnd, InvokeShowQuickSwitchWindow);
262283
}
263284
}
264285
else
@@ -333,9 +354,7 @@ uint dwmsEventTime
333354
}
334355
}
335356

336-
// Here we do not start & stop the timer beacause the start time is not accurate (more than 1s delay)
337-
// So we start & stop the timer when we find a file dialog window
338-
/*private static void MoveSizeCallBack(
357+
private static void MoveSizeCallBack(
339358
HWINEVENTHOOK hWinEventHook,
340359
uint eventType,
341360
HWND hwnd,
@@ -346,7 +365,7 @@ uint dwmsEventTime
346365
)
347366
{
348367
// If the dialog window is moved or resized, update the quick switch window position
349-
if (_dialogWindowHandle != HWND.Null && _dialogWindowHandle == hwnd && _dragMoveTimer != null)
368+
if (_dragMoveTimer != null)
350369
{
351370
switch (eventType)
352371
{
@@ -358,7 +377,7 @@ uint dwmsEventTime
358377
break;
359378
}
360379
}
361-
}*/
380+
}
362381

363382
private static void DestroyChangeCallback(
364383
HWINEVENTHOOK hWinEventHook,
@@ -600,11 +619,11 @@ public static void Dispose()
600619
PInvoke.UnhookWinEvent(_locationChangeHook);
601620
_locationChangeHook = HWINEVENTHOOK.Null;
602621
}
603-
/*if (!_moveSizeHook.IsNull)
622+
if (!_moveSizeHook.IsNull)
604623
{
605624
PInvoke.UnhookWinEvent(_moveSizeHook);
606625
_moveSizeHook = HWINEVENTHOOK.Null;
607-
}*/
626+
}
608627
if (!_destroyChangeHook.IsNull)
609628
{
610629
PInvoke.UnhookWinEvent(_destroyChangeHook);

0 commit comments

Comments
 (0)