Skip to content

Commit 9b58dd3

Browse files
committed
Improve dialog window check & Fix issue that dialogs are enabled on other dialog windows
1 parent c343337 commit 9b58dd3

File tree

1 file changed

+66
-50
lines changed

1 file changed

+66
-50
lines changed

Flow.Launcher.Infrastructure/QuickSwitch/Models/WindowsDialog.cs

Lines changed: 66 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -21,13 +21,23 @@ internal class WindowsDialog : IQuickSwitchDialog
2121

2222
public bool CheckDialogWindow(HWND hwnd)
2323
{
24-
if (GetWindowClassName(hwnd) == WindowsDialogClassName)
24+
// Has it been checked?
25+
if (DialogWindow != null && DialogWindow.Handle == hwnd)
2526
{
26-
if (DialogWindow == null || DialogWindow.Handle != hwnd)
27+
return true;
28+
}
29+
30+
// Is it a Win32 dialog box?
31+
if (GetClassName(hwnd) == WindowsDialogClassName)
32+
{
33+
// Is it a windows file dialog?
34+
var dialogType = GetFileDialogType(hwnd);
35+
if (dialogType != DialogType.Others)
2736
{
28-
DialogWindow = new WindowsDialogWindow(hwnd);
37+
DialogWindow = new WindowsDialogWindow(hwnd, dialogType);
38+
39+
return true;
2940
}
30-
return true;
3141
}
3242
return false;
3343
}
@@ -38,22 +48,34 @@ public void Dispose()
3848
DialogWindow = null;
3949
}
4050

41-
private static string GetWindowClassName(HWND handle)
42-
{
43-
return GetClassName(handle);
51+
#region Help Methods
4452

45-
static unsafe string GetClassName(HWND handle)
53+
private static unsafe string GetClassName(HWND handle)
54+
{
55+
fixed (char* buf = new char[256])
4656
{
47-
fixed (char* buf = new char[256])
57+
return PInvoke.GetClassName(handle, buf, 256) switch
4858
{
49-
return PInvoke.GetClassName(handle, buf, 256) switch
50-
{
51-
0 => string.Empty,
52-
_ => new string(buf),
53-
};
54-
}
59+
0 => string.Empty,
60+
_ => new string(buf),
61+
};
5562
}
5663
}
64+
65+
private static DialogType GetFileDialogType(HWND handle)
66+
{
67+
// Is it a Windows Open file dialog?
68+
var fileEditor = PInvoke.GetDlgItem(handle, 0x047C);
69+
if (fileEditor != HWND.Null && GetClassName(fileEditor) == "ComboBoxEx32") return DialogType.Open;
70+
71+
// Is it a Windows Save or Save As file dialog?
72+
fileEditor = PInvoke.GetDlgItem(handle, 0x0000);
73+
if (fileEditor != HWND.Null && GetClassName(fileEditor) == "DUIViewWndClassName") return DialogType.SaveOrSaveAs;
74+
75+
return DialogType.Others;
76+
}
77+
78+
#endregion
5779
}
5880

5981
internal class WindowsDialogWindow : IQuickSwitchDialogWindow
@@ -64,14 +86,17 @@ internal class WindowsDialogWindow : IQuickSwitchDialogWindow
6486
// So we need to cache the current tab and use the original handle
6587
private IQuickSwitchDialogWindowTab _currentTab { get; set; } = null;
6688

67-
public WindowsDialogWindow(HWND handle)
89+
private readonly DialogType _dialogType;
90+
91+
public WindowsDialogWindow(HWND handle, DialogType dialogType)
6892
{
6993
Handle = handle;
94+
_dialogType = dialogType;
7095
}
7196

7297
public IQuickSwitchDialogWindowTab GetCurrentTab()
7398
{
74-
return _currentTab ??= new WindowsDialogTab(Handle);
99+
return _currentTab ??= new WindowsDialogTab(Handle, _dialogType);
75100
}
76101

77102
public void Dispose()
@@ -94,9 +119,9 @@ internal class WindowsDialogTab : IQuickSwitchDialogWindowTab
94119

95120
private static readonly InputSimulator _inputSimulator = new();
96121

97-
private bool _legacy { get; set; } = false;
98-
private DialogType _type { get; set; } = DialogType.None;
122+
private readonly DialogType _dialogType;
99123

124+
private bool _legacy { get; set; } = false;
100125
private HWND _pathControl { get; set; } = HWND.Null;
101126
private HWND _pathEditor { get; set; } = HWND.Null;
102127
private HWND _fileEditor { get; set; } = HWND.Null;
@@ -106,9 +131,11 @@ internal class WindowsDialogTab : IQuickSwitchDialogWindowTab
106131

107132
#region Constructor
108133

109-
public WindowsDialogTab(HWND handle)
134+
public WindowsDialogTab(HWND handle, DialogType dialogType)
110135
{
111136
Handle = handle;
137+
_dialogType = dialogType;
138+
Log.Debug(ClassName, $"File dialog type: {dialogType}");
112139
}
113140

114141
#endregion
@@ -232,34 +259,27 @@ private bool GetPathControlEditor()
232259

233260
private bool GetFileEditor()
234261
{
235-
// Get the handle of the file name editor of Open file dialog
236-
_fileEditor = PInvoke.GetDlgItem(Handle, 0x047C); // ComboBoxEx32
237-
_fileEditor = PInvoke.GetDlgItem(_fileEditor, 0x047C); // ComboBox
238-
_fileEditor = PInvoke.GetDlgItem(_fileEditor, 0x047C); // Edit
239-
if (_fileEditor == HWND.Null)
262+
if (_dialogType == DialogType.Open)
263+
{
264+
// Get the handle of the file name editor of Open file dialog
265+
_fileEditor = PInvoke.GetDlgItem(Handle, 0x047C); // ComboBoxEx32
266+
_fileEditor = PInvoke.GetDlgItem(_fileEditor, 0x047C); // ComboBox
267+
_fileEditor = PInvoke.GetDlgItem(_fileEditor, 0x047C); // Edit
268+
}
269+
else
240270
{
241271
// Get the handle of the file name editor of Save / SaveAs file dialog
242272
_fileEditor = PInvoke.GetDlgItem(Handle, 0x0000); // DUIViewWndClassName
243273
_fileEditor = PInvoke.GetDlgItem(_fileEditor, 0x0000); // DirectUIHWND
244274
_fileEditor = PInvoke.GetDlgItem(_fileEditor, 0x0000); // FloatNotifySink
245275
_fileEditor = PInvoke.GetDlgItem(_fileEditor, 0x0000); // ComboBox
246276
_fileEditor = PInvoke.GetDlgItem(_fileEditor, 0x03E9); // Edit
247-
if (_fileEditor == HWND.Null)
248-
{
249-
Log.Error(ClassName, "Failed to find file name editor handle");
250-
_type = DialogType.None;
251-
return false;
252-
}
253-
else
254-
{
255-
Log.Debug(ClassName, "File dialog type: Save / Save As");
256-
_type = DialogType.SaveOrSaveAs;
257-
}
258277
}
259-
else
278+
279+
if (_fileEditor == HWND.Null)
260280
{
261-
Log.Debug(ClassName, "File dialog type: Open");
262-
_type = DialogType.Open;
281+
Log.Error(ClassName, "Failed to find file name editor handle");
282+
return false;
263283
}
264284

265285
return true;
@@ -310,7 +330,7 @@ private static unsafe nint SetWindowText(HWND handle, string text)
310330
private bool JumpFolderWithFileEditor(string path, bool resetFocus)
311331
{
312332
// For Save / Save As dialog, the default value in file editor is not null and it can cause strange behaviors.
313-
if (resetFocus && _type == DialogType.SaveOrSaveAs) return false;
333+
if (resetFocus && _dialogType == DialogType.SaveOrSaveAs) return false;
314334

315335
if (_fileEditor.IsNull && !GetFileEditor()) return false;
316336
SetWindowText(_fileEditor, path);
@@ -324,16 +344,12 @@ private bool JumpFolderWithFileEditor(string path, bool resetFocus)
324344
#endregion
325345

326346
#endregion
347+
}
327348

328-
#region Classes
329-
330-
private enum DialogType
331-
{
332-
None,
333-
Open,
334-
SaveOrSaveAs
335-
}
336-
337-
#endregion
349+
internal enum DialogType
350+
{
351+
Others,
352+
Open,
353+
SaveOrSaveAs
338354
}
339355
}

0 commit comments

Comments
 (0)