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

Side by Side Diff: ui/aura/root_window_host_linux.cc

Issue 10905163: aura-x11: Fix touch-calibration for multi-monitor setups. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: . Created 8 years, 3 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/aura/root_window_host_linux.h ('k') | ui/base/events/event.h » ('j') | 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/aura/root_window_host_linux.h" 5 #include "ui/aura/root_window_host_linux.h"
6 6
7 #include <X11/cursorfont.h> 7 #include <X11/cursorfont.h>
8 #include <X11/extensions/Xfixes.h> 8 #include <X11/extensions/Xfixes.h>
9 #include <X11/extensions/XInput2.h> 9 #include <X11/extensions/XInput2.h>
10 #include <X11/extensions/Xrandr.h> 10 #include <X11/extensions/Xrandr.h>
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
44 namespace aura { 44 namespace aura {
45 45
46 namespace { 46 namespace {
47 47
48 // Standard Linux mouse buttons for going back and forward. 48 // Standard Linux mouse buttons for going back and forward.
49 const int kBackMouseButton = 8; 49 const int kBackMouseButton = 8;
50 const int kForwardMouseButton = 9; 50 const int kForwardMouseButton = 9;
51 51
52 const int kAnimatedCursorFrameDelayMs = 25; 52 const int kAnimatedCursorFrameDelayMs = 25;
53 53
54 // These are the same values that are used to calibrate touch events in
55 // |CalibrateTouchCoordinates| (in ui/base/x/events_x.cc).
56 // TODO(sad|skuhne): Remove the duplication of values (http://crbug.com/147605)
57 const int kXRootWindowPaddingLeft = 40;
58 const int kXRootWindowPaddingRight = 40;
59 const int kXRootWindowPaddingBottom = 30;
60 const int kXRootWindowPaddingTop = 0;
61
54 const char kRootWindowHostLinuxKey[] = "__AURA_ROOT_WINDOW_HOST_LINUX__"; 62 const char kRootWindowHostLinuxKey[] = "__AURA_ROOT_WINDOW_HOST_LINUX__";
55 63
56 const char* kAtomsToCache[] = { 64 const char* kAtomsToCache[] = {
57 "WM_DELETE_WINDOW", 65 "WM_DELETE_WINDOW",
58 "_NET_WM_PING", 66 "_NET_WM_PING",
59 "_NET_WM_PID", 67 "_NET_WM_PID",
60 "WM_S0", 68 "WM_S0",
61 NULL 69 NULL
62 }; 70 };
63 71
(...skipping 197 matching lines...) Expand 10 before | Expand all | Expand 10 after
261 } else { 269 } else {
262 // This isn't an event we want so free its cookie data. 270 // This isn't an event we want so free its cookie data.
263 XFreeEventData(display, &next_event.xcookie); 271 XFreeEventData(display, &next_event.xcookie);
264 } 272 }
265 } 273 }
266 break; 274 break;
267 } 275 }
268 return num_coalesed; 276 return num_coalesed;
269 } 277 }
270 278
279 void SelectEventsForRootWindow() {
280 XIEventMask evmask;
281 unsigned char mask[XIMaskLen(XI_LASTEVENT)] = {};
282 memset(mask, 0, sizeof(mask));
283
284 XISetMask(mask, XI_HierarchyChanged);
285
286 XISetMask(mask, XI_KeyPress);
287 XISetMask(mask, XI_KeyRelease);
288
289 #if defined(USE_XI2_MT)
290 XISetMask(mask, XI_TouchBegin);
291 XISetMask(mask, XI_TouchUpdate);
292 XISetMask(mask, XI_TouchEnd);
293 #endif
294 XISetMask(mask, XI_ButtonPress);
295 XISetMask(mask, XI_ButtonRelease);
296 XISetMask(mask, XI_Motion);
297
298 evmask.deviceid = XIAllDevices;
299 evmask.mask_len = sizeof(mask);
300 evmask.mask = mask;
301
302 Display* display = ui::GetXDisplay();
303 ::Window root_window = ui::GetX11RootWindow();
304 XISelectEvents(display, root_window, &evmask, 1);
305
306 // Receive resize events for the root-window so |x_root_bounds_| can be
307 // updated.
308 XSelectInput(display, root_window, StructureNotifyMask);
309 }
310
271 // We emulate Windows' WM_KEYDOWN and WM_CHAR messages. WM_CHAR events are only 311 // We emulate Windows' WM_KEYDOWN and WM_CHAR messages. WM_CHAR events are only
272 // generated for certain keys; see 312 // generated for certain keys; see
273 // http://msdn.microsoft.com/en-us/library/windows/desktop/ms646268.aspx. Per 313 // http://msdn.microsoft.com/en-us/library/windows/desktop/ms646268.aspx. Per
274 // discussion on http://crbug.com/108480, char events should furthermore not be 314 // discussion on http://crbug.com/108480, char events should furthermore not be
275 // generated for Tab, Escape, and Backspace. 315 // generated for Tab, Escape, and Backspace.
276 bool ShouldSendCharEventForKeyboardCode(ui::KeyboardCode keycode) { 316 bool ShouldSendCharEventForKeyboardCode(ui::KeyboardCode keycode) {
277 if ((keycode >= ui::VKEY_0 && keycode <= ui::VKEY_9) || 317 if ((keycode >= ui::VKEY_0 && keycode <= ui::VKEY_9) ||
278 (keycode >= ui::VKEY_A && keycode <= ui::VKEY_Z) || 318 (keycode >= ui::VKEY_A && keycode <= ui::VKEY_Z) ||
279 (keycode >= ui::VKEY_NUMPAD0 && keycode <= ui::VKEY_NUMPAD9)) { 319 (keycode >= ui::VKEY_NUMPAD0 && keycode <= ui::VKEY_NUMPAD9)) {
280 return true; 320 return true;
(...skipping 243 matching lines...) Expand 10 before | Expand all | Expand 10 after
524 xwindow_ = XCreateWindow( 564 xwindow_ = XCreateWindow(
525 xdisplay_, x_root_window_, 565 xdisplay_, x_root_window_,
526 bounds.x(), bounds.y(), bounds.width(), bounds.height(), 566 bounds.x(), bounds.y(), bounds.width(), bounds.height(),
527 0, // border width 567 0, // border width
528 CopyFromParent, // depth 568 CopyFromParent, // depth
529 InputOutput, 569 InputOutput,
530 CopyFromParent, // visual 570 CopyFromParent, // visual
531 CWBackPixmap, 571 CWBackPixmap,
532 &swa); 572 &swa);
533 base::MessagePumpAuraX11::Current()->AddDispatcherForWindow(this, xwindow_); 573 base::MessagePumpAuraX11::Current()->AddDispatcherForWindow(this, xwindow_);
574 base::MessagePumpAuraX11::Current()->AddDispatcherForRootWindow(this);
534 575
535 prop_.reset(new ui::ViewProp(xwindow_, kRootWindowHostLinuxKey, this)); 576 prop_.reset(new ui::ViewProp(xwindow_, kRootWindowHostLinuxKey, this));
536 577
537 long event_mask = ButtonPressMask | ButtonReleaseMask | FocusChangeMask | 578 long event_mask = ButtonPressMask | ButtonReleaseMask | FocusChangeMask |
538 KeyPressMask | KeyReleaseMask | 579 KeyPressMask | KeyReleaseMask |
539 EnterWindowMask | LeaveWindowMask | 580 EnterWindowMask | LeaveWindowMask |
540 ExposureMask | VisibilityChangeMask | 581 ExposureMask | VisibilityChangeMask |
541 StructureNotifyMask | PropertyChangeMask | 582 StructureNotifyMask | PropertyChangeMask |
542 PointerMotionMask; 583 PointerMotionMask;
543 XSelectInput(xdisplay_, xwindow_, event_mask); 584 XSelectInput(xdisplay_, xwindow_, event_mask);
544 XFlush(xdisplay_); 585 XFlush(xdisplay_);
545 586
546 if (base::MessagePumpForUI::HasXInput2()) 587 if (base::MessagePumpForUI::HasXInput2())
547 ui::TouchFactory::GetInstance()->SetupXI2ForXWindow(xwindow_); 588 ui::TouchFactory::GetInstance()->SetupXI2ForXWindow(xwindow_);
548 589
590 SelectEventsForRootWindow();
591
592 // Get the initial size of the X root window.
593 XWindowAttributes attrs;
594 XGetWindowAttributes(xdisplay_, x_root_window_, &attrs);
595 x_root_bounds_.SetRect(attrs.x, attrs.y, attrs.width, attrs.height);
596
549 // Initialize invisible cursor. 597 // Initialize invisible cursor.
550 char nodata[] = { 0, 0, 0, 0, 0, 0, 0, 0 }; 598 char nodata[] = { 0, 0, 0, 0, 0, 0, 0, 0 };
551 XColor black; 599 XColor black;
552 black.red = black.green = black.blue = 0; 600 black.red = black.green = black.blue = 0;
553 Pixmap blank = XCreateBitmapFromData(xdisplay_, xwindow_, 601 Pixmap blank = XCreateBitmapFromData(xdisplay_, xwindow_,
554 nodata, 8, 8); 602 nodata, 8, 8);
555 invisible_cursor_ = XCreatePixmapCursor(xdisplay_, blank, blank, 603 invisible_cursor_ = XCreatePixmapCursor(xdisplay_, blank, blank,
556 &black, &black, 0, 0); 604 &black, &black, 0, 0);
557 XFreePixmap(xdisplay_, blank); 605 XFreePixmap(xdisplay_, blank);
558 606
(...skipping 27 matching lines...) Expand all
586 // window to broadcast. 634 // window to broadcast.
587 // TODO(jhorwich) Remove this once Chrome supports window-based broadcasting. 635 // TODO(jhorwich) Remove this once Chrome supports window-based broadcasting.
588 static int root_window_number = 0; 636 static int root_window_number = 0;
589 std::string name = StringPrintf("aura_root_%d", root_window_number++); 637 std::string name = StringPrintf("aura_root_%d", root_window_number++);
590 XStoreName(xdisplay_, xwindow_, name.c_str()); 638 XStoreName(xdisplay_, xwindow_, name.c_str());
591 XRRSelectInput(xdisplay_, x_root_window_, 639 XRRSelectInput(xdisplay_, x_root_window_,
592 RRScreenChangeNotifyMask | RROutputChangeNotifyMask); 640 RRScreenChangeNotifyMask | RROutputChangeNotifyMask);
593 } 641 }
594 642
595 RootWindowHostLinux::~RootWindowHostLinux() { 643 RootWindowHostLinux::~RootWindowHostLinux() {
644 base::MessagePumpAuraX11::Current()->RemoveDispatcherForRootWindow(this);
596 base::MessagePumpAuraX11::Current()->RemoveDispatcherForWindow(xwindow_); 645 base::MessagePumpAuraX11::Current()->RemoveDispatcherForWindow(xwindow_);
597 646
598 UnConfineCursor(); 647 UnConfineCursor();
599 648
600 XDestroyWindow(xdisplay_, xwindow_); 649 XDestroyWindow(xdisplay_, xwindow_);
601 650
602 // Clears XCursorCache. 651 // Clears XCursorCache.
603 ui::GetXCursor(ui::kCursorClearXCursorCache); 652 ui::GetXCursor(ui::kCursorClearXCursorCache);
604 653
605 XFreeCursor(xdisplay_, invisible_cursor_); 654 XFreeCursor(xdisplay_, invisible_cursor_);
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
641 case ButtonRelease: { 690 case ButtonRelease: {
642 ui::MouseEvent mouseev(xev); 691 ui::MouseEvent mouseev(xev);
643 delegate_->OnHostMouseEvent(&mouseev); 692 delegate_->OnHostMouseEvent(&mouseev);
644 break; 693 break;
645 } 694 }
646 case FocusOut: 695 case FocusOut:
647 if (xev->xfocus.mode != NotifyGrab) 696 if (xev->xfocus.mode != NotifyGrab)
648 delegate_->OnHostLostCapture(); 697 delegate_->OnHostLostCapture();
649 break; 698 break;
650 case ConfigureNotify: { 699 case ConfigureNotify: {
651 DCHECK_EQ(xwindow_, xev->xconfigure.window); 700 if (xev->xconfigure.window == xwindow_) {
652 DCHECK_EQ(xwindow_, xev->xconfigure.event); 701 DCHECK_EQ(xwindow_, xev->xconfigure.event);
653 // It's possible that the X window may be resized by some other means than 702 // It's possible that the X window may be resized by some other means
654 // from within aura (e.g. the X window manager can change the size). Make 703 // than from within aura (e.g. the X window manager can change the
655 // sure the root window size is maintained properly. 704 // size). Make sure the root window size is maintained properly.
656 gfx::Rect bounds(xev->xconfigure.x, xev->xconfigure.y, 705 gfx::Rect bounds(xev->xconfigure.x, xev->xconfigure.y,
657 xev->xconfigure.width, xev->xconfigure.height); 706 xev->xconfigure.width, xev->xconfigure.height);
658 bool size_changed = bounds_.size() != bounds.size(); 707 bool size_changed = bounds_.size() != bounds.size();
659 bool origin_changed = bounds_.origin() != bounds.origin(); 708 bool origin_changed = bounds_.origin() != bounds.origin();
660 bounds_ = bounds; 709 bounds_ = bounds;
661 // Update barrier and mouse location when the root window has 710 // Update barrier and mouse location when the root window has
662 // moved/resized. 711 // moved/resized.
663 if (pointer_barriers_.get() && (size_changed || origin_changed)) { 712 if (pointer_barriers_.get() && (size_changed || origin_changed)) {
664 UnConfineCursor(); 713 UnConfineCursor();
665 RootWindow* root = delegate_->AsRootWindow(); 714 RootWindow* root = delegate_->AsRootWindow();
666 client::ScreenPositionClient* client = 715 client::ScreenPositionClient* client =
667 client::GetScreenPositionClient(root); 716 client::GetScreenPositionClient(root);
668 if (client) { 717 if (client) {
669 gfx::Point p = gfx::Screen::GetCursorScreenPoint(); 718 gfx::Point p = gfx::Screen::GetCursorScreenPoint();
670 client->ConvertPointFromScreen(root, &p); 719 client->ConvertPointFromScreen(root, &p);
671 if (root->ContainsPoint(p)) { 720 if (root->ContainsPoint(p)) {
672 root->ConvertPointToNativeScreen(&p); 721 root->ConvertPointToNativeScreen(&p);
673 XWarpPointer( 722 XWarpPointer(
674 xdisplay_, None, x_root_window_, 0, 0, 0, 0, p.x(), p.y()); 723 xdisplay_, None, x_root_window_, 0, 0, 0, 0, p.x(), p.y());
724 }
675 } 725 }
726 ConfineCursorToRootWindow();
676 } 727 }
677 ConfineCursorToRootWindow(); 728 if (size_changed)
729 delegate_->OnHostResized(bounds.size());
730 if (origin_changed)
731 delegate_->OnHostMoved(bounds_.origin());
732 } else {
733 DCHECK_EQ(x_root_window_, xev->xconfigure.event);
734 DCHECK_EQ(x_root_window_, xev->xconfigure.window);
735 x_root_bounds_.SetRect(xev->xconfigure.x, xev->xconfigure.y,
736 xev->xconfigure.width, xev->xconfigure.height);
678 } 737 }
679 if (size_changed)
680 delegate_->OnHostResized(bounds.size());
681 if (origin_changed)
682 delegate_->OnHostMoved(bounds_.origin());
683 break; 738 break;
684 } 739 }
685 case GenericEvent: { 740 case GenericEvent: {
686 ui::TouchFactory* factory = ui::TouchFactory::GetInstance(); 741 ui::TouchFactory* factory = ui::TouchFactory::GetInstance();
687 if (!factory->ShouldProcessXI2Event(xev)) 742 if (!factory->ShouldProcessXI2Event(xev))
688 break; 743 break;
689 744
690 ui::EventType type = ui::EventTypeFromNative(xev); 745 ui::EventType type = ui::EventTypeFromNative(xev);
691 XEvent last_event; 746 XEvent last_event;
692 int num_coalesced = 0; 747 int num_coalesced = 0;
693 748
694 switch (type) { 749 switch (type) {
695 case ui::ET_TOUCH_MOVED: 750 case ui::ET_TOUCH_MOVED:
696 num_coalesced = CoalescePendingMotionEvents(xev, &last_event); 751 num_coalesced = CoalescePendingMotionEvents(xev, &last_event);
697 if (num_coalesced > 0) 752 if (num_coalesced > 0)
698 xev = &last_event; 753 xev = &last_event;
699 // fallthrough 754 // fallthrough
700 case ui::ET_TOUCH_PRESSED: 755 case ui::ET_TOUCH_PRESSED:
701 case ui::ET_TOUCH_RELEASED: { 756 case ui::ET_TOUCH_RELEASED: {
702 ui::TouchEvent touchev(xev); 757 ui::TouchEvent touchev(xev);
758 // X maps the touch-surface to the size of the X root-window. In
759 // multi-monitor setup, the X root-window size is a combination of
760 // both the monitor sizes. So it is necessary to remap the location of
761 // the event from the X root-window to the X host-window for the aura
762 // root-window.
763 touchev.CalibrateLocation(x_root_bounds_.size(), bounds_.size());
764 if (!bounds_.Contains(touchev.location())) {
765 // This might still be in the bezel region.
766 gfx::Rect expanded(bounds_);
767 expanded.Inset(-kXRootWindowPaddingLeft,
768 -kXRootWindowPaddingTop,
769 -kXRootWindowPaddingRight,
770 -kXRootWindowPaddingBottom);
771 if (!expanded.Contains(touchev.location()))
772 break;
773 }
703 delegate_->OnHostTouchEvent(&touchev); 774 delegate_->OnHostTouchEvent(&touchev);
704 break; 775 break;
705 } 776 }
706 case ui::ET_MOUSE_MOVED: 777 case ui::ET_MOUSE_MOVED:
707 case ui::ET_MOUSE_DRAGGED: 778 case ui::ET_MOUSE_DRAGGED:
708 case ui::ET_MOUSE_PRESSED: 779 case ui::ET_MOUSE_PRESSED:
709 case ui::ET_MOUSE_RELEASED: 780 case ui::ET_MOUSE_RELEASED:
710 case ui::ET_MOUSE_ENTERED: 781 case ui::ET_MOUSE_ENTERED:
711 case ui::ET_MOUSE_EXITED: { 782 case ui::ET_MOUSE_EXITED: {
712 if (type == ui::ET_MOUSE_MOVED || type == ui::ET_MOUSE_DRAGGED) { 783 if (type == ui::ET_MOUSE_MOVED || type == ui::ET_MOUSE_DRAGGED) {
(...skipping 423 matching lines...) Expand 10 before | Expand all | Expand 10 after
1136 ui::ViewProp::GetValue(accelerated_widget, kRootWindowHostLinuxKey)); 1207 ui::ViewProp::GetValue(accelerated_widget, kRootWindowHostLinuxKey));
1137 } 1208 }
1138 1209
1139 // static 1210 // static
1140 gfx::Size RootWindowHost::GetNativeScreenSize() { 1211 gfx::Size RootWindowHost::GetNativeScreenSize() {
1141 ::Display* xdisplay = base::MessagePumpAuraX11::GetDefaultXDisplay(); 1212 ::Display* xdisplay = base::MessagePumpAuraX11::GetDefaultXDisplay();
1142 return gfx::Size(DisplayWidth(xdisplay, 0), DisplayHeight(xdisplay, 0)); 1213 return gfx::Size(DisplayWidth(xdisplay, 0), DisplayHeight(xdisplay, 0));
1143 } 1214 }
1144 1215
1145 } // namespace aura 1216 } // namespace aura
OLDNEW
« no previous file with comments | « ui/aura/root_window_host_linux.h ('k') | ui/base/events/event.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698