Merge lp:~compiz-team/compiz/compiz.fix_1008020 into lp:compiz/0.9.8

Proposed by Sam Spilsbury
Status: Merged
Merged at revision: 3259
Proposed branch: lp:~compiz-team/compiz/compiz.fix_1008020
Merge into: lp:compiz/0.9.8
Diff against target: 255 lines (+55/-21)
9 files modified
include/core/abiversion.h (+1/-1)
include/core/screen.h (+2/-1)
include/core/window.h (+1/-0)
src/event.cpp (+10/-2)
src/privatescreen.h (+4/-2)
src/privatescreen/tests/test-privatescreen.cpp (+2/-1)
src/privatewindow.h (+1/-1)
src/screen.cpp (+24/-7)
src/window.cpp (+10/-6)
To merge this branch: bzr merge lp:~compiz-team/compiz/compiz.fix_1008020
Reviewer Review Type Date Requested Status
Daniel van Vugt Approve
Robert Carr testing Pending
Tim Penhey Pending
Andrea Cimitan Pending
Review via email: mp+111146@code.launchpad.net

This proposal supersedes a proposal from 2012-06-18.

Description of the change

Don't insert the window into the server list above the window it was
  created above.

  The server list might have been modified by the time that we process the
  create event, and as such there is a case where a window can be inserted
  into the server list above another window and not at the top (the default
  for where windows are created) if that window is pending a restack.

  When updateAttributes is called later, putting it above the correct window
  will silently fail, because it is already there in the server list, even
  though a restack was never issued to put it there.

  (LP: #1008020) (LP: #886605)

We really need to do something about the fact that the stacking code is not under test. An email was sent about smoke testing window stacking for now until we can get some kind of sensible unit testing story.

I tested this against lp:~smspillaz/+junk/stackingtest (using proc test-stacking-ops which creates tons of new windows and reshuffles them, excersizing this code). Nothing went above panels or screensavers after the fixes were applied.

Case from bug 1008020 that I know this fixed:

1. Log in to unity-2d or gnome-classic
2. kill unity-2d-shell (so just the panel remains)
3. Open nautilus and repeatedly hit Ctrl-N to create a new window really quickly
4. Windows will eventually go above the panel

To post a comment you must log in.
Revision history for this message
Daniel van Vugt (vanvugt) wrote : Posted in a previous version of this proposal

Using stackingtest in a loop, I find windows appear over the top of the lock screen even with this fix. But only when using the animation plugin. Is that still what's being fixed here or a different issue?

I see exactly the same stacking behaviour with and without this fix...

review: Needs Information
Revision history for this message
Daniel van Vugt (vanvugt) wrote : Posted in a previous version of this proposal

Also, there's a trivial conflict in abiversion.h.

Revision history for this message
Sam Spilsbury (smspillaz) wrote : Posted in a previous version of this proposal

Could be a different issue. There is no conflict in abiversion.h according to lp

Revision history for this message
Sam Spilsbury (smspillaz) wrote : Posted in a previous version of this proposal

(Have a look at bug 1008020 for the case that I can absolutely confirm this fixes, I wasn't sure if the screen lock one and this one were related as I can't reproduce it anyways [I hate these race conditions])

Revision history for this message
Sam Spilsbury (smspillaz) wrote : Posted in a previous version of this proposal

> Using stackingtest in a loop, I find windows appear over the top of the lock
> screen even with this fix. But only when using the animation plugin. Is that
> still what's being fixed here or a different issue?
>
> I see exactly the same stacking behaviour with and without this fix...

A small question here: Do the windows appear temporarily on top of the lockscreen, or do they go away quickly? I know that we're supposed to create windows on top of fullscreen windows and it is the job of the fullscreen window to request that it goes on top of the other windows in that case.

Revision history for this message
Daniel van Vugt (vanvugt) wrote : Posted in a previous version of this proposal

As far as I can tell, only the open/close animations are visible over the lock screen.

Revision history for this message
Sam Spilsbury (smspillaz) wrote : Posted in a previous version of this proposal

In that case, there is no stacking bug (but a bug in the animation plugin for sure)

Revision history for this message
Sam Spilsbury (smspillaz) wrote : Posted in a previous version of this proposal

(What happens if you turn down the speed of the animations too)

Revision history for this message
Sam Spilsbury (smspillaz) wrote : Posted in a previous version of this proposal

I updated the description with the case I know this fixes for sure. We can unlinkbug 886605 if appropriate. I'd like to get feedback from cimi and racarr on that since they have macbook airs that can reproduce this.

Revision history for this message
Alan Griffiths (alan-griffiths) wrote : Posted in a previous version of this proposal

There is a trivial conflict in abiversion.h

Also, as list::size() can be O(N)

117 + if (serverWindows.size ())

Should be:

117 + if (!serverWindows.empty ())

Revision history for this message
Daniel van Vugt (vanvugt) wrote : Posted in a previous version of this proposal

I think we should be making new functions as useful as possible. That means returning CompWindow* instead of Window (None --> NULL):
  Window cps::WindowManager::getTopServerWindow()

If you just return Window and actually want a CompWindow then you have to waste CPU and more lines of code looking it up again.

review: Needs Fixing
Revision history for this message
Sam Spilsbury (smspillaz) wrote : Posted in a previous version of this proposal

There is no CPU wastage since it hits the cached last found window. Im amy case the function cab be changed

Sent from Samsung Mobile

 Daniel van Vugt <email address hidden> wrote:

null

Revision history for this message
Daniel van Vugt (vanvugt) wrote : Posted in a previous version of this proposal

I'm not talking about this proposal. I mean potential wastage for anyone else trying to use the function in future.

Revision history for this message
Sam Spilsbury (smspillaz) wrote : Posted in a previous version of this proposal

To be honest, we should move getTopWindow and getTopServerWindow to a more private place too.

Sent from Samsung Mobile

 Daniel van Vugt <email address hidden> wrote:

I'm not talking about this proposal. I mean potential wastage for anyone else trying to use the function in future.
--
https://code.launchpad.net/~compiz-team/compiz/compiz.fix_1008020/+merge/109758
Your team Compiz Maintainers is subscribed to branch lp:compiz.

Revision history for this message
Daniel van Vugt (vanvugt) wrote : Posted in a previous version of this proposal

I don't see any problems running this branch. But I also still can't reproduce any of the bugs we're aiming to fix here. So can't really verify the fixes.

Just some notes on style:
You have inconsistent use of white space in function (calls). Sometimes there's a space, sometimes not. I think we should switch to no white space like most coding conventions do: function(calls).

review: Approve
Revision history for this message
Sam Spilsbury (smspillaz) wrote : Posted in a previous version of this proposal

Compiz coding style has always had a space between the caller and the brackets. i'd prefer to keep it that way

Sent from Samsung Mobile

 Daniel van Vugt <email address hidden> wrote:

Review: Approve

I don't see any problems running this branch. But I also still can't reproduce any of the bugs we're aiming to fix here. So can't really verify the fixes.

Just some notes on style:
You have inconsistent use of white space in function (calls). Sometimes there's a space, sometimes not. I think we should switch to no white space like most coding conventions do: function(calls).

--
https://code.launchpad.net/~compiz-team/compiz/compiz.fix_1008020/+merge/110724
Your team Compiz Maintainers is subscribed to branch lp:compiz.

Revision history for this message
Tim Penhey (thumper) wrote : Posted in a previous version of this proposal

You have functions that may return null pointers, and call sites where you are dereferencing without checking.

Something should be done there.

review: Needs Fixing
Revision history for this message
Tim Penhey (thumper) wrote : Posted in a previous version of this proposal

I suggest something like:

inline Window window_from_compwindow(CompWindow* win)
{
  return win ? win->id () : None;
}

Revision history for this message
Sam Spilsbury (smspillaz) wrote : Posted in a previous version of this proposal

> I suggest something like:
>
> inline Window window_from_compwindow(CompWindow* win)
> {
> return win ? win->id () : None;
> }

Thanks, will do

Revision history for this message
Tim Penhey (thumper) wrote : Posted in a previous version of this proposal

Line 71 also needs the function treatment.

> PrivateWindow::createCompWindow (i ? children[i - 1] : 0, i ? children[i - 1] : 0, attrib, children[i]);

This is fugly.

Please do something the equivalent of:

CompWindow* top_window_id = i ? children[i - 1] : 0;
PrivateWindow::createCompWindow (top_window_id, top_window_id, attrib, children[i]);

If you had the CompWindowToWindow function defined in a header, you could use it in src/window.cpp instead of implementing the logic again.

review: Needs Fixing
Revision history for this message
Sam Spilsbury (smspillaz) wrote : Posted in a previous version of this proposal

> Line 71 also needs the function treatment.
>
> > PrivateWindow::createCompWindow (i ? children[i - 1] : 0, i ? children[i -
> 1] : 0, attrib, children[i]);
>
> This is fugly.
>
> Please do something the equivalent of:
>
> CompWindow* top_window_id = i ? children[i - 1] : 0;
> PrivateWindow::createCompWindow (top_window_id, top_window_id, attrib,
> children[i]);
>

It is not a CompWindow*, but I will still do

Window topWindowId = i ? children[i - 1] : 0;

> If you had the CompWindowToWindow function defined in a header, you could use
> it in src/window.cpp instead of implementing the logic again.

I do not like functions in headers, changing them means rebuilding everything that includes that header.

Revision history for this message
Daniel van Vugt (vanvugt) wrote : Posted in a previous version of this proposal

Remember to use "None" instead of "0". :)

Revision history for this message
Sam Spilsbury (smspillaz) wrote : Posted in a previous version of this proposal

0 == none but I can change it.

Sent from Samsung Mobile

 Daniel van Vugt <email address hidden> wrote:

Remember to use "None" instead of "0". :)
--
https://code.launchpad.net/~compiz-team/compiz/compiz.fix_1008020/+merge/110724
Your team Compiz Maintainers is subscribed to branch lp:compiz.

Revision history for this message
Daniel van Vugt (vanvugt) wrote :

Looks good, works well, though I still can't reproduce the bugs.

Ideally, CompWindowToWindow (CompWindow *window) would be CompWindowToWindow (const CompWindow *window). But I know that's not possible because CompWindow::id() is not const (!)

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'include/core/abiversion.h'
2--- include/core/abiversion.h 2012-05-26 06:07:20 +0000
3+++ include/core/abiversion.h 2012-06-20 05:34:30 +0000
4@@ -5,6 +5,6 @@
5 # error Conflicting definitions of CORE_ABIVERSION
6 #endif
7
8-#define CORE_ABIVERSION 20120526
9+#define CORE_ABIVERSION 20120603
10
11 #endif // COMPIZ_ABIVERSION_H
12
13=== modified file 'include/core/screen.h'
14--- include/core/screen.h 2012-06-06 05:12:28 +0000
15+++ include/core/screen.h 2012-06-20 05:34:30 +0000
16@@ -401,7 +401,8 @@
17 virtual void updatePassiveKeyGrabs () const = 0;
18 virtual void applyStartupProperties (CompWindow *window) = 0;
19 virtual void updateClientList() = 0;
20- virtual Window getTopWindow() const = 0;
21+ virtual CompWindow * getTopWindow() const = 0;
22+ virtual CompWindow * getTopServerWindow() const = 0;
23 virtual CoreOptions& getCoreOptions() = 0;
24 virtual Colormap colormap() const = 0;
25 virtual void setCurrentDesktop (unsigned int desktop) = 0;
26
27=== modified file 'include/core/window.h'
28--- include/core/window.h 2012-05-04 09:29:44 +0000
29+++ include/core/window.h 2012-06-20 05:34:30 +0000
30@@ -569,6 +569,7 @@
31 private:
32
33 CompWindow (Window aboveId,
34+ Window aboveServerId,
35 XWindowAttributes &wa,
36 PrivateWindow *priv);
37
38
39=== modified file 'src/event.cpp'
40--- src/event.cpp 2012-06-06 05:12:28 +0000
41+++ src/event.cpp 2012-06-20 05:34:30 +0000
42@@ -44,6 +44,14 @@
43
44 namespace cps = compiz::private_screen;
45
46+namespace
47+{
48+Window CompWindowToWindow (CompWindow *window)
49+{
50+ return window ? window->id () : None;
51+}
52+}
53+
54
55 bool
56 PrivateWindow::handleSyncAlarm ()
57@@ -1225,7 +1233,7 @@
58 * that to wait until the map request */
59 if (wa.root == privateScreen.rootWindow())
60 {
61- PrivateWindow::createCompWindow (getTopWindow (), wa, event->xcreatewindow.window);
62+ PrivateWindow::createCompWindow (CompWindowToWindow (getTopWindow ()), CompWindowToWindow (getTopServerWindow ()), wa, event->xcreatewindow.window);
63 }
64 else
65 XSelectInput (privateScreen.dpy, event->xcreatewindow.window,
66@@ -1361,7 +1369,7 @@
67 if (!XGetWindowAttributes (privateScreen.dpy, event->xcreatewindow.window, &wa))
68 privateScreen.setDefaultWindowAttributes (&wa);
69
70- PrivateWindow::createCompWindow (getTopWindow (), wa, event->xcreatewindow.window);
71+ PrivateWindow::createCompWindow (getTopWindow ()->id (), getTopServerWindow ()->id (), wa, event->xcreatewindow.window);
72 break;
73 }
74 else
75
76=== modified file 'src/privatescreen.h'
77--- src/privatescreen.h 2012-06-06 05:12:28 +0000
78+++ src/privatescreen.h 2012-06-20 05:34:30 +0000
79@@ -183,7 +183,8 @@
80 { return clientListStacking; }
81
82 CompWindow * findWindow (Window id) const;
83- Window getTopWindow() const;
84+ CompWindow * getTopWindow() const;
85+ CompWindow * getTopServerWindow() const;
86
87
88 void removeFromFindWindowCache(CompWindow* w)
89@@ -1075,7 +1076,8 @@
90 virtual bool displayInitialised() const;
91 virtual void applyStartupProperties (CompWindow *window);
92 virtual void updateClientList();
93- virtual Window getTopWindow() const;
94+ virtual CompWindow * getTopWindow() const;
95+ virtual CompWindow * getTopServerWindow() const;
96 virtual CoreOptions& getCoreOptions();
97 virtual Colormap colormap() const;
98 virtual void setCurrentDesktop (unsigned int desktop);
99
100=== modified file 'src/privatescreen/tests/test-privatescreen.cpp'
101--- src/privatescreen/tests/test-privatescreen.cpp 2012-06-10 11:06:37 +0000
102+++ src/privatescreen/tests/test-privatescreen.cpp 2012-06-20 05:34:30 +0000
103@@ -185,7 +185,8 @@
104 MOCK_CONST_METHOD0(displayInitialised, bool ());
105 MOCK_METHOD1(applyStartupProperties, void (CompWindow *window));
106 MOCK_METHOD0(updateClientList, void ());
107- MOCK_CONST_METHOD0(getTopWindow, Window ());
108+ MOCK_CONST_METHOD0(getTopWindow, CompWindow * ());
109+ MOCK_CONST_METHOD0(getTopServerWindow, CompWindow * ());
110 MOCK_METHOD0(getCoreOptions, CoreOptions& ());
111 MOCK_CONST_METHOD0(colormap, Colormap ());
112 MOCK_METHOD1(setCurrentDesktop, void (unsigned int desktop));
113
114=== modified file 'src/privatewindow.h'
115--- src/privatewindow.h 2012-05-27 04:32:55 +0000
116+++ src/privatewindow.h 2012-06-20 05:34:30 +0000
117@@ -283,7 +283,7 @@
118
119 bool checkClear ();
120
121- static CompWindow* createCompWindow (Window aboveId, XWindowAttributes &wa, Window id);
122+ static CompWindow* createCompWindow (Window aboveId, Window aboveServerId, XWindowAttributes &wa, Window id);
123 public:
124
125 PrivateWindow *priv;
126
127=== modified file 'src/screen.cpp'
128--- src/screen.cpp 2012-06-18 06:22:29 +0000
129+++ src/screen.cpp 2012-06-20 05:34:30 +0000
130@@ -4097,14 +4097,23 @@
131 XUnmapWindow (dpy, screenEdge[edge].id);
132 }
133
134-Window
135+CompWindow *
136 cps::WindowManager::getTopWindow() const
137 {
138 /* return first window that has not been destroyed */
139- if (windows.size ())
140- return windows.back ()->id ();
141-
142- return None;
143+ if (!windows.empty ())
144+ return windows.back ();
145+
146+ return NULL;
147+}
148+
149+CompWindow *
150+cps::WindowManager::getTopServerWindow () const
151+{
152+ if (!serverWindows.empty ())
153+ return serverWindows.back ();
154+
155+ return NULL;
156 }
157
158 int
159@@ -4858,12 +4867,18 @@
160 privateScreen.updateClientList ();
161 }
162
163-Window
164+CompWindow *
165 CompScreenImpl::getTopWindow() const
166 {
167 return windowManager.getTopWindow();
168 }
169
170+CompWindow *
171+CompScreenImpl::getTopServerWindow () const
172+{
173+ return windowManager.getTopServerWindow();
174+}
175+
176 CoreOptions&
177 CompScreenImpl::getCoreOptions()
178 {
179@@ -5292,7 +5307,9 @@
180 if (!XGetWindowAttributes (screen->dpy (), children[i], &attrib))
181 setDefaultWindowAttributes(&attrib);
182
183- PrivateWindow::createCompWindow (i ? children[i - 1] : 0, attrib, children[i]);
184+ Window topWindowInTree = i ? children[i - 1] : None;
185+
186+ PrivateWindow::createCompWindow (topWindowInTree, topWindowInTree, attrib, children[i]);
187 }
188
189 /* enforce restack on all windows
190
191=== modified file 'src/window.cpp'
192--- src/window.cpp 2012-05-27 04:32:55 +0000
193+++ src/window.cpp 2012-06-20 05:34:30 +0000
194@@ -1205,7 +1205,7 @@
195
196 /* Put the frame window "above" the client window
197 * in the stack */
198- PrivateWindow::createCompWindow (priv->id, attrib, priv->serverFrame);
199+ PrivateWindow::createCompWindow (priv->id, priv->id, attrib, priv->serverFrame);
200 }
201
202 /* Immediately unhook the window once destroyed
203@@ -1890,7 +1890,10 @@
204 Window newAboveId;
205
206 if (ce->place == PlaceOnTop)
207- newAboveId = screen->getTopWindow ();
208+ {
209+ CompWindow *newAbove = screen->getTopWindow ();
210+ newAboveId = newAbove ? newAbove->id () : None;
211+ }
212 else
213 newAboveId = 0;
214
215@@ -5969,19 +5972,20 @@
216 }
217
218 CompWindow *
219-PrivateWindow::createCompWindow (Window aboveId, XWindowAttributes &wa, Window id)
220+PrivateWindow::createCompWindow (Window aboveId, Window aboveServerId, XWindowAttributes &wa, Window id)
221 {
222 PrivateWindow* priv(new PrivateWindow ());
223 priv->id = id;
224 priv->serverId = id;
225
226- CompWindow *fw = new CompWindow (aboveId, wa, priv);
227+ CompWindow *fw = new CompWindow (aboveId, aboveServerId, wa, priv);
228
229 return fw;
230 }
231
232
233 CompWindow::CompWindow (Window aboveId,
234+ Window aboveServerId,
235 XWindowAttributes &wa,
236 PrivateWindow *priv) :
237 PluginClassStorage (windowPluginClassIndices),
238@@ -5994,7 +5998,7 @@
239 priv->window = this;
240
241 screen->insertWindow (this, aboveId);
242- screen->insertServerWindow (this, aboveId);
243+ screen->insertServerWindow (this, aboveServerId);
244
245 /* We must immediately insert the window into the debugging
246 * stack */
247@@ -6896,7 +6900,7 @@
248
249 /* Put the frame window "above" the client window
250 * in the stack */
251- PrivateWindow::createCompWindow (id, attrib, serverFrame);
252+ PrivateWindow::createCompWindow (id, id, attrib, serverFrame);
253 }
254
255 /* Issue a DestroyNotify */

Subscribers

People subscribed via source and target branches