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 |