summaryrefslogtreecommitdiff
diff options
authorMarco Trevisan (TreviƱo) <mail@3v1n0.net>2016-03-10 10:09:29 +0000
committerCI Train Bot <ci-train-bot@canonical.com>2016-03-10 10:09:29 +0000
commit641d4cd0b42aab89186ca977971e49f335e6c31c (patch)
tree4f5fa50aad835a98142c4f2bf733dd0b7eaba293
parent7aff5c5e617272b6d0ea210262028db65641b56d (diff)
parentbd4f8127fcd9945e3c27e24518f0d557c5f651cf (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.cpp47
-rw-r--r--decorations/DecorationsManager.cpp22
-rw-r--r--decorations/DecorationsPriv.h13
-rw-r--r--plugins/unityshell/src/inputremover.cpp13
-rw-r--r--plugins/unityshell/src/inputremover.h1
-rw-r--r--plugins/unityshell/src/unityshell.cpp31
-rw-r--r--unity-shared/CompizUtils.cpp20
-rw-r--r--unity-shared/CompizUtils.h10
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*);