| 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/cursorfont.h> | 8 #include <X11/cursorfont.h> |
| 9 #include <X11/extensions/XInput2.h> | 9 #include <X11/extensions/XInput2.h> |
| 10 #include <X11/extensions/Xfixes.h> | 10 #include <X11/extensions/Xfixes.h> |
| (...skipping 368 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 379 UnConfineCursor(); | 379 UnConfineCursor(); |
| 380 | 380 |
| 381 XDestroyWindow(xdisplay_, xwindow_); | 381 XDestroyWindow(xdisplay_, xwindow_); |
| 382 | 382 |
| 383 // Clears XCursorCache. | 383 // Clears XCursorCache. |
| 384 ui::GetXCursor(ui::kCursorClearXCursorCache); | 384 ui::GetXCursor(ui::kCursorClearXCursorCache); |
| 385 | 385 |
| 386 XFreeCursor(xdisplay_, invisible_cursor_); | 386 XFreeCursor(xdisplay_, invisible_cursor_); |
| 387 } | 387 } |
| 388 | 388 |
| 389 base::MessagePumpDispatcher::DispatchStatus RootWindowHostLinux::Dispatch( | 389 bool RootWindowHostLinux::Dispatch(const base::NativeEvent& event) { |
| 390 XEvent* xev) { | 390 XEvent* xev = event; |
| 391 bool handled = false; | |
| 392 | 391 |
| 393 // See crbug.com/109884. | 392 // See crbug.com/109884. |
| 394 // CheckXEventForConsistency(xev); | 393 // CheckXEventForConsistency(xev); |
| 395 | 394 |
| 396 switch (xev->type) { | 395 switch (xev->type) { |
| 397 case Expose: | 396 case Expose: |
| 398 root_window_->ScheduleFullDraw(); | 397 root_window_->ScheduleFullDraw(); |
| 399 handled = true; | |
| 400 break; | 398 break; |
| 401 case KeyPress: { | 399 case KeyPress: { |
| 402 KeyEvent keydown_event(xev, false); | 400 KeyEvent keydown_event(xev, false); |
| 403 handled = root_window_->DispatchKeyEvent(&keydown_event); | 401 root_window_->DispatchKeyEvent(&keydown_event); |
| 404 break; | 402 break; |
| 405 } | 403 } |
| 406 case KeyRelease: { | 404 case KeyRelease: { |
| 407 KeyEvent keyup_event(xev, false); | 405 KeyEvent keyup_event(xev, false); |
| 408 handled = root_window_->DispatchKeyEvent(&keyup_event); | 406 root_window_->DispatchKeyEvent(&keyup_event); |
| 409 break; | 407 break; |
| 410 } | 408 } |
| 411 case ButtonPress: | 409 case ButtonPress: |
| 412 case ButtonRelease: { | 410 case ButtonRelease: { |
| 413 MouseEvent mouseev(xev); | 411 MouseEvent mouseev(xev); |
| 414 handled = root_window_->DispatchMouseEvent(&mouseev); | 412 root_window_->DispatchMouseEvent(&mouseev); |
| 415 break; | 413 break; |
| 416 } | 414 } |
| 417 case FocusOut: | 415 case FocusOut: |
| 418 if (xev->xfocus.mode != NotifyGrab) | 416 if (xev->xfocus.mode != NotifyGrab) |
| 419 root_window_->SetCapture(NULL); | 417 root_window_->SetCapture(NULL); |
| 420 break; | 418 break; |
| 421 case ConfigureNotify: { | 419 case ConfigureNotify: { |
| 422 DCHECK_EQ(xwindow_, xev->xconfigure.window); | 420 DCHECK_EQ(xwindow_, xev->xconfigure.window); |
| 423 DCHECK_EQ(xwindow_, xev->xconfigure.event); | 421 DCHECK_EQ(xwindow_, xev->xconfigure.event); |
| 424 // Update barrier and mouse location when the root window has | 422 // Update barrier and mouse location when the root window has |
| 425 // moved/resized. | 423 // moved/resized. |
| 426 if (pointer_barriers_.get()) { | 424 if (pointer_barriers_.get()) { |
| 427 UnConfineCursor(); | 425 UnConfineCursor(); |
| 428 gfx::Point p = root_window_->last_mouse_location(); | 426 gfx::Point p = root_window_->last_mouse_location(); |
| 429 XWarpPointer(xdisplay_, None, xwindow_, 0, 0, 0, 0, p.x(), p.y()); | 427 XWarpPointer(xdisplay_, None, xwindow_, 0, 0, 0, 0, p.x(), p.y()); |
| 430 ConfineCursorToRootWindow(); | 428 ConfineCursorToRootWindow(); |
| 431 } | 429 } |
| 432 // It's possible that the X window may be resized by some other means than | 430 // It's possible that the X window may be resized by some other means than |
| 433 // from within aura (e.g. the X window manager can change the size). Make | 431 // from within aura (e.g. the X window manager can change the size). Make |
| 434 // sure the root window size is maintained properly. | 432 // sure the root window size is maintained properly. |
| 435 gfx::Rect bounds(xev->xconfigure.x, xev->xconfigure.y, | 433 gfx::Rect bounds(xev->xconfigure.x, xev->xconfigure.y, |
| 436 xev->xconfigure.width, xev->xconfigure.height); | 434 xev->xconfigure.width, xev->xconfigure.height); |
| 437 bool size_changed = bounds_.size() != bounds.size(); | 435 bool size_changed = bounds_.size() != bounds.size(); |
| 438 bounds_ = bounds; | 436 bounds_ = bounds; |
| 439 if (size_changed) | 437 if (size_changed) |
| 440 root_window_->OnHostResized(bounds.size()); | 438 root_window_->OnHostResized(bounds.size()); |
| 441 handled = true; | |
| 442 break; | 439 break; |
| 443 } | 440 } |
| 444 case GenericEvent: { | 441 case GenericEvent: { |
| 445 ui::TouchFactory* factory = ui::TouchFactory::GetInstance(); | 442 ui::TouchFactory* factory = ui::TouchFactory::GetInstance(); |
| 446 if (!factory->ShouldProcessXI2Event(xev)) | 443 if (!factory->ShouldProcessXI2Event(xev)) |
| 447 break; | 444 break; |
| 448 | 445 |
| 449 ui::EventType type = ui::EventTypeFromNative(xev); | 446 ui::EventType type = ui::EventTypeFromNative(xev); |
| 450 // If this is a motion event we want to coalesce all pending motion | 447 // If this is a motion event we want to coalesce all pending motion |
| 451 // events that are at the top of the queue. | 448 // events that are at the top of the queue. |
| 452 XEvent last_event; | 449 XEvent last_event; |
| 453 int num_coalesced = 0; | 450 int num_coalesced = 0; |
| 454 | 451 |
| 455 switch (type) { | 452 switch (type) { |
| 456 case ui::ET_TOUCH_PRESSED: | 453 case ui::ET_TOUCH_PRESSED: |
| 457 case ui::ET_TOUCH_RELEASED: | 454 case ui::ET_TOUCH_RELEASED: |
| 458 case ui::ET_TOUCH_MOVED: { | 455 case ui::ET_TOUCH_MOVED: { |
| 459 TouchEvent touchev(xev); | 456 TouchEvent touchev(xev); |
| 460 handled = root_window_->DispatchTouchEvent(&touchev); | 457 root_window_->DispatchTouchEvent(&touchev); |
| 461 break; | 458 break; |
| 462 } | 459 } |
| 463 case ui::ET_MOUSE_MOVED: | 460 case ui::ET_MOUSE_MOVED: |
| 464 case ui::ET_MOUSE_DRAGGED: { | 461 case ui::ET_MOUSE_DRAGGED: { |
| 465 // If this is a motion event we want to coalesce all pending motion | 462 // If this is a motion event we want to coalesce all pending motion |
| 466 // events that are at the top of the queue. | 463 // events that are at the top of the queue. |
| 467 num_coalesced = CoalescePendingXIMotionEvents(xev, &last_event); | 464 num_coalesced = CoalescePendingXIMotionEvents(xev, &last_event); |
| 468 if (num_coalesced > 0) | 465 if (num_coalesced > 0) |
| 469 xev = &last_event; | 466 xev = &last_event; |
| 470 } | 467 } |
| 471 case ui::ET_MOUSE_PRESSED: | 468 case ui::ET_MOUSE_PRESSED: |
| 472 case ui::ET_MOUSE_RELEASED: | 469 case ui::ET_MOUSE_RELEASED: |
| 473 case ui::ET_MOUSEWHEEL: | 470 case ui::ET_MOUSEWHEEL: |
| 474 case ui::ET_MOUSE_ENTERED: | 471 case ui::ET_MOUSE_ENTERED: |
| 475 case ui::ET_MOUSE_EXITED: { | 472 case ui::ET_MOUSE_EXITED: { |
| 476 MouseEvent mouseev(xev); | 473 MouseEvent mouseev(xev); |
| 477 handled = root_window_->DispatchMouseEvent(&mouseev); | 474 root_window_->DispatchMouseEvent(&mouseev); |
| 478 break; | 475 break; |
| 479 } | 476 } |
| 480 case ui::ET_SCROLL_FLING_START: | 477 case ui::ET_SCROLL_FLING_START: |
| 481 case ui::ET_SCROLL_FLING_CANCEL: | 478 case ui::ET_SCROLL_FLING_CANCEL: |
| 482 case ui::ET_SCROLL: { | 479 case ui::ET_SCROLL: { |
| 483 ScrollEvent scrollev(xev); | 480 ScrollEvent scrollev(xev); |
| 484 handled = root_window_->DispatchScrollEvent(&scrollev); | 481 root_window_->DispatchScrollEvent(&scrollev); |
| 485 break; | 482 break; |
| 486 } | 483 } |
| 487 case ui::ET_UNKNOWN: | 484 case ui::ET_UNKNOWN: |
| 488 handled = false; | |
| 489 break; | 485 break; |
| 490 default: | 486 default: |
| 491 NOTREACHED(); | 487 NOTREACHED(); |
| 492 } | 488 } |
| 493 | 489 |
| 494 // If we coalesced an event we need to free its cookie. | 490 // If we coalesced an event we need to free its cookie. |
| 495 if (num_coalesced > 0) | 491 if (num_coalesced > 0) |
| 496 XFreeEventData(xev->xgeneric.display, &last_event.xcookie); | 492 XFreeEventData(xev->xgeneric.display, &last_event.xcookie); |
| 497 break; | 493 break; |
| 498 } | 494 } |
| 499 case MapNotify: { | 495 case MapNotify: { |
| 500 // If there's no window manager running, we need to assign the X input | 496 // If there's no window manager running, we need to assign the X input |
| 501 // focus to our host window. | 497 // focus to our host window. |
| 502 if (!IsWindowManagerPresent() && focus_when_shown_) | 498 if (!IsWindowManagerPresent() && focus_when_shown_) |
| 503 XSetInputFocus(xdisplay_, xwindow_, RevertToNone, CurrentTime); | 499 XSetInputFocus(xdisplay_, xwindow_, RevertToNone, CurrentTime); |
| 504 handled = true; | |
| 505 break; | 500 break; |
| 506 } | 501 } |
| 507 case ClientMessage: { | 502 case ClientMessage: { |
| 508 Atom message_type = static_cast<Atom>(xev->xclient.data.l[0]); | 503 Atom message_type = static_cast<Atom>(xev->xclient.data.l[0]); |
| 509 if (message_type == cached_atoms_[ATOM_WM_DELETE_WINDOW]) { | 504 if (message_type == cached_atoms_[ATOM_WM_DELETE_WINDOW]) { |
| 510 // We have received a close message from the window manager. | 505 // We have received a close message from the window manager. |
| 511 root_window_->OnRootWindowHostClosed(); | 506 root_window_->OnRootWindowHostClosed(); |
| 512 handled = true; | |
| 513 } else if (message_type == cached_atoms_[ATOM__NET_WM_PING]) { | 507 } else if (message_type == cached_atoms_[ATOM__NET_WM_PING]) { |
| 514 XEvent reply_event = *xev; | 508 XEvent reply_event = *xev; |
| 515 reply_event.xclient.window = x_root_window_; | 509 reply_event.xclient.window = x_root_window_; |
| 516 | 510 |
| 517 XSendEvent(xdisplay_, | 511 XSendEvent(xdisplay_, |
| 518 reply_event.xclient.window, | 512 reply_event.xclient.window, |
| 519 False, | 513 False, |
| 520 SubstructureRedirectMask | SubstructureNotifyMask, | 514 SubstructureRedirectMask | SubstructureNotifyMask, |
| 521 &reply_event); | 515 &reply_event); |
| 522 | |
| 523 handled = true; | |
| 524 } | 516 } |
| 525 break; | 517 break; |
| 526 } | 518 } |
| 527 case MappingNotify: { | 519 case MappingNotify: { |
| 528 switch (xev->xmapping.request) { | 520 switch (xev->xmapping.request) { |
| 529 case MappingModifier: | 521 case MappingModifier: |
| 530 case MappingKeyboard: | 522 case MappingKeyboard: |
| 531 XRefreshKeyboardMapping(&xev->xmapping); | 523 XRefreshKeyboardMapping(&xev->xmapping); |
| 532 root_window_->OnKeyboardMappingChanged(); | 524 root_window_->OnKeyboardMappingChanged(); |
| 533 break; | 525 break; |
| (...skipping 18 matching lines...) Expand all Loading... |
| 552 next_event.xmotion.subwindow == xev->xmotion.subwindow && | 544 next_event.xmotion.subwindow == xev->xmotion.subwindow && |
| 553 next_event.xmotion.state == xev->xmotion.state) { | 545 next_event.xmotion.state == xev->xmotion.state) { |
| 554 XNextEvent(xev->xany.display, &last_event); | 546 XNextEvent(xev->xany.display, &last_event); |
| 555 xev = &last_event; | 547 xev = &last_event; |
| 556 } else { | 548 } else { |
| 557 break; | 549 break; |
| 558 } | 550 } |
| 559 } | 551 } |
| 560 | 552 |
| 561 MouseEvent mouseev(xev); | 553 MouseEvent mouseev(xev); |
| 562 handled = root_window_->DispatchMouseEvent(&mouseev); | 554 root_window_->DispatchMouseEvent(&mouseev); |
| 563 break; | 555 break; |
| 564 } | 556 } |
| 565 } | 557 } |
| 566 return handled ? base::MessagePumpDispatcher::EVENT_PROCESSED : | 558 return true; |
| 567 base::MessagePumpDispatcher::EVENT_IGNORED; | |
| 568 } | 559 } |
| 569 | 560 |
| 570 void RootWindowHostLinux::SetRootWindow(RootWindow* root_window) { | 561 void RootWindowHostLinux::SetRootWindow(RootWindow* root_window) { |
| 571 root_window_ = root_window; | 562 root_window_ = root_window; |
| 572 } | 563 } |
| 573 | 564 |
| 574 gfx::AcceleratedWidget RootWindowHostLinux::GetAcceleratedWidget() { | 565 gfx::AcceleratedWidget RootWindowHostLinux::GetAcceleratedWidget() { |
| 575 return xwindow_; | 566 return xwindow_; |
| 576 } | 567 } |
| 577 | 568 |
| (...skipping 210 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 788 return new RootWindowHostLinux(bounds); | 779 return new RootWindowHostLinux(bounds); |
| 789 } | 780 } |
| 790 | 781 |
| 791 // static | 782 // static |
| 792 gfx::Size RootWindowHost::GetNativeScreenSize() { | 783 gfx::Size RootWindowHost::GetNativeScreenSize() { |
| 793 ::Display* xdisplay = base::MessagePumpX::GetDefaultXDisplay(); | 784 ::Display* xdisplay = base::MessagePumpX::GetDefaultXDisplay(); |
| 794 return gfx::Size(DisplayWidth(xdisplay, 0), DisplayHeight(xdisplay, 0)); | 785 return gfx::Size(DisplayWidth(xdisplay, 0), DisplayHeight(xdisplay, 0)); |
| 795 } | 786 } |
| 796 | 787 |
| 797 } // namespace aura | 788 } // namespace aura |
| OLD | NEW |