Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(159)

Side by Side Diff: ui/views/widget/desktop_aura/desktop_window_tree_host_x11.cc

Issue 380943003: Do not release capture when transferring capture between Chrome windows on Linux (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 6 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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>
11 #include <X11/Xutil.h> 11 #include <X11/Xutil.h>
12 12
13 #include "base/basictypes.h" 13 #include "base/basictypes.h"
14 #include "base/command_line.h" 14 #include "base/command_line.h"
15 #include "base/debug/trace_event.h" 15 #include "base/debug/trace_event.h"
16 #include "base/strings/stringprintf.h" 16 #include "base/strings/stringprintf.h"
17 #include "base/strings/utf_string_conversions.h" 17 #include "base/strings/utf_string_conversions.h"
18 #include "third_party/skia/include/core/SkPath.h" 18 #include "third_party/skia/include/core/SkPath.h"
19 #include "ui/aura/client/cursor_client.h" 19 #include "ui/aura/client/cursor_client.h"
20 #include "ui/aura/client/focus_client.h" 20 #include "ui/aura/client/focus_client.h"
21 #include "ui/aura/client/screen_position_client.h"
21 #include "ui/aura/window.h" 22 #include "ui/aura/window.h"
22 #include "ui/aura/window_event_dispatcher.h" 23 #include "ui/aura/window_event_dispatcher.h"
23 #include "ui/aura/window_property.h" 24 #include "ui/aura/window_property.h"
24 #include "ui/base/dragdrop/os_exchange_data_provider_aurax11.h" 25 #include "ui/base/dragdrop/os_exchange_data_provider_aurax11.h"
25 #include "ui/base/hit_test.h" 26 #include "ui/base/hit_test.h"
26 #include "ui/base/x/x11_util.h" 27 #include "ui/base/x/x11_util.h"
27 #include "ui/events/event_utils.h" 28 #include "ui/events/event_utils.h"
28 #include "ui/events/platform/platform_event_source.h" 29 #include "ui/events/platform/platform_event_source.h"
29 #include "ui/events/platform/x11/x11_event_source.h" 30 #include "ui/events/platform/x11/x11_event_source.h"
30 #include "ui/events/x/device_data_manager_x11.h" 31 #include "ui/events/x/device_data_manager_x11.h"
31 #include "ui/events/x/device_list_cache_x.h" 32 #include "ui/events/x/device_list_cache_x.h"
32 #include "ui/events/x/touch_factory_x11.h" 33 #include "ui/events/x/touch_factory_x11.h"
33 #include "ui/gfx/image/image_skia.h" 34 #include "ui/gfx/image/image_skia.h"
34 #include "ui/gfx/image/image_skia_rep.h" 35 #include "ui/gfx/image/image_skia_rep.h"
35 #include "ui/gfx/insets.h" 36 #include "ui/gfx/insets.h"
36 #include "ui/gfx/path.h" 37 #include "ui/gfx/path.h"
37 #include "ui/gfx/path_x11.h" 38 #include "ui/gfx/path_x11.h"
38 #include "ui/gfx/screen.h" 39 #include "ui/gfx/screen.h"
39 #include "ui/native_theme/native_theme.h" 40 #include "ui/native_theme/native_theme.h"
40 #include "ui/views/corewm/tooltip_aura.h" 41 #include "ui/views/corewm/tooltip_aura.h"
41 #include "ui/views/ime/input_method.h" 42 #include "ui/views/ime/input_method.h"
42 #include "ui/views/linux_ui/linux_ui.h" 43 #include "ui/views/linux_ui/linux_ui.h"
43 #include "ui/views/views_delegate.h" 44 #include "ui/views/views_delegate.h"
44 #include "ui/views/views_switches.h" 45 #include "ui/views/views_switches.h"
45 #include "ui/views/widget/desktop_aura/desktop_drag_drop_client_aurax11.h" 46 #include "ui/views/widget/desktop_aura/desktop_drag_drop_client_aurax11.h"
46 #include "ui/views/widget/desktop_aura/desktop_native_cursor_manager.h" 47 #include "ui/views/widget/desktop_aura/desktop_native_cursor_manager.h"
47 #include "ui/views/widget/desktop_aura/desktop_native_widget_aura.h" 48 #include "ui/views/widget/desktop_aura/desktop_native_widget_aura.h"
48 #include "ui/views/widget/desktop_aura/desktop_window_tree_host_observer_x11.h" 49 #include "ui/views/widget/desktop_aura/desktop_window_tree_host_observer_x11.h"
50 #include "ui/views/widget/desktop_aura/x11_capture_window.h"
49 #include "ui/views/widget/desktop_aura/x11_desktop_handler.h" 51 #include "ui/views/widget/desktop_aura/x11_desktop_handler.h"
50 #include "ui/views/widget/desktop_aura/x11_desktop_window_move_client.h" 52 #include "ui/views/widget/desktop_aura/x11_desktop_window_move_client.h"
51 #include "ui/views/widget/desktop_aura/x11_scoped_capture.h"
52 #include "ui/views/widget/desktop_aura/x11_window_event_filter.h" 53 #include "ui/views/widget/desktop_aura/x11_window_event_filter.h"
53 #include "ui/wm/core/compound_event_filter.h" 54 #include "ui/wm/core/compound_event_filter.h"
54 #include "ui/wm/core/window_util.h" 55 #include "ui/wm/core/window_util.h"
55 56
56 namespace views { 57 namespace views {
57 58
58 DesktopWindowTreeHostX11* DesktopWindowTreeHostX11::g_current_capture = 59 DesktopWindowTreeHostX11* DesktopWindowTreeHostX11::g_current_capture =
59 NULL; 60 NULL;
60 std::list<XID>* DesktopWindowTreeHostX11::open_windows_ = NULL; 61 std::list<XID>* DesktopWindowTreeHostX11::open_windows_ = NULL;
61 62
(...skipping 832 matching lines...) Expand 10 before | Expand all | Expand 10 after
894 OnHostResized(bounds.size()); 895 OnHostResized(bounds.size());
895 ResetWindowRegion(); 896 ResetWindowRegion();
896 } 897 }
897 } 898 }
898 899
899 gfx::Point DesktopWindowTreeHostX11::GetLocationOnNativeScreen() const { 900 gfx::Point DesktopWindowTreeHostX11::GetLocationOnNativeScreen() const {
900 return bounds_.origin(); 901 return bounds_.origin();
901 } 902 }
902 903
903 void DesktopWindowTreeHostX11::SetCapture() { 904 void DesktopWindowTreeHostX11::SetCapture() {
904 // This is vaguely based on the old NativeWidgetGtk implementation. 905 DesktopWindowTreeHostX11* old_capture = g_current_capture;
905 // 906 g_current_capture = this;
906 // X11's XPointerGrab() shouldn't be used for everything; it doesn't map 907 if (old_capture) {
907 // cleanly to Windows' SetCapture(). GTK only provides a separate concept of 908 // Take ownership of |old_capture|'s capture window which already has a
908 // a grab that wasn't the X11 pointer grab, but was instead a manual 909 // mouse grab. Because there is no X11 mouse grab or mouse ungrab, the
909 // redirection of the event. (You need to drop into GDK if you want to 910 // capture change is sychronous.
910 // perform a raw X11 grab). 911 capture_window_ = old_capture->ReleaseCaptureWindow().Pass();
911 912
912 if (g_current_capture) 913 old_capture->OnHostLostWindowCapture();
913 g_current_capture->OnCaptureReleased(); 914 }
914 915
915 g_current_capture = this; 916 if (!capture_window_) {
916 x11_capture_.reset(new X11ScopedCapture(xwindow_)); 917 // Create an X11CaptureWindow to asynchronously grab the mouse. As
918 // |xwindow_| is likely the topmost window underneath the mouse, we will
919 // likely not miss any mouse events.
920 capture_window_.reset(new X11CaptureWindow);
921 }
917 } 922 }
918 923
919 void DesktopWindowTreeHostX11::ReleaseCapture() { 924 void DesktopWindowTreeHostX11::ReleaseCapture() {
920 if (g_current_capture == this) 925 if (g_current_capture == this) {
921 g_current_capture->OnCaptureReleased(); 926 // Release mouse grab asynchronously. |xwindow_| is likely the topmost
927 // window underneath the mouse so the capture release being asynchronous is
928 // likely inconsequential.
929 g_current_capture = NULL;
930 capture_window_.reset();
931
932 OnHostLostWindowCapture();
933 }
922 } 934 }
923 935
924 void DesktopWindowTreeHostX11::SetCursorNative(gfx::NativeCursor cursor) { 936 void DesktopWindowTreeHostX11::SetCursorNative(gfx::NativeCursor cursor) {
925 XDefineCursor(xdisplay_, xwindow_, cursor.platform()); 937 XDefineCursor(xdisplay_, xwindow_, cursor.platform());
926 } 938 }
927 939
928 void DesktopWindowTreeHostX11::MoveCursorToNative(const gfx::Point& location) { 940 void DesktopWindowTreeHostX11::MoveCursorToNative(const gfx::Point& location) {
929 XWarpPointer(xdisplay_, None, x_root_window_, 0, 0, 0, 0, 941 XWarpPointer(xdisplay_, None, x_root_window_, 0, 0, 0, 0,
930 bounds_.x() + location.x(), bounds_.y() + location.y()); 942 bounds_.x() + location.x(), bounds_.y() + location.y());
931 } 943 }
(...skipping 361 matching lines...) Expand 10 before | Expand all | Expand 10 after
1293 return window_properties_.find(atom_cache_.GetAtom(property)) != 1305 return window_properties_.find(atom_cache_.GetAtom(property)) !=
1294 window_properties_.end(); 1306 window_properties_.end();
1295 } 1307 }
1296 1308
1297 void DesktopWindowTreeHostX11::SetUseNativeFrame(bool use_native_frame) { 1309 void DesktopWindowTreeHostX11::SetUseNativeFrame(bool use_native_frame) {
1298 use_native_frame_ = use_native_frame; 1310 use_native_frame_ = use_native_frame;
1299 ui::SetUseOSWindowFrame(xwindow_, use_native_frame); 1311 ui::SetUseOSWindowFrame(xwindow_, use_native_frame);
1300 ResetWindowRegion(); 1312 ResetWindowRegion();
1301 } 1313 }
1302 1314
1303 void DesktopWindowTreeHostX11::OnCaptureReleased() { 1315 scoped_ptr<X11CaptureWindow> DesktopWindowTreeHostX11::ReleaseCaptureWindow() {
1304 x11_capture_.reset(); 1316 return capture_window_.Pass();
1305 g_current_capture = NULL;
1306 OnHostLostWindowCapture();
1307 } 1317 }
1308 1318
1309 void DesktopWindowTreeHostX11::DispatchMouseEvent(ui::MouseEvent* event) { 1319 void DesktopWindowTreeHostX11::DispatchMouseEvent(ui::MouseEvent* event) {
1310 // In Windows, the native events sent to chrome are separated into client 1320 // In Windows, the native events sent to chrome are separated into client
1311 // and non-client versions of events, which we record on our LocatedEvent 1321 // and non-client versions of events, which we record on our LocatedEvent
1312 // structures. On X11, we emulate the concept of non-client. Before we pass 1322 // structures. On X11, we emulate the concept of non-client. Before we pass
1313 // this event to the cross platform event handling framework, we need to 1323 // this event to the cross platform event handling framework, we need to
1314 // make sure it is appropriately marked as non-client if it's in the non 1324 // make sure it is appropriately marked as non-client if it's in the non
1315 // client area, or otherwise, we can get into a state where the a window is 1325 // client area, or otherwise, we can get into a state where the a window is
1316 // set as the |mouse_pressed_handler_| in window_event_dispatcher.cc 1326 // set as the |mouse_pressed_handler_| in window_event_dispatcher.cc
(...skipping 13 matching lines...) Expand all
1330 if (hit_test_code != HTCLIENT && hit_test_code != HTNOWHERE) 1340 if (hit_test_code != HTCLIENT && hit_test_code != HTNOWHERE)
1331 flags |= ui::EF_IS_NON_CLIENT; 1341 flags |= ui::EF_IS_NON_CLIENT;
1332 event->set_flags(flags); 1342 event->set_flags(flags);
1333 } 1343 }
1334 1344
1335 // While we unset the urgency hint when we gain focus, we also must remove it 1345 // While we unset the urgency hint when we gain focus, we also must remove it
1336 // on mouse clicks because we can call FlashFrame() on an active window. 1346 // on mouse clicks because we can call FlashFrame() on an active window.
1337 if (event->IsAnyButton() || event->IsMouseWheelEvent()) 1347 if (event->IsAnyButton() || event->IsMouseWheelEvent())
1338 FlashFrame(false); 1348 FlashFrame(false);
1339 1349
1350 if (ui::EventTargetFromNative(event->native_event()) != xwindow_) {
1351 // The event was targeted at |capture_window_|'s X window.
1352 gfx::Point location =
1353 ui::EventSystemLocationFromNative(event->native_event());
1354 aura::client::GetScreenPositionClient(window())->ConvertPointFromScreen(
1355 window(), &location);
1356 event->set_location(location);
1357 }
1358
1340 if (!g_current_capture || g_current_capture == this) { 1359 if (!g_current_capture || g_current_capture == this) {
1341 SendEventToProcessor(event); 1360 SendEventToProcessor(event);
1342 } else { 1361 } else {
1343 // Another DesktopWindowTreeHostX11 has installed itself as 1362 // Another DesktopWindowTreeHostX11 has capture. Translate the event's
1344 // capture. Translate the event's location and dispatch to the other. 1363 // location and dispatch to the other DesktopWindowTreeHostX11.
1345 event->ConvertLocationToTarget(window(), g_current_capture->window()); 1364 event->ConvertLocationToTarget(window(), g_current_capture->window());
1346 g_current_capture->SendEventToProcessor(event); 1365 g_current_capture->SendEventToProcessor(event);
1347 } 1366 }
1348 } 1367 }
1349 1368
1350 void DesktopWindowTreeHostX11::DispatchTouchEvent(ui::TouchEvent* event) { 1369 void DesktopWindowTreeHostX11::DispatchTouchEvent(ui::TouchEvent* event) {
1370 DCHECK_EQ(ui::EventTargetFromNative(event->native_event()), xwindow_);
1351 if (g_current_capture && g_current_capture != this && 1371 if (g_current_capture && g_current_capture != this &&
1352 event->type() == ui::ET_TOUCH_PRESSED) { 1372 event->type() == ui::ET_TOUCH_PRESSED) {
1353 event->ConvertLocationToTarget(window(), g_current_capture->window()); 1373 event->ConvertLocationToTarget(window(), g_current_capture->window());
1354 g_current_capture->SendEventToProcessor(event); 1374 g_current_capture->SendEventToProcessor(event);
1355 } else { 1375 } else {
1356 SendEventToProcessor(event); 1376 SendEventToProcessor(event);
1357 } 1377 }
1358 } 1378 }
1359 1379
1360 void DesktopWindowTreeHostX11::ResetWindowRegion() { 1380 void DesktopWindowTreeHostX11::ResetWindowRegion() {
(...skipping 158 matching lines...) Expand 10 before | Expand all | Expand 10 after
1519 non_client_view->InvalidateLayout(); 1539 non_client_view->InvalidateLayout();
1520 } 1540 }
1521 widget->GetRootView()->Layout(); 1541 widget->GetRootView()->Layout();
1522 } 1542 }
1523 1543
1524 //////////////////////////////////////////////////////////////////////////////// 1544 ////////////////////////////////////////////////////////////////////////////////
1525 // DesktopWindowTreeHostX11, ui::PlatformEventDispatcher implementation: 1545 // DesktopWindowTreeHostX11, ui::PlatformEventDispatcher implementation:
1526 1546
1527 bool DesktopWindowTreeHostX11::CanDispatchEvent( 1547 bool DesktopWindowTreeHostX11::CanDispatchEvent(
1528 const ui::PlatformEvent& event) { 1548 const ui::PlatformEvent& event) {
1529 return event->xany.window == xwindow_ || 1549 XID target = ui::EventTargetFromNative(event);
1530 (event->type == GenericEvent && 1550 return target == xwindow_ ||
1531 static_cast<XIDeviceEvent*>(event->xcookie.data)->event == xwindow_); 1551 (capture_window_ && target == capture_window_->xwindow());
1532 } 1552 }
1533 1553
1534 uint32_t DesktopWindowTreeHostX11::DispatchEvent( 1554 uint32_t DesktopWindowTreeHostX11::DispatchEvent(
1535 const ui::PlatformEvent& event) { 1555 const ui::PlatformEvent& event) {
1536 XEvent* xev = event; 1556 XEvent* xev = event;
1537 1557
1538 TRACE_EVENT1("views", "DesktopWindowTreeHostX11::Dispatch", 1558 TRACE_EVENT1("views", "DesktopWindowTreeHostX11::Dispatch",
1539 "event->type", event->type); 1559 "event->type", event->type);
1540 1560
1541 UpdateWMUserTime(event); 1561 UpdateWMUserTime(event);
1542 1562
1543 // May want to factor CheckXEventForConsistency(xev); into a common location 1563 // May want to factor CheckXEventForConsistency(xev); into a common location
1544 // since it is called here. 1564 // since it is called here.
1545 switch (xev->type) { 1565 switch (xev->type) {
1546 case EnterNotify: 1566 case EnterNotify:
1547 case LeaveNotify: { 1567 case LeaveNotify: {
1548 // Ignore EventNotify and LeaveNotify events from children of |xwindow_|. 1568 // Ignore EventNotify and LeaveNotify events from children of |xwindow_|.
1549 // NativeViewGLSurfaceGLX adds a child to |xwindow_|. 1569 // NativeViewGLSurfaceGLX adds a child to |xwindow_|.
1550 // TODO(pkotwicz|tdanderson): Figure out whether the suppression is 1570 // TODO(pkotwicz|tdanderson): Figure out whether the suppression is
1551 // necessary. crbug.com/385716 1571 // necessary. crbug.com/385716
1552 if (xev->xcrossing.detail == NotifyInferior) 1572 if (xev->xcrossing.detail == NotifyInferior)
1553 break; 1573 break;
1554 1574
1555 ui::MouseEvent mouse_event(xev); 1575 ui::MouseEvent mouse_event(xev);
1556 DispatchMouseEvent(&mouse_event); 1576 DispatchMouseEvent(&mouse_event);
1577
1578 if (xev->xcrossing.mode == NotifyGrab ||
1579 xev->xcrossing.mode == NotifyUngrab) {
1580 ReleaseCapture();
1581 }
1557 break; 1582 break;
1558 } 1583 }
1559 case Expose: { 1584 case Expose: {
1560 gfx::Rect damage_rect(xev->xexpose.x, xev->xexpose.y, 1585 gfx::Rect damage_rect(xev->xexpose.x, xev->xexpose.y,
1561 xev->xexpose.width, xev->xexpose.height); 1586 xev->xexpose.width, xev->xexpose.height);
1562 compositor()->ScheduleRedrawRect(damage_rect); 1587 compositor()->ScheduleRedrawRect(damage_rect);
1563 break; 1588 break;
1564 } 1589 }
1565 case KeyPress: 1590 case KeyPress:
1566 case KeyRelease: { 1591 case KeyRelease: {
(...skipping 239 matching lines...) Expand 10 before | Expand all | Expand 10 after
1806 if (linux_ui) { 1831 if (linux_ui) {
1807 ui::NativeTheme* native_theme = linux_ui->GetNativeTheme(window); 1832 ui::NativeTheme* native_theme = linux_ui->GetNativeTheme(window);
1808 if (native_theme) 1833 if (native_theme)
1809 return native_theme; 1834 return native_theme;
1810 } 1835 }
1811 1836
1812 return ui::NativeTheme::instance(); 1837 return ui::NativeTheme::instance();
1813 } 1838 }
1814 1839
1815 } // namespace views 1840 } // namespace views
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698