Windows: Fix focus assignment after dismissing JS dialogs (issue #2584)

This commit is contained in:
Marshall Greenblatt 2019-02-11 17:22:42 -05:00
parent b8eaec0db2
commit f85816f0c7
4 changed files with 24 additions and 13 deletions

View File

@ -707,7 +707,10 @@ LRESULT CALLBACK CefBrowserPlatformDelegateNativeWin::WndProc(HWND hwnd,
return 0;
case WM_SETFOCUS:
if (browser)
// Selecting "Close window" from the task bar menu may send a focus
// notification even though the window is currently disabled (e.g. while
// a modal JS dialog is displayed).
if (browser && ::IsWindowEnabled(hwnd))
browser->SetFocus(true);
return 0;

View File

@ -39,8 +39,7 @@ INT_PTR CALLBACK CefJavaScriptDialogRunnerWin::DialogProc(HWND dialog,
reinterpret_cast<CefJavaScriptDialogRunnerWin*>(
GetWindowLongPtr(dialog, DWLP_USER));
if (owner) {
owner->Cancel();
owner->callback_.Run(false, base::string16());
owner->CloseDialog(false, base::string16());
// No need for the system to call DestroyWindow() because it will be
// called by the Cancel() method.
@ -74,8 +73,7 @@ INT_PTR CALLBACK CefJavaScriptDialogRunnerWin::DialogProc(HWND dialog,
break;
}
if (finish) {
owner->Cancel();
owner->callback_.Run(result, user_input);
owner->CloseDialog(result, user_input);
}
break;
}
@ -153,12 +151,9 @@ void CefJavaScriptDialogRunnerWin::Run(
}
void CefJavaScriptDialogRunnerWin::Cancel() {
HWND parent = NULL;
// Re-enable the parent before closing the popup to avoid focus/activation/
// z-order issues.
if (parent_win_ && IsWindow(parent_win_) && !IsWindowEnabled(parent_win_)) {
parent = parent_win_;
EnableWindow(parent_win_, TRUE);
parent_win_ = NULL;
}
@ -169,16 +164,24 @@ void CefJavaScriptDialogRunnerWin::Cancel() {
dialog_win_ = NULL;
}
// Return focus to the parent window.
if (parent)
SetFocus(parent);
if (hook_installed_) {
UninstallMessageHook();
hook_installed_ = false;
}
}
void CefJavaScriptDialogRunnerWin::CloseDialog(
bool success,
const base::string16& user_input) {
// Run the callback first so that RenderProcessHostImpl::IsBlocked is
// cleared. Otherwise, RenderWidgetHostImpl::IsIgnoringInputEvents will
// return true and RenderWidgetHostViewAura::OnWindowFocused will fail to
// re-assign browser focus.
callback_.Run(success, user_input);
callback_.Reset();
Cancel();
}
// static
LRESULT CALLBACK CefJavaScriptDialogRunnerWin::GetMsgProc(int code,
WPARAM wparam,

View File

@ -26,6 +26,8 @@ class CefJavaScriptDialogRunnerWin : public CefJavaScriptDialogRunner {
void Cancel() override;
private:
void CloseDialog(bool success, const base::string16& user_input);
HWND dialog_win_;
HWND parent_win_;

View File

@ -623,7 +623,10 @@ void RootWindowWin::OnPaint() {
}
void RootWindowWin::OnFocus() {
if (browser_window_)
// Selecting "Close window" from the task bar menu may send a focus
// notification even though the window is currently disabled (e.g. while a
// modal JS dialog is displayed).
if (browser_window_ && ::IsWindowEnabled(hwnd_))
browser_window_->SetFocus(true);
}