Chromium Code Reviews| 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 188 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 199 } else { | 199 } else { |
| 200 // This isn't an event we want so free its cookie data. | 200 // This isn't an event we want so free its cookie data. |
| 201 XFreeEventData(display, &next_event.xcookie); | 201 XFreeEventData(display, &next_event.xcookie); |
| 202 } | 202 } |
| 203 } | 203 } |
| 204 break; | 204 break; |
| 205 } | 205 } |
| 206 return num_coalesed; | 206 return num_coalesed; |
| 207 } | 207 } |
| 208 | 208 |
| 209 ::Window FindEventTarget(const base::NativeEvent& xev) { | |
| 210 ::Window target = xev->xany.window; | |
| 211 if (xev->type == GenericEvent) | |
| 212 target = static_cast<XIDeviceEvent*>(xev->xcookie.data)->event; | |
| 213 return target; | |
| 214 } | |
| 215 | |
| 209 void SelectEventsForRootWindow() { | 216 void SelectEventsForRootWindow() { |
| 210 XIEventMask evmask; | 217 XIEventMask evmask; |
| 211 unsigned char mask[XIMaskLen(XI_LASTEVENT)] = {}; | 218 unsigned char mask[XIMaskLen(XI_LASTEVENT)] = {}; |
| 212 memset(mask, 0, sizeof(mask)); | 219 memset(mask, 0, sizeof(mask)); |
| 213 | 220 |
| 214 XISetMask(mask, XI_HierarchyChanged); | 221 XISetMask(mask, XI_HierarchyChanged); |
| 215 | 222 |
| 216 XISetMask(mask, XI_KeyPress); | 223 XISetMask(mask, XI_KeyPress); |
| 217 XISetMask(mask, XI_KeyRelease); | 224 XISetMask(mask, XI_KeyRelease); |
| 218 | 225 |
| 219 #if defined(USE_XI2_MT) | 226 #if defined(USE_XI2_MT) |
| 220 XISetMask(mask, XI_TouchBegin); | 227 XISetMask(mask, XI_TouchBegin); |
| 221 XISetMask(mask, XI_TouchUpdate); | 228 XISetMask(mask, XI_TouchUpdate); |
| 222 XISetMask(mask, XI_TouchEnd); | 229 XISetMask(mask, XI_TouchEnd); |
| 223 #endif | 230 #endif |
| 224 XISetMask(mask, XI_ButtonPress); | 231 XISetMask(mask, XI_ButtonPress); |
| 225 XISetMask(mask, XI_ButtonRelease); | 232 XISetMask(mask, XI_ButtonRelease); |
| 226 XISetMask(mask, XI_Motion); | 233 XISetMask(mask, XI_Motion); |
| 227 | 234 |
| 228 evmask.deviceid = XIAllDevices; | 235 evmask.deviceid = XIAllDevices; |
| 229 evmask.mask_len = sizeof(mask); | 236 evmask.mask_len = sizeof(mask); |
| 230 evmask.mask = mask; | 237 evmask.mask = mask; |
| 231 | 238 |
| 232 Display* display = ui::GetXDisplay(); | 239 Display* display = ui::GetXDisplay(); |
| 233 ::Window root_window = ui::GetX11RootWindow(); | 240 ::Window root_window = ui::GetX11RootWindow(); |
| 234 XISelectEvents(display, root_window, &evmask, 1); | 241 XISelectEvents(display, root_window, &evmask, 1); |
| 235 | 242 |
| 236 // Receive resize events for the root-window so |x_root_bounds_| can be | 243 // Receive resize events for the root-window so |x_root_bounds_| can be |
| 237 // updated. | 244 // updated. |
| 238 XSelectInput(display, root_window, StructureNotifyMask); | 245 XWindowAttributes attr; |
| 246 XGetWindowAttributes(display, root_window, &attr); | |
| 247 if (!(attr.your_event_mask & StructureNotifyMask)) { | |
| 248 XSelectInput(display, root_window, | |
| 249 StructureNotifyMask | attr.your_event_mask); | |
| 250 } | |
| 239 } | 251 } |
| 240 | 252 |
| 241 // We emulate Windows' WM_KEYDOWN and WM_CHAR messages. WM_CHAR events are only | 253 // We emulate Windows' WM_KEYDOWN and WM_CHAR messages. WM_CHAR events are only |
| 242 // generated for certain keys; see | 254 // generated for certain keys; see |
| 243 // http://msdn.microsoft.com/en-us/library/windows/desktop/ms646268.aspx. Per | 255 // http://msdn.microsoft.com/en-us/library/windows/desktop/ms646268.aspx. Per |
| 244 // discussion on http://crbug.com/108480, char events should furthermore not be | 256 // discussion on http://crbug.com/108480, char events should furthermore not be |
| 245 // generated for Tab, Escape, and Backspace. | 257 // generated for Tab, Escape, and Backspace. |
| 246 bool ShouldSendCharEventForKeyboardCode(ui::KeyboardCode keycode) { | 258 bool ShouldSendCharEventForKeyboardCode(ui::KeyboardCode keycode) { |
| 247 if ((keycode >= ui::VKEY_0 && keycode <= ui::VKEY_9) || | 259 if ((keycode >= ui::VKEY_0 && keycode <= ui::VKEY_9) || |
| 248 (keycode >= ui::VKEY_A && keycode <= ui::VKEY_Z) || | 260 (keycode >= ui::VKEY_A && keycode <= ui::VKEY_Z) || |
| (...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 373 XDestroyWindow(xdisplay_, xwindow_); | 385 XDestroyWindow(xdisplay_, xwindow_); |
| 374 | 386 |
| 375 XFreeCursor(xdisplay_, invisible_cursor_); | 387 XFreeCursor(xdisplay_, invisible_cursor_); |
| 376 } | 388 } |
| 377 | 389 |
| 378 bool RootWindowHostLinux::Dispatch(const base::NativeEvent& event) { | 390 bool RootWindowHostLinux::Dispatch(const base::NativeEvent& event) { |
| 379 XEvent* xev = event; | 391 XEvent* xev = event; |
| 380 | 392 |
| 381 CheckXEventForConsistency(xev); | 393 CheckXEventForConsistency(xev); |
| 382 | 394 |
| 395 if (FindEventTarget(event) == x_root_window_) | |
| 396 return DispatchEventForRootWindow(event); | |
| 397 | |
| 383 switch (xev->type) { | 398 switch (xev->type) { |
| 384 case EnterNotify: { | 399 case EnterNotify: { |
| 385 ui::MouseEvent mouseenter_event(xev); | 400 ui::MouseEvent mouseenter_event(xev); |
| 386 delegate_->OnHostMouseEvent(&mouseenter_event); | 401 delegate_->OnHostMouseEvent(&mouseenter_event); |
| 387 break; | 402 break; |
| 388 } | 403 } |
| 389 case Expose: | 404 case Expose: |
| 390 delegate_->AsRootWindow()->ScheduleFullDraw(); | 405 delegate_->AsRootWindow()->ScheduleFullDraw(); |
| 391 break; | 406 break; |
| 392 case KeyPress: { | 407 case KeyPress: { |
| (...skipping 23 matching lines...) Expand all Loading... | |
| 416 case ButtonRelease: { | 431 case ButtonRelease: { |
| 417 ui::MouseEvent mouseev(xev); | 432 ui::MouseEvent mouseev(xev); |
| 418 delegate_->OnHostMouseEvent(&mouseev); | 433 delegate_->OnHostMouseEvent(&mouseev); |
| 419 break; | 434 break; |
| 420 } | 435 } |
| 421 case FocusOut: | 436 case FocusOut: |
| 422 if (xev->xfocus.mode != NotifyGrab) | 437 if (xev->xfocus.mode != NotifyGrab) |
| 423 delegate_->OnHostLostCapture(); | 438 delegate_->OnHostLostCapture(); |
| 424 break; | 439 break; |
| 425 case ConfigureNotify: { | 440 case ConfigureNotify: { |
| 426 if (xev->xconfigure.window == xwindow_) { | 441 DCHECK_EQ(xwindow_, xev->xconfigure.event); |
| 427 DCHECK_EQ(xwindow_, xev->xconfigure.event); | 442 DCHECK_EQ(xwindow_, xev->xconfigure.window); |
| 428 // It's possible that the X window may be resized by some other means | 443 // It's possible that the X window may be resized by some other means |
| 429 // than from within aura (e.g. the X window manager can change the | 444 // than from within aura (e.g. the X window manager can change the |
| 430 // size). Make sure the root window size is maintained properly. | 445 // size). Make sure the root window size is maintained properly. |
| 431 gfx::Rect bounds(xev->xconfigure.x, xev->xconfigure.y, | 446 gfx::Rect bounds(xev->xconfigure.x, xev->xconfigure.y, |
| 432 xev->xconfigure.width, xev->xconfigure.height); | 447 xev->xconfigure.width, xev->xconfigure.height); |
| 433 bool size_changed = bounds_.size() != bounds.size(); | 448 bool size_changed = bounds_.size() != bounds.size(); |
| 434 bool origin_changed = bounds_.origin() != bounds.origin(); | 449 bool origin_changed = bounds_.origin() != bounds.origin(); |
| 435 bounds_ = bounds; | 450 bounds_ = bounds; |
| 436 // Always update barrier and mouse location because |bounds_| might | 451 // Always update barrier and mouse location because |bounds_| might |
| 437 // have already been updated in |SetBounds|. | 452 // have already been updated in |SetBounds|. |
| 438 if (pointer_barriers_.get()) { | 453 if (pointer_barriers_.get()) { |
| 439 UnConfineCursor(); | 454 UnConfineCursor(); |
| 440 RootWindow* root = delegate_->AsRootWindow(); | 455 RootWindow* root = delegate_->AsRootWindow(); |
| 441 client::ScreenPositionClient* client = | 456 client::ScreenPositionClient* client = |
| 442 client::GetScreenPositionClient(root); | 457 client::GetScreenPositionClient(root); |
| 443 if (client) { | 458 if (client) { |
| 444 gfx::Point p = gfx::Screen::GetCursorScreenPoint(); | 459 gfx::Point p = gfx::Screen::GetCursorScreenPoint(); |
| 445 client->ConvertPointFromScreen(root, &p); | 460 client->ConvertPointFromScreen(root, &p); |
| 446 if (root->ContainsPoint(p)) { | 461 if (root->ContainsPoint(p)) { |
| 447 root->ConvertPointToNativeScreen(&p); | 462 root->ConvertPointToNativeScreen(&p); |
| 448 XWarpPointer( | 463 XWarpPointer( |
| 449 xdisplay_, None, x_root_window_, 0, 0, 0, 0, p.x(), p.y()); | 464 xdisplay_, None, x_root_window_, 0, 0, 0, 0, p.x(), p.y()); |
| 450 } | |
| 451 } | 465 } |
| 452 ConfineCursorToRootWindow(); | |
| 453 } | 466 } |
| 454 if (size_changed) | 467 ConfineCursorToRootWindow(); |
| 455 delegate_->OnHostResized(bounds.size()); | |
| 456 if (origin_changed) | |
| 457 delegate_->OnHostMoved(bounds_.origin()); | |
| 458 } else { | |
| 459 DCHECK_EQ(x_root_window_, xev->xconfigure.event); | |
| 460 DCHECK_EQ(x_root_window_, xev->xconfigure.window); | |
| 461 x_root_bounds_.SetRect(xev->xconfigure.x, xev->xconfigure.y, | |
| 462 xev->xconfigure.width, xev->xconfigure.height); | |
| 463 } | 468 } |
| 469 if (size_changed) | |
| 470 delegate_->OnHostResized(bounds.size()); | |
| 471 if (origin_changed) | |
| 472 delegate_->OnHostMoved(bounds_.origin()); | |
| 464 break; | 473 break; |
| 465 } | 474 } |
| 466 case GenericEvent: { | 475 case GenericEvent: { |
| 467 ui::TouchFactory* factory = ui::TouchFactory::GetInstance(); | 476 ui::TouchFactory* factory = ui::TouchFactory::GetInstance(); |
| 468 if (!factory->ShouldProcessXI2Event(xev)) | 477 if (!factory->ShouldProcessXI2Event(xev)) |
| 469 break; | 478 break; |
| 470 | 479 |
| 471 ui::EventType type = ui::EventTypeFromNative(xev); | 480 ui::EventType type = ui::EventTypeFromNative(xev); |
| 472 XEvent last_event; | 481 XEvent last_event; |
| 473 int num_coalesced = 0; | 482 int num_coalesced = 0; |
| (...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 621 } | 630 } |
| 622 | 631 |
| 623 ui::MouseEvent mouseev(xev); | 632 ui::MouseEvent mouseev(xev); |
| 624 delegate_->OnHostMouseEvent(&mouseev); | 633 delegate_->OnHostMouseEvent(&mouseev); |
| 625 break; | 634 break; |
| 626 } | 635 } |
| 627 } | 636 } |
| 628 return true; | 637 return true; |
| 629 } | 638 } |
| 630 | 639 |
| 640 bool RootWindowHostLinux::DispatchEventForRootWindow( | |
| 641 const base::NativeEvent& event) { | |
| 642 switch (event->type) { | |
| 643 case ConfigureNotify: | |
| 644 DCHECK_EQ(x_root_window_, event->xconfigure.event); | |
| 645 DCHECK_EQ(x_root_window_, event->xconfigure.window); | |
| 646 x_root_bounds_.SetRect(event->xconfigure.x, event->xconfigure.y, | |
| 647 event->xconfigure.width, event->xconfigure.height); | |
| 648 break; | |
| 649 } | |
| 650 | |
| 651 return false; | |
|
Daniel Erat
2012/09/13 19:14:09
i think that we previously returned true in this c
sadrul
2012/09/13 23:41:24
It wasn't. Incidentally, however, the return value
| |
| 652 } | |
| 653 | |
| 631 RootWindow* RootWindowHostLinux::GetRootWindow() { | 654 RootWindow* RootWindowHostLinux::GetRootWindow() { |
| 632 return delegate_->AsRootWindow(); | 655 return delegate_->AsRootWindow(); |
| 633 } | 656 } |
| 634 | 657 |
| 635 gfx::AcceleratedWidget RootWindowHostLinux::GetAcceleratedWidget() { | 658 gfx::AcceleratedWidget RootWindowHostLinux::GetAcceleratedWidget() { |
| 636 return xwindow_; | 659 return xwindow_; |
| 637 } | 660 } |
| 638 | 661 |
| 639 void RootWindowHostLinux::Show() { | 662 void RootWindowHostLinux::Show() { |
| 640 if (!window_mapped_) { | 663 if (!window_mapped_) { |
| (...skipping 279 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 920 ui::ViewProp::GetValue(accelerated_widget, kRootWindowHostLinuxKey)); | 943 ui::ViewProp::GetValue(accelerated_widget, kRootWindowHostLinuxKey)); |
| 921 } | 944 } |
| 922 | 945 |
| 923 // static | 946 // static |
| 924 gfx::Size RootWindowHost::GetNativeScreenSize() { | 947 gfx::Size RootWindowHost::GetNativeScreenSize() { |
| 925 ::Display* xdisplay = base::MessagePumpAuraX11::GetDefaultXDisplay(); | 948 ::Display* xdisplay = base::MessagePumpAuraX11::GetDefaultXDisplay(); |
| 926 return gfx::Size(DisplayWidth(xdisplay, 0), DisplayHeight(xdisplay, 0)); | 949 return gfx::Size(DisplayWidth(xdisplay, 0), DisplayHeight(xdisplay, 0)); |
| 927 } | 950 } |
| 928 | 951 |
| 929 } // namespace aura | 952 } // namespace aura |
| OLD | NEW |