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 170 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
181 // DesktopWindowTreeHostX11, public: | 181 // DesktopWindowTreeHostX11, public: |
182 | 182 |
183 DesktopWindowTreeHostX11::DesktopWindowTreeHostX11( | 183 DesktopWindowTreeHostX11::DesktopWindowTreeHostX11( |
184 internal::NativeWidgetDelegate* native_widget_delegate, | 184 internal::NativeWidgetDelegate* native_widget_delegate, |
185 DesktopNativeWidgetAura* desktop_native_widget_aura) | 185 DesktopNativeWidgetAura* desktop_native_widget_aura) |
186 : xdisplay_(gfx::GetXDisplay()), | 186 : xdisplay_(gfx::GetXDisplay()), |
187 xwindow_(0), | 187 xwindow_(0), |
188 x_root_window_(DefaultRootWindow(xdisplay_)), | 188 x_root_window_(DefaultRootWindow(xdisplay_)), |
189 atom_cache_(xdisplay_, kAtomsToCache), | 189 atom_cache_(xdisplay_, kAtomsToCache), |
190 window_mapped_(false), | 190 window_mapped_(false), |
191 wait_for_unmap_(false), | 191 is_visible_(false), |
192 is_fullscreen_(false), | 192 is_fullscreen_(false), |
193 is_always_on_top_(false), | 193 is_always_on_top_(false), |
194 use_native_frame_(false), | 194 use_native_frame_(false), |
195 should_maximize_after_map_(false), | 195 should_maximize_after_map_(false), |
196 use_argb_visual_(false), | 196 use_argb_visual_(false), |
197 drag_drop_client_(NULL), | 197 drag_drop_client_(NULL), |
198 native_widget_delegate_(native_widget_delegate), | 198 native_widget_delegate_(native_widget_delegate), |
199 desktop_native_widget_aura_(desktop_native_widget_aura), | 199 desktop_native_widget_aura_(desktop_native_widget_aura), |
200 content_window_(NULL), | 200 content_window_(NULL), |
201 window_parent_(NULL), | 201 window_parent_(NULL), |
(...skipping 384 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
586 | 586 |
587 void DesktopWindowTreeHostX11::ShowMaximizedWithBounds( | 587 void DesktopWindowTreeHostX11::ShowMaximizedWithBounds( |
588 const gfx::Rect& restored_bounds) { | 588 const gfx::Rect& restored_bounds) { |
589 ShowWindowWithState(ui::SHOW_STATE_MAXIMIZED); | 589 ShowWindowWithState(ui::SHOW_STATE_MAXIMIZED); |
590 // Enforce |restored_bounds_in_pixels_| since calling Maximize() could have | 590 // Enforce |restored_bounds_in_pixels_| since calling Maximize() could have |
591 // reset it. | 591 // reset it. |
592 restored_bounds_in_pixels_ = ToPixelRect(restored_bounds); | 592 restored_bounds_in_pixels_ = ToPixelRect(restored_bounds); |
593 } | 593 } |
594 | 594 |
595 bool DesktopWindowTreeHostX11::IsVisible() const { | 595 bool DesktopWindowTreeHostX11::IsVisible() const { |
596 return window_mapped_ && !wait_for_unmap_; | 596 return is_visible_; |
597 } | 597 } |
598 | 598 |
599 void DesktopWindowTreeHostX11::SetSize(const gfx::Size& requested_size) { | 599 void DesktopWindowTreeHostX11::SetSize(const gfx::Size& requested_size) { |
600 gfx::Size size_in_pixels = ToPixelRect(gfx::Rect(requested_size)).size(); | 600 gfx::Size size_in_pixels = ToPixelRect(gfx::Rect(requested_size)).size(); |
601 size_in_pixels = AdjustSize(size_in_pixels); | 601 size_in_pixels = AdjustSize(size_in_pixels); |
602 bool size_changed = bounds_in_pixels_.size() != size_in_pixels; | 602 bool size_changed = bounds_in_pixels_.size() != size_in_pixels; |
603 XResizeWindow(xdisplay_, xwindow_, size_in_pixels.width(), | 603 XResizeWindow(xdisplay_, xwindow_, size_in_pixels.width(), |
604 size_in_pixels.height()); | 604 size_in_pixels.height()); |
605 bounds_in_pixels_.set_size(size_in_pixels); | 605 bounds_in_pixels_.set_size(size_in_pixels); |
606 if (size_changed) { | 606 if (size_changed) { |
(...skipping 599 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1206 return xwindow_; | 1206 return xwindow_; |
1207 } | 1207 } |
1208 | 1208 |
1209 void DesktopWindowTreeHostX11::ShowImpl() { | 1209 void DesktopWindowTreeHostX11::ShowImpl() { |
1210 ShowWindowWithState(ui::SHOW_STATE_NORMAL); | 1210 ShowWindowWithState(ui::SHOW_STATE_NORMAL); |
1211 native_widget_delegate_->OnNativeWidgetVisibilityChanged(true); | 1211 native_widget_delegate_->OnNativeWidgetVisibilityChanged(true); |
1212 } | 1212 } |
1213 | 1213 |
1214 void DesktopWindowTreeHostX11::HideImpl() { | 1214 void DesktopWindowTreeHostX11::HideImpl() { |
1215 if (IsVisible()) { | 1215 if (IsVisible()) { |
1216 XWithdrawWindow(xdisplay_, xwindow_, 0); | 1216 XWithdrawWindow(xdisplay_, xwindow_, 0); |
Daniel Erat
2017/03/09 15:07:22
this also unmaps the window, right? is there a rea
Tom (Use chromium acct)
2017/03/10 01:29:57
Before, we had wait_for_unmap_ that sort of did th
| |
1217 wait_for_unmap_ = true; | 1217 is_visible_ = false; |
1218 } | 1218 } |
1219 native_widget_delegate_->OnNativeWidgetVisibilityChanged(false); | 1219 native_widget_delegate_->OnNativeWidgetVisibilityChanged(false); |
1220 } | 1220 } |
1221 | 1221 |
1222 gfx::Rect DesktopWindowTreeHostX11::GetBoundsInPixels() const { | 1222 gfx::Rect DesktopWindowTreeHostX11::GetBoundsInPixels() const { |
1223 return bounds_in_pixels_; | 1223 return bounds_in_pixels_; |
1224 } | 1224 } |
1225 | 1225 |
1226 void DesktopWindowTreeHostX11::SetBoundsInPixels( | 1226 void DesktopWindowTreeHostX11::SetBoundsInPixels( |
1227 const gfx::Rect& requested_bounds_in_pixel) { | 1227 const gfx::Rect& requested_bounds_in_pixel) { |
1228 gfx::Rect bounds_in_pixels(requested_bounds_in_pixel.origin(), | 1228 gfx::Rect bounds_in_pixels(requested_bounds_in_pixel.origin(), |
1229 AdjustSize(requested_bounds_in_pixel.size())); | 1229 AdjustSize(requested_bounds_in_pixel.size())); |
1230 bool origin_changed = bounds_in_pixels_.origin() != bounds_in_pixels.origin(); | 1230 bool origin_changed = bounds_in_pixels_.origin() != bounds_in_pixels.origin(); |
1231 bool size_changed = bounds_in_pixels_.size() != bounds_in_pixels.size(); | 1231 bool size_changed = bounds_in_pixels_.size() != bounds_in_pixels.size(); |
1232 XWindowChanges changes = {0}; | 1232 XWindowChanges changes = {0}; |
1233 unsigned value_mask = 0; | 1233 unsigned value_mask = 0; |
1234 | 1234 |
1235 delayed_resize_task_.Cancel(); | |
1236 | 1235 |
1237 if (size_changed) { | 1236 if (size_changed) { |
1237 // Only cancel the delayed resize task if we're already about to call | |
1238 // OnHostResized in this function. | |
1239 delayed_resize_task_.Cancel(); | |
1240 | |
1238 // Update the minimum and maximum sizes in case they have changed. | 1241 // Update the minimum and maximum sizes in case they have changed. |
1239 UpdateMinAndMaxSize(); | 1242 UpdateMinAndMaxSize(); |
1240 | 1243 |
1241 if (bounds_in_pixels.width() < min_size_in_pixels_.width() || | 1244 if (bounds_in_pixels.width() < min_size_in_pixels_.width() || |
1242 bounds_in_pixels.height() < min_size_in_pixels_.height() || | 1245 bounds_in_pixels.height() < min_size_in_pixels_.height() || |
1243 (!max_size_in_pixels_.IsEmpty() && | 1246 (!max_size_in_pixels_.IsEmpty() && |
1244 (bounds_in_pixels.width() > max_size_in_pixels_.width() || | 1247 (bounds_in_pixels.width() > max_size_in_pixels_.width() || |
1245 bounds_in_pixels.height() > max_size_in_pixels_.height()))) { | 1248 bounds_in_pixels.height() > max_size_in_pixels_.height()))) { |
1246 gfx::Size size_in_pixels = bounds_in_pixels.size(); | 1249 gfx::Size size_in_pixels = bounds_in_pixels.size(); |
1247 if (!max_size_in_pixels_.IsEmpty()) | 1250 if (!max_size_in_pixels_.IsEmpty()) |
(...skipping 399 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1647 insets.size() == 4) { | 1650 insets.size() == 4) { |
1648 // |insets| are returned in the order: [left, right, top, bottom]. | 1651 // |insets| are returned in the order: [left, right, top, bottom]. |
1649 native_window_frame_borders_in_pixels_ = | 1652 native_window_frame_borders_in_pixels_ = |
1650 gfx::Insets(insets[2], insets[0], insets[3], insets[1]); | 1653 gfx::Insets(insets[2], insets[0], insets[3], insets[1]); |
1651 } else { | 1654 } else { |
1652 native_window_frame_borders_in_pixels_ = gfx::Insets(); | 1655 native_window_frame_borders_in_pixels_ = gfx::Insets(); |
1653 } | 1656 } |
1654 } | 1657 } |
1655 | 1658 |
1656 void DesktopWindowTreeHostX11::UpdateMinAndMaxSize() { | 1659 void DesktopWindowTreeHostX11::UpdateMinAndMaxSize() { |
1657 if (!IsVisible()) | |
1658 return; | |
1659 | |
1660 gfx::Size minimum_in_pixels = | 1660 gfx::Size minimum_in_pixels = |
1661 ToPixelRect(gfx::Rect(native_widget_delegate_->GetMinimumSize())).size(); | 1661 ToPixelRect(gfx::Rect(native_widget_delegate_->GetMinimumSize())).size(); |
1662 gfx::Size maximum_in_pixels = | 1662 gfx::Size maximum_in_pixels = |
1663 ToPixelRect(gfx::Rect(native_widget_delegate_->GetMaximumSize())).size(); | 1663 ToPixelRect(gfx::Rect(native_widget_delegate_->GetMaximumSize())).size(); |
1664 if (min_size_in_pixels_ == minimum_in_pixels && | 1664 if (min_size_in_pixels_ == minimum_in_pixels && |
1665 max_size_in_pixels_ == maximum_in_pixels) | 1665 max_size_in_pixels_ == maximum_in_pixels) |
1666 return; | 1666 return; |
1667 | 1667 |
1668 min_size_in_pixels_ = minimum_in_pixels; | 1668 min_size_in_pixels_ = minimum_in_pixels; |
1669 max_size_in_pixels_ = maximum_in_pixels; | 1669 max_size_in_pixels_ = maximum_in_pixels; |
(...skipping 250 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1920 if (show_state == ui::SHOW_STATE_INACTIVE || wm_user_time_ms != 0) { | 1920 if (show_state == ui::SHOW_STATE_INACTIVE || wm_user_time_ms != 0) { |
1921 XChangeProperty( | 1921 XChangeProperty( |
1922 xdisplay_, xwindow_, atom_cache_.GetAtom("_NET_WM_USER_TIME"), | 1922 xdisplay_, xwindow_, atom_cache_.GetAtom("_NET_WM_USER_TIME"), |
1923 XA_CARDINAL, 32, PropModeReplace, | 1923 XA_CARDINAL, 32, PropModeReplace, |
1924 reinterpret_cast<const unsigned char*>(&wm_user_time_ms), 1); | 1924 reinterpret_cast<const unsigned char*>(&wm_user_time_ms), 1); |
1925 } | 1925 } |
1926 | 1926 |
1927 ui::X11EventSource* event_source = ui::X11EventSource::GetInstance(); | 1927 ui::X11EventSource* event_source = ui::X11EventSource::GetInstance(); |
1928 DCHECK(event_source); | 1928 DCHECK(event_source); |
1929 | 1929 |
1930 if (wait_for_unmap_) { | 1930 UpdateMinAndMaxSize(); |
1931 // Block until our window is unmapped. This avoids a race condition when | |
1932 // remapping an unmapped window. | |
1933 event_source->BlockUntilWindowUnmapped(xwindow_); | |
1934 DCHECK(!wait_for_unmap_); | |
1935 } | |
1936 | 1931 |
1937 XMapWindow(xdisplay_, xwindow_); | 1932 XMapWindow(xdisplay_, xwindow_); |
1938 | 1933 is_visible_ = true; |
1939 // We now block until our window is mapped. Some X11 APIs will crash and | |
1940 // burn if passed |xwindow_| before the window is mapped, and XMapWindow is | |
1941 // asynchronous. | |
1942 event_source->BlockUntilWindowMapped(xwindow_); | |
1943 } | 1934 } |
1944 | 1935 |
1945 void DesktopWindowTreeHostX11::SetWindowTransparency() { | 1936 void DesktopWindowTreeHostX11::SetWindowTransparency() { |
1946 compositor()->SetHostHasTransparentBackground(use_argb_visual_); | 1937 compositor()->SetHostHasTransparentBackground(use_argb_visual_); |
1947 window()->SetTransparent(use_argb_visual_); | 1938 window()->SetTransparent(use_argb_visual_); |
1948 content_window_->SetTransparent(use_argb_visual_); | 1939 content_window_->SetTransparent(use_argb_visual_); |
1949 } | 1940 } |
1950 | 1941 |
1951 void DesktopWindowTreeHostX11::Relayout() { | 1942 void DesktopWindowTreeHostX11::Relayout() { |
1952 Widget* widget = native_widget_delegate_->AsWidget(); | 1943 Widget* widget = native_widget_delegate_->AsWidget(); |
(...skipping 207 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2160 if (num_coalesced > 0) | 2151 if (num_coalesced > 0) |
2161 XFreeEventData(xev->xgeneric.display, &last_event.xcookie); | 2152 XFreeEventData(xev->xgeneric.display, &last_event.xcookie); |
2162 break; | 2153 break; |
2163 } | 2154 } |
2164 case MapNotify: { | 2155 case MapNotify: { |
2165 window_mapped_ = true; | 2156 window_mapped_ = true; |
2166 | 2157 |
2167 for (DesktopWindowTreeHostObserverX11& observer : observer_list_) | 2158 for (DesktopWindowTreeHostObserverX11& observer : observer_list_) |
2168 observer.OnWindowMapped(xwindow_); | 2159 observer.OnWindowMapped(xwindow_); |
2169 | 2160 |
2170 UpdateMinAndMaxSize(); | |
2171 | |
2172 // Some WMs only respect maximize hints after the window has been mapped. | 2161 // Some WMs only respect maximize hints after the window has been mapped. |
2173 // Check whether we need to re-do a maximization. | 2162 // Check whether we need to re-do a maximization. |
2174 if (should_maximize_after_map_) { | 2163 if (should_maximize_after_map_) { |
2175 Maximize(); | 2164 Maximize(); |
2176 should_maximize_after_map_ = false; | 2165 should_maximize_after_map_ = false; |
2177 } | 2166 } |
2178 | 2167 |
2179 break; | 2168 break; |
2180 } | 2169 } |
2181 case UnmapNotify: { | 2170 case UnmapNotify: { |
2182 window_mapped_ = false; | 2171 window_mapped_ = false; |
2183 wait_for_unmap_ = false; | |
2184 has_pointer_ = false; | 2172 has_pointer_ = false; |
2185 has_pointer_grab_ = false; | 2173 has_pointer_grab_ = false; |
2186 has_pointer_focus_ = false; | 2174 has_pointer_focus_ = false; |
2187 has_window_focus_ = false; | 2175 has_window_focus_ = false; |
sadrul
2017/02/04 02:27:51
Should this update is_visible_ too?
Tom (Use chromium acct)
2017/02/04 17:58:54
no, is_visible is updated when the (un)map notify
| |
2188 for (DesktopWindowTreeHostObserverX11& observer : observer_list_) | 2176 for (DesktopWindowTreeHostObserverX11& observer : observer_list_) |
2189 observer.OnWindowUnmapped(xwindow_); | 2177 observer.OnWindowUnmapped(xwindow_); |
2190 break; | 2178 break; |
2191 } | 2179 } |
2192 case ClientMessage: { | 2180 case ClientMessage: { |
2193 Atom message_type = xev->xclient.message_type; | 2181 Atom message_type = xev->xclient.message_type; |
2194 if (message_type == atom_cache_.GetAtom("WM_PROTOCOLS")) { | 2182 if (message_type == atom_cache_.GetAtom("WM_PROTOCOLS")) { |
2195 Atom protocol = static_cast<Atom>(xev->xclient.data.l[0]); | 2183 Atom protocol = static_cast<Atom>(xev->xclient.data.l[0]); |
2196 if (protocol == atom_cache_.GetAtom("WM_DELETE_WINDOW")) { | 2184 if (protocol == atom_cache_.GetAtom("WM_DELETE_WINDOW")) { |
2197 // We have received a close message from the window manager. | 2185 // We have received a close message from the window manager. |
(...skipping 159 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2357 | 2345 |
2358 // static | 2346 // static |
2359 DesktopWindowTreeHost* DesktopWindowTreeHost::Create( | 2347 DesktopWindowTreeHost* DesktopWindowTreeHost::Create( |
2360 internal::NativeWidgetDelegate* native_widget_delegate, | 2348 internal::NativeWidgetDelegate* native_widget_delegate, |
2361 DesktopNativeWidgetAura* desktop_native_widget_aura) { | 2349 DesktopNativeWidgetAura* desktop_native_widget_aura) { |
2362 return new DesktopWindowTreeHostX11(native_widget_delegate, | 2350 return new DesktopWindowTreeHostX11(native_widget_delegate, |
2363 desktop_native_widget_aura); | 2351 desktop_native_widget_aura); |
2364 } | 2352 } |
2365 | 2353 |
2366 } // namespace views | 2354 } // namespace views |
OLD | NEW |