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

Unified Diff: ui/views/widget/desktop_aura/desktop_window_tree_host_x11.cc

Issue 268673017: 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 side-by-side diff with in-line comments
Download patch
Index: ui/views/widget/desktop_aura/desktop_window_tree_host_x11.cc
diff --git a/ui/views/widget/desktop_aura/desktop_window_tree_host_x11.cc b/ui/views/widget/desktop_aura/desktop_window_tree_host_x11.cc
index 5fa2bc3beaf022b16f302f7284cc3f6310b65900..ab4a7ac112c993b09d51cc8b1b2bdf7b10e0093a 100644
--- a/ui/views/widget/desktop_aura/desktop_window_tree_host_x11.cc
+++ b/ui/views/widget/desktop_aura/desktop_window_tree_host_x11.cc
@@ -76,6 +76,7 @@ const char* kAtomsToCache[] = {
"UTF8_STRING",
"WM_DELETE_WINDOW",
"WM_PROTOCOLS",
+ "_NET_FRAME_EXTENTS",
"_NET_WM_CM_S0",
"_NET_WM_ICON",
"_NET_WM_NAME",
@@ -140,7 +141,8 @@ DesktopWindowTreeHostX11::DesktopWindowTreeHostX11(
desktop_native_widget_aura_(desktop_native_widget_aura),
content_window_(NULL),
window_parent_(NULL),
- custom_window_shape_(NULL),
+ window_shape_(NULL),
+ custom_window_shape_(false),
urgency_hint_set_(false) {
}
@@ -148,8 +150,8 @@ DesktopWindowTreeHostX11::~DesktopWindowTreeHostX11() {
window()->ClearProperty(kHostForRootWindow);
aura::client::SetWindowMoveClient(window(), NULL);
desktop_native_widget_aura_->OnDesktopWindowTreeHostDestroyed(this);
- if (custom_window_shape_)
- XDestroyRegion(custom_window_shape_);
+ if (window_shape_)
+ XDestroyRegion(window_shape_);
DestroyDispatcher();
}
@@ -181,6 +183,16 @@ gfx::Rect DesktopWindowTreeHostX11::GetX11RootWindowBounds() const {
return bounds_;
}
+gfx::Rect DesktopWindowTreeHostX11::GetX11RootWindowOuterBounds() const {
+ gfx::Rect outer_bounds(bounds_);
+ outer_bounds.Inset(-native_window_frame_borders_);
+ return outer_bounds;
+}
+
+::Region DesktopWindowTreeHostX11::GetWindowShape() const {
+ return window_shape_;
+}
+
void DesktopWindowTreeHostX11::HandleNativeWidgetActivationChanged(
bool active) {
if (active) {
@@ -332,8 +344,10 @@ aura::WindowTreeHost* DesktopWindowTreeHostX11::AsWindowTreeHost() {
void DesktopWindowTreeHostX11::ShowWindowWithState(
ui::WindowShowState show_state) {
- if (!window_mapped_)
+ if (!window_mapped_) {
MapWindow(show_state);
+ ResetWindowRegion();
+ }
if (show_state == ui::SHOW_STATE_NORMAL ||
show_state == ui::SHOW_STATE_MAXIMIZED) {
@@ -464,9 +478,10 @@ gfx::Rect DesktopWindowTreeHostX11::GetWorkAreaBoundsInScreen() const {
}
void DesktopWindowTreeHostX11::SetShape(gfx::NativeRegion native_region) {
- if (custom_window_shape_)
- XDestroyRegion(custom_window_shape_);
- custom_window_shape_ = gfx::CreateRegionFromSkRegion(*native_region);
+ if (window_shape_)
+ XDestroyRegion(window_shape_);
+ custom_window_shape_ = true;
+ window_shape_ = gfx::CreateRegionFromSkRegion(*native_region);
ResetWindowRegion();
delete native_region;
}
@@ -1112,6 +1127,68 @@ void DesktopWindowTreeHostX11::InitX11Window(
CreateCompositor(GetAcceleratedWidget());
}
+void DesktopWindowTreeHostX11::OnWMStateUpdated() {
+ std::vector< ::Atom> atom_list;
+ if (!ui::GetAtomArrayProperty(xwindow_, "_NET_WM_STATE", &atom_list))
+ return;
+
+ window_properties_.clear();
+ std::copy(atom_list.begin(), atom_list.end(),
+ inserter(window_properties_, window_properties_.begin()));
+
+ if (!restored_bounds_.IsEmpty() && !IsMaximized()) {
+ // If we have restored bounds, but WM_STATE no longer claims to be
+ // maximized, we should clear our restored bounds.
+ restored_bounds_ = gfx::Rect();
+ } else if (IsMaximized() && restored_bounds_.IsEmpty()) {
+ // The request that we become maximized originated from a different process.
+ // |bounds_| already contains our maximized bounds. Do a best effort attempt
+ // to get restored bounds by setting it to our previously set bounds (and if
+ // we get this wrong, we aren't any worse off since we'd otherwise be
+ // returning our maximized bounds).
+ restored_bounds_ = previous_bounds_;
+ }
+
+ is_fullscreen_ = HasWMSpecProperty("_NET_WM_STATE_FULLSCREEN");
+ is_always_on_top_ = HasWMSpecProperty("_NET_WM_STATE_ABOVE");
+
+ // Now that we have different window properties, we may need to relayout the
+ // window. (The windows code doesn't need this because their window change is
+ // synchronous.)
+ //
+ // TODO(erg): While this does work, there's a quick flash showing the
+ // tabstrip/toolbar/etc. when going into fullscreen mode before hiding those
+ // parts of the UI because we receive the sizing event from the window
+ // manager before we receive the event that changes the fullscreen state.
+ // Unsure what to do about that.
+ Widget* widget = native_widget_delegate_->AsWidget();
+ NonClientView* non_client_view = widget->non_client_view();
+ // non_client_view may be NULL, especially during creation.
+ if (non_client_view) {
+ non_client_view->client_view()->InvalidateLayout();
+ non_client_view->InvalidateLayout();
+ }
+ widget->GetRootView()->Layout();
+ // Refresh the window's border, which may need to be updated if we have
+ // changed the window's maximization state.
+ ResetWindowRegion();
+}
+
+void DesktopWindowTreeHostX11::OnFrameExtentsUpdated() {
+ std::vector<int> insets;
+ if (ui::GetIntArrayProperty(xwindow_, "_NET_FRAME_EXTENTS", &insets) &&
+ insets.size() == 4) {
+ // |insets| are returned in the order: [left, right, top, bottom].
+ native_window_frame_borders_ = gfx::Insets(
+ insets[2],
+ insets[0],
+ insets[3],
+ insets[1]);
+ } else {
+ native_window_frame_borders_ = gfx::Insets();
+ }
+}
+
void DesktopWindowTreeHostX11::SetWMSpecState(bool enabled,
::Atom state1,
::Atom state2) {
@@ -1205,10 +1282,14 @@ void DesktopWindowTreeHostX11::ResetWindowRegion() {
// If a custom window shape was supplied then apply it.
if (custom_window_shape_) {
XShapeCombineRegion(
- xdisplay_, xwindow_, ShapeBounding, 0, 0, custom_window_shape_, false);
+ xdisplay_, xwindow_, ShapeBounding, 0, 0, window_shape_, false);
return;
}
+ if (window_shape_)
+ XDestroyRegion(window_shape_);
+ window_shape_ = NULL;
+
if (!IsMaximized()) {
gfx::Path window_mask;
views::Widget* widget = native_widget_delegate_->AsWidget();
@@ -1217,10 +1298,9 @@ void DesktopWindowTreeHostX11::ResetWindowRegion() {
// so, use it to define the window shape. If not, fall through.
widget->non_client_view()->GetWindowMask(bounds_.size(), &window_mask);
if (window_mask.countPoints() > 0) {
- Region region = gfx::CreateRegionFromSkPath(window_mask);
+ window_shape_ = gfx::CreateRegionFromSkPath(window_mask);
XShapeCombineRegion(xdisplay_, xwindow_, ShapeBounding,
- 0, 0, region, false);
- XDestroyRegion(region);
+ 0, 0, window_shape_, false);
return;
}
}
@@ -1603,53 +1683,11 @@ uint32_t DesktopWindowTreeHostX11::DispatchEvent(
break;
}
case PropertyNotify: {
- // Get our new window property state if the WM has told us its changed.
- ::Atom state = atom_cache_.GetAtom("_NET_WM_STATE");
-
- std::vector< ::Atom> atom_list;
- if (xev->xproperty.atom == state &&
- ui::GetAtomArrayProperty(xwindow_, "_NET_WM_STATE", &atom_list)) {
- window_properties_.clear();
- std::copy(atom_list.begin(), atom_list.end(),
- inserter(window_properties_, window_properties_.begin()));
-
- if (!restored_bounds_.IsEmpty() && !IsMaximized()) {
- // If we have restored bounds, but WM_STATE no longer claims to be
- // maximized, we should clear our restored bounds.
- restored_bounds_ = gfx::Rect();
- } else if (IsMaximized() && restored_bounds_.IsEmpty()) {
- // The request that we become maximized originated from a different
- // process. |bounds_| already contains our maximized bounds. Do a
- // best effort attempt to get restored bounds by setting it to our
- // previously set bounds (and if we get this wrong, we aren't any
- // worse off since we'd otherwise be returning our maximized bounds).
- restored_bounds_ = previous_bounds_;
- }
-
- is_fullscreen_ = HasWMSpecProperty("_NET_WM_STATE_FULLSCREEN");
- is_always_on_top_ = HasWMSpecProperty("_NET_WM_STATE_ABOVE");
-
- // Now that we have different window properties, we may need to
- // relayout the window. (The windows code doesn't need this because
- // their window change is synchronous.)
- //
- // TODO(erg): While this does work, there's a quick flash showing the
- // tabstrip/toolbar/etc. when going into fullscreen mode before hiding
- // those parts of the UI because we receive the sizing event from the
- // window manager before we receive the event that changes the
- // fullscreen state. Unsure what to do about that.
- Widget* widget = native_widget_delegate_->AsWidget();
- NonClientView* non_client_view = widget->non_client_view();
- // non_client_view may be NULL, especially during creation.
- if (non_client_view) {
- non_client_view->client_view()->InvalidateLayout();
- non_client_view->InvalidateLayout();
- }
- widget->GetRootView()->Layout();
- // Refresh the window's border, which may need to be updated if we have
- // changed the window's maximization state.
- ResetWindowRegion();
- }
+ ::Atom changed_atom = xev->xproperty.atom;
+ if (changed_atom == atom_cache_.GetAtom("_NET_WM_STATE"))
+ OnWMStateUpdated();
+ else if (changed_atom == atom_cache_.GetAtom("_NET_FRAME_EXTENTS"))
+ OnFrameExtentsUpdated();
break;
}
case SelectionNotify: {

Powered by Google App Engine
This is Rietveld 408576698