| 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 453 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 464 // we don't destroy the window before the callback returned (as the caller | 464 // we don't destroy the window before the callback returned (as the caller |
| 465 // may delete ourselves on destroy and the ATL callback would still | 465 // may delete ourselves on destroy and the ATL callback would still |
| 466 // dereference us when the callback returns). | 466 // dereference us when the callback returns). |
| 467 base::ThreadTaskRunnerHandle::Get()->PostTask( | 467 base::ThreadTaskRunnerHandle::Get()->PostTask( |
| 468 FROM_HERE, base::Bind(&DesktopWindowTreeHostX11::CloseNow, | 468 FROM_HERE, base::Bind(&DesktopWindowTreeHostX11::CloseNow, |
| 469 close_widget_factory_.GetWeakPtr())); | 469 close_widget_factory_.GetWeakPtr())); |
| 470 } | 470 } |
| 471 } | 471 } |
| 472 | 472 |
| 473 void DesktopWindowTreeHostX11::CloseNow() { | 473 void DesktopWindowTreeHostX11::CloseNow() { |
| 474 if (xwindow_ == None) | 474 if (xwindow_ == X11Constants::None) |
| 475 return; | 475 return; |
| 476 | 476 |
| 477 ReleaseCapture(); | 477 ReleaseCapture(); |
| 478 native_widget_delegate_->OnNativeWidgetDestroying(); | 478 native_widget_delegate_->OnNativeWidgetDestroying(); |
| 479 | 479 |
| 480 // If we have children, close them. Use a copy for iteration because they'll | 480 // If we have children, close them. Use a copy for iteration because they'll |
| 481 // remove themselves. | 481 // remove themselves. |
| 482 std::set<DesktopWindowTreeHostX11*> window_children_copy = window_children_; | 482 std::set<DesktopWindowTreeHostX11*> window_children_copy = window_children_; |
| 483 for (std::set<DesktopWindowTreeHostX11*>::iterator it = | 483 for (std::set<DesktopWindowTreeHostX11*>::iterator it = |
| 484 window_children_copy.begin(); it != window_children_copy.end(); | 484 window_children_copy.begin(); it != window_children_copy.end(); |
| (...skipping 17 matching lines...) Expand all Loading... |
| 502 // Destroy the compositor before destroying the |xwindow_| since shutdown | 502 // Destroy the compositor before destroying the |xwindow_| since shutdown |
| 503 // may try to swap, and the swap without a window causes an X error, which | 503 // may try to swap, and the swap without a window causes an X error, which |
| 504 // causes a crash with in-process renderer. | 504 // causes a crash with in-process renderer. |
| 505 DestroyCompositor(); | 505 DestroyCompositor(); |
| 506 | 506 |
| 507 open_windows().remove(xwindow_); | 507 open_windows().remove(xwindow_); |
| 508 // Actually free our native resources. | 508 // Actually free our native resources. |
| 509 if (ui::PlatformEventSource::GetInstance()) | 509 if (ui::PlatformEventSource::GetInstance()) |
| 510 ui::PlatformEventSource::GetInstance()->RemovePlatformEventDispatcher(this); | 510 ui::PlatformEventSource::GetInstance()->RemovePlatformEventDispatcher(this); |
| 511 XDestroyWindow(xdisplay_, xwindow_); | 511 XDestroyWindow(xdisplay_, xwindow_); |
| 512 xwindow_ = None; | 512 xwindow_ = X11Constants::None; |
| 513 | 513 |
| 514 desktop_native_widget_aura_->OnHostClosed(); | 514 desktop_native_widget_aura_->OnHostClosed(); |
| 515 } | 515 } |
| 516 | 516 |
| 517 aura::WindowTreeHost* DesktopWindowTreeHostX11::AsWindowTreeHost() { | 517 aura::WindowTreeHost* DesktopWindowTreeHostX11::AsWindowTreeHost() { |
| 518 return this; | 518 return this; |
| 519 } | 519 } |
| 520 | 520 |
| 521 void DesktopWindowTreeHostX11::ShowWindowWithState( | 521 void DesktopWindowTreeHostX11::ShowWindowWithState( |
| 522 ui::WindowShowState show_state) { | 522 ui::WindowShowState show_state) { |
| (...skipping 219 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 742 memset(&xclient, 0, sizeof(xclient)); | 742 memset(&xclient, 0, sizeof(xclient)); |
| 743 xclient.type = ClientMessage; | 743 xclient.type = ClientMessage; |
| 744 xclient.xclient.window = xwindow_; | 744 xclient.xclient.window = xwindow_; |
| 745 xclient.xclient.message_type = gfx::GetAtom("_NET_ACTIVE_WINDOW"); | 745 xclient.xclient.message_type = gfx::GetAtom("_NET_ACTIVE_WINDOW"); |
| 746 xclient.xclient.format = 32; | 746 xclient.xclient.format = 32; |
| 747 xclient.xclient.data.l[0] = 1; // Specified we are an app. | 747 xclient.xclient.data.l[0] = 1; // Specified we are an app. |
| 748 xclient.xclient.data.l[1] = timestamp; | 748 xclient.xclient.data.l[1] = timestamp; |
| 749 // TODO(thomasanderson): if another chrome window is active, specify that in | 749 // TODO(thomasanderson): if another chrome window is active, specify that in |
| 750 // data.l[2]. The EWMH spec claims this may make the WM more likely to | 750 // data.l[2]. The EWMH spec claims this may make the WM more likely to |
| 751 // service our _NET_ACTIVE_WINDOW request. | 751 // service our _NET_ACTIVE_WINDOW request. |
| 752 xclient.xclient.data.l[2] = None; | 752 xclient.xclient.data.l[2] = X11Constants::None; |
| 753 xclient.xclient.data.l[3] = 0; | 753 xclient.xclient.data.l[3] = 0; |
| 754 xclient.xclient.data.l[4] = 0; | 754 xclient.xclient.data.l[4] = 0; |
| 755 | 755 |
| 756 XSendEvent(xdisplay_, x_root_window_, False, | 756 XSendEvent(xdisplay_, x_root_window_, X11Constants::False, |
| 757 SubstructureRedirectMask | SubstructureNotifyMask, &xclient); | 757 SubstructureRedirectMask | SubstructureNotifyMask, &xclient); |
| 758 } else { | 758 } else { |
| 759 XRaiseWindow(xdisplay_, xwindow_); | 759 XRaiseWindow(xdisplay_, xwindow_); |
| 760 // Directly ask the X server to give focus to the window. Note that the call | 760 // Directly ask the X server to give focus to the window. Note that the call |
| 761 // would have raised an X error if the window is not mapped. | 761 // would have raised an X error if the window is not mapped. |
| 762 auto old_error_handler = XSetErrorHandler(IgnoreX11Errors); | 762 auto old_error_handler = XSetErrorHandler(IgnoreX11Errors); |
| 763 XSetInputFocus(xdisplay_, xwindow_, RevertToParent, timestamp); | 763 XSetInputFocus(xdisplay_, xwindow_, RevertToParent, timestamp); |
| 764 // At this point, we know we will receive focus, and some | 764 // At this point, we know we will receive focus, and some |
| 765 // webdriver tests depend on a window being IsActive() immediately | 765 // webdriver tests depend on a window being IsActive() immediately |
| 766 // after an Activate(), so just set this state now. | 766 // after an Activate(), so just set this state now. |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 799 | 799 |
| 800 // |has_window_focus_| and |has_pointer_focus_| are mutually exclusive. | 800 // |has_window_focus_| and |has_pointer_focus_| are mutually exclusive. |
| 801 DCHECK(!has_window_focus_ || !has_pointer_focus_); | 801 DCHECK(!has_window_focus_ || !has_pointer_focus_); |
| 802 | 802 |
| 803 return is_active; | 803 return is_active; |
| 804 } | 804 } |
| 805 | 805 |
| 806 void DesktopWindowTreeHostX11::Maximize() { | 806 void DesktopWindowTreeHostX11::Maximize() { |
| 807 if (HasWMSpecProperty("_NET_WM_STATE_FULLSCREEN")) { | 807 if (HasWMSpecProperty("_NET_WM_STATE_FULLSCREEN")) { |
| 808 // Unfullscreen the window if it is fullscreen. | 808 // Unfullscreen the window if it is fullscreen. |
| 809 SetWMSpecState(false, gfx::GetAtom("_NET_WM_STATE_FULLSCREEN"), None); | 809 SetWMSpecState(false, gfx::GetAtom("_NET_WM_STATE_FULLSCREEN"), X11Constants
::None); |
| 810 | 810 |
| 811 // Resize the window so that it does not have the same size as a monitor. | 811 // Resize the window so that it does not have the same size as a monitor. |
| 812 // (Otherwise, some window managers immediately put the window back in | 812 // (Otherwise, some window managers immediately put the window back in |
| 813 // fullscreen mode). | 813 // fullscreen mode). |
| 814 gfx::Rect adjusted_bounds_in_pixels(bounds_in_pixels_.origin(), | 814 gfx::Rect adjusted_bounds_in_pixels(bounds_in_pixels_.origin(), |
| 815 AdjustSize(bounds_in_pixels_.size())); | 815 AdjustSize(bounds_in_pixels_.size())); |
| 816 if (adjusted_bounds_in_pixels != bounds_in_pixels_) | 816 if (adjusted_bounds_in_pixels != bounds_in_pixels_) |
| 817 SetBoundsInPixels(adjusted_bounds_in_pixels); | 817 SetBoundsInPixels(adjusted_bounds_in_pixels); |
| 818 } | 818 } |
| 819 | 819 |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 853 bool DesktopWindowTreeHostX11::IsMinimized() const { | 853 bool DesktopWindowTreeHostX11::IsMinimized() const { |
| 854 return HasWMSpecProperty("_NET_WM_STATE_HIDDEN"); | 854 return HasWMSpecProperty("_NET_WM_STATE_HIDDEN"); |
| 855 } | 855 } |
| 856 | 856 |
| 857 bool DesktopWindowTreeHostX11::HasCapture() const { | 857 bool DesktopWindowTreeHostX11::HasCapture() const { |
| 858 return g_current_capture == this; | 858 return g_current_capture == this; |
| 859 } | 859 } |
| 860 | 860 |
| 861 void DesktopWindowTreeHostX11::SetAlwaysOnTop(bool always_on_top) { | 861 void DesktopWindowTreeHostX11::SetAlwaysOnTop(bool always_on_top) { |
| 862 is_always_on_top_ = always_on_top; | 862 is_always_on_top_ = always_on_top; |
| 863 SetWMSpecState(always_on_top, gfx::GetAtom("_NET_WM_STATE_ABOVE"), None); | 863 SetWMSpecState(always_on_top, gfx::GetAtom("_NET_WM_STATE_ABOVE"), X11Constant
s::None); |
| 864 } | 864 } |
| 865 | 865 |
| 866 bool DesktopWindowTreeHostX11::IsAlwaysOnTop() const { | 866 bool DesktopWindowTreeHostX11::IsAlwaysOnTop() const { |
| 867 return is_always_on_top_; | 867 return is_always_on_top_; |
| 868 } | 868 } |
| 869 | 869 |
| 870 void DesktopWindowTreeHostX11::SetVisibleOnAllWorkspaces(bool always_visible) { | 870 void DesktopWindowTreeHostX11::SetVisibleOnAllWorkspaces(bool always_visible) { |
| 871 SetWMSpecState(always_visible, gfx::GetAtom("_NET_WM_STATE_STICKY"), None); | 871 SetWMSpecState(always_visible, gfx::GetAtom("_NET_WM_STATE_STICKY"), X11Consta
nts::None); |
| 872 | 872 |
| 873 int new_desktop = 0; | 873 int new_desktop = 0; |
| 874 if (always_visible) { | 874 if (always_visible) { |
| 875 new_desktop = kAllDesktops; | 875 new_desktop = kAllDesktops; |
| 876 } else { | 876 } else { |
| 877 if (!ui::GetCurrentDesktop(&new_desktop)) | 877 if (!ui::GetCurrentDesktop(&new_desktop)) |
| 878 return; | 878 return; |
| 879 } | 879 } |
| 880 | 880 |
| 881 workspace_ = base::IntToString(kAllDesktops); | 881 workspace_ = base::IntToString(kAllDesktops); |
| 882 XEvent xevent; | 882 XEvent xevent; |
| 883 memset (&xevent, 0, sizeof (xevent)); | 883 memset (&xevent, 0, sizeof (xevent)); |
| 884 xevent.type = ClientMessage; | 884 xevent.type = ClientMessage; |
| 885 xevent.xclient.window = xwindow_; | 885 xevent.xclient.window = xwindow_; |
| 886 xevent.xclient.message_type = gfx::GetAtom("_NET_WM_DESKTOP"); | 886 xevent.xclient.message_type = gfx::GetAtom("_NET_WM_DESKTOP"); |
| 887 xevent.xclient.format = 32; | 887 xevent.xclient.format = 32; |
| 888 xevent.xclient.data.l[0] = new_desktop; | 888 xevent.xclient.data.l[0] = new_desktop; |
| 889 xevent.xclient.data.l[1] = 0; | 889 xevent.xclient.data.l[1] = 0; |
| 890 xevent.xclient.data.l[2] = 0; | 890 xevent.xclient.data.l[2] = 0; |
| 891 xevent.xclient.data.l[3] = 0; | 891 xevent.xclient.data.l[3] = 0; |
| 892 xevent.xclient.data.l[4] = 0; | 892 xevent.xclient.data.l[4] = 0; |
| 893 XSendEvent(xdisplay_, x_root_window_, False, | 893 XSendEvent(xdisplay_, x_root_window_, X11Constants::False, |
| 894 SubstructureRedirectMask | SubstructureNotifyMask, | 894 SubstructureRedirectMask | SubstructureNotifyMask, &xevent); |
| 895 &xevent); | |
| 896 } | 895 } |
| 897 | 896 |
| 898 bool DesktopWindowTreeHostX11::IsVisibleOnAllWorkspaces() const { | 897 bool DesktopWindowTreeHostX11::IsVisibleOnAllWorkspaces() const { |
| 899 // We don't need a check for _NET_WM_STATE_STICKY because that would specify | 898 // We don't need a check for _NET_WM_STATE_STICKY because that would specify |
| 900 // that the window remain in a fixed position even if the viewport scrolls. | 899 // that the window remain in a fixed position even if the viewport scrolls. |
| 901 // This is different from the type of workspace that's associated with | 900 // This is different from the type of workspace that's associated with |
| 902 // _NET_WM_DESKTOP. | 901 // _NET_WM_DESKTOP. |
| 903 return GetWorkspace() == base::IntToString(kAllDesktops); | 902 return GetWorkspace() == base::IntToString(kAllDesktops); |
| 904 } | 903 } |
| 905 | 904 |
| 906 bool DesktopWindowTreeHostX11::SetWindowTitle(const base::string16& title) { | 905 bool DesktopWindowTreeHostX11::SetWindowTitle(const base::string16& title) { |
| 907 if (window_title_ == title) | 906 if (window_title_ == title) |
| 908 return false; | 907 return false; |
| 909 window_title_ = title; | 908 window_title_ = title; |
| 910 std::string utf8str = base::UTF16ToUTF8(title); | 909 std::string utf8str = base::UTF16ToUTF8(title); |
| 911 XChangeProperty(xdisplay_, xwindow_, gfx::GetAtom("_NET_WM_NAME"), | 910 XChangeProperty(xdisplay_, xwindow_, gfx::GetAtom("_NET_WM_NAME"), |
| 912 gfx::GetAtom("UTF8_STRING"), 8, PropModeReplace, | 911 gfx::GetAtom("UTF8_STRING"), 8, PropModeReplace, |
| 913 reinterpret_cast<const unsigned char*>(utf8str.c_str()), | 912 reinterpret_cast<const unsigned char*>(utf8str.c_str()), |
| 914 utf8str.size()); | 913 utf8str.size()); |
| 915 XTextProperty xtp; | 914 XTextProperty xtp; |
| 916 char* c_utf8_str = const_cast<char*>(utf8str.c_str()); | 915 char* c_utf8_str = const_cast<char*>(utf8str.c_str()); |
| 917 if (Xutf8TextListToTextProperty(xdisplay_, &c_utf8_str, 1, | 916 if (Xutf8TextListToTextProperty(xdisplay_, &c_utf8_str, 1, XUTF8StringStyle, |
| 918 XUTF8StringStyle, &xtp) == Success) { | 917 &xtp) == X11Constants::Success) { |
| 919 XSetWMName(xdisplay_, xwindow_, &xtp); | 918 XSetWMName(xdisplay_, xwindow_, &xtp); |
| 920 XFree(xtp.value); | 919 XFree(xtp.value); |
| 921 } | 920 } |
| 922 return true; | 921 return true; |
| 923 } | 922 } |
| 924 | 923 |
| 925 void DesktopWindowTreeHostX11::ClearNativeFocus() { | 924 void DesktopWindowTreeHostX11::ClearNativeFocus() { |
| 926 // This method is weird and misnamed. Instead of clearing the native focus, | 925 // This method is weird and misnamed. Instead of clearing the native focus, |
| 927 // it sets the focus to our |content_window_|, which will trigger a cascade | 926 // it sets the focus to our |content_window_|, which will trigger a cascade |
| 928 // of focus changes into views. | 927 // of focus changes into views. |
| (...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 999 | 998 |
| 1000 // Work around a bug where if we try to unfullscreen, metacity immediately | 999 // Work around a bug where if we try to unfullscreen, metacity immediately |
| 1001 // fullscreens us again. This is a little flickery and not necessary if | 1000 // fullscreens us again. This is a little flickery and not necessary if |
| 1002 // there's a gnome-panel, but it's not easy to detect whether there's a | 1001 // there's a gnome-panel, but it's not easy to detect whether there's a |
| 1003 // panel or not. | 1002 // panel or not. |
| 1004 bool unmaximize_and_remaximize = !fullscreen && IsMaximized() && | 1003 bool unmaximize_and_remaximize = !fullscreen && IsMaximized() && |
| 1005 ui::GuessWindowManager() == ui::WM_METACITY; | 1004 ui::GuessWindowManager() == ui::WM_METACITY; |
| 1006 | 1005 |
| 1007 if (unmaximize_and_remaximize) | 1006 if (unmaximize_and_remaximize) |
| 1008 Restore(); | 1007 Restore(); |
| 1009 SetWMSpecState(fullscreen, gfx::GetAtom("_NET_WM_STATE_FULLSCREEN"), None); | 1008 SetWMSpecState(fullscreen, gfx::GetAtom("_NET_WM_STATE_FULLSCREEN"), X11Consta
nts::None); |
| 1010 if (unmaximize_and_remaximize) | 1009 if (unmaximize_and_remaximize) |
| 1011 Maximize(); | 1010 Maximize(); |
| 1012 | 1011 |
| 1013 // Try to guess the size we will have after the switch to/from fullscreen: | 1012 // Try to guess the size we will have after the switch to/from fullscreen: |
| 1014 // - (may) avoid transient states | 1013 // - (may) avoid transient states |
| 1015 // - works around Flash content which expects to have the size updated | 1014 // - works around Flash content which expects to have the size updated |
| 1016 // synchronously. | 1015 // synchronously. |
| 1017 // See https://crbug.com/361408 | 1016 // See https://crbug.com/361408 |
| 1018 if (fullscreen) { | 1017 if (fullscreen) { |
| 1019 restored_bounds_in_pixels_ = bounds_in_pixels_; | 1018 restored_bounds_in_pixels_ = bounds_in_pixels_; |
| (...skipping 238 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1258 DesktopWindowTreeHostX11* old_capturer = g_current_capture; | 1257 DesktopWindowTreeHostX11* old_capturer = g_current_capture; |
| 1259 | 1258 |
| 1260 // Update |g_current_capture| prior to calling OnHostLostWindowCapture() to | 1259 // Update |g_current_capture| prior to calling OnHostLostWindowCapture() to |
| 1261 // avoid releasing pointer grab. | 1260 // avoid releasing pointer grab. |
| 1262 g_current_capture = this; | 1261 g_current_capture = this; |
| 1263 if (old_capturer) | 1262 if (old_capturer) |
| 1264 old_capturer->OnHostLostWindowCapture(); | 1263 old_capturer->OnHostLostWindowCapture(); |
| 1265 | 1264 |
| 1266 // If the pointer is already in |xwindow_|, we will not get a crossing event | 1265 // If the pointer is already in |xwindow_|, we will not get a crossing event |
| 1267 // with a mode of NotifyGrab, so we must record the grab state manually. | 1266 // with a mode of NotifyGrab, so we must record the grab state manually. |
| 1268 has_pointer_grab_ |= !GrabPointer(xwindow_, true, None); | 1267 has_pointer_grab_ |= !GrabPointer(xwindow_, true, X11Constants::None); |
| 1269 } | 1268 } |
| 1270 | 1269 |
| 1271 void DesktopWindowTreeHostX11::ReleaseCapture() { | 1270 void DesktopWindowTreeHostX11::ReleaseCapture() { |
| 1272 if (g_current_capture == this) { | 1271 if (g_current_capture == this) { |
| 1273 // Release mouse grab asynchronously. A window managed by Chrome is likely | 1272 // Release mouse grab asynchronously. A window managed by Chrome is likely |
| 1274 // the topmost window underneath the mouse so the capture release being | 1273 // the topmost window underneath the mouse so the capture release being |
| 1275 // asynchronous is likely inconsequential. | 1274 // asynchronous is likely inconsequential. |
| 1276 g_current_capture = NULL; | 1275 g_current_capture = NULL; |
| 1277 UngrabPointer(); | 1276 UngrabPointer(); |
| 1278 has_pointer_grab_ = false; | 1277 has_pointer_grab_ = false; |
| 1279 | 1278 |
| 1280 OnHostLostWindowCapture(); | 1279 OnHostLostWindowCapture(); |
| 1281 } | 1280 } |
| 1282 } | 1281 } |
| 1283 | 1282 |
| 1284 void DesktopWindowTreeHostX11::SetCursorNative(gfx::NativeCursor cursor) { | 1283 void DesktopWindowTreeHostX11::SetCursorNative(gfx::NativeCursor cursor) { |
| 1285 XDefineCursor(xdisplay_, xwindow_, cursor.platform()); | 1284 XDefineCursor(xdisplay_, xwindow_, cursor.platform()); |
| 1286 } | 1285 } |
| 1287 | 1286 |
| 1288 void DesktopWindowTreeHostX11::MoveCursorToScreenLocationInPixels( | 1287 void DesktopWindowTreeHostX11::MoveCursorToScreenLocationInPixels( |
| 1289 const gfx::Point& location_in_pixels) { | 1288 const gfx::Point& location_in_pixels) { |
| 1290 XWarpPointer(xdisplay_, None, x_root_window_, 0, 0, 0, 0, | 1289 XWarpPointer(xdisplay_, X11Constants::None, x_root_window_, 0, 0, 0, 0, |
| 1291 bounds_in_pixels_.x() + location_in_pixels.x(), | 1290 bounds_in_pixels_.x() + location_in_pixels.x(), |
| 1292 bounds_in_pixels_.y() + location_in_pixels.y()); | 1291 bounds_in_pixels_.y() + location_in_pixels.y()); |
| 1293 } | 1292 } |
| 1294 | 1293 |
| 1295 void DesktopWindowTreeHostX11::OnCursorVisibilityChangedNative(bool show) { | 1294 void DesktopWindowTreeHostX11::OnCursorVisibilityChangedNative(bool show) { |
| 1296 // TODO(erg): Conditional on us enabling touch on desktop linux builds, do | 1295 // TODO(erg): Conditional on us enabling touch on desktop linux builds, do |
| 1297 // the same tap-to-click disabling here that chromeos does. | 1296 // the same tap-to-click disabling here that chromeos does. |
| 1298 } | 1297 } |
| 1299 | 1298 |
| 1300 //////////////////////////////////////////////////////////////////////////////// | 1299 //////////////////////////////////////////////////////////////////////////////// |
| (...skipping 17 matching lines...) Expand all Loading... |
| 1318 } | 1317 } |
| 1319 | 1318 |
| 1320 //////////////////////////////////////////////////////////////////////////////// | 1319 //////////////////////////////////////////////////////////////////////////////// |
| 1321 // DesktopWindowTreeHostX11, private: | 1320 // DesktopWindowTreeHostX11, private: |
| 1322 | 1321 |
| 1323 void DesktopWindowTreeHostX11::InitX11Window( | 1322 void DesktopWindowTreeHostX11::InitX11Window( |
| 1324 const Widget::InitParams& params) { | 1323 const Widget::InitParams& params) { |
| 1325 unsigned long attribute_mask = CWBackPixmap | CWBitGravity; | 1324 unsigned long attribute_mask = CWBackPixmap | CWBitGravity; |
| 1326 XSetWindowAttributes swa; | 1325 XSetWindowAttributes swa; |
| 1327 memset(&swa, 0, sizeof(swa)); | 1326 memset(&swa, 0, sizeof(swa)); |
| 1328 swa.background_pixmap = None; | 1327 swa.background_pixmap = X11Constants::None; |
| 1329 swa.bit_gravity = NorthWestGravity; | 1328 swa.bit_gravity = NorthWestGravity; |
| 1330 | 1329 |
| 1331 ::Atom window_type; | 1330 ::Atom window_type; |
| 1332 switch (params.type) { | 1331 switch (params.type) { |
| 1333 case Widget::InitParams::TYPE_MENU: | 1332 case Widget::InitParams::TYPE_MENU: |
| 1334 swa.override_redirect = True; | 1333 swa.override_redirect = X11Constants::True; |
| 1335 window_type = gfx::GetAtom("_NET_WM_WINDOW_TYPE_MENU"); | 1334 window_type = gfx::GetAtom("_NET_WM_WINDOW_TYPE_MENU"); |
| 1336 break; | 1335 break; |
| 1337 case Widget::InitParams::TYPE_TOOLTIP: | 1336 case Widget::InitParams::TYPE_TOOLTIP: |
| 1338 swa.override_redirect = True; | 1337 swa.override_redirect = X11Constants::True; |
| 1339 window_type = gfx::GetAtom("_NET_WM_WINDOW_TYPE_TOOLTIP"); | 1338 window_type = gfx::GetAtom("_NET_WM_WINDOW_TYPE_TOOLTIP"); |
| 1340 break; | 1339 break; |
| 1341 case Widget::InitParams::TYPE_POPUP: | 1340 case Widget::InitParams::TYPE_POPUP: |
| 1342 swa.override_redirect = True; | 1341 swa.override_redirect = X11Constants::True; |
| 1343 window_type = gfx::GetAtom("_NET_WM_WINDOW_TYPE_NOTIFICATION"); | 1342 window_type = gfx::GetAtom("_NET_WM_WINDOW_TYPE_NOTIFICATION"); |
| 1344 break; | 1343 break; |
| 1345 case Widget::InitParams::TYPE_DRAG: | 1344 case Widget::InitParams::TYPE_DRAG: |
| 1346 swa.override_redirect = True; | 1345 swa.override_redirect = X11Constants::True; |
| 1347 window_type = gfx::GetAtom("_NET_WM_WINDOW_TYPE_DND"); | 1346 window_type = gfx::GetAtom("_NET_WM_WINDOW_TYPE_DND"); |
| 1348 break; | 1347 break; |
| 1349 default: | 1348 default: |
| 1350 window_type = gfx::GetAtom("_NET_WM_WINDOW_TYPE_NORMAL"); | 1349 window_type = gfx::GetAtom("_NET_WM_WINDOW_TYPE_NORMAL"); |
| 1351 break; | 1350 break; |
| 1352 } | 1351 } |
| 1353 // An in-activatable window should not interact with the system wm. | 1352 // An in-activatable window should not interact with the system wm. |
| 1354 if (!activatable_) | 1353 if (!activatable_) |
| 1355 swa.override_redirect = True; | 1354 swa.override_redirect = X11Constants::True; |
| 1356 | 1355 |
| 1357 if (swa.override_redirect) | 1356 if (swa.override_redirect) |
| 1358 attribute_mask |= CWOverrideRedirect; | 1357 attribute_mask |= CWOverrideRedirect; |
| 1359 | 1358 |
| 1360 bool enable_transparent_visuals; | 1359 bool enable_transparent_visuals; |
| 1361 switch (params.opacity) { | 1360 switch (params.opacity) { |
| 1362 case Widget::InitParams::OPAQUE_WINDOW: | 1361 case Widget::InitParams::OPAQUE_WINDOW: |
| 1363 enable_transparent_visuals = false; | 1362 enable_transparent_visuals = false; |
| 1364 break; | 1363 break; |
| 1365 case Widget::InitParams::TRANSLUCENT_WINDOW: | 1364 case Widget::InitParams::TRANSLUCENT_WINDOW: |
| (...skipping 323 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1689 xclient.xclient.window = xwindow_; | 1688 xclient.xclient.window = xwindow_; |
| 1690 xclient.xclient.message_type = gfx::GetAtom("_NET_WM_STATE"); | 1689 xclient.xclient.message_type = gfx::GetAtom("_NET_WM_STATE"); |
| 1691 xclient.xclient.format = 32; | 1690 xclient.xclient.format = 32; |
| 1692 xclient.xclient.data.l[0] = | 1691 xclient.xclient.data.l[0] = |
| 1693 enabled ? k_NET_WM_STATE_ADD : k_NET_WM_STATE_REMOVE; | 1692 enabled ? k_NET_WM_STATE_ADD : k_NET_WM_STATE_REMOVE; |
| 1694 xclient.xclient.data.l[1] = state1; | 1693 xclient.xclient.data.l[1] = state1; |
| 1695 xclient.xclient.data.l[2] = state2; | 1694 xclient.xclient.data.l[2] = state2; |
| 1696 xclient.xclient.data.l[3] = 1; | 1695 xclient.xclient.data.l[3] = 1; |
| 1697 xclient.xclient.data.l[4] = 0; | 1696 xclient.xclient.data.l[4] = 0; |
| 1698 | 1697 |
| 1699 XSendEvent(xdisplay_, x_root_window_, False, | 1698 XSendEvent(xdisplay_, x_root_window_, X11Constants::False, |
| 1700 SubstructureRedirectMask | SubstructureNotifyMask, | 1699 SubstructureRedirectMask | SubstructureNotifyMask, &xclient); |
| 1701 &xclient); | |
| 1702 } | 1700 } |
| 1703 | 1701 |
| 1704 bool DesktopWindowTreeHostX11::HasWMSpecProperty(const char* property) const { | 1702 bool DesktopWindowTreeHostX11::HasWMSpecProperty(const char* property) const { |
| 1705 return window_properties_.find(gfx::GetAtom(property)) != | 1703 return window_properties_.find(gfx::GetAtom(property)) != |
| 1706 window_properties_.end(); | 1704 window_properties_.end(); |
| 1707 } | 1705 } |
| 1708 | 1706 |
| 1709 void DesktopWindowTreeHostX11::SetUseNativeFrame(bool use_native_frame) { | 1707 void DesktopWindowTreeHostX11::SetUseNativeFrame(bool use_native_frame) { |
| 1710 use_native_frame_ = use_native_frame; | 1708 use_native_frame_ = use_native_frame; |
| 1711 ui::SetUseOSWindowFrame(xwindow_, use_native_frame); | 1709 ui::SetUseOSWindowFrame(xwindow_, use_native_frame); |
| (...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1809 } | 1807 } |
| 1810 } | 1808 } |
| 1811 | 1809 |
| 1812 // If we didn't set the shape for any reason, reset the shaping information. | 1810 // If we didn't set the shape for any reason, reset the shaping information. |
| 1813 // How this is done depends on the border style, due to quirks and bugs in | 1811 // How this is done depends on the border style, due to quirks and bugs in |
| 1814 // various window managers. | 1812 // various window managers. |
| 1815 if (ShouldUseNativeFrame()) { | 1813 if (ShouldUseNativeFrame()) { |
| 1816 // If the window has system borders, the mask must be set to null (not a | 1814 // If the window has system borders, the mask must be set to null (not a |
| 1817 // rectangle), because several window managers (eg, KDE, XFCE, XMonad) will | 1815 // rectangle), because several window managers (eg, KDE, XFCE, XMonad) will |
| 1818 // not put borders on a window with a custom shape. | 1816 // not put borders on a window with a custom shape. |
| 1819 XShapeCombineMask(xdisplay_, xwindow_, ShapeBounding, 0, 0, None, ShapeSet); | 1817 XShapeCombineMask(xdisplay_, xwindow_, ShapeBounding, 0, 0, |
| 1818 X11Constants::None, ShapeSet); |
| 1820 } else { | 1819 } else { |
| 1821 // Conversely, if the window does not have system borders, the mask must be | 1820 // Conversely, if the window does not have system borders, the mask must be |
| 1822 // manually set to a rectangle that covers the whole window (not null). This | 1821 // manually set to a rectangle that covers the whole window (not null). This |
| 1823 // is due to a bug in KWin <= 4.11.5 (KDE bug #330573) where setting a null | 1822 // is due to a bug in KWin <= 4.11.5 (KDE bug #330573) where setting a null |
| 1824 // shape causes the hint to disable system borders to be ignored (resulting | 1823 // shape causes the hint to disable system borders to be ignored (resulting |
| 1825 // in a double border). | 1824 // in a double border). |
| 1826 XRectangle r = {0, | 1825 XRectangle r = {0, |
| 1827 0, | 1826 0, |
| 1828 static_cast<unsigned short>(bounds_in_pixels_.width()), | 1827 static_cast<unsigned short>(bounds_in_pixels_.width()), |
| 1829 static_cast<unsigned short>(bounds_in_pixels_.height())}; | 1828 static_cast<unsigned short>(bounds_in_pixels_.height())}; |
| (...skipping 311 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2141 Atom message_type = xev->xclient.message_type; | 2140 Atom message_type = xev->xclient.message_type; |
| 2142 if (message_type == gfx::GetAtom("WM_PROTOCOLS")) { | 2141 if (message_type == gfx::GetAtom("WM_PROTOCOLS")) { |
| 2143 Atom protocol = static_cast<Atom>(xev->xclient.data.l[0]); | 2142 Atom protocol = static_cast<Atom>(xev->xclient.data.l[0]); |
| 2144 if (protocol == gfx::GetAtom("WM_DELETE_WINDOW")) { | 2143 if (protocol == gfx::GetAtom("WM_DELETE_WINDOW")) { |
| 2145 // We have received a close message from the window manager. | 2144 // We have received a close message from the window manager. |
| 2146 OnHostCloseRequested(); | 2145 OnHostCloseRequested(); |
| 2147 } else if (protocol == gfx::GetAtom("_NET_WM_PING")) { | 2146 } else if (protocol == gfx::GetAtom("_NET_WM_PING")) { |
| 2148 XEvent reply_event = *xev; | 2147 XEvent reply_event = *xev; |
| 2149 reply_event.xclient.window = x_root_window_; | 2148 reply_event.xclient.window = x_root_window_; |
| 2150 | 2149 |
| 2151 XSendEvent(xdisplay_, | 2150 XSendEvent(xdisplay_, reply_event.xclient.window, X11Constants::False, |
| 2152 reply_event.xclient.window, | |
| 2153 False, | |
| 2154 SubstructureRedirectMask | SubstructureNotifyMask, | 2151 SubstructureRedirectMask | SubstructureNotifyMask, |
| 2155 &reply_event); | 2152 &reply_event); |
| 2156 } | 2153 } |
| 2157 } else if (message_type == gfx::GetAtom("XdndEnter")) { | 2154 } else if (message_type == gfx::GetAtom("XdndEnter")) { |
| 2158 drag_drop_client_->OnXdndEnter(xev->xclient); | 2155 drag_drop_client_->OnXdndEnter(xev->xclient); |
| 2159 } else if (message_type == gfx::GetAtom("XdndLeave")) { | 2156 } else if (message_type == gfx::GetAtom("XdndLeave")) { |
| 2160 drag_drop_client_->OnXdndLeave(xev->xclient); | 2157 drag_drop_client_->OnXdndLeave(xev->xclient); |
| 2161 } else if (message_type == gfx::GetAtom("XdndPosition")) { | 2158 } else if (message_type == gfx::GetAtom("XdndPosition")) { |
| 2162 drag_drop_client_->OnXdndPosition(xev->xclient); | 2159 drag_drop_client_->OnXdndPosition(xev->xclient); |
| 2163 } else if (message_type == gfx::GetAtom("XdndStatus")) { | 2160 } else if (message_type == gfx::GetAtom("XdndStatus")) { |
| (...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2311 | 2308 |
| 2312 // static | 2309 // static |
| 2313 DesktopWindowTreeHost* DesktopWindowTreeHost::Create( | 2310 DesktopWindowTreeHost* DesktopWindowTreeHost::Create( |
| 2314 internal::NativeWidgetDelegate* native_widget_delegate, | 2311 internal::NativeWidgetDelegate* native_widget_delegate, |
| 2315 DesktopNativeWidgetAura* desktop_native_widget_aura) { | 2312 DesktopNativeWidgetAura* desktop_native_widget_aura) { |
| 2316 return new DesktopWindowTreeHostX11(native_widget_delegate, | 2313 return new DesktopWindowTreeHostX11(native_widget_delegate, |
| 2317 desktop_native_widget_aura); | 2314 desktop_native_widget_aura); |
| 2318 } | 2315 } |
| 2319 | 2316 |
| 2320 } // namespace views | 2317 } // namespace views |
| OLD | NEW |