Windows: Use WS_EX_NOACTIVATE to control initial window activation (issue #1856)
This commit is contained in:
parent
84a5749f9f
commit
b8eaec0db2
|
@ -207,8 +207,27 @@ bool CefBrowserPlatformDelegateNativeWin::CreateHostWindow() {
|
|||
gfx::Rect(0, 0, point.x(), point.y()));
|
||||
|
||||
window_widget_ = delegate_view->GetWidget();
|
||||
|
||||
const HWND widget_hwnd = HWNDForWidget(window_widget_);
|
||||
DCHECK(widget_hwnd);
|
||||
const DWORD widget_ex_styles = GetWindowLongPtr(widget_hwnd, GWL_EXSTYLE);
|
||||
|
||||
if (window_info_.ex_style & WS_EX_NOACTIVATE) {
|
||||
// Add the WS_EX_NOACTIVATE style on the DesktopWindowTreeHostWin HWND
|
||||
// so that HWNDMessageHandler::Show() called via Widget::Show() does not
|
||||
// activate the window.
|
||||
SetWindowLongPtr(widget_hwnd, GWL_EXSTYLE,
|
||||
widget_ex_styles | WS_EX_NOACTIVATE);
|
||||
}
|
||||
|
||||
window_widget_->Show();
|
||||
|
||||
if (window_info_.ex_style & WS_EX_NOACTIVATE) {
|
||||
// Remove the WS_EX_NOACTIVATE style so that future mouse clicks inside the
|
||||
// browser correctly activate and focus the window.
|
||||
SetWindowLongPtr(widget_hwnd, GWL_EXSTYLE, widget_ex_styles);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -41,6 +41,9 @@ void BrowserWindowOsrWin::GetPopupConfig(CefWindowHandle temp_handle,
|
|||
windowInfo.external_begin_frame_enabled =
|
||||
osr_window_->settings().external_begin_frame_enabled;
|
||||
|
||||
// Don't activate the hidden browser on creation.
|
||||
windowInfo.ex_style |= WS_EX_NOACTIVATE;
|
||||
|
||||
client = client_handler_;
|
||||
}
|
||||
|
||||
|
|
|
@ -26,6 +26,11 @@ void BrowserWindowStdWin::CreateBrowser(
|
|||
RECT wnd_rect = {rect.x, rect.y, rect.x + rect.width, rect.y + rect.height};
|
||||
window_info.SetAsChild(parent_handle, wnd_rect);
|
||||
|
||||
if (GetWindowLongPtr(parent_handle, GWL_EXSTYLE) & WS_EX_NOACTIVATE) {
|
||||
// Don't activate the browser window on creation.
|
||||
window_info.ex_style |= WS_EX_NOACTIVATE;
|
||||
}
|
||||
|
||||
CefBrowserHost::CreateBrowser(window_info, client_handler_,
|
||||
client_handler_->startup_url(), settings,
|
||||
request_context);
|
||||
|
@ -39,6 +44,10 @@ void BrowserWindowStdWin::GetPopupConfig(CefWindowHandle temp_handle,
|
|||
|
||||
// The window will be properly sized after the browser is created.
|
||||
windowInfo.SetAsChild(temp_handle, RECT());
|
||||
|
||||
// Don't activate the hidden browser window on creation.
|
||||
windowInfo.ex_style |= WS_EX_NOACTIVATE;
|
||||
|
||||
client = client_handler_;
|
||||
}
|
||||
|
||||
|
@ -53,8 +62,11 @@ void BrowserWindowStdWin::ShowPopup(ClientWindowHandle parent_handle,
|
|||
if (hwnd) {
|
||||
SetParent(hwnd, parent_handle);
|
||||
SetWindowPos(hwnd, NULL, x, y, static_cast<int>(width),
|
||||
static_cast<int>(height), SWP_NOZORDER);
|
||||
ShowWindow(hwnd, SW_SHOW);
|
||||
static_cast<int>(height), SWP_NOZORDER | SWP_NOACTIVATE);
|
||||
|
||||
const bool no_activate =
|
||||
GetWindowLongPtr(parent_handle, GWL_EXSTYLE) & WS_EX_NOACTIVATE;
|
||||
ShowWindow(hwnd, no_activate ? SW_SHOWNOACTIVATE : SW_SHOW);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -249,7 +249,8 @@ ClientHandler::ClientHandler(Delegate* delegate,
|
|||
browser_count_(0),
|
||||
console_log_file_(MainContext::Get()->GetConsoleLogPath()),
|
||||
first_console_message_(true),
|
||||
focus_on_editable_field_(false) {
|
||||
focus_on_editable_field_(false),
|
||||
initial_navigation_(true) {
|
||||
DCHECK(!console_log_file_.empty());
|
||||
|
||||
#if defined(OS_LINUX)
|
||||
|
@ -497,6 +498,22 @@ void ClientHandler::OnTakeFocus(CefRefPtr<CefBrowser> browser, bool next) {
|
|||
NotifyTakeFocus(next);
|
||||
}
|
||||
|
||||
bool ClientHandler::OnSetFocus(CefRefPtr<CefBrowser> browser,
|
||||
FocusSource source) {
|
||||
CEF_REQUIRE_UI_THREAD();
|
||||
|
||||
if (initial_navigation_) {
|
||||
CefRefPtr<CefCommandLine> command_line =
|
||||
CefCommandLine::GetGlobalCommandLine();
|
||||
if (command_line->HasSwitch(switches::kNoActivate)) {
|
||||
// Don't give focus to the browser on creation.
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool ClientHandler::OnPreKeyEvent(CefRefPtr<CefBrowser> browser,
|
||||
const CefKeyEvent& event,
|
||||
CefEventHandle os_event,
|
||||
|
@ -606,6 +623,10 @@ void ClientHandler::OnLoadingStateChange(CefRefPtr<CefBrowser> browser,
|
|||
bool canGoForward) {
|
||||
CEF_REQUIRE_UI_THREAD();
|
||||
|
||||
if (!isLoading && initial_navigation_) {
|
||||
initial_navigation_ = false;
|
||||
}
|
||||
|
||||
NotifyLoadingState(isLoading, canGoBack, canGoForward);
|
||||
}
|
||||
|
||||
|
|
|
@ -169,6 +169,7 @@ class ClientHandler : public CefClient,
|
|||
|
||||
// CefFocusHandler methods
|
||||
void OnTakeFocus(CefRefPtr<CefBrowser> browser, bool next) OVERRIDE;
|
||||
bool OnSetFocus(CefRefPtr<CefBrowser> browser, FocusSource source) OVERRIDE;
|
||||
|
||||
// CefKeyboardHandler methods
|
||||
bool OnPreKeyEvent(CefRefPtr<CefBrowser> browser,
|
||||
|
@ -370,6 +371,9 @@ class ClientHandler : public CefClient,
|
|||
// True if an editable field currently has focus.
|
||||
bool focus_on_editable_field_;
|
||||
|
||||
// True for the initial navigation after browser creation.
|
||||
bool initial_navigation_;
|
||||
|
||||
// Set of Handlers registered with the message router.
|
||||
MessageHandlerSet message_handler_set_;
|
||||
|
||||
|
|
|
@ -76,6 +76,11 @@ void OsrWindowWin::CreateBrowser(HWND parent_hwnd,
|
|||
CefWindowInfo window_info;
|
||||
window_info.SetAsWindowless(hwnd_);
|
||||
|
||||
if (GetWindowLongPtr(parent_hwnd, GWL_EXSTYLE) & WS_EX_NOACTIVATE) {
|
||||
// Don't activate the browser window on creation.
|
||||
window_info.ex_style |= WS_EX_NOACTIVATE;
|
||||
}
|
||||
|
||||
window_info.shared_texture_enabled = settings_.shared_texture_enabled;
|
||||
window_info.external_begin_frame_enabled =
|
||||
settings_.external_begin_frame_enabled;
|
||||
|
@ -220,10 +225,16 @@ void OsrWindowWin::Create(HWND parent_hwnd, const RECT& rect) {
|
|||
|
||||
RegisterOsrClass(hInst, background_brush);
|
||||
|
||||
DWORD ex_style = 0;
|
||||
if (GetWindowLongPtr(parent_hwnd, GWL_EXSTYLE) & WS_EX_NOACTIVATE) {
|
||||
// Don't activate the browser window on creation.
|
||||
ex_style |= WS_EX_NOACTIVATE;
|
||||
}
|
||||
|
||||
// Create the native window with a border so it's easier to visually identify
|
||||
// OSR windows.
|
||||
hwnd_ = ::CreateWindow(
|
||||
kWndClass, 0,
|
||||
hwnd_ = ::CreateWindowEx(
|
||||
ex_style, kWndClass, 0,
|
||||
WS_BORDER | WS_CHILD | WS_CLIPCHILDREN | WS_CLIPSIBLINGS | WS_VISIBLE,
|
||||
rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top,
|
||||
parent_hwnd, 0, hInst, 0);
|
||||
|
|
|
@ -150,6 +150,7 @@ class RootWindow
|
|||
ShowNormal,
|
||||
ShowMinimized,
|
||||
ShowMaximized,
|
||||
ShowNoActivate,
|
||||
};
|
||||
|
||||
// Show the window.
|
||||
|
|
|
@ -226,6 +226,9 @@ void RootWindowWin::Show(ShowMode mode) {
|
|||
case ShowMaximized:
|
||||
nCmdShow = SW_SHOWMAXIMIZED;
|
||||
break;
|
||||
case ShowNoActivate:
|
||||
nCmdShow = SW_SHOWNOACTIVATE;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
@ -334,8 +337,16 @@ void RootWindowWin::CreateRootWindow(const CefBrowserSettings& settings,
|
|||
find_message_id_ = RegisterWindowMessage(FINDMSGSTRING);
|
||||
CHECK(find_message_id_);
|
||||
|
||||
CefRefPtr<CefCommandLine> command_line =
|
||||
CefCommandLine::GetGlobalCommandLine();
|
||||
const bool no_activate = command_line->HasSwitch(switches::kNoActivate);
|
||||
|
||||
const DWORD dwStyle = WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN;
|
||||
const DWORD dwExStyle = always_on_top_ ? WS_EX_TOPMOST : 0;
|
||||
DWORD dwExStyle = always_on_top_ ? WS_EX_TOPMOST : 0;
|
||||
if (no_activate) {
|
||||
// Don't activate the browser window on creation.
|
||||
dwExStyle |= WS_EX_NOACTIVATE;
|
||||
}
|
||||
|
||||
int x, y, width, height;
|
||||
if (::IsRectEmpty(&start_rect_)) {
|
||||
|
@ -373,7 +384,7 @@ void RootWindowWin::CreateRootWindow(const CefBrowserSettings& settings,
|
|||
|
||||
if (!initially_hidden) {
|
||||
// Show this window.
|
||||
Show(ShowNormal);
|
||||
Show(no_activate ? ShowNoActivate : ShowNormal);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1069,6 +1080,22 @@ void RootWindowWin::OnSetLoadingState(bool isLoading,
|
|||
EnableWindow(stop_hwnd_, isLoading);
|
||||
EnableWindow(edit_hwnd_, TRUE);
|
||||
}
|
||||
|
||||
if (!isLoading && GetWindowLongPtr(hwnd_, GWL_EXSTYLE) & WS_EX_NOACTIVATE) {
|
||||
// Done with the initial navigation. Remove the WS_EX_NOACTIVATE style so
|
||||
// that future mouse clicks inside the browser correctly activate and focus
|
||||
// the window. For the top-level window removing this style causes Windows
|
||||
// to display the task bar button.
|
||||
SetWindowLongPtr(hwnd_, GWL_EXSTYLE,
|
||||
GetWindowLongPtr(hwnd_, GWL_EXSTYLE) & ~WS_EX_NOACTIVATE);
|
||||
|
||||
if (browser_window_) {
|
||||
HWND browser_hwnd = browser_window_->GetWindowHandle();
|
||||
SetWindowLongPtr(
|
||||
browser_hwnd, GWL_EXSTYLE,
|
||||
GetWindowLongPtr(browser_hwnd, GWL_EXSTYLE) & ~WS_EX_NOACTIVATE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
|
|
@ -43,6 +43,7 @@ const char kWidevineCdmPath[] = "widevine-cdm-path";
|
|||
const char kSslClientCertificate[] = "ssl-client-certificate";
|
||||
const char kCRLSetsPath[] = "crl-sets-path";
|
||||
const char kLoadExtension[] = "load-extension";
|
||||
const char kNoActivate[] = "no-activate";
|
||||
|
||||
} // namespace switches
|
||||
} // namespace client
|
||||
|
|
|
@ -37,6 +37,7 @@ extern const char kWidevineCdmPath[];
|
|||
extern const char kSslClientCertificate[];
|
||||
extern const char kCRLSetsPath[];
|
||||
extern const char kLoadExtension[];
|
||||
extern const char kNoActivate[];
|
||||
|
||||
} // namespace switches
|
||||
} // namespace client
|
||||
|
|
Loading…
Reference in New Issue