Merge lp:~smspillaz/unity/unity.stack_debug_fixed_minimized_windows into lp:unity

Proposed by Sam Spilsbury
Status: Merged
Approved by: Neil J. Patel
Approved revision: no longer in the source branch.
Merged at revision: 1529
Proposed branch: lp:~smspillaz/unity/unity.stack_debug_fixed_minimized_windows
Merge into: lp:unity
Diff against target: 277 lines (+142/-33)
4 files modified
plugins/unityshell/src/compizminimizedwindowhandler.h (+4/-30)
plugins/unityshell/src/inputremover.cpp (+132/-0)
plugins/unityshell/src/inputremover.h (+4/-1)
plugins/unityshell/src/minimizedwindowhandler.cpp (+2/-2)
To merge this branch: bzr merge lp:~smspillaz/unity/unity.stack_debug_fixed_minimized_windows
Reviewer Review Type Date Requested Status
Neil J. Patel (community) Approve
Review via email: mp+74792@code.launchpad.net

Description of the change

Fixes a case where minimized windows would not get their frame region restored correctly because we used XShape on the frame window directly.

Send a synethetic ShapeNotify instead and let core figure it out.

To post a comment you must log in.
Revision history for this message
Neil J. Patel (njpatel) :
review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'plugins/unityshell/src/compizminimizedwindowhandler.h'
--- plugins/unityshell/src/compizminimizedwindowhandler.h 2011-09-02 14:32:40 +0000
+++ plugins/unityshell/src/compizminimizedwindowhandler.h 2011-09-09 13:52:44 +0000
@@ -37,7 +37,6 @@
37 PrivateCompizMinimizedWindowHandler () {};37 PrivateCompizMinimizedWindowHandler () {};
3838
39 CompWindow *mWindow;39 CompWindow *mWindow;
40 WindowInputRemover *clientInputRemover;
41};40};
4241
43template <typename Screen, typename Window>42template <typename Screen, typename Window>
@@ -87,7 +86,6 @@
87 priv = new PrivateCompizMinimizedWindowHandler ();86 priv = new PrivateCompizMinimizedWindowHandler ();
8887
89 priv->mWindow = w;88 priv->mWindow = w;
90 priv->clientInputRemover = NULL;
9189
92}90}
9391
@@ -115,33 +113,7 @@
115void113void
116compiz::CompizMinimizedWindowHandler<Screen, Window>::setVisibility (bool visible)114compiz::CompizMinimizedWindowHandler<Screen, Window>::setVisibility (bool visible)
117{115{
118 CompWindow::Geometry gm = priv->mWindow->geometry ();116 MinimizedWindowHandler::setVisibility (visible, priv->mWindow->id ());
119 MinimizedWindowHandler::setVisibility (visible, ROOTPARENT (priv->mWindow));
120
121 if (!visible && !priv->clientInputRemover)
122 {
123 priv->clientInputRemover = new compiz::WindowInputRemover (screen->dpy (), priv->mWindow->id ());
124 if (!priv->clientInputRemover)
125 return;
126
127 if (priv->clientInputRemover->save ())
128 priv->clientInputRemover->remove ();
129 }
130 else if (visible && priv->clientInputRemover)
131 {
132 priv->clientInputRemover->restore ();
133
134 delete priv->clientInputRemover;
135 priv->clientInputRemover = NULL;
136 }
137
138 /* This is a little hack to ensure that the window region gets updated,
139 * because there's no API in core to do that */
140
141 gm.setBorder (gm.border () + 1);
142 priv->mWindow->resize (gm);
143 gm.setBorder (gm.border () - 1);
144 priv->mWindow->resize (gm);
145117
146 CompositeWindow::get (priv->mWindow)->addDamage ();118 CompositeWindow::get (priv->mWindow)->addDamage ();
147 GLWindow::get (priv->mWindow)->glPaintSetEnabled (Window::get (priv->mWindow), !visible);119 GLWindow::get (priv->mWindow)->glPaintSetEnabled (Window::get (priv->mWindow), !visible);
@@ -285,8 +257,10 @@
285void257void
286compiz::CompizMinimizedWindowHandler<Screen, Window>::handleEvent (XEvent *event)258compiz::CompizMinimizedWindowHandler<Screen, Window>::handleEvent (XEvent *event)
287{259{
260 /* Ignore sent events from the InputRemover */
288 if (screen->XShape () && event->type ==261 if (screen->XShape () && event->type ==
289 screen->shapeEvent () + ShapeNotify)262 screen->shapeEvent () + ShapeNotify &&
263 !event->xany.send_event)
290 {264 {
291 CompWindow *w = screen->findWindow (((XShapeEvent *) event)->window);265 CompWindow *w = screen->findWindow (((XShapeEvent *) event)->window);
292266
293267
=== modified file 'plugins/unityshell/src/inputremover.cpp'
--- plugins/unityshell/src/inputremover.cpp 2011-09-02 14:32:40 +0000
+++ plugins/unityshell/src/inputremover.cpp 2011-09-09 13:52:44 +0000
@@ -20,6 +20,7 @@
20 */20 */
2121
22#include "inputremover.h"22#include "inputremover.h"
23#include <X11/Xregion.h>
23#include <cstdio>24#include <cstdio>
2425
25compiz::WindowInputRemover::WindowInputRemover (Display *dpy,26compiz::WindowInputRemover::WindowInputRemover (Display *dpy,
@@ -43,6 +44,132 @@
43 restore ();44 restore ();
44}45}
4546
47void
48compiz::WindowInputRemover::sendShapeNotify ()
49{
50 /* Send a synthetic ShapeNotify event to the root window
51 * since we ignored shape events when setting visibility
52 * in order to avoid cycling in the shape handling code -
53 * ignore the sent shape notify event since that will
54 * be send_event = true */
55
56 XShapeEvent xsev;
57 XEvent *xev = (XEvent *) &xsev;
58 Window rootReturn, parentReturn;
59 Window childReturn;
60 Window *children;
61 int x, y, xOffset, yOffset;
62 unsigned int width, height, depth, border, nchildren;
63 int shapeEvent, shapeError, shapeMask;
64
65 /* FIXME: roundtrip */
66 XShapeQueryExtension (mDpy, &shapeEvent, &shapeError);
67 shapeMask = XShapeInputSelected (mDpy, mShapeWindow);
68
69 xev->type = shapeEvent + ShapeNotify;
70 xsev.window = mShapeWindow;
71
72 if (!mRemoved)
73 {
74 /* FIXME: these roundtrips suck */
75 XGetGeometry (mDpy, mShapeWindow, &rootReturn, &x, &y, &width, &height, &depth, &border);
76 XQueryTree (mDpy, mShapeWindow, &rootReturn, &parentReturn, &children, &nchildren);
77
78 /* We need to translate the co-ordinates of the origin to the
79 * client window to its parent to find out the offset of its
80 * position so that we can subtract that from the final bounding
81 * rect of the window shape according to the Shape extension
82 * specification */
83
84 XTranslateCoordinates (mDpy, mShapeWindow, parentReturn, 0, 0, &xOffset, &yOffset, &childReturn);
85
86 xev->type = ShapeBounding;
87
88 /* Calculate extents of the bounding shape */
89 if (!mNBoundingRects)
90 {
91 /* No set input shape, we must use the client geometry */
92 xsev.x = x - xOffset;
93 xsev.y = y - yOffset;
94 xsev.width = width;
95 xsev.height = height;
96 xsev.shaped = false;
97 }
98 else
99 {
100 Region boundingRegion = XCreateRegion ();
101
102 for (int i = 0; i < mNBoundingRects; i++)
103 XUnionRectWithRegion (&(mBoundingRects[i]), boundingRegion, boundingRegion);
104
105 xsev.x = boundingRegion->extents.x1 - xOffset;
106 xsev.y = boundingRegion->extents.y1 - yOffset;
107 xsev.width = boundingRegion->extents.x2 - boundingRegion->extents.x1;
108 xsev.height = boundingRegion->extents.y2 - boundingRegion->extents.y1;
109 xsev.shaped = true;
110
111 XDestroyRegion (boundingRegion);
112 }
113
114 xsev.time = CurrentTime;
115 XSendEvent (mDpy, DefaultRootWindow (mDpy), false, shapeMask, xev);
116
117 xev->type = ShapeInput;
118
119 /* Calculate extents of the bounding shape */
120 if (!mNInputRects)
121 {
122 /* No set input shape, we must use the client geometry */
123 xsev.x = x - xOffset;
124 xsev.y = y - yOffset;
125 xsev.width = width;
126 xsev.height = height;
127 xsev.shaped = false;
128 }
129 else
130 {
131 Region inputRegion = XCreateRegion ();
132
133 for (int i = 0; i < mNInputRects; i++)
134 XUnionRectWithRegion (&(mInputRects[i]), inputRegion, inputRegion);
135
136 xsev.x = inputRegion->extents.x1 - xOffset;
137 xsev.y = inputRegion->extents.y1 - yOffset;
138 xsev.width = inputRegion->extents.x2 - inputRegion->extents.x1;
139 xsev.height = inputRegion->extents.y2 - inputRegion->extents.y1;
140 xsev.shaped = true;
141
142 XDestroyRegion (inputRegion);
143 }
144
145 xsev.time = CurrentTime;
146 XSendEvent (mDpy, DefaultRootWindow (mDpy), false, shapeMask, xev);
147
148 if (children)
149 XFree (children);
150 }
151 else
152 {
153 xev->type = ShapeBounding;
154
155 xsev.x = 0;
156 xsev.y = 0;
157 xsev.width = 0;
158 xsev.height = 0;
159 xsev.shaped = true;
160
161 xsev.time = CurrentTime;
162 XSendEvent (mDpy, DefaultRootWindow (mDpy), false, shapeMask, xev);
163
164 xev->type = ShapeInput;
165
166 /* Both ShapeBounding and ShapeInput are null */
167
168 xsev.time = CurrentTime;
169 XSendEvent (mDpy, DefaultRootWindow (mDpy), false, shapeMask, xev);
170 }
171}
172
46bool173bool
47compiz::WindowInputRemover::save ()174compiz::WindowInputRemover::save ()
48{175{
@@ -111,6 +238,8 @@
111238
112 XShapeSelectInput (mDpy, mShapeWindow, ShapeNotify);239 XShapeSelectInput (mDpy, mShapeWindow, ShapeNotify);
113240
241 sendShapeNotify ();
242
114 mRemoved = true;243 mRemoved = true;
115 return true;244 return true;
116}245}
@@ -125,6 +254,7 @@
125 XShapeCombineRectangles (mDpy, mShapeWindow, ShapeInput, 0, 0,254 XShapeCombineRectangles (mDpy, mShapeWindow, ShapeInput, 0, 0,
126 mInputRects, mNInputRects,255 mInputRects, mNInputRects,
127 ShapeSet, mInputRectOrdering);256 ShapeSet, mInputRectOrdering);
257
128 }258 }
129 else259 else
130 {260 {
@@ -153,6 +283,8 @@
153283
154 XShapeSelectInput (mDpy, mShapeWindow, mShapeMask);284 XShapeSelectInput (mDpy, mShapeWindow, mShapeMask);
155285
286 sendShapeNotify ();
287
156 mRemoved = false;288 mRemoved = false;
157 mNInputRects = 0;289 mNInputRects = 0;
158 mInputRects = NULL;290 mInputRects = NULL;
159291
=== modified file 'plugins/unityshell/src/inputremover.h'
--- plugins/unityshell/src/inputremover.h 2011-09-01 17:18:02 +0000
+++ plugins/unityshell/src/inputremover.h 2011-09-09 13:52:44 +0000
@@ -41,6 +41,9 @@
41 bool restore ();41 bool restore ();
4242
43private:43private:
44
45 void sendShapeNotify ();
46
44 Display *mDpy;47 Display *mDpy;
45 Window mShapeWindow;48 Window mShapeWindow;
46 unsigned long mShapeMask;49 unsigned long mShapeMask;
@@ -52,7 +55,7 @@
52 XRectangle *mBoundingRects;55 XRectangle *mBoundingRects;
53 int mNBoundingRects;56 int mNBoundingRects;
54 int mBoundingRectOrdering;57 int mBoundingRectOrdering;
55 bool mRemoved;58 bool mRemoved;
5659
57};60};
58}61}
5962
=== modified file 'plugins/unityshell/src/minimizedwindowhandler.cpp'
--- plugins/unityshell/src/minimizedwindowhandler.cpp 2011-08-26 10:37:35 +0000
+++ plugins/unityshell/src/minimizedwindowhandler.cpp 2011-09-09 13:52:44 +0000
@@ -58,10 +58,10 @@
58 {58 {
59 priv->mRemover = new compiz::WindowInputRemover (priv->mDpy, shapeWin);59 priv->mRemover = new compiz::WindowInputRemover (priv->mDpy, shapeWin);
60 if (!priv->mRemover)60 if (!priv->mRemover)
61 return;61 return;
6262
63 if (priv->mRemover->save ())63 if (priv->mRemover->save ())
64 priv->mRemover->remove ();64 priv->mRemover->remove ();
65 }65 }
66 else if (visible && priv->mRemover)66 else if (visible && priv->mRemover)
67 {67 {