| 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/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 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 62 const char kRootWindowHostLinuxKey[] = "__AURA_ROOT_WINDOW_HOST_LINUX__"; | 62 const char kRootWindowHostLinuxKey[] = "__AURA_ROOT_WINDOW_HOST_LINUX__"; |
| 63 | 63 |
| 64 const char* kAtomsToCache[] = { | 64 const char* kAtomsToCache[] = { |
| 65 "WM_DELETE_WINDOW", | 65 "WM_DELETE_WINDOW", |
| 66 "_NET_WM_PING", | 66 "_NET_WM_PING", |
| 67 "_NET_WM_PID", | 67 "_NET_WM_PID", |
| 68 "WM_S0", | 68 "WM_S0", |
| 69 NULL | 69 NULL |
| 70 }; | 70 }; |
| 71 | 71 |
| 72 ::Window FindEventTarget(const base::NativeEvent& xev) { |
| 73 ::Window target = xev->xany.window; |
| 74 if (xev->type == GenericEvent) |
| 75 target = static_cast<XIDeviceEvent*>(xev->xcookie.data)->event; |
| 76 return target; |
| 77 } |
| 78 |
| 72 // The events reported for slave devices can have incorrect information for some | 79 // The events reported for slave devices can have incorrect information for some |
| 73 // fields. This utility function is used to check for such inconsistencies. | 80 // fields. This utility function is used to check for such inconsistencies. |
| 74 void CheckXEventForConsistency(XEvent* xevent) { | 81 void CheckXEventForConsistency(XEvent* xevent) { |
| 75 #if defined(USE_XI2_MT) && !defined(NDEBUG) | 82 #if defined(USE_XI2_MT) && !defined(NDEBUG) |
| 76 static bool expect_master_event = false; | 83 static bool expect_master_event = false; |
| 77 static XIDeviceEvent slave_event; | 84 static XIDeviceEvent slave_event; |
| 78 static gfx::Point slave_location; | 85 static gfx::Point slave_location; |
| 79 static int slave_button; | 86 static int slave_button; |
| 80 | 87 |
| 81 // Note: If an event comes from a slave pointer device, then it will be | 88 // Note: If an event comes from a slave pointer device, then it will be |
| (...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 201 // This isn't an event we want so free its cookie data. | 208 // This isn't an event we want so free its cookie data. |
| 202 XFreeEventData(display, &next_event.xcookie); | 209 XFreeEventData(display, &next_event.xcookie); |
| 203 } | 210 } |
| 204 } | 211 } |
| 205 break; | 212 break; |
| 206 } | 213 } |
| 207 return num_coalesed; | 214 return num_coalesed; |
| 208 } | 215 } |
| 209 | 216 |
| 210 void SelectEventsForRootWindow() { | 217 void SelectEventsForRootWindow() { |
| 218 Display* display = ui::GetXDisplay(); |
| 219 ::Window root_window = ui::GetX11RootWindow(); |
| 220 |
| 221 // Receive resize events for the root-window so |x_root_bounds_| can be |
| 222 // updated. |
| 223 XWindowAttributes attr; |
| 224 XGetWindowAttributes(display, root_window, &attr); |
| 225 if (!(attr.your_event_mask & StructureNotifyMask)) { |
| 226 XSelectInput(display, root_window, |
| 227 StructureNotifyMask | attr.your_event_mask); |
| 228 } |
| 229 |
| 211 XIEventMask evmask; | 230 XIEventMask evmask; |
| 212 unsigned char mask[XIMaskLen(XI_LASTEVENT)] = {}; | 231 unsigned char mask[XIMaskLen(XI_LASTEVENT)] = {}; |
| 213 memset(mask, 0, sizeof(mask)); | 232 memset(mask, 0, sizeof(mask)); |
| 214 | 233 |
| 215 XISetMask(mask, XI_HierarchyChanged); | 234 XISetMask(mask, XI_HierarchyChanged); |
| 216 | 235 |
| 217 XISetMask(mask, XI_KeyPress); | 236 XISetMask(mask, XI_KeyPress); |
| 218 XISetMask(mask, XI_KeyRelease); | 237 XISetMask(mask, XI_KeyRelease); |
| 219 | 238 |
| 220 #if defined(USE_XI2_MT) | 239 #if defined(USE_XI2_MT) |
| 221 XISetMask(mask, XI_TouchBegin); | 240 XISetMask(mask, XI_TouchBegin); |
| 222 XISetMask(mask, XI_TouchUpdate); | 241 XISetMask(mask, XI_TouchUpdate); |
| 223 XISetMask(mask, XI_TouchEnd); | 242 XISetMask(mask, XI_TouchEnd); |
| 224 #endif | 243 #endif |
| 225 XISetMask(mask, XI_ButtonPress); | 244 XISetMask(mask, XI_ButtonPress); |
| 226 XISetMask(mask, XI_ButtonRelease); | 245 XISetMask(mask, XI_ButtonRelease); |
| 227 XISetMask(mask, XI_Motion); | 246 XISetMask(mask, XI_Motion); |
| 228 | 247 |
| 229 evmask.deviceid = XIAllDevices; | 248 evmask.deviceid = XIAllDevices; |
| 230 evmask.mask_len = sizeof(mask); | 249 evmask.mask_len = sizeof(mask); |
| 231 evmask.mask = mask; | 250 evmask.mask = mask; |
| 232 | 251 |
| 233 Display* display = ui::GetXDisplay(); | |
| 234 ::Window root_window = ui::GetX11RootWindow(); | |
| 235 XISelectEvents(display, root_window, &evmask, 1); | 252 XISelectEvents(display, root_window, &evmask, 1); |
| 236 | |
| 237 // Receive resize events for the root-window so |x_root_bounds_| can be | |
| 238 // updated. | |
| 239 XSelectInput(display, root_window, StructureNotifyMask); | |
| 240 } | 253 } |
| 241 | 254 |
| 242 // We emulate Windows' WM_KEYDOWN and WM_CHAR messages. WM_CHAR events are only | 255 // We emulate Windows' WM_KEYDOWN and WM_CHAR messages. WM_CHAR events are only |
| 243 // generated for certain keys; see | 256 // generated for certain keys; see |
| 244 // http://msdn.microsoft.com/en-us/library/windows/desktop/ms646268.aspx. Per | 257 // http://msdn.microsoft.com/en-us/library/windows/desktop/ms646268.aspx. Per |
| 245 // discussion on http://crbug.com/108480, char events should furthermore not be | 258 // discussion on http://crbug.com/108480, char events should furthermore not be |
| 246 // generated for Tab, Escape, and Backspace. | 259 // generated for Tab, Escape, and Backspace. |
| 247 bool ShouldSendCharEventForKeyboardCode(ui::KeyboardCode keycode) { | 260 bool ShouldSendCharEventForKeyboardCode(ui::KeyboardCode keycode) { |
| 248 if ((keycode >= ui::VKEY_0 && keycode <= ui::VKEY_9) || | 261 if ((keycode >= ui::VKEY_0 && keycode <= ui::VKEY_9) || |
| 249 (keycode >= ui::VKEY_A && keycode <= ui::VKEY_Z) || | 262 (keycode >= ui::VKEY_A && keycode <= ui::VKEY_Z) || |
| (...skipping 165 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 415 XDestroyWindow(xdisplay_, xwindow_); | 428 XDestroyWindow(xdisplay_, xwindow_); |
| 416 | 429 |
| 417 XFreeCursor(xdisplay_, invisible_cursor_); | 430 XFreeCursor(xdisplay_, invisible_cursor_); |
| 418 } | 431 } |
| 419 | 432 |
| 420 bool RootWindowHostLinux::Dispatch(const base::NativeEvent& event) { | 433 bool RootWindowHostLinux::Dispatch(const base::NativeEvent& event) { |
| 421 XEvent* xev = event; | 434 XEvent* xev = event; |
| 422 | 435 |
| 423 CheckXEventForConsistency(xev); | 436 CheckXEventForConsistency(xev); |
| 424 | 437 |
| 438 if (FindEventTarget(event) == x_root_window_) |
| 439 return DispatchEventForRootWindow(event); |
| 440 |
| 425 switch (xev->type) { | 441 switch (xev->type) { |
| 426 case EnterNotify: { | 442 case EnterNotify: { |
| 427 ui::MouseEvent mouseenter_event(xev); | 443 ui::MouseEvent mouseenter_event(xev); |
| 428 delegate_->OnHostMouseEvent(&mouseenter_event); | 444 delegate_->OnHostMouseEvent(&mouseenter_event); |
| 429 break; | 445 break; |
| 430 } | 446 } |
| 431 case Expose: | 447 case Expose: |
| 432 delegate_->AsRootWindow()->ScheduleFullDraw(); | 448 delegate_->AsRootWindow()->ScheduleFullDraw(); |
| 433 break; | 449 break; |
| 434 case KeyPress: { | 450 case KeyPress: { |
| (...skipping 23 matching lines...) Expand all Loading... |
| 458 case ButtonRelease: { | 474 case ButtonRelease: { |
| 459 ui::MouseEvent mouseev(xev); | 475 ui::MouseEvent mouseev(xev); |
| 460 delegate_->OnHostMouseEvent(&mouseev); | 476 delegate_->OnHostMouseEvent(&mouseev); |
| 461 break; | 477 break; |
| 462 } | 478 } |
| 463 case FocusOut: | 479 case FocusOut: |
| 464 if (xev->xfocus.mode != NotifyGrab) | 480 if (xev->xfocus.mode != NotifyGrab) |
| 465 delegate_->OnHostLostCapture(); | 481 delegate_->OnHostLostCapture(); |
| 466 break; | 482 break; |
| 467 case ConfigureNotify: { | 483 case ConfigureNotify: { |
| 468 if (xev->xconfigure.window == xwindow_) { | 484 DCHECK_EQ(xwindow_, xev->xconfigure.event); |
| 469 DCHECK_EQ(xwindow_, xev->xconfigure.event); | 485 DCHECK_EQ(xwindow_, xev->xconfigure.window); |
| 470 // It's possible that the X window may be resized by some other means | 486 // It's possible that the X window may be resized by some other means |
| 471 // than from within aura (e.g. the X window manager can change the | 487 // than from within aura (e.g. the X window manager can change the |
| 472 // size). Make sure the root window size is maintained properly. | 488 // size). Make sure the root window size is maintained properly. |
| 473 gfx::Rect bounds(xev->xconfigure.x, xev->xconfigure.y, | 489 gfx::Rect bounds(xev->xconfigure.x, xev->xconfigure.y, |
| 474 xev->xconfigure.width, xev->xconfigure.height); | 490 xev->xconfigure.width, xev->xconfigure.height); |
| 475 bool size_changed = bounds_.size() != bounds.size(); | 491 bool size_changed = bounds_.size() != bounds.size(); |
| 476 bool origin_changed = bounds_.origin() != bounds.origin(); | 492 bool origin_changed = bounds_.origin() != bounds.origin(); |
| 477 bounds_ = bounds; | 493 bounds_ = bounds; |
| 478 // Always update barrier and mouse location because |bounds_| might | 494 // Always update barrier and mouse location because |bounds_| might |
| 479 // have already been updated in |SetBounds|. | 495 // have already been updated in |SetBounds|. |
| 480 if (pointer_barriers_.get()) { | 496 if (pointer_barriers_.get()) { |
| 481 UnConfineCursor(); | 497 UnConfineCursor(); |
| 482 RootWindow* root = delegate_->AsRootWindow(); | 498 RootWindow* root = delegate_->AsRootWindow(); |
| 483 client::ScreenPositionClient* client = | 499 client::ScreenPositionClient* client = |
| 484 client::GetScreenPositionClient(root); | 500 client::GetScreenPositionClient(root); |
| 485 if (client) { | 501 if (client) { |
| 486 gfx::Point p = gfx::Screen::GetCursorScreenPoint(); | 502 gfx::Point p = gfx::Screen::GetCursorScreenPoint(); |
| 487 client->ConvertPointFromScreen(root, &p); | 503 client->ConvertPointFromScreen(root, &p); |
| 488 if (root->ContainsPoint(p)) { | 504 if (root->ContainsPoint(p)) { |
| 489 root->ConvertPointToNativeScreen(&p); | 505 root->ConvertPointToNativeScreen(&p); |
| 490 XWarpPointer( | 506 XWarpPointer( |
| 491 xdisplay_, None, x_root_window_, 0, 0, 0, 0, p.x(), p.y()); | 507 xdisplay_, None, x_root_window_, 0, 0, 0, 0, p.x(), p.y()); |
| 492 } | |
| 493 } | 508 } |
| 494 ConfineCursorToRootWindow(); | |
| 495 } | 509 } |
| 496 if (size_changed) | 510 ConfineCursorToRootWindow(); |
| 497 delegate_->OnHostResized(bounds.size()); | |
| 498 if (origin_changed) | |
| 499 delegate_->OnHostMoved(bounds_.origin()); | |
| 500 } else { | |
| 501 DCHECK_EQ(x_root_window_, xev->xconfigure.event); | |
| 502 DCHECK_EQ(x_root_window_, xev->xconfigure.window); | |
| 503 x_root_bounds_.SetRect(xev->xconfigure.x, xev->xconfigure.y, | |
| 504 xev->xconfigure.width, xev->xconfigure.height); | |
| 505 } | 511 } |
| 512 if (size_changed) |
| 513 delegate_->OnHostResized(bounds.size()); |
| 514 if (origin_changed) |
| 515 delegate_->OnHostMoved(bounds_.origin()); |
| 506 break; | 516 break; |
| 507 } | 517 } |
| 508 case GenericEvent: { | 518 case GenericEvent: |
| 509 ui::TouchFactory* factory = ui::TouchFactory::GetInstance(); | 519 DispatchXI2Event(event); |
| 510 if (!factory->ShouldProcessXI2Event(xev)) | |
| 511 break; | |
| 512 | |
| 513 ui::EventType type = ui::EventTypeFromNative(xev); | |
| 514 XEvent last_event; | |
| 515 int num_coalesced = 0; | |
| 516 | |
| 517 switch (type) { | |
| 518 case ui::ET_TOUCH_MOVED: | |
| 519 num_coalesced = CoalescePendingMotionEvents(xev, &last_event); | |
| 520 if (num_coalesced > 0) | |
| 521 xev = &last_event; | |
| 522 // fallthrough | |
| 523 case ui::ET_TOUCH_PRESSED: | |
| 524 case ui::ET_TOUCH_RELEASED: { | |
| 525 ui::TouchEvent touchev(xev); | |
| 526 #if defined(OS_CHROMEOS) | |
| 527 // X maps the touch-surface to the size of the X root-window. In | |
| 528 // multi-monitor setup, the X root-window size is a combination of | |
| 529 // both the monitor sizes. So it is necessary to remap the location of | |
| 530 // the event from the X root-window to the X host-window for the aura | |
| 531 // root-window. | |
| 532 if (base::chromeos::IsRunningOnChromeOS()) { | |
| 533 touchev.CalibrateLocation(x_root_bounds_.size(), bounds_.size()); | |
| 534 if (!bounds_.Contains(touchev.location())) { | |
| 535 // This might still be in the bezel region. | |
| 536 gfx::Rect expanded(bounds_); | |
| 537 expanded.Inset(-kXRootWindowPaddingLeft, | |
| 538 -kXRootWindowPaddingTop, | |
| 539 -kXRootWindowPaddingRight, | |
| 540 -kXRootWindowPaddingBottom); | |
| 541 if (!expanded.Contains(touchev.location())) | |
| 542 break; | |
| 543 } | |
| 544 } | |
| 545 #endif // defined(OS_CHROMEOS) | |
| 546 delegate_->OnHostTouchEvent(&touchev); | |
| 547 break; | |
| 548 } | |
| 549 case ui::ET_MOUSE_MOVED: | |
| 550 case ui::ET_MOUSE_DRAGGED: | |
| 551 case ui::ET_MOUSE_PRESSED: | |
| 552 case ui::ET_MOUSE_RELEASED: | |
| 553 case ui::ET_MOUSE_ENTERED: | |
| 554 case ui::ET_MOUSE_EXITED: { | |
| 555 if (type == ui::ET_MOUSE_MOVED || type == ui::ET_MOUSE_DRAGGED) { | |
| 556 // If this is a motion event, we want to coalesce all pending motion | |
| 557 // events that are at the top of the queue. | |
| 558 num_coalesced = CoalescePendingMotionEvents(xev, &last_event); | |
| 559 if (num_coalesced > 0) | |
| 560 xev = &last_event; | |
| 561 } else if (type == ui::ET_MOUSE_PRESSED) { | |
| 562 XIDeviceEvent* xievent = | |
| 563 static_cast<XIDeviceEvent*>(xev->xcookie.data); | |
| 564 int button = xievent->detail; | |
| 565 if (button == kBackMouseButton || button == kForwardMouseButton) { | |
| 566 client::UserActionClient* gesture_client = | |
| 567 client::GetUserActionClient(delegate_->AsRootWindow()); | |
| 568 if (gesture_client) { | |
| 569 bool reverse_direction = | |
| 570 ui::IsTouchpadEvent(xev) && ui::IsNaturalScrollEnabled(); | |
| 571 gesture_client->OnUserAction( | |
| 572 (button == kBackMouseButton && !reverse_direction) || | |
| 573 (button == kForwardMouseButton && reverse_direction) ? | |
| 574 client::UserActionClient::BACK : | |
| 575 client::UserActionClient::FORWARD); | |
| 576 } | |
| 577 break; | |
| 578 } | |
| 579 } | |
| 580 ui::MouseEvent mouseev(xev); | |
| 581 delegate_->OnHostMouseEvent(&mouseev); | |
| 582 break; | |
| 583 } | |
| 584 case ui::ET_MOUSEWHEEL: { | |
| 585 ui::MouseWheelEvent mouseev(xev); | |
| 586 delegate_->OnHostMouseEvent(&mouseev); | |
| 587 break; | |
| 588 } | |
| 589 case ui::ET_SCROLL_FLING_START: | |
| 590 case ui::ET_SCROLL_FLING_CANCEL: | |
| 591 case ui::ET_SCROLL: { | |
| 592 ui::ScrollEvent scrollev(xev); | |
| 593 delegate_->OnHostScrollEvent(&scrollev); | |
| 594 break; | |
| 595 } | |
| 596 case ui::ET_UNKNOWN: | |
| 597 break; | |
| 598 default: | |
| 599 NOTREACHED(); | |
| 600 } | |
| 601 | |
| 602 // If we coalesced an event we need to free its cookie. | |
| 603 if (num_coalesced > 0) | |
| 604 XFreeEventData(xev->xgeneric.display, &last_event.xcookie); | |
| 605 break; | 520 break; |
| 606 } | |
| 607 case MapNotify: { | 521 case MapNotify: { |
| 608 // If there's no window manager running, we need to assign the X input | 522 // If there's no window manager running, we need to assign the X input |
| 609 // focus to our host window. | 523 // focus to our host window. |
| 610 if (!IsWindowManagerPresent() && focus_when_shown_) | 524 if (!IsWindowManagerPresent() && focus_when_shown_) |
| 611 XSetInputFocus(xdisplay_, xwindow_, RevertToNone, CurrentTime); | 525 XSetInputFocus(xdisplay_, xwindow_, RevertToNone, CurrentTime); |
| 612 break; | 526 break; |
| 613 } | 527 } |
| 614 case ClientMessage: { | 528 case ClientMessage: { |
| 615 Atom message_type = static_cast<Atom>(xev->xclient.data.l[0]); | 529 Atom message_type = static_cast<Atom>(xev->xclient.data.l[0]); |
| 616 if (message_type == atom_cache_.GetAtom("WM_DELETE_WINDOW")) { | 530 if (message_type == atom_cache_.GetAtom("WM_DELETE_WINDOW")) { |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 663 } | 577 } |
| 664 | 578 |
| 665 ui::MouseEvent mouseev(xev); | 579 ui::MouseEvent mouseev(xev); |
| 666 delegate_->OnHostMouseEvent(&mouseev); | 580 delegate_->OnHostMouseEvent(&mouseev); |
| 667 break; | 581 break; |
| 668 } | 582 } |
| 669 } | 583 } |
| 670 return true; | 584 return true; |
| 671 } | 585 } |
| 672 | 586 |
| 587 bool RootWindowHostLinux::DispatchEventForRootWindow( |
| 588 const base::NativeEvent& event) { |
| 589 switch (event->type) { |
| 590 case ConfigureNotify: |
| 591 DCHECK_EQ(x_root_window_, event->xconfigure.event); |
| 592 x_root_bounds_.SetRect(event->xconfigure.x, event->xconfigure.y, |
| 593 event->xconfigure.width, event->xconfigure.height); |
| 594 break; |
| 595 |
| 596 case GenericEvent: |
| 597 DispatchXI2Event(event); |
| 598 break; |
| 599 } |
| 600 |
| 601 return true; |
| 602 } |
| 603 |
| 604 void RootWindowHostLinux::DispatchXI2Event(const base::NativeEvent& event) { |
| 605 ui::TouchFactory* factory = ui::TouchFactory::GetInstance(); |
| 606 XEvent* xev = event; |
| 607 if (!factory->ShouldProcessXI2Event(xev)) |
| 608 return; |
| 609 |
| 610 ui::EventType type = ui::EventTypeFromNative(xev); |
| 611 XEvent last_event; |
| 612 int num_coalesced = 0; |
| 613 |
| 614 switch (type) { |
| 615 case ui::ET_TOUCH_MOVED: |
| 616 num_coalesced = CoalescePendingMotionEvents(xev, &last_event); |
| 617 if (num_coalesced > 0) |
| 618 xev = &last_event; |
| 619 // fallthrough |
| 620 case ui::ET_TOUCH_PRESSED: |
| 621 case ui::ET_TOUCH_RELEASED: { |
| 622 ui::TouchEvent touchev(xev); |
| 623 #if defined(OS_CHROMEOS) |
| 624 // X maps the touch-surface to the size of the X root-window. In |
| 625 // multi-monitor setup, the X root-window size is a combination of |
| 626 // both the monitor sizes. So it is necessary to remap the location of |
| 627 // the event from the X root-window to the X host-window for the aura |
| 628 // root-window. |
| 629 if (base::chromeos::IsRunningOnChromeOS()) { |
| 630 touchev.CalibrateLocation(x_root_bounds_.size(), bounds_.size()); |
| 631 if (!bounds_.Contains(touchev.location())) { |
| 632 // This might still be in the bezel region. |
| 633 gfx::Rect expanded(bounds_); |
| 634 expanded.Inset(-kXRootWindowPaddingLeft, |
| 635 -kXRootWindowPaddingTop, |
| 636 -kXRootWindowPaddingRight, |
| 637 -kXRootWindowPaddingBottom); |
| 638 if (!expanded.Contains(touchev.location())) |
| 639 break; |
| 640 } |
| 641 } |
| 642 #endif // defined(OS_CHROMEOS) |
| 643 delegate_->OnHostTouchEvent(&touchev); |
| 644 break; |
| 645 } |
| 646 case ui::ET_MOUSE_MOVED: |
| 647 case ui::ET_MOUSE_DRAGGED: |
| 648 case ui::ET_MOUSE_PRESSED: |
| 649 case ui::ET_MOUSE_RELEASED: |
| 650 case ui::ET_MOUSE_ENTERED: |
| 651 case ui::ET_MOUSE_EXITED: { |
| 652 if (type == ui::ET_MOUSE_MOVED || type == ui::ET_MOUSE_DRAGGED) { |
| 653 // If this is a motion event, we want to coalesce all pending motion |
| 654 // events that are at the top of the queue. |
| 655 num_coalesced = CoalescePendingMotionEvents(xev, &last_event); |
| 656 if (num_coalesced > 0) |
| 657 xev = &last_event; |
| 658 } else if (type == ui::ET_MOUSE_PRESSED) { |
| 659 XIDeviceEvent* xievent = |
| 660 static_cast<XIDeviceEvent*>(xev->xcookie.data); |
| 661 int button = xievent->detail; |
| 662 if (button == kBackMouseButton || button == kForwardMouseButton) { |
| 663 client::UserActionClient* gesture_client = |
| 664 client::GetUserActionClient(delegate_->AsRootWindow()); |
| 665 if (gesture_client) { |
| 666 bool reverse_direction = |
| 667 ui::IsTouchpadEvent(xev) && ui::IsNaturalScrollEnabled(); |
| 668 gesture_client->OnUserAction( |
| 669 (button == kBackMouseButton && !reverse_direction) || |
| 670 (button == kForwardMouseButton && reverse_direction) ? |
| 671 client::UserActionClient::BACK : |
| 672 client::UserActionClient::FORWARD); |
| 673 } |
| 674 break; |
| 675 } |
| 676 } |
| 677 ui::MouseEvent mouseev(xev); |
| 678 delegate_->OnHostMouseEvent(&mouseev); |
| 679 break; |
| 680 } |
| 681 case ui::ET_MOUSEWHEEL: { |
| 682 ui::MouseWheelEvent mouseev(xev); |
| 683 delegate_->OnHostMouseEvent(&mouseev); |
| 684 break; |
| 685 } |
| 686 case ui::ET_SCROLL_FLING_START: |
| 687 case ui::ET_SCROLL_FLING_CANCEL: |
| 688 case ui::ET_SCROLL: { |
| 689 ui::ScrollEvent scrollev(xev); |
| 690 delegate_->OnHostScrollEvent(&scrollev); |
| 691 break; |
| 692 } |
| 693 case ui::ET_UNKNOWN: |
| 694 break; |
| 695 default: |
| 696 NOTREACHED(); |
| 697 } |
| 698 |
| 699 // If we coalesced an event we need to free its cookie. |
| 700 if (num_coalesced > 0) |
| 701 XFreeEventData(xev->xgeneric.display, &last_event.xcookie); |
| 702 } |
| 703 |
| 673 RootWindow* RootWindowHostLinux::GetRootWindow() { | 704 RootWindow* RootWindowHostLinux::GetRootWindow() { |
| 674 return delegate_->AsRootWindow(); | 705 return delegate_->AsRootWindow(); |
| 675 } | 706 } |
| 676 | 707 |
| 677 gfx::AcceleratedWidget RootWindowHostLinux::GetAcceleratedWidget() { | 708 gfx::AcceleratedWidget RootWindowHostLinux::GetAcceleratedWidget() { |
| 678 return xwindow_; | 709 return xwindow_; |
| 679 } | 710 } |
| 680 | 711 |
| 681 void RootWindowHostLinux::Show() { | 712 void RootWindowHostLinux::Show() { |
| 682 if (!window_mapped_) { | 713 if (!window_mapped_) { |
| (...skipping 279 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 962 ui::ViewProp::GetValue(accelerated_widget, kRootWindowHostLinuxKey)); | 993 ui::ViewProp::GetValue(accelerated_widget, kRootWindowHostLinuxKey)); |
| 963 } | 994 } |
| 964 | 995 |
| 965 // static | 996 // static |
| 966 gfx::Size RootWindowHost::GetNativeScreenSize() { | 997 gfx::Size RootWindowHost::GetNativeScreenSize() { |
| 967 ::Display* xdisplay = base::MessagePumpAuraX11::GetDefaultXDisplay(); | 998 ::Display* xdisplay = base::MessagePumpAuraX11::GetDefaultXDisplay(); |
| 968 return gfx::Size(DisplayWidth(xdisplay, 0), DisplayHeight(xdisplay, 0)); | 999 return gfx::Size(DisplayWidth(xdisplay, 0), DisplayHeight(xdisplay, 0)); |
| 969 } | 1000 } |
| 970 | 1001 |
| 971 } // namespace aura | 1002 } // namespace aura |
| OLD | NEW |