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), |
169 use_native_frame_(false), | 170 use_native_frame_(false), |
170 should_maximize_after_map_(false), | 171 should_maximize_after_map_(false), |
171 use_argb_visual_(false), | 172 use_argb_visual_(false), |
172 drag_drop_client_(NULL), | 173 drag_drop_client_(NULL), |
173 native_widget_delegate_(native_widget_delegate), | 174 native_widget_delegate_(native_widget_delegate), |
174 desktop_native_widget_aura_(desktop_native_widget_aura), | 175 desktop_native_widget_aura_(desktop_native_widget_aura), |
175 content_window_(NULL), | 176 content_window_(NULL), |
176 window_parent_(NULL), | 177 window_parent_(NULL), |
177 custom_window_shape_(false), | 178 custom_window_shape_(false), |
178 urgency_hint_set_(false), | 179 urgency_hint_set_(false), |
(...skipping 783 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
962 | 963 |
963 void DesktopWindowTreeHostX11::ShowImpl() { | 964 void DesktopWindowTreeHostX11::ShowImpl() { |
964 ShowWindowWithState(ui::SHOW_STATE_NORMAL); | 965 ShowWindowWithState(ui::SHOW_STATE_NORMAL); |
965 native_widget_delegate_->OnNativeWidgetVisibilityChanged(true); | 966 native_widget_delegate_->OnNativeWidgetVisibilityChanged(true); |
966 } | 967 } |
967 | 968 |
968 void DesktopWindowTreeHostX11::HideImpl() { | 969 void DesktopWindowTreeHostX11::HideImpl() { |
969 if (window_mapped_) { | 970 if (window_mapped_) { |
970 XWithdrawWindow(xdisplay_, xwindow_, 0); | 971 XWithdrawWindow(xdisplay_, xwindow_, 0); |
971 window_mapped_ = false; | 972 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 } |
972 } | 978 } |
973 native_widget_delegate_->OnNativeWidgetVisibilityChanged(false); | 979 native_widget_delegate_->OnNativeWidgetVisibilityChanged(false); |
974 } | 980 } |
975 | 981 |
976 gfx::Rect DesktopWindowTreeHostX11::GetBounds() const { | 982 gfx::Rect DesktopWindowTreeHostX11::GetBounds() const { |
977 return bounds_in_pixels_; | 983 return bounds_in_pixels_; |
978 } | 984 } |
979 | 985 |
980 void DesktopWindowTreeHostX11::SetBounds( | 986 void DesktopWindowTreeHostX11::SetBounds( |
981 const gfx::Rect& requested_bounds_in_pixel) { | 987 const gfx::Rect& requested_bounds_in_pixel) { |
(...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1116 window_type = atom_cache_.GetAtom("_NET_WM_WINDOW_TYPE_NORMAL"); | 1122 window_type = atom_cache_.GetAtom("_NET_WM_WINDOW_TYPE_NORMAL"); |
1117 break; | 1123 break; |
1118 } | 1124 } |
1119 // An in-activatable window should not interact with the system wm. | 1125 // An in-activatable window should not interact with the system wm. |
1120 if (!activatable_) | 1126 if (!activatable_) |
1121 swa.override_redirect = True; | 1127 swa.override_redirect = True; |
1122 | 1128 |
1123 if (swa.override_redirect) | 1129 if (swa.override_redirect) |
1124 attribute_mask |= CWOverrideRedirect; | 1130 attribute_mask |= CWOverrideRedirect; |
1125 | 1131 |
| 1132 is_override_redirect_ = swa.override_redirect; |
| 1133 |
1126 Visual* visual; | 1134 Visual* visual; |
1127 int depth; | 1135 int depth; |
1128 ui::ChooseVisualForWindow(&visual, &depth); | 1136 ui::ChooseVisualForWindow(&visual, &depth); |
1129 if (depth == 32) { | 1137 if (depth == 32) { |
1130 attribute_mask |= CWColormap; | 1138 attribute_mask |= CWColormap; |
1131 swa.colormap = | 1139 swa.colormap = |
1132 XCreateColormap(xdisplay_, x_root_window_, visual, AllocNone); | 1140 XCreateColormap(xdisplay_, x_root_window_, visual, AllocNone); |
1133 | 1141 |
1134 // x.org will BadMatch if we don't set a border when the depth isn't the | 1142 // x.org will BadMatch if we don't set a border when the depth isn't the |
1135 // same as the parent depth. | 1143 // same as the parent depth. |
(...skipping 239 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1375 if (ui::GetIntArrayProperty(xwindow_, "_NET_FRAME_EXTENTS", &insets) && | 1383 if (ui::GetIntArrayProperty(xwindow_, "_NET_FRAME_EXTENTS", &insets) && |
1376 insets.size() == 4) { | 1384 insets.size() == 4) { |
1377 // |insets| are returned in the order: [left, right, top, bottom]. | 1385 // |insets| are returned in the order: [left, right, top, bottom]. |
1378 native_window_frame_borders_in_pixels_ = | 1386 native_window_frame_borders_in_pixels_ = |
1379 gfx::Insets(insets[2], insets[0], insets[3], insets[1]); | 1387 gfx::Insets(insets[2], insets[0], insets[3], insets[1]); |
1380 } else { | 1388 } else { |
1381 native_window_frame_borders_in_pixels_ = gfx::Insets(); | 1389 native_window_frame_borders_in_pixels_ = gfx::Insets(); |
1382 } | 1390 } |
1383 } | 1391 } |
1384 | 1392 |
| 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 |
| 1412 void DesktopWindowTreeHostX11::OnX11WindowUnmapped() { |
| 1413 window_mapped_ = false; |
| 1414 FOR_EACH_OBSERVER(DesktopWindowTreeHostObserverX11, |
| 1415 observer_list_, |
| 1416 OnWindowUnmapped(xwindow_)); |
| 1417 } |
| 1418 |
1385 void DesktopWindowTreeHostX11::UpdateMinAndMaxSize() { | 1419 void DesktopWindowTreeHostX11::UpdateMinAndMaxSize() { |
1386 if (!window_mapped_) | 1420 if (!window_mapped_) |
1387 return; | 1421 return; |
1388 | 1422 |
1389 gfx::Size minimum_in_pixels = | 1423 gfx::Size minimum_in_pixels = |
1390 ToPixelRect(gfx::Rect(native_widget_delegate_->GetMinimumSize())).size(); | 1424 ToPixelRect(gfx::Rect(native_widget_delegate_->GetMinimumSize())).size(); |
1391 gfx::Size maximum_in_pixels = | 1425 gfx::Size maximum_in_pixels = |
1392 ToPixelRect(gfx::Rect(native_widget_delegate_->GetMaximumSize())).size(); | 1426 ToPixelRect(gfx::Rect(native_widget_delegate_->GetMaximumSize())).size(); |
1393 if (min_size_in_pixels_ == minimum_in_pixels && | 1427 if (min_size_in_pixels_ == minimum_in_pixels && |
1394 max_size_in_pixels_ == maximum_in_pixels) | 1428 max_size_in_pixels_ == maximum_in_pixels) |
(...skipping 252 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1647 xwindow_, | 1681 xwindow_, |
1648 atom_cache_.GetAtom("_NET_WM_USER_TIME"), | 1682 atom_cache_.GetAtom("_NET_WM_USER_TIME"), |
1649 XA_CARDINAL, | 1683 XA_CARDINAL, |
1650 32, | 1684 32, |
1651 PropModeReplace, | 1685 PropModeReplace, |
1652 reinterpret_cast<const unsigned char *>(&wm_user_time_ms), | 1686 reinterpret_cast<const unsigned char *>(&wm_user_time_ms), |
1653 1); | 1687 1); |
1654 } | 1688 } |
1655 | 1689 |
1656 XMapWindow(xdisplay_, xwindow_); | 1690 XMapWindow(xdisplay_, xwindow_); |
1657 | 1691 if (is_override_redirect_) { |
1658 // We now block until our window is mapped. Some X11 APIs will crash and | 1692 // Override redirect windows don't get routed through the window manager; |
1659 // burn if passed |xwindow_| before the window is mapped, and XMapWindow is | 1693 // we won't reliably get a MapNotify. |
1660 // asynchronous. | 1694 OnX11WindowMapped(); |
1661 if (ui::X11EventSource::GetInstance()) | 1695 } else { |
1662 ui::X11EventSource::GetInstance()->BlockUntilWindowMapped(xwindow_); | 1696 // We now block until our window is mapped. Some X11 APIs will crash and |
| 1697 // burn if passed |xwindow_| before the window is mapped, and XMapWindow is |
| 1698 // asynchronous. |
| 1699 if (ui::X11EventSource::GetInstance()) |
| 1700 ui::X11EventSource::GetInstance()->BlockUntilWindowMapped(xwindow_); |
| 1701 } |
1663 } | 1702 } |
1664 | 1703 |
1665 void DesktopWindowTreeHostX11::SetWindowTransparency() { | 1704 void DesktopWindowTreeHostX11::SetWindowTransparency() { |
1666 compositor()->SetHostHasTransparentBackground(use_argb_visual_); | 1705 compositor()->SetHostHasTransparentBackground(use_argb_visual_); |
1667 window()->SetTransparent(use_argb_visual_); | 1706 window()->SetTransparent(use_argb_visual_); |
1668 content_window_->SetTransparent(use_argb_visual_); | 1707 content_window_->SetTransparent(use_argb_visual_); |
1669 } | 1708 } |
1670 | 1709 |
1671 void DesktopWindowTreeHostX11::Relayout() { | 1710 void DesktopWindowTreeHostX11::Relayout() { |
1672 Widget* widget = native_widget_delegate_->AsWidget(); | 1711 Widget* widget = native_widget_delegate_->AsWidget(); |
(...skipping 193 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1866 default: | 1905 default: |
1867 NOTREACHED(); | 1906 NOTREACHED(); |
1868 } | 1907 } |
1869 | 1908 |
1870 // If we coalesced an event we need to free its cookie. | 1909 // If we coalesced an event we need to free its cookie. |
1871 if (num_coalesced > 0) | 1910 if (num_coalesced > 0) |
1872 XFreeEventData(xev->xgeneric.display, &last_event.xcookie); | 1911 XFreeEventData(xev->xgeneric.display, &last_event.xcookie); |
1873 break; | 1912 break; |
1874 } | 1913 } |
1875 case MapNotify: { | 1914 case MapNotify: { |
1876 window_mapped_ = true; | 1915 OnX11WindowMapped(); |
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 | |
1891 break; | 1916 break; |
1892 } | 1917 } |
1893 case UnmapNotify: { | 1918 case UnmapNotify: { |
1894 FOR_EACH_OBSERVER(DesktopWindowTreeHostObserverX11, | 1919 OnX11WindowUnmapped(); |
1895 observer_list_, | |
1896 OnWindowUnmapped(xwindow_)); | |
1897 break; | 1920 break; |
1898 } | 1921 } |
1899 case ClientMessage: { | 1922 case ClientMessage: { |
1900 Atom message_type = xev->xclient.message_type; | 1923 Atom message_type = xev->xclient.message_type; |
1901 if (message_type == atom_cache_.GetAtom("WM_PROTOCOLS")) { | 1924 if (message_type == atom_cache_.GetAtom("WM_PROTOCOLS")) { |
1902 Atom protocol = static_cast<Atom>(xev->xclient.data.l[0]); | 1925 Atom protocol = static_cast<Atom>(xev->xclient.data.l[0]); |
1903 if (protocol == atom_cache_.GetAtom("WM_DELETE_WINDOW")) { | 1926 if (protocol == atom_cache_.GetAtom("WM_DELETE_WINDOW")) { |
1904 // We have received a close message from the window manager. | 1927 // We have received a close message from the window manager. |
1905 OnHostCloseRequested(); | 1928 OnHostCloseRequested(); |
1906 } else if (protocol == atom_cache_.GetAtom("_NET_WM_PING")) { | 1929 } else if (protocol == atom_cache_.GetAtom("_NET_WM_PING")) { |
(...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2039 if (linux_ui) { | 2062 if (linux_ui) { |
2040 ui::NativeTheme* native_theme = linux_ui->GetNativeTheme(window); | 2063 ui::NativeTheme* native_theme = linux_ui->GetNativeTheme(window); |
2041 if (native_theme) | 2064 if (native_theme) |
2042 return native_theme; | 2065 return native_theme; |
2043 } | 2066 } |
2044 | 2067 |
2045 return ui::NativeThemeAura::instance(); | 2068 return ui::NativeThemeAura::instance(); |
2046 } | 2069 } |
2047 | 2070 |
2048 } // namespace views | 2071 } // namespace views |
OLD | NEW |