1
0
mirror of https://github.com/cookiengineer/audacity synced 2025-06-25 16:48:44 +02:00

Restore focus if another modal dialog is opened on top of FileDialog

An example of this would be the FFmpeg custom options dialog.  When
the options dialog would close, focus would be lost and with no
apparent way to get it back when using the keyboard.

This change tracks the modal dialogs that are opened after the
current file dialog and that are descendants of the current file
dialog.  Once all of the descendants are closed, the current file
dialog will restore the focus and make sure it is the topmost
window.

This only affected Windows.
This commit is contained in:
Leland Lucius 2015-08-26 20:38:05 -05:00
parent c45ea059e6
commit d635ff36c4
2 changed files with 87 additions and 2 deletions

View File

@ -286,6 +286,9 @@ void FileDialog::MSWOnInitDialog(HWND hDlg, LPOPENFILENAME pOfn)
// Since we've specified the OFN_EXPLORER flag, the "real" dialog is the parent of this one // Since we've specified the OFN_EXPLORER flag, the "real" dialog is the parent of this one
mParentDlg = ::GetParent(hDlg); mParentDlg = ::GetParent(hDlg);
// Now we can initialize the disabler
mDisabler.Init(this, mParentDlg);
// This is the dialog were our controls will go // This is the dialog were our controls will go
mChildDlg = hDlg; mChildDlg = hDlg;
@ -866,6 +869,8 @@ static bool ShowCommFileDialog(OPENFILENAME *of, long style)
int FileDialog::ShowModal() int FileDialog::ShowModal()
{ {
WX_HOOK_MODAL_DIALOG();
HWND hWnd = 0; HWND hWnd = 0;
if (m_parent) hWnd = (HWND) m_parent->GetHWND(); if (m_parent) hWnd = (HWND) m_parent->GetHWND();
if (!hWnd && wxTheApp->GetTopWindow()) if (!hWnd && wxTheApp->GetTopWindow())
@ -1131,3 +1136,65 @@ int FileDialog::ShowModal()
return wxID_OK; return wxID_OK;
} }
FileDialog::Disabler::Disabler()
{
mRoot = NULL;
mHwnd = (HWND) INVALID_HANDLE_VALUE;
mModalCount = 0;
Register();
}
void FileDialog::Disabler::Init(wxWindow *root, HWND hwnd)
{
mRoot = root;
mHwnd = hwnd;
}
int FileDialog::Disabler::Enter(wxDialog *dialog)
{
if (mHwnd != (HWND) INVALID_HANDLE_VALUE)
{
if (IsChild(dialog)) {
::EnableWindow(mHwnd, FALSE);
mModalCount++;
}
}
return wxID_NONE;
}
void FileDialog::Disabler::Exit(wxDialog *dialog)
{
if (mHwnd != (HWND) INVALID_HANDLE_VALUE)
{
if (IsChild(dialog))
{
mModalCount--;
if (mModalCount == 0)
{
::EnableWindow(mHwnd, TRUE);
::SetWindowPos(mHwnd, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE);
}
}
}
}
bool FileDialog::Disabler::IsChild(const wxDialog *dialog) const
{
if (!dialog)
{
return false;
}
for (const wxWindow *w = dialog->GetParent(); w != NULL; w = w->GetParent())
{
if (w == mRoot)
{
return true;
}
}
return false;
}

View File

@ -16,6 +16,8 @@
#include <windows.h> #include <windows.h>
#include <wx/modalhook.h>
//------------------------------------------------------------------------- //-------------------------------------------------------------------------
// FileDialog // FileDialog
//------------------------------------------------------------------------- //-------------------------------------------------------------------------
@ -36,9 +38,8 @@ class FileDialog : public FileDialogBase
virtual void GetPaths(wxArrayString& paths) const; virtual void GetPaths(wxArrayString& paths) const;
virtual void GetFilenames(wxArrayString& files) const; virtual void GetFilenames(wxArrayString& files) const;
void OnSize(wxSizeEvent & e);
virtual int ShowModal(); virtual int ShowModal();
protected: protected:
// ----------------------------------------- // -----------------------------------------
// wxMSW-specific implementation from now on // wxMSW-specific implementation from now on
@ -98,6 +99,23 @@ private:
wxPanel *mRoot; wxPanel *mRoot;
class Disabler : public wxModalDialogHook
{
public:
Disabler();
void Init(wxWindow *root, HWND hwnd);
protected:
int Enter(wxDialog *dialog);
void Exit(wxDialog *dialog);
bool IsChild(const wxDialog *dialog) const;
private:
wxWindow *mRoot;
HWND mHwnd;
int mModalCount;
} mDisabler;
DECLARE_DYNAMIC_CLASS(FileDialog) DECLARE_DYNAMIC_CLASS(FileDialog)
DECLARE_NO_COPY_CLASS(FileDialog) DECLARE_NO_COPY_CLASS(FileDialog)
}; };