OLD | NEW |
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/aura/root_window_host_linux.h" | 5 #include "ui/aura/root_window_host_linux.h" |
6 | 6 |
7 #include <X11/Xatom.h> | 7 #include <X11/Xatom.h> |
8 #include <X11/Xcursor/Xcursor.h> | 8 #include <X11/Xcursor/Xcursor.h> |
9 #include <X11/cursorfont.h> | 9 #include <X11/cursorfont.h> |
10 #include <X11/extensions/XInput2.h> | 10 #include <X11/extensions/XInput2.h> |
11 #include <X11/extensions/Xfixes.h> | 11 #include <X11/extensions/Xfixes.h> |
12 #include <X11/extensions/Xrandr.h> | 12 #include <X11/extensions/Xrandr.h> |
13 #include <algorithm> | 13 #include <algorithm> |
14 | 14 |
15 #include "base/message_pump_x.h" | 15 #include "base/message_pump_x.h" |
16 #include "base/stl_util.h" | 16 #include "base/stl_util.h" |
17 #include "base/stringprintf.h" | 17 #include "base/stringprintf.h" |
18 #include "grit/ui_resources_standard.h" | 18 #include "grit/ui_resources_standard.h" |
19 #include "third_party/skia/include/core/SkBitmap.h" | 19 #include "third_party/skia/include/core/SkBitmap.h" |
20 #include "ui/aura/client/user_gesture_client.h" | 20 #include "ui/aura/client/user_gesture_client.h" |
21 #include "ui/aura/dispatcher_linux.h" | 21 #include "ui/aura/dispatcher_linux.h" |
22 #include "ui/aura/env.h" | 22 #include "ui/aura/env.h" |
23 #include "ui/aura/event.h" | 23 #include "ui/aura/event.h" |
24 #include "ui/aura/root_window.h" | 24 #include "ui/aura/root_window.h" |
25 #include "ui/base/cursor/cursor.h" | 25 #include "ui/base/cursor/cursor.h" |
26 #include "ui/base/keycodes/keyboard_codes.h" | 26 #include "ui/base/keycodes/keyboard_codes.h" |
27 #include "ui/base/resource/resource_bundle.h" | 27 #include "ui/base/resource/resource_bundle.h" |
28 #include "ui/base/touch/touch_factory.h" | 28 #include "ui/base/touch/touch_factory.h" |
29 #include "ui/base/view_prop.h" | 29 #include "ui/base/view_prop.h" |
| 30 #include "ui/base/x/x11_atom_cache.h" |
30 #include "ui/base/x/x11_util.h" | 31 #include "ui/base/x/x11_util.h" |
31 #include "ui/compositor/layer.h" | 32 #include "ui/compositor/layer.h" |
32 #include "ui/gfx/image/image.h" | 33 #include "ui/gfx/image/image.h" |
33 | 34 |
| 35 using ui::X11AtomCache; |
34 using std::max; | 36 using std::max; |
35 using std::min; | 37 using std::min; |
36 | 38 |
37 namespace aura { | 39 namespace aura { |
38 | 40 |
39 namespace { | 41 namespace { |
40 | 42 |
41 // Standard Linux mouse buttons for going back and forward. | 43 // Standard Linux mouse buttons for going back and forward. |
42 const int kBackMouseButton = 8; | 44 const int kBackMouseButton = 8; |
43 const int kForwardMouseButton = 9; | 45 const int kForwardMouseButton = 9; |
(...skipping 235 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
279 case ui::VKEY_OEM_PLUS: | 281 case ui::VKEY_OEM_PLUS: |
280 case ui::VKEY_OEM_COMMA: | 282 case ui::VKEY_OEM_COMMA: |
281 case ui::VKEY_OEM_MINUS: | 283 case ui::VKEY_OEM_MINUS: |
282 case ui::VKEY_OEM_PERIOD: | 284 case ui::VKEY_OEM_PERIOD: |
283 return true; | 285 return true; |
284 default: | 286 default: |
285 return false; | 287 return false; |
286 } | 288 } |
287 } | 289 } |
288 | 290 |
289 // A list of atoms that we'll intern on host creation to save roundtrips to the | |
290 // X11 server. Must be kept in sync with RootWindowHostLinux::AtomList | |
291 const char* kAtomList[] = { | |
292 "WM_DELETE_WINDOW", | |
293 "_NET_WM_PING", | |
294 "_NET_WM_PID", | |
295 "WM_S0" | |
296 }; | |
297 | |
298 } // namespace | 291 } // namespace |
299 | 292 |
300 // A utility class that provides X Cursor for NativeCursors for which we have | 293 // A utility class that provides X Cursor for NativeCursors for which we have |
301 // image resources. | 294 // image resources. |
302 class RootWindowHostLinux::ImageCursors { | 295 class RootWindowHostLinux::ImageCursors { |
303 public: | 296 public: |
304 ImageCursors() { | 297 ImageCursors() { |
305 LoadImageCursor(ui::kCursorNoDrop, IDR_AURA_CURSOR_NO_DROP); | 298 LoadImageCursor(ui::kCursorNoDrop, IDR_AURA_CURSOR_NO_DROP); |
306 LoadImageCursor(ui::kCursorCopy, IDR_AURA_CURSOR_COPY); | 299 LoadImageCursor(ui::kCursorCopy, IDR_AURA_CURSOR_COPY); |
307 // TODO (varunjain): add more cursors once we have assets. | 300 // TODO (varunjain): add more cursors once we have assets. |
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
388 black.red = black.green = black.blue = 0; | 381 black.red = black.green = black.blue = 0; |
389 Pixmap blank = XCreateBitmapFromData(xdisplay_, xwindow_, | 382 Pixmap blank = XCreateBitmapFromData(xdisplay_, xwindow_, |
390 nodata, 8, 8); | 383 nodata, 8, 8); |
391 invisible_cursor_ = XCreatePixmapCursor(xdisplay_, blank, blank, | 384 invisible_cursor_ = XCreatePixmapCursor(xdisplay_, blank, blank, |
392 &black, &black, 0, 0); | 385 &black, &black, 0, 0); |
393 XFreePixmap(xdisplay_, blank); | 386 XFreePixmap(xdisplay_, blank); |
394 | 387 |
395 if (RootWindow::hide_host_cursor()) | 388 if (RootWindow::hide_host_cursor()) |
396 XDefineCursor(xdisplay_, x_root_window_, invisible_cursor_); | 389 XDefineCursor(xdisplay_, x_root_window_, invisible_cursor_); |
397 | 390 |
398 // Grab all the atoms we need now to minimize roundtrips to the X11 server. | |
399 XInternAtoms(xdisplay_, const_cast<char**>(kAtomList), ATOM_COUNT, False, | |
400 cached_atoms_); | |
401 | |
402 // TODO(erg): We currently only request window deletion events. We also | 391 // TODO(erg): We currently only request window deletion events. We also |
403 // should listen for activation events and anything else that GTK+ listens | 392 // should listen for activation events and anything else that GTK+ listens |
404 // for, and do something useful. | 393 // for, and do something useful. |
| 394 X11AtomCache* cache = X11AtomCache::GetInstance(); |
405 ::Atom protocols[2]; | 395 ::Atom protocols[2]; |
406 protocols[0] = cached_atoms_[ATOM_WM_DELETE_WINDOW]; | 396 protocols[0] = cache->GetAtom(ui::ATOM_WM_DELETE_WINDOW); |
407 protocols[1] = cached_atoms_[ATOM__NET_WM_PING]; | 397 protocols[1] = cache->GetAtom(ui::ATOM__NET_WM_PING); |
408 XSetWMProtocols(xdisplay_, xwindow_, protocols, 2); | 398 XSetWMProtocols(xdisplay_, xwindow_, protocols, 2); |
409 | 399 |
410 // We need a WM_CLIENT_MACHINE and WM_LOCALE_NAME value so we integrate with | 400 // We need a WM_CLIENT_MACHINE and WM_LOCALE_NAME value so we integrate with |
411 // the desktop environment. | 401 // the desktop environment. |
412 XSetWMProperties(xdisplay_, xwindow_, NULL, NULL, NULL, 0, NULL, NULL, NULL); | 402 XSetWMProperties(xdisplay_, xwindow_, NULL, NULL, NULL, 0, NULL, NULL, NULL); |
413 | 403 |
414 // Likewise, the X server needs to know this window's pid so it knows which | 404 // Likewise, the X server needs to know this window's pid so it knows which |
415 // program to kill if the window hangs. | 405 // program to kill if the window hangs. |
416 pid_t pid = getpid(); | 406 pid_t pid = getpid(); |
417 XChangeProperty(xdisplay_, | 407 XChangeProperty(xdisplay_, |
418 xwindow_, | 408 xwindow_, |
419 cached_atoms_[ATOM__NET_WM_PID], | 409 cache->GetAtom(ui::ATOM__NET_WM_PID), |
420 XA_CARDINAL, | 410 XA_CARDINAL, |
421 32, | 411 32, |
422 PropModeReplace, | 412 PropModeReplace, |
423 reinterpret_cast<unsigned char*>(&pid), 1); | 413 reinterpret_cast<unsigned char*>(&pid), 1); |
424 | 414 |
425 // crbug.com/120229 - set the window title so gtalk can find the primary root | 415 // crbug.com/120229 - set the window title so gtalk can find the primary root |
426 // window to broadcast. | 416 // window to broadcast. |
427 // TODO(jhorwich) Remove this once Chrome supports window-based broadcasting. | 417 // TODO(jhorwich) Remove this once Chrome supports window-based broadcasting. |
428 static int root_window_number = 0; | 418 static int root_window_number = 0; |
429 std::string name = StringPrintf("aura_root_%d", root_window_number++); | 419 std::string name = StringPrintf("aura_root_%d", root_window_number++); |
(...skipping 151 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
581 } | 571 } |
582 case MapNotify: { | 572 case MapNotify: { |
583 // If there's no window manager running, we need to assign the X input | 573 // If there's no window manager running, we need to assign the X input |
584 // focus to our host window. | 574 // focus to our host window. |
585 if (!IsWindowManagerPresent() && focus_when_shown_) | 575 if (!IsWindowManagerPresent() && focus_when_shown_) |
586 XSetInputFocus(xdisplay_, xwindow_, RevertToNone, CurrentTime); | 576 XSetInputFocus(xdisplay_, xwindow_, RevertToNone, CurrentTime); |
587 break; | 577 break; |
588 } | 578 } |
589 case ClientMessage: { | 579 case ClientMessage: { |
590 Atom message_type = static_cast<Atom>(xev->xclient.data.l[0]); | 580 Atom message_type = static_cast<Atom>(xev->xclient.data.l[0]); |
591 if (message_type == cached_atoms_[ATOM_WM_DELETE_WINDOW]) { | 581 X11AtomCache* cache = X11AtomCache::GetInstance(); |
| 582 if (message_type == cache->GetAtom(ui::ATOM_WM_DELETE_WINDOW)) { |
592 // We have received a close message from the window manager. | 583 // We have received a close message from the window manager. |
593 root_window_->OnRootWindowHostClosed(); | 584 root_window_->OnRootWindowHostClosed(); |
594 } else if (message_type == cached_atoms_[ATOM__NET_WM_PING]) { | 585 } else if (message_type == cache->GetAtom(ui::ATOM__NET_WM_PING)) { |
595 XEvent reply_event = *xev; | 586 XEvent reply_event = *xev; |
596 reply_event.xclient.window = x_root_window_; | 587 reply_event.xclient.window = x_root_window_; |
597 | 588 |
598 XSendEvent(xdisplay_, | 589 XSendEvent(xdisplay_, |
599 reply_event.xclient.window, | 590 reply_event.xclient.window, |
600 False, | 591 False, |
601 SubstructureRedirectMask | SubstructureNotifyMask, | 592 SubstructureRedirectMask | SubstructureNotifyMask, |
602 &reply_event); | 593 &reply_event); |
603 } | 594 } |
604 break; | 595 break; |
(...skipping 228 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
833 } | 824 } |
834 default: | 825 default: |
835 break; | 826 break; |
836 } | 827 } |
837 XSendEvent(xdisplay_, xwindow_, False, 0, &xevent); | 828 XSendEvent(xdisplay_, xwindow_, False, 0, &xevent); |
838 } | 829 } |
839 | 830 |
840 bool RootWindowHostLinux::IsWindowManagerPresent() { | 831 bool RootWindowHostLinux::IsWindowManagerPresent() { |
841 // Per ICCCM 2.8, "Manager Selections", window managers should take ownership | 832 // Per ICCCM 2.8, "Manager Selections", window managers should take ownership |
842 // of WM_Sn selections (where n is a screen number). | 833 // of WM_Sn selections (where n is a screen number). |
843 return XGetSelectionOwner(xdisplay_, cached_atoms_[ATOM_WM_S0]) != None; | 834 return XGetSelectionOwner( |
| 835 xdisplay_, |
| 836 X11AtomCache::GetInstance()->GetAtom(ui::ATOM_WM_S0)) != None; |
844 } | 837 } |
845 | 838 |
846 void RootWindowHostLinux::SetCursorInternal(gfx::NativeCursor cursor) { | 839 void RootWindowHostLinux::SetCursorInternal(gfx::NativeCursor cursor) { |
847 ::Cursor xcursor = | 840 ::Cursor xcursor = |
848 image_cursors_->IsImageCursor(cursor) ? | 841 image_cursors_->IsImageCursor(cursor) ? |
849 image_cursors_->ImageCursorFromNative(cursor) : | 842 image_cursors_->ImageCursorFromNative(cursor) : |
850 cursor == ui::kCursorNone ? | 843 cursor == ui::kCursorNone ? |
851 invisible_cursor_ : | 844 invisible_cursor_ : |
852 cursor == ui::kCursorCustom ? | 845 cursor == ui::kCursorCustom ? |
853 cursor.platform() : | 846 cursor.platform() : |
(...skipping 13 matching lines...) Expand all Loading... |
867 ui::ViewProp::GetValue(accelerated_widget, kRootWindowHostLinuxKey)); | 860 ui::ViewProp::GetValue(accelerated_widget, kRootWindowHostLinuxKey)); |
868 } | 861 } |
869 | 862 |
870 // static | 863 // static |
871 gfx::Size RootWindowHost::GetNativeScreenSize() { | 864 gfx::Size RootWindowHost::GetNativeScreenSize() { |
872 ::Display* xdisplay = base::MessagePumpX::GetDefaultXDisplay(); | 865 ::Display* xdisplay = base::MessagePumpX::GetDefaultXDisplay(); |
873 return gfx::Size(DisplayWidth(xdisplay, 0), DisplayHeight(xdisplay, 0)); | 866 return gfx::Size(DisplayWidth(xdisplay, 0), DisplayHeight(xdisplay, 0)); |
874 } | 867 } |
875 | 868 |
876 } // namespace aura | 869 } // namespace aura |
OLD | NEW |