diff options
| author | Marco Trevisan (TreviƱo) <mail@3v1n0.net> | 2016-03-10 10:09:29 +0000 |
|---|---|---|
| committer | CI Train Bot <ci-train-bot@canonical.com> | 2016-03-10 10:09:29 +0000 |
| commit | 641d4cd0b42aab89186ca977971e49f335e6c31c (patch) | |
| tree | 4f5fa50aad835a98142c4f2bf733dd0b7eaba293 | |
| parent | 7aff5c5e617272b6d0ea210262028db65641b56d (diff) | |
| parent | bd4f8127fcd9945e3c27e24518f0d557c5f651cf (diff) | |
DecoratedWindow: move the shadow under the window if we've a client-side decorated window with corners Fixes: #1516403
Approved by: Andrea Azzarone, PS Jenkins bot (bzr r4085)
| -rw-r--r-- | decorations/DecoratedWindow.cpp | 47 | ||||
| -rw-r--r-- | decorations/DecorationsManager.cpp | 22 | ||||
| -rw-r--r-- | decorations/DecorationsPriv.h | 13 | ||||
| -rw-r--r-- | plugins/unityshell/src/inputremover.cpp | 13 | ||||
| -rw-r--r-- | plugins/unityshell/src/inputremover.h | 1 | ||||
| -rw-r--r-- | plugins/unityshell/src/unityshell.cpp | 31 | ||||
| -rw-r--r-- | unity-shared/CompizUtils.cpp | 20 | ||||
| -rw-r--r-- | unity-shared/CompizUtils.h | 10 |
8 files changed, 111 insertions, 46 deletions
diff --git a/decorations/DecoratedWindow.cpp b/decorations/DecoratedWindow.cpp index b58a56c5a..0cadcfbee 100644 --- a/decorations/DecoratedWindow.cpp +++ b/decorations/DecoratedWindow.cpp @@ -47,6 +47,7 @@ Window::Impl::Impl(Window* parent, CompWindow* win) , monitor_(0) , dirty_geo_(true) , dirty_frame_(false) + , client_decorated_(false) , deco_elements_(cu::DecorationElement::NONE) , last_mwm_decor_(win_->mwmDecor()) , last_actions_(win_->actions()) @@ -105,7 +106,8 @@ Window::Impl::~Impl() void Window::Impl::Update() { - UpdateElements(); + UpdateClientDecorationsState(); + UpdateElements(client_decorated_ ? cu::WindowFilter::CLIENTSIDE_DECORATED : cu::WindowFilter::NONE); if (deco_elements_ & (cu::DecorationElement::EDGE | cu::DecorationElement::BORDER)) Decorate(); @@ -212,10 +214,10 @@ void Window::Impl::UpdateFrame() if (win_->shaded()) frame_geo.height = input.top + input.bottom; - if (!frame_) + if (!frame_ && win_->frame()) CreateFrame(frame_geo); - if (frame_geo_ != frame_geo) + if (frame_ && frame_geo_ != frame_geo) UpdateFrameGeo(frame_geo); } @@ -431,7 +433,7 @@ bool Window::Impl::IsMaximized() const return (win_->state() & MAXIMIZE_STATE) == MAXIMIZE_STATE; } -void Window::Impl::UpdateElements(cu::WindowFilter::Value wf) +void Window::Impl::UpdateElements(cu::WindowFilter wf) { if (!parent_->scaled() && IsMaximized()) { @@ -442,6 +444,31 @@ void Window::Impl::UpdateElements(cu::WindowFilter::Value wf) deco_elements_ = cu::WindowDecorationElements(win_, wf); } +void Window::Impl::UpdateClientDecorationsState() +{ + if (win_->alpha()) + { + auto const& corners = WindowManager::Default().GetCardinalProperty(win_->id(), atom::_UNITY_GTK_BORDER_RADIUS); + + if (!corners.empty()) + { + enum Corner { TOP_LEFT, TOP_RIGHT, BOTTOM_LEFT, BOTTOM_RIGHT }; + client_borders_.top = std::max(corners[TOP_LEFT], corners[TOP_RIGHT]); + client_borders_.left = std::max(corners[TOP_LEFT], corners[BOTTOM_LEFT]); + client_borders_.right = std::max(corners[TOP_RIGHT], corners[BOTTOM_RIGHT]); + client_borders_.bottom = std::max(corners[BOTTOM_LEFT], corners[BOTTOM_RIGHT]); + client_decorated_ = true; + return; + } + } + + if (client_decorated_) + { + client_borders_ = CompWindowExtents(); + client_decorated_ = false; + } +} + bool Window::Impl::ShadowDecorated() const { return deco_elements_ & cu::DecorationElement::SHADOW; @@ -613,7 +640,14 @@ void Window::Impl::ComputeShadowQuads() if (shadows_rect != last_shadow_rect_) { - auto const& win_region = win_->region(); + auto win_region = win_->region(); + + if (client_decorated_) + { + win_region.shrink(client_borders_.left + client_borders_.right, client_borders_.top + client_borders_.bottom); + win_region.translate(client_borders_.left - client_borders_.right, client_borders_.top - client_borders_.bottom); + } + quads[Quads::Pos::TOP_LEFT].region = CompRegion(quads[Quads::Pos::TOP_LEFT].box) - win_region; quads[Quads::Pos::TOP_RIGHT].region = CompRegion(quads[Quads::Pos::TOP_RIGHT].box) - win_region; quads[Quads::Pos::BOTTOM_LEFT].region = CompRegion(quads[Quads::Pos::BOTTOM_LEFT].box) - win_region; @@ -657,6 +691,9 @@ void Window::Impl::Draw(GLMatrix const& transformation, auto const& clip_region = (mask & PAINT_WINDOW_TRANSFORMED_MASK) ? infiniteRegion : region; mask |= PAINT_WINDOW_BLEND_MASK; + if (win_->alpha() || attrib.opacity != OPAQUE) + mask |= PAINT_WINDOW_TRANSLUCENT_MASK; + glwin_->vertexBuffer()->begin(); for (unsigned i = 0; i < shadow_quads_.size(); ++i) diff --git a/decorations/DecorationsManager.cpp b/decorations/DecorationsManager.cpp index e859850c9..4be19cb33 100644 --- a/decorations/DecorationsManager.cpp +++ b/decorations/DecorationsManager.cpp @@ -31,18 +31,15 @@ namespace decoration { Manager* manager_ = nullptr; -namespace -{ namespace atom { Atom _NET_REQUEST_FRAME_EXTENTS = 0; Atom _NET_WM_VISIBLE_NAME = 0; -} +Atom _UNITY_GTK_BORDER_RADIUS = 0; } Manager::Impl::Impl(decoration::Manager* parent, menu::Manager::Ptr const& menu) - : enable_add_supported_atoms_(true) - , data_pool_(DataPool::Get()) + : data_pool_(DataPool::Get()) , menu_manager_(menu) { if (!manager_) @@ -51,6 +48,7 @@ Manager::Impl::Impl(decoration::Manager* parent, menu::Manager::Ptr const& menu) Display* dpy = screen->dpy(); atom::_NET_REQUEST_FRAME_EXTENTS = XInternAtom(dpy, "_NET_REQUEST_FRAME_EXTENTS", False); atom::_NET_WM_VISIBLE_NAME = XInternAtom(dpy, "_NET_WM_VISIBLE_NAME", False); + atom::_UNITY_GTK_BORDER_RADIUS = XInternAtom(dpy, "_UNITY_GTK_BORDER_RADIUS", False); auto rebuild_cb = sigc::mem_fun(this, &Impl::OnShadowOptionsChanged); manager_->active_shadow_color.changed.connect(sigc::hide(sigc::bind(rebuild_cb, true))); @@ -65,12 +63,6 @@ Manager::Impl::Impl(decoration::Manager* parent, menu::Manager::Ptr const& menu) SetupIntegratedMenus(); } -Manager::Impl::~Impl() -{ - enable_add_supported_atoms_ = false; - screen->updateSupportedWmHints(); -} - cu::PixmapTexture::Ptr Manager::Impl::BuildShadowTexture(unsigned radius, nux::Color const& color) { int tex_size = radius * 4; @@ -279,6 +271,10 @@ bool Manager::Impl::HandleEventAfter(XEvent* event) win->title = wm.GetStringProperty(event->xproperty.window, event->xproperty.atom); } } + else if (event->xproperty.atom == atom::_UNITY_GTK_BORDER_RADIUS) + { + UpdateWindow(event->xproperty.window); + } break; } case ConfigureNotify: @@ -400,8 +396,8 @@ Manager::~Manager() void Manager::AddSupportedAtoms(std::vector<Atom>& atoms) const { - if (impl_->enable_add_supported_atoms_) - atoms.push_back(atom::_NET_REQUEST_FRAME_EXTENTS); + atoms.push_back(atom::_UNITY_GTK_BORDER_RADIUS); + atoms.push_back(atom::_NET_REQUEST_FRAME_EXTENTS); } bool Manager::HandleEventBefore(XEvent* xevent) diff --git a/decorations/DecorationsPriv.h b/decorations/DecorationsPriv.h index 4c3886b16..0192cb0a4 100644 --- a/decorations/DecorationsPriv.h +++ b/decorations/DecorationsPriv.h @@ -50,6 +50,11 @@ class ForceQuitDialog; namespace cu = compiz_utils; +namespace atom +{ +extern Atom _UNITY_GTK_BORDER_RADIUS; +} + struct Quads { enum class Pos @@ -93,7 +98,8 @@ struct Window::Impl private: void UnsetExtents(); void SetupExtents(); - void UpdateElements(cu::WindowFilter::Value wf = cu::WindowFilter::NONE); + void UpdateElements(cu::WindowFilter wf = cu::WindowFilter::NONE); + void UpdateClientDecorationsState(); void UpdateMonitor(); void UpdateFrame(); void CreateFrame(nux::Geometry const&); @@ -132,6 +138,7 @@ private: int monitor_; bool dirty_geo_; bool dirty_frame_; + bool client_decorated_; unsigned deco_elements_; unsigned last_mwm_decor_; unsigned last_actions_; @@ -140,6 +147,7 @@ private: Quads shadow_quads_; nux::Geometry frame_geo_; CompRegion frame_region_; + CompWindowExtents client_borders_; connection::Wrapper theme_changed_; connection::Wrapper dpi_changed_; connection::Wrapper grab_mouse_changed_; @@ -161,7 +169,6 @@ private: struct Manager::Impl : sigc::trackable { Impl(decoration::Manager*, menu::Manager::Ptr const&); - ~Impl(); Window::Ptr HandleWindow(CompWindow* cwin); bool HandleEventBefore(XEvent*); @@ -188,8 +195,6 @@ private: friend class Manager; friend struct Window::Impl; - bool enable_add_supported_atoms_; - DataPool::Ptr data_pool_; cu::PixmapTexture::Ptr active_shadow_pixmap_; cu::PixmapTexture::Ptr inactive_shadow_pixmap_; diff --git a/plugins/unityshell/src/inputremover.cpp b/plugins/unityshell/src/inputremover.cpp index ec09f9eeb..c24639c81 100644 --- a/plugins/unityshell/src/inputremover.cpp +++ b/plugins/unityshell/src/inputremover.cpp @@ -88,6 +88,7 @@ compiz::WindowInputRemover::WindowInputRemover (Display *dpy, Window shapeWindow, Window propWindow) : mDpy (dpy), + mProperty (XInternAtom (mDpy, "_UNITY_SAVED_WINDOW_SHAPE", False)), mShapeWindow (shapeWindow), mPropWindow (propWindow), mShapeMask (0), @@ -328,7 +329,6 @@ compiz::WindowInputRemover::writeProperty (XRectangle *input, int nInput, int inputOrdering) { - Atom prop = XInternAtom (mDpy, "_UNITY_SAVED_WINDOW_SHAPE", FALSE); Atom type = XA_CARDINAL; int fmt = 32; @@ -365,7 +365,7 @@ compiz::WindowInputRemover::writeProperty (XRectangle *input, /* No need to check return code, always returns 0 */ XChangeProperty(mDpy, mPropWindow, - prop, + mProperty, type, fmt, PropModeReplace, @@ -381,7 +381,6 @@ compiz::WindowInputRemover::queryProperty(XRectangle **input, int *inputOrdering) { - Atom prop = XInternAtom (mDpy, "_UNITY_SAVED_WINDOW_SHAPE", FALSE); Atom type = XA_CARDINAL; int fmt = 32; @@ -399,7 +398,7 @@ compiz::WindowInputRemover::queryProperty(XRectangle **input, * long the rest of the property is going to be */ if (!XGetWindowProperty(mDpy, mPropWindow, - prop, + mProperty, 0L, headerLength, FALSE, @@ -438,7 +437,7 @@ compiz::WindowInputRemover::queryProperty(XRectangle **input, if (!XGetWindowProperty(mDpy, mPropWindow, - prop, + mProperty, 0L, fullLength, FALSE, @@ -486,9 +485,7 @@ compiz::WindowInputRemover::queryProperty(XRectangle **input, void compiz::WindowInputRemover::clearProperty() { - Atom prop = XInternAtom (mDpy, "_UNITY_SAVED_WINDOW_SHAPE", FALSE); - - XDeleteProperty(mDpy, mPropWindow, prop); + XDeleteProperty(mDpy, mPropWindow, mProperty); } bool diff --git a/plugins/unityshell/src/inputremover.h b/plugins/unityshell/src/inputremover.h index d5c6f5a45..764327acb 100644 --- a/plugins/unityshell/src/inputremover.h +++ b/plugins/unityshell/src/inputremover.h @@ -97,6 +97,7 @@ private: void clearRectangles (); Display *mDpy; + Atom mProperty; Window mShapeWindow; Window mPropWindow; unsigned long mShapeMask; diff --git a/plugins/unityshell/src/unityshell.cpp b/plugins/unityshell/src/unityshell.cpp index 514eb2c83..a4108cc9a 100644 --- a/plugins/unityshell/src/unityshell.cpp +++ b/plugins/unityshell/src/unityshell.cpp @@ -175,6 +175,13 @@ const std::string HUD_UNGRAB_WAIT = "hud-ungrab-wait"; const std::string FIRST_RUN_STAMP = "first_run.stamp"; const std::string LOCKED_STAMP = "locked.stamp"; } // namespace local + +namespace atom +{ +Atom _UNITY_SHELL = 0; +Atom _UNITY_SAVED_WINDOW_SHAPE = 0; +} + } // anon namespace UnityScreen::UnityScreen(CompScreen* screen) @@ -311,6 +318,9 @@ UnityScreen::UnityScreen(CompScreen* screen) CompositeScreenInterface::setHandler(cScreen); GLScreenInterface::setHandler(gScreen); ScaleScreenInterface::setHandler(sScreen); + + atom::_UNITY_SHELL = XInternAtom(screen->dpy(), "_UNITY_SHELL", False); + atom::_UNITY_SAVED_WINDOW_SHAPE = XInternAtom(screen->dpy(), "_UNITY_SAVED_WINDOW_SHAPE", False); screen->updateSupportedWmHints(); nux::NuxInitialize(0); @@ -504,8 +514,10 @@ UnityScreen::~UnityScreen() QuicklistManager::Destroy(); decoration::DataPool::Reset(); SaveLockStamp(false); - reset_glib_logging(); + + screen->addSupportedAtomsSetEnabled(this, false); + screen->updateSupportedWmHints(); } void UnityScreen::InitAltTabNextWindow() @@ -1768,6 +1780,8 @@ void UnityScreen::determineNuxDamage(CompRegion& nux_damage) void UnityScreen::addSupportedAtoms(std::vector<Atom>& atoms) { screen->addSupportedAtoms(atoms); + atoms.push_back(atom::_UNITY_SHELL); + atoms.push_back(atom::_UNITY_SAVED_WINDOW_SHAPE); deco_manager_->AddSupportedAtoms(atoms); } @@ -3028,9 +3042,8 @@ bool UnityWindow::glPaint(const GLWindowPaintAttrib& attrib, wAttrib.brightness *= 0.75f; } - bool ret = gWindow->glPaint(wAttrib, matrix, region, mask); deco_win_->Paint(matrix, wAttrib, region, mask); - return ret; + return gWindow->glPaint(wAttrib, matrix, region, mask); } /* handle window painting in an opengl context @@ -3153,8 +3166,8 @@ bool UnityWindow::glDraw(const GLMatrix& matrix, if (draw_panel_shadow == DrawPanelShadow::BELOW_WINDOW) uScreen->paintPanelShadow(region); - bool ret = gWindow->glDraw(matrix, attrib, region, mask); deco_win_->Draw(matrix, attrib, region, mask); + bool ret = gWindow->glDraw(matrix, attrib, region, mask); if (draw_panel_shadow == DrawPanelShadow::OVER_WINDOW) uScreen->paintPanelShadow(region); @@ -4181,13 +4194,17 @@ bool WindowHasInconsistentShapeRects(Display *d, Window w) int n; Atom *atoms = XListProperties(d, w, &n); bool has_inconsistent_shape = false; - static Atom unity_shape_rects_atom = XInternAtom(d, "_UNITY_SAVED_WINDOW_SHAPE", False); for (int i = 0; i < n; ++i) - if (atoms[i] == unity_shape_rects_atom) + { + if (atoms[i] == atom::_UNITY_SAVED_WINDOW_SHAPE) + { has_inconsistent_shape = true; + break; + } + } - XFree (atoms); + XFree(atoms); return has_inconsistent_shape; } } diff --git a/unity-shared/CompizUtils.cpp b/unity-shared/CompizUtils.cpp index b49c8cc00..acd1e15a3 100644 --- a/unity-shared/CompizUtils.cpp +++ b/unity-shared/CompizUtils.cpp @@ -177,7 +177,7 @@ int CairoContext::height() const // // -unsigned WindowDecorationElements(CompWindow* win, WindowFilter::Value wf) +unsigned WindowDecorationElements(CompWindow* win, WindowFilter wf) { unsigned elements = DecorationElement::NONE; @@ -194,8 +194,22 @@ unsigned WindowDecorationElements(CompWindow* win, WindowFilter::Value wf) bool rectangular = (region.numRects() == 1); bool alpha = win->alpha(); - if (!rectangular && alpha) // Non-rectangular windows with alpha channel - return elements; + if (alpha) + { + if (wf == WindowFilter::CLIENTSIDE_DECORATED) + { + elements = DecorationElement::SHADOW; + + if (win->actions() & CompWindowActionResizeMask) + elements |= DecorationElement::EDGE; + + return elements; + } + else if (!rectangular) // Non-rectangular windows with alpha channel + { + return elements; + } + } if (region.boundingRect() != win->geometry()) // Shaped windows return elements; diff --git a/unity-shared/CompizUtils.h b/unity-shared/CompizUtils.h index 8129ab2b7..ef4b03c88 100644 --- a/unity-shared/CompizUtils.h +++ b/unity-shared/CompizUtils.h @@ -119,14 +119,12 @@ private: cairo_t *cr_; }; -namespace WindowFilter -{ -enum Value +enum class WindowFilter { NONE, - UNMAPPED + UNMAPPED, + CLIENTSIDE_DECORATED }; -} namespace DecorationElement { @@ -140,7 +138,7 @@ enum }; } -unsigned WindowDecorationElements(CompWindow*, WindowFilter::Value wf = WindowFilter::NONE); +unsigned WindowDecorationElements(CompWindow*, WindowFilter wf = WindowFilter::NONE); bool IsWindowEdgeDecorable(CompWindow*); bool IsWindowShadowDecorable(CompWindow*); |
