Linux: Fix focus/activation handling and keyboard input (issue #1679).
This commit is contained in:
parent
fdf3088470
commit
efbc200b51
|
@ -41,13 +41,9 @@ void CefWindowDelegateView::Init(
|
|||
params.opacity = views::Widget::InitParams::OPAQUE_WINDOW;
|
||||
// Tell Aura not to draw the window frame on resize.
|
||||
params.remove_standard_frame = true;
|
||||
#if defined(OS_WIN)
|
||||
// Cause WidgetDelegate::CanActivate to return true. See comments in
|
||||
// CefBrowserHostImpl::PlatformSetFocus.
|
||||
// TODO(cef): Do we need similar logic on Linux for proper activation/focus
|
||||
// handling?
|
||||
params.activatable = views::Widget::InitParams::ACTIVATABLE_YES;
|
||||
#endif
|
||||
|
||||
// Results in a call to InitContent().
|
||||
widget->Init(params);
|
||||
|
@ -56,10 +52,8 @@ void CefWindowDelegateView::Init(
|
|||
DCHECK_EQ(widget, GetWidget());
|
||||
// |widget| must be top-level for focus handling to work correctly.
|
||||
DCHECK(widget->is_top_level());
|
||||
#if defined(OS_WIN)
|
||||
// |widget| must be activatable for focus handling to work correctly.
|
||||
DCHECK(widget->widget_delegate()->CanActivate());
|
||||
#endif
|
||||
}
|
||||
|
||||
void CefWindowDelegateView::InitContent() {
|
||||
|
|
|
@ -57,6 +57,12 @@ patches = [
|
|||
'name': 'views_widget_180_1677',
|
||||
'path': '../ui/views/widget/',
|
||||
},
|
||||
{
|
||||
# Fix focus/activation handling and keyboard input on Linux.
|
||||
# https://bitbucket.org/chromiumembedded/cef/issues/1679
|
||||
'name': 'x11_desktop_handler_focus',
|
||||
'path': '../',
|
||||
},
|
||||
{
|
||||
# Allow continued use of ContentRendererClient::HandleNavigation.
|
||||
# https://code.google.com/p/chromiumembedded/issues/detail?id=1129
|
||||
|
|
|
@ -0,0 +1,82 @@
|
|||
diff --git content/browser/renderer_host/render_widget_host_view_aura.cc content/browser/renderer_host/render_widget_host_view_aura.cc
|
||||
index c7aac43..89817b7 100644
|
||||
--- content/browser/renderer_host/render_widget_host_view_aura.cc
|
||||
+++ content/browser/renderer_host/render_widget_host_view_aura.cc
|
||||
@@ -758,6 +758,13 @@ void RenderWidgetHostViewAura::SetKeyboardFocus() {
|
||||
::SetFocus(host->GetAcceleratedWidget());
|
||||
}
|
||||
#endif
|
||||
+#if defined(OS_LINUX)
|
||||
+ if (CanFocus()) {
|
||||
+ aura::WindowTreeHost* host = window_->GetHost();
|
||||
+ if (host)
|
||||
+ host->Show();
|
||||
+ }
|
||||
+#endif
|
||||
if (host_ && set_focus_on_mouse_down_) {
|
||||
set_focus_on_mouse_down_ = false;
|
||||
host_->Focus();
|
||||
diff --git ui/views/widget/desktop_aura/x11_desktop_handler.cc ui/views/widget/desktop_aura/x11_desktop_handler.cc
|
||||
index 5ab84f9..1052e2c 100644
|
||||
--- ui/views/widget/desktop_aura/x11_desktop_handler.cc
|
||||
+++ ui/views/widget/desktop_aura/x11_desktop_handler.cc
|
||||
@@ -31,6 +31,30 @@ views::X11DesktopHandler* g_handler = NULL;
|
||||
|
||||
namespace views {
|
||||
|
||||
+namespace {
|
||||
+
|
||||
+bool IsParentOfWindow(XDisplay* xdisplay,
|
||||
+ ::Window potential_parent,
|
||||
+ ::Window window) {
|
||||
+ ::Window parent_win, root_win;
|
||||
+ Window* child_windows;
|
||||
+ unsigned int num_child_windows;
|
||||
+ while (window) {
|
||||
+ if (!XQueryTree(xdisplay, window, &root_win, &parent_win,
|
||||
+ &child_windows, &num_child_windows)) {
|
||||
+ break;
|
||||
+ }
|
||||
+ if(child_windows)
|
||||
+ XFree(child_windows);
|
||||
+ if (parent_win == potential_parent)
|
||||
+ return true;
|
||||
+ window = parent_win;
|
||||
+ }
|
||||
+ return false;
|
||||
+}
|
||||
+
|
||||
+} // namespace
|
||||
+
|
||||
// static
|
||||
X11DesktopHandler* X11DesktopHandler::get() {
|
||||
if (!g_handler)
|
||||
@@ -58,14 +82,7 @@ X11DesktopHandler::X11DesktopHandler()
|
||||
attr.your_event_mask | PropertyChangeMask |
|
||||
StructureNotifyMask | SubstructureNotifyMask);
|
||||
|
||||
- if (ui::GuessWindowManager() == ui::WM_WMII) {
|
||||
- // wmii says that it supports _NET_ACTIVE_WINDOW but does not.
|
||||
- // https://code.google.com/p/wmii/issues/detail?id=266
|
||||
- wm_supports_active_window_ = false;
|
||||
- } else {
|
||||
- wm_supports_active_window_ =
|
||||
- ui::WmSupportsHint(atom_cache_.GetAtom("_NET_ACTIVE_WINDOW"));
|
||||
- }
|
||||
+ wm_supports_active_window_ = false;
|
||||
}
|
||||
|
||||
X11DesktopHandler::~X11DesktopHandler() {
|
||||
@@ -175,8 +192,10 @@ uint32_t X11DesktopHandler::DispatchEvent(const ui::PlatformEvent& event) {
|
||||
::Window window;
|
||||
if (ui::GetXIDProperty(x_root_window_, "_NET_ACTIVE_WINDOW", &window) &&
|
||||
window) {
|
||||
- x_active_window_ = window;
|
||||
- OnActiveWindowChanged(window, ACTIVE);
|
||||
+ if (!IsParentOfWindow(xdisplay_, window, current_window_)) {
|
||||
+ x_active_window_ = window;
|
||||
+ OnActiveWindowChanged(window, ACTIVE);
|
||||
+ }
|
||||
} else {
|
||||
x_active_window_ = None;
|
||||
}
|
|
@ -603,7 +603,31 @@ gboolean RootWindowGtk::URLEntryButtonPress(GtkWidget* widget,
|
|||
GdkWindow* gdk_window = gtk_widget_get_window(window);
|
||||
::Display* xdisplay = GDK_WINDOW_XDISPLAY(gdk_window);
|
||||
::Window xwindow = GDK_WINDOW_XID(gdk_window);
|
||||
XSetInputFocus(xdisplay, xwindow, RevertToParent, CurrentTime);
|
||||
|
||||
// Retrieve the atoms required by the below XSendEvent call.
|
||||
const char* kAtoms[] = {
|
||||
"WM_PROTOCOLS",
|
||||
"WM_TAKE_FOCUS"
|
||||
};
|
||||
Atom atoms[2];
|
||||
int result = XInternAtoms(xdisplay, const_cast<char**>(kAtoms), 2, false,
|
||||
atoms);
|
||||
if (!result)
|
||||
NOTREACHED();
|
||||
|
||||
XEvent e;
|
||||
e.type = ClientMessage;
|
||||
e.xany.display = xdisplay;
|
||||
e.xany.window = xwindow;
|
||||
e.xclient.format = 32;
|
||||
e.xclient.message_type = atoms[0];
|
||||
e.xclient.data.l[0] = atoms[1];
|
||||
e.xclient.data.l[1] = CurrentTime;
|
||||
e.xclient.data.l[2] = 0;
|
||||
e.xclient.data.l[3] = 0;
|
||||
e.xclient.data.l[4] = 0;
|
||||
|
||||
XSendEvent(xdisplay, xwindow, false, 0, &e);
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue