Fix delivery of focus/blur events (issue #1301).

git-svn-id: https://chromiumembedded.googlecode.com/svn/trunk@1717 5089003a-bbd8-11dd-ad1f-f1f9622dbc98
This commit is contained in:
Marshall Greenblatt 2014-06-06 19:04:21 +00:00
parent 99faa3fda4
commit 62d9365b51
17 changed files with 314 additions and 67 deletions

View File

@ -235,10 +235,16 @@ typedef struct _cef_browser_host_t {
int force_close); int force_close);
/// ///
// Set focus for the browser window. If |enable| is true (1) focus will be set // Set whether the browser is focused.
// to the window. Otherwise, focus will be removed.
/// ///
void (CEF_CALLBACK *set_focus)(struct _cef_browser_host_t* self, int enable); void (CEF_CALLBACK *set_focus)(struct _cef_browser_host_t* self, int focus);
///
// Set whether the window containing the browser is visible
// (minimized/unminimized, app hidden/unhidden, etc). Only used on Mac OS X.
///
void (CEF_CALLBACK *set_window_visibility)(struct _cef_browser_host_t* self,
int visible);
/// ///
// Retrieve the window handle for this browser. // Retrieve the window handle for this browser.

View File

@ -271,11 +271,17 @@ class CefBrowserHost : public virtual CefBase {
virtual void CloseBrowser(bool force_close) =0; virtual void CloseBrowser(bool force_close) =0;
/// ///
// Set focus for the browser window. If |enable| is true focus will be set to // Set whether the browser is focused.
// the window. Otherwise, focus will be removed.
/// ///
/*--cef()--*/ /*--cef()--*/
virtual void SetFocus(bool enable) =0; virtual void SetFocus(bool focus) =0;
///
// Set whether the window containing the browser is visible
// (minimized/unminimized, app hidden/unhidden, etc). Only used on Mac OS X.
///
/*--cef()--*/
virtual void SetWindowVisibility(bool visible) =0;
/// ///
// Retrieve the window handle for this browser. // Retrieve the window handle for this browser.

View File

@ -632,11 +632,29 @@ void CefBrowserHostImpl::CloseBrowser(bool force_close) {
} }
} }
void CefBrowserHostImpl::SetFocus(bool enable) { void CefBrowserHostImpl::SetFocus(bool focus) {
if (!enable) if (focus) {
return;
OnSetFocus(FOCUS_SOURCE_SYSTEM); OnSetFocus(FOCUS_SOURCE_SYSTEM);
} else {
if (CEF_CURRENTLY_ON_UIT()) {
PlatformSetFocus(false);
} else {
CEF_POST_TASK(CEF_UIT,
base::Bind(&CefBrowserHostImpl::PlatformSetFocus, this, false));
}
}
}
void CefBrowserHostImpl::SetWindowVisibility(bool visible) {
#if defined(OS_MACOSX)
if (CEF_CURRENTLY_ON_UIT()) {
PlatformSetWindowVisibility(visible);
} else {
CEF_POST_TASK(CEF_UIT,
base::Bind(&CefBrowserHostImpl::PlatformSetWindowVisibility,
this, visible));
}
#endif
} }
CefWindowHandle CefBrowserHostImpl::GetWindowHandle() { CefWindowHandle CefBrowserHostImpl::GetWindowHandle() {
@ -1499,15 +1517,7 @@ void CefBrowserHostImpl::OnSetFocus(cef_focus_source_t source) {
} }
} }
if (web_contents_.get()) PlatformSetFocus(true);
web_contents_->Focus();
#if defined(OS_WIN)
// When windowed rendering is used in combination with Aura on Windows we
// need to explicitly set focus to the native window handle. Otherwise,
// the window doesn't get keyboard focus.
PlatformSetViewFocus();
#endif // defined(OS_WIN)
} else { } else {
CEF_POST_TASK(CEF_UIT, CEF_POST_TASK(CEF_UIT,
base::Bind(&CefBrowserHostImpl::OnSetFocus, this, source)); base::Bind(&CefBrowserHostImpl::OnSetFocus, this, source));

View File

@ -127,7 +127,8 @@ class CefBrowserHostImpl : public CefBrowserHost,
// CefBrowserHost methods. // CefBrowserHost methods.
virtual CefRefPtr<CefBrowser> GetBrowser() OVERRIDE; virtual CefRefPtr<CefBrowser> GetBrowser() OVERRIDE;
virtual void CloseBrowser(bool force_close) OVERRIDE; virtual void CloseBrowser(bool force_close) OVERRIDE;
virtual void SetFocus(bool enable) OVERRIDE; virtual void SetFocus(bool focus) OVERRIDE;
virtual void SetWindowVisibility(bool visible) OVERRIDE;
virtual CefWindowHandle GetWindowHandle() OVERRIDE; virtual CefWindowHandle GetWindowHandle() OVERRIDE;
virtual CefWindowHandle GetOpenerWindowHandle() OVERRIDE; virtual CefWindowHandle GetOpenerWindowHandle() OVERRIDE;
virtual CefRefPtr<CefClient> GetClient() OVERRIDE; virtual CefRefPtr<CefClient> GetClient() OVERRIDE;
@ -443,8 +444,6 @@ class CefBrowserHostImpl : public CefBrowserHost,
static LPCTSTR GetWndClass(); static LPCTSTR GetWndClass();
static LRESULT CALLBACK WndProc(HWND hwnd, UINT message, static LRESULT CALLBACK WndProc(HWND hwnd, UINT message,
WPARAM wParam, LPARAM lParam); WPARAM wParam, LPARAM lParam);
void PlatformSetViewFocus();
#endif #endif
// Create the window. // Create the window.
@ -454,6 +453,12 @@ class CefBrowserHostImpl : public CefBrowserHost,
void PlatformCloseWindow(); void PlatformCloseWindow();
// Resize the window to the given dimensions. // Resize the window to the given dimensions.
void PlatformSizeTo(int width, int height); void PlatformSizeTo(int width, int height);
// Set or remove focus from the window.
void PlatformSetFocus(bool focus);
#if defined(OS_MACOSX)
// Set or remove window visibility.
void PlatformSetWindowVisibility(bool visible);
#endif
// Return the handle for this window. // Return the handle for this window.
CefWindowHandle PlatformGetWindowHandle(); CefWindowHandle PlatformGetWindowHandle();
// Open the specified text in the default text editor. // Open the specified text in the default text editor.

View File

@ -100,6 +100,24 @@ void CefBrowserHostImpl::PlatformSizeTo(int width, int height) {
} }
} }
void CefBrowserHostImpl::PlatformSetFocus(bool focus) {
if (!focus)
return;
if (web_contents_) {
// Give logical focus to the RenderWidgetHostViewAura in the views
// hierarchy. This does not change the native keyboard focus.
web_contents_->Focus();
}
if (window_x11_) {
// Give native focus to the DesktopNativeWidgetAura for the root window.
// Needs to be done via the ::Window so that keyboard focus is assigned
// correctly.
window_x11_->Focus();
}
}
CefWindowHandle CefBrowserHostImpl::PlatformGetWindowHandle() { CefWindowHandle CefBrowserHostImpl::PlatformGetWindowHandle() {
return window_info_.window; return window_info_.window;
} }

View File

@ -18,6 +18,7 @@
#include "base/strings/utf_string_conversions.h" #include "base/strings/utf_string_conversions.h"
#include "base/threading/thread_restrictions.h" #include "base/threading/thread_restrictions.h"
#include "content/public/browser/native_web_keyboard_event.h" #include "content/public/browser/native_web_keyboard_event.h"
#include "content/public/browser/render_widget_host_view.h"
#include "content/public/browser/web_contents.h" #include "content/public/browser/web_contents.h"
#include "content/public/common/file_chooser_params.h" #include "content/public/common/file_chooser_params.h"
#include "grit/ui_strings.h" #include "grit/ui_strings.h"
@ -34,7 +35,6 @@
@interface CefBrowserHostView : NSView { @interface CefBrowserHostView : NSView {
@private @private
CefBrowserHostImpl* browser_; // weak CefBrowserHostImpl* browser_; // weak
bool is_in_onsetfocus_;
} }
@property (nonatomic, assign) CefBrowserHostImpl* browser; @property (nonatomic, assign) CefBrowserHostImpl* browser;
@ -55,23 +55,6 @@
[super dealloc]; [super dealloc];
} }
- (BOOL)acceptsFirstResponder {
return browser_ && browser_->GetWebContents();
}
- (BOOL)becomeFirstResponder {
if (browser_ && browser_->GetWebContents()) {
// Avoid re-entering OnSetFocus.
if (!is_in_onsetfocus_) {
is_in_onsetfocus_ = true;
browser_->OnSetFocus(FOCUS_SOURCE_SYSTEM);
is_in_onsetfocus_ = false;
}
}
return YES;
}
@end @end
// Receives notifications from the browser window. Will delete itself when done. // Receives notifications from the browser window. Will delete itself when done.
@ -88,6 +71,48 @@
@synthesize browser = browser_; @synthesize browser = browser_;
// Called when we are activated (when we gain focus).
- (void)windowDidBecomeKey:(NSNotification*)notification {
if (browser_)
browser_->SetFocus(true);
}
// Called when we are deactivated (when we lose focus).
- (void)windowDidResignKey:(NSNotification*)notification {
if (browser_)
browser_->SetFocus(false);
}
// Called when we have been minimized.
- (void)windowDidMiniaturize:(NSNotification *)notification {
if (browser_)
browser_->SetWindowVisibility(false);
}
// Called when we have been unminimized.
- (void)windowDidDeminiaturize:(NSNotification *)notification {
if (browser_)
browser_->SetWindowVisibility(true);
}
// Called when the application has been hidden.
- (void)applicationDidHide:(NSNotification *)notification {
// If the window is miniaturized then nothing has really changed.
if (![[notification object] isMiniaturized]) {
if (browser_)
browser_->SetWindowVisibility(false);
}
}
// Called when the application has been unhidden.
- (void)applicationDidUnhide:(NSNotification *)notification {
// If the window is miniaturized then nothing has really changed.
if (![[notification object] isMiniaturized]) {
if (browser_)
browser_->SetWindowVisibility(true);
}
}
- (BOOL)windowShouldClose:(id)window { - (BOOL)windowShouldClose:(id)window {
// Protect against multiple requests to close while the close is pending. // Protect against multiple requests to close while the close is pending.
if (browser_ && browser_->destruction_state() <= if (browser_ && browser_->destruction_state() <=
@ -345,6 +370,31 @@ void CefBrowserHostImpl::PlatformSizeTo(int width, int height) {
// Not needed; subviews are bound. // Not needed; subviews are bound.
} }
void CefBrowserHostImpl::PlatformSetFocus(bool focus) {
if (web_contents_) {
if (content::RenderWidgetHostView* view =
web_contents_->GetRenderWidgetHostView()) {
view->SetActive(focus);
if (focus) {
// Give keyboard focus to the native view.
NSView* view = web_contents_->GetContentNativeView();
DCHECK([view canBecomeKeyView]);
[[view window] makeFirstResponder:view];
}
}
}
}
void CefBrowserHostImpl::PlatformSetWindowVisibility(bool visible) {
if (web_contents_) {
if (content::RenderWidgetHostView* view =
web_contents_->GetRenderWidgetHostView()) {
view->SetWindowVisibility(visible);
}
}
}
CefWindowHandle CefBrowserHostImpl::PlatformGetWindowHandle() { CefWindowHandle CefBrowserHostImpl::PlatformGetWindowHandle() {
return window_info_.view; return window_info_.view;
} }

View File

@ -601,7 +601,7 @@ LRESULT CALLBACK CefBrowserHostImpl::WndProc(HWND hwnd, UINT message,
case WM_SETFOCUS: case WM_SETFOCUS:
if (browser) if (browser)
browser->OnSetFocus(FOCUS_SOURCE_SYSTEM); browser->SetFocus(true);
return 0; return 0;
case WM_ERASEBKGND: case WM_ERASEBKGND:
@ -611,11 +611,6 @@ LRESULT CALLBACK CefBrowserHostImpl::WndProc(HWND hwnd, UINT message,
return DefWindowProc(hwnd, message, wParam, lParam); return DefWindowProc(hwnd, message, wParam, lParam);
} }
void CefBrowserHostImpl::PlatformSetViewFocus() {
if (window_widget_)
::SetFocus(views::HWNDForWidget(window_widget_));
}
ui::PlatformCursor CefBrowserHostImpl::GetPlatformCursor( ui::PlatformCursor CefBrowserHostImpl::GetPlatformCursor(
blink::WebCursorInfo::Type type) { blink::WebCursorInfo::Type type) {
HMODULE module_handle = NULL; HMODULE module_handle = NULL;
@ -701,6 +696,25 @@ void CefBrowserHostImpl::PlatformSizeTo(int width, int height) {
rect.bottom, SWP_NOZORDER | SWP_NOMOVE | SWP_NOACTIVATE); rect.bottom, SWP_NOZORDER | SWP_NOMOVE | SWP_NOACTIVATE);
} }
void CefBrowserHostImpl::PlatformSetFocus(bool focus) {
if (!focus)
return;
if (web_contents_) {
// Give logical focus to the RenderWidgetHostViewAura in the views
// hierarchy. This does not change the native keyboard focus.
web_contents_->Focus();
}
if (window_widget_) {
// Give native focus to the DesktopNativeWidgetAura for the root window.
// Needs to be done via the HWND so that keyboard focus is assigned
// correctly. DesktopNativeWidgetAura will update focus state on the
// aura::Window when WM_SETFOCUS and WM_KILLFOCUS are received.
::SetFocus(HWNDForWidget(window_widget_));
}
}
CefWindowHandle CefBrowserHostImpl::PlatformGetWindowHandle() { CefWindowHandle CefBrowserHostImpl::PlatformGetWindowHandle() {
return window_info_.window; return window_info_.window;
} }

View File

@ -10,6 +10,7 @@
#include <X11/Xatom.h> #include <X11/Xatom.h>
#include <X11/Xutil.h> #include <X11/Xutil.h>
#include "ui/base/x/x11_util.h"
#include "ui/events/platform/x11/x11_event_source.h" #include "ui/events/platform/x11/x11_event_source.h"
namespace { namespace {
@ -58,7 +59,9 @@ CefWindowX11::CefWindowX11(CefRefPtr<CefBrowserHostImpl> browser,
xwindow_(0), xwindow_(0),
window_mapped_(false), window_mapped_(false),
bounds_(bounds), bounds_(bounds),
atom_cache_(xdisplay_, kAtomsToCache) { focus_pending_(false),
atom_cache_(xdisplay_, kAtomsToCache),
weak_ptr_factory_(this) {
if (parent_xwindow_ == None) if (parent_xwindow_ == None)
parent_xwindow_ = DefaultRootWindow(xdisplay_); parent_xwindow_ = DefaultRootWindow(xdisplay_);
@ -166,6 +169,17 @@ void CefWindowX11::Hide() {
} }
} }
void CefWindowX11::Focus() {
if (xwindow_ == None || !window_mapped_)
return;
::Window child = FindChild(xdisplay_, xwindow_);
if (child && ui::IsWindowVisible(child)) {
// Give focus to the child DesktopWindowTreeHostX11.
XSetInputFocus(xdisplay_, child, RevertToParent, CurrentTime);
}
}
void CefWindowX11::SetBounds(const gfx::Rect& bounds) { void CefWindowX11::SetBounds(const gfx::Rect& bounds) {
if (xwindow_ == None) if (xwindow_ == None)
return; return;
@ -274,13 +288,31 @@ uint32_t CefWindowX11::DispatchEvent(const ui::PlatformEvent& event) {
// "_NET_ACTIVE_WINDOW" message it will erroneously mark the WebView // "_NET_ACTIVE_WINDOW" message it will erroneously mark the WebView
// (hosted in a DesktopWindowTreeHostX11) as unfocused. Use a delayed // (hosted in a DesktopWindowTreeHostX11) as unfocused. Use a delayed
// task here to restore the WebView's focus state. // task here to restore the WebView's focus state.
if (!focus_pending_) {
focus_pending_ = true;
CEF_POST_DELAYED_TASK(CEF_UIT, CEF_POST_DELAYED_TASK(CEF_UIT,
base::Bind(&CefBrowserHostImpl::OnSetFocus, browser_, base::Bind(&CefWindowX11::ContinueFocus,
FOCUS_SOURCE_SYSTEM), weak_ptr_factory_.GetWeakPtr()),
100); 100);
}
break;
case FocusOut:
// Cancel the pending focus change if some other window has gained focus
// while waiting for the async task to run. Otherwise we can get stuck in
// a focus change loop.
if (focus_pending_)
focus_pending_ = false;
break; break;
} }
return ui::POST_DISPATCH_STOP_PROPAGATION; return ui::POST_DISPATCH_STOP_PROPAGATION;
} }
void CefWindowX11::ContinueFocus() {
if (!focus_pending_)
return;
browser_->SetFocus(true);
focus_pending_ = false;
}

View File

@ -11,6 +11,7 @@
#include "libcef/browser/browser_host_impl.h" #include "libcef/browser/browser_host_impl.h"
#include "base/memory/weak_ptr.h"
#include "ui/events/platform/platform_event_dispatcher.h" #include "ui/events/platform/platform_event_dispatcher.h"
#include "ui/gfx/rect.h" #include "ui/gfx/rect.h"
#include "ui/gfx/x/x11_atom_cache.h" #include "ui/gfx/x/x11_atom_cache.h"
@ -29,6 +30,8 @@ class CefWindowX11 : public ui::PlatformEventDispatcher {
void Show(); void Show();
void Hide(); void Hide();
void Focus();
void SetBounds(const gfx::Rect& bounds); void SetBounds(const gfx::Rect& bounds);
gfx::Rect GetBoundsInScreen(); gfx::Rect GetBoundsInScreen();
@ -41,6 +44,8 @@ class CefWindowX11 : public ui::PlatformEventDispatcher {
gfx::Rect bounds() const { return bounds_; } gfx::Rect bounds() const { return bounds_; }
private: private:
void ContinueFocus();
CefRefPtr<CefBrowserHostImpl> browser_; CefRefPtr<CefBrowserHostImpl> browser_;
// The display and the native X window hosting the root window. // The display and the native X window hosting the root window.
@ -54,8 +59,13 @@ class CefWindowX11 : public ui::PlatformEventDispatcher {
// The bounds of |xwindow_|. // The bounds of |xwindow_|.
gfx::Rect bounds_; gfx::Rect bounds_;
bool focus_pending_;
ui::X11AtomCache atom_cache_; ui::X11AtomCache atom_cache_;
// Must always be the last member.
base::WeakPtrFactory<CefWindowX11> weak_ptr_factory_;
DISALLOW_COPY_AND_ASSIGN(CefWindowX11); DISALLOW_COPY_AND_ASSIGN(CefWindowX11);
}; };

View File

@ -126,7 +126,7 @@ void CEF_CALLBACK browser_host_close_browser(struct _cef_browser_host_t* self,
} }
void CEF_CALLBACK browser_host_set_focus(struct _cef_browser_host_t* self, void CEF_CALLBACK browser_host_set_focus(struct _cef_browser_host_t* self,
int enable) { int focus) {
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING // AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
DCHECK(self); DCHECK(self);
@ -135,7 +135,20 @@ void CEF_CALLBACK browser_host_set_focus(struct _cef_browser_host_t* self,
// Execute // Execute
CefBrowserHostCppToC::Get(self)->SetFocus( CefBrowserHostCppToC::Get(self)->SetFocus(
enable?true:false); focus?true:false);
}
void CEF_CALLBACK browser_host_set_window_visibility(
struct _cef_browser_host_t* self, int visible) {
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
DCHECK(self);
if (!self)
return;
// Execute
CefBrowserHostCppToC::Get(self)->SetWindowVisibility(
visible?true:false);
} }
cef_window_handle_t CEF_CALLBACK browser_host_get_window_handle( cef_window_handle_t CEF_CALLBACK browser_host_get_window_handle(
@ -527,6 +540,7 @@ CefBrowserHostCppToC::CefBrowserHostCppToC(CefBrowserHost* cls)
struct_.struct_.get_browser = browser_host_get_browser; struct_.struct_.get_browser = browser_host_get_browser;
struct_.struct_.close_browser = browser_host_close_browser; struct_.struct_.close_browser = browser_host_close_browser;
struct_.struct_.set_focus = browser_host_set_focus; struct_.struct_.set_focus = browser_host_set_focus;
struct_.struct_.set_window_visibility = browser_host_set_window_visibility;
struct_.struct_.get_window_handle = browser_host_get_window_handle; struct_.struct_.get_window_handle = browser_host_get_window_handle;
struct_.struct_.get_opener_window_handle = struct_.struct_.get_opener_window_handle =
browser_host_get_opener_window_handle; browser_host_get_opener_window_handle;

View File

@ -87,7 +87,7 @@ void CefBrowserHostCToCpp::CloseBrowser(bool force_close) {
force_close); force_close);
} }
void CefBrowserHostCToCpp::SetFocus(bool enable) { void CefBrowserHostCToCpp::SetFocus(bool focus) {
if (CEF_MEMBER_MISSING(struct_, set_focus)) if (CEF_MEMBER_MISSING(struct_, set_focus))
return; return;
@ -95,7 +95,18 @@ void CefBrowserHostCToCpp::SetFocus(bool enable) {
// Execute // Execute
struct_->set_focus(struct_, struct_->set_focus(struct_,
enable); focus);
}
void CefBrowserHostCToCpp::SetWindowVisibility(bool visible) {
if (CEF_MEMBER_MISSING(struct_, set_window_visibility))
return;
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
// Execute
struct_->set_window_visibility(struct_,
visible);
} }
CefWindowHandle CefBrowserHostCToCpp::GetWindowHandle() { CefWindowHandle CefBrowserHostCToCpp::GetWindowHandle() {

View File

@ -39,7 +39,8 @@ class CefBrowserHostCToCpp
// CefBrowserHost methods // CefBrowserHost methods
virtual CefRefPtr<CefBrowser> GetBrowser() OVERRIDE; virtual CefRefPtr<CefBrowser> GetBrowser() OVERRIDE;
virtual void CloseBrowser(bool force_close) OVERRIDE; virtual void CloseBrowser(bool force_close) OVERRIDE;
virtual void SetFocus(bool enable) OVERRIDE; virtual void SetFocus(bool focus) OVERRIDE;
virtual void SetWindowVisibility(bool visible) OVERRIDE;
virtual CefWindowHandle GetWindowHandle() OVERRIDE; virtual CefWindowHandle GetWindowHandle() OVERRIDE;
virtual CefWindowHandle GetOpenerWindowHandle() OVERRIDE; virtual CefWindowHandle GetOpenerWindowHandle() OVERRIDE;
virtual CefRefPtr<CefClient> GetClient() OVERRIDE; virtual CefRefPtr<CefClient> GetClient() OVERRIDE;

View File

@ -26,6 +26,22 @@ Index: desktop_aura/desktop_window_tree_host_win.cc
parent_hwnd = params.parent->GetHost()->GetAcceleratedWidget(); parent_hwnd = params.parent->GetHost()->GetAcceleratedWidget();
message_handler_->set_remove_standard_frame(params.remove_standard_frame); message_handler_->set_remove_standard_frame(params.remove_standard_frame);
@@ -775,6 +777,7 @@
void DesktopWindowTreeHostWin::HandleNativeFocus(HWND last_focused_window) {
// TODO(beng): inform the native_widget_delegate_.
+ GetWidget()->GetNativeWindow()->Focus();
InputMethod* input_method = GetInputMethod();
if (input_method)
input_method->OnFocus();
@@ -782,6 +785,7 @@
void DesktopWindowTreeHostWin::HandleNativeBlur(HWND focused_window) {
// TODO(beng): inform the native_widget_delegate_.
+ GetWidget()->GetNativeWindow()->Blur();
InputMethod* input_method = GetInputMethod();
if (input_method)
input_method->OnBlur();
Index: desktop_aura/desktop_window_tree_host_x11.cc Index: desktop_aura/desktop_window_tree_host_x11.cc
=================================================================== ===================================================================
--- desktop_aura/desktop_window_tree_host_x11.cc (revision 272007) --- desktop_aura/desktop_window_tree_host_x11.cc (revision 272007)

View File

@ -94,9 +94,7 @@ gboolean WindowFocusIn(GtkWidget* widget,
CefRefPtr<CefBrowser> browser = g_handler->GetBrowser(); CefRefPtr<CefBrowser> browser = g_handler->GetBrowser();
if (browser) { if (browser) {
// Give focus to the browser window. // Give focus to the browser window.
::Display* xdisplay = cef_get_xdisplay(); browser->GetHost()->SetFocus(true);
::Window xwindow = browser->GetHost()->GetWindowHandle();
XSetInputFocus(xdisplay, xwindow, RevertToParent, CurrentTime);
return TRUE; return TRUE;
} }
} }

View File

@ -202,10 +202,63 @@ const int kWindowHeight = 600;
[self alert:@"File Download" withMessage:str]; [self alert:@"File Download" withMessage:str];
} }
// Called when we are activated (when we gain focus).
- (void)windowDidBecomeKey:(NSNotification*)notification { - (void)windowDidBecomeKey:(NSNotification*)notification {
if (g_handler.get() && g_handler->GetBrowserId()) { if (g_handler.get()) {
// Give focus to the browser window. CefRefPtr<CefBrowser> browser = g_handler->GetBrowser();
g_handler->GetBrowser()->GetHost()->SetFocus(true); if (browser.get())
browser->GetHost()->SetFocus(true);
}
}
// Called when we are deactivated (when we lose focus).
- (void)windowDidResignKey:(NSNotification*)notification {
if (g_handler.get()) {
CefRefPtr<CefBrowser> browser = g_handler->GetBrowser();
if (browser.get())
browser->GetHost()->SetFocus(false);
}
}
// Called when we have been minimized.
- (void)windowDidMiniaturize:(NSNotification *)notification {
if (g_handler.get()) {
CefRefPtr<CefBrowser> browser = g_handler->GetBrowser();
if (browser.get())
browser->GetHost()->SetWindowVisibility(false);
}
}
// Called when we have been unminimized.
- (void)windowDidDeminiaturize:(NSNotification *)notification {
if (g_handler.get()) {
CefRefPtr<CefBrowser> browser = g_handler->GetBrowser();
if (browser.get())
browser->GetHost()->SetWindowVisibility(true);
}
}
// Called when the application has been hidden.
- (void)applicationDidHide:(NSNotification *)notification {
// If the window is miniaturized then nothing has really changed.
if (![[notification object] isMiniaturized]) {
if (g_handler.get()) {
CefRefPtr<CefBrowser> browser = g_handler->GetBrowser();
if (browser.get())
browser->GetHost()->SetWindowVisibility(false);
}
}
}
// Called when the application has been unhidden.
- (void)applicationDidUnhide:(NSNotification *)notification {
// If the window is miniaturized then nothing has really changed.
if (![[notification object] isMiniaturized]) {
if (g_handler.get()) {
CefRefPtr<CefBrowser> browser = g_handler->GetBrowser();
if (browser.get())
browser->GetHost()->SetWindowVisibility(true);
}
} }
} }

View File

@ -517,11 +517,8 @@ LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam,
case WM_SETFOCUS: case WM_SETFOCUS:
if (g_handler.get() && g_handler->GetBrowser()) { if (g_handler.get() && g_handler->GetBrowser()) {
// Pass focus to the browser window // Give focus to the browser.
CefWindowHandle hwnd = g_handler->GetBrowser()->GetHost()->SetFocus(true);
g_handler->GetBrowser()->GetHost()->GetWindowHandle();
if (hwnd)
PostMessage(hwnd, WM_SETFOCUS, wParam, NULL);
} }
return 0; return 0;

View File

@ -306,6 +306,12 @@ void ClientHandler::OnAfterCreated(CefRefPtr<CefBrowser> browser) {
} else if (browser->IsPopup()) { } else if (browser->IsPopup()) {
// Add to the list of popup browsers. // Add to the list of popup browsers.
m_PopupBrowsers.push_back(browser); m_PopupBrowsers.push_back(browser);
// Give focus to the popup browser. Perform asynchronously because the
// parent window may attempt to keep focus after launching the popup.
CefPostTask(TID_UI,
NewCefRunnableMethod(browser->GetHost().get(),
&CefBrowserHost::SetFocus, true));
} }
m_BrowserCount++; m_BrowserCount++;