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 |