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/views/widget/desktop_aura/desktop_window_tree_host_x11.h" | 5 #include "ui/views/widget/desktop_aura/desktop_window_tree_host_x11.h" |
| 6 | 6 |
| 7 #include <X11/extensions/shape.h> | 7 #include <X11/extensions/shape.h> |
| 8 #include <X11/extensions/XInput2.h> | 8 #include <X11/extensions/XInput2.h> |
| 9 #include <X11/Xatom.h> | 9 #include <X11/Xatom.h> |
| 10 #include <X11/Xregion.h> | 10 #include <X11/Xregion.h> |
| (...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 84 const int k_NET_WM_STATE_REMOVE = 0; | 84 const int k_NET_WM_STATE_REMOVE = 0; |
| 85 | 85 |
| 86 // Special value of the _NET_WM_DESKTOP property which indicates that the window | 86 // Special value of the _NET_WM_DESKTOP property which indicates that the window |
| 87 // should appear on all desktops. | 87 // should appear on all desktops. |
| 88 const int kAllDesktops = 0xFFFFFFFF; | 88 const int kAllDesktops = 0xFFFFFFFF; |
| 89 | 89 |
| 90 const char* kAtomsToCache[] = { | 90 const char* kAtomsToCache[] = { |
| 91 "UTF8_STRING", | 91 "UTF8_STRING", |
| 92 "WM_DELETE_WINDOW", | 92 "WM_DELETE_WINDOW", |
| 93 "WM_PROTOCOLS", | 93 "WM_PROTOCOLS", |
| 94 "_NET_ACTIVE_WINDOW", | |
| 94 "_NET_FRAME_EXTENTS", | 95 "_NET_FRAME_EXTENTS", |
| 95 "_NET_WM_CM_S0", | 96 "_NET_WM_CM_S0", |
| 96 "_NET_WM_DESKTOP", | 97 "_NET_WM_DESKTOP", |
| 97 "_NET_WM_ICON", | 98 "_NET_WM_ICON", |
| 98 "_NET_WM_NAME", | 99 "_NET_WM_NAME", |
| 99 "_NET_WM_PID", | 100 "_NET_WM_PID", |
| 100 "_NET_WM_PING", | 101 "_NET_WM_PING", |
| 101 "_NET_WM_STATE", | 102 "_NET_WM_STATE", |
| 102 "_NET_WM_STATE_ABOVE", | 103 "_NET_WM_STATE_ABOVE", |
| 103 "_NET_WM_STATE_FULLSCREEN", | 104 "_NET_WM_STATE_FULLSCREEN", |
| (...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 223 gfx::Rect DesktopWindowTreeHostX11::GetX11RootWindowOuterBounds() const { | 224 gfx::Rect DesktopWindowTreeHostX11::GetX11RootWindowOuterBounds() const { |
| 224 gfx::Rect outer_bounds(bounds_in_pixels_); | 225 gfx::Rect outer_bounds(bounds_in_pixels_); |
| 225 outer_bounds.Inset(-native_window_frame_borders_in_pixels_); | 226 outer_bounds.Inset(-native_window_frame_borders_in_pixels_); |
| 226 return outer_bounds; | 227 return outer_bounds; |
| 227 } | 228 } |
| 228 | 229 |
| 229 ::Region DesktopWindowTreeHostX11::GetWindowShape() const { | 230 ::Region DesktopWindowTreeHostX11::GetWindowShape() const { |
| 230 return window_shape_.get(); | 231 return window_shape_.get(); |
| 231 } | 232 } |
| 232 | 233 |
| 233 void DesktopWindowTreeHostX11::HandleNativeWidgetActivationChanged( | 234 void DesktopWindowTreeHostX11::BeforeActivationStateChanged() { |
| 234 bool active) { | 235 was_active_ = IsActive(); |
| 235 if (active) { | 236 had_pointer_grab_ = has_pointer_grab_; |
| 237 had_window_focus_ = has_window_focus_; | |
| 238 } | |
| 239 | |
| 240 void DesktopWindowTreeHostX11::AfterActivationStateChanged() { | |
| 241 if (had_pointer_grab_ && !has_pointer_grab_) | |
| 242 dispatcher()->OnHostLostMouseGrab(); | |
| 243 if (had_window_focus_ && !has_window_focus_) | |
| 244 OnHostLostWindowCapture(); | |
| 245 | |
| 246 if (!was_active_ && IsActive()) { | |
| 236 FlashFrame(false); | 247 FlashFrame(false); |
| 237 OnHostActivated(); | 248 OnHostActivated(); |
| 249 // TODO(thomasanderson): Remove this window shuffling and use XWindowCache | |
| 250 // instead. | |
| 238 open_windows().remove(xwindow_); | 251 open_windows().remove(xwindow_); |
| 239 open_windows().insert(open_windows().begin(), xwindow_); | 252 open_windows().insert(open_windows().begin(), xwindow_); |
| 240 } else { | |
| 241 ReleaseCapture(); | |
| 242 } | 253 } |
| 243 | 254 if (was_active_ != IsActive()) { |
| 244 desktop_native_widget_aura_->HandleActivationChanged(active); | 255 desktop_native_widget_aura_->HandleActivationChanged(IsActive()); |
| 245 | 256 native_widget_delegate_->AsWidget()->GetRootView()->SchedulePaint(); |
|
danakj
2016/08/11 21:48:20
This really only needs to be done when becoming ac
Tom (Use chromium acct)
2016/08/15 18:42:46
Not only when it becomes active, when the activati
| |
| 246 native_widget_delegate_->AsWidget()->GetRootView()->SchedulePaint(); | 257 } |
| 247 } | 258 } |
| 248 | 259 |
| 249 void DesktopWindowTreeHostX11::AddObserver( | 260 void DesktopWindowTreeHostX11::AddObserver( |
| 250 views::DesktopWindowTreeHostObserverX11* observer) { | 261 views::DesktopWindowTreeHostObserverX11* observer) { |
| 251 observer_list_.AddObserver(observer); | 262 observer_list_.AddObserver(observer); |
| 252 } | 263 } |
| 253 | 264 |
| 254 void DesktopWindowTreeHostX11::RemoveObserver( | 265 void DesktopWindowTreeHostX11::RemoveObserver( |
| 255 views::DesktopWindowTreeHostObserverX11* observer) { | 266 views::DesktopWindowTreeHostObserverX11* observer) { |
| 256 observer_list_.RemoveObserver(observer); | 267 observer_list_.RemoveObserver(observer); |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 301 sanitized_params.bounds.set_height(100); | 312 sanitized_params.bounds.set_height(100); |
| 302 | 313 |
| 303 InitX11Window(sanitized_params); | 314 InitX11Window(sanitized_params); |
| 304 } | 315 } |
| 305 | 316 |
| 306 void DesktopWindowTreeHostX11::OnNativeWidgetCreated( | 317 void DesktopWindowTreeHostX11::OnNativeWidgetCreated( |
| 307 const Widget::InitParams& params) { | 318 const Widget::InitParams& params) { |
| 308 window()->SetProperty(kViewsWindowForRootWindow, content_window_); | 319 window()->SetProperty(kViewsWindowForRootWindow, content_window_); |
| 309 window()->SetProperty(kHostForRootWindow, this); | 320 window()->SetProperty(kHostForRootWindow, this); |
| 310 | 321 |
| 311 // Ensure that the X11DesktopHandler exists so that it dispatches activation | 322 // Ensure that the X11DesktopHandler exists so that it tracks create/destroy |
| 312 // messages to us. | 323 // notify events. |
| 313 X11DesktopHandler::get(); | 324 X11DesktopHandler::get(); |
| 314 | 325 |
| 315 // TODO(erg): Unify this code once the other consumer goes away. | 326 // TODO(erg): Unify this code once the other consumer goes away. |
| 316 SwapNonClientEventHandler( | 327 SwapNonClientEventHandler( |
| 317 std::unique_ptr<ui::EventHandler>(new X11WindowEventFilter(this))); | 328 std::unique_ptr<ui::EventHandler>(new X11WindowEventFilter(this))); |
| 318 SetUseNativeFrame(params.type == Widget::InitParams::TYPE_WINDOW && | 329 SetUseNativeFrame(params.type == Widget::InitParams::TYPE_WINDOW && |
| 319 !params.remove_standard_frame); | 330 !params.remove_standard_frame); |
| 320 | 331 |
| 321 x11_window_move_client_.reset(new X11DesktopWindowMoveClient); | 332 x11_window_move_client_.reset(new X11DesktopWindowMoveClient); |
| 322 aura::client::SetWindowMoveClient(window(), x11_window_move_client_.get()); | 333 aura::client::SetWindowMoveClient(window(), x11_window_move_client_.get()); |
| (...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 419 case ui::SHOW_STATE_FULLSCREEN: | 430 case ui::SHOW_STATE_FULLSCREEN: |
| 420 SetFullscreen(true); | 431 SetFullscreen(true); |
| 421 break; | 432 break; |
| 422 default: | 433 default: |
| 423 break; | 434 break; |
| 424 } | 435 } |
| 425 | 436 |
| 426 // Makes the window activated by default if the state is not INACTIVE or | 437 // Makes the window activated by default if the state is not INACTIVE or |
| 427 // MINIMIZED. | 438 // MINIMIZED. |
| 428 if (show_state != ui::SHOW_STATE_INACTIVE && | 439 if (show_state != ui::SHOW_STATE_INACTIVE && |
| 429 show_state != ui::SHOW_STATE_MINIMIZED && | 440 show_state != ui::SHOW_STATE_MINIMIZED) { |
| 430 activatable_) { | |
| 431 Activate(); | 441 Activate(); |
| 432 } | 442 } |
| 433 | 443 |
| 434 native_widget_delegate_->AsWidget()->SetInitialFocus(show_state); | 444 native_widget_delegate_->AsWidget()->SetInitialFocus(show_state); |
| 435 } | 445 } |
| 436 | 446 |
| 437 void DesktopWindowTreeHostX11::ShowMaximizedWithBounds( | 447 void DesktopWindowTreeHostX11::ShowMaximizedWithBounds( |
| 438 const gfx::Rect& restored_bounds) { | 448 const gfx::Rect& restored_bounds) { |
| 439 ShowWindowWithState(ui::SHOW_STATE_MAXIMIZED); | 449 ShowWindowWithState(ui::SHOW_STATE_MAXIMIZED); |
| 440 // Enforce |restored_bounds_in_pixels_| since calling Maximize() could have | 450 // Enforce |restored_bounds_in_pixels_| since calling Maximize() could have |
| (...skipping 166 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 607 } else { | 617 } else { |
| 608 window_shape_.reset(gfx::CreateRegionFromSkRegion(*native_region)); | 618 window_shape_.reset(gfx::CreateRegionFromSkRegion(*native_region)); |
| 609 } | 619 } |
| 610 | 620 |
| 611 custom_window_shape_ = true; | 621 custom_window_shape_ = true; |
| 612 } | 622 } |
| 613 ResetWindowRegion(); | 623 ResetWindowRegion(); |
| 614 } | 624 } |
| 615 | 625 |
| 616 void DesktopWindowTreeHostX11::Activate() { | 626 void DesktopWindowTreeHostX11::Activate() { |
| 617 if (!window_mapped_) | 627 if (!window_mapped_ || !activatable_) |
| 618 return; | 628 return; |
| 619 | 629 |
| 620 X11DesktopHandler::get()->ActivateWindow(xwindow_); | 630 BeforeActivationStateChanged(); |
| 631 | |
| 632 ignore_input_ = false; | |
| 633 | |
| 634 // wmii says that it supports _NET_ACTIVE_WINDOW but does not. | |
| 635 // https://code.google.com/p/wmii/issues/detail?id=266 | |
| 636 static bool wm_supports_active_window = | |
| 637 ui::GuessWindowManager() != ui::WM_WMII && | |
| 638 ui::WmSupportsHint(atom_cache_.GetAtom("_NET_ACTIVE_WINDOW")); | |
| 639 | |
| 640 if (wm_supports_active_window) { | |
| 641 XEvent xclient; | |
| 642 memset(&xclient, 0, sizeof(xclient)); | |
| 643 xclient.type = ClientMessage; | |
| 644 xclient.xclient.window = xwindow_; | |
| 645 xclient.xclient.message_type = atom_cache_.GetAtom("_NET_ACTIVE_WINDOW"); | |
| 646 xclient.xclient.format = 32; | |
| 647 xclient.xclient.data.l[0] = 1; // Specified we are an app. | |
| 648 xclient.xclient.data.l[1] = GetTimestamp(); | |
| 649 xclient.xclient.data.l[2] = None; | |
|
danakj
2016/08/11 21:48:20
This is actually a lie if another chrome window is
Tom (Use chromium acct)
2016/08/15 18:42:46
Done.
| |
| 650 xclient.xclient.data.l[3] = 0; | |
| 651 xclient.xclient.data.l[4] = 0; | |
| 652 | |
| 653 XSendEvent(xdisplay_, x_root_window_, False, | |
| 654 SubstructureRedirectMask | SubstructureNotifyMask, &xclient); | |
| 655 } else { | |
| 656 XRaiseWindow(xdisplay_, xwindow_); | |
| 657 // Directly ask the X server to give focus to the window. Note | |
| 658 // that the call will raise an X error if the window is not | |
| 659 // mapped. | |
| 660 XSetInputFocus(xdisplay_, xwindow_, RevertToParent, CurrentTime); | |
|
danakj
2016/08/11 21:48:20
Can you explain/document why CurrentTime and not G
Tom (Use chromium acct)
2016/08/15 18:42:46
Copy/paste bug. Fixed.
| |
| 661 // At this point, we know we will receive focus, and some tests depend on a | |
| 662 // window being IsActive() immediately after an Activate(), so just set this | |
| 663 // state now. | |
| 664 has_pointer_focus_ = false; | |
| 665 has_window_focus_ = true; | |
| 666 } | |
| 667 AfterActivationStateChanged(); | |
| 621 } | 668 } |
| 622 | 669 |
| 623 void DesktopWindowTreeHostX11::Deactivate() { | 670 void DesktopWindowTreeHostX11::Deactivate() { |
| 624 if (!IsActive()) | 671 BeforeActivationStateChanged(); |
| 625 return; | 672 |
| 673 // Ignore future input events. | |
| 674 ignore_input_ = true; | |
| 626 | 675 |
| 627 ReleaseCapture(); | 676 ReleaseCapture(); |
| 628 X11DesktopHandler::get()->DeactivateWindow(xwindow_); | 677 XLowerWindow(xdisplay_, xwindow_); |
| 678 | |
| 679 AfterActivationStateChanged(); | |
| 629 } | 680 } |
| 630 | 681 |
| 631 bool DesktopWindowTreeHostX11::IsActive() const { | 682 bool DesktopWindowTreeHostX11::IsActive() const { |
| 632 return X11DesktopHandler::get()->IsActiveWindow(xwindow_); | 683 // Focus and stacking order are independent in X11. Since we cannot guarantee |
| 684 // a window is topmost iff it has focus, just use the focus state to determine | |
| 685 // if a window is active. Note that Activate() and Deactivate() change the | |
| 686 // stacking order in addition to changing the focus state. | |
| 687 return window_mapped_ && | |
|
danakj
2016/08/11 21:48:20
the has focus things can't be true while window_ma
Tom (Use chromium acct)
2016/08/15 18:42:46
Done.
| |
| 688 (has_window_focus_ || has_pointer_grab_ || has_pointer_focus_) && | |
| 689 !ignore_input_; | |
| 633 } | 690 } |
| 634 | 691 |
| 635 void DesktopWindowTreeHostX11::Maximize() { | 692 void DesktopWindowTreeHostX11::Maximize() { |
| 636 if (HasWMSpecProperty("_NET_WM_STATE_FULLSCREEN")) { | 693 if (HasWMSpecProperty("_NET_WM_STATE_FULLSCREEN")) { |
| 637 // Unfullscreen the window if it is fullscreen. | 694 // Unfullscreen the window if it is fullscreen. |
| 638 SetWMSpecState(false, | 695 SetWMSpecState(false, |
| 639 atom_cache_.GetAtom("_NET_WM_STATE_FULLSCREEN"), | 696 atom_cache_.GetAtom("_NET_WM_STATE_FULLSCREEN"), |
| 640 None); | 697 None); |
| 641 | 698 |
| 642 // Resize the window so that it does not have the same size as a monitor. | 699 // Resize the window so that it does not have the same size as a monitor. |
| (...skipping 830 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1473 unsigned long wm_user_time_ms = static_cast<unsigned long>( | 1530 unsigned long wm_user_time_ms = static_cast<unsigned long>( |
| 1474 (ui::EventTimeFromNative(event) - base::TimeTicks()).InMilliseconds()); | 1531 (ui::EventTimeFromNative(event) - base::TimeTicks()).InMilliseconds()); |
| 1475 XChangeProperty(xdisplay_, | 1532 XChangeProperty(xdisplay_, |
| 1476 xwindow_, | 1533 xwindow_, |
| 1477 atom_cache_.GetAtom("_NET_WM_USER_TIME"), | 1534 atom_cache_.GetAtom("_NET_WM_USER_TIME"), |
| 1478 XA_CARDINAL, | 1535 XA_CARDINAL, |
| 1479 32, | 1536 32, |
| 1480 PropModeReplace, | 1537 PropModeReplace, |
| 1481 reinterpret_cast<const unsigned char *>(&wm_user_time_ms), | 1538 reinterpret_cast<const unsigned char *>(&wm_user_time_ms), |
| 1482 1); | 1539 1); |
| 1483 X11DesktopHandler::get()->set_wm_user_time_ms(wm_user_time_ms); | |
| 1484 } | 1540 } |
| 1485 } | 1541 } |
| 1486 | 1542 |
| 1543 Time DesktopWindowTreeHostX11::GetTimestamp() { | |
| 1544 ui::X11EventSource* event_source = ui::X11EventSource::GetInstance(); | |
| 1545 Time time = event_source->last_seen_server_time(); | |
| 1546 if (time == CurrentTime) { | |
|
danakj
2016/08/11 21:48:20
This feels like an approximation for what we want.
Tom (Use chromium acct)
2016/08/15 18:42:45
We don't currently do that :(
But I think this is
| |
| 1547 time = event_source->UpdateLastSeenServerTime(); | |
| 1548 } | |
| 1549 return time; | |
| 1550 } | |
| 1551 | |
| 1487 void DesktopWindowTreeHostX11::SetWMSpecState(bool enabled, | 1552 void DesktopWindowTreeHostX11::SetWMSpecState(bool enabled, |
| 1488 ::Atom state1, | 1553 ::Atom state1, |
| 1489 ::Atom state2) { | 1554 ::Atom state2) { |
| 1490 XEvent xclient; | 1555 XEvent xclient; |
| 1491 memset(&xclient, 0, sizeof(xclient)); | 1556 memset(&xclient, 0, sizeof(xclient)); |
| 1492 xclient.type = ClientMessage; | 1557 xclient.type = ClientMessage; |
| 1493 xclient.xclient.window = xwindow_; | 1558 xclient.xclient.window = xwindow_; |
| 1494 xclient.xclient.message_type = atom_cache_.GetAtom("_NET_WM_STATE"); | 1559 xclient.xclient.message_type = atom_cache_.GetAtom("_NET_WM_STATE"); |
| 1495 xclient.xclient.format = 32; | 1560 xclient.xclient.format = 32; |
| 1496 xclient.xclient.data.l[0] = | 1561 xclient.xclient.data.l[0] = |
| (...skipping 177 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1674 // will ignore toplevel XMoveWindow commands. | 1739 // will ignore toplevel XMoveWindow commands. |
| 1675 XSizeHints size_hints; | 1740 XSizeHints size_hints; |
| 1676 size_hints.flags = PPosition; | 1741 size_hints.flags = PPosition; |
| 1677 size_hints.x = bounds_in_pixels_.x(); | 1742 size_hints.x = bounds_in_pixels_.x(); |
| 1678 size_hints.y = bounds_in_pixels_.y(); | 1743 size_hints.y = bounds_in_pixels_.y(); |
| 1679 XSetWMNormalHints(xdisplay_, xwindow_, &size_hints); | 1744 XSetWMNormalHints(xdisplay_, xwindow_, &size_hints); |
| 1680 | 1745 |
| 1681 // If SHOW_STATE_INACTIVE, tell the window manager not to focus the window | 1746 // If SHOW_STATE_INACTIVE, tell the window manager not to focus the window |
| 1682 // when mapping. This is done by setting the _NET_WM_USER_TIME to 0. See e.g. | 1747 // when mapping. This is done by setting the _NET_WM_USER_TIME to 0. See e.g. |
| 1683 // http://standards.freedesktop.org/wm-spec/latest/ar01s05.html | 1748 // http://standards.freedesktop.org/wm-spec/latest/ar01s05.html |
| 1684 unsigned long wm_user_time_ms = (show_state == ui::SHOW_STATE_INACTIVE) ? | 1749 has_pointer_ = false; |
|
danakj
2016/08/11 21:48:20
I'd expect these to all be initialized to false, a
Tom (Use chromium acct)
2016/08/15 18:42:45
shouldn't happen, done
| |
| 1685 0 : X11DesktopHandler::get()->wm_user_time_ms(); | 1750 has_pointer_grab_ = false; |
| 1751 has_pointer_focus_ = false; | |
| 1752 has_window_focus_ = false; | |
| 1753 ignore_input_ = show_state == ui::SHOW_STATE_INACTIVE; | |
| 1754 unsigned long wm_user_time_ms = ignore_input_ ? 0 : GetTimestamp(); | |
|
danakj
2016/08/11 21:48:20
So here we want to use the "window launch time" in
Tom (Use chromium acct)
2016/08/15 18:42:46
We need the window launch time for _NET_ACTIVE_WIN
| |
| 1686 if (show_state == ui::SHOW_STATE_INACTIVE || wm_user_time_ms != 0) { | 1755 if (show_state == ui::SHOW_STATE_INACTIVE || wm_user_time_ms != 0) { |
| 1687 XChangeProperty(xdisplay_, | 1756 XChangeProperty( |
| 1688 xwindow_, | 1757 xdisplay_, xwindow_, atom_cache_.GetAtom("_NET_WM_USER_TIME"), |
| 1689 atom_cache_.GetAtom("_NET_WM_USER_TIME"), | 1758 XA_CARDINAL, 32, PropModeReplace, |
| 1690 XA_CARDINAL, | 1759 reinterpret_cast<const unsigned char*>(&wm_user_time_ms), 1); |
| 1691 32, | |
| 1692 PropModeReplace, | |
| 1693 reinterpret_cast<const unsigned char *>(&wm_user_time_ms), | |
| 1694 1); | |
| 1695 } | 1760 } |
| 1696 | 1761 |
| 1697 ui::X11EventSource* event_source = ui::X11EventSource::GetInstance(); | 1762 ui::X11EventSource* event_source = ui::X11EventSource::GetInstance(); |
| 1698 DCHECK(event_source); | 1763 DCHECK(event_source); |
| 1699 | 1764 |
| 1700 if (wait_for_unmap_) { | 1765 if (wait_for_unmap_) { |
| 1701 // Block until our window is unmapped. This avoids a race condition when | 1766 // Block until our window is unmapped. This avoids a race condition when |
| 1702 // remapping an unmapped window. | 1767 // remapping an unmapped window. |
| 1703 event_source->BlockUntilWindowUnmapped(xwindow_); | 1768 event_source->BlockUntilWindowUnmapped(xwindow_); |
| 1704 DCHECK(!wait_for_unmap_); | 1769 DCHECK(!wait_for_unmap_); |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1748 | 1813 |
| 1749 UpdateWMUserTime(event); | 1814 UpdateWMUserTime(event); |
| 1750 | 1815 |
| 1751 // May want to factor CheckXEventForConsistency(xev); into a common location | 1816 // May want to factor CheckXEventForConsistency(xev); into a common location |
| 1752 // since it is called here. | 1817 // since it is called here. |
| 1753 switch (xev->type) { | 1818 switch (xev->type) { |
| 1754 case EnterNotify: | 1819 case EnterNotify: |
| 1755 case LeaveNotify: { | 1820 case LeaveNotify: { |
| 1756 // Ignore EventNotify and LeaveNotify events from children of |xwindow_|. | 1821 // Ignore EventNotify and LeaveNotify events from children of |xwindow_|. |
| 1757 // NativeViewGLSurfaceGLX adds a child to |xwindow_|. | 1822 // NativeViewGLSurfaceGLX adds a child to |xwindow_|. |
| 1758 // TODO(pkotwicz|tdanderson): Figure out whether the suppression is | |
| 1759 // necessary. crbug.com/385716 | |
| 1760 if (xev->xcrossing.detail == NotifyInferior) | 1823 if (xev->xcrossing.detail == NotifyInferior) |
| 1761 break; | 1824 break; |
| 1762 | 1825 |
| 1826 BeforeActivationStateChanged(); | |
| 1827 | |
| 1828 if (xev->xcrossing.mode == NotifyGrab) | |
| 1829 has_pointer_grab_ = xev->type == EnterNotify; | |
| 1830 else if (xev->xcrossing.mode == NotifyUngrab) | |
| 1831 has_pointer_grab_ = false; | |
| 1832 | |
| 1833 has_pointer_ = xev->type == EnterNotify; | |
| 1834 if(!xev->xcrossing.focus && has_window_focus_) { | |
|
danakj
2016/08/11 21:48:20
git cl format
Tom (Use chromium acct)
2016/08/15 18:42:45
Done.
| |
| 1835 has_pointer_focus_ = has_pointer_; | |
|
danakj
2016/08/11 21:48:20
In the header we claimed that has_window_focus_ an
Tom (Use chromium acct)
2016/08/15 18:42:46
Thanks for catching this terrible logic :)
The ! s
| |
| 1836 ignore_input_ = false; | |
|
danakj
2016/08/11 21:48:20
I'm hesitant about the whole ignore_input_ thing.
Tom (Use chromium acct)
2016/08/15 18:42:46
I don't know when we call Deactivate() in producti
| |
| 1837 } | |
| 1838 AfterActivationStateChanged(); | |
| 1839 | |
| 1763 ui::MouseEvent mouse_event(xev); | 1840 ui::MouseEvent mouse_event(xev); |
| 1764 DispatchMouseEvent(&mouse_event); | 1841 DispatchMouseEvent(&mouse_event); |
| 1765 break; | 1842 break; |
| 1766 } | 1843 } |
| 1767 case Expose: { | 1844 case Expose: { |
| 1768 gfx::Rect damage_rect_in_pixels(xev->xexpose.x, xev->xexpose.y, | 1845 gfx::Rect damage_rect_in_pixels(xev->xexpose.x, xev->xexpose.y, |
| 1769 xev->xexpose.width, xev->xexpose.height); | 1846 xev->xexpose.width, xev->xexpose.height); |
| 1770 compositor()->ScheduleRedrawRect(damage_rect_in_pixels); | 1847 compositor()->ScheduleRedrawRect(damage_rect_in_pixels); |
| 1771 break; | 1848 break; |
| 1772 } | 1849 } |
| 1773 case KeyPress: { | 1850 case KeyPress: { |
| 1774 ui::KeyEvent keydown_event(xev); | 1851 ui::KeyEvent keydown_event(xev); |
| 1775 DispatchKeyEvent(&keydown_event); | 1852 DispatchKeyEvent(&keydown_event); |
| 1776 break; | 1853 break; |
| 1777 } | 1854 } |
| 1778 case KeyRelease: { | 1855 case KeyRelease: { |
| 1779 // There is no way to deactivate a window in X11 so ignore input if | 1856 // There is no way to deactivate a window in X11 so ignore input if |
| 1780 // window is supposed to be 'inactive'. See comments in | 1857 // window is supposed to be 'inactive'. |
| 1781 // X11DesktopHandler::DeactivateWindow() for more details. | |
| 1782 if (!IsActive() && !HasCapture()) | 1858 if (!IsActive() && !HasCapture()) |
| 1783 break; | 1859 break; |
| 1784 | 1860 |
| 1785 ui::KeyEvent key_event(xev); | 1861 ui::KeyEvent key_event(xev); |
| 1786 DispatchKeyEvent(&key_event); | 1862 DispatchKeyEvent(&key_event); |
| 1787 break; | 1863 break; |
| 1788 } | 1864 } |
| 1789 case ButtonPress: | 1865 case ButtonPress: |
| 1790 case ButtonRelease: { | 1866 case ButtonRelease: { |
| 1791 ui::EventType event_type = ui::EventTypeFromNative(xev); | 1867 ui::EventType event_type = ui::EventTypeFromNative(xev); |
| (...skipping 10 matching lines...) Expand all Loading... | |
| 1802 break; | 1878 break; |
| 1803 } | 1879 } |
| 1804 case ui::ET_UNKNOWN: | 1880 case ui::ET_UNKNOWN: |
| 1805 // No event is created for X11-release events for mouse-wheel buttons. | 1881 // No event is created for X11-release events for mouse-wheel buttons. |
| 1806 break; | 1882 break; |
| 1807 default: | 1883 default: |
| 1808 NOTREACHED() << event_type; | 1884 NOTREACHED() << event_type; |
| 1809 } | 1885 } |
| 1810 break; | 1886 break; |
| 1811 } | 1887 } |
| 1812 case FocusOut: | 1888 case FocusIn: |
| 1813 if (xev->xfocus.mode != NotifyGrab) { | 1889 case FocusOut: { |
| 1814 ReleaseCapture(); | 1890 BeforeActivationStateChanged(); |
| 1815 OnHostLostWindowCapture(); | 1891 bool focus_in = xev->type == FocusIn; |
| 1816 X11DesktopHandler::get()->ProcessXEvent(xev); | 1892 auto mode = event->xfocus.mode; |
| 1817 } else { | 1893 bool grab_notify = mode == NotifyGrab || mode == XINotifyPassiveGrab || |
| 1818 dispatcher()->OnHostLostMouseGrab(); | 1894 mode == NotifyUngrab || mode == XINotifyPassiveUngrab; |
| 1895 switch (xev->xfocus.detail) { | |
| 1896 case NotifyAncestor: | |
| 1897 case NotifyVirtual: | |
| 1898 if (has_pointer_ && !grab_notify) | |
| 1899 has_pointer_focus_ = !focus_in; | |
|
danakj
2016/08/11 21:48:20
I think you only want to do this for FocusOut. Oth
Tom (Use chromium acct)
2016/08/15 18:42:46
Doesn't it say to do this for FocusIn as well?
| |
| 1900 // fallthrough | |
| 1901 case NotifyNonlinear: | |
| 1902 case NotifyNonlinearVirtual: | |
| 1903 if (!grab_notify) | |
| 1904 has_window_focus_ = focus_in; | |
|
danakj
2016/08/11 21:48:20
The focus_tracking.txt doc says has_window_focus s
Tom (Use chromium acct)
2016/08/15 18:42:46
Probably a mistake in the doc. NotifyPointer shou
| |
| 1905 break; | |
| 1906 case NotifyPointer: | |
| 1907 if (!grab_notify) | |
| 1908 has_pointer_focus_ = focus_in; | |
| 1909 default: | |
| 1910 break; | |
| 1819 } | 1911 } |
| 1912 ignore_input_ = false; | |
| 1913 AfterActivationStateChanged(); | |
| 1820 break; | 1914 break; |
| 1821 case FocusIn: | 1915 } |
| 1822 X11DesktopHandler::get()->ProcessXEvent(xev); | |
| 1823 break; | |
| 1824 case ConfigureNotify: { | 1916 case ConfigureNotify: { |
| 1825 DCHECK_EQ(xwindow_, xev->xconfigure.window); | 1917 DCHECK_EQ(xwindow_, xev->xconfigure.window); |
| 1826 DCHECK_EQ(xwindow_, xev->xconfigure.event); | 1918 DCHECK_EQ(xwindow_, xev->xconfigure.event); |
| 1827 // It's possible that the X window may be resized by some other means than | 1919 // It's possible that the X window may be resized by some other means than |
| 1828 // from within aura (e.g. the X window manager can change the size). Make | 1920 // from within aura (e.g. the X window manager can change the size). Make |
| 1829 // sure the root window size is maintained properly. | 1921 // sure the root window size is maintained properly. |
| 1830 int translated_x_in_pixels = xev->xconfigure.x; | 1922 int translated_x_in_pixels = xev->xconfigure.x; |
| 1831 int translated_y_in_pixels = xev->xconfigure.y; | 1923 int translated_y_in_pixels = xev->xconfigure.y; |
| 1832 if (!xev->xconfigure.send_event && !xev->xconfigure.override_redirect) { | 1924 if (!xev->xconfigure.send_event && !xev->xconfigure.override_redirect) { |
| 1833 Window unused; | 1925 Window unused; |
| (...skipping 260 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2094 if (linux_ui) { | 2186 if (linux_ui) { |
| 2095 ui::NativeTheme* native_theme = linux_ui->GetNativeTheme(window); | 2187 ui::NativeTheme* native_theme = linux_ui->GetNativeTheme(window); |
| 2096 if (native_theme) | 2188 if (native_theme) |
| 2097 return native_theme; | 2189 return native_theme; |
| 2098 } | 2190 } |
| 2099 | 2191 |
| 2100 return ui::NativeThemeAura::instance(); | 2192 return ui::NativeThemeAura::instance(); |
| 2101 } | 2193 } |
| 2102 | 2194 |
| 2103 } // namespace views | 2195 } // namespace views |
| OLD | NEW |