| 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 456 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 467 // we don't destroy the window before the callback returned (as the caller | 467 // we don't destroy the window before the callback returned (as the caller |
| 468 // may delete ourselves on destroy and the ATL callback would still | 468 // may delete ourselves on destroy and the ATL callback would still |
| 469 // dereference us when the callback returns). | 469 // dereference us when the callback returns). |
| 470 base::ThreadTaskRunnerHandle::Get()->PostTask( | 470 base::ThreadTaskRunnerHandle::Get()->PostTask( |
| 471 FROM_HERE, base::Bind(&DesktopWindowTreeHostX11::CloseNow, | 471 FROM_HERE, base::Bind(&DesktopWindowTreeHostX11::CloseNow, |
| 472 close_widget_factory_.GetWeakPtr())); | 472 close_widget_factory_.GetWeakPtr())); |
| 473 } | 473 } |
| 474 } | 474 } |
| 475 | 475 |
| 476 void DesktopWindowTreeHostX11::CloseNow() { | 476 void DesktopWindowTreeHostX11::CloseNow() { |
| 477 if (xwindow_ == None) | 477 if (xwindow_ == X11Constants::None) |
| 478 return; | 478 return; |
| 479 | 479 |
| 480 ReleaseCapture(); | 480 ReleaseCapture(); |
| 481 native_widget_delegate_->OnNativeWidgetDestroying(); | 481 native_widget_delegate_->OnNativeWidgetDestroying(); |
| 482 | 482 |
| 483 // If we have children, close them. Use a copy for iteration because they'll | 483 // If we have children, close them. Use a copy for iteration because they'll |
| 484 // remove themselves. | 484 // remove themselves. |
| 485 std::set<DesktopWindowTreeHostX11*> window_children_copy = window_children_; | 485 std::set<DesktopWindowTreeHostX11*> window_children_copy = window_children_; |
| 486 for (std::set<DesktopWindowTreeHostX11*>::iterator it = | 486 for (std::set<DesktopWindowTreeHostX11*>::iterator it = |
| 487 window_children_copy.begin(); it != window_children_copy.end(); | 487 window_children_copy.begin(); it != window_children_copy.end(); |
| (...skipping 17 matching lines...) Expand all Loading... |
| 505 // Destroy the compositor before destroying the |xwindow_| since shutdown | 505 // Destroy the compositor before destroying the |xwindow_| since shutdown |
| 506 // may try to swap, and the swap without a window causes an X error, which | 506 // may try to swap, and the swap without a window causes an X error, which |
| 507 // causes a crash with in-process renderer. | 507 // causes a crash with in-process renderer. |
| 508 DestroyCompositor(); | 508 DestroyCompositor(); |
| 509 | 509 |
| 510 open_windows().remove(xwindow_); | 510 open_windows().remove(xwindow_); |
| 511 // Actually free our native resources. | 511 // Actually free our native resources. |
| 512 if (ui::PlatformEventSource::GetInstance()) | 512 if (ui::PlatformEventSource::GetInstance()) |
| 513 ui::PlatformEventSource::GetInstance()->RemovePlatformEventDispatcher(this); | 513 ui::PlatformEventSource::GetInstance()->RemovePlatformEventDispatcher(this); |
| 514 XDestroyWindow(xdisplay_, xwindow_); | 514 XDestroyWindow(xdisplay_, xwindow_); |
| 515 xwindow_ = None; | 515 xwindow_ = X11Constants::None; |
| 516 | 516 |
| 517 desktop_native_widget_aura_->OnHostClosed(); | 517 desktop_native_widget_aura_->OnHostClosed(); |
| 518 } | 518 } |
| 519 | 519 |
| 520 aura::WindowTreeHost* DesktopWindowTreeHostX11::AsWindowTreeHost() { | 520 aura::WindowTreeHost* DesktopWindowTreeHostX11::AsWindowTreeHost() { |
| 521 return this; | 521 return this; |
| 522 } | 522 } |
| 523 | 523 |
| 524 void DesktopWindowTreeHostX11::ShowWindowWithState( | 524 void DesktopWindowTreeHostX11::ShowWindowWithState( |
| 525 ui::WindowShowState show_state) { | 525 ui::WindowShowState show_state) { |
| (...skipping 222 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 748 memset(&xclient, 0, sizeof(xclient)); | 748 memset(&xclient, 0, sizeof(xclient)); |
| 749 xclient.type = ClientMessage; | 749 xclient.type = ClientMessage; |
| 750 xclient.xclient.window = xwindow_; | 750 xclient.xclient.window = xwindow_; |
| 751 xclient.xclient.message_type = gfx::GetAtom("_NET_ACTIVE_WINDOW"); | 751 xclient.xclient.message_type = gfx::GetAtom("_NET_ACTIVE_WINDOW"); |
| 752 xclient.xclient.format = 32; | 752 xclient.xclient.format = 32; |
| 753 xclient.xclient.data.l[0] = 1; // Specified we are an app. | 753 xclient.xclient.data.l[0] = 1; // Specified we are an app. |
| 754 xclient.xclient.data.l[1] = timestamp; | 754 xclient.xclient.data.l[1] = timestamp; |
| 755 // TODO(thomasanderson): if another chrome window is active, specify that in | 755 // TODO(thomasanderson): if another chrome window is active, specify that in |
| 756 // data.l[2]. The EWMH spec claims this may make the WM more likely to | 756 // data.l[2]. The EWMH spec claims this may make the WM more likely to |
| 757 // service our _NET_ACTIVE_WINDOW request. | 757 // service our _NET_ACTIVE_WINDOW request. |
| 758 xclient.xclient.data.l[2] = None; | 758 xclient.xclient.data.l[2] = X11Constants::None; |
| 759 xclient.xclient.data.l[3] = 0; | 759 xclient.xclient.data.l[3] = 0; |
| 760 xclient.xclient.data.l[4] = 0; | 760 xclient.xclient.data.l[4] = 0; |
| 761 | 761 |
| 762 XSendEvent(xdisplay_, x_root_window_, False, | 762 XSendEvent(xdisplay_, x_root_window_, X11Constants::False, |
| 763 SubstructureRedirectMask | SubstructureNotifyMask, &xclient); | 763 SubstructureRedirectMask | SubstructureNotifyMask, &xclient); |
| 764 } else { | 764 } else { |
| 765 XRaiseWindow(xdisplay_, xwindow_); | 765 XRaiseWindow(xdisplay_, xwindow_); |
| 766 // Directly ask the X server to give focus to the window. Note that the call | 766 // Directly ask the X server to give focus to the window. Note that the call |
| 767 // would have raised an X error if the window is not mapped. | 767 // would have raised an X error if the window is not mapped. |
| 768 auto old_error_handler = XSetErrorHandler(IgnoreX11Errors); | 768 auto old_error_handler = XSetErrorHandler(IgnoreX11Errors); |
| 769 XSetInputFocus(xdisplay_, xwindow_, RevertToParent, timestamp); | 769 XSetInputFocus(xdisplay_, xwindow_, RevertToParent, timestamp); |
| 770 // At this point, we know we will receive focus, and some | 770 // At this point, we know we will receive focus, and some |
| 771 // webdriver tests depend on a window being IsActive() immediately | 771 // webdriver tests depend on a window being IsActive() immediately |
| 772 // after an Activate(), so just set this state now. | 772 // after an Activate(), so just set this state now. |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 805 | 805 |
| 806 // |has_window_focus_| and |has_pointer_focus_| are mutually exclusive. | 806 // |has_window_focus_| and |has_pointer_focus_| are mutually exclusive. |
| 807 DCHECK(!has_window_focus_ || !has_pointer_focus_); | 807 DCHECK(!has_window_focus_ || !has_pointer_focus_); |
| 808 | 808 |
| 809 return is_active; | 809 return is_active; |
| 810 } | 810 } |
| 811 | 811 |
| 812 void DesktopWindowTreeHostX11::Maximize() { | 812 void DesktopWindowTreeHostX11::Maximize() { |
| 813 if (HasWMSpecProperty("_NET_WM_STATE_FULLSCREEN")) { | 813 if (HasWMSpecProperty("_NET_WM_STATE_FULLSCREEN")) { |
| 814 // Unfullscreen the window if it is fullscreen. | 814 // Unfullscreen the window if it is fullscreen. |
| 815 SetWMSpecState(false, gfx::GetAtom("_NET_WM_STATE_FULLSCREEN"), None); | 815 SetWMSpecState(false, gfx::GetAtom("_NET_WM_STATE_FULLSCREEN"), X11Constants
::None); |
| 816 | 816 |
| 817 // Resize the window so that it does not have the same size as a monitor. | 817 // Resize the window so that it does not have the same size as a monitor. |
| 818 // (Otherwise, some window managers immediately put the window back in | 818 // (Otherwise, some window managers immediately put the window back in |
| 819 // fullscreen mode). | 819 // fullscreen mode). |
| 820 gfx::Rect adjusted_bounds_in_pixels(bounds_in_pixels_.origin(), | 820 gfx::Rect adjusted_bounds_in_pixels(bounds_in_pixels_.origin(), |
| 821 AdjustSize(bounds_in_pixels_.size())); | 821 AdjustSize(bounds_in_pixels_.size())); |
| 822 if (adjusted_bounds_in_pixels != bounds_in_pixels_) | 822 if (adjusted_bounds_in_pixels != bounds_in_pixels_) |
| 823 SetBoundsInPixels(adjusted_bounds_in_pixels); | 823 SetBoundsInPixels(adjusted_bounds_in_pixels); |
| 824 } | 824 } |
| 825 | 825 |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 859 bool DesktopWindowTreeHostX11::IsMinimized() const { | 859 bool DesktopWindowTreeHostX11::IsMinimized() const { |
| 860 return HasWMSpecProperty("_NET_WM_STATE_HIDDEN"); | 860 return HasWMSpecProperty("_NET_WM_STATE_HIDDEN"); |
| 861 } | 861 } |
| 862 | 862 |
| 863 bool DesktopWindowTreeHostX11::HasCapture() const { | 863 bool DesktopWindowTreeHostX11::HasCapture() const { |
| 864 return g_current_capture == this; | 864 return g_current_capture == this; |
| 865 } | 865 } |
| 866 | 866 |
| 867 void DesktopWindowTreeHostX11::SetAlwaysOnTop(bool always_on_top) { | 867 void DesktopWindowTreeHostX11::SetAlwaysOnTop(bool always_on_top) { |
| 868 is_always_on_top_ = always_on_top; | 868 is_always_on_top_ = always_on_top; |
| 869 SetWMSpecState(always_on_top, gfx::GetAtom("_NET_WM_STATE_ABOVE"), None); | 869 SetWMSpecState(always_on_top, gfx::GetAtom("_NET_WM_STATE_ABOVE"), X11Constant
s::None); |
| 870 } | 870 } |
| 871 | 871 |
| 872 bool DesktopWindowTreeHostX11::IsAlwaysOnTop() const { | 872 bool DesktopWindowTreeHostX11::IsAlwaysOnTop() const { |
| 873 return is_always_on_top_; | 873 return is_always_on_top_; |
| 874 } | 874 } |
| 875 | 875 |
| 876 void DesktopWindowTreeHostX11::SetVisibleOnAllWorkspaces(bool always_visible) { | 876 void DesktopWindowTreeHostX11::SetVisibleOnAllWorkspaces(bool always_visible) { |
| 877 SetWMSpecState(always_visible, gfx::GetAtom("_NET_WM_STATE_STICKY"), None); | 877 SetWMSpecState(always_visible, gfx::GetAtom("_NET_WM_STATE_STICKY"), X11Consta
nts::None); |
| 878 | 878 |
| 879 int new_desktop = 0; | 879 int new_desktop = 0; |
| 880 if (always_visible) { | 880 if (always_visible) { |
| 881 new_desktop = kAllDesktops; | 881 new_desktop = kAllDesktops; |
| 882 } else { | 882 } else { |
| 883 if (!ui::GetCurrentDesktop(&new_desktop)) | 883 if (!ui::GetCurrentDesktop(&new_desktop)) |
| 884 return; | 884 return; |
| 885 } | 885 } |
| 886 | 886 |
| 887 workspace_ = base::IntToString(kAllDesktops); | 887 workspace_ = base::IntToString(kAllDesktops); |
| 888 XEvent xevent; | 888 XEvent xevent; |
| 889 memset (&xevent, 0, sizeof (xevent)); | 889 memset (&xevent, 0, sizeof (xevent)); |
| 890 xevent.type = ClientMessage; | 890 xevent.type = ClientMessage; |
| 891 xevent.xclient.window = xwindow_; | 891 xevent.xclient.window = xwindow_; |
| 892 xevent.xclient.message_type = gfx::GetAtom("_NET_WM_DESKTOP"); | 892 xevent.xclient.message_type = gfx::GetAtom("_NET_WM_DESKTOP"); |
| 893 xevent.xclient.format = 32; | 893 xevent.xclient.format = 32; |
| 894 xevent.xclient.data.l[0] = new_desktop; | 894 xevent.xclient.data.l[0] = new_desktop; |
| 895 xevent.xclient.data.l[1] = 0; | 895 xevent.xclient.data.l[1] = 0; |
| 896 xevent.xclient.data.l[2] = 0; | 896 xevent.xclient.data.l[2] = 0; |
| 897 xevent.xclient.data.l[3] = 0; | 897 xevent.xclient.data.l[3] = 0; |
| 898 xevent.xclient.data.l[4] = 0; | 898 xevent.xclient.data.l[4] = 0; |
| 899 XSendEvent(xdisplay_, x_root_window_, False, | 899 XSendEvent(xdisplay_, x_root_window_, X11Constants::False, |
| 900 SubstructureRedirectMask | SubstructureNotifyMask, | 900 SubstructureRedirectMask | SubstructureNotifyMask, &xevent); |
| 901 &xevent); | |
| 902 } | 901 } |
| 903 | 902 |
| 904 bool DesktopWindowTreeHostX11::IsVisibleOnAllWorkspaces() const { | 903 bool DesktopWindowTreeHostX11::IsVisibleOnAllWorkspaces() const { |
| 905 // We don't need a check for _NET_WM_STATE_STICKY because that would specify | 904 // We don't need a check for _NET_WM_STATE_STICKY because that would specify |
| 906 // that the window remain in a fixed position even if the viewport scrolls. | 905 // that the window remain in a fixed position even if the viewport scrolls. |
| 907 // This is different from the type of workspace that's associated with | 906 // This is different from the type of workspace that's associated with |
| 908 // _NET_WM_DESKTOP. | 907 // _NET_WM_DESKTOP. |
| 909 return GetWorkspace() == base::IntToString(kAllDesktops); | 908 return GetWorkspace() == base::IntToString(kAllDesktops); |
| 910 } | 909 } |
| 911 | 910 |
| 912 bool DesktopWindowTreeHostX11::SetWindowTitle(const base::string16& title) { | 911 bool DesktopWindowTreeHostX11::SetWindowTitle(const base::string16& title) { |
| 913 if (window_title_ == title) | 912 if (window_title_ == title) |
| 914 return false; | 913 return false; |
| 915 window_title_ = title; | 914 window_title_ = title; |
| 916 std::string utf8str = base::UTF16ToUTF8(title); | 915 std::string utf8str = base::UTF16ToUTF8(title); |
| 917 XChangeProperty(xdisplay_, xwindow_, gfx::GetAtom("_NET_WM_NAME"), | 916 XChangeProperty(xdisplay_, xwindow_, gfx::GetAtom("_NET_WM_NAME"), |
| 918 gfx::GetAtom("UTF8_STRING"), 8, PropModeReplace, | 917 gfx::GetAtom("UTF8_STRING"), 8, PropModeReplace, |
| 919 reinterpret_cast<const unsigned char*>(utf8str.c_str()), | 918 reinterpret_cast<const unsigned char*>(utf8str.c_str()), |
| 920 utf8str.size()); | 919 utf8str.size()); |
| 921 XTextProperty xtp; | 920 XTextProperty xtp; |
| 922 char* c_utf8_str = const_cast<char*>(utf8str.c_str()); | 921 char* c_utf8_str = const_cast<char*>(utf8str.c_str()); |
| 923 if (Xutf8TextListToTextProperty(xdisplay_, &c_utf8_str, 1, | 922 if (Xutf8TextListToTextProperty(xdisplay_, &c_utf8_str, 1, XUTF8StringStyle, |
| 924 XUTF8StringStyle, &xtp) == Success) { | 923 &xtp) == X11Constants::Success) { |
| 925 XSetWMName(xdisplay_, xwindow_, &xtp); | 924 XSetWMName(xdisplay_, xwindow_, &xtp); |
| 926 XFree(xtp.value); | 925 XFree(xtp.value); |
| 927 } | 926 } |
| 928 return true; | 927 return true; |
| 929 } | 928 } |
| 930 | 929 |
| 931 void DesktopWindowTreeHostX11::ClearNativeFocus() { | 930 void DesktopWindowTreeHostX11::ClearNativeFocus() { |
| 932 // This method is weird and misnamed. Instead of clearing the native focus, | 931 // This method is weird and misnamed. Instead of clearing the native focus, |
| 933 // it sets the focus to our |content_window_|, which will trigger a cascade | 932 // it sets the focus to our |content_window_|, which will trigger a cascade |
| 934 // of focus changes into views. | 933 // of focus changes into views. |
| (...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1005 | 1004 |
| 1006 // Work around a bug where if we try to unfullscreen, metacity immediately | 1005 // Work around a bug where if we try to unfullscreen, metacity immediately |
| 1007 // fullscreens us again. This is a little flickery and not necessary if | 1006 // fullscreens us again. This is a little flickery and not necessary if |
| 1008 // there's a gnome-panel, but it's not easy to detect whether there's a | 1007 // there's a gnome-panel, but it's not easy to detect whether there's a |
| 1009 // panel or not. | 1008 // panel or not. |
| 1010 bool unmaximize_and_remaximize = !fullscreen && IsMaximized() && | 1009 bool unmaximize_and_remaximize = !fullscreen && IsMaximized() && |
| 1011 ui::GuessWindowManager() == ui::WM_METACITY; | 1010 ui::GuessWindowManager() == ui::WM_METACITY; |
| 1012 | 1011 |
| 1013 if (unmaximize_and_remaximize) | 1012 if (unmaximize_and_remaximize) |
| 1014 Restore(); | 1013 Restore(); |
| 1015 SetWMSpecState(fullscreen, gfx::GetAtom("_NET_WM_STATE_FULLSCREEN"), None); | 1014 SetWMSpecState(fullscreen, gfx::GetAtom("_NET_WM_STATE_FULLSCREEN"), X11Consta
nts::None); |
| 1016 if (unmaximize_and_remaximize) | 1015 if (unmaximize_and_remaximize) |
| 1017 Maximize(); | 1016 Maximize(); |
| 1018 | 1017 |
| 1019 // Try to guess the size we will have after the switch to/from fullscreen: | 1018 // Try to guess the size we will have after the switch to/from fullscreen: |
| 1020 // - (may) avoid transient states | 1019 // - (may) avoid transient states |
| 1021 // - works around Flash content which expects to have the size updated | 1020 // - works around Flash content which expects to have the size updated |
| 1022 // synchronously. | 1021 // synchronously. |
| 1023 // See https://crbug.com/361408 | 1022 // See https://crbug.com/361408 |
| 1024 if (fullscreen) { | 1023 if (fullscreen) { |
| 1025 restored_bounds_in_pixels_ = bounds_in_pixels_; | 1024 restored_bounds_in_pixels_ = bounds_in_pixels_; |
| (...skipping 238 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1264 DesktopWindowTreeHostX11* old_capturer = g_current_capture; | 1263 DesktopWindowTreeHostX11* old_capturer = g_current_capture; |
| 1265 | 1264 |
| 1266 // Update |g_current_capture| prior to calling OnHostLostWindowCapture() to | 1265 // Update |g_current_capture| prior to calling OnHostLostWindowCapture() to |
| 1267 // avoid releasing pointer grab. | 1266 // avoid releasing pointer grab. |
| 1268 g_current_capture = this; | 1267 g_current_capture = this; |
| 1269 if (old_capturer) | 1268 if (old_capturer) |
| 1270 old_capturer->OnHostLostWindowCapture(); | 1269 old_capturer->OnHostLostWindowCapture(); |
| 1271 | 1270 |
| 1272 // If the pointer is already in |xwindow_|, we will not get a crossing event | 1271 // If the pointer is already in |xwindow_|, we will not get a crossing event |
| 1273 // with a mode of NotifyGrab, so we must record the grab state manually. | 1272 // with a mode of NotifyGrab, so we must record the grab state manually. |
| 1274 has_pointer_grab_ |= !GrabPointer(xwindow_, true, None); | 1273 has_pointer_grab_ |= !GrabPointer(xwindow_, true, X11Constants::None); |
| 1275 } | 1274 } |
| 1276 | 1275 |
| 1277 void DesktopWindowTreeHostX11::ReleaseCapture() { | 1276 void DesktopWindowTreeHostX11::ReleaseCapture() { |
| 1278 if (g_current_capture == this) { | 1277 if (g_current_capture == this) { |
| 1279 // Release mouse grab asynchronously. A window managed by Chrome is likely | 1278 // Release mouse grab asynchronously. A window managed by Chrome is likely |
| 1280 // the topmost window underneath the mouse so the capture release being | 1279 // the topmost window underneath the mouse so the capture release being |
| 1281 // asynchronous is likely inconsequential. | 1280 // asynchronous is likely inconsequential. |
| 1282 g_current_capture = NULL; | 1281 g_current_capture = NULL; |
| 1283 UngrabPointer(); | 1282 UngrabPointer(); |
| 1284 has_pointer_grab_ = false; | 1283 has_pointer_grab_ = false; |
| 1285 | 1284 |
| 1286 OnHostLostWindowCapture(); | 1285 OnHostLostWindowCapture(); |
| 1287 } | 1286 } |
| 1288 } | 1287 } |
| 1289 | 1288 |
| 1290 void DesktopWindowTreeHostX11::SetCursorNative(gfx::NativeCursor cursor) { | 1289 void DesktopWindowTreeHostX11::SetCursorNative(gfx::NativeCursor cursor) { |
| 1291 XDefineCursor(xdisplay_, xwindow_, cursor.platform()); | 1290 XDefineCursor(xdisplay_, xwindow_, cursor.platform()); |
| 1292 } | 1291 } |
| 1293 | 1292 |
| 1294 void DesktopWindowTreeHostX11::MoveCursorToScreenLocationInPixels( | 1293 void DesktopWindowTreeHostX11::MoveCursorToScreenLocationInPixels( |
| 1295 const gfx::Point& location_in_pixels) { | 1294 const gfx::Point& location_in_pixels) { |
| 1296 XWarpPointer(xdisplay_, None, x_root_window_, 0, 0, 0, 0, | 1295 XWarpPointer(xdisplay_, X11Constants::None, x_root_window_, 0, 0, 0, 0, |
| 1297 bounds_in_pixels_.x() + location_in_pixels.x(), | 1296 bounds_in_pixels_.x() + location_in_pixels.x(), |
| 1298 bounds_in_pixels_.y() + location_in_pixels.y()); | 1297 bounds_in_pixels_.y() + location_in_pixels.y()); |
| 1299 } | 1298 } |
| 1300 | 1299 |
| 1301 void DesktopWindowTreeHostX11::OnCursorVisibilityChangedNative(bool show) { | 1300 void DesktopWindowTreeHostX11::OnCursorVisibilityChangedNative(bool show) { |
| 1302 // TODO(erg): Conditional on us enabling touch on desktop linux builds, do | 1301 // TODO(erg): Conditional on us enabling touch on desktop linux builds, do |
| 1303 // the same tap-to-click disabling here that chromeos does. | 1302 // the same tap-to-click disabling here that chromeos does. |
| 1304 } | 1303 } |
| 1305 | 1304 |
| 1306 //////////////////////////////////////////////////////////////////////////////// | 1305 //////////////////////////////////////////////////////////////////////////////// |
| (...skipping 19 matching lines...) Expand all Loading... |
| 1326 void DesktopWindowTreeHostX11::OnMaximizedStateChanged() {} | 1325 void DesktopWindowTreeHostX11::OnMaximizedStateChanged() {} |
| 1327 | 1326 |
| 1328 //////////////////////////////////////////////////////////////////////////////// | 1327 //////////////////////////////////////////////////////////////////////////////// |
| 1329 // DesktopWindowTreeHostX11, private: | 1328 // DesktopWindowTreeHostX11, private: |
| 1330 | 1329 |
| 1331 void DesktopWindowTreeHostX11::InitX11Window( | 1330 void DesktopWindowTreeHostX11::InitX11Window( |
| 1332 const Widget::InitParams& params) { | 1331 const Widget::InitParams& params) { |
| 1333 unsigned long attribute_mask = CWBackPixmap | CWBitGravity; | 1332 unsigned long attribute_mask = CWBackPixmap | CWBitGravity; |
| 1334 XSetWindowAttributes swa; | 1333 XSetWindowAttributes swa; |
| 1335 memset(&swa, 0, sizeof(swa)); | 1334 memset(&swa, 0, sizeof(swa)); |
| 1336 swa.background_pixmap = None; | 1335 swa.background_pixmap = X11Constants::None; |
| 1337 swa.bit_gravity = NorthWestGravity; | 1336 swa.bit_gravity = NorthWestGravity; |
| 1338 | 1337 |
| 1339 ::Atom window_type; | 1338 ::Atom window_type; |
| 1340 switch (params.type) { | 1339 switch (params.type) { |
| 1341 case Widget::InitParams::TYPE_MENU: | 1340 case Widget::InitParams::TYPE_MENU: |
| 1342 swa.override_redirect = True; | 1341 swa.override_redirect = X11Constants::True; |
| 1343 window_type = gfx::GetAtom("_NET_WM_WINDOW_TYPE_MENU"); | 1342 window_type = gfx::GetAtom("_NET_WM_WINDOW_TYPE_MENU"); |
| 1344 break; | 1343 break; |
| 1345 case Widget::InitParams::TYPE_TOOLTIP: | 1344 case Widget::InitParams::TYPE_TOOLTIP: |
| 1346 swa.override_redirect = True; | 1345 swa.override_redirect = X11Constants::True; |
| 1347 window_type = gfx::GetAtom("_NET_WM_WINDOW_TYPE_TOOLTIP"); | 1346 window_type = gfx::GetAtom("_NET_WM_WINDOW_TYPE_TOOLTIP"); |
| 1348 break; | 1347 break; |
| 1349 case Widget::InitParams::TYPE_POPUP: | 1348 case Widget::InitParams::TYPE_POPUP: |
| 1350 swa.override_redirect = True; | 1349 swa.override_redirect = X11Constants::True; |
| 1351 window_type = gfx::GetAtom("_NET_WM_WINDOW_TYPE_NOTIFICATION"); | 1350 window_type = gfx::GetAtom("_NET_WM_WINDOW_TYPE_NOTIFICATION"); |
| 1352 break; | 1351 break; |
| 1353 case Widget::InitParams::TYPE_DRAG: | 1352 case Widget::InitParams::TYPE_DRAG: |
| 1354 swa.override_redirect = True; | 1353 swa.override_redirect = X11Constants::True; |
| 1355 window_type = gfx::GetAtom("_NET_WM_WINDOW_TYPE_DND"); | 1354 window_type = gfx::GetAtom("_NET_WM_WINDOW_TYPE_DND"); |
| 1356 break; | 1355 break; |
| 1357 default: | 1356 default: |
| 1358 window_type = gfx::GetAtom("_NET_WM_WINDOW_TYPE_NORMAL"); | 1357 window_type = gfx::GetAtom("_NET_WM_WINDOW_TYPE_NORMAL"); |
| 1359 break; | 1358 break; |
| 1360 } | 1359 } |
| 1361 // An in-activatable window should not interact with the system wm. | 1360 // An in-activatable window should not interact with the system wm. |
| 1362 if (!activatable_) | 1361 if (!activatable_) |
| 1363 swa.override_redirect = True; | 1362 swa.override_redirect = X11Constants::True; |
| 1364 | 1363 |
| 1365 if (swa.override_redirect) | 1364 if (swa.override_redirect) |
| 1366 attribute_mask |= CWOverrideRedirect; | 1365 attribute_mask |= CWOverrideRedirect; |
| 1367 | 1366 |
| 1368 bool enable_transparent_visuals; | 1367 bool enable_transparent_visuals; |
| 1369 switch (params.opacity) { | 1368 switch (params.opacity) { |
| 1370 case Widget::InitParams::OPAQUE_WINDOW: | 1369 case Widget::InitParams::OPAQUE_WINDOW: |
| 1371 enable_transparent_visuals = false; | 1370 enable_transparent_visuals = false; |
| 1372 break; | 1371 break; |
| 1373 case Widget::InitParams::TRANSLUCENT_WINDOW: | 1372 case Widget::InitParams::TRANSLUCENT_WINDOW: |
| (...skipping 332 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1706 xclient.xclient.window = xwindow_; | 1705 xclient.xclient.window = xwindow_; |
| 1707 xclient.xclient.message_type = gfx::GetAtom("_NET_WM_STATE"); | 1706 xclient.xclient.message_type = gfx::GetAtom("_NET_WM_STATE"); |
| 1708 xclient.xclient.format = 32; | 1707 xclient.xclient.format = 32; |
| 1709 xclient.xclient.data.l[0] = | 1708 xclient.xclient.data.l[0] = |
| 1710 enabled ? k_NET_WM_STATE_ADD : k_NET_WM_STATE_REMOVE; | 1709 enabled ? k_NET_WM_STATE_ADD : k_NET_WM_STATE_REMOVE; |
| 1711 xclient.xclient.data.l[1] = state1; | 1710 xclient.xclient.data.l[1] = state1; |
| 1712 xclient.xclient.data.l[2] = state2; | 1711 xclient.xclient.data.l[2] = state2; |
| 1713 xclient.xclient.data.l[3] = 1; | 1712 xclient.xclient.data.l[3] = 1; |
| 1714 xclient.xclient.data.l[4] = 0; | 1713 xclient.xclient.data.l[4] = 0; |
| 1715 | 1714 |
| 1716 XSendEvent(xdisplay_, x_root_window_, False, | 1715 XSendEvent(xdisplay_, x_root_window_, X11Constants::False, |
| 1717 SubstructureRedirectMask | SubstructureNotifyMask, | 1716 SubstructureRedirectMask | SubstructureNotifyMask, &xclient); |
| 1718 &xclient); | |
| 1719 } | 1717 } |
| 1720 | 1718 |
| 1721 bool DesktopWindowTreeHostX11::HasWMSpecProperty(const char* property) const { | 1719 bool DesktopWindowTreeHostX11::HasWMSpecProperty(const char* property) const { |
| 1722 return window_properties_.find(gfx::GetAtom(property)) != | 1720 return window_properties_.find(gfx::GetAtom(property)) != |
| 1723 window_properties_.end(); | 1721 window_properties_.end(); |
| 1724 } | 1722 } |
| 1725 | 1723 |
| 1726 void DesktopWindowTreeHostX11::SetUseNativeFrame(bool use_native_frame) { | 1724 void DesktopWindowTreeHostX11::SetUseNativeFrame(bool use_native_frame) { |
| 1727 use_native_frame_ = use_native_frame; | 1725 use_native_frame_ = use_native_frame; |
| 1728 ui::SetUseOSWindowFrame(xwindow_, use_native_frame); | 1726 ui::SetUseOSWindowFrame(xwindow_, use_native_frame); |
| (...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1826 } | 1824 } |
| 1827 } | 1825 } |
| 1828 | 1826 |
| 1829 // If we didn't set the shape for any reason, reset the shaping information. | 1827 // If we didn't set the shape for any reason, reset the shaping information. |
| 1830 // How this is done depends on the border style, due to quirks and bugs in | 1828 // How this is done depends on the border style, due to quirks and bugs in |
| 1831 // various window managers. | 1829 // various window managers. |
| 1832 if (ShouldUseNativeFrame()) { | 1830 if (ShouldUseNativeFrame()) { |
| 1833 // If the window has system borders, the mask must be set to null (not a | 1831 // If the window has system borders, the mask must be set to null (not a |
| 1834 // rectangle), because several window managers (eg, KDE, XFCE, XMonad) will | 1832 // rectangle), because several window managers (eg, KDE, XFCE, XMonad) will |
| 1835 // not put borders on a window with a custom shape. | 1833 // not put borders on a window with a custom shape. |
| 1836 XShapeCombineMask(xdisplay_, xwindow_, ShapeBounding, 0, 0, None, ShapeSet); | 1834 XShapeCombineMask(xdisplay_, xwindow_, ShapeBounding, 0, 0, |
| 1835 X11Constants::None, ShapeSet); |
| 1837 } else { | 1836 } else { |
| 1838 // Conversely, if the window does not have system borders, the mask must be | 1837 // Conversely, if the window does not have system borders, the mask must be |
| 1839 // manually set to a rectangle that covers the whole window (not null). This | 1838 // manually set to a rectangle that covers the whole window (not null). This |
| 1840 // is due to a bug in KWin <= 4.11.5 (KDE bug #330573) where setting a null | 1839 // is due to a bug in KWin <= 4.11.5 (KDE bug #330573) where setting a null |
| 1841 // shape causes the hint to disable system borders to be ignored (resulting | 1840 // shape causes the hint to disable system borders to be ignored (resulting |
| 1842 // in a double border). | 1841 // in a double border). |
| 1843 XRectangle r = {0, | 1842 XRectangle r = {0, |
| 1844 0, | 1843 0, |
| 1845 static_cast<unsigned short>(bounds_in_pixels_.width()), | 1844 static_cast<unsigned short>(bounds_in_pixels_.width()), |
| 1846 static_cast<unsigned short>(bounds_in_pixels_.height())}; | 1845 static_cast<unsigned short>(bounds_in_pixels_.height())}; |
| (...skipping 311 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2158 Atom message_type = xev->xclient.message_type; | 2157 Atom message_type = xev->xclient.message_type; |
| 2159 if (message_type == gfx::GetAtom("WM_PROTOCOLS")) { | 2158 if (message_type == gfx::GetAtom("WM_PROTOCOLS")) { |
| 2160 Atom protocol = static_cast<Atom>(xev->xclient.data.l[0]); | 2159 Atom protocol = static_cast<Atom>(xev->xclient.data.l[0]); |
| 2161 if (protocol == gfx::GetAtom("WM_DELETE_WINDOW")) { | 2160 if (protocol == gfx::GetAtom("WM_DELETE_WINDOW")) { |
| 2162 // We have received a close message from the window manager. | 2161 // We have received a close message from the window manager. |
| 2163 OnHostCloseRequested(); | 2162 OnHostCloseRequested(); |
| 2164 } else if (protocol == gfx::GetAtom("_NET_WM_PING")) { | 2163 } else if (protocol == gfx::GetAtom("_NET_WM_PING")) { |
| 2165 XEvent reply_event = *xev; | 2164 XEvent reply_event = *xev; |
| 2166 reply_event.xclient.window = x_root_window_; | 2165 reply_event.xclient.window = x_root_window_; |
| 2167 | 2166 |
| 2168 XSendEvent(xdisplay_, | 2167 XSendEvent(xdisplay_, reply_event.xclient.window, X11Constants::False, |
| 2169 reply_event.xclient.window, | |
| 2170 False, | |
| 2171 SubstructureRedirectMask | SubstructureNotifyMask, | 2168 SubstructureRedirectMask | SubstructureNotifyMask, |
| 2172 &reply_event); | 2169 &reply_event); |
| 2173 } | 2170 } |
| 2174 } else if (message_type == gfx::GetAtom("XdndEnter")) { | 2171 } else if (message_type == gfx::GetAtom("XdndEnter")) { |
| 2175 drag_drop_client_->OnXdndEnter(xev->xclient); | 2172 drag_drop_client_->OnXdndEnter(xev->xclient); |
| 2176 } else if (message_type == gfx::GetAtom("XdndLeave")) { | 2173 } else if (message_type == gfx::GetAtom("XdndLeave")) { |
| 2177 drag_drop_client_->OnXdndLeave(xev->xclient); | 2174 drag_drop_client_->OnXdndLeave(xev->xclient); |
| 2178 } else if (message_type == gfx::GetAtom("XdndPosition")) { | 2175 } else if (message_type == gfx::GetAtom("XdndPosition")) { |
| 2179 drag_drop_client_->OnXdndPosition(xev->xclient); | 2176 drag_drop_client_->OnXdndPosition(xev->xclient); |
| 2180 } else if (message_type == gfx::GetAtom("XdndStatus")) { | 2177 } else if (message_type == gfx::GetAtom("XdndStatus")) { |
| (...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2328 | 2325 |
| 2329 // static | 2326 // static |
| 2330 DesktopWindowTreeHost* DesktopWindowTreeHost::Create( | 2327 DesktopWindowTreeHost* DesktopWindowTreeHost::Create( |
| 2331 internal::NativeWidgetDelegate* native_widget_delegate, | 2328 internal::NativeWidgetDelegate* native_widget_delegate, |
| 2332 DesktopNativeWidgetAura* desktop_native_widget_aura) { | 2329 DesktopNativeWidgetAura* desktop_native_widget_aura) { |
| 2333 return new DesktopWindowTreeHostX11(native_widget_delegate, | 2330 return new DesktopWindowTreeHostX11(native_widget_delegate, |
| 2334 desktop_native_widget_aura); | 2331 desktop_native_widget_aura); |
| 2335 } | 2332 } |
| 2336 | 2333 |
| 2337 } // namespace views | 2334 } // namespace views |
| OLD | NEW |