diff options
| author | Marco Trevisan (TreviƱo) <mail@3v1n0.net> | 2014-10-16 15:09:56 +0000 |
|---|---|---|
| committer | CI bot <ps-jenkins@lists.canonical.com> | 2014-10-16 15:09:56 +0000 |
| commit | 860fb995364c766263f5ba6757763b760f5b5f86 (patch) | |
| tree | dcd269ec77019e34eec727f792a768146cb0d16b /unity-shared | |
| parent | 946a78364d75599be97ef0650d42c6da4a62fd5b (diff) | |
| parent | 153642b1dc3a3ca18bc2eb45e60b4c99f007348d (diff) | |
DecoratedWindow: make edges independent from borders and properly update them on actions changed
Now windows can have edges (handles) also if they are not fully decorated, and the other way around. Improved the logic to detect which kind of decorations are supported by windows (so now we add shadows to windows with borders, and we do not to shaped ones). Removed a lot of duplicated matrix/region computations. Properly rebuild decorations when _NET_WM_ALLOWED_ACTIONS changes Fixes to the ForceQuit dialog shadows (and support for backdrop mode). Fixes: 1276177, 1299741, 1301776, 1324104, 1364225, 1373695 Approved by: Brandon Schaefer, PS Jenkins bot (bzr r3882)
Diffstat (limited to 'unity-shared')
| -rw-r--r-- | unity-shared/CompizUtils.cpp | 113 | ||||
| -rw-r--r-- | unity-shared/CompizUtils.h | 29 | ||||
| -rw-r--r-- | unity-shared/XWindowManager.cpp | 2 |
3 files changed, 91 insertions, 53 deletions
diff --git a/unity-shared/CompizUtils.cpp b/unity-shared/CompizUtils.cpp index be197c73e..94322a68f 100644 --- a/unity-shared/CompizUtils.cpp +++ b/unity-shared/CompizUtils.cpp @@ -1,6 +1,6 @@ // -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*- /* -* Copyright (C) 2013 Canonical Ltd +* Copyright (C) 2013-2014 Canonical Ltd * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 as @@ -30,6 +30,11 @@ namespace { const unsigned PIXMAP_DEPTH = 32; const float DEFAULT_SCALE = 1.0f; + const unsigned DECORABLE_WINDOW_TYPES = CompWindowTypeDialogMask | + CompWindowTypeModalDialogMask | + CompWindowTypeUtilMask | + CompWindowTypeMenuMask | + CompWindowTypeNormalMask; } SimpleTexture::SimpleTexture(GLTexture::List const& tex) @@ -39,7 +44,7 @@ SimpleTexture::SimpleTexture(GLTexture::List const& tex) // SimpleTextureQuad::SimpleTextureQuad() - : scale(DEFAULT_SCALE) + : scale_(DEFAULT_SCALE) {} bool SimpleTextureQuad::SetTexture(SimpleTexture::Ptr const& simple_texture) @@ -52,24 +57,27 @@ bool SimpleTextureQuad::SetTexture(SimpleTexture::Ptr const& simple_texture) if (st && st->texture()) { auto* tex = st->texture(); - CompPoint old_coords(quad.box.x(), quad.box.y()); - short invalid = std::numeric_limits<short>::min(); - quad.box.setGeometry(invalid, invalid, tex->width() * scale, tex->height() * scale); - SetCoords(old_coords.x(), old_coords.y()); + CompSize size(tex->width() * scale_, tex->height() * scale_); + + if (quad.box.width() != size.width() || quad.box.height() != size.height()) + { + quad.box.setSize(size); + UpdateMatrix(); + } } return true; } -bool SimpleTextureQuad::SetScale(float s) +bool SimpleTextureQuad::SetScale(double s) { - if (!st || scale == s) + if (!st || scale_ == s) return false; - scale = s; + scale_ = s; auto* tex = st->texture(); - quad.box.setWidth(tex->width() * scale); - quad.box.setHeight(tex->height() * scale); + quad.box.setWidth(tex->width() * scale_); + quad.box.setHeight(tex->height() * scale_); UpdateMatrix(); return true; } @@ -91,8 +99,8 @@ void SimpleTextureQuad::UpdateMatrix() int y = quad.box.y(); quad.matrix = (st && st->texture()) ? st->texture()->matrix() : GLTexture::Matrix(); - quad.matrix.xx /= scale; - quad.matrix.yy /= scale; + quad.matrix.xx /= scale_; + quad.matrix.yy /= scale_; quad.matrix.x0 = 0.0f - COMP_TEX_COORD_X(quad.matrix, x); quad.matrix.y0 = 0.0f - COMP_TEX_COORD_Y(quad.matrix, y); } @@ -166,57 +174,68 @@ int CairoContext::height() const return cairo_xlib_surface_get_height(surface_); } -bool IsWindowShadowDecorable(CompWindow* win) +// +// + +unsigned WindowDecorationElements(CompWindow* win) { + unsigned elements = DecorationElement::NONE; + if (!win) - return false; + return elements; if (!win->isViewable()) - return false; + return elements; if (win->wmType() & (CompWindowTypeDockMask | CompWindowTypeDesktopMask)) - return false; + return elements; - if (win->region().numRects() != 1) // Non rectangular windows - return false; + if (win->inShowDesktopMode()) + return elements; - if (win->alpha()) - return WindowHasMotifDecorations(win); + auto const& region = win->region(); + bool rectangular = (region.numRects() == 1); + bool alpha = win->alpha(); - return true; -} + if (!rectangular && alpha) // Non-rectangular windows with alpha channel + return elements; -bool IsWindowFullyDecorable(CompWindow* win) -{ - if (!win) - return false; + if (region.boundingRect() != win->geometry()) // Shaped windows + return elements; - if (!IsWindowShadowDecorable(win)) - return false; + if (rectangular) + elements |= DecorationElement::SHADOW; - return WindowHasMotifDecorations(win); + if (!win->overrideRedirect() && + (win->type() & DECORABLE_WINDOW_TYPES) && + (win->frame() || win->hasUnmapReference())) + { + if (win->actions() & CompWindowActionResizeMask) + elements |= DecorationElement::EDGE; + + if (rectangular && (win->mwmDecor() & (MwmDecorAll | MwmDecorTitle))) + elements |= DecorationElement::BORDER; + } + + if (alpha && !(elements & DecorationElement::BORDER) && !(win->mwmDecor() & MwmDecorBorder)) + elements &= ~DecorationElement::SHADOW; + + return elements; } -bool WindowHasMotifDecorations(CompWindow* win) +bool IsWindowEdgeDecorable(CompWindow* win) { - if (!win) - return false; - - if (win->overrideRedirect()) - return false; + return WindowDecorationElements(win) & DecorationElement::EDGE; +} - switch (win->type()) - { - case CompWindowTypeDialogMask: - case CompWindowTypeModalDialogMask: - case CompWindowTypeUtilMask: - case CompWindowTypeMenuMask: - case CompWindowTypeNormalMask: - if (win->mwmDecor() & (MwmDecorAll | MwmDecorTitle)) - return true; - } +bool IsWindowShadowDecorable(CompWindow* win) +{ + return WindowDecorationElements(win) & DecorationElement::SHADOW; +} - return false; +bool IsWindowFullyDecorable(CompWindow* win) +{ + return WindowDecorationElements(win) & DecorationElement::BORDER; } } // compiz_utils namespace diff --git a/unity-shared/CompizUtils.h b/unity-shared/CompizUtils.h index bab45a532..f1885a5cc 100644 --- a/unity-shared/CompizUtils.h +++ b/unity-shared/CompizUtils.h @@ -31,8 +31,15 @@ namespace compiz_utils struct TextureQuad { + TextureQuad() + : matrices(1) + , matrix(matrices[0]) + {} + CompRect box; - GLTexture::Matrix matrix; + CompRegion region; + GLTexture::MatrixList matrices; + GLTexture::Matrix& matrix; }; struct SimpleTexture @@ -59,11 +66,13 @@ struct SimpleTextureQuad { SimpleTextureQuad(); bool SetTexture(SimpleTexture::Ptr const&); - bool SetScale(float scale); + bool SetScale(double scale); bool SetCoords(int x, int y); bool SetX(int x); bool SetY(int y); + void UpdateMatrix(); + operator SimpleTexture::Ptr() const { return st; } operator bool() const { return st && st->texture(); } operator GLTexture*() const { return st ? st->texture() : nullptr; } @@ -73,8 +82,7 @@ struct SimpleTextureQuad TextureQuad quad; private: - void UpdateMatrix(); - float scale; + double scale_; }; struct PixmapTexture : SimpleTexture @@ -111,9 +119,20 @@ private: cairo_t *cr_; }; +enum DecorationElement +{ + NONE = 0, + EDGE = (1 << 0), + SHADOW = (1 << 1), + BORDER = (1 << 2), + FULL = EDGE|SHADOW|BORDER +}; + +unsigned WindowDecorationElements(CompWindow*); + +bool IsWindowEdgeDecorable(CompWindow*); bool IsWindowShadowDecorable(CompWindow*); bool IsWindowFullyDecorable(CompWindow*); -bool WindowHasMotifDecorations(CompWindow*); } // compiz_utils namespace } // unity namespace diff --git a/unity-shared/XWindowManager.cpp b/unity-shared/XWindowManager.cpp index aa3d9c54f..5058c2952 100644 --- a/unity-shared/XWindowManager.cpp +++ b/unity-shared/XWindowManager.cpp @@ -83,7 +83,7 @@ std::string XWindowManager::GetStringProperty(Window window_id, Atom atom) const { LOG_ERROR(logger) << "Impossible to get the property " << gdk_x11_get_xatom_name(atom) << " for window " << window_id << ": invalid string type: " - << gdk_x11_get_xatom_name(Atoms::utf8String); + << gdk_x11_get_xatom_name(type); return std::string(); } |
