diff --git a/libcef/browser/native/browser_platform_delegate_native_win.cc b/libcef/browser/native/browser_platform_delegate_native_win.cc index d9a322c13..04e13a081 100644 --- a/libcef/browser/native/browser_platform_delegate_native_win.cc +++ b/libcef/browser/native/browser_platform_delegate_native_win.cc @@ -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; diff --git a/libcef/browser/native/javascript_dialog_runner_win.cc b/libcef/browser/native/javascript_dialog_runner_win.cc index 188e7f559..42b993026 100644 --- a/libcef/browser/native/javascript_dialog_runner_win.cc +++ b/libcef/browser/native/javascript_dialog_runner_win.cc @@ -39,8 +39,7 @@ INT_PTR CALLBACK CefJavaScriptDialogRunnerWin::DialogProc(HWND dialog, reinterpret_cast( 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, diff --git a/libcef/browser/native/javascript_dialog_runner_win.h b/libcef/browser/native/javascript_dialog_runner_win.h index 11030265a..2897bc3b2 100644 --- a/libcef/browser/native/javascript_dialog_runner_win.h +++ b/libcef/browser/native/javascript_dialog_runner_win.h @@ -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_; diff --git a/tests/cefclient/browser/root_window_win.cc b/tests/cefclient/browser/root_window_win.cc index f6821b0ca..d48e101e0 100644 --- a/tests/cefclient/browser/root_window_win.cc +++ b/tests/cefclient/browser/root_window_win.cc @@ -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); }