Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(591)

Side by Side Diff: ui/views/widget/desktop_aura/desktop_window_tree_host_x11.cc

Issue 2630773002: Avoid blocking while mapping an X11 window (Closed)
Patch Set: fix flaky tests Created 3 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
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
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
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
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
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698