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

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

Issue 291583003: Revert of Fix X11TopmostWindowFinder (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 6 years, 7 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 | Annotate | Revision Log
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 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
69 namespace { 69 namespace {
70 70
71 // Constants that are part of EWMH. 71 // Constants that are part of EWMH.
72 const int k_NET_WM_STATE_ADD = 1; 72 const int k_NET_WM_STATE_ADD = 1;
73 const int k_NET_WM_STATE_REMOVE = 0; 73 const int k_NET_WM_STATE_REMOVE = 0;
74 74
75 const char* kAtomsToCache[] = { 75 const char* kAtomsToCache[] = {
76 "UTF8_STRING", 76 "UTF8_STRING",
77 "WM_DELETE_WINDOW", 77 "WM_DELETE_WINDOW",
78 "WM_PROTOCOLS", 78 "WM_PROTOCOLS",
79 "_NET_FRAME_EXTENTS",
80 "_NET_WM_CM_S0", 79 "_NET_WM_CM_S0",
81 "_NET_WM_ICON", 80 "_NET_WM_ICON",
82 "_NET_WM_NAME", 81 "_NET_WM_NAME",
83 "_NET_WM_PID", 82 "_NET_WM_PID",
84 "_NET_WM_PING", 83 "_NET_WM_PING",
85 "_NET_WM_STATE", 84 "_NET_WM_STATE",
86 "_NET_WM_STATE_ABOVE", 85 "_NET_WM_STATE_ABOVE",
87 "_NET_WM_STATE_FULLSCREEN", 86 "_NET_WM_STATE_FULLSCREEN",
88 "_NET_WM_STATE_HIDDEN", 87 "_NET_WM_STATE_HIDDEN",
89 "_NET_WM_STATE_MAXIMIZED_HORZ", 88 "_NET_WM_STATE_MAXIMIZED_HORZ",
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
134 is_fullscreen_(false), 133 is_fullscreen_(false),
135 is_always_on_top_(false), 134 is_always_on_top_(false),
136 use_native_frame_(false), 135 use_native_frame_(false),
137 use_argb_visual_(false), 136 use_argb_visual_(false),
138 drag_drop_client_(NULL), 137 drag_drop_client_(NULL),
139 current_cursor_(ui::kCursorNull), 138 current_cursor_(ui::kCursorNull),
140 native_widget_delegate_(native_widget_delegate), 139 native_widget_delegate_(native_widget_delegate),
141 desktop_native_widget_aura_(desktop_native_widget_aura), 140 desktop_native_widget_aura_(desktop_native_widget_aura),
142 content_window_(NULL), 141 content_window_(NULL),
143 window_parent_(NULL), 142 window_parent_(NULL),
144 window_shape_(NULL), 143 custom_window_shape_(NULL),
145 custom_window_shape_(false),
146 urgency_hint_set_(false) { 144 urgency_hint_set_(false) {
147 } 145 }
148 146
149 DesktopWindowTreeHostX11::~DesktopWindowTreeHostX11() { 147 DesktopWindowTreeHostX11::~DesktopWindowTreeHostX11() {
150 window()->ClearProperty(kHostForRootWindow); 148 window()->ClearProperty(kHostForRootWindow);
151 aura::client::SetWindowMoveClient(window(), NULL); 149 aura::client::SetWindowMoveClient(window(), NULL);
152 desktop_native_widget_aura_->OnDesktopWindowTreeHostDestroyed(this); 150 desktop_native_widget_aura_->OnDesktopWindowTreeHostDestroyed(this);
153 if (window_shape_) 151 if (custom_window_shape_)
154 XDestroyRegion(window_shape_); 152 XDestroyRegion(custom_window_shape_);
155 DestroyDispatcher(); 153 DestroyDispatcher();
156 } 154 }
157 155
158 // static 156 // static
159 aura::Window* DesktopWindowTreeHostX11::GetContentWindowForXID(XID xid) { 157 aura::Window* DesktopWindowTreeHostX11::GetContentWindowForXID(XID xid) {
160 aura::WindowTreeHost* host = 158 aura::WindowTreeHost* host =
161 aura::WindowTreeHost::GetForAcceleratedWidget(xid); 159 aura::WindowTreeHost::GetForAcceleratedWidget(xid);
162 return host ? host->window()->GetProperty(kViewsWindowForRootWindow) : NULL; 160 return host ? host->window()->GetProperty(kViewsWindowForRootWindow) : NULL;
163 } 161 }
164 162
(...skipping 11 matching lines...) Expand all
176 open_windows().end(), 174 open_windows().end(),
177 windows.begin(), 175 windows.begin(),
178 GetContentWindowForXID); 176 GetContentWindowForXID);
179 return windows; 177 return windows;
180 } 178 }
181 179
182 gfx::Rect DesktopWindowTreeHostX11::GetX11RootWindowBounds() const { 180 gfx::Rect DesktopWindowTreeHostX11::GetX11RootWindowBounds() const {
183 return bounds_; 181 return bounds_;
184 } 182 }
185 183
186 gfx::Rect DesktopWindowTreeHostX11::GetX11RootWindowOuterBounds() const {
187 gfx::Rect outer_bounds(bounds_);
188 outer_bounds.Inset(-native_window_frame_borders_);
189 return outer_bounds;
190 }
191
192 ::Region DesktopWindowTreeHostX11::GetWindowShape() const {
193 return window_shape_;
194 }
195
196 void DesktopWindowTreeHostX11::HandleNativeWidgetActivationChanged( 184 void DesktopWindowTreeHostX11::HandleNativeWidgetActivationChanged(
197 bool active) { 185 bool active) {
198 if (active) { 186 if (active) {
199 FlashFrame(false); 187 FlashFrame(false);
200 OnHostActivated(); 188 OnHostActivated();
201 open_windows().remove(xwindow_); 189 open_windows().remove(xwindow_);
202 open_windows().insert(open_windows().begin(), xwindow_); 190 open_windows().insert(open_windows().begin(), xwindow_);
203 } 191 }
204 192
205 desktop_native_widget_aura_->HandleActivationChanged(active); 193 desktop_native_widget_aura_->HandleActivationChanged(active);
(...skipping 131 matching lines...) Expand 10 before | Expand all | Expand 10 after
337 325
338 desktop_native_widget_aura_->OnHostClosed(); 326 desktop_native_widget_aura_->OnHostClosed();
339 } 327 }
340 328
341 aura::WindowTreeHost* DesktopWindowTreeHostX11::AsWindowTreeHost() { 329 aura::WindowTreeHost* DesktopWindowTreeHostX11::AsWindowTreeHost() {
342 return this; 330 return this;
343 } 331 }
344 332
345 void DesktopWindowTreeHostX11::ShowWindowWithState( 333 void DesktopWindowTreeHostX11::ShowWindowWithState(
346 ui::WindowShowState show_state) { 334 ui::WindowShowState show_state) {
347 if (!window_mapped_) { 335 if (!window_mapped_)
348 MapWindow(show_state); 336 MapWindow(show_state);
349 ResetWindowRegion();
350 }
351 337
352 if (show_state == ui::SHOW_STATE_NORMAL || 338 if (show_state == ui::SHOW_STATE_NORMAL ||
353 show_state == ui::SHOW_STATE_MAXIMIZED) { 339 show_state == ui::SHOW_STATE_MAXIMIZED) {
354 // Note: XFCE ignores a maximize hint given before mapping the window. 340 // Note: XFCE ignores a maximize hint given before mapping the window.
355 if (show_state == ui::SHOW_STATE_MAXIMIZED) 341 if (show_state == ui::SHOW_STATE_MAXIMIZED)
356 Maximize(); 342 Maximize();
357 Activate(); 343 Activate();
358 } 344 }
359 345
360 native_widget_delegate_->AsWidget()->SetInitialFocus(show_state); 346 native_widget_delegate_->AsWidget()->SetInitialFocus(show_state);
(...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after
471 if (!XGetGeometry(xdisplay_, x_root_window_, &root, &x, &y, 457 if (!XGetGeometry(xdisplay_, x_root_window_, &root, &x, &y,
472 &width, &height, &border_width, &depth)) { 458 &width, &height, &border_width, &depth)) {
473 NOTIMPLEMENTED(); 459 NOTIMPLEMENTED();
474 return gfx::Rect(0, 0, 10, 10); 460 return gfx::Rect(0, 0, 10, 10);
475 } 461 }
476 462
477 return gfx::Rect(x, y, width, height); 463 return gfx::Rect(x, y, width, height);
478 } 464 }
479 465
480 void DesktopWindowTreeHostX11::SetShape(gfx::NativeRegion native_region) { 466 void DesktopWindowTreeHostX11::SetShape(gfx::NativeRegion native_region) {
481 if (window_shape_) 467 if (custom_window_shape_)
482 XDestroyRegion(window_shape_); 468 XDestroyRegion(custom_window_shape_);
483 custom_window_shape_ = true; 469 custom_window_shape_ = gfx::CreateRegionFromSkRegion(*native_region);
484 window_shape_ = gfx::CreateRegionFromSkRegion(*native_region);
485 ResetWindowRegion(); 470 ResetWindowRegion();
486 delete native_region; 471 delete native_region;
487 } 472 }
488 473
489 void DesktopWindowTreeHostX11::Activate() { 474 void DesktopWindowTreeHostX11::Activate() {
490 if (!window_mapped_) 475 if (!window_mapped_)
491 return; 476 return;
492 477
493 X11DesktopHandler::get()->ActivateWindow(xwindow_); 478 X11DesktopHandler::get()->ActivateWindow(xwindow_);
494 } 479 }
(...skipping 625 matching lines...) Expand 10 before | Expand all | Expand 10 after
1120 // If we have a delegate which is providing a default window icon, use that 1105 // If we have a delegate which is providing a default window icon, use that
1121 // icon. 1106 // icon.
1122 gfx::ImageSkia* window_icon = ViewsDelegate::views_delegate ? 1107 gfx::ImageSkia* window_icon = ViewsDelegate::views_delegate ?
1123 ViewsDelegate::views_delegate->GetDefaultWindowIcon() : NULL; 1108 ViewsDelegate::views_delegate->GetDefaultWindowIcon() : NULL;
1124 if (window_icon) { 1109 if (window_icon) {
1125 SetWindowIcons(gfx::ImageSkia(), *window_icon); 1110 SetWindowIcons(gfx::ImageSkia(), *window_icon);
1126 } 1111 }
1127 CreateCompositor(GetAcceleratedWidget()); 1112 CreateCompositor(GetAcceleratedWidget());
1128 } 1113 }
1129 1114
1130 void DesktopWindowTreeHostX11::OnWMStateUpdated() {
1131 std::vector< ::Atom> atom_list;
1132 if (!ui::GetAtomArrayProperty(xwindow_, "_NET_WM_STATE", &atom_list))
1133 return;
1134
1135 window_properties_.clear();
1136 std::copy(atom_list.begin(), atom_list.end(),
1137 inserter(window_properties_, window_properties_.begin()));
1138
1139 if (!restored_bounds_.IsEmpty() && !IsMaximized()) {
1140 // If we have restored bounds, but WM_STATE no longer claims to be
1141 // maximized, we should clear our restored bounds.
1142 restored_bounds_ = gfx::Rect();
1143 } else if (IsMaximized() && restored_bounds_.IsEmpty()) {
1144 // The request that we become maximized originated from a different process.
1145 // |bounds_| already contains our maximized bounds. Do a best effort attempt
1146 // to get restored bounds by setting it to our previously set bounds (and if
1147 // we get this wrong, we aren't any worse off since we'd otherwise be
1148 // returning our maximized bounds).
1149 restored_bounds_ = previous_bounds_;
1150 }
1151
1152 is_fullscreen_ = HasWMSpecProperty("_NET_WM_STATE_FULLSCREEN");
1153 is_always_on_top_ = HasWMSpecProperty("_NET_WM_STATE_ABOVE");
1154
1155 // Now that we have different window properties, we may need to relayout the
1156 // window. (The windows code doesn't need this because their window change is
1157 // synchronous.)
1158 //
1159 // TODO(erg): While this does work, there's a quick flash showing the
1160 // tabstrip/toolbar/etc. when going into fullscreen mode before hiding those
1161 // parts of the UI because we receive the sizing event from the window
1162 // manager before we receive the event that changes the fullscreen state.
1163 // Unsure what to do about that.
1164 Widget* widget = native_widget_delegate_->AsWidget();
1165 NonClientView* non_client_view = widget->non_client_view();
1166 // non_client_view may be NULL, especially during creation.
1167 if (non_client_view) {
1168 non_client_view->client_view()->InvalidateLayout();
1169 non_client_view->InvalidateLayout();
1170 }
1171 widget->GetRootView()->Layout();
1172 // Refresh the window's border, which may need to be updated if we have
1173 // changed the window's maximization state.
1174 ResetWindowRegion();
1175 }
1176
1177 void DesktopWindowTreeHostX11::OnFrameExtentsUpdated() {
1178 std::vector<int> insets;
1179 if (ui::GetIntArrayProperty(xwindow_, "_NET_FRAME_EXTENTS", &insets) &&
1180 insets.size() == 4) {
1181 // |insets| are returned in the order: [left, right, top, bottom].
1182 native_window_frame_borders_ = gfx::Insets(
1183 insets[2],
1184 insets[0],
1185 insets[3],
1186 insets[1]);
1187 } else {
1188 native_window_frame_borders_ = gfx::Insets();
1189 }
1190 }
1191
1192 void DesktopWindowTreeHostX11::SetWMSpecState(bool enabled, 1115 void DesktopWindowTreeHostX11::SetWMSpecState(bool enabled,
1193 ::Atom state1, 1116 ::Atom state1,
1194 ::Atom state2) { 1117 ::Atom state2) {
1195 XEvent xclient; 1118 XEvent xclient;
1196 memset(&xclient, 0, sizeof(xclient)); 1119 memset(&xclient, 0, sizeof(xclient));
1197 xclient.type = ClientMessage; 1120 xclient.type = ClientMessage;
1198 xclient.xclient.window = xwindow_; 1121 xclient.xclient.window = xwindow_;
1199 xclient.xclient.message_type = atom_cache_.GetAtom("_NET_WM_STATE"); 1122 xclient.xclient.message_type = atom_cache_.GetAtom("_NET_WM_STATE");
1200 xclient.xclient.format = 32; 1123 xclient.xclient.format = 32;
1201 xclient.xclient.data.l[0] = 1124 xclient.xclient.data.l[0] =
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after
1275 g_current_capture->SendEventToProcessor(event); 1198 g_current_capture->SendEventToProcessor(event);
1276 } else { 1199 } else {
1277 SendEventToProcessor(event); 1200 SendEventToProcessor(event);
1278 } 1201 }
1279 } 1202 }
1280 1203
1281 void DesktopWindowTreeHostX11::ResetWindowRegion() { 1204 void DesktopWindowTreeHostX11::ResetWindowRegion() {
1282 // If a custom window shape was supplied then apply it. 1205 // If a custom window shape was supplied then apply it.
1283 if (custom_window_shape_) { 1206 if (custom_window_shape_) {
1284 XShapeCombineRegion( 1207 XShapeCombineRegion(
1285 xdisplay_, xwindow_, ShapeBounding, 0, 0, window_shape_, false); 1208 xdisplay_, xwindow_, ShapeBounding, 0, 0, custom_window_shape_, false);
1286 return; 1209 return;
1287 } 1210 }
1288 1211
1289 if (window_shape_)
1290 XDestroyRegion(window_shape_);
1291 window_shape_ = NULL;
1292
1293 if (!IsMaximized()) { 1212 if (!IsMaximized()) {
1294 gfx::Path window_mask; 1213 gfx::Path window_mask;
1295 views::Widget* widget = native_widget_delegate_->AsWidget(); 1214 views::Widget* widget = native_widget_delegate_->AsWidget();
1296 if (widget->non_client_view()) { 1215 if (widget->non_client_view()) {
1297 // Some frame views define a custom (non-rectangular) window mask. If 1216 // Some frame views define a custom (non-rectangular) window mask. If
1298 // so, use it to define the window shape. If not, fall through. 1217 // so, use it to define the window shape. If not, fall through.
1299 widget->non_client_view()->GetWindowMask(bounds_.size(), &window_mask); 1218 widget->non_client_view()->GetWindowMask(bounds_.size(), &window_mask);
1300 if (window_mask.countPoints() > 0) { 1219 if (window_mask.countPoints() > 0) {
1301 window_shape_ = gfx::CreateRegionFromSkPath(window_mask); 1220 Region region = gfx::CreateRegionFromSkPath(window_mask);
1302 XShapeCombineRegion(xdisplay_, xwindow_, ShapeBounding, 1221 XShapeCombineRegion(xdisplay_, xwindow_, ShapeBounding,
1303 0, 0, window_shape_, false); 1222 0, 0, region, false);
1223 XDestroyRegion(region);
1304 return; 1224 return;
1305 } 1225 }
1306 } 1226 }
1307 } 1227 }
1308 1228
1309 // If we didn't set the shape for any reason, reset the shaping information. 1229 // If we didn't set the shape for any reason, reset the shaping information.
1310 // How this is done depends on the border style, due to quirks and bugs in 1230 // How this is done depends on the border style, due to quirks and bugs in
1311 // various window managers. 1231 // various window managers.
1312 if (ShouldUseNativeFrame()) { 1232 if (ShouldUseNativeFrame()) {
1313 // If the window has system borders, the mask must be set to null (not a 1233 // If the window has system borders, the mask must be set to null (not a
(...skipping 362 matching lines...) Expand 10 before | Expand all | Expand 10 after
1676 } else { 1596 } else {
1677 break; 1597 break;
1678 } 1598 }
1679 } 1599 }
1680 1600
1681 ui::MouseEvent mouseev(xev); 1601 ui::MouseEvent mouseev(xev);
1682 DispatchMouseEvent(&mouseev); 1602 DispatchMouseEvent(&mouseev);
1683 break; 1603 break;
1684 } 1604 }
1685 case PropertyNotify: { 1605 case PropertyNotify: {
1686 ::Atom changed_atom = xev->xproperty.atom; 1606 // Get our new window property state if the WM has told us its changed.
1687 if (changed_atom == atom_cache_.GetAtom("_NET_WM_STATE")) 1607 ::Atom state = atom_cache_.GetAtom("_NET_WM_STATE");
1688 OnWMStateUpdated(); 1608
1689 else if (changed_atom == atom_cache_.GetAtom("_NET_FRAME_EXTENTS")) 1609 std::vector< ::Atom> atom_list;
1690 OnFrameExtentsUpdated(); 1610 if (xev->xproperty.atom == state &&
1611 ui::GetAtomArrayProperty(xwindow_, "_NET_WM_STATE", &atom_list)) {
1612 window_properties_.clear();
1613 std::copy(atom_list.begin(), atom_list.end(),
1614 inserter(window_properties_, window_properties_.begin()));
1615
1616 if (!restored_bounds_.IsEmpty() && !IsMaximized()) {
1617 // If we have restored bounds, but WM_STATE no longer claims to be
1618 // maximized, we should clear our restored bounds.
1619 restored_bounds_ = gfx::Rect();
1620 } else if (IsMaximized() && restored_bounds_.IsEmpty()) {
1621 // The request that we become maximized originated from a different
1622 // process. |bounds_| already contains our maximized bounds. Do a
1623 // best effort attempt to get restored bounds by setting it to our
1624 // previously set bounds (and if we get this wrong, we aren't any
1625 // worse off since we'd otherwise be returning our maximized bounds).
1626 restored_bounds_ = previous_bounds_;
1627 }
1628
1629 is_fullscreen_ = HasWMSpecProperty("_NET_WM_STATE_FULLSCREEN");
1630 is_always_on_top_ = HasWMSpecProperty("_NET_WM_STATE_ABOVE");
1631
1632 // Now that we have different window properties, we may need to
1633 // relayout the window. (The windows code doesn't need this because
1634 // their window change is synchronous.)
1635 //
1636 // TODO(erg): While this does work, there's a quick flash showing the
1637 // tabstrip/toolbar/etc. when going into fullscreen mode before hiding
1638 // those parts of the UI because we receive the sizing event from the
1639 // window manager before we receive the event that changes the
1640 // fullscreen state. Unsure what to do about that.
1641 Widget* widget = native_widget_delegate_->AsWidget();
1642 NonClientView* non_client_view = widget->non_client_view();
1643 // non_client_view may be NULL, especially during creation.
1644 if (non_client_view) {
1645 non_client_view->client_view()->InvalidateLayout();
1646 non_client_view->InvalidateLayout();
1647 }
1648 widget->GetRootView()->Layout();
1649 // Refresh the window's border, which may need to be updated if we have
1650 // changed the window's maximization state.
1651 ResetWindowRegion();
1652 }
1691 break; 1653 break;
1692 } 1654 }
1693 case SelectionNotify: { 1655 case SelectionNotify: {
1694 drag_drop_client_->OnSelectionNotify(xev->xselection); 1656 drag_drop_client_->OnSelectionNotify(xev->xselection);
1695 break; 1657 break;
1696 } 1658 }
1697 } 1659 }
1698 return ui::POST_DISPATCH_STOP_PROPAGATION; 1660 return ui::POST_DISPATCH_STOP_PROPAGATION;
1699 } 1661 }
1700 1662
(...skipping 14 matching lines...) Expand all
1715 if (linux_ui) { 1677 if (linux_ui) {
1716 ui::NativeTheme* native_theme = linux_ui->GetNativeTheme(window); 1678 ui::NativeTheme* native_theme = linux_ui->GetNativeTheme(window);
1717 if (native_theme) 1679 if (native_theme)
1718 return native_theme; 1680 return native_theme;
1719 } 1681 }
1720 1682
1721 return ui::NativeTheme::instance(); 1683 return ui::NativeTheme::instance();
1722 } 1684 }
1723 1685
1724 } // namespace views 1686 } // namespace views
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698