summaryrefslogtreecommitdiffstats
path: root/chromium/ui/views/widget/desktop_aura/x11_desktop_handler.cc
diff options
context:
space:
mode:
Diffstat (limited to 'chromium/ui/views/widget/desktop_aura/x11_desktop_handler.cc')
-rw-r--r--chromium/ui/views/widget/desktop_aura/x11_desktop_handler.cc116
1 files changed, 72 insertions, 44 deletions
diff --git a/chromium/ui/views/widget/desktop_aura/x11_desktop_handler.cc b/chromium/ui/views/widget/desktop_aura/x11_desktop_handler.cc
index 0cfe040cbdf..d43b853093b 100644
--- a/chromium/ui/views/widget/desktop_aura/x11_desktop_handler.cc
+++ b/chromium/ui/views/widget/desktop_aura/x11_desktop_handler.cc
@@ -9,19 +9,18 @@
#include "base/message_loop/message_loop.h"
#include "ui/aura/env.h"
-#include "ui/aura/root_window.h"
+#include "ui/aura/window_event_dispatcher.h"
+#include "ui/base/x/x11_menu_list.h"
#include "ui/base/x/x11_util.h"
-
-#if !defined(OS_CHROMEOS)
+#include "ui/events/platform/platform_event_source.h"
+#include "ui/gfx/x/x11_error_tracker.h"
#include "ui/views/ime/input_method.h"
-#include "ui/views/widget/desktop_aura/desktop_root_window_host_x11.h"
-#endif
+#include "ui/views/widget/desktop_aura/desktop_window_tree_host_x11.h"
namespace {
const char* kAtomsToCache[] = {
"_NET_ACTIVE_WINDOW",
- "_NET_SUPPORTED",
NULL
};
@@ -43,10 +42,12 @@ X11DesktopHandler* X11DesktopHandler::get() {
X11DesktopHandler::X11DesktopHandler()
: xdisplay_(gfx::GetXDisplay()),
x_root_window_(DefaultRootWindow(xdisplay_)),
+ wm_user_time_ms_(0),
current_window_(None),
atom_cache_(xdisplay_, kAtomsToCache),
wm_supports_active_window_(false) {
- base::MessagePumpX11::Current()->AddDispatcherForRootWindow(this);
+ if (ui::PlatformEventSource::GetInstance())
+ ui::PlatformEventSource::GetInstance()->AddPlatformEventDispatcher(this);
aura::Env::GetInstance()->AddObserver(this);
XWindowAttributes attr;
@@ -55,22 +56,16 @@ X11DesktopHandler::X11DesktopHandler()
attr.your_event_mask | PropertyChangeMask |
StructureNotifyMask | SubstructureNotifyMask);
- std::vector<Atom> atoms;
- if (ui::GetAtomArrayProperty(x_root_window_, "_NET_ACTIVE_WINDOW", &atoms)) {
- Atom active_window = atom_cache_.GetAtom("_NET_ACTIVE_WINDOW");
- for (std::vector<Atom>::iterator iter = atoms.begin(); iter != atoms.end();
- ++iter) {
- if (*(iter) == active_window) {
- wm_supports_active_window_ = true;
- break;
- }
- }
- }
+ ::Window active_window;
+ wm_supports_active_window_ =
+ ui::GetXIDProperty(x_root_window_, "_NET_ACTIVE_WINDOW", &active_window) &&
+ active_window;
}
X11DesktopHandler::~X11DesktopHandler() {
aura::Env::GetInstance()->RemoveObserver(this);
- base::MessagePumpX11::Current()->RemoveDispatcherForRootWindow(this);
+ if (ui::PlatformEventSource::GetInstance())
+ ui::PlatformEventSource::GetInstance()->RemovePlatformEventDispatcher(this);
}
void X11DesktopHandler::ActivateWindow(::Window window) {
@@ -84,7 +79,7 @@ void X11DesktopHandler::ActivateWindow(::Window window) {
xclient.xclient.message_type = atom_cache_.GetAtom("_NET_ACTIVE_WINDOW");
xclient.xclient.format = 32;
xclient.xclient.data.l[0] = 1; // Specified we are an app.
- xclient.xclient.data.l[1] = CurrentTime;
+ xclient.xclient.data.l[1] = wm_user_time_ms_;
xclient.xclient.data.l[2] = None;
xclient.xclient.data.l[3] = 0;
xclient.xclient.data.l[4] = 0;
@@ -94,6 +89,12 @@ void X11DesktopHandler::ActivateWindow(::Window window) {
&xclient);
} else {
XRaiseWindow(xdisplay_, window);
+
+ // XRaiseWindow will not give input focus to the window. We now need to ask
+ // the X server to do that. Note that the call will raise an X error if the
+ // window is not mapped.
+ XSetInputFocus(xdisplay_, window, RevertToParent, CurrentTime);
+
OnActiveWindowChanged(window);
}
}
@@ -102,16 +103,14 @@ bool X11DesktopHandler::IsActiveWindow(::Window window) const {
return window == current_window_;
}
-void X11DesktopHandler::ProcessXEvent(const base::NativeEvent& event) {
+void X11DesktopHandler::ProcessXEvent(XEvent* event) {
switch (event->type) {
- case EnterNotify:
- if (event->xcrossing.focus == True &&
- current_window_ != event->xcrossing.window)
- OnActiveWindowChanged(event->xcrossing.window);
+ case FocusIn:
+ if (current_window_ != event->xfocus.window)
+ OnActiveWindowChanged(event->xfocus.window);
break;
- case LeaveNotify:
- if (event->xcrossing.focus == False &&
- current_window_ == event->xcrossing.window)
+ case FocusOut:
+ if (current_window_ == event->xfocus.window)
OnActiveWindowChanged(None);
break;
default:
@@ -119,25 +118,53 @@ void X11DesktopHandler::ProcessXEvent(const base::NativeEvent& event) {
}
}
-bool X11DesktopHandler::Dispatch(const base::NativeEvent& event) {
- // Check for a change to the active window.
+bool X11DesktopHandler::CanDispatchEvent(const ui::PlatformEvent& event) {
+ return event->type == CreateNotify || event->type == DestroyNotify ||
+ (event->type == PropertyNotify &&
+ event->xproperty.window == x_root_window_);
+}
+
+uint32_t X11DesktopHandler::DispatchEvent(const ui::PlatformEvent& event) {
switch (event->type) {
case PropertyNotify: {
- ::Atom active_window = atom_cache_.GetAtom("_NET_ACTIVE_WINDOW");
-
- if (event->xproperty.window == x_root_window_ &&
- event->xproperty.atom == active_window) {
- int window;
- if (ui::GetIntProperty(x_root_window_, "_NET_ACTIVE_WINDOW", &window) &&
+ // Check for a change to the active window.
+ CHECK_EQ(x_root_window_, event->xproperty.window);
+ ::Atom active_window_atom = atom_cache_.GetAtom("_NET_ACTIVE_WINDOW");
+ if (event->xproperty.atom == active_window_atom) {
+ ::Window window;
+ if (ui::GetXIDProperty(x_root_window_, "_NET_ACTIVE_WINDOW", &window) &&
window) {
- OnActiveWindowChanged(static_cast< ::Window>(window));
+ OnActiveWindowChanged(window);
}
}
break;
}
+
+ // Menus created by Chrome can be drag and drop targets. Since they are
+ // direct children of the screen root window and have override_redirect
+ // we cannot use regular _NET_CLIENT_LIST_STACKING property to find them
+ // and use a separate cache to keep track of them.
+ // TODO(varkha): Implement caching of all top level X windows and their
+ // coordinates and stacking order to eliminate repeated calls to X server
+ // during mouse movement, drag and shaping events.
+ case CreateNotify: {
+ // The window might be destroyed if the message pump haven't gotten a
+ // chance to run but we can safely ignore the X error.
+ gfx::X11ErrorTracker error_tracker;
+ XCreateWindowEvent *xcwe = &event->xcreatewindow;
+ ui::XMenuList::GetInstance()->MaybeRegisterMenu(xcwe->window);
+ break;
+ }
+ case DestroyNotify: {
+ XDestroyWindowEvent *xdwe = &event->xdestroywindow;
+ ui::XMenuList::GetInstance()->MaybeUnregisterMenu(xdwe->window);
+ break;
+ }
+ default:
+ NOTREACHED();
}
- return true;
+ return ui::POST_DISPATCH_NONE;
}
void X11DesktopHandler::OnWindowInitialized(aura::Window* window) {
@@ -151,17 +178,18 @@ void X11DesktopHandler::OnWillDestroyEnv() {
void X11DesktopHandler::OnActiveWindowChanged(::Window xid) {
if (current_window_ == xid)
return;
- DesktopRootWindowHostX11* old_host =
- views::DesktopRootWindowHostX11::GetHostForXID(current_window_);
+ DesktopWindowTreeHostX11* old_host =
+ views::DesktopWindowTreeHostX11::GetHostForXID(current_window_);
if (old_host)
old_host->HandleNativeWidgetActivationChanged(false);
- DesktopRootWindowHostX11* new_host =
- views::DesktopRootWindowHostX11::GetHostForXID(xid);
+ // Update the current window ID to effectively change the active widget.
+ current_window_ = xid;
+
+ DesktopWindowTreeHostX11* new_host =
+ views::DesktopWindowTreeHostX11::GetHostForXID(xid);
if (new_host)
new_host->HandleNativeWidgetActivationChanged(true);
-
- current_window_ = xid;
}
} // namespace views