Merge lp:~mc-return/compiz/compiz.merge-fix771448-desktop-wall-edge-flipping-broken into lp:compiz/0.9.10

Proposed by MC Return
Status: Merged
Approved by: Sam Spilsbury
Approved revision: 3680
Merged at revision: 3707
Proposed branch: lp:~mc-return/compiz/compiz.merge-fix771448-desktop-wall-edge-flipping-broken
Merge into: lp:compiz/0.9.10
Diff against target: 440 lines (+138/-128)
5 files modified
plugins/wall/src/wall.cpp (+76/-121)
plugins/wall/src/wall.h (+2/-5)
plugins/wall/wall.xml.in (+4/-1)
src/screen.cpp (+7/-1)
tests/manual/plugins/wall.txt (+49/-0)
To merge this branch: bzr merge lp:~mc-return/compiz/compiz.merge-fix771448-desktop-wall-edge-flipping-broken
Reviewer Review Type Date Requested Status
PS Jenkins bot (community) continuous-integration Approve
Sam Spilsbury Approve
Review via email: mp+161103@code.launchpad.net

Commit message

Wall:
Fixed broken wall edge flipping functions:
"Edge Flip Pointer"
"Edge Flip Move"

Removed void WallScreen::updateScreenEdgeRegions () completely.
This function not needed hereat all, no other plugin
needs to re-define the screen edge regions by itself -
just core should do that.
The screen edge region updating also confused the edge flipping functionality.
case ConfigureNotify: just breaks out now
Added missing default: case and a break (just a style issue).

Minor cleanup in bool WallScreen::initiateFlip (...).
One declaration per line.

Note: "Edge Flip DnD" still seems to be broken, but will be fixed in a follow-up
proposal.

(LP: #771448, LP: #858845)

To post a comment you must log in.
Revision history for this message
Sam Spilsbury (smspillaz) wrote :

I figured the screen edge update stuff would be controversial when I added it a few years ago.

The reason why its there is because the screen edge detection windows had an annoying tendency to block input on, eg, panels. That was really, really, annoying.

Instead of removing them, I'd suggest trying to say if you can make it work with that code.

The way it's meant to work as I understand it is that when a window is being dragged, the screen edges will be dynamically re-enabled. Although it was really complicated to get right now I remember, because we had to detect when a grab happened and then figure out whether or not the edges should be enabled because of XDnD grabs being external to our own.

I might branch this off myself tonight and see if I can come up with something a bit better, as it was quite complicated.

review: Abstain
Revision history for this message
Sam Spilsbury (smspillaz) wrote :

So what I'm thinking is that we can probably remove the mousepoll + edge update stuff and do something like this:

1. On grab, turn all edges on (eg, toggleEdges)
2. Listen for xdndEnter and xdndLeave events
3. When an edge action is triggered, if we don't have "pointer" edge flipping enabled then:
   a. If "edge flip move" is enabled check if:
      1. There has been a grabbed window and
      2. Its grabbed for moving
   b. If "edge flip dnd" is enabled check if:
      1. We currently have the xdndEnter event for an edge.

This might require some core changes too - to check if an edge was entered for a DnD event.

Revision history for this message
MC Return (mc-return) wrote :

> I figured the screen edge update stuff would be controversial when I added it
> a few years ago.
>
> The reason why its there is because the screen edge detection windows had an
> annoying tendency to block input on, eg, panels. That was really, really,
> annoying.
>
Well, there are no regressions here, maybe there once were.

> Instead of removing them, I'd suggest trying to say if you can make it work
> with that code.
>
Why ?
It is not needed here -> look at rotate cube, where the edge flipping works
perfectly as well, completely without the plugin trying to take over core's work.

> The way it's meant to work as I understand it is that when a window is being
> dragged, the screen edges will be dynamically re-enabled. Although it was
> really complicated to get right now I remember, because we had to detect when
> a grab happened and then figure out whether or not the edges should be enabled
> because of XDnD grabs being external to our own.
>
I really do not see a reason to overcomplicate stuff in this case.

> I might branch this off myself tonight and see if I can come up with something
> a bit better, as it was quite complicated.

Sure, but I recommend to not reinvent the wheel for this, rather take some other
bug and fix it ;)

Revision history for this message
MC Return (mc-return) wrote :

> So what I'm thinking is that we can probably remove the mousepoll + edge
> update stuff and do something like this:
>
> 1. On grab, turn all edges on (eg, toggleEdges)
> 2. Listen for xdndEnter and xdndLeave events
> 3. When an edge action is triggered, if we don't have "pointer" edge flipping
> enabled then:
> a. If "edge flip move" is enabled check if:
> 1. There has been a grabbed window and
> 2. Its grabbed for moving
> b. If "edge flip dnd" is enabled check if:
> 1. We currently have the xdndEnter event for an edge.
>
> This might require some core changes too - to check if an edge was entered for
> a DnD event.

I really see no reason for this -> I have a multimonitor system and all edge-flip
cube stuff is always working here...

If you want to fix a thing regarding the screen edges, please-please-please fix
this one:

bug #1011167

Revision history for this message
Sam Spilsbury (smspillaz) wrote :

At least testing on my end shows that xdnd edge flipping is not working with this branch. Which is why I wanted to have a further look into it because I know the issues there were quite complicated.

Give me a little bit of time with this.

As for LP: #110167 - I commented on the bug report.

Revision history for this message
Sam Spilsbury (smspillaz) wrote :

Actually, I can't reproduce any of the issues you've mentioned in this branch on trunk. Edge flipping works fine in wall regardless.

But in any case I still think that the requirement to do mouse polling and a screen edge detection workaround is a bit of a kludge. So I'll see if I can come up with something better.

Revision history for this message
MC Return (mc-return) wrote :

> At least testing on my end shows that xdnd edge flipping is not working with
> this branch. Which is why I wanted to have a further look into it because I
> know the issues there were quite complicated.
>
That is really strange -> it is working perfectly here, I even tried 2x2 configurations.
I can use the pointer to flip and I can move windows around the 4 desktops, which was
not working before.

Damn - you are right -> DnD of icons does not seem to work, but note that this branch also
seems to fix: bug #858845

> Give me a little bit of time with this.
>
Sure. I will pause working on wall then...

Revision history for this message
MC Return (mc-return) wrote :

> Actually, I can't reproduce any of the issues you've mentioned in this branch
> on trunk. Edge flipping works fine in wall regardless.
>
I do not think that I am hallucinating, 26 other people marked the bug as affecting them ;)

Well, bug #1172881 was the reason I started looking into this issue, as I usually
have the cube running to rotate to my desktops and Compiz does not allow me to
use wall and cube together (bug #1173256).

When I started looking into it I noticed that it is a duplicate of bug #771448,
which affects 26 other people, was reported as regression on 2011-04-26 and has over 100 heat.
So I thought it is an issue worth looking into and when I discovered the strange,
duplicated core code in there, I remembered bug #858845, which I never could reproduce locally,
because wall was always disabled here, because... (see above)

Bug #858845 affects 136 other people, was reported on 2011-09-25.
Those people also seem credible to me...

> But in any case I still think that the requirement to do mouse polling and a
> screen edge detection workaround is a bit of a kludge. So I'll see if I can
> come up with something better.

As long as it is efficient, does not create regressions and works I'm fine with that solution also of course.

Revision history for this message
MC Return (mc-return) wrote :

My suggestion: Let us simply get this in first, then your corrections afterwards...

3678. By MC Return

Merged latest lp:compiz

Revision history for this message
MC Return (mc-return) wrote :

I've adjusted the commit message...

Revision history for this message
Sam Spilsbury (smspillaz) wrote :

Can you merge this with lp:compiz again after your other merges land?

review: Needs Resubmitting
3679. By MC Return

Merged latest lp:compiz

3680. By MC Return

wall: Remove mouse polling edge flip detection code, instead turn edges on
      in the following situations:

    1. Edge flip pointer is on (always on)
    2. Edge flip move is on, and the screen is grabbed (someone is moving
       a window)
    3. Edge flip dnd is on, and a dnd type window is mapped (someone is
       doing a dnd)

Fix a misconstructed boolean condition in removeAction that could cause
actions to be removed twice and as such cause the edge reference count to
go negative.

Note that dnd window detection is a bit imprecise, but I didn't want to resort
to using some exotic workarounds for the dnd edge cases (such as non-EWMH
compliant dnd windows which are still compliant with ICCCM).

Revision history for this message
Sam Spilsbury (smspillaz) wrote :

Excellent.

review: Approve
Revision history for this message
PS Jenkins bot (ps-jenkins) :
review: Approve (continuous-integration)

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'plugins/wall/src/wall.cpp'
2--- plugins/wall/src/wall.cpp 2013-05-09 13:43:07 +0000
3+++ plugins/wall/src/wall.cpp 2013-05-15 10:56:26 +0000
4@@ -495,29 +495,24 @@
5
6 moveViewport (-dx, -dy, None);
7 }
8- if (event->xclient.message_type == Atoms::xdndEnter)
9- {
10- toggleEdges (true);
11- edgeDrag = true;
12- }
13- else if (event->xclient.message_type == Atoms::xdndLeave)
14- edgeDrag = false;
15
16 break;
17
18 case FocusIn:
19 case FocusOut:
20- if (event->xfocus.mode == NotifyGrab)
21- poller.start ();
22- else if (event->xfocus.mode == NotifyUngrab)
23- poller.stop ();
24- break;
25+ /* Edges on when grabbed */
26+ if (!optionGetEdgeflipPointer ())
27+ {
28+ if (event->xfocus.mode == NotifyGrab)
29+ toggleEdges (true);
30+ else if (event->xfocus.mode == NotifyUngrab)
31+ toggleEdges (false);
32+ }
33
34 case ConfigureNotify:
35-
36- if (event->xconfigure.window == screen->root ())
37- updateScreenEdgeRegions ();
38-
39+ break;
40+
41+ default:
42 break;
43 }
44
45@@ -525,67 +520,32 @@
46 }
47
48 /*
49- * Borrowed this from PrivateScreen::updateScreenEdges
50- *
51+ * When a dnd type window is mapped toggle edge flip dnd windows back on
52+ * _NET_WM_WINDOW_TYPE_DND windows. This will not detect all dnd windows
53+ * but it will detect the EWMH-compliant ones without resorting to
54+ * hacks involving selection stealing.
55 */
56-
57-#define SCREEN_EDGE_NUM 8
58-
59-void
60-WallScreen::updateScreenEdgeRegions ()
61-{
62- edgeRegion = CompRegion (0, 0, screen->width (), screen->height ());
63- noEdgeRegion = CompRegion (0, 0, screen->width (), screen->height ());
64-
65- struct screenEdgeGeometry {
66- int xw, x0;
67- int yh, y0;
68- int ww, w0;
69- int hh, h0;
70- } geometry[SCREEN_EDGE_NUM] = {
71- { 0, 0, 0, 2, 0, 2, 1, -4 }, /* left */
72- { 1, -2, 0, 2, 0, 2, 1, -4 }, /* right */
73- { 0, 2, 0, 0, 1, -4, 0, 2 }, /* top */
74- { 0, 2, 1, -2, 1, -4, 0, 2 }, /* bottom */
75- { 0, 0, 0, 0, 0, 2, 0, 2 }, /* top-left */
76- { 1, -2, 0, 0, 0, 2, 0, 2 }, /* top-right */
77- { 0, 0, 1, -2, 0, 2, 0, 2 }, /* bottom-left */
78- { 1, -2, 1, -2, 0, 2, 0, 2 } /* bottom-right */
79- };
80-
81- for (unsigned int i = 0; i < SCREEN_EDGE_NUM; i++)
82- {
83- CompRegion edge (geometry[i].xw * screen->width () +
84- geometry[i].x0,
85- geometry[i].yh * screen->height () +
86- geometry[i].y0,
87- geometry[i].ww * screen->width () +
88- geometry[i].w0,
89- geometry[i].hh * screen->height () +
90- geometry[i].h0);
91-
92- noEdgeRegion -= edgeRegion;
93- }
94-
95- edgeRegion -= noEdgeRegion;
96-}
97-
98-#undef SCREEN_EDGE_NUM
99-
100-void
101-WallScreen::positionUpdate (const CompPoint &pos)
102-{
103- if (edgeDrag)
104- return;
105-
106- if (edgeRegion.contains (pos))
107- toggleEdges (false);
108- else if (noEdgeRegion.contains (pos))
109- {
110- if (!screen->grabbed ())
111- poller.stop ();
112- toggleEdges (true);
113- }
114+void
115+WallWindow::windowNotify (CompWindowNotify n)
116+{
117+ WallScreen *ws = WallScreen::get (screen);
118+ bool toggleOnDnd = ws->optionGetEdgeflipDnd ();
119+
120+ switch (n)
121+ {
122+ case CompWindowNotifyMap:
123+ if (window->type () & CompWindowTypeDndMask && toggleOnDnd)
124+ ws->toggleEdges (true);
125+ break;
126+ case CompWindowNotifyUnmap:
127+ if (window->type () & CompWindowTypeDndMask && toggleOnDnd)
128+ ws->toggleEdges (false);
129+ break;
130+ default:
131+ break;
132+ }
133+
134+ window->windowNotify (n);
135 }
136
137 void
138@@ -648,19 +608,19 @@
139 void
140 WallWindow::grabNotify (int x,
141 int y,
142- unsigned int width,
143- unsigned int height)
144+ unsigned int state,
145+ unsigned int mask)
146 {
147- WallScreen::get (screen)->toggleEdges (true);
148- WallScreen::get (screen)->edgeDrag = true;
149+ if (mask & (CompWindowGrabMoveMask | CompWindowGrabButtonMask))
150+ WallScreen::get (screen)->windowIsDragMoved = true;
151
152- window->grabNotify (x, y, width, height);
153+ window->grabNotify (x, y, state, mask);
154 }
155
156 void
157 WallWindow::ungrabNotify ()
158 {
159- WallScreen::get (screen)->edgeDrag = false;
160+ WallScreen::get (screen)->windowIsDragMoved = false;
161
162 window->ungrabNotify ();
163 }
164@@ -804,49 +764,47 @@
165 WallScreen::initiateFlip (Direction direction,
166 CompAction::State state)
167 {
168+ CompOption::Vector o (0);
169+
170 int dx, dy;
171 int amountX, amountY;
172
173- if (screen->otherGrabExist ("wall", "move", "group-drag", 0))
174- return false;
175-
176- if (state & CompAction::StateInitEdgeDnd)
177- {
178- if (!optionGetEdgeflipDnd ())
179- return false;
180- }
181- else if (screen->grabExist ("move"))
182- {
183- if (!optionGetEdgeflipMove ())
184- return false;
185- }
186- else if (screen->grabExist ("group-drag"))
187- {
188- if (!optionGetEdgeflipDnd ())
189- return false;
190- }
191- else if (!optionGetEdgeflipPointer ())
192- {
193- toggleEdges (false);
194- poller.start ();
195- return false;
196- }
197-
198- switch (direction) {
199+ const bool allowFlipDnd = (state & CompAction::StateInitEdgeDnd) &&
200+ optionGetEdgeflipDnd ();
201+ const bool allowFlipMove = (windowIsDragMoved &&
202+ optionGetEdgeflipMove ());
203+ const bool allowFlipPointer = optionGetEdgeflipPointer ();
204+
205+ if (!allowFlipDnd &&
206+ !allowFlipMove &&
207+ !allowFlipPointer)
208+ return false;
209+
210+ switch (direction)
211+ {
212 case Left:
213- dx = -1; dy = 0;
214+ dx = -1;
215+ dy = 0;
216 break;
217+
218 case Right:
219- dx = 1; dy = 0;
220+ dx = 1;
221+ dy = 0;
222 break;
223+
224 case Up:
225- dx = 0; dy = -1;
226+ dx = 0;
227+ dy = -1;
228 break;
229+
230 case Down:
231- dx = 0; dy = 1;
232+ dx = 0;
233+ dy = 1;
234 break;
235+
236 default:
237- dx = 0; dy = 0;
238+ dx = 0;
239+ dy = 0;
240 break;
241 }
242
243@@ -1610,6 +1568,9 @@
244 ww->isSliding = !optionGetNoSlideMatch ().evaluate (w);
245 }
246 break;
247+ case WallOptions::EdgeflipPointer:
248+ toggleEdges (optionGetEdgeflipPointer ());
249+ break;
250
251 default:
252 break;
253@@ -1670,7 +1631,7 @@
254 moveWindow (None),
255 focusDefault (true),
256 transform (NoTransformation),
257- edgeDrag (false)
258+ windowIsDragMoved (false)
259 {
260 ScreenInterface::setHandler (screen);
261 CompositeScreenInterface::setHandler (cScreen);
262@@ -1737,11 +1698,6 @@
263 setNotify (ArrowShadowColor);
264 setNotify (NoSlideMatch);
265 setNotify (EdgeflipPointer);
266-
267- updateScreenEdgeRegions ();
268-
269- poller.setCallback (boost::bind (&WallScreen::positionUpdate, this,
270- _1));
271 }
272
273 WallScreen::~WallScreen ()
274@@ -1770,8 +1726,7 @@
275 {
276 if (CompPlugin::checkPluginABI ("core", CORE_ABIVERSION) &&
277 CompPlugin::checkPluginABI ("composite", COMPIZ_COMPOSITE_ABI) &&
278- CompPlugin::checkPluginABI ("opengl", COMPIZ_OPENGL_ABI) &&
279- CompPlugin::checkPluginABI ("mousepoll", COMPIZ_MOUSEPOLL_ABI))
280+ CompPlugin::checkPluginABI ("opengl", COMPIZ_OPENGL_ABI))
281 return true;
282
283 return false;
284
285=== modified file 'plugins/wall/src/wall.h'
286--- plugins/wall/src/wall.h 2013-01-04 08:43:45 +0000
287+++ plugins/wall/src/wall.h 2013-05-15 10:56:26 +0000
288@@ -124,7 +124,6 @@
289 void toggleEdges (bool);
290
291 void positionUpdate (const CompPoint &pos);
292- void updateScreenEdgeRegions ();
293
294 CompositeScreen *cScreen;
295 GLScreen *glScreen;
296@@ -168,10 +167,7 @@
297 WallCairoContext highlightContext;
298 WallCairoContext arrowContext;
299
300- MousePoller poller;
301- bool edgeDrag;
302- CompRegion edgeRegion;
303- CompRegion noEdgeRegion;
304+ bool windowIsDragMoved;
305 };
306
307 class WallWindow :
308@@ -185,6 +181,7 @@
309 virtual void activate ();
310 void grabNotify (int, int, unsigned int, unsigned int);
311 void ungrabNotify ();
312+ void windowNotify (CompWindowNotify);
313 bool glPaint (const GLWindowPaintAttrib &, const GLMatrix &,
314 const CompRegion &, unsigned int);
315
316
317=== modified file 'plugins/wall/wall.xml.in'
318--- plugins/wall/wall.xml.in 2012-10-15 10:31:51 +0000
319+++ plugins/wall/wall.xml.in 2013-05-15 10:56:26 +0000
320@@ -17,7 +17,6 @@
321 </relation>
322 <requirement>
323 <plugin>opengl</plugin>
324- <plugin>mousepoll</plugin>
325 </requirement>
326 </deps>
327 <options>
328@@ -290,6 +289,7 @@
329 <edge name="Left"/>
330 </default>
331 <allowed edgednd="true"/>
332+ <passive_grab>false</passive_grab>
333 </option>
334 <option name="flip_right_edge" type="edge">
335 <_short>Flip Right</_short>
336@@ -299,6 +299,7 @@
337 <edge name="Right"/>
338 </default>
339 <allowed edgednd="true"/>
340+ <passive_grab>false</passive_grab>
341 </option>
342 <option name="flip_up_edge" type="edge">
343 <_short>Flip Up</_short>
344@@ -308,6 +309,7 @@
345 <edge name="Top"/>
346 </default>
347 <allowed edgednd="true"/>
348+ <passive_grab>false</passive_grab>
349 </option>
350 <option name="flip_down_edge" type="edge">
351 <_short>Flip Down</_short>
352@@ -317,6 +319,7 @@
353 <edge name="Bottom"/>
354 </default>
355 <allowed edgednd="true"/>
356+ <passive_grab>false</passive_grab>
357 </option>
358 </subgroup>
359 </group>
360
361=== modified file 'src/screen.cpp'
362--- src/screen.cpp 2013-05-12 08:20:10 +0000
363+++ src/screen.cpp 2013-05-15 10:56:26 +0000
364@@ -3487,7 +3487,8 @@
365 void
366 CompScreenImpl::removeAction (CompAction *action)
367 {
368- if (!(privateScreen.initialized || action->active ()))
369+ if (!privateScreen.initialized ||
370+ !action->active ())
371 return;
372
373 grabManager.setCurrentState(action->state());
374@@ -3903,6 +3904,11 @@
375 SubstructureRedirectMask | SubstructureNotifyMask, &xev);
376 }
377
378+/* These functions do not guard against negative decrements
379+ * as they are unable to determine the source of the reference
380+ * and as such they should only be called by functions that
381+ * actually determine the source of what was referencing the
382+ * edge and can guard against multiple-references-per-owner */
383 void
384 PrivateScreen::enableEdge (int edge)
385 {
386
387=== added directory 'tests/manual/plugins'
388=== added file 'tests/manual/plugins/wall.txt'
389--- tests/manual/plugins/wall.txt 1970-01-01 00:00:00 +0000
390+++ tests/manual/plugins/wall.txt 2013-05-15 10:56:26 +0000
391@@ -0,0 +1,49 @@
392+COMPIZ WALL PLUGIN MANUAL TESTS
393+===============================
394+Sam Spilsbury <smspillaz@gmail.com>
395+
396+Edge Flip Pointer
397+-----------------
398+Setup:
399+#. Enable "Edge Flip Pointer" in the wall plugin
400+ and set up screen edges as appropriate
401+
402+Actions:
403+#. Move cursor to relevant screen edge
404+#. Viewport will change to the next one
405+ over
406+#. Viewport will not change if that
407+ viewport is the last one in the row
408+ or column
409+
410+Edge Flip Move
411+--------------
412+Setup:
413+#. Disable "Edge Flip Pointer" in the wall plugin,
414+ enable "Edge Flip Move" in the wall plugin,
415+ and set up screen edges as appropriate
416+
417+Actions:
418+#. Grab window by titlebar
419+#. Move cursor to relevant screen edge
420+#. Viewport will change to the next one
421+ over while window is grabbed
422+#. Viewport will not change if that
423+ viewport is the last one in the row
424+ or colum
425+
426+Edge Flip Dnd
427+-------------
428+Setup:
429+#. Disable "Edge Flip Pointer" in the wall plugin,
430+ enable "Edge Flip Dnd" in the wall plugin,
431+ and set up screen edges as appropriate
432+
433+Actions:
434+#. Grab a desktop icon
435+#. Move cursor to relevant screen edge
436+#. Viewport will change to the next one
437+ over while icon is grabbed
438+#. Viewport will not change if that
439+ viewport is the last one in the row
440+ or colum

Subscribers

People subscribed via source and target branches

to all changes: