Merge lp:~smspillaz/unity/unity.less-paint-insanity into lp:unity

Proposed by Sam Spilsbury
Status: Superseded
Proposed branch: lp:~smspillaz/unity/unity.less-paint-insanity
Merge into: lp:unity
Diff against target: 1610 lines (+776/-158)
21 files modified
plugins/unityshell/src/ScreenEffectFramebufferObject.cpp (+0/-2)
plugins/unityshell/src/compizminimizedwindowhandler.h (+2/-0)
plugins/unityshell/src/comptransientfor.cpp (+3/-0)
plugins/unityshell/src/comptransientfor.h (+3/-0)
plugins/unityshell/src/inputremover.cpp (+3/-0)
plugins/unityshell/src/inputremover.h (+2/-0)
plugins/unityshell/src/minimizedwindowhandler.cpp (+3/-0)
plugins/unityshell/src/minimizedwindowhandler.h (+3/-0)
plugins/unityshell/src/transientfor.cpp (+4/-0)
plugins/unityshell/src/transientfor.h (+3/-0)
plugins/unityshell/src/unityshell.cpp (+185/-119)
plugins/unityshell/src/unityshell.h (+37/-14)
tests/CMakeLists.txt (+2/-0)
tests/test-input-remover/test-input-remover.cpp (+2/-0)
tests/test-minimize-window-handler/test-minimize-handler.cpp (+2/-0)
tests/test_shell_paint_schedule.cpp (+271/-0)
tests/test_showdesktop_handler.cpp (+30/-23)
tests/x11-window-read-transients.cpp (+2/-0)
unity-shared/CMakeLists.txt (+1/-0)
unity-shared/ShellPaintSchedule.cpp (+93/-0)
unity-shared/ShellPaintSchedule.h (+125/-0)
To merge this branch: bzr merge lp:~smspillaz/unity/unity.less-paint-insanity
Reviewer Review Type Date Requested Status
Tim Penhey (community) Needs Fixing
Daniel van Vugt Pending
Jason Smith Pending
Sam Spilsbury Pending
Marco Trevisan (Treviño) Pending
Review via email: mp+110267@code.launchpad.net

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

This proposal has been superseded by a proposal from 2012-06-24.

Description of the change

== Problem ==

The old implementation of ensuring that unity gets painted in the right place and the nux base windows aren't painted was to hook getWindowPaintList and remove nux windows from the list every single time compiz draws a frame.

That resulted in lots of list copying.

In addition, every time we painted a window, we needed to check if it was actually above a nux window by scanning the paint list down, and the complexity of that grew by o(logN) for every new window added.

== Solution ==

Just hook glPaint, skip the wrap chain to core (eg every single plugin skipped) and tell core not to do anything with the window by returning false

== Errata ==

I have no idea why there is a bunch of logic about whether or not to paint the panel in glDraw (that was moved to glPaint). Someone enlighten me?

Blocked by: https://code.launchpad.net/~compiz-team/compiz/compiz.fix_1012956/+merge/110268

== Test ==

Unit tests included, code refactored to get under test

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

Bump?

I'd like to see this go in, because it should reduce lots of list copying within unity and also lots of unecessary list traversal, which should represent a nice speed boost. In addition, its far simpler in its implementation and far less bug prone.

I'm sure testing is probably an issue. I'll have another quick look at the code and see if I can think of a way to get it under test.

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

Works for me. Though there are some indentation/tab mismatches around line 107. Looks like your tabs are not 8 characters wide like they should be?

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

indentation fixed ... will add tests when I have time.

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

Manual testing -> Works well.

This branch also appears to solve the problem of my missing panel shadow when running dev builds of Unity. But that's just a bonus.

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

Whoops. It turns out this branch is tricking the decor plugin into painting (proper) shadows for the panel and launcher. It looks awesome so I hope we can keep it. But it's probably a mistake.

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

> Whoops. It turns out this branch is tricking the decor plugin into painting
> (proper) shadows for the panel and launcher. It looks awesome so I hope we can
> keep it. But it's probably a mistake.

It probably is, thanks for catching that.

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

Back, with tests.

The decor plugin is going to try and draw shadows now on the launcher and panel. That's a bug in the decor plugin. See https://code.launchpad.net/~compiz-team/compiz/compiz.fix_1012956/+merge/110268

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

Hmm, I was happy with the old proposal. It was so nice and simple. Now I'm seeing lots more green than red, which is not ideal.

I think the implementation is too abstract for its own good. Words like "Requestor", "Interface", "BindingQuery" and "dispatch" confuse what was once simpler code, making maintenance more difficult. Rewriting code to produce something that's harder to understand is much worse than no test cases.

Maybe another day I'll feel more optimistic and test and review it again properly.

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

The code is abstract so we can get it under test. More classes with single responsibilities is not a bad thing.

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

It shouldn't be a choice between readability and testability. It is possible to write readable code that is testable too.

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

The code is readable.

The whole point of coding to interfaces is so that you can clearly label the intent of each particular process that is going on.

For example, I know just from looking at the class names that:

The paint dispatch is responsible for queuing paint requests to the painter
The painter queries whether an fbo was bound to perform a particular operation
Paint Requestors fufill the role of requesting a repaint

That's so much more clear than the voodoocode of how it used to work with stuff like

421 - if (uScreen->doShellRepaint && !uScreen->forcePaintOnTop ())
... PaintDisplay ()

In UnityWindow::glDraw and in UnityWindow::glPaintOutput

If another person comes along and reads that, they now need to figure out what forcePaintOnTop represents, where doShellRepaint is set and unset, why the code is there twice in two different "paint" functions. They also need to figure out where allowWindowPaint is set, why it is set, what it represents, etc.

In addition, there are no tests that the maintainer can go to to see how all the bits fit together. And there is no way for the maintainer to know if they've broken that code.

More Diff Size != Less Maintainability.

2398. By Sam Spilsbury

Merge lp:unity

Revision history for this message
Tim Penhey (thumper) wrote :

Sam,

This code isn't really that readable. The code it is replacing
wasn't really readable either to anyone who doesn't deeply
understand the internals of the compiz drawing machinary.

I do agree that "more diff size != less maintainability", however
in this case, the class names and method names do not express
intent. I am not able to clearly follow what is supposed to be
happening here.

As an example, we have "FBOBindingQueryInterface", which has a
single pure virtual function called "WasBound". However this
method reflects the internal state of some object. It does not
describe the intent, or why a bound FBO is an important thing.

There is no documentation in the header files for any of these
classes compounding their confusion.

I'd suggest that we put all the methods and headers here into a
nested namespace inside unity, as it is directly related to
compiz painting. So unity::compiz or unity::plugin. Givin there
is a ::compiz namespace, it probably makes sense to have it in
namespace unity::plugin.

The constants inside ShellPaintRequestorInterface should really
be an enum. Also it isn't specified that the paint requestors
are supposed to be masks, or that the values will be used as
masks. Also, if we have a nested namespace with an enum, the
enum could be moved outside the class itself.

The fact that I had to do many searchs in the diff to work out
who called what with which parameters is an indicator of how hard
this code is to follow.

On matters of style, this code should follow the unity style
guidelines, not compiz, so * and & next to type not variable
names, no spaces before ().

Also unity has a strong preference for sigc::slot definitions for
functions, not boost::functions.

The fundamental objection I have to this is that the new code and
interfaces don't sufficiently describe the intent, but instead
leak implementation details into the class and method names.

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

(cant reply inline)

On "not being able to follow what is happening here" : can you clarify?

On FBOBindingQueryInterface: I will see if this can be removed ... I think it may not be necessary

On namespaces: ack

On enums: I will change the constants to enums if they can be used as masks

On searching the diff: please clarify

On leaking implementation: please clarify (Apart from the fbo query, which I agree is an ugly leak)

Sent from Samsung Mobile

 Tim Penhey <email address hidden> wrote:

Review: Needs Fixing

Sam,

This code isn't really that readable.  The code it is replacing
wasn't really readable either to anyone who doesn't deeply
understand the internals of the compiz drawing machinary.

I do agree that "more diff size != less maintainability", however
in this case, the class names and method names do not express
intent.  I am not able to clearly follow what is supposed to be
happening here.

As an example, we have "FBOBindingQueryInterface", which has a
single pure virtual function called "WasBound".  However this
method reflects the internal state of some object.  It does not
describe the intent, or why a bound FBO is an important thing.

There is no documentation in the header files for any of these
classes compounding their confusion.

I'd suggest that we put all the methods and headers here into a
nested namespace inside unity, as it is directly related to
compiz painting.  So unity::compiz or unity::plugin.  Givin there
is a ::compiz namespace, it probably makes sense to have it in
namespace unity::plugin.

The constants inside ShellPaintRequestorInterface should really
be an enum.  Also it isn't specified that the paint requestors
are supposed to be masks, or that the values will be used as
masks.  Also, if we have a nested namespace with an enum, the
enum could be moved outside the class itself.

The fact that I had to do many searchs in the diff to work out
who called what with which parameters is an indicator of how hard
this code is to follow.

On matters of style, this code should follow the unity style
guidelines, not compiz, so * and & next to type not variable
names, no spaces before ().

Also unity has a strong preference for sigc::slot definitions for
functions, not boost::functions.

The fundamental objection I have to this is that the new code and
interfaces don't sufficiently describe the intent, but instead
leak implementation details into the class and method names.

--
https://code.launchpad.net/~smspillaz/unity/unity.less-paint-insanity/+merge/110267
You are the owner of lp:~smspillaz/unity/unity.less-paint-insanity.

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

Leaving this open for now so I can get some more suggestions as to the desired design before I go back in and refactor it.

2399. By Sam Spilsbury

Merge lp:unity

2400. By Sam Spilsbury

Change namespace to unity::compiz

2401. By Sam Spilsbury

unsigned int -> enum && move namespace compiz {} to namespace unity::compiz

2402. By Sam Spilsbury

Nuke FBOBindingQueryInterface

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

Nuked FBOBindingQueryInterface, changed the masks to enum and moved stuff into unity::compiz. Unfortunately that caused ambiguity in namespace lookup so I moved the other stuff in compiz to unity::compiz

2403. By Sam Spilsbury

Basic documentation, not really a substitute for better code ...

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

I'm resubmitting this so that it goes to the top again.

I expect this to be marked needs fixing again, but I need some more detailed feedback as to where the design can be improved. I won't merge this fix in without tests.

2404. By Sam Spilsbury

Merge lp:unity

2405. By Sam Spilsbury

Remove unused method and rename methods to make more sense

Unmerged revisions

2405. By Sam Spilsbury

Remove unused method and rename methods to make more sense

2404. By Sam Spilsbury

Merge lp:unity

2403. By Sam Spilsbury

Basic documentation, not really a substitute for better code ...

2402. By Sam Spilsbury

Nuke FBOBindingQueryInterface

2401. By Sam Spilsbury

unsigned int -> enum && move namespace compiz {} to namespace unity::compiz

2400. By Sam Spilsbury

Change namespace to unity::compiz

2399. By Sam Spilsbury

Merge lp:unity

2398. By Sam Spilsbury

Merge lp:unity

2397. By Sam Spilsbury

Test prohibited paint requestor retreival

2396. By Sam Spilsbury

Tests for RepaintPending value

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'plugins/unityshell/src/ScreenEffectFramebufferObject.cpp'
2--- plugins/unityshell/src/ScreenEffectFramebufferObject.cpp 2012-05-28 03:19:35 +0000
3+++ plugins/unityshell/src/ScreenEffectFramebufferObject.cpp 2012-06-19 09:32:20 +0000
4@@ -76,7 +76,6 @@
5 mScreenSize = screenSize;
6 }
7
8-
9 void unity::ScreenEffectFramebufferObject::unbind ()
10 {
11 if (!mBoundCnt)
12@@ -212,7 +211,6 @@
13 mBoundCnt++;
14 }
15
16-
17 unity::ScreenEffectFramebufferObject::ScreenEffectFramebufferObject (GLXGetProcAddressProc p, const nux::Geometry &geom)
18 : getProcAddressGLX (p)
19 , mFboStatus (false)
20
21=== modified file 'plugins/unityshell/src/compizminimizedwindowhandler.h'
22--- plugins/unityshell/src/compizminimizedwindowhandler.h 2012-05-31 09:28:02 +0000
23+++ plugins/unityshell/src/compizminimizedwindowhandler.h 2012-06-19 09:32:20 +0000
24@@ -29,6 +29,7 @@
25 #include <memory>
26
27 // Will be merged back into compiz
28+namespace unity {
29 namespace compiz {
30
31 class PrivateCompizMinimizedWindowHandler
32@@ -357,5 +358,6 @@
33 Window::get (w)->window->minimize();
34 }
35 }
36+}
37
38 #endif
39
40=== modified file 'plugins/unityshell/src/comptransientfor.cpp'
41--- plugins/unityshell/src/comptransientfor.cpp 2012-03-14 06:24:18 +0000
42+++ plugins/unityshell/src/comptransientfor.cpp 2012-06-19 09:32:20 +0000
43@@ -21,6 +21,8 @@
44
45 #include "comptransientfor.h"
46
47+namespace unity
48+{
49 namespace compiz
50 {
51 class PrivateCompTransientForReader
52@@ -84,3 +86,4 @@
53
54 return false;
55 }
56+}
57
58=== modified file 'plugins/unityshell/src/comptransientfor.h'
59--- plugins/unityshell/src/comptransientfor.h 2012-05-31 09:28:02 +0000
60+++ plugins/unityshell/src/comptransientfor.h 2012-06-19 09:32:20 +0000
61@@ -28,6 +28,8 @@
62 #include "transientfor.h"
63
64 // Will be merged back into compiz
65+namespace unity
66+{
67 namespace compiz
68 {
69 class PrivateCompTransientForReader;
70@@ -51,5 +53,6 @@
71 PrivateCompTransientForReader *priv;
72 };
73 }
74+}
75
76 #endif
77
78=== modified file 'plugins/unityshell/src/inputremover.cpp'
79--- plugins/unityshell/src/inputremover.cpp 2012-03-24 02:57:48 +0000
80+++ plugins/unityshell/src/inputremover.cpp 2012-06-19 09:32:20 +0000
81@@ -24,6 +24,8 @@
82 #include <cstdio>
83 #include <cstring>
84
85+namespace unity {
86+
87 compiz::WindowInputRemoverInterface::~WindowInputRemoverInterface ()
88 {
89 }
90@@ -348,3 +350,4 @@
91
92 return true;
93 }
94+}
95
96=== modified file 'plugins/unityshell/src/inputremover.h'
97--- plugins/unityshell/src/inputremover.h 2012-04-23 12:25:44 +0000
98+++ plugins/unityshell/src/inputremover.h 2012-06-19 09:32:20 +0000
99@@ -28,6 +28,7 @@
100 #include <X11/extensions/shape.h>
101
102 // Will be merged back into compiz
103+namespace unity {
104 namespace compiz {
105
106 class WindowInputRemoverInterface
107@@ -127,5 +128,6 @@
108 };
109
110 }
111+}
112
113 #endif
114
115=== modified file 'plugins/unityshell/src/minimizedwindowhandler.cpp'
116--- plugins/unityshell/src/minimizedwindowhandler.cpp 2012-04-23 12:25:44 +0000
117+++ plugins/unityshell/src/minimizedwindowhandler.cpp 2012-06-19 09:32:20 +0000
118@@ -23,6 +23,8 @@
119 #include "inputremover.h"
120 #include <cstring>
121
122+namespace unity
123+{
124 namespace compiz
125 {
126 class PrivateMinimizedWindowHandler
127@@ -273,3 +275,4 @@
128 {
129 delete priv;
130 }
131+}
132
133=== modified file 'plugins/unityshell/src/minimizedwindowhandler.h'
134--- plugins/unityshell/src/minimizedwindowhandler.h 2012-04-18 09:19:44 +0000
135+++ plugins/unityshell/src/minimizedwindowhandler.h 2012-06-19 09:32:20 +0000
136@@ -30,6 +30,8 @@
137 #include <boost/bind.hpp>
138
139 // Will be merged back into compiz
140+namespace unity
141+{
142 namespace compiz
143 {
144 class PrivateMinimizedWindowHandler;
145@@ -58,5 +60,6 @@
146 PrivateMinimizedWindowHandler *priv;
147 };
148 }
149+}
150
151 #endif
152
153=== modified file 'plugins/unityshell/src/transientfor.cpp'
154--- plugins/unityshell/src/transientfor.cpp 2012-03-14 06:24:18 +0000
155+++ plugins/unityshell/src/transientfor.cpp 2012-06-19 09:32:20 +0000
156@@ -21,6 +21,9 @@
157
158 #include "transientfor.h"
159
160+namespace unity
161+{
162+
163 Atom compiz::X11TransientForReader::wmTransientFor = None;
164 Atom compiz::X11TransientForReader::wmClientLeader = None;
165
166@@ -216,3 +219,4 @@
167 {
168 delete priv;
169 }
170+}
171
172=== modified file 'plugins/unityshell/src/transientfor.h'
173--- plugins/unityshell/src/transientfor.h 2012-05-31 09:28:02 +0000
174+++ plugins/unityshell/src/transientfor.h 2012-06-19 09:32:20 +0000
175@@ -29,6 +29,8 @@
176 #include <string>
177
178 // Will be merged back into compiz
179+namespace unity
180+{
181 namespace compiz
182 {
183 class PrivateX11TransientForReader;
184@@ -57,5 +59,6 @@
185 PrivateX11TransientForReader *priv;
186 };
187 }
188+}
189
190 #endif
191
192=== modified file 'plugins/unityshell/src/unityshell.cpp'
193--- plugins/unityshell/src/unityshell.cpp 2012-06-15 02:03:31 +0000
194+++ plugins/unityshell/src/unityshell.cpp 2012-06-19 09:32:20 +0000
195@@ -110,6 +110,8 @@
196 , screen(screen)
197 , cScreen(CompositeScreen::get(screen))
198 , gScreen(GLScreen::get(screen))
199+ , paint_dispatch_ (this,
200+ boost::bind (&UnityScreen::GetProhibitedPaintMasks, this))
201 , debugger_(this)
202 , enable_shortcut_overlay_(true)
203 , gesture_engine_(screen)
204@@ -117,8 +119,6 @@
205 , _in_paint(false)
206 , super_keypressed_(false)
207 , newFocusedWindow(nullptr)
208- , doShellRepaint(false)
209- , allowWindowPaint(false)
210 , damaged(false)
211 , _key_nav_mode_requested(false)
212 , _last_output(nullptr)
213@@ -263,8 +263,8 @@
214 if (GL::fbo)
215 {
216 nux::Geometry geometry (0, 0, screen->width (), screen->height ());
217- uScreen->_fbo = ScreenEffectFramebufferObject::Ptr (new ScreenEffectFramebufferObject (glXGetProcAddressP, geometry));
218- uScreen->_fbo->onScreenSizeChanged (geometry);
219+ uScreen->fbo_ = ScreenEffectFramebufferObject::Ptr (new ScreenEffectFramebufferObject (glXGetProcAddressP, geometry));
220+ uScreen->fbo_->onScreenSizeChanged (geometry);
221 }
222 #endif
223
224@@ -734,16 +734,51 @@
225 panel_texture_has_changed_ = true;
226 }
227
228-#ifdef USE_MODERN_COMPIZ_GL
229-void UnityScreen::paintDisplay()
230+bool
231+UnityScreen::WasBound ()
232+{
233+#ifndef USE_MODERN_COMPIZ_GL
234+ return fbo_->NewContentsValid ();
235 #else
236-void UnityScreen::paintDisplay(const CompRegion& region, const GLMatrix& transform, unsigned int mask)
237-#endif
238+ return true;
239+#endif
240+}
241+
242+compiz::ShellPaintRequestorInterface::PaintRequestorType
243+UnityScreen::GetPaintRequestorType ()
244+{
245+ return compiz::ShellPaintRequestorInterface::PaintRequestorType::Screen;
246+}
247+
248+bool UnityScreen::PaintBackingFBO (CompOutput *output)
249+{
250+#ifndef USE_MODERN_COMPIZ_GL
251+ bool was_bound = fbo_->bound ();
252+ if (was_bound)
253+ {
254+ fbo_->unbind ();
255+ GLMatrix sTransform;
256+ sTransform.toScreenSpace (&screen->fullscreenOutput (), -DEFAULT_Z_CAMERA);
257+ glPushMatrix ();
258+ glLoadMatrixf (sTransform.getMatrix ());
259+ fbo_->paint (nux::Geometry (output->x (), output->y (), output->width (), output->height ()));
260+ glPopMatrix ();
261+ }
262+
263+ return was_bound;
264+#endif
265+ return false;
266+}
267+
268+void UnityScreen::PaintDisplay ()
269 {
270 CompOutput *output = _last_output;
271
272 #ifndef USE_MODERN_COMPIZ_GL
273- bool was_bound = _fbo->bound ();
274+ bool was_bound = PaintBackingFBO (output);
275+#else
276+ bool was_bound = true;
277+#endif
278
279 if (nux::GetGraphicsDisplay()->GetGraphicsEngine()->UsingGLSLCodePath())
280 {
281@@ -779,28 +814,18 @@
282 }
283 }
284
285- _fbo->unbind ();
286-
287 /* Draw the bit of the relevant framebuffer for each output */
288
289- if (was_bound)
290- {
291- GLMatrix sTransform;
292- sTransform.toScreenSpace (&screen->fullscreenOutput (), -DEFAULT_Z_CAMERA);
293- glPushMatrix ();
294- glLoadMatrixf (sTransform.getMatrix ());
295- _fbo->paint (nux::Geometry (output->x (), output->y (), output->width (), output->height ()));
296- glPopMatrix ();
297- }
298+ GLuint fbo_texture_name = 0;
299+#ifndef USE_MODERN_COMPIZ_GL
300+ fbo_texture_name = fbo_->texture();
301+#else
302+ fbo_texture_name = gScreen->fbo ()->tex ()->name ();
303+#endif
304
305 nux::ObjectPtr<nux::IOpenGLBaseTexture> device_texture =
306- nux::GetGraphicsDisplay()->GetGpuDevice()->CreateTexture2DFromID(_fbo->texture(),
307+ nux::GetGraphicsDisplay()->GetGpuDevice()->CreateTexture2DFromID(fbo_texture_name,
308 screen->width (), screen->height(), 1, nux::BITFMT_R8G8B8A8);
309-#else
310- nux::ObjectPtr<nux::IOpenGLTexture2D> device_texture =
311- nux::GetGraphicsDisplay()->GetGpuDevice()->CreateTexture2DFromID(gScreen->fbo ()->tex ()->name (),
312- output->width(), output->height(), 1, nux::BITFMT_R8G8B8A8);
313-#endif
314
315 nux::GetGraphicsDisplay()->GetGpuDevice()->backup_texture0_ = device_texture;
316
317@@ -823,7 +848,7 @@
318
319 for (Window tray_xid : panel_controller_->GetTrayXids())
320 {
321- if (tray_xid && !allowWindowPaint)
322+ if (tray_xid && (no_paint_allowed_mask_ == ShellPaintRequestorInterface::PaintRequestorType::Window))
323 {
324 CompWindow *tray = screen->findWindow (tray_xid);
325
326@@ -901,15 +926,53 @@
327 }
328 }
329
330- doShellRepaint = false;
331 damaged = false;
332 }
333
334-bool UnityScreen::forcePaintOnTop ()
335-{
336- return !allowWindowPaint ||
337- ((switcher_controller_->Visible() || launcher_controller_->IsOverlayOpen())
338- && !fullscreen_windows_.empty () && (!(screen->grabbed () && !screen->otherGrabExist (NULL))));
339+compiz::ShellPaintRequestorInterface::PaintRequestorType UnityScreen::GetProhibitedPaintMasks()
340+{
341+ bool unity_force_overlay = switcher_controller_->Visible() || launcher_controller_->IsOverlayOpen();
342+ bool no_screen_grabs = !(screen->grabbed () && !screen->otherGrabExist (NULL));
343+ bool fullscreen_windows = !fullscreen_windows_.empty ();
344+
345+ compiz::ShellPaintRequestorInterface::PaintRequestorType pmask = no_paint_allowed_mask_;
346+
347+ if (unity_force_overlay &&
348+ fullscreen_windows &&
349+ no_screen_grabs)
350+ pmask = compiz::ShellPaintRequestorInterface::PaintRequestorType::Window;
351+
352+ return pmask;
353+}
354+
355+bool UnityScreen::Paint (compiz::ShellPaintRequestorInterface *r)
356+{
357+ return paint_dispatch_.Paint (r);
358+}
359+
360+bool UnityScreen::EnforceRequestor (compiz::ShellPaintRequestorInterface *r)
361+{
362+ return paint_dispatch_.EnforceRequestor (r);
363+}
364+
365+void UnityScreen::ClearRequestorEnforcement ()
366+{
367+ paint_dispatch_.ClearRequestorEnforcement ();
368+}
369+
370+compiz::ShellPaintRequestorInterface::PaintRequestorType UnityScreen::ProhibitedPaintRequestors()
371+{
372+ return paint_dispatch_.ProhibitedPaintRequestors ();
373+}
374+
375+void UnityScreen::RequireShellRepaint ()
376+{
377+ paint_dispatch_.RequireShellRepaint ();
378+}
379+
380+bool UnityScreen::RepaintPending ()
381+{
382+ return paint_dispatch_.RepaintPending ();
383 }
384
385 void UnityWindow::paintThumbnail (nux::Geometry const& bounding, float alpha)
386@@ -1204,8 +1267,9 @@
387 {
388 bool ret;
389
390- doShellRepaint = true;
391- allowWindowPaint = true;
392+ ClearRequestorEnforcement ();
393+ RequireShellRepaint ();
394+ no_paint_allowed_mask_ = compiz::ShellPaintRequestorInterface::PaintRequestorType::Nil;
395 _last_output = output;
396 paint_panel_ = false;
397
398@@ -1220,16 +1284,13 @@
399 * attempts to bind it will only increment
400 * its bind reference so make sure that
401 * you always unbind as much as you bind */
402- _fbo->bind (nux::Geometry (output->x (), output->y (), output->width (), output->height ()));
403+ fbo_->bind (nux::Geometry (output->x (), output->y (), output->width (), output->height ()));
404 #endif
405
406 /* glPaintOutput is part of the opengl plugin, so we need the GLScreen base class. */
407 ret = gScreen->glPaintOutput(attrib, transform, region, output, mask);
408
409-#ifndef USE_MODERN_COMPIZ_GL
410- if (doShellRepaint)
411- paintDisplay(region, transform, mask);
412-#endif
413+ Paint (this);
414
415 return ret;
416 }
417@@ -1241,7 +1302,7 @@
418 {
419 bool useFbo = false;
420
421- if (doShellRepaint)
422+ if (RepaintPending ())
423 {
424 oldFbo = fbo->bind ();
425 useFbo = fbo->checkStatus () && fbo->tex ();
426@@ -1250,7 +1311,7 @@
427 ::GLFramebufferObject::rebind (oldFbo);
428 return;
429 }
430- paintDisplay();
431+ Paint (this);
432 ::GLFramebufferObject::rebind (oldFbo);
433 }
434
435@@ -1267,7 +1328,7 @@
436 CompOutput* output,
437 unsigned int mask)
438 {
439- allowWindowPaint = false;
440+ no_paint_allowed_mask_ = compiz::ShellPaintRequestorInterface::PaintRequestorType::Window;
441 gScreen->glPaintTransformedOutput(attrib, transform, region, output, mask);
442
443 }
444@@ -2105,31 +2166,6 @@
445 return "Unity";
446 }
447
448-bool isNuxWindow (CompWindow* value)
449-{
450- std::vector<Window> const& xwns = nux::XInputWindow::NativeHandleList();
451- auto id = value->id();
452-
453- // iterate loop by hand rather than use std::find as this is considerably faster
454- // we care about performance here becuase of the high frequency in which this function is
455- // called (nearly every frame)
456- unsigned int size = xwns.size();
457- for (unsigned int i = 0; i < size; ++i)
458- {
459- if (xwns[i] == id)
460- return true;
461- }
462- return false;
463-}
464-
465-const CompWindowList& UnityScreen::getWindowPaintList()
466-{
467- CompWindowList& pl = _withRemovedNuxWindows = cScreen->getWindowPaintList();
468- pl.remove_if(isNuxWindow);
469-
470- return pl;
471-}
472-
473 void UnityScreen::RaiseInputWindows()
474 {
475 std::vector<Window> const& xwns = nux::XInputWindow::NativeHandleList();
476@@ -2142,13 +2178,11 @@
477 }
478 }
479
480-/* detect occlusions
481- *
482- * core passes down the PAINT_WINDOW_OCCLUSION_DETECTION
483- * mask when it is doing occlusion detection, so use that
484- * order to fill our occlusion buffer which we'll flip
485- * to nux later
486- */
487+/* we want to paint underneath other windows here,
488+ * so we need to find if this window is actually
489+ * stacked on top of one of the nux input windows
490+ * and if so paint nux and stop us from painting
491+ * other windows or on top of the whole screen */
492 bool UnityWindow::glPaint(const GLWindowPaintAttrib& attrib,
493 const GLMatrix& matrix,
494 const CompRegion& region,
495@@ -2168,7 +2202,7 @@
496
497 std::vector<Window> const& tray_xids = uScreen->panel_controller_->GetTrayXids();
498 if (std::find(tray_xids.begin(), tray_xids.end(), window->id()) != tray_xids.end() &&
499- !uScreen->allowWindowPaint)
500+ (uScreen->ProhibitedPaintRequestors () == compiz::ShellPaintRequestorInterface::PaintRequestorType::Window))
501 {
502 if (!uScreen->painting_tray_)
503 {
504@@ -2177,26 +2211,7 @@
505 }
506 }
507
508- return gWindow->glPaint(wAttrib, matrix, region, mask);
509-}
510-
511-/* handle window painting in an opengl context
512- *
513- * we want to paint underneath other windows here,
514- * so we need to find if this window is actually
515- * stacked on top of one of the nux input windows
516- * and if so paint nux and stop us from painting
517- * other windows or on top of the whole screen */
518-bool UnityWindow::glDraw(const GLMatrix& matrix,
519-#ifndef USE_MODERN_COMPIZ_GL
520- GLFragment::Attrib& attrib,
521-#else
522- const GLWindowPaintAttrib& attrib,
523-#endif
524- const CompRegion& region,
525- unsigned int mask)
526-{
527- if (uScreen->doShellRepaint && !uScreen->paint_panel_ && window->type() == CompWindowTypeNormalMask)
528+ if (uScreen->RepaintPending () && !uScreen->paint_panel_ && window->type() == CompWindowTypeNormalMask)
529 {
530 guint32 id = window->id();
531 bool maximized = WindowManager::Default()->IsWindowMaximized(id);
532@@ -2212,29 +2227,63 @@
533 }
534 }
535
536- if (uScreen->doShellRepaint && !uScreen->forcePaintOnTop ())
537+ if (IsNuxWindow ())
538 {
539- std::vector<Window> const& xwns = nux::XInputWindow::NativeHandleList();
540- unsigned int size = xwns.size();
541-
542- for (CompWindow* w = window; w && uScreen->doShellRepaint; w = w->prev)
543- {
544- auto id = w->id();
545-
546- for (unsigned int i = 0; i < size; ++i)
547- {
548- if (xwns[i] == id)
549- {
550-#ifdef USE_MODERN_COMPIZ_GL
551- uScreen->paintDisplay();
552+ /* Windows are painted in top-to-bottom order
553+ * with occlusion detection on, so we can
554+ * find out the top most nux window and paint
555+ * there */
556+ if (mask & PAINT_WINDOW_OCCLUSION_DETECTION_MASK)
557+ {
558+ GLWindowPaintAttrib noAlphaAttrib;
559+
560+ noAlphaAttrib.opacity = OPAQUE;
561+ noAlphaAttrib.brightness = BRIGHT;
562+ noAlphaAttrib.saturation = COLOR;
563+
564+ bool status = gWindow->glPaint (noAlphaAttrib,
565+ matrix,
566+ region,
567+ PAINT_WINDOW_OCCLUSION_DETECTION_MASK);
568+
569+ if (status)
570+ uScreen->EnforceRequestor (this);
571+
572+ /* We don't want core to take this window
573+ * into account when doing occlusion detection
574+ * however */
575+ return false;
576+ }
577+ /* Don't care about "fake" paints */
578+ else if (mask & PAINT_WINDOW_NO_CORE_INSTANCE_MASK)
579+ {
580+ return false;
581+ }
582+ else
583+ {
584+ uScreen->Paint (this);
585+
586+ /* Don't paint nux windows on the real paint pass */
587+ return false;
588+ }
589+ }
590+
591+ return gWindow->glPaint(wAttrib, matrix, region, mask);
592+}
593+
594+/* handle window painting in an opengl context
595+ */
596+bool UnityWindow::glDraw(const GLMatrix& matrix,
597+#ifndef USE_MODERN_COMPIZ_GL
598+ GLFragment::Attrib& attrib,
599 #else
600- uScreen->paintDisplay(region, matrix, mask);
601+ const GLWindowPaintAttrib& attrib,
602 #endif
603- break;
604- }
605- }
606- }
607- }
608+ const CompRegion& region,
609+ unsigned int mask)
610+{
611+ if (IsNuxWindow ())
612+ return false;
613
614 if (window->type() == CompWindowTypeDesktopMask)
615 uScreen->setPanelShadowMatrix(matrix);
616@@ -2253,7 +2302,6 @@
617 uScreen->paintPanelShadow(matrix);
618 }
619
620-
621 return ret;
622 }
623
624@@ -2728,8 +2776,8 @@
625 #ifndef USE_MODERN_COMPIZ_GL
626 if (GL::fbo)
627 {
628- uScreen->_fbo = ScreenEffectFramebufferObject::Ptr (new ScreenEffectFramebufferObject (glXGetProcAddressP, geometry));
629- uScreen->_fbo->onScreenSizeChanged (geometry);
630+ uScreen->fbo_ = ScreenEffectFramebufferObject::Ptr (new ScreenEffectFramebufferObject (glXGetProcAddressP, geometry));
631+ uScreen->fbo_->onScreenSizeChanged (geometry);
632 }
633 #endif
634
635@@ -2895,6 +2943,18 @@
636 hints_.push_back(std::make_shared<shortcut::Hint>(windows, "", _(" Drag"), _("Resize window."), shortcut::COMPIZ_MOUSE_OPTION, "resize", "initiate_button"));
637 }
638
639+bool
640+UnityWindow::IsNuxWindow ()
641+{
642+ return is_nux_window_;
643+}
644+
645+compiz::ShellPaintRequestorInterface::PaintRequestorType
646+UnityWindow::GetPaintRequestorType ()
647+{
648+ return compiz::ShellPaintRequestorInterface::PaintRequestorType::Window;
649+}
650+
651 /* Window init */
652 UnityWindow::UnityWindow(CompWindow* window)
653 : BaseSwitchWindow (dynamic_cast<BaseSwitchScreen *> (UnityScreen::get (screen)), window)
654@@ -2903,10 +2963,16 @@
655 , gWindow(GLWindow::get(window))
656 , mMinimizeHandler()
657 , mShowdesktopHandler(nullptr)
658+ , is_nux_window_ (false)
659 {
660 WindowInterface::setHandler(window);
661 GLWindowInterface::setHandler(gWindow);
662
663+ std::vector<Window> const& xwns = nux::XInputWindow::NativeHandleList();
664+ for (unsigned int i = 0; i < xwns.size(); i++)
665+ if (xwns[i] == window->id ())
666+ is_nux_window_ = true;
667+
668 if (UnityScreen::get (screen)->optionGetShowMinimizedWindows () &&
669 window->mapNum ())
670 {
671
672=== modified file 'plugins/unityshell/src/unityshell.h'
673--- plugins/unityshell/src/unityshell.h 2012-06-15 02:03:31 +0000
674+++ plugins/unityshell/src/unityshell.h 2012-06-19 09:32:20 +0000
675@@ -52,6 +52,7 @@
676 #include "UBusWrapper.h"
677 #include "UnityshellPrivate.h"
678 #include "UnityShowdesktopHandler.h"
679+#include "ShellPaintSchedule.h"
680 #ifndef USE_MODERN_COMPIZ_GL
681 #include "ScreenEffectFramebufferObject.h"
682 #endif
683@@ -68,6 +69,9 @@
684
685 /* base screen class */
686 class UnityScreen :
687+ public compiz::ShellPaintDispatchInterface,
688+ public compiz::ShellPaintRequestorInterface,
689+ public compiz::ShellPaintInterface,
690 public unity::debug::Introspectable,
691 public sigc::trackable,
692 public ScreenInterface,
693@@ -92,11 +96,8 @@
694 void nuxEpilogue();
695
696 /* nux draw wrapper */
697-#ifdef USE_MODERN_COMPIZ_GL
698- void paintDisplay();
699-#else
700- void paintDisplay(const CompRegion& region, const GLMatrix& transform, unsigned int mask);
701-#endif
702+ bool PaintBackingFBO (CompOutput *output);
703+ void PaintDisplay ();
704 void paintPanelShadow(const GLMatrix& matrix);
705 void setPanelShadowMatrix(const GLMatrix& matrix);
706
707@@ -133,9 +134,6 @@
708 CompOutput*,
709 unsigned int);
710
711- /* Pop our InputOutput windows from the paint list */
712- const CompWindowList& getWindowPaintList();
713-
714 /* handle X11 events */
715 void handleEvent(XEvent*);
716
717@@ -189,8 +187,6 @@
718 void NeedsRelayout();
719 void ScheduleRelayout(guint timeout);
720
721- bool forcePaintOnTop ();
722-
723 protected:
724 std::string GetName() const;
725 void AddProperties(GVariantBuilder* builder);
726@@ -232,6 +228,19 @@
727
728 void OnPanelStyleChanged();
729
730+ bool WasBound ();
731+ compiz::ShellPaintRequestorInterface::PaintRequestorType GetPaintRequestorType ();
732+ compiz::ShellPaintRequestorInterface::PaintRequestorType GetProhibitedPaintMasks ();
733+
734+ bool Paint (compiz::ShellPaintRequestorInterface *);
735+ bool EnforceRequestor (compiz::ShellPaintRequestorInterface *);
736+ void ClearRequestorEnforcement ();
737+ ShellPaintRequestorInterface::PaintRequestorType ProhibitedPaintRequestors ();
738+ void RequireShellRepaint ();
739+ bool RepaintPending ();
740+
741+ compiz::ShellPaintDispatch paint_dispatch_;
742+
743 Settings dash_settings_;
744 dash::Style dash_style_;
745 panel::Style panel_style_;
746@@ -271,12 +280,9 @@
747 GLTexture::List _shadow_texture;
748
749 /* handle paint order */
750- bool doShellRepaint;
751- bool allowWindowPaint;
752 bool damaged;
753 bool _key_nav_mode_requested;
754 CompOutput* _last_output;
755- CompWindowList _withRemovedNuxWindows;
756
757 nux::Property<nux::Geometry> primary_monitor_;
758
759@@ -285,7 +291,7 @@
760 #ifdef USE_MODERN_COMPIZ_GL
761 ::GLFramebufferObject *oldFbo;
762 #else
763- ScreenEffectFramebufferObject::Ptr _fbo;
764+ ScreenEffectFramebufferObject::Ptr fbo_;
765 GLuint _active_fbo;
766 #endif
767
768@@ -312,15 +318,27 @@
769
770 UBusManager ubus_manager_;
771 glib::SourceManager sources_;
772+ compiz::ShellPaintRequestorInterface::PaintRequestorType no_paint_allowed_mask_;
773
774 friend class UnityWindow;
775 };
776
777+class NuxBridgeWindowInterface
778+{
779+public:
780+
781+ virtual ~NuxBridgeWindowInterface () {};
782+
783+ virtual bool IsNuxWindow () = 0;
784+};
785+
786 class UnityWindow :
787 public WindowInterface,
788 public GLWindowInterface,
789 public ShowdesktopHandlerWindowInterface,
790 public compiz::WindowInputRemoverLockAcquireInterface,
791+ public NuxBridgeWindowInterface,
792+ public compiz::ShellPaintRequestorInterface,
793 public BaseSwitchWindow,
794 public PluginClassHandler <UnityWindow, CompWindow>
795 {
796@@ -418,7 +436,12 @@
797
798 compiz::WindowInputRemoverLock::Ptr GetInputRemover ();
799
800+ bool IsNuxWindow ();
801+ compiz::ShellPaintRequestorInterface::PaintRequestorType GetPaintRequestorType ();
802+
803 compiz::WindowInputRemoverLock::Weak input_remover_;
804+
805+ bool is_nux_window_;
806 glib::Source::UniquePtr focus_desktop_timeout_;
807 };
808
809
810=== modified file 'tests/CMakeLists.txt'
811--- tests/CMakeLists.txt 2012-06-15 02:03:31 +0000
812+++ tests/CMakeLists.txt 2012-06-19 09:32:20 +0000
813@@ -150,6 +150,7 @@
814 test_unityshell_private.cpp
815 test_showdesktop_handler.cpp
816 test_hud_private.cpp
817+ test_shell_paint_schedule.cpp
818 ${CMAKE_SOURCE_DIR}/launcher/AbstractLauncherIcon.cpp
819 ${CMAKE_SOURCE_DIR}/unity-shared/Animator.cpp
820 ${UNITY_SRC}/DebugDBusInterface.cpp
821@@ -162,6 +163,7 @@
822 ${CMAKE_SOURCE_DIR}/launcher/FavoriteStorePrivate.cpp
823 ${CMAKE_SOURCE_DIR}/shortcuts/ShortcutModel.cpp
824 ${CMAKE_SOURCE_DIR}/shortcuts/ShortcutHintPrivate.cpp
825+ ${CMAKE_SOURCE_DIR}/unity-shared/ShellPaintSchedule.cpp
826 ${CMAKE_SOURCE_DIR}/unity-shared/Introspectable.cpp
827 ${CMAKE_SOURCE_DIR}/unity-shared/TextureCache.cpp
828 ${CMAKE_SOURCE_DIR}/unity-shared/Timer.cpp
829
830=== modified file 'tests/test-input-remover/test-input-remover.cpp'
831--- tests/test-input-remover/test-input-remover.cpp 2011-09-13 12:52:31 +0000
832+++ tests/test-input-remover/test-input-remover.cpp 2012-06-19 09:32:20 +0000
833@@ -27,6 +27,8 @@
834 #include <unistd.h>
835 #include <sstream>
836
837+using namespace unity;
838+
839 void usage ()
840 {
841 std::cout << "test-input-remover [WINDOW] [TIME]" << std::endl;
842
843=== modified file 'tests/test-minimize-window-handler/test-minimize-handler.cpp'
844--- tests/test-minimize-window-handler/test-minimize-handler.cpp 2012-04-18 09:19:44 +0000
845+++ tests/test-minimize-window-handler/test-minimize-handler.cpp 2012-06-19 09:32:20 +0000
846@@ -34,6 +34,8 @@
847
848 #include <x11-window-read-transients.h>
849
850+using namespace unity;
851+
852 class X11WindowFakeMinimizable :
853 public X11WindowReadTransients,
854 public compiz::WindowInputRemoverLockAcquireInterface
855
856=== added file 'tests/test_shell_paint_schedule.cpp'
857--- tests/test_shell_paint_schedule.cpp 1970-01-01 00:00:00 +0000
858+++ tests/test_shell_paint_schedule.cpp 2012-06-19 09:32:20 +0000
859@@ -0,0 +1,271 @@
860+/*
861+ * Copyright 2012 Canonical Ltd.
862+ *
863+ * This program is free software: you can redistribute it and/or modify it
864+ * under the terms of the GNU General Public License version 3, as published
865+ * by the Free Software Foundation.
866+ *
867+ * This program is distributed in the hope that it will be useful, but
868+ * WITHOUT ANY WARRANTY; without even the implied warranties of
869+ * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR
870+ * PURPOSE. See the GNU General Public License for more details.
871+ *
872+ * You should have received a copy of the GNU General Public License
873+ * version 3 along with this program. If not, see
874+ * <http://www.gnu.org/licenses/>
875+ *
876+ * Authored by: Sam Spilsbury <sam.spilsbury@canonical.com>
877+ *
878+ */
879+
880+#include <gtest/gtest.h>
881+#include <gmock/gmock.h>
882+
883+using ::testing::StrictMock;
884+using ::testing::_;
885+using ::testing::AtLeast;
886+using ::testing::Return;
887+
888+#include "ShellPaintSchedule.h"
889+
890+using namespace unity::compiz;
891+
892+class MockShellPaintRequestor :
893+ public ShellPaintRequestorInterface
894+{
895+public:
896+
897+ MOCK_METHOD0 (GetPaintRequestorType, PaintRequestorType ());
898+
899+ MockShellPaintRequestor ()
900+ {
901+ ON_CALL (*this, GetPaintRequestorType ()).WillByDefault (Return (ShellPaintRequestorInterface::PaintRequestorType::Nil));
902+ }
903+
904+};
905+
906+class MockShellPaint :
907+ public ShellPaintInterface
908+{
909+public:
910+
911+ MOCK_METHOD0 (PaintDisplay, void ());
912+};
913+
914+class MockShellPaintDispatch
915+{
916+public:
917+
918+ MOCK_METHOD1 (Paint, bool (ShellPaintRequestorInterface *));
919+ MOCK_METHOD1 (EnforceRequestor, void (ShellPaintRequestorInterface *));
920+ MOCK_METHOD0 (ClearRequestorEnforcement, void ());
921+ MOCK_METHOD0 (ProhibitedPaintRequestors, ShellPaintRequestorInterface::PaintRequestorType ());
922+ MOCK_METHOD0 (RequireShellRepaint, void ());
923+ MOCK_METHOD0 (RepaintPending, bool ());
924+};
925+
926+class TestShellPaintSchedule :
927+ public ::testing::Test
928+{
929+};
930+
931+TEST(TestShellPaintSchedule, NoPaintWhereNotRequired)
932+{
933+ StrictMock <MockShellPaint> p;
934+ MockShellPaintRequestor r;
935+ ShellPaintDispatch::GetProhibitedPaintMasksFunc f ([]() -> ShellPaintRequestorInterface::PaintRequestorType { return ShellPaintRequestorInterface::PaintRequestorType::Nil; } );
936+
937+ ShellPaintDispatch dispatch (&p, f);
938+
939+ dispatch.Paint (&r);
940+}
941+
942+TEST(TestShellPaintSchedule, PaintWhereRequired)
943+{
944+ StrictMock <MockShellPaint> p;
945+ MockShellPaintRequestor r;
946+ ShellPaintDispatch::GetProhibitedPaintMasksFunc f ([]() -> ShellPaintRequestorInterface::PaintRequestorType { return ShellPaintRequestorInterface::PaintRequestorType::Nil; } );
947+
948+ ShellPaintDispatch dispatch (&p, f);
949+
950+ dispatch.RequireShellRepaint ();
951+
952+ EXPECT_CALL (r, GetPaintRequestorType ()).WillOnce (Return (ShellPaintRequestorInterface::PaintRequestorType::Window));
953+ EXPECT_CALL (p, PaintDisplay ());
954+
955+ dispatch.Paint (&r);
956+}
957+
958+TEST(TestShellPaintSchedule, NoPaintTwice)
959+{
960+ StrictMock <MockShellPaint> p;
961+ MockShellPaintRequestor r;
962+ ShellPaintDispatch::GetProhibitedPaintMasksFunc f ([]() -> ShellPaintRequestorInterface::PaintRequestorType { return ShellPaintRequestorInterface::PaintRequestorType::Nil; } );
963+
964+ ShellPaintDispatch dispatch (&p, f);
965+
966+ dispatch.RequireShellRepaint ();
967+
968+ EXPECT_CALL (r, GetPaintRequestorType ()).WillOnce (Return (ShellPaintRequestorInterface::PaintRequestorType::Window));
969+ EXPECT_CALL (p, PaintDisplay ());
970+
971+ dispatch.Paint (&r);
972+ dispatch.Paint (&r);
973+}
974+
975+TEST(TestShellPaintSchedule, NoWindowPaintButScreenPaint)
976+{
977+ StrictMock <MockShellPaint> p;
978+ MockShellPaintRequestor r;
979+ ShellPaintDispatch::GetProhibitedPaintMasksFunc f ([]() -> ShellPaintRequestorInterface::PaintRequestorType { return ShellPaintRequestorInterface::PaintRequestorType::Window; } );
980+
981+ ShellPaintDispatch dispatch (&p, f);
982+
983+ dispatch.RequireShellRepaint ();
984+
985+ EXPECT_CALL (r, GetPaintRequestorType ()).WillOnce (Return (ShellPaintRequestorInterface::PaintRequestorType::Window));
986+
987+ dispatch.Paint (&r);
988+
989+ EXPECT_CALL (r, GetPaintRequestorType ()).WillOnce (Return (ShellPaintRequestorInterface::PaintRequestorType::Screen));
990+ EXPECT_CALL (p, PaintDisplay ());
991+
992+ dispatch.Paint (&r);
993+}
994+
995+TEST(TestShellPaintSchedule, NoScreenPaintButWindowPaint)
996+{
997+ StrictMock <MockShellPaint> p;
998+ MockShellPaintRequestor r;
999+ ShellPaintDispatch::GetProhibitedPaintMasksFunc f ([]() -> ShellPaintRequestorInterface::PaintRequestorType { return ShellPaintRequestorInterface::PaintRequestorType::Screen; } );
1000+
1001+ ShellPaintDispatch dispatch (&p, f);
1002+
1003+ dispatch.RequireShellRepaint ();
1004+
1005+ EXPECT_CALL (r, GetPaintRequestorType ()).WillOnce (Return (ShellPaintRequestorInterface::PaintRequestorType::Screen));
1006+
1007+ dispatch.Paint (&r);
1008+
1009+ EXPECT_CALL (r, GetPaintRequestorType ()).WillOnce (Return (ShellPaintRequestorInterface::PaintRequestorType::Window));
1010+ EXPECT_CALL (p, PaintDisplay ());
1011+
1012+ dispatch.Paint (&r);
1013+}
1014+
1015+TEST(TestShellPaintSchedule, TopRequestorOnlyPaints)
1016+{
1017+ StrictMock <MockShellPaint> p;
1018+ MockShellPaintRequestor r_w1, r_w2;
1019+ ShellPaintDispatch::GetProhibitedPaintMasksFunc f ([]() -> ShellPaintRequestorInterface::PaintRequestorType { return ShellPaintRequestorInterface::PaintRequestorType::Nil; } );
1020+
1021+ ShellPaintDispatch dispatch (&p, f);
1022+
1023+ dispatch.RequireShellRepaint ();
1024+
1025+ dispatch.ClearRequestorEnforcement ();
1026+ dispatch.EnforceRequestor (&r_w2);
1027+
1028+ EXPECT_CALL (r_w2, GetPaintRequestorType ()).WillOnce (Return (ShellPaintRequestorInterface::PaintRequestorType::Window));
1029+ EXPECT_CALL (r_w1, GetPaintRequestorType ()).WillRepeatedly (Return (ShellPaintRequestorInterface::PaintRequestorType::Window));
1030+
1031+ dispatch.Paint (&r_w1);
1032+
1033+ EXPECT_CALL (r_w2, GetPaintRequestorType ()).WillRepeatedly (Return (ShellPaintRequestorInterface::PaintRequestorType::Window));
1034+ EXPECT_CALL (p, PaintDisplay ());
1035+
1036+ dispatch.Paint (&r_w2);
1037+}
1038+
1039+TEST(TestShellPaintSchedule, SuperveningRequestorOfOtherTypePaints)
1040+{
1041+ StrictMock <MockShellPaint> p;
1042+ MockShellPaintRequestor r_w1, r_w2, r_s1;
1043+ ShellPaintDispatch::GetProhibitedPaintMasksFunc f ([]() -> ShellPaintRequestorInterface::PaintRequestorType { return ShellPaintRequestorInterface::PaintRequestorType::Nil; } );
1044+
1045+ ShellPaintDispatch dispatch (&p, f);
1046+
1047+ dispatch.RequireShellRepaint ();
1048+
1049+ dispatch.ClearRequestorEnforcement ();
1050+ dispatch.EnforceRequestor (&r_w2);
1051+
1052+ EXPECT_CALL (r_w2, GetPaintRequestorType ()).WillOnce (Return (ShellPaintRequestorInterface::PaintRequestorType::Window));
1053+ EXPECT_CALL (r_w1, GetPaintRequestorType ()).WillRepeatedly (Return (ShellPaintRequestorInterface::PaintRequestorType::Window));
1054+
1055+ dispatch.Paint (&r_w1);
1056+
1057+ EXPECT_CALL (r_w2, GetPaintRequestorType ()).WillOnce (Return (ShellPaintRequestorInterface::PaintRequestorType::Window));
1058+ EXPECT_CALL (r_s1, GetPaintRequestorType ()).WillRepeatedly (Return (ShellPaintRequestorInterface::PaintRequestorType::Screen));
1059+
1060+ EXPECT_CALL (p, PaintDisplay ());
1061+
1062+ dispatch.Paint (&r_s1);
1063+
1064+ EXPECT_CALL (r_w2, GetPaintRequestorType ()).WillRepeatedly (Return (ShellPaintRequestorInterface::PaintRequestorType::Window));
1065+
1066+ dispatch.Paint (&r_w2);
1067+}
1068+
1069+TEST(TestShellPaintSchedule, DoubleEnforcementHasNoEffect)
1070+{
1071+ StrictMock <MockShellPaint> p;
1072+ MockShellPaintRequestor r_w1, r_w2;
1073+ ShellPaintDispatch::GetProhibitedPaintMasksFunc f ([]() -> ShellPaintRequestorInterface::PaintRequestorType { return ShellPaintRequestorInterface::PaintRequestorType::Nil; } );
1074+
1075+ ShellPaintDispatch dispatch (&p, f);
1076+
1077+ dispatch.RequireShellRepaint ();
1078+
1079+ dispatch.ClearRequestorEnforcement ();
1080+ dispatch.EnforceRequestor (&r_w2);
1081+ dispatch.EnforceRequestor (&r_w1);
1082+
1083+ EXPECT_CALL (r_w2, GetPaintRequestorType ()).WillOnce (Return (ShellPaintRequestorInterface::PaintRequestorType::Window));
1084+ EXPECT_CALL (r_w1, GetPaintRequestorType ()).WillRepeatedly (Return (ShellPaintRequestorInterface::PaintRequestorType::Window));
1085+
1086+ dispatch.Paint (&r_w1);
1087+
1088+ EXPECT_CALL (r_w2, GetPaintRequestorType ()).WillRepeatedly (Return (ShellPaintRequestorInterface::PaintRequestorType::Window));
1089+ EXPECT_CALL (p, PaintDisplay ());
1090+
1091+ dispatch.Paint (&r_w2);
1092+}
1093+
1094+TEST(TestShellPaintSchedule, GetPendingRepaint)
1095+{
1096+ StrictMock <MockShellPaint> p;
1097+ MockShellPaintRequestor r;
1098+ ShellPaintDispatch::GetProhibitedPaintMasksFunc f ([]() -> ShellPaintRequestorInterface::PaintRequestorType { return ShellPaintRequestorInterface::PaintRequestorType::Nil; } );
1099+
1100+ ShellPaintDispatch dispatch (&p, f);
1101+
1102+ EXPECT_FALSE (dispatch.RepaintPending ());
1103+
1104+ dispatch.RequireShellRepaint ();
1105+
1106+ EXPECT_TRUE (dispatch.RepaintPending ());
1107+
1108+ EXPECT_CALL (r, GetPaintRequestorType ()).WillOnce (Return (ShellPaintRequestorInterface::PaintRequestorType::Window));
1109+ EXPECT_CALL (p, PaintDisplay ());
1110+
1111+ dispatch.Paint (&r);
1112+
1113+ EXPECT_FALSE (dispatch.RepaintPending ());
1114+}
1115+
1116+TEST(TestShellPaintSchedule, GetProhibitedPaintMasks)
1117+{
1118+ StrictMock <MockShellPaint> p;
1119+ MockShellPaintRequestor r;
1120+ ShellPaintRequestorInterface::PaintRequestorType prohibited_paint_mask = ShellPaintRequestorInterface::PaintRequestorType::Nil;
1121+ ShellPaintDispatch::GetProhibitedPaintMasksFunc f ([&]() -> ShellPaintRequestorInterface::PaintRequestorType { return prohibited_paint_mask; } );
1122+
1123+ ShellPaintDispatch dispatch (&p, f);
1124+
1125+ EXPECT_EQ (prohibited_paint_mask, dispatch.ProhibitedPaintRequestors ());
1126+ prohibited_paint_mask = ShellPaintRequestorInterface::PaintRequestorType::Window;
1127+ EXPECT_EQ (prohibited_paint_mask, dispatch.ProhibitedPaintRequestors ());
1128+ prohibited_paint_mask = ShellPaintRequestorInterface::PaintRequestorType::Screen;
1129+ EXPECT_EQ (prohibited_paint_mask, dispatch.ProhibitedPaintRequestors ());
1130+}
1131
1132=== modified file 'tests/test_showdesktop_handler.cpp'
1133--- tests/test_showdesktop_handler.cpp 2012-04-18 09:30:53 +0000
1134+++ tests/test_showdesktop_handler.cpp 2012-06-19 09:32:20 +0000
1135@@ -4,12 +4,14 @@
1136 #include <gmock/gmock.h>
1137 #include <UnityShowdesktopHandler.h>
1138
1139-using namespace unity;
1140 using ::testing::_;
1141 using ::testing::Return;
1142 using ::testing::Invoke;
1143 using ::testing::InSequence;
1144
1145+namespace unity
1146+{
1147+
1148 compiz::WindowInputRemoverInterface::~WindowInputRemoverInterface () {}
1149
1150 class MockWindowInputRemover :
1151@@ -96,11 +98,16 @@
1152 MOCK_METHOD0 (DoDeleteHandler, void ());
1153 };
1154
1155+}
1156+
1157+using namespace unity;
1158+using namespace unity::compiz;
1159+
1160 TEST_F(UnityShowdesktopHandlerTest, TestNoORWindowsSD)
1161 {
1162 MockUnityShowdesktopHandlerWindow mMockWindow;
1163
1164- ShowdesktopHandler mMockHandler (static_cast <ShowdesktopHandlerWindowInterface *> (&mMockWindow), static_cast <compiz::WindowInputRemoverLockAcquireInterface *> (&mMockWindow));
1165+ ShowdesktopHandler mMockHandler (static_cast <ShowdesktopHandlerWindowInterface *> (&mMockWindow), static_cast <WindowInputRemoverLockAcquireInterface *> (&mMockWindow));
1166
1167 EXPECT_CALL (mMockWindow, IsOverrideRedirect ()).WillOnce (Return (true));
1168 EXPECT_FALSE (ShowdesktopHandler::ShouldHide (&mMockWindow));
1169@@ -110,7 +117,7 @@
1170 {
1171 MockUnityShowdesktopHandlerWindow mMockWindow;
1172
1173- ShowdesktopHandler mMockHandler (static_cast <ShowdesktopHandlerWindowInterface *> (&mMockWindow), static_cast <compiz::WindowInputRemoverLockAcquireInterface *> (&mMockWindow));
1174+ ShowdesktopHandler mMockHandler (static_cast <ShowdesktopHandlerWindowInterface *> (&mMockWindow), static_cast <WindowInputRemoverLockAcquireInterface *> (&mMockWindow));
1175
1176 EXPECT_CALL (mMockWindow, IsOverrideRedirect ());
1177 EXPECT_CALL (mMockWindow, IsManaged ()).WillOnce (Return (false));
1178@@ -121,7 +128,7 @@
1179 {
1180 MockUnityShowdesktopHandlerWindow mMockWindow;
1181
1182- ShowdesktopHandler mMockHandler (static_cast <ShowdesktopHandlerWindowInterface *> (&mMockWindow), static_cast <compiz::WindowInputRemoverLockAcquireInterface *> (&mMockWindow));
1183+ ShowdesktopHandler mMockHandler (static_cast <ShowdesktopHandlerWindowInterface *> (&mMockWindow), static_cast <WindowInputRemoverLockAcquireInterface *> (&mMockWindow));
1184
1185 EXPECT_CALL (mMockWindow, IsOverrideRedirect ());
1186 EXPECT_CALL (mMockWindow, IsManaged ());
1187@@ -133,7 +140,7 @@
1188 {
1189 MockUnityShowdesktopHandlerWindow mMockWindow;
1190
1191- ShowdesktopHandler mMockHandler (static_cast <ShowdesktopHandlerWindowInterface *> (&mMockWindow), static_cast <compiz::WindowInputRemoverLockAcquireInterface *> (&mMockWindow));
1192+ ShowdesktopHandler mMockHandler (static_cast <ShowdesktopHandlerWindowInterface *> (&mMockWindow), static_cast <WindowInputRemoverLockAcquireInterface *> (&mMockWindow));
1193
1194 EXPECT_CALL (mMockWindow, IsOverrideRedirect ());
1195 EXPECT_CALL (mMockWindow, IsManaged ());
1196@@ -146,7 +153,7 @@
1197 {
1198 MockUnityShowdesktopHandlerWindow mMockWindow;
1199
1200- ShowdesktopHandler mMockHandler (static_cast <ShowdesktopHandlerWindowInterface *> (&mMockWindow), static_cast <compiz::WindowInputRemoverLockAcquireInterface *> (&mMockWindow));
1201+ ShowdesktopHandler mMockHandler (static_cast <ShowdesktopHandlerWindowInterface *> (&mMockWindow), static_cast <WindowInputRemoverLockAcquireInterface *> (&mMockWindow));
1202
1203 EXPECT_CALL (mMockWindow, IsOverrideRedirect ());
1204 EXPECT_CALL (mMockWindow, IsManaged ());
1205@@ -160,7 +167,7 @@
1206 {
1207 MockUnityShowdesktopHandlerWindow mMockWindow;
1208
1209- ShowdesktopHandler mMockHandler (static_cast <ShowdesktopHandlerWindowInterface *> (&mMockWindow), static_cast <compiz::WindowInputRemoverLockAcquireInterface *> (&mMockWindow));
1210+ ShowdesktopHandler mMockHandler (static_cast <ShowdesktopHandlerWindowInterface *> (&mMockWindow), static_cast <WindowInputRemoverLockAcquireInterface *> (&mMockWindow));
1211
1212 EXPECT_CALL (mMockWindow, IsOverrideRedirect ());
1213 EXPECT_CALL (mMockWindow, IsManaged ());
1214@@ -177,7 +184,7 @@
1215 {
1216 MockUnityShowdesktopHandlerWindow mMockWindow;
1217
1218- ShowdesktopHandler mMockHandler (static_cast <ShowdesktopHandlerWindowInterface *> (&mMockWindow), static_cast <compiz::WindowInputRemoverLockAcquireInterface *> (&mMockWindow));
1219+ ShowdesktopHandler mMockHandler (static_cast <ShowdesktopHandlerWindowInterface *> (&mMockWindow), static_cast <WindowInputRemoverLockAcquireInterface *> (&mMockWindow));
1220
1221 EXPECT_CALL (mMockWindow, IsOverrideRedirect ());
1222 EXPECT_CALL (mMockWindow, IsManaged ());
1223@@ -193,7 +200,7 @@
1224 {
1225 MockUnityShowdesktopHandlerWindow mMockWindow;
1226
1227- ShowdesktopHandler mMockHandler (static_cast <ShowdesktopHandlerWindowInterface *> (&mMockWindow), static_cast <compiz::WindowInputRemoverLockAcquireInterface *> (&mMockWindow));
1228+ ShowdesktopHandler mMockHandler (static_cast <ShowdesktopHandlerWindowInterface *> (&mMockWindow), static_cast <WindowInputRemoverLockAcquireInterface *> (&mMockWindow));
1229
1230 EXPECT_CALL (mMockWindow, IsOverrideRedirect ());
1231 EXPECT_CALL (mMockWindow, IsManaged ());
1232@@ -211,7 +218,7 @@
1233 {
1234 MockUnityShowdesktopHandlerWindow mMockWindow;
1235
1236- ShowdesktopHandler mMockHandler (static_cast <ShowdesktopHandlerWindowInterface *> (&mMockWindow), static_cast <compiz::WindowInputRemoverLockAcquireInterface *> (&mMockWindow));
1237+ ShowdesktopHandler mMockHandler (static_cast <ShowdesktopHandlerWindowInterface *> (&mMockWindow), static_cast <WindowInputRemoverLockAcquireInterface *> (&mMockWindow));
1238
1239 EXPECT_CALL (mMockWindow, IsOverrideRedirect ());
1240 EXPECT_CALL (mMockWindow, IsManaged ());
1241@@ -226,7 +233,7 @@
1242 }
1243
1244 class MockWindowInputRemoverTestFadeOut :
1245- public compiz::WindowInputRemoverInterface
1246+ public WindowInputRemoverInterface
1247 {
1248 public:
1249
1250@@ -252,7 +259,7 @@
1251
1252 EXPECT_CALL (mMockWindow, GetInputRemover ()).WillOnce (Invoke (UnityShowdesktopHandlerTest::getLock <MockWindowInputRemoverTestFadeOut>));
1253
1254- ShowdesktopHandler mMockHandler (static_cast <ShowdesktopHandlerWindowInterface *> (&mMockWindow), static_cast <compiz::WindowInputRemoverLockAcquireInterface *> (&mMockWindow));
1255+ ShowdesktopHandler mMockHandler (static_cast <ShowdesktopHandlerWindowInterface *> (&mMockWindow), static_cast <WindowInputRemoverLockAcquireInterface *> (&mMockWindow));
1256
1257 EXPECT_CALL (mMockWindow, IsHidden ());
1258 EXPECT_CALL (mMockWindow, DoHide ());
1259@@ -264,7 +271,7 @@
1260 }
1261
1262 class MockWindowInputRemoverTestFadeOutAlready :
1263- public compiz::WindowInputRemoverInterface
1264+ public WindowInputRemoverInterface
1265 {
1266 public:
1267
1268@@ -284,7 +291,7 @@
1269 {
1270 MockUnityShowdesktopHandlerWindow mMockWindow;
1271
1272- ShowdesktopHandler mMockHandler (static_cast <ShowdesktopHandlerWindowInterface *> (&mMockWindow), static_cast <compiz::WindowInputRemoverLockAcquireInterface *> (&mMockWindow));
1273+ ShowdesktopHandler mMockHandler (static_cast <ShowdesktopHandlerWindowInterface *> (&mMockWindow), static_cast <WindowInputRemoverLockAcquireInterface *> (&mMockWindow));
1274
1275 EXPECT_CALL (mMockWindow, IsHidden ()).WillOnce (Return (true));
1276
1277@@ -298,7 +305,7 @@
1278 MockUnityShowdesktopHandlerWindow mMockWindow;
1279
1280 EXPECT_CALL (mMockWindow, GetInputRemover ()).WillOnce (Invoke (UnityShowdesktopHandlerTest::getLock <MockWindowInputRemoverTestFadeOut>));
1281- ShowdesktopHandler mMockHandler (static_cast <ShowdesktopHandlerWindowInterface *> (&mMockWindow), static_cast <compiz::WindowInputRemoverLockAcquireInterface *> (&mMockWindow));
1282+ ShowdesktopHandler mMockHandler (static_cast <ShowdesktopHandlerWindowInterface *> (&mMockWindow), static_cast <WindowInputRemoverLockAcquireInterface *> (&mMockWindow));
1283
1284 EXPECT_CALL (mMockWindow, IsHidden ());
1285 EXPECT_CALL (mMockWindow, DoHide ());
1286@@ -314,7 +321,7 @@
1287 {
1288 MockUnityShowdesktopHandlerWindow mMockWindow;
1289
1290- ShowdesktopHandler mMockHandler (static_cast <ShowdesktopHandlerWindowInterface *> (&mMockWindow), static_cast <compiz::WindowInputRemoverLockAcquireInterface *> (&mMockWindow));
1291+ ShowdesktopHandler mMockHandler (static_cast <ShowdesktopHandlerWindowInterface *> (&mMockWindow), static_cast <WindowInputRemoverLockAcquireInterface *> (&mMockWindow));
1292
1293 mMockHandler.FadeIn ();
1294
1295@@ -322,7 +329,7 @@
1296 }
1297
1298 class MockWindowInputRemoverTestFadeOutFadeIn :
1299- public compiz::WindowInputRemoverInterface
1300+ public WindowInputRemoverInterface
1301 {
1302 public:
1303
1304@@ -347,7 +354,7 @@
1305 MockUnityShowdesktopHandlerWindow mMockWindow;
1306
1307 EXPECT_CALL (mMockWindow, GetInputRemover ()).WillOnce (Invoke (UnityShowdesktopHandlerTest::getLock <MockWindowInputRemoverTestFadeOutFadeIn>));
1308- ShowdesktopHandler mMockHandler (static_cast <ShowdesktopHandlerWindowInterface *> (&mMockWindow), static_cast <compiz::WindowInputRemoverLockAcquireInterface *> (&mMockWindow));
1309+ ShowdesktopHandler mMockHandler (static_cast <ShowdesktopHandlerWindowInterface *> (&mMockWindow), static_cast <WindowInputRemoverLockAcquireInterface *> (&mMockWindow));
1310
1311 EXPECT_CALL (mMockWindow, IsHidden ());
1312 EXPECT_CALL (mMockWindow, DoHide ());
1313@@ -368,7 +375,7 @@
1314 MockUnityShowdesktopHandlerWindow mMockWindow;
1315
1316 EXPECT_CALL (mMockWindow, GetInputRemover ()).WillOnce (Invoke (UnityShowdesktopHandlerTest::getLock <MockWindowInputRemoverTestFadeOutFadeIn>));
1317- ShowdesktopHandler mMockHandler (static_cast <ShowdesktopHandlerWindowInterface *> (&mMockWindow), static_cast <compiz::WindowInputRemoverLockAcquireInterface *> (&mMockWindow));
1318+ ShowdesktopHandler mMockHandler (static_cast <ShowdesktopHandlerWindowInterface *> (&mMockWindow), static_cast <WindowInputRemoverLockAcquireInterface *> (&mMockWindow));
1319
1320 EXPECT_CALL (mMockWindow, IsHidden ());
1321 EXPECT_CALL (mMockWindow, DoHide ());
1322@@ -409,7 +416,7 @@
1323 MockUnityShowdesktopHandlerWindow mMockWindow;
1324
1325 EXPECT_CALL (mMockWindow, GetInputRemover ()).WillOnce (Invoke (UnityShowdesktopHandlerTest::getLock <MockWindowInputRemoverTestFadeOutFadeIn>));
1326- ShowdesktopHandler mMockHandler (static_cast <ShowdesktopHandlerWindowInterface *> (&mMockWindow), static_cast <compiz::WindowInputRemoverLockAcquireInterface *> (&mMockWindow));
1327+ ShowdesktopHandler mMockHandler (static_cast <ShowdesktopHandlerWindowInterface *> (&mMockWindow), static_cast <WindowInputRemoverLockAcquireInterface *> (&mMockWindow));
1328
1329 EXPECT_CALL (mMockWindow, IsHidden ());
1330 EXPECT_CALL (mMockWindow, DoHide ());
1331@@ -465,7 +472,7 @@
1332 MockUnityShowdesktopHandlerWindow mMockWindow;
1333
1334 EXPECT_CALL (mMockWindow, GetInputRemover ()).WillOnce (Invoke (UnityShowdesktopHandlerTest::getLock <MockWindowInputRemoverTestFadeOutFadeIn>));
1335- ShowdesktopHandler mMockHandler (static_cast <ShowdesktopHandlerWindowInterface *> (&mMockWindow), static_cast <compiz::WindowInputRemoverLockAcquireInterface *> (&mMockWindow));
1336+ ShowdesktopHandler mMockHandler (static_cast <ShowdesktopHandlerWindowInterface *> (&mMockWindow), static_cast <WindowInputRemoverLockAcquireInterface *> (&mMockWindow));
1337
1338 EXPECT_CALL (mMockWindow, IsHidden ());
1339 EXPECT_CALL (mMockWindow, DoHide ());
1340@@ -491,7 +498,7 @@
1341 }
1342
1343 class MockWindowInputRemoverTestFadeOutFadeInWithShapeEvent :
1344- public compiz::WindowInputRemoverInterface
1345+ public WindowInputRemoverInterface
1346 {
1347 public:
1348
1349@@ -520,7 +527,7 @@
1350 MockUnityShowdesktopHandlerWindow mMockWindow;
1351
1352 EXPECT_CALL (mMockWindow, GetInputRemover ()).WillOnce (Invoke (UnityShowdesktopHandlerTest::getLock <MockWindowInputRemoverTestFadeOutFadeInWithShapeEvent>));
1353- ShowdesktopHandler mMockHandler (static_cast <ShowdesktopHandlerWindowInterface *> (&mMockWindow), static_cast <compiz::WindowInputRemoverLockAcquireInterface *> (&mMockWindow));
1354+ ShowdesktopHandler mMockHandler (static_cast <ShowdesktopHandlerWindowInterface *> (&mMockWindow), static_cast <WindowInputRemoverLockAcquireInterface *> (&mMockWindow));
1355
1356 EXPECT_CALL (mMockWindow, IsHidden ());
1357 EXPECT_CALL (mMockWindow, DoHide ());
1358
1359=== modified file 'tests/x11-window-read-transients.cpp'
1360--- tests/x11-window-read-transients.cpp 2011-08-24 16:46:09 +0000
1361+++ tests/x11-window-read-transients.cpp 2012-06-19 09:32:20 +0000
1362@@ -25,6 +25,8 @@
1363 #define _GNU_SOURCE
1364 #endif
1365
1366+using namespace unity;
1367+
1368 X11WindowReadTransients::X11WindowReadTransients (Display *d, Window w) :
1369 X11Window::X11Window (d, w)
1370 {
1371
1372=== modified file 'unity-shared/CMakeLists.txt'
1373--- unity-shared/CMakeLists.txt 2012-05-22 10:15:47 +0000
1374+++ unity-shared/CMakeLists.txt 2012-06-19 09:32:20 +0000
1375@@ -47,6 +47,7 @@
1376 PanelStyle.cpp
1377 SearchBar.cpp
1378 SearchBarSpinner.cpp
1379+ ShellPaintSchedule.cpp
1380 StaticCairoText.cpp
1381 TextureCache.cpp
1382 Timer.cpp
1383
1384=== added file 'unity-shared/ShellPaintSchedule.cpp'
1385--- unity-shared/ShellPaintSchedule.cpp 1970-01-01 00:00:00 +0000
1386+++ unity-shared/ShellPaintSchedule.cpp 2012-06-19 09:32:20 +0000
1387@@ -0,0 +1,93 @@
1388+// -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*-
1389+/*
1390+ * Copyright (C) 2012 Canonical Ltd
1391+ *
1392+ * This program is free software: you can redistribute it and/or modify
1393+ * it under the terms of the GNU General Public License version 3 as
1394+ * published by the Free Software Foundation.
1395+ *
1396+ * This program is distributed in the hope that it will be useful,
1397+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
1398+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1399+ * GNU General Public License for more details.
1400+ *
1401+ * You should have received a copy of the GNU General Public License
1402+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1403+ *
1404+ * Authored by: Sam Spilsbury <sam.spilsbury@canonical.com>
1405+ */
1406+
1407+#include "ShellPaintSchedule.h"
1408+
1409+namespace unity
1410+{
1411+namespace compiz
1412+{
1413+
1414+ShellPaintDispatch::ShellPaintDispatch (ShellPaintInterface *paint_interface,
1415+ const GetProhibitedPaintMasksFunc &prohibited_func) :
1416+ shell_repaint_required_ (false),
1417+ top_requestor_ (nullptr),
1418+ prohibited_paint_masks_func_ (prohibited_func),
1419+ paint_interface_ (paint_interface)
1420+{
1421+}
1422+
1423+bool
1424+ShellPaintDispatch::Paint (ShellPaintRequestorInterface *requestor)
1425+{
1426+ if (!shell_repaint_required_)
1427+ return false;
1428+
1429+ if (prohibited_paint_masks_func_ () == requestor->GetPaintRequestorType ())
1430+ return false;
1431+
1432+ if (top_requestor_)
1433+ if ((top_requestor_->GetPaintRequestorType () ==
1434+ requestor->GetPaintRequestorType ()) && top_requestor_ != requestor)
1435+ return false;
1436+
1437+ paint_interface_->PaintDisplay ();
1438+
1439+ shell_repaint_required_ = false;
1440+
1441+ return true;
1442+}
1443+
1444+bool
1445+ShellPaintDispatch::EnforceRequestor (ShellPaintRequestorInterface *requestor)
1446+{
1447+ if (top_requestor_)
1448+ return false;
1449+
1450+ top_requestor_ = requestor;
1451+
1452+ return true;
1453+}
1454+
1455+void
1456+ShellPaintDispatch::ClearRequestorEnforcement ()
1457+{
1458+ top_requestor_ = nullptr;
1459+}
1460+
1461+ShellPaintRequestorInterface::PaintRequestorType
1462+ShellPaintDispatch::ProhibitedPaintRequestors ()
1463+{
1464+ return prohibited_paint_masks_func_ ();
1465+}
1466+
1467+void
1468+ShellPaintDispatch::RequireShellRepaint ()
1469+{
1470+ shell_repaint_required_ = true;
1471+}
1472+
1473+bool
1474+ShellPaintDispatch::RepaintPending ()
1475+{
1476+ return shell_repaint_required_;
1477+}
1478+
1479+}
1480+}
1481
1482=== added file 'unity-shared/ShellPaintSchedule.h'
1483--- unity-shared/ShellPaintSchedule.h 1970-01-01 00:00:00 +0000
1484+++ unity-shared/ShellPaintSchedule.h 2012-06-19 09:32:20 +0000
1485@@ -0,0 +1,125 @@
1486+// -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*-
1487+/*
1488+ * Copyright (C) 2012 Canonical Ltd
1489+ *
1490+ * This program is free software: you can redistribute it and/or modify
1491+ * it under the terms of the GNU General Public License version 3 as
1492+ * published by the Free Software Foundation.
1493+ *
1494+ * This program is distributed in the hope that it will be useful,
1495+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
1496+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1497+ * GNU General Public License for more details.
1498+ *
1499+ * You should have received a copy of the GNU General Public License
1500+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
1501+ *
1502+ * Authored by: Sam Spilsbury <sam.spilsbury@canonical.com>
1503+ */
1504+
1505+#ifndef UNITY_PAINT_SCHEDULE_H
1506+#define UNITY_PAINT_SCHEDULE_H
1507+
1508+#include <boost/bind.hpp>
1509+#include <boost/function.hpp>
1510+
1511+namespace unity
1512+{
1513+namespace compiz
1514+{
1515+
1516+/*
1517+ * Implementors of ShellPaintRequestorInterface are able
1518+ * to request a repaint of the unity shell by calling
1519+ * Paint () in ShellPaintDispatchInterface. Requestors
1520+ * must identify themselves to an implementor of
1521+ * ShellPaintDispatchInterface such that ShellPaintDispatch
1522+ * interface can decide whether to allow a redraw
1523+ */
1524+class ShellPaintRequestorInterface
1525+{
1526+public:
1527+
1528+ enum class PaintRequestorType
1529+ {
1530+ Nil = 0,
1531+ Window = (1 << 0),
1532+ Screen = (1 << 1)
1533+ };
1534+
1535+ virtual ~ShellPaintRequestorInterface () {}
1536+
1537+ virtual PaintRequestorType GetPaintRequestorType () = 0;
1538+};
1539+
1540+/*
1541+ * Implementors of ShellPaintInterface are capable
1542+ * of repainting the shell */
1543+class ShellPaintInterface
1544+{
1545+public:
1546+
1547+ virtual ~ShellPaintInterface () {};
1548+
1549+ virtual void PaintDisplay () = 0;
1550+};
1551+
1552+/*
1553+ * Implementors of ShellPaintDispatchInterface
1554+ * manage when the shell is allowed to be repainted
1555+ * by examining what is requesting the repaint of
1556+ * the shell and determining whether or not a
1557+ * repaint is required
1558+ */
1559+class ShellPaintDispatchInterface
1560+{
1561+public:
1562+
1563+ virtual ~ShellPaintDispatchInterface () {}
1564+
1565+ virtual bool Paint (ShellPaintRequestorInterface *) = 0;
1566+ virtual bool EnforceRequestor (ShellPaintRequestorInterface *) = 0;
1567+ virtual void ClearRequestorEnforcement () = 0;
1568+ virtual ShellPaintRequestorInterface::PaintRequestorType ProhibitedPaintRequestors () = 0;
1569+ virtual void RequireShellRepaint () = 0;
1570+ virtual bool RepaintPending () = 0;
1571+
1572+};
1573+
1574+/*
1575+ * ShellPaintDispatch is the canonical implementor
1576+ * of ShellPaintDispatchInterface and manages when
1577+ * the shell is allowed to be repainted depending
1578+ * on what ShellPaintRequestorInterface is requesting
1579+ * the repaint
1580+ */
1581+class ShellPaintDispatch :
1582+ public ShellPaintDispatchInterface
1583+{
1584+public:
1585+
1586+ typedef boost::function <ShellPaintRequestorInterface::PaintRequestorType ()> GetProhibitedPaintMasksFunc;
1587+
1588+ ShellPaintDispatch (ShellPaintInterface * paint_interface,
1589+ const GetProhibitedPaintMasksFunc &func);
1590+
1591+ bool Paint (ShellPaintRequestorInterface *);
1592+ bool EnforceRequestor (ShellPaintRequestorInterface *);
1593+ void ClearRequestorEnforcement ();
1594+ ShellPaintRequestorInterface::PaintRequestorType ProhibitedPaintRequestors();
1595+ void RequireShellRepaint ();
1596+ bool RepaintPending ();
1597+
1598+
1599+protected:
1600+
1601+ bool shell_repaint_required_;
1602+ ShellPaintRequestorInterface *top_requestor_;
1603+ GetProhibitedPaintMasksFunc prohibited_paint_masks_func_;
1604+ ShellPaintInterface *paint_interface_;
1605+};
1606+
1607+}
1608+}
1609+
1610+#endif