| 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/Xatom.h> | 7 #include <X11/Xatom.h> |
| 8 #include <X11/Xregion.h> | 8 #include <X11/Xregion.h> |
| 9 #include <X11/Xutil.h> | 9 #include <X11/Xutil.h> |
| 10 #include <X11/extensions/XInput2.h> | 10 #include <X11/extensions/XInput2.h> |
| (...skipping 148 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 159 DesktopWindowTreeHostX11::DesktopWindowTreeHostX11( | 159 DesktopWindowTreeHostX11::DesktopWindowTreeHostX11( |
| 160 internal::NativeWidgetDelegate* native_widget_delegate, | 160 internal::NativeWidgetDelegate* native_widget_delegate, |
| 161 DesktopNativeWidgetAura* desktop_native_widget_aura) | 161 DesktopNativeWidgetAura* desktop_native_widget_aura) |
| 162 : xdisplay_(gfx::GetXDisplay()), | 162 : xdisplay_(gfx::GetXDisplay()), |
| 163 xwindow_(0), | 163 xwindow_(0), |
| 164 x_root_window_(DefaultRootWindow(xdisplay_)), | 164 x_root_window_(DefaultRootWindow(xdisplay_)), |
| 165 atom_cache_(xdisplay_, kAtomsToCache), | 165 atom_cache_(xdisplay_, kAtomsToCache), |
| 166 window_mapped_(false), | 166 window_mapped_(false), |
| 167 is_fullscreen_(false), | 167 is_fullscreen_(false), |
| 168 is_always_on_top_(false), | 168 is_always_on_top_(false), |
| 169 is_override_redirect_(false), | |
| 170 use_native_frame_(false), | 169 use_native_frame_(false), |
| 171 should_maximize_after_map_(false), | 170 should_maximize_after_map_(false), |
| 172 use_argb_visual_(false), | 171 use_argb_visual_(false), |
| 173 drag_drop_client_(NULL), | 172 drag_drop_client_(NULL), |
| 174 native_widget_delegate_(native_widget_delegate), | 173 native_widget_delegate_(native_widget_delegate), |
| 175 desktop_native_widget_aura_(desktop_native_widget_aura), | 174 desktop_native_widget_aura_(desktop_native_widget_aura), |
| 176 content_window_(NULL), | 175 content_window_(NULL), |
| 177 window_parent_(NULL), | 176 window_parent_(NULL), |
| 178 custom_window_shape_(false), | 177 custom_window_shape_(false), |
| 179 urgency_hint_set_(false), | 178 urgency_hint_set_(false), |
| (...skipping 783 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 963 | 962 |
| 964 void DesktopWindowTreeHostX11::ShowImpl() { | 963 void DesktopWindowTreeHostX11::ShowImpl() { |
| 965 ShowWindowWithState(ui::SHOW_STATE_NORMAL); | 964 ShowWindowWithState(ui::SHOW_STATE_NORMAL); |
| 966 native_widget_delegate_->OnNativeWidgetVisibilityChanged(true); | 965 native_widget_delegate_->OnNativeWidgetVisibilityChanged(true); |
| 967 } | 966 } |
| 968 | 967 |
| 969 void DesktopWindowTreeHostX11::HideImpl() { | 968 void DesktopWindowTreeHostX11::HideImpl() { |
| 970 if (window_mapped_) { | 969 if (window_mapped_) { |
| 971 XWithdrawWindow(xdisplay_, xwindow_, 0); | 970 XWithdrawWindow(xdisplay_, xwindow_, 0); |
| 972 window_mapped_ = false; | 971 window_mapped_ = false; |
| 973 if (is_override_redirect_) { | |
| 974 // If we're override-redirect, we won't receive an UnmapNotify message, | |
| 975 // so run the unmap handler directly. | |
| 976 OnX11WindowUnmapped(); | |
| 977 } | |
| 978 } | 972 } |
| 979 native_widget_delegate_->OnNativeWidgetVisibilityChanged(false); | 973 native_widget_delegate_->OnNativeWidgetVisibilityChanged(false); |
| 980 } | 974 } |
| 981 | 975 |
| 982 gfx::Rect DesktopWindowTreeHostX11::GetBounds() const { | 976 gfx::Rect DesktopWindowTreeHostX11::GetBounds() const { |
| 983 return bounds_in_pixels_; | 977 return bounds_in_pixels_; |
| 984 } | 978 } |
| 985 | 979 |
| 986 void DesktopWindowTreeHostX11::SetBounds( | 980 void DesktopWindowTreeHostX11::SetBounds( |
| 987 const gfx::Rect& requested_bounds_in_pixel) { | 981 const gfx::Rect& requested_bounds_in_pixel) { |
| (...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1122 window_type = atom_cache_.GetAtom("_NET_WM_WINDOW_TYPE_NORMAL"); | 1116 window_type = atom_cache_.GetAtom("_NET_WM_WINDOW_TYPE_NORMAL"); |
| 1123 break; | 1117 break; |
| 1124 } | 1118 } |
| 1125 // An in-activatable window should not interact with the system wm. | 1119 // An in-activatable window should not interact with the system wm. |
| 1126 if (!activatable_) | 1120 if (!activatable_) |
| 1127 swa.override_redirect = True; | 1121 swa.override_redirect = True; |
| 1128 | 1122 |
| 1129 if (swa.override_redirect) | 1123 if (swa.override_redirect) |
| 1130 attribute_mask |= CWOverrideRedirect; | 1124 attribute_mask |= CWOverrideRedirect; |
| 1131 | 1125 |
| 1132 is_override_redirect_ = swa.override_redirect; | |
| 1133 | |
| 1134 Visual* visual; | 1126 Visual* visual; |
| 1135 int depth; | 1127 int depth; |
| 1136 ui::ChooseVisualForWindow(&visual, &depth); | 1128 ui::ChooseVisualForWindow(&visual, &depth); |
| 1137 if (depth == 32) { | 1129 if (depth == 32) { |
| 1138 attribute_mask |= CWColormap; | 1130 attribute_mask |= CWColormap; |
| 1139 swa.colormap = | 1131 swa.colormap = |
| 1140 XCreateColormap(xdisplay_, x_root_window_, visual, AllocNone); | 1132 XCreateColormap(xdisplay_, x_root_window_, visual, AllocNone); |
| 1141 | 1133 |
| 1142 // x.org will BadMatch if we don't set a border when the depth isn't the | 1134 // x.org will BadMatch if we don't set a border when the depth isn't the |
| 1143 // same as the parent depth. | 1135 // same as the parent depth. |
| (...skipping 239 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1383 if (ui::GetIntArrayProperty(xwindow_, "_NET_FRAME_EXTENTS", &insets) && | 1375 if (ui::GetIntArrayProperty(xwindow_, "_NET_FRAME_EXTENTS", &insets) && |
| 1384 insets.size() == 4) { | 1376 insets.size() == 4) { |
| 1385 // |insets| are returned in the order: [left, right, top, bottom]. | 1377 // |insets| are returned in the order: [left, right, top, bottom]. |
| 1386 native_window_frame_borders_in_pixels_ = | 1378 native_window_frame_borders_in_pixels_ = |
| 1387 gfx::Insets(insets[2], insets[0], insets[3], insets[1]); | 1379 gfx::Insets(insets[2], insets[0], insets[3], insets[1]); |
| 1388 } else { | 1380 } else { |
| 1389 native_window_frame_borders_in_pixels_ = gfx::Insets(); | 1381 native_window_frame_borders_in_pixels_ = gfx::Insets(); |
| 1390 } | 1382 } |
| 1391 } | 1383 } |
| 1392 | 1384 |
| 1393 void DesktopWindowTreeHostX11::OnX11WindowMapped() { | |
| 1394 if (!window_mapped_) { | |
| 1395 window_mapped_ = true; | |
| 1396 | |
| 1397 FOR_EACH_OBSERVER(DesktopWindowTreeHostObserverX11, | |
| 1398 observer_list_, | |
| 1399 OnWindowMapped(xwindow_)); | |
| 1400 | |
| 1401 UpdateMinAndMaxSize(); | |
| 1402 | |
| 1403 // Some WMs only respect maximize hints after the window has been mapped. | |
| 1404 // Check whether we need to re-do a maximization. | |
| 1405 if (should_maximize_after_map_) { | |
| 1406 Maximize(); | |
| 1407 should_maximize_after_map_ = false; | |
| 1408 } | |
| 1409 } | |
| 1410 | |
| 1411 // If we're an override redirect window, we need to perform a full redraw | |
| 1412 // because on AMD drivers we might get a MapNotify event after performing the | |
| 1413 // initial draw, which can result in a blank window. crbug.com/606661. | |
| 1414 if (is_override_redirect_) | |
| 1415 compositor()->ScheduleFullRedraw(); | |
| 1416 } | |
| 1417 | |
| 1418 void DesktopWindowTreeHostX11::OnX11WindowUnmapped() { | |
| 1419 window_mapped_ = false; | |
| 1420 FOR_EACH_OBSERVER(DesktopWindowTreeHostObserverX11, | |
| 1421 observer_list_, | |
| 1422 OnWindowUnmapped(xwindow_)); | |
| 1423 } | |
| 1424 | |
| 1425 void DesktopWindowTreeHostX11::UpdateMinAndMaxSize() { | 1385 void DesktopWindowTreeHostX11::UpdateMinAndMaxSize() { |
| 1426 if (!window_mapped_) | 1386 if (!window_mapped_) |
| 1427 return; | 1387 return; |
| 1428 | 1388 |
| 1429 gfx::Size minimum_in_pixels = | 1389 gfx::Size minimum_in_pixels = |
| 1430 ToPixelRect(gfx::Rect(native_widget_delegate_->GetMinimumSize())).size(); | 1390 ToPixelRect(gfx::Rect(native_widget_delegate_->GetMinimumSize())).size(); |
| 1431 gfx::Size maximum_in_pixels = | 1391 gfx::Size maximum_in_pixels = |
| 1432 ToPixelRect(gfx::Rect(native_widget_delegate_->GetMaximumSize())).size(); | 1392 ToPixelRect(gfx::Rect(native_widget_delegate_->GetMaximumSize())).size(); |
| 1433 if (min_size_in_pixels_ == minimum_in_pixels && | 1393 if (min_size_in_pixels_ == minimum_in_pixels && |
| 1434 max_size_in_pixels_ == maximum_in_pixels) | 1394 max_size_in_pixels_ == maximum_in_pixels) |
| (...skipping 252 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1687 xwindow_, | 1647 xwindow_, |
| 1688 atom_cache_.GetAtom("_NET_WM_USER_TIME"), | 1648 atom_cache_.GetAtom("_NET_WM_USER_TIME"), |
| 1689 XA_CARDINAL, | 1649 XA_CARDINAL, |
| 1690 32, | 1650 32, |
| 1691 PropModeReplace, | 1651 PropModeReplace, |
| 1692 reinterpret_cast<const unsigned char *>(&wm_user_time_ms), | 1652 reinterpret_cast<const unsigned char *>(&wm_user_time_ms), |
| 1693 1); | 1653 1); |
| 1694 } | 1654 } |
| 1695 | 1655 |
| 1696 XMapWindow(xdisplay_, xwindow_); | 1656 XMapWindow(xdisplay_, xwindow_); |
| 1697 if (is_override_redirect_) { | 1657 |
| 1698 // Override redirect windows don't get routed through the window manager; | 1658 // We now block until our window is mapped. Some X11 APIs will crash and |
| 1699 // we won't reliably get a MapNotify. | 1659 // burn if passed |xwindow_| before the window is mapped, and XMapWindow is |
| 1700 OnX11WindowMapped(); | 1660 // asynchronous. |
| 1701 } else { | 1661 if (ui::X11EventSource::GetInstance()) |
| 1702 // We now block until our window is mapped. Some X11 APIs will crash and | 1662 ui::X11EventSource::GetInstance()->BlockUntilWindowMapped(xwindow_); |
| 1703 // burn if passed |xwindow_| before the window is mapped, and XMapWindow is | |
| 1704 // asynchronous. | |
| 1705 if (ui::X11EventSource::GetInstance()) | |
| 1706 ui::X11EventSource::GetInstance()->BlockUntilWindowMapped(xwindow_); | |
| 1707 } | |
| 1708 } | 1663 } |
| 1709 | 1664 |
| 1710 void DesktopWindowTreeHostX11::SetWindowTransparency() { | 1665 void DesktopWindowTreeHostX11::SetWindowTransparency() { |
| 1711 compositor()->SetHostHasTransparentBackground(use_argb_visual_); | 1666 compositor()->SetHostHasTransparentBackground(use_argb_visual_); |
| 1712 window()->SetTransparent(use_argb_visual_); | 1667 window()->SetTransparent(use_argb_visual_); |
| 1713 content_window_->SetTransparent(use_argb_visual_); | 1668 content_window_->SetTransparent(use_argb_visual_); |
| 1714 } | 1669 } |
| 1715 | 1670 |
| 1716 void DesktopWindowTreeHostX11::Relayout() { | 1671 void DesktopWindowTreeHostX11::Relayout() { |
| 1717 Widget* widget = native_widget_delegate_->AsWidget(); | 1672 Widget* widget = native_widget_delegate_->AsWidget(); |
| (...skipping 193 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1911 default: | 1866 default: |
| 1912 NOTREACHED(); | 1867 NOTREACHED(); |
| 1913 } | 1868 } |
| 1914 | 1869 |
| 1915 // If we coalesced an event we need to free its cookie. | 1870 // If we coalesced an event we need to free its cookie. |
| 1916 if (num_coalesced > 0) | 1871 if (num_coalesced > 0) |
| 1917 XFreeEventData(xev->xgeneric.display, &last_event.xcookie); | 1872 XFreeEventData(xev->xgeneric.display, &last_event.xcookie); |
| 1918 break; | 1873 break; |
| 1919 } | 1874 } |
| 1920 case MapNotify: { | 1875 case MapNotify: { |
| 1921 OnX11WindowMapped(); | 1876 window_mapped_ = true; |
| 1877 |
| 1878 FOR_EACH_OBSERVER(DesktopWindowTreeHostObserverX11, |
| 1879 observer_list_, |
| 1880 OnWindowMapped(xwindow_)); |
| 1881 |
| 1882 UpdateMinAndMaxSize(); |
| 1883 |
| 1884 // Some WMs only respect maximize hints after the window has been mapped. |
| 1885 // Check whether we need to re-do a maximization. |
| 1886 if (should_maximize_after_map_) { |
| 1887 Maximize(); |
| 1888 should_maximize_after_map_ = false; |
| 1889 } |
| 1890 |
| 1922 break; | 1891 break; |
| 1923 } | 1892 } |
| 1924 case UnmapNotify: { | 1893 case UnmapNotify: { |
| 1925 OnX11WindowUnmapped(); | 1894 FOR_EACH_OBSERVER(DesktopWindowTreeHostObserverX11, |
| 1895 observer_list_, |
| 1896 OnWindowUnmapped(xwindow_)); |
| 1926 break; | 1897 break; |
| 1927 } | 1898 } |
| 1928 case ClientMessage: { | 1899 case ClientMessage: { |
| 1929 Atom message_type = xev->xclient.message_type; | 1900 Atom message_type = xev->xclient.message_type; |
| 1930 if (message_type == atom_cache_.GetAtom("WM_PROTOCOLS")) { | 1901 if (message_type == atom_cache_.GetAtom("WM_PROTOCOLS")) { |
| 1931 Atom protocol = static_cast<Atom>(xev->xclient.data.l[0]); | 1902 Atom protocol = static_cast<Atom>(xev->xclient.data.l[0]); |
| 1932 if (protocol == atom_cache_.GetAtom("WM_DELETE_WINDOW")) { | 1903 if (protocol == atom_cache_.GetAtom("WM_DELETE_WINDOW")) { |
| 1933 // We have received a close message from the window manager. | 1904 // We have received a close message from the window manager. |
| 1934 OnHostCloseRequested(); | 1905 OnHostCloseRequested(); |
| 1935 } else if (protocol == atom_cache_.GetAtom("_NET_WM_PING")) { | 1906 } else if (protocol == atom_cache_.GetAtom("_NET_WM_PING")) { |
| (...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2068 if (linux_ui) { | 2039 if (linux_ui) { |
| 2069 ui::NativeTheme* native_theme = linux_ui->GetNativeTheme(window); | 2040 ui::NativeTheme* native_theme = linux_ui->GetNativeTheme(window); |
| 2070 if (native_theme) | 2041 if (native_theme) |
| 2071 return native_theme; | 2042 return native_theme; |
| 2072 } | 2043 } |
| 2073 | 2044 |
| 2074 return ui::NativeThemeAura::instance(); | 2045 return ui::NativeThemeAura::instance(); |
| 2075 } | 2046 } |
| 2076 | 2047 |
| 2077 } // namespace views | 2048 } // namespace views |
| OLD | NEW |