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

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

Issue 22455002: linux_aura: Implement the static part of the dbus menu for Unity. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: The gyp fix Created 7 years, 4 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
« no previous file with comments | « ui/views/widget/desktop_aura/desktop_root_window_host_x11.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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/desktop_root_window_host_x11.h" 5 #include "ui/views/widget/desktop_aura/desktop_root_window_host_x11.h"
6 6
7 #include <X11/extensions/shape.h> 7 #include <X11/extensions/shape.h>
8 #include <X11/extensions/XInput2.h> 8 #include <X11/extensions/XInput2.h>
9 #include <X11/Xatom.h> 9 #include <X11/Xatom.h>
10 #include <X11/Xregion.h> 10 #include <X11/Xregion.h>
(...skipping 23 matching lines...) Expand all
34 #include "ui/views/ime/input_method.h" 34 #include "ui/views/ime/input_method.h"
35 #include "ui/views/widget/desktop_aura/desktop_activation_client.h" 35 #include "ui/views/widget/desktop_aura/desktop_activation_client.h"
36 #include "ui/views/widget/desktop_aura/desktop_capture_client.h" 36 #include "ui/views/widget/desktop_aura/desktop_capture_client.h"
37 #include "ui/views/widget/desktop_aura/desktop_cursor_loader_updater_aurax11.h" 37 #include "ui/views/widget/desktop_aura/desktop_cursor_loader_updater_aurax11.h"
38 #include "ui/views/widget/desktop_aura/desktop_dispatcher_client.h" 38 #include "ui/views/widget/desktop_aura/desktop_dispatcher_client.h"
39 #include "ui/views/widget/desktop_aura/desktop_drag_drop_client_aurax11.h" 39 #include "ui/views/widget/desktop_aura/desktop_drag_drop_client_aurax11.h"
40 #include "ui/views/widget/desktop_aura/desktop_focus_rules.h" 40 #include "ui/views/widget/desktop_aura/desktop_focus_rules.h"
41 #include "ui/views/widget/desktop_aura/desktop_layout_manager.h" 41 #include "ui/views/widget/desktop_aura/desktop_layout_manager.h"
42 #include "ui/views/widget/desktop_aura/desktop_native_cursor_manager.h" 42 #include "ui/views/widget/desktop_aura/desktop_native_cursor_manager.h"
43 #include "ui/views/widget/desktop_aura/desktop_native_widget_aura.h" 43 #include "ui/views/widget/desktop_aura/desktop_native_widget_aura.h"
44 #include "ui/views/widget/desktop_aura/desktop_root_window_host_observer_x11.h"
44 #include "ui/views/widget/desktop_aura/desktop_screen_position_client.h" 45 #include "ui/views/widget/desktop_aura/desktop_screen_position_client.h"
45 #include "ui/views/widget/desktop_aura/x11_desktop_handler.h" 46 #include "ui/views/widget/desktop_aura/x11_desktop_handler.h"
46 #include "ui/views/widget/desktop_aura/x11_desktop_window_move_client.h" 47 #include "ui/views/widget/desktop_aura/x11_desktop_window_move_client.h"
47 #include "ui/views/widget/desktop_aura/x11_window_event_filter.h" 48 #include "ui/views/widget/desktop_aura/x11_window_event_filter.h"
48 49
49 namespace views { 50 namespace views {
50 51
51 DesktopRootWindowHostX11* DesktopRootWindowHostX11::g_current_capture = 52 DesktopRootWindowHostX11* DesktopRootWindowHostX11::g_current_capture =
52 NULL; 53 NULL;
53 std::list<XID>* DesktopRootWindowHostX11::open_windows_ = NULL; 54 std::list<XID>* DesktopRootWindowHostX11::open_windows_ = NULL;
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after
128 129
129 DesktopRootWindowHostX11::~DesktopRootWindowHostX11() { 130 DesktopRootWindowHostX11::~DesktopRootWindowHostX11() {
130 root_window_->ClearProperty(kHostForRootWindow); 131 root_window_->ClearProperty(kHostForRootWindow);
131 if (corewm::UseFocusControllerOnDesktop()) { 132 if (corewm::UseFocusControllerOnDesktop()) {
132 aura::client::SetFocusClient(root_window_, NULL); 133 aura::client::SetFocusClient(root_window_, NULL);
133 aura::client::SetActivationClient(root_window_, NULL); 134 aura::client::SetActivationClient(root_window_, NULL);
134 } 135 }
135 } 136 }
136 137
137 // static 138 // static
138 ui::NativeTheme* DesktopRootWindowHost::GetNativeTheme(aura::Window* window) {
139 const ui::LinuxUI* linux_ui = ui::LinuxUI::instance();
140 if (linux_ui) {
141 ui::NativeTheme* native_theme = linux_ui->GetNativeTheme();
142 if (native_theme)
143 return native_theme;
144 }
145
146 return ui::NativeTheme::instance();
147 }
148
149 ////////////////////////////////////////////////////////////////////////////////
150 // DesktopRootWindowHostX11, private:
151
152 void DesktopRootWindowHostX11::InitX11Window(
153 const Widget::InitParams& params) {
154 unsigned long attribute_mask = CWBackPixmap;
155 XSetWindowAttributes swa;
156 memset(&swa, 0, sizeof(swa));
157 swa.background_pixmap = None;
158
159 ::Atom window_type;
160 switch (params.type) {
161 case Widget::InitParams::TYPE_MENU:
162 swa.override_redirect = True;
163 attribute_mask |= CWOverrideRedirect;
164 window_type = atom_cache_.GetAtom("_NET_WM_WINDOW_TYPE_MENU");
165 break;
166 case Widget::InitParams::TYPE_TOOLTIP:
167 window_type = atom_cache_.GetAtom("_NET_WM_WINDOW_TYPE_TOOLTIP");
168 break;
169 default:
170 window_type = atom_cache_.GetAtom("_NET_WM_WINDOW_TYPE_NORMAL");
171 break;
172 }
173
174 xwindow_ = XCreateWindow(
175 xdisplay_, x_root_window_,
176 params.bounds.x(), params.bounds.y(),
177 params.bounds.width(), params.bounds.height(),
178 0, // border width
179 CopyFromParent, // depth
180 InputOutput,
181 CopyFromParent, // visual
182 attribute_mask,
183 &swa);
184 base::MessagePumpAuraX11::Current()->AddDispatcherForWindow(this, xwindow_);
185 open_windows().push_back(xwindow_);
186
187 // TODO(erg): Maybe need to set a ViewProp here like in RWHL::RWHL().
188
189 long event_mask = ButtonPressMask | ButtonReleaseMask | FocusChangeMask |
190 KeyPressMask | KeyReleaseMask |
191 EnterWindowMask | LeaveWindowMask |
192 ExposureMask | VisibilityChangeMask |
193 StructureNotifyMask | PropertyChangeMask |
194 PointerMotionMask;
195 XSelectInput(xdisplay_, xwindow_, event_mask);
196 XFlush(xdisplay_);
197
198 if (base::MessagePumpForUI::HasXInput2())
199 ui::TouchFactory::GetInstance()->SetupXI2ForXWindow(xwindow_);
200
201 // TODO(erg): We currently only request window deletion events. We also
202 // should listen for activation events and anything else that GTK+ listens
203 // for, and do something useful.
204 ::Atom protocols[2];
205 protocols[0] = atom_cache_.GetAtom("WM_DELETE_WINDOW");
206 protocols[1] = atom_cache_.GetAtom("_NET_WM_PING");
207 XSetWMProtocols(xdisplay_, xwindow_, protocols, 2);
208
209 // We need a WM_CLIENT_MACHINE and WM_LOCALE_NAME value so we integrate with
210 // the desktop environment.
211 XSetWMProperties(xdisplay_, xwindow_, NULL, NULL, NULL, 0, NULL, NULL, NULL);
212
213 // Likewise, the X server needs to know this window's pid so it knows which
214 // program to kill if the window hangs.
215 pid_t pid = getpid();
216 XChangeProperty(xdisplay_,
217 xwindow_,
218 atom_cache_.GetAtom("_NET_WM_PID"),
219 XA_CARDINAL,
220 32,
221 PropModeReplace,
222 reinterpret_cast<unsigned char*>(&pid), 1);
223
224 XChangeProperty(xdisplay_,
225 xwindow_,
226 atom_cache_.GetAtom("_NET_WM_WINDOW_TYPE"),
227 XA_ATOM,
228 32,
229 PropModeReplace,
230 reinterpret_cast<unsigned char*>(&window_type), 1);
231
232 // Remove popup windows from taskbar.
233 if (params.type == Widget::InitParams::TYPE_POPUP ||
234 params.type == Widget::InitParams::TYPE_BUBBLE) {
235 Atom atom = atom_cache_.GetAtom("_NET_WM_STATE_SKIP_TASKBAR");
236
237 // Setting _NET_WM_STATE by sending a message to the root_window (with
238 // SetWMSpecState) has no effect here since the window has not yet been
239 // mapped. So we manually change the state.
240 XChangeProperty (xdisplay_,
241 xwindow_,
242 atom_cache_.GetAtom("_NET_WM_STATE"),
243 XA_ATOM,
244 32,
245 PropModeAppend,
246 reinterpret_cast<unsigned char*>(&atom), 1);
247 }
248 }
249
250 // static
251 aura::Window* DesktopRootWindowHostX11::GetContentWindowForXID(XID xid) { 139 aura::Window* DesktopRootWindowHostX11::GetContentWindowForXID(XID xid) {
252 aura::RootWindow* root = aura::RootWindow::GetForAcceleratedWidget(xid); 140 aura::RootWindow* root = aura::RootWindow::GetForAcceleratedWidget(xid);
253 return root ? root->GetProperty(kViewsWindowForRootWindow) : NULL; 141 return root ? root->GetProperty(kViewsWindowForRootWindow) : NULL;
254 } 142 }
255 143
256 // static 144 // static
257 DesktopRootWindowHostX11* DesktopRootWindowHostX11::GetHostForXID(XID xid) { 145 DesktopRootWindowHostX11* DesktopRootWindowHostX11::GetHostForXID(XID xid) {
258 aura::RootWindow* root = aura::RootWindow::GetForAcceleratedWidget(xid); 146 aura::RootWindow* root = aura::RootWindow::GetForAcceleratedWidget(xid);
259 return root ? root->GetProperty(kHostForRootWindow) : NULL; 147 return root ? root->GetProperty(kHostForRootWindow) : NULL;
260 } 148 }
261 149
262 // static 150 // static
263 std::vector<aura::Window*> DesktopRootWindowHostX11::GetAllOpenWindows() { 151 std::vector<aura::Window*> DesktopRootWindowHostX11::GetAllOpenWindows() {
264 std::vector<aura::Window*> windows(open_windows().size()); 152 std::vector<aura::Window*> windows(open_windows().size());
265 std::transform(open_windows().begin(), 153 std::transform(open_windows().begin(),
266 open_windows().end(), 154 open_windows().end(),
267 windows.begin(), 155 windows.begin(),
268 GetContentWindowForXID); 156 GetContentWindowForXID);
269 return windows; 157 return windows;
270 } 158 }
271 159
272 void DesktopRootWindowHostX11::HandleNativeWidgetActivationChanged( 160 void DesktopRootWindowHostX11::HandleNativeWidgetActivationChanged(
273 bool active) { 161 bool active) {
274 native_widget_delegate_->OnNativeWidgetActivationChanged(active); 162 native_widget_delegate_->OnNativeWidgetActivationChanged(active);
275 native_widget_delegate_->AsWidget()->GetRootView()->SchedulePaint(); 163 native_widget_delegate_->AsWidget()->GetRootView()->SchedulePaint();
276 } 164 }
277 165
166 void DesktopRootWindowHostX11::AddObserver(
167 views::DesktopRootWindowHostObserverX11* observer) {
168 observer_list_.AddObserver(observer);
169 }
170
171 void DesktopRootWindowHostX11::RemoveObserver(
172 views::DesktopRootWindowHostObserverX11* observer) {
173 observer_list_.RemoveObserver(observer);
174 }
175
278 void DesktopRootWindowHostX11::CleanUpWindowList() { 176 void DesktopRootWindowHostX11::CleanUpWindowList() {
279 delete open_windows_; 177 delete open_windows_;
280 open_windows_ = NULL; 178 open_windows_ = NULL;
281 } 179 }
282 180
283 // TODO(erg): This method should basically be everything I need form
284 // RootWindowHostX11::RootWindowHostX11().
285 aura::RootWindow* DesktopRootWindowHostX11::InitRootWindow(
286 const Widget::InitParams& params) {
287 bounds_ = params.bounds;
288
289 aura::RootWindow::CreateParams rw_params(bounds_);
290 rw_params.host = this;
291 root_window_ = new aura::RootWindow(rw_params);
292 root_window_->Init();
293 root_window_->AddChild(content_window_);
294 root_window_->SetLayoutManager(new DesktopLayoutManager(root_window_));
295 root_window_->SetProperty(kViewsWindowForRootWindow, content_window_);
296 root_window_->SetProperty(kHostForRootWindow, this);
297 root_window_host_delegate_ = root_window_;
298
299 // If we're given a parent, we need to mark ourselves as transient to another
300 // window. Otherwise activation gets screwy.
301 gfx::NativeView parent = params.parent;
302 if (!params.child && params.parent)
303 parent->AddTransientChild(content_window_);
304
305 native_widget_delegate_->OnNativeWidgetCreated(true);
306
307 capture_client_.reset(new views::DesktopCaptureClient(root_window_));
308 aura::client::SetCaptureClient(root_window_, capture_client_.get());
309
310 // Ensure that the X11DesktopHandler exists so that it dispatches activation
311 // messages to us.
312 X11DesktopHandler::get();
313
314 if (corewm::UseFocusControllerOnDesktop()) {
315 corewm::FocusController* focus_controller =
316 new corewm::FocusController(new DesktopFocusRules);
317 focus_client_.reset(focus_controller);
318 aura::client::SetFocusClient(root_window_, focus_controller);
319 aura::client::SetActivationClient(root_window_, focus_controller);
320 root_window_->AddPreTargetHandler(focus_controller);
321 } else {
322 focus_client_.reset(new aura::FocusManager);
323 aura::client::SetFocusClient(root_window_, focus_client_.get());
324 activation_client_.reset(new DesktopActivationClient(root_window_));
325 }
326
327 dispatcher_client_.reset(new DesktopDispatcherClient);
328 aura::client::SetDispatcherClient(root_window_,
329 dispatcher_client_.get());
330
331 views::DesktopNativeCursorManager* desktop_native_cursor_manager =
332 new views::DesktopNativeCursorManager(
333 root_window_,
334 scoped_ptr<DesktopCursorLoaderUpdater>(
335 new DesktopCursorLoaderUpdaterAuraX11));
336 cursor_client_.reset(
337 new views::corewm::CursorManager(
338 scoped_ptr<corewm::NativeCursorManager>(
339 desktop_native_cursor_manager)));
340 aura::client::SetCursorClient(root_window_,
341 cursor_client_.get());
342
343 position_client_.reset(new DesktopScreenPositionClient);
344 aura::client::SetScreenPositionClient(root_window_,
345 position_client_.get());
346
347 desktop_native_widget_aura_->InstallInputMethodEventFilter(root_window_);
348
349 drag_drop_client_.reset(new DesktopDragDropClientAuraX11(
350 this, root_window_, desktop_native_cursor_manager, xdisplay_, xwindow_));
351 aura::client::SetDragDropClient(root_window_, drag_drop_client_.get());
352
353 // TODO(erg): Unify this code once the other consumer goes away.
354 x11_window_event_filter_.reset(
355 new X11WindowEventFilter(root_window_, activation_client_.get()));
356 x11_window_event_filter_->SetUseHostWindowBorders(false);
357 desktop_native_widget_aura_->root_window_event_filter()->AddHandler(
358 x11_window_event_filter_.get());
359
360 x11_window_move_client_.reset(new X11DesktopWindowMoveClient);
361 aura::client::SetWindowMoveClient(root_window_,
362 x11_window_move_client_.get());
363
364 focus_client_->FocusWindow(content_window_);
365 return root_window_;
366 }
367
368 bool DesktopRootWindowHostX11::IsWindowManagerPresent() {
369 // Per ICCCM 2.8, "Manager Selections", window managers should take ownership
370 // of WM_Sn selections (where n is a screen number).
371 return XGetSelectionOwner(
372 xdisplay_, atom_cache_.GetAtom("WM_S0")) != None;
373 }
374
375 void DesktopRootWindowHostX11::SetWMSpecState(bool enabled,
376 ::Atom state1,
377 ::Atom state2) {
378 XEvent xclient;
379 memset(&xclient, 0, sizeof(xclient));
380 xclient.type = ClientMessage;
381 xclient.xclient.window = xwindow_;
382 xclient.xclient.message_type = atom_cache_.GetAtom("_NET_WM_STATE");
383 xclient.xclient.format = 32;
384 xclient.xclient.data.l[0] =
385 enabled ? k_NET_WM_STATE_ADD : k_NET_WM_STATE_REMOVE;
386 xclient.xclient.data.l[1] = state1;
387 xclient.xclient.data.l[2] = state2;
388 xclient.xclient.data.l[3] = 1;
389 xclient.xclient.data.l[4] = 0;
390
391 XSendEvent(xdisplay_, x_root_window_, False,
392 SubstructureRedirectMask | SubstructureNotifyMask,
393 &xclient);
394 }
395
396 bool DesktopRootWindowHostX11::HasWMSpecProperty(const char* property) const {
397 return window_properties_.find(atom_cache_.GetAtom(property)) !=
398 window_properties_.end();
399 }
400
401 //////////////////////////////////////////////////////////////////////////////// 181 ////////////////////////////////////////////////////////////////////////////////
402 // DesktopRootWindowHostX11, DesktopRootWindowHost implementation: 182 // DesktopRootWindowHostX11, DesktopRootWindowHost implementation:
403 183
404 aura::RootWindow* DesktopRootWindowHostX11::Init( 184 aura::RootWindow* DesktopRootWindowHostX11::Init(
405 aura::Window* content_window, 185 aura::Window* content_window,
406 const Widget::InitParams& params) { 186 const Widget::InitParams& params) {
407 content_window_ = content_window; 187 content_window_ = content_window;
408 188
409 // TODO(erg): Check whether we *should* be building a RootWindowHost here, or 189 // TODO(erg): Check whether we *should* be building a RootWindowHost here, or
410 // whether we should be proxying requests to another DRWHL. 190 // whether we should be proxying requests to another DRWHL.
(...skipping 207 matching lines...) Expand 10 before | Expand all | Expand 10 after
618 398
619 bool DesktopRootWindowHostX11::IsMaximized() const { 399 bool DesktopRootWindowHostX11::IsMaximized() const {
620 return (HasWMSpecProperty("_NET_WM_STATE_MAXIMIZED_VERT") || 400 return (HasWMSpecProperty("_NET_WM_STATE_MAXIMIZED_VERT") ||
621 HasWMSpecProperty("_NET_WM_STATE_MAXIMIZED_HORZ")); 401 HasWMSpecProperty("_NET_WM_STATE_MAXIMIZED_HORZ"));
622 } 402 }
623 403
624 bool DesktopRootWindowHostX11::IsMinimized() const { 404 bool DesktopRootWindowHostX11::IsMinimized() const {
625 return HasWMSpecProperty("_NET_WM_STATE_HIDDEN"); 405 return HasWMSpecProperty("_NET_WM_STATE_HIDDEN");
626 } 406 }
627 407
628 void DesktopRootWindowHostX11::OnCaptureReleased() {
629 native_widget_delegate_->OnMouseCaptureLost();
630 g_current_capture = NULL;
631 }
632
633 void DesktopRootWindowHostX11::DispatchMouseEvent(ui::MouseEvent* event) {
634 if (!g_current_capture || g_current_capture == this) {
635 root_window_host_delegate_->OnHostMouseEvent(event);
636 } else {
637 // Another DesktopRootWindowHostX11 has installed itself as
638 // capture. Translate the event's location and dispatch to the other.
639 event->ConvertLocationToTarget(root_window_,
640 g_current_capture->root_window_);
641 g_current_capture->root_window_host_delegate_->OnHostMouseEvent(event);
642 }
643 }
644
645 std::list<XID>& DesktopRootWindowHostX11::open_windows() {
646 if (!open_windows_)
647 open_windows_ = new std::list<XID>();
648 return *open_windows_;
649 }
650 408
651 bool DesktopRootWindowHostX11::HasCapture() const { 409 bool DesktopRootWindowHostX11::HasCapture() const {
652 return g_current_capture == this; 410 return g_current_capture == this;
653 } 411 }
654 412
655 void DesktopRootWindowHostX11::SetAlwaysOnTop(bool always_on_top) { 413 void DesktopRootWindowHostX11::SetAlwaysOnTop(bool always_on_top) {
656 SetWMSpecState(always_on_top, 414 SetWMSpecState(always_on_top,
657 atom_cache_.GetAtom("_NET_WM_STATE_ABOVE"), 415 atom_cache_.GetAtom("_NET_WM_STATE_ABOVE"),
658 None); 416 None);
659 } 417 }
(...skipping 339 matching lines...) Expand 10 before | Expand all | Expand 10 after
999 } 757 }
1000 758
1001 void DesktopRootWindowHostX11::OnDeviceScaleFactorChanged( 759 void DesktopRootWindowHostX11::OnDeviceScaleFactorChanged(
1002 float device_scale_factor) { 760 float device_scale_factor) {
1003 } 761 }
1004 762
1005 void DesktopRootWindowHostX11::PrepareForShutdown() { 763 void DesktopRootWindowHostX11::PrepareForShutdown() {
1006 } 764 }
1007 765
1008 //////////////////////////////////////////////////////////////////////////////// 766 ////////////////////////////////////////////////////////////////////////////////
767 // DesktopRootWindowHostX11, private:
768
769 void DesktopRootWindowHostX11::InitX11Window(
770 const Widget::InitParams& params) {
771 unsigned long attribute_mask = CWBackPixmap;
772 XSetWindowAttributes swa;
773 memset(&swa, 0, sizeof(swa));
774 swa.background_pixmap = None;
775
776 ::Atom window_type;
777 switch (params.type) {
778 case Widget::InitParams::TYPE_MENU:
779 swa.override_redirect = True;
780 attribute_mask |= CWOverrideRedirect;
781 window_type = atom_cache_.GetAtom("_NET_WM_WINDOW_TYPE_MENU");
782 break;
783 case Widget::InitParams::TYPE_TOOLTIP:
784 window_type = atom_cache_.GetAtom("_NET_WM_WINDOW_TYPE_TOOLTIP");
785 break;
786 default:
787 window_type = atom_cache_.GetAtom("_NET_WM_WINDOW_TYPE_NORMAL");
788 break;
789 }
790
791 xwindow_ = XCreateWindow(
792 xdisplay_, x_root_window_,
793 params.bounds.x(), params.bounds.y(),
794 params.bounds.width(), params.bounds.height(),
795 0, // border width
796 CopyFromParent, // depth
797 InputOutput,
798 CopyFromParent, // visual
799 attribute_mask,
800 &swa);
801 base::MessagePumpAuraX11::Current()->AddDispatcherForWindow(this, xwindow_);
802
803 // TODO(erg): Maybe need to set a ViewProp here like in RWHL::RWHL().
804
805 long event_mask = ButtonPressMask | ButtonReleaseMask | FocusChangeMask |
806 KeyPressMask | KeyReleaseMask |
807 EnterWindowMask | LeaveWindowMask |
808 ExposureMask | VisibilityChangeMask |
809 StructureNotifyMask | PropertyChangeMask |
810 PointerMotionMask;
811 XSelectInput(xdisplay_, xwindow_, event_mask);
812 XFlush(xdisplay_);
813
814 if (base::MessagePumpForUI::HasXInput2())
815 ui::TouchFactory::GetInstance()->SetupXI2ForXWindow(xwindow_);
816
817 // TODO(erg): We currently only request window deletion events. We also
818 // should listen for activation events and anything else that GTK+ listens
819 // for, and do something useful.
820 ::Atom protocols[2];
821 protocols[0] = atom_cache_.GetAtom("WM_DELETE_WINDOW");
822 protocols[1] = atom_cache_.GetAtom("_NET_WM_PING");
823 XSetWMProtocols(xdisplay_, xwindow_, protocols, 2);
824
825 // We need a WM_CLIENT_MACHINE and WM_LOCALE_NAME value so we integrate with
826 // the desktop environment.
827 XSetWMProperties(xdisplay_, xwindow_, NULL, NULL, NULL, 0, NULL, NULL, NULL);
828
829 // Likewise, the X server needs to know this window's pid so it knows which
830 // program to kill if the window hangs.
831 pid_t pid = getpid();
832 XChangeProperty(xdisplay_,
833 xwindow_,
834 atom_cache_.GetAtom("_NET_WM_PID"),
835 XA_CARDINAL,
836 32,
837 PropModeReplace,
838 reinterpret_cast<unsigned char*>(&pid), 1);
839
840 XChangeProperty(xdisplay_,
841 xwindow_,
842 atom_cache_.GetAtom("_NET_WM_WINDOW_TYPE"),
843 XA_ATOM,
844 32,
845 PropModeReplace,
846 reinterpret_cast<unsigned char*>(&window_type), 1);
847
848 // Remove popup windows from taskbar.
849 if (params.type == Widget::InitParams::TYPE_POPUP ||
850 params.type == Widget::InitParams::TYPE_BUBBLE) {
851 Atom atom = atom_cache_.GetAtom("_NET_WM_STATE_SKIP_TASKBAR");
852
853 // Setting _NET_WM_STATE by sending a message to the root_window (with
854 // SetWMSpecState) has no effect here since the window has not yet been
855 // mapped. So we manually change the state.
856 XChangeProperty (xdisplay_,
857 xwindow_,
858 atom_cache_.GetAtom("_NET_WM_STATE"),
859 XA_ATOM,
860 32,
861 PropModeAppend,
862 reinterpret_cast<unsigned char*>(&atom), 1);
863 }
864 }
865
866 // TODO(erg): This method should basically be everything I need form
867 // RootWindowHostX11::RootWindowHostX11().
868 aura::RootWindow* DesktopRootWindowHostX11::InitRootWindow(
869 const Widget::InitParams& params) {
870 bounds_ = params.bounds;
871
872 aura::RootWindow::CreateParams rw_params(bounds_);
873 rw_params.host = this;
874 root_window_ = new aura::RootWindow(rw_params);
875 root_window_->Init();
876 root_window_->AddChild(content_window_);
877 root_window_->SetLayoutManager(new DesktopLayoutManager(root_window_));
878 root_window_->SetProperty(kViewsWindowForRootWindow, content_window_);
879 root_window_->SetProperty(kHostForRootWindow, this);
880 root_window_host_delegate_ = root_window_;
881
882 // If we're given a parent, we need to mark ourselves as transient to another
883 // window. Otherwise activation gets screwy.
884 gfx::NativeView parent = params.parent;
885 if (!params.child && params.parent)
886 parent->AddTransientChild(content_window_);
887
888 native_widget_delegate_->OnNativeWidgetCreated(true);
889
890 capture_client_.reset(new views::DesktopCaptureClient(root_window_));
891 aura::client::SetCaptureClient(root_window_, capture_client_.get());
892
893 // Ensure that the X11DesktopHandler exists so that it dispatches activation
894 // messages to us.
895 X11DesktopHandler::get();
896
897 if (corewm::UseFocusControllerOnDesktop()) {
898 corewm::FocusController* focus_controller =
899 new corewm::FocusController(new DesktopFocusRules);
900 focus_client_.reset(focus_controller);
901 aura::client::SetFocusClient(root_window_, focus_controller);
902 aura::client::SetActivationClient(root_window_, focus_controller);
903 root_window_->AddPreTargetHandler(focus_controller);
904 } else {
905 focus_client_.reset(new aura::FocusManager);
906 aura::client::SetFocusClient(root_window_, focus_client_.get());
907 activation_client_.reset(new DesktopActivationClient(root_window_));
908 }
909
910 dispatcher_client_.reset(new DesktopDispatcherClient);
911 aura::client::SetDispatcherClient(root_window_,
912 dispatcher_client_.get());
913
914 views::DesktopNativeCursorManager* desktop_native_cursor_manager =
915 new views::DesktopNativeCursorManager(
916 root_window_,
917 scoped_ptr<DesktopCursorLoaderUpdater>(
918 new DesktopCursorLoaderUpdaterAuraX11));
919 cursor_client_.reset(
920 new views::corewm::CursorManager(
921 scoped_ptr<corewm::NativeCursorManager>(
922 desktop_native_cursor_manager)));
923 aura::client::SetCursorClient(root_window_,
924 cursor_client_.get());
925
926 position_client_.reset(new DesktopScreenPositionClient);
927 aura::client::SetScreenPositionClient(root_window_,
928 position_client_.get());
929
930 desktop_native_widget_aura_->InstallInputMethodEventFilter(root_window_);
931
932 drag_drop_client_.reset(new DesktopDragDropClientAuraX11(
933 this, root_window_, desktop_native_cursor_manager, xdisplay_, xwindow_));
934 aura::client::SetDragDropClient(root_window_, drag_drop_client_.get());
935
936 // TODO(erg): Unify this code once the other consumer goes away.
937 x11_window_event_filter_.reset(
938 new X11WindowEventFilter(root_window_, activation_client_.get()));
939 x11_window_event_filter_->SetUseHostWindowBorders(false);
940 desktop_native_widget_aura_->root_window_event_filter()->AddHandler(
941 x11_window_event_filter_.get());
942
943 x11_window_move_client_.reset(new X11DesktopWindowMoveClient);
944 aura::client::SetWindowMoveClient(root_window_,
945 x11_window_move_client_.get());
946
947 focus_client_->FocusWindow(content_window_);
948 return root_window_;
949 }
950
951 bool DesktopRootWindowHostX11::IsWindowManagerPresent() {
952 // Per ICCCM 2.8, "Manager Selections", window managers should take ownership
953 // of WM_Sn selections (where n is a screen number).
954 return XGetSelectionOwner(
955 xdisplay_, atom_cache_.GetAtom("WM_S0")) != None;
956 }
957
958 void DesktopRootWindowHostX11::SetWMSpecState(bool enabled,
959 ::Atom state1,
960 ::Atom state2) {
961 XEvent xclient;
962 memset(&xclient, 0, sizeof(xclient));
963 xclient.type = ClientMessage;
964 xclient.xclient.window = xwindow_;
965 xclient.xclient.message_type = atom_cache_.GetAtom("_NET_WM_STATE");
966 xclient.xclient.format = 32;
967 xclient.xclient.data.l[0] =
968 enabled ? k_NET_WM_STATE_ADD : k_NET_WM_STATE_REMOVE;
969 xclient.xclient.data.l[1] = state1;
970 xclient.xclient.data.l[2] = state2;
971 xclient.xclient.data.l[3] = 1;
972 xclient.xclient.data.l[4] = 0;
973
974 XSendEvent(xdisplay_, x_root_window_, False,
975 SubstructureRedirectMask | SubstructureNotifyMask,
976 &xclient);
977 }
978
979 bool DesktopRootWindowHostX11::HasWMSpecProperty(const char* property) const {
980 return window_properties_.find(atom_cache_.GetAtom(property)) !=
981 window_properties_.end();
982 }
983
984 void DesktopRootWindowHostX11::OnCaptureReleased() {
985 native_widget_delegate_->OnMouseCaptureLost();
986 g_current_capture = NULL;
987 }
988
989 void DesktopRootWindowHostX11::DispatchMouseEvent(ui::MouseEvent* event) {
990 if (!g_current_capture || g_current_capture == this) {
991 root_window_host_delegate_->OnHostMouseEvent(event);
992 } else {
993 // Another DesktopRootWindowHostX11 has installed itself as
994 // capture. Translate the event's location and dispatch to the other.
995 event->ConvertLocationToTarget(root_window_,
996 g_current_capture->root_window_);
997 g_current_capture->root_window_host_delegate_->OnHostMouseEvent(event);
998 }
999 }
1000
1001 std::list<XID>& DesktopRootWindowHostX11::open_windows() {
1002 if (!open_windows_)
1003 open_windows_ = new std::list<XID>();
1004 return *open_windows_;
1005 }
1006
1007 ////////////////////////////////////////////////////////////////////////////////
1009 // DesktopRootWindowHostX11, MessageLoop::Dispatcher implementation: 1008 // DesktopRootWindowHostX11, MessageLoop::Dispatcher implementation:
1010 1009
1011 bool DesktopRootWindowHostX11::Dispatch(const base::NativeEvent& event) { 1010 bool DesktopRootWindowHostX11::Dispatch(const base::NativeEvent& event) {
1012 XEvent* xev = event; 1011 XEvent* xev = event;
1013 1012
1014 // May want to factor CheckXEventForConsistency(xev); into a common location 1013 // May want to factor CheckXEventForConsistency(xev); into a common location
1015 // since it is called here. 1014 // since it is called here.
1016 switch (xev->type) { 1015 switch (xev->type) {
1017 case EnterNotify: 1016 case EnterNotify:
1018 case LeaveNotify: { 1017 case LeaveNotify: {
(...skipping 156 matching lines...) Expand 10 before | Expand all | Expand 10 after
1175 // If we coalesced an event we need to free its cookie. 1174 // If we coalesced an event we need to free its cookie.
1176 if (num_coalesced > 0) 1175 if (num_coalesced > 0)
1177 XFreeEventData(xev->xgeneric.display, &last_event.xcookie); 1176 XFreeEventData(xev->xgeneric.display, &last_event.xcookie);
1178 break; 1177 break;
1179 } 1178 }
1180 case MapNotify: { 1179 case MapNotify: {
1181 // If there's no window manager running, we need to assign the X input 1180 // If there's no window manager running, we need to assign the X input
1182 // focus to our host window. 1181 // focus to our host window.
1183 if (!IsWindowManagerPresent() && focus_when_shown_) 1182 if (!IsWindowManagerPresent() && focus_when_shown_)
1184 XSetInputFocus(xdisplay_, xwindow_, RevertToNone, CurrentTime); 1183 XSetInputFocus(xdisplay_, xwindow_, RevertToNone, CurrentTime);
1184
1185 FOR_EACH_OBSERVER(DesktopRootWindowHostObserverX11,
1186 observer_list_,
1187 OnWindowMapped(xwindow_));
1188 break;
1189 }
1190 case UnmapNotify: {
1191 FOR_EACH_OBSERVER(DesktopRootWindowHostObserverX11,
1192 observer_list_,
1193 OnWindowUnmapped(xwindow_));
1185 break; 1194 break;
1186 } 1195 }
1187 case ClientMessage: { 1196 case ClientMessage: {
1188 Atom message_type = xev->xclient.message_type; 1197 Atom message_type = xev->xclient.message_type;
1189 if (message_type == atom_cache_.GetAtom("WM_PROTOCOLS")) { 1198 if (message_type == atom_cache_.GetAtom("WM_PROTOCOLS")) {
1190 Atom protocol = static_cast<Atom>(xev->xclient.data.l[0]); 1199 Atom protocol = static_cast<Atom>(xev->xclient.data.l[0]);
1191 if (protocol == atom_cache_.GetAtom("WM_DELETE_WINDOW")) { 1200 if (protocol == atom_cache_.GetAtom("WM_DELETE_WINDOW")) {
1192 // We have received a close message from the window manager. 1201 // We have received a close message from the window manager.
1193 root_window_->OnRootWindowHostCloseRequested(); 1202 root_window_->OnRootWindowHostCloseRequested();
1194 } else if (protocol == atom_cache_.GetAtom("_NET_WM_PING")) { 1203 } else if (protocol == atom_cache_.GetAtom("_NET_WM_PING")) {
(...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after
1312 // static 1321 // static
1313 DesktopRootWindowHost* DesktopRootWindowHost::Create( 1322 DesktopRootWindowHost* DesktopRootWindowHost::Create(
1314 internal::NativeWidgetDelegate* native_widget_delegate, 1323 internal::NativeWidgetDelegate* native_widget_delegate,
1315 DesktopNativeWidgetAura* desktop_native_widget_aura, 1324 DesktopNativeWidgetAura* desktop_native_widget_aura,
1316 const gfx::Rect& initial_bounds) { 1325 const gfx::Rect& initial_bounds) {
1317 return new DesktopRootWindowHostX11(native_widget_delegate, 1326 return new DesktopRootWindowHostX11(native_widget_delegate,
1318 desktop_native_widget_aura, 1327 desktop_native_widget_aura,
1319 initial_bounds); 1328 initial_bounds);
1320 } 1329 }
1321 1330
1331 // static
1332 ui::NativeTheme* DesktopRootWindowHost::GetNativeTheme(aura::Window* window) {
1333 const ui::LinuxUI* linux_ui = ui::LinuxUI::instance();
1334 if (linux_ui) {
1335 ui::NativeTheme* native_theme = linux_ui->GetNativeTheme();
1336 if (native_theme)
1337 return native_theme;
1338 }
1339
1340 return ui::NativeTheme::instance();
1341 }
1342
1322 } // namespace views 1343 } // namespace views
OLDNEW
« no previous file with comments | « ui/views/widget/desktop_aura/desktop_root_window_host_x11.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698