| 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 // 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 |
| 1385 void DesktopWindowTreeHostX11::UpdateMinAndMaxSize() { | 1425 void DesktopWindowTreeHostX11::UpdateMinAndMaxSize() { |
| 1386 if (!window_mapped_) | 1426 if (!window_mapped_) |
| 1387 return; | 1427 return; |
| 1388 | 1428 |
| 1389 gfx::Size minimum_in_pixels = | 1429 gfx::Size minimum_in_pixels = |
| 1390 ToPixelRect(gfx::Rect(native_widget_delegate_->GetMinimumSize())).size(); | 1430 ToPixelRect(gfx::Rect(native_widget_delegate_->GetMinimumSize())).size(); |
| 1391 gfx::Size maximum_in_pixels = | 1431 gfx::Size maximum_in_pixels = |
| 1392 ToPixelRect(gfx::Rect(native_widget_delegate_->GetMaximumSize())).size(); | 1432 ToPixelRect(gfx::Rect(native_widget_delegate_->GetMaximumSize())).size(); |
| 1393 if (min_size_in_pixels_ == minimum_in_pixels && | 1433 if (min_size_in_pixels_ == minimum_in_pixels && |
| 1394 max_size_in_pixels_ == maximum_in_pixels) | 1434 max_size_in_pixels_ == maximum_in_pixels) |
| (...skipping 252 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1647 xwindow_, | 1687 xwindow_, |
| 1648 atom_cache_.GetAtom("_NET_WM_USER_TIME"), | 1688 atom_cache_.GetAtom("_NET_WM_USER_TIME"), |
| 1649 XA_CARDINAL, | 1689 XA_CARDINAL, |
| 1650 32, | 1690 32, |
| 1651 PropModeReplace, | 1691 PropModeReplace, |
| 1652 reinterpret_cast<const unsigned char *>(&wm_user_time_ms), | 1692 reinterpret_cast<const unsigned char *>(&wm_user_time_ms), |
| 1653 1); | 1693 1); |
| 1654 } | 1694 } |
| 1655 | 1695 |
| 1656 XMapWindow(xdisplay_, xwindow_); | 1696 XMapWindow(xdisplay_, xwindow_); |
| 1657 | 1697 if (is_override_redirect_) { |
| 1658 // We now block until our window is mapped. Some X11 APIs will crash and | 1698 // Override redirect windows don't get routed through the window manager; |
| 1659 // burn if passed |xwindow_| before the window is mapped, and XMapWindow is | 1699 // we won't reliably get a MapNotify. |
| 1660 // asynchronous. | 1700 OnX11WindowMapped(); |
| 1661 if (ui::X11EventSource::GetInstance()) | 1701 } else { |
| 1662 ui::X11EventSource::GetInstance()->BlockUntilWindowMapped(xwindow_); | 1702 // We now block until our window is mapped. Some X11 APIs will crash and |
| 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 } |
| 1663 } | 1708 } |
| 1664 | 1709 |
| 1665 void DesktopWindowTreeHostX11::SetWindowTransparency() { | 1710 void DesktopWindowTreeHostX11::SetWindowTransparency() { |
| 1666 compositor()->SetHostHasTransparentBackground(use_argb_visual_); | 1711 compositor()->SetHostHasTransparentBackground(use_argb_visual_); |
| 1667 window()->SetTransparent(use_argb_visual_); | 1712 window()->SetTransparent(use_argb_visual_); |
| 1668 content_window_->SetTransparent(use_argb_visual_); | 1713 content_window_->SetTransparent(use_argb_visual_); |
| 1669 } | 1714 } |
| 1670 | 1715 |
| 1671 void DesktopWindowTreeHostX11::Relayout() { | 1716 void DesktopWindowTreeHostX11::Relayout() { |
| 1672 Widget* widget = native_widget_delegate_->AsWidget(); | 1717 Widget* widget = native_widget_delegate_->AsWidget(); |
| (...skipping 193 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1866 default: | 1911 default: |
| 1867 NOTREACHED(); | 1912 NOTREACHED(); |
| 1868 } | 1913 } |
| 1869 | 1914 |
| 1870 // If we coalesced an event we need to free its cookie. | 1915 // If we coalesced an event we need to free its cookie. |
| 1871 if (num_coalesced > 0) | 1916 if (num_coalesced > 0) |
| 1872 XFreeEventData(xev->xgeneric.display, &last_event.xcookie); | 1917 XFreeEventData(xev->xgeneric.display, &last_event.xcookie); |
| 1873 break; | 1918 break; |
| 1874 } | 1919 } |
| 1875 case MapNotify: { | 1920 case MapNotify: { |
| 1876 window_mapped_ = true; | 1921 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; | 1922 break; |
| 1892 } | 1923 } |
| 1893 case UnmapNotify: { | 1924 case UnmapNotify: { |
| 1894 FOR_EACH_OBSERVER(DesktopWindowTreeHostObserverX11, | 1925 OnX11WindowUnmapped(); |
| 1895 observer_list_, | |
| 1896 OnWindowUnmapped(xwindow_)); | |
| 1897 break; | 1926 break; |
| 1898 } | 1927 } |
| 1899 case ClientMessage: { | 1928 case ClientMessage: { |
| 1900 Atom message_type = xev->xclient.message_type; | 1929 Atom message_type = xev->xclient.message_type; |
| 1901 if (message_type == atom_cache_.GetAtom("WM_PROTOCOLS")) { | 1930 if (message_type == atom_cache_.GetAtom("WM_PROTOCOLS")) { |
| 1902 Atom protocol = static_cast<Atom>(xev->xclient.data.l[0]); | 1931 Atom protocol = static_cast<Atom>(xev->xclient.data.l[0]); |
| 1903 if (protocol == atom_cache_.GetAtom("WM_DELETE_WINDOW")) { | 1932 if (protocol == atom_cache_.GetAtom("WM_DELETE_WINDOW")) { |
| 1904 // We have received a close message from the window manager. | 1933 // We have received a close message from the window manager. |
| 1905 OnHostCloseRequested(); | 1934 OnHostCloseRequested(); |
| 1906 } else if (protocol == atom_cache_.GetAtom("_NET_WM_PING")) { | 1935 } 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) { | 2068 if (linux_ui) { |
| 2040 ui::NativeTheme* native_theme = linux_ui->GetNativeTheme(window); | 2069 ui::NativeTheme* native_theme = linux_ui->GetNativeTheme(window); |
| 2041 if (native_theme) | 2070 if (native_theme) |
| 2042 return native_theme; | 2071 return native_theme; |
| 2043 } | 2072 } |
| 2044 | 2073 |
| 2045 return ui::NativeThemeAura::instance(); | 2074 return ui::NativeThemeAura::instance(); |
| 2046 } | 2075 } |
| 2047 | 2076 |
| 2048 } // namespace views | 2077 } // namespace views |
| OLD | NEW |