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 |