Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(218)

Side by Side Diff: ui/views/widget/desktop_aura/x11_desktop_handler.cc

Issue 219743002: x11: Move X event handling out of the message-pump. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: tot-merge-r261267 Created 6 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "ui/views/widget/desktop_aura/x11_desktop_handler.h" 5 #include "ui/views/widget/desktop_aura/x11_desktop_handler.h"
6 6
7 #include <X11/Xatom.h> 7 #include <X11/Xatom.h>
8 #include <X11/Xlib.h> 8 #include <X11/Xlib.h>
9 9
10 #include "base/message_loop/message_loop.h" 10 #include "base/message_loop/message_loop.h"
11 #include "ui/aura/env.h" 11 #include "ui/aura/env.h"
12 #include "ui/aura/window_event_dispatcher.h" 12 #include "ui/aura/window_event_dispatcher.h"
13 #include "ui/base/x/x11_menu_list.h" 13 #include "ui/base/x/x11_menu_list.h"
14 #include "ui/base/x/x11_util.h" 14 #include "ui/base/x/x11_util.h"
15 #include "ui/events/platform/platform_event_source.h"
15 #include "ui/gfx/x/x11_error_tracker.h" 16 #include "ui/gfx/x/x11_error_tracker.h"
16
17 #if !defined(OS_CHROMEOS)
18 #include "ui/views/ime/input_method.h" 17 #include "ui/views/ime/input_method.h"
19 #include "ui/views/widget/desktop_aura/desktop_window_tree_host_x11.h" 18 #include "ui/views/widget/desktop_aura/desktop_window_tree_host_x11.h"
20 #endif
21 19
22 namespace { 20 namespace {
23 21
24 const char* kAtomsToCache[] = { 22 const char* kAtomsToCache[] = {
25 "_NET_ACTIVE_WINDOW", 23 "_NET_ACTIVE_WINDOW",
26 NULL 24 NULL
27 }; 25 };
28 26
29 // Our global instance. Deleted when our Env() is deleted. 27 // Our global instance. Deleted when our Env() is deleted.
30 views::X11DesktopHandler* g_handler = NULL; 28 views::X11DesktopHandler* g_handler = NULL;
31 29
32 } // namespace 30 } // namespace
33 31
34 namespace views { 32 namespace views {
35 33
36 // static 34 // static
37 X11DesktopHandler* X11DesktopHandler::get() { 35 X11DesktopHandler* X11DesktopHandler::get() {
38 if (!g_handler) 36 if (!g_handler)
39 g_handler = new X11DesktopHandler; 37 g_handler = new X11DesktopHandler;
40 38
41 return g_handler; 39 return g_handler;
42 } 40 }
43 41
44 X11DesktopHandler::X11DesktopHandler() 42 X11DesktopHandler::X11DesktopHandler()
45 : xdisplay_(gfx::GetXDisplay()), 43 : xdisplay_(gfx::GetXDisplay()),
46 x_root_window_(DefaultRootWindow(xdisplay_)), 44 x_root_window_(DefaultRootWindow(xdisplay_)),
47 current_window_(None), 45 current_window_(None),
48 atom_cache_(xdisplay_, kAtomsToCache), 46 atom_cache_(xdisplay_, kAtomsToCache),
49 wm_supports_active_window_(false) { 47 wm_supports_active_window_(false) {
50 base::MessagePumpX11::Current()->AddDispatcherForRootWindow(this); 48 if (ui::PlatformEventSource::GetInstance())
49 ui::PlatformEventSource::GetInstance()->AddPlatformEventDispatcher(this);
51 aura::Env::GetInstance()->AddObserver(this); 50 aura::Env::GetInstance()->AddObserver(this);
52 51
53 XWindowAttributes attr; 52 XWindowAttributes attr;
54 XGetWindowAttributes(xdisplay_, x_root_window_, &attr); 53 XGetWindowAttributes(xdisplay_, x_root_window_, &attr);
55 XSelectInput(xdisplay_, x_root_window_, 54 XSelectInput(xdisplay_, x_root_window_,
56 attr.your_event_mask | PropertyChangeMask | 55 attr.your_event_mask | PropertyChangeMask |
57 StructureNotifyMask | SubstructureNotifyMask); 56 StructureNotifyMask | SubstructureNotifyMask);
58 57
59 ::Window active_window; 58 ::Window active_window;
60 wm_supports_active_window_ = 59 wm_supports_active_window_ =
61 ui::GetXIDProperty(x_root_window_, "_NET_ACTIVE_WINDOW", &active_window) && 60 ui::GetXIDProperty(x_root_window_, "_NET_ACTIVE_WINDOW", &active_window) &&
62 active_window; 61 active_window;
63 } 62 }
64 63
65 X11DesktopHandler::~X11DesktopHandler() { 64 X11DesktopHandler::~X11DesktopHandler() {
66 aura::Env::GetInstance()->RemoveObserver(this); 65 aura::Env::GetInstance()->RemoveObserver(this);
67 base::MessagePumpX11::Current()->RemoveDispatcherForRootWindow(this); 66 if (ui::PlatformEventSource::GetInstance())
67 ui::PlatformEventSource::GetInstance()->RemovePlatformEventDispatcher(this);
68 } 68 }
69 69
70 void X11DesktopHandler::ActivateWindow(::Window window) { 70 void X11DesktopHandler::ActivateWindow(::Window window) {
71 if (wm_supports_active_window_) { 71 if (wm_supports_active_window_) {
72 DCHECK_EQ(gfx::GetXDisplay(), xdisplay_); 72 DCHECK_EQ(gfx::GetXDisplay(), xdisplay_);
73 73
74 XEvent xclient; 74 XEvent xclient;
75 memset(&xclient, 0, sizeof(xclient)); 75 memset(&xclient, 0, sizeof(xclient));
76 xclient.type = ClientMessage; 76 xclient.type = ClientMessage;
77 xclient.xclient.window = window; 77 xclient.xclient.window = window;
(...skipping 17 matching lines...) Expand all
95 XSetInputFocus(xdisplay_, window, RevertToParent, CurrentTime); 95 XSetInputFocus(xdisplay_, window, RevertToParent, CurrentTime);
96 96
97 OnActiveWindowChanged(window); 97 OnActiveWindowChanged(window);
98 } 98 }
99 } 99 }
100 100
101 bool X11DesktopHandler::IsActiveWindow(::Window window) const { 101 bool X11DesktopHandler::IsActiveWindow(::Window window) const {
102 return window == current_window_; 102 return window == current_window_;
103 } 103 }
104 104
105 void X11DesktopHandler::ProcessXEvent(const base::NativeEvent& event) { 105 void X11DesktopHandler::ProcessXEvent(XEvent* event) {
106 switch (event->type) { 106 switch (event->type) {
107 case EnterNotify: 107 case EnterNotify:
108 if (event->xcrossing.focus == True && 108 if (event->xcrossing.focus == True &&
109 current_window_ != event->xcrossing.window) 109 current_window_ != event->xcrossing.window)
110 OnActiveWindowChanged(event->xcrossing.window); 110 OnActiveWindowChanged(event->xcrossing.window);
111 break; 111 break;
112 case LeaveNotify: 112 case LeaveNotify:
113 if (event->xcrossing.focus == False && 113 if (event->xcrossing.focus == False &&
114 current_window_ == event->xcrossing.window) 114 current_window_ == event->xcrossing.window)
115 OnActiveWindowChanged(None); 115 OnActiveWindowChanged(None);
116 break; 116 break;
117 case FocusIn: 117 case FocusIn:
118 if (event->xfocus.mode == NotifyNormal && 118 if (event->xfocus.mode == NotifyNormal &&
119 current_window_ != event->xfocus.window) 119 current_window_ != event->xfocus.window)
120 OnActiveWindowChanged(event->xfocus.window); 120 OnActiveWindowChanged(event->xfocus.window);
121 break; 121 break;
122 default: 122 default:
123 NOTREACHED(); 123 NOTREACHED();
124 } 124 }
125 } 125 }
126 126
127 uint32_t X11DesktopHandler::Dispatch(const base::NativeEvent& event) { 127 bool X11DesktopHandler::CanDispatchEvent(const ui::PlatformEvent& event) {
128 // Check for a change to the active window. 128 return event->type == CreateNotify || event->type == DestroyNotify ||
129 (event->type == PropertyNotify &&
130 event->xproperty.window == x_root_window_);
131 }
132
133 uint32_t X11DesktopHandler::DispatchEvent(const ui::PlatformEvent& event) {
129 switch (event->type) { 134 switch (event->type) {
130 case PropertyNotify: { 135 case PropertyNotify: {
136 // Check for a change to the active window.
137 CHECK_EQ(x_root_window_, event->xproperty.window);
131 ::Atom active_window_atom = atom_cache_.GetAtom("_NET_ACTIVE_WINDOW"); 138 ::Atom active_window_atom = atom_cache_.GetAtom("_NET_ACTIVE_WINDOW");
132 139 if (event->xproperty.atom == active_window_atom) {
133 if (event->xproperty.window == x_root_window_ &&
134 event->xproperty.atom == active_window_atom) {
135 ::Window window; 140 ::Window window;
136 if (ui::GetXIDProperty(x_root_window_, "_NET_ACTIVE_WINDOW", &window) && 141 if (ui::GetXIDProperty(x_root_window_, "_NET_ACTIVE_WINDOW", &window) &&
137 window) { 142 window) {
138 OnActiveWindowChanged(window); 143 OnActiveWindowChanged(window);
139 } 144 }
140 } 145 }
141 break; 146 break;
142 } 147 }
148
143 // Menus created by Chrome can be drag and drop targets. Since they are 149 // Menus created by Chrome can be drag and drop targets. Since they are
144 // direct children of the screen root window and have override_redirect 150 // direct children of the screen root window and have override_redirect
145 // we cannot use regular _NET_CLIENT_LIST_STACKING property to find them 151 // we cannot use regular _NET_CLIENT_LIST_STACKING property to find them
146 // and use a separate cache to keep track of them. 152 // and use a separate cache to keep track of them.
147 // TODO(varkha): Implement caching of all top level X windows and their 153 // TODO(varkha): Implement caching of all top level X windows and their
148 // coordinates and stacking order to eliminate repeated calls to X server 154 // coordinates and stacking order to eliminate repeated calls to X server
149 // during mouse movement, drag and shaping events. 155 // during mouse movement, drag and shaping events.
150 case CreateNotify: { 156 case CreateNotify: {
151 // The window might be destroyed if the message pump haven't gotten a 157 // The window might be destroyed if the message pump haven't gotten a
152 // chance to run but we can safely ignore the X error. 158 // chance to run but we can safely ignore the X error.
153 gfx::X11ErrorTracker error_tracker; 159 gfx::X11ErrorTracker error_tracker;
154 XCreateWindowEvent *xcwe = &event->xcreatewindow; 160 XCreateWindowEvent *xcwe = &event->xcreatewindow;
155 ui::XMenuList::GetInstance()->MaybeRegisterMenu(xcwe->window); 161 ui::XMenuList::GetInstance()->MaybeRegisterMenu(xcwe->window);
156 break; 162 break;
157 } 163 }
158 case DestroyNotify: { 164 case DestroyNotify: {
159 XDestroyWindowEvent *xdwe = &event->xdestroywindow; 165 XDestroyWindowEvent *xdwe = &event->xdestroywindow;
160 ui::XMenuList::GetInstance()->MaybeUnregisterMenu(xdwe->window); 166 ui::XMenuList::GetInstance()->MaybeUnregisterMenu(xdwe->window);
161 break; 167 break;
162 } 168 }
169 default:
170 NOTREACHED();
163 } 171 }
164 172
165 return POST_DISPATCH_NONE; 173 return ui::POST_DISPATCH_NONE;
166 } 174 }
167 175
168 void X11DesktopHandler::OnWindowInitialized(aura::Window* window) { 176 void X11DesktopHandler::OnWindowInitialized(aura::Window* window) {
169 } 177 }
170 178
171 void X11DesktopHandler::OnWillDestroyEnv() { 179 void X11DesktopHandler::OnWillDestroyEnv() {
172 g_handler = NULL; 180 g_handler = NULL;
173 delete this; 181 delete this;
174 } 182 }
175 183
176 void X11DesktopHandler::OnActiveWindowChanged(::Window xid) { 184 void X11DesktopHandler::OnActiveWindowChanged(::Window xid) {
177 if (current_window_ == xid) 185 if (current_window_ == xid)
178 return; 186 return;
179 DesktopWindowTreeHostX11* old_host = 187 DesktopWindowTreeHostX11* old_host =
180 views::DesktopWindowTreeHostX11::GetHostForXID(current_window_); 188 views::DesktopWindowTreeHostX11::GetHostForXID(current_window_);
181 if (old_host) 189 if (old_host)
182 old_host->HandleNativeWidgetActivationChanged(false); 190 old_host->HandleNativeWidgetActivationChanged(false);
183 191
184 DesktopWindowTreeHostX11* new_host = 192 DesktopWindowTreeHostX11* new_host =
185 views::DesktopWindowTreeHostX11::GetHostForXID(xid); 193 views::DesktopWindowTreeHostX11::GetHostForXID(xid);
186 if (new_host) 194 if (new_host)
187 new_host->HandleNativeWidgetActivationChanged(true); 195 new_host->HandleNativeWidgetActivationChanged(true);
188 196
189 current_window_ = xid; 197 current_window_ = xid;
190 } 198 }
191 199
192 } // namespace views 200 } // namespace views
OLDNEW
« no previous file with comments | « ui/views/widget/desktop_aura/x11_desktop_handler.h ('k') | ui/views/widget/desktop_aura/x11_whole_screen_move_loop.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698