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

Proposed by Sam Spilsbury on 2012-03-30
Status: Superseded
Proposed branch: lp:~smspillaz/unity/unity.fix_877778
Merge into: lp:unity
Diff against target: 1732 lines (+1166/-285)
8 files modified
plugins/unityshell/src/UnityShowdesktopHandler.cpp (+215/-0)
plugins/unityshell/src/UnityShowdesktopHandler.h (+158/-0)
plugins/unityshell/src/inputremover.cpp (+7/-3)
plugins/unityshell/src/inputremover.h (+27/-5)
plugins/unityshell/src/unityshell.cpp (+179/-229)
plugins/unityshell/src/unityshell.h (+37/-47)
tests/CMakeLists.txt (+4/-1)
tests/test_showdesktop_handler.cpp (+539/-0)
To merge this branch: bzr merge lp:~smspillaz/unity/unity.fix_877778
Reviewer Review Type Date Requested Status
Tim Penhey (community) Needs Fixing on 2012-04-04
Gord Allott 2012-03-30 Pending
Review via email: mp+100174@code.launchpad.net

This proposal supersedes a proposal from 2012-03-24.

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

Commit message

Fix UnityShowdesktopHandler brokenness LP#877778

Fix UnityShowdesktopHandler, namely the animation going in the wrong direction, damage being applied at the wrong time, handlers not being removed when they should be. Also use PAINT_WINDOW_NO_CORE_INSTANCE_MASK when the window is fully transparent and set the opacity to MAXINT (since the scale plugin uses this to bypass the no paint mask)

Show Desktop mode was completely broken, but the bug there is mainly about the fact that showdesktoped windows would be invisible in the spread. That's now fixed

Split UnityShowdesktopHandler out into a separate file, created UnityShowdesktopHandlerWindowInterface, UnityWindow inmplements this, test coverage created in test_showdesktop_handler.cpp using Google Mock and Google Test. Also see AP tests.

Description of the change

Fixes LP #877778 - Introduces tests for UnityShowdesktopHandler

== Problem ==

See LP #877778 - in fact, Show Desktop mode was completely broken, but the bug there is mainly about the fact that showdesktoped windows would be invisible in the spread. That's now fixed

== Solution ==

Fix UnityShowdesktopHandler brokenness, namely the animation going in the wrong direction, damage being applied at the wrong time, handlers not being removed when they should be. Also use PAINT_WINDOW_NO_CORE_INSTANCE_MASK when the window is fully transparent and set the opacity to MAXINT (since the scale plugin uses this to bypass the no paint mask)

== Test Coverage ==

Split UnityShowdesktopHandler out into a separate file, created UnityShowdesktopHandlerWindowInterface, UnityWindow inmplements this, test coverage created in test_showdesktop_handler.cpp using Google Mock and Google Test. Also see AP tests.

To post a comment you must log in.
Gord Allott (gordallott) wrote : Posted in a previous version of this proposal

Great stuff, but needs to conform to our code style :) namely FooBar() methods and _foo instead of mFoo, quick sed should fix it

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

On Wed 28 Mar 2012 21:47:21 NZDT, Gord Allott wrote:
> Review: Needs Fixing
>
> Great stuff, but needs to conform to our code style :) namely FooBar() methods and _foo instead of mFoo, quick sed should fix it

s/_foo/foo_/

Omer Akram (om26er) wrote :

has conflicts.

Unity Merger (unity-merger) wrote :

No commit message specified.

Tim Penhey (thumper) wrote :

A few style things:

If you are in namespace unity, you should prefix your classes with Unity.

also

s/ ()/()/g

The tests shouldn't be calling the virtual methods. It should be dealing only with the interface methods.

review: Needs Fixing
Tim Penhey (thumper) wrote :

> A few style things:
>
> If you are in namespace unity, you should prefix your classes with Unity.

s/should/should not/

lp:~smspillaz/unity/unity.fix_877778 updated on 2012-04-06
2174. By Sam Spilsbury on 2012-04-06

Merge lp:unity and style

2175. By Sam Spilsbury on 2012-04-06

Make pure virtual methods private

2176. By Sam Spilsbury on 2012-04-06

Also update frame region when the window is unshowdesktoped

2177. By Sam Spilsbury on 2012-04-06

Fix typo

2178. By Sam Spilsbury on 2012-04-06

Merge trunk

Unmerged revisions

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== added file 'plugins/unityshell/src/UnityShowdesktopHandler.cpp'
2--- plugins/unityshell/src/UnityShowdesktopHandler.cpp 1970-01-01 00:00:00 +0000
3+++ plugins/unityshell/src/UnityShowdesktopHandler.cpp 2012-04-02 01:40:26 +0000
4@@ -0,0 +1,215 @@
5+// -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*-
6+/* Compiz unity plugin
7+ * unity.h
8+ *
9+ * Copyright (c) 2010-11 Canonical Ltd.
10+ *
11+ * This program is free software; you can redistribute it and/or
12+ * modify it under the terms of the GNU General Public License
13+ * as published by the Free Software Foundation; either version 3
14+ * of the License, or (at your option) any later version.
15+ *
16+ * This program is distributed in the hope that it will be useful,
17+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
18+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19+ * GNU General Public License for more details.
20+ *
21+ * Your own copyright notice would go above. You are free to choose whatever
22+ * licence you want, just take note that some compiz code is GPL and you will
23+ * not be able to re-use it if you want to use a different licence.
24+ */
25+
26+#include <glib.h>
27+#include "UnityShowdesktopHandler.h"
28+
29+namespace unity
30+{
31+
32+UnityShowdesktopHandlerWindowInterface::~UnityShowdesktopHandlerWindowInterface ()
33+{
34+}
35+
36+/* 300 ms */
37+const unsigned int UnityShowdesktopHandler::fade_time = 300;
38+std::list <UnityShowdesktopHandlerWindowInterface *> UnityShowdesktopHandler::animating_windows (0);
39+
40+bool UnityShowdesktopHandler::ShouldHide (UnityShowdesktopHandlerWindowInterface *wi)
41+{
42+ if (wi->OverrideRedirect ())
43+ return false;
44+
45+ if (!wi->Managed ())
46+ return false;
47+
48+ if (wi->Grabbed ())
49+ return false;
50+
51+ if (wi->DesktopOrDock ())
52+ return false;
53+
54+ if (wi->SkipTaskbarOrPager ())
55+ return false;
56+
57+ if (wi->Hidden ())
58+ if ((wi->ShowDesktopMode () || wi->Shaded ()))
59+ return false;
60+
61+ return true;
62+}
63+
64+guint32 UnityShowdesktopHandler::inhibiting_xid = 0;
65+
66+void
67+UnityShowdesktopHandler::InhibitLeaveShowdesktopMode (guint32 xid)
68+{
69+ if (!inhibiting_xid)
70+ inhibiting_xid = xid;
71+}
72+
73+void
74+UnityShowdesktopHandler::AllowLeaveShowdesktopMode (guint32 xid)
75+{
76+ if (inhibiting_xid == xid)
77+ inhibiting_xid = 0;
78+}
79+
80+guint32
81+UnityShowdesktopHandler::InhibitingXid ()
82+{
83+ return inhibiting_xid;
84+}
85+
86+UnityShowdesktopHandler::UnityShowdesktopHandler (UnityShowdesktopHandlerWindowInterface *wi) :
87+ showdesktop_handler_window_interface_ (wi),
88+ remover_ (wi->InputRemover ()),
89+ state_ (StateVisible),
90+ progress_ (0.0f)
91+{
92+}
93+
94+UnityShowdesktopHandler::~UnityShowdesktopHandler ()
95+{
96+}
97+
98+void UnityShowdesktopHandler::FadeOut ()
99+{
100+ if (state_ != StateVisible && state_ != StateFadeIn)
101+ return;
102+
103+ state_ = UnityShowdesktopHandler::StateFadeOut;
104+ progress_ = 0.0f;
105+
106+ was_hidden_ = showdesktop_handler_window_interface_->Hidden ();
107+
108+ if (!was_hidden_)
109+ {
110+ showdesktop_handler_window_interface_->Hide ();
111+ showdesktop_handler_window_interface_->NotifyHidden ();
112+ remover_->save ();
113+ remover_->remove ();
114+
115+ if (std::find (animating_windows.begin(),
116+ animating_windows.end(),
117+ showdesktop_handler_window_interface_) == animating_windows.end())
118+ animating_windows.push_back (showdesktop_handler_window_interface_);
119+
120+ }
121+}
122+
123+void UnityShowdesktopHandler::FadeIn ()
124+{
125+ if (state_ != StateInvisible && state_ != StateFadeOut)
126+ return;
127+
128+ state_ = UnityShowdesktopHandler::StateFadeIn;
129+
130+ if (!was_hidden_)
131+ {
132+ showdesktop_handler_window_interface_->Show ();
133+ showdesktop_handler_window_interface_->NotifyShown ();
134+ remover_->restore ();
135+
136+ if (std::find (animating_windows.begin(),
137+ animating_windows.end(),
138+ showdesktop_handler_window_interface_) == animating_windows.end())
139+ animating_windows.push_back(showdesktop_handler_window_interface_);
140+ }
141+}
142+
143+UnityShowdesktopHandlerWindowInterface::PostPaintAction UnityShowdesktopHandler::Animate (unsigned int ms)
144+{
145+ float inc = ms / static_cast <float> (fade_time);
146+
147+ if (state_ == UnityShowdesktopHandler::StateFadeOut)
148+ {
149+ progress_ += inc;
150+ if (progress_ >= 1.0f)
151+ {
152+ progress_ = 1.0f;
153+ state_ = StateInvisible;
154+ }
155+ }
156+ else if (state_ == StateFadeIn)
157+ {
158+ progress_ -= inc;
159+ if (progress_ <= 0.0f)
160+ {
161+ progress_ = 0.0f;
162+ state_ = StateVisible;
163+ }
164+ }
165+ else if (state_ == StateVisible)
166+ return UnityShowdesktopHandlerWindowInterface::PostPaintAction::Remove;
167+ else if (state_ == StateInvisible)
168+ return UnityShowdesktopHandlerWindowInterface::PostPaintAction::Wait;
169+
170+ return UnityShowdesktopHandlerWindowInterface::PostPaintAction::Damage;
171+}
172+
173+void UnityShowdesktopHandler::PaintOpacity (unsigned short &opacity)
174+{
175+ if (progress_ == 1.0f || progress_ == 0.0f)
176+ opacity = std::numeric_limits <unsigned short>::max ();
177+ else
178+ opacity *= (1.0f - progress_);
179+}
180+
181+unsigned int UnityShowdesktopHandler::GetPaintMask ()
182+{
183+ return (progress_ == 1.0f) ? showdesktop_handler_window_interface_->NoCoreInstanceMask () : 0;
184+}
185+
186+void UnityShowdesktopHandler::HandleShapeEvent ()
187+{
188+ /* Ignore sent events from the InputRemover */
189+ if (remover_)
190+ {
191+ remover_->save ();
192+ remover_->remove ();
193+ }
194+}
195+
196+void UnityShowdesktopHandler::WindowFocusChangeNotify ()
197+{
198+ if (showdesktop_handler_window_interface_->Minimized ())
199+ {
200+ for (UnityShowdesktopHandlerWindowInterface *w : animating_windows)
201+ w->DisableFocus ();
202+
203+ showdesktop_handler_window_interface_->MoveFocusAway ();
204+
205+ for (UnityShowdesktopHandlerWindowInterface *w : animating_windows)
206+ w->EnableFocus ();
207+ }
208+}
209+
210+void UnityShowdesktopHandler::UpdateFrameRegion (CompRegion &r)
211+{
212+ r = CompRegion ();
213+
214+ /* Ensure no other plugins can touch this frame region */
215+ showdesktop_handler_window_interface_->OverrideFrameRegion (r);
216+}
217+
218+}
219+
220
221=== added file 'plugins/unityshell/src/UnityShowdesktopHandler.h'
222--- plugins/unityshell/src/UnityShowdesktopHandler.h 1970-01-01 00:00:00 +0000
223+++ plugins/unityshell/src/UnityShowdesktopHandler.h 2012-04-02 01:40:26 +0000
224@@ -0,0 +1,158 @@
225+// -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*-
226+/* Compiz unity plugin
227+ * unity.h
228+ *
229+ * Copyright (c) 2010-11 Canonical Ltd.
230+ *
231+ * This program is free software; you can redistribute it and/or
232+ * modify it under the terms of the GNU General Public License
233+ * as published by the Free Software Foundation; either version 3
234+ * of the License, or (at your option) any later version.
235+ *
236+ * This program is distributed in the hope that it will be useful,
237+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
238+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
239+ * GNU General Public License for more details.
240+ *
241+ * Your own copyright notice would go above. You are free to choose whatever
242+ * licence you want, just take note that some compiz code is GPL and you will
243+ * not be able to re-use it if you want to use a different licence.
244+ */
245+#ifndef UNITY_SHOWDESKTOP_HANDLER_H
246+#define UNITY_SHOWDESKTOP_HANDLER_H
247+
248+#include <list>
249+#include <algorithm>
250+#include <core/region.h>
251+
252+#include <gio/gio.h>
253+
254+#include "inputremover.h"
255+
256+namespace unity
257+{
258+
259+class UnityShowdesktopHandlerWindowInterface
260+{
261+ public:
262+
263+ enum class PostPaintAction {
264+ Wait = 0,
265+ Damage = 1,
266+ Remove = 2
267+ };
268+
269+ virtual ~UnityShowdesktopHandlerWindowInterface ();
270+
271+ void EnableFocus () { DoEnableFocus (); }
272+ void DisableFocus () { DoDisableFocus (); }
273+
274+ bool OverrideRedirect () { return IsOverrideRedirect (); }
275+ bool Managed () { return IsManaged (); }
276+ bool Grabbed () { return IsGrabbed (); }
277+ bool DesktopOrDock () { return IsDesktopOrDock (); }
278+ bool SkipTaskbarOrPager () { return IsSkipTaskbarOrPager (); }
279+ bool Hidden () { return IsHidden (); }
280+ bool Shaded () { return IsShaded (); }
281+ bool Minimized () { return IsMinimized (); }
282+ bool ShowDesktopMode () { return IsInShowdesktopMode (); }
283+ void OverrideFrameRegion (CompRegion &r) { return DoOverrideFrameRegion (r); }
284+
285+ void Hide () { DoHide (); }
286+ void NotifyHidden () { DoNotifyHidden (); }
287+ void Show () { DoShow (); }
288+ void NotifyShown () { DoNotifyShown (); }
289+ void MoveFocusAway () { DoMoveFocusAway (); }
290+
291+ PostPaintAction HandleAnimations (unsigned int ms) { return DoHandleAnimations (ms); }
292+ void AddDamage () { DoAddDamage (); }
293+
294+ void DeleteHandler () { DoDeleteHandler (); }
295+
296+ unsigned int NoCoreInstanceMask () { return GetNoCoreInstanceMask (); }
297+
298+ compiz::WindowInputRemoverInterface::Ptr InputRemover () { return GetInputRemover (); }
299+
300+ protected:
301+
302+ virtual void DoEnableFocus () = 0;
303+ virtual void DoDisableFocus () = 0;
304+
305+ virtual bool IsOverrideRedirect () = 0;
306+ virtual bool IsManaged () = 0;
307+ virtual bool IsGrabbed () = 0;
308+ virtual bool IsDesktopOrDock () = 0;
309+
310+ virtual bool IsSkipTaskbarOrPager () = 0;
311+ virtual bool IsHidden () = 0;
312+ virtual bool IsInShowdesktopMode () = 0;
313+ virtual bool IsShaded () = 0;
314+
315+ virtual bool IsMinimized () = 0;
316+
317+ virtual void DoOverrideFrameRegion (CompRegion &) = 0;
318+
319+ virtual void DoHide () = 0;
320+ virtual void DoNotifyHidden () = 0;
321+ virtual void DoShow () = 0;
322+ virtual void DoNotifyShown () = 0;
323+
324+ virtual void DoMoveFocusAway () = 0;
325+ virtual PostPaintAction DoHandleAnimations (unsigned int ms) = 0;
326+ virtual void DoAddDamage () = 0;
327+
328+ virtual void DoDeleteHandler () = 0;
329+
330+ virtual unsigned int GetNoCoreInstanceMask () = 0;
331+
332+ virtual compiz::WindowInputRemoverInterface::Ptr GetInputRemover () = 0;
333+};
334+
335+class UnityShowdesktopHandler
336+{
337+ public:
338+
339+ UnityShowdesktopHandler (UnityShowdesktopHandlerWindowInterface *uwi);
340+ ~UnityShowdesktopHandler ();
341+
342+ typedef enum {
343+ StateVisible = 0,
344+ StateFadeOut = 1,
345+ StateFadeIn = 2,
346+ StateInvisible = 3
347+ } State;
348+
349+public:
350+
351+ void FadeOut ();
352+ void FadeIn ();
353+ UnityShowdesktopHandlerWindowInterface::PostPaintAction Animate (unsigned int ms);
354+ void PaintOpacity (unsigned short &opacity);
355+ unsigned int GetPaintMask ();
356+ void HandleShapeEvent ();
357+ void WindowFocusChangeNotify ();
358+ void UpdateFrameRegion (CompRegion &r);
359+
360+ UnityShowdesktopHandler::State GetState ();
361+
362+ static const unsigned int fade_time;
363+ static std::list <UnityShowdesktopHandlerWindowInterface *> animating_windows;
364+ static bool ShouldHide (UnityShowdesktopHandlerWindowInterface *);
365+ static void InhibitLeaveShowdesktopMode (guint32 xid);
366+ static void AllowLeaveShowdesktopMode (guint32 xid);
367+ static guint32 InhibitingXid ();
368+
369+private:
370+
371+ UnityShowdesktopHandlerWindowInterface *showdesktop_handler_window_interface_;
372+ compiz::WindowInputRemoverInterface::Ptr remover_;
373+ UnityShowdesktopHandler::State state_;
374+ float progress_;
375+ bool was_hidden_;
376+ static guint32 inhibiting_xid;
377+};
378+
379+}
380+
381+
382+#endif
383
384=== modified file 'plugins/unityshell/src/inputremover.cpp'
385--- plugins/unityshell/src/inputremover.cpp 2011-09-28 16:25:42 +0000
386+++ plugins/unityshell/src/inputremover.cpp 2012-04-02 01:40:26 +0000
387@@ -24,6 +24,10 @@
388 #include <cstdio>
389 #include <cstring>
390
391+compiz::WindowInputRemoverInterface::~WindowInputRemoverInterface ()
392+{
393+}
394+
395 compiz::WindowInputRemover::WindowInputRemover (Display *dpy,
396 Window xid) :
397 mDpy (dpy),
398@@ -203,7 +207,7 @@
399 }
400
401 bool
402-compiz::WindowInputRemover::save ()
403+compiz::WindowInputRemover::saveInput ()
404 {
405 XRectangle *rects;
406 int count = 0, ordering;
407@@ -267,7 +271,7 @@
408 }
409
410 bool
411-compiz::WindowInputRemover::remove ()
412+compiz::WindowInputRemover::removeInput ()
413 {
414 if (!mNInputRects)
415 if (!save ())
416@@ -290,7 +294,7 @@
417 }
418
419 bool
420-compiz::WindowInputRemover::restore ()
421+compiz::WindowInputRemover::restoreInput ()
422 {
423 XShapeSelectInput (mDpy, mShapeWindow, NoEventMask);
424
425
426=== modified file 'plugins/unityshell/src/inputremover.h'
427--- plugins/unityshell/src/inputremover.h 2011-09-13 12:52:31 +0000
428+++ plugins/unityshell/src/inputremover.h 2012-04-02 01:40:26 +0000
429@@ -22,6 +22,8 @@
430 #ifndef _COMPIZ_INPUTREMOVER_H
431 #define _COMPIZ_INPUTREMOVER_H
432
433+#include <memory>
434+
435 #include <X11/Xlib.h>
436 #include <X11/Xatom.h>
437 #include <X11/extensions/shape.h>
438@@ -29,19 +31,39 @@
439 // Will be merged back into compiz
440 namespace compiz {
441
442-class WindowInputRemover
443+class WindowInputRemoverInterface
444+{
445+ public:
446+
447+ typedef std::shared_ptr <WindowInputRemoverInterface> Ptr;
448+
449+ bool save () { return saveInput (); }
450+ bool remove () { return removeInput (); }
451+ bool restore () { return restoreInput (); }
452+
453+ virtual ~WindowInputRemoverInterface ();
454+
455+ protected:
456+
457+ virtual bool saveInput () = 0;
458+ virtual bool removeInput () = 0;
459+ virtual bool restoreInput () = 0;
460+};
461+
462+class WindowInputRemover :
463+ public WindowInputRemoverInterface
464 {
465 public:
466
467 WindowInputRemover (Display *, Window xid);
468 ~WindowInputRemover ();
469
470- bool save ();
471- bool remove ();
472- bool restore ();
473-
474 private:
475
476+ bool saveInput ();
477+ bool removeInput ();
478+ bool restoreInput ();
479+
480 void sendShapeNotify ();
481
482 Display *mDpy;
483
484=== modified file 'plugins/unityshell/src/unityshell.cpp'
485--- plugins/unityshell/src/unityshell.cpp 2012-03-30 15:24:34 +0000
486+++ plugins/unityshell/src/unityshell.cpp 2012-04-02 01:40:26 +0000
487@@ -904,7 +904,9 @@
488 {
489 for (CompWindow *w : screen->windows ())
490 {
491- if (UnityShowdesktopHandler::shouldHide (w))
492+ UnityWindow *uw = UnityWindow::get (w);
493+
494+ if (UnityShowdesktopHandler::ShouldHide (static_cast <UnityShowdesktopHandlerWindowInterface *> (uw)))
495 {
496 UnityWindow::get (w)->enterShowDesktop ();
497 // the animation plugin does strange things here ...
498@@ -941,16 +943,16 @@
499 /* Where a window is inhibiting, only allow the window
500 * that is inhibiting the leave show desktop to actually
501 * fade in again - all other windows should remain faded out */
502- if (!UnityShowdesktopHandler::inhibitingXid ())
503+ if (!UnityShowdesktopHandler::InhibitingXid ())
504 {
505 for (CompWindow *cw : screen->windows ())
506 {
507 if (cw->inShowDesktopMode ())
508 {
509- UnityWindow::get (cw)->leaveShowDesktop ();
510- // the animation plugin does strange things here ...
511- // if this notification is sent
512- //cw->windowNotify (CompWindowNotifyLeaveShowDesktopMode);
513+ UnityWindow::get (cw)->leaveShowDesktop ();
514+ // the animation plugin does strange things here ...
515+ // if this notification is sent
516+ //cw->windowNotify (CompWindowNotifyLeaveShowDesktopMode);
517 }
518 }
519
520@@ -960,12 +962,12 @@
521 }
522 else
523 {
524- CompWindow *cw = screen->findWindow (UnityShowdesktopHandler::inhibitingXid ());
525+ CompWindow *cw = screen->findWindow (UnityShowdesktopHandler::InhibitingXid ());
526 if (cw)
527 {
528 if (cw->inShowDesktopMode ())
529 {
530- UnityWindow::get (cw)->leaveShowDesktop ();
531+ UnityWindow::get (cw)->leaveShowDesktop ();
532 }
533 }
534 }
535@@ -974,227 +976,159 @@
536 void UnityWindow::enterShowDesktop ()
537 {
538 if (!mShowdesktopHandler)
539- mShowdesktopHandler = new UnityShowdesktopHandler (window);
540+ mShowdesktopHandler = new UnityShowdesktopHandler (static_cast <UnityShowdesktopHandlerWindowInterface *> (this));
541
542 window->setShowDesktopMode (true);
543- mShowdesktopHandler->fadeOut ();
544+ mShowdesktopHandler->FadeOut ();
545 }
546
547 void UnityWindow::leaveShowDesktop ()
548 {
549 if (mShowdesktopHandler)
550 {
551- mShowdesktopHandler->fadeIn ();
552+ mShowdesktopHandler->FadeIn ();
553 window->setShowDesktopMode (false);
554- delete mShowdesktopHandler;
555- mShowdesktopHandler = NULL;
556 }
557 }
558
559 void UnityWindow::activate ()
560 {
561- UnityShowdesktopHandler::inhibitLeaveShowdesktopMode (window->id ());
562+ UnityShowdesktopHandler::InhibitLeaveShowdesktopMode (window->id ());
563 window->activate ();
564- UnityShowdesktopHandler::allowLeaveShowdesktopMode (window->id ());
565-}
566-
567-bool UnityWindow::handleAnimations (unsigned int ms)
568-{
569+ UnityShowdesktopHandler::AllowLeaveShowdesktopMode (window->id ());
570+}
571+
572+void UnityWindow::DoEnableFocus ()
573+{
574+ window->focusSetEnabled (this, true);
575+}
576+
577+void UnityWindow::DoDisableFocus ()
578+{
579+ window->focusSetEnabled (this, false);
580+}
581+
582+bool UnityWindow::IsOverrideRedirect ()
583+{
584+ return window->overrideRedirect ();
585+}
586+
587+bool UnityWindow::IsManaged ()
588+{
589+ return window->managed ();
590+}
591+
592+bool UnityWindow::IsGrabbed ()
593+{
594+ return window->grabbed ();
595+}
596+
597+bool UnityWindow::IsDesktopOrDock ()
598+{
599+ return (window->type () & (CompWindowTypeDesktopMask | CompWindowTypeDockMask));
600+}
601+
602+bool UnityWindow::IsSkipTaskbarOrPager ()
603+{
604+ return (window->state () & (CompWindowStateSkipTaskbarMask | CompWindowStateSkipPagerMask));
605+}
606+
607+bool UnityWindow::IsInShowdesktopMode ()
608+{
609+ return window->inShowDesktopMode ();
610+}
611+
612+bool UnityWindow::IsHidden ()
613+{
614+ return window->state () & CompWindowStateHiddenMask;
615+}
616+
617+bool UnityWindow::IsShaded ()
618+{
619+ return window->shaded ();
620+}
621+
622+bool UnityWindow::IsMinimized ()
623+{
624+ return window->minimized ();
625+}
626+
627+void UnityWindow::DoOverrideFrameRegion (CompRegion &region)
628+{
629+ unsigned int oldUpdateFrameRegionIndex = window->updateFrameRegionGetCurrentIndex ();
630+
631+ window->updateFrameRegionSetCurrentIndex (MAXSHORT);
632+ window->updateFrameRegion (region);
633+ window->updateFrameRegionSetCurrentIndex (oldUpdateFrameRegionIndex);
634+}
635+
636+void UnityWindow::DoHide ()
637+{
638+ window->changeState (window->state () | CompWindowStateHiddenMask);
639+}
640+
641+void UnityWindow::DoNotifyHidden ()
642+{
643+ window->windowNotify (CompWindowNotifyHide);
644+}
645+
646+void UnityWindow::DoShow ()
647+{
648+ window->changeState (window->state () & ~(CompWindowStateHiddenMask));
649+}
650+
651+void UnityWindow::DoNotifyShown ()
652+{
653+ window->windowNotify (CompWindowNotifyShow);
654+}
655+
656+void UnityWindow::DoMoveFocusAway ()
657+{
658+ window->moveInputFocusToOtherWindow ();
659+}
660+
661+UnityShowdesktopHandlerWindowInterface::PostPaintAction UnityWindow::DoHandleAnimations (unsigned int ms)
662+{
663+ UnityShowdesktopHandlerWindowInterface::PostPaintAction action = UnityShowdesktopHandlerWindowInterface::PostPaintAction::Wait;
664+
665 if (mShowdesktopHandler)
666- if (mShowdesktopHandler->animate (ms))
667- {
668- delete mShowdesktopHandler;
669- mShowdesktopHandler = NULL;
670- return true;
671- }
672-
673- return false;
674-}
675-
676-/* 300 ms */
677-const unsigned int UnityShowdesktopHandler::fade_time = 300;
678-CompWindowList UnityShowdesktopHandler::animating_windows (0);
679-
680-bool UnityShowdesktopHandler::shouldHide (CompWindow *w)
681-{
682- if (w->overrideRedirect ())
683- return false;
684-
685- if (!w->managed ())
686- return false;
687-
688- if (w->grabbed ())
689- return false;
690-
691- if (w->wmType () & (CompWindowTypeDesktopMask |
692- CompWindowTypeDockMask))
693- return false;
694-
695- if (w->state () & (CompWindowStateSkipPagerMask |
696- CompWindowStateSkipTaskbarMask))
697- return false;
698-
699- if ((w->state () & CompWindowStateHiddenMask))
700- if (!(w->inShowDesktopMode () || w->shaded ()))
701- return false;
702-
703- return true;
704-}
705-
706-guint32 UnityShowdesktopHandler::mInhibitingXid = 0;
707-
708-void
709-UnityShowdesktopHandler::inhibitLeaveShowdesktopMode (guint32 xid)
710-{
711- if (!mInhibitingXid)
712- mInhibitingXid = xid;
713-}
714-
715-void
716-UnityShowdesktopHandler::allowLeaveShowdesktopMode (guint32 xid)
717-{
718- if (mInhibitingXid == xid)
719- mInhibitingXid = 0;
720-}
721-
722-guint32
723-UnityShowdesktopHandler::inhibitingXid ()
724-{
725- return mInhibitingXid;
726-}
727-
728-UnityShowdesktopHandler::UnityShowdesktopHandler (CompWindow *w) :
729- mWindow (w),
730- mRemover (new compiz::WindowInputRemover (screen->dpy (), w->id ())),
731- mState (Visible),
732- mProgress (0.0f)
733-{
734-}
735-
736-UnityShowdesktopHandler::~UnityShowdesktopHandler ()
737-{
738- if (mRemover)
739- delete mRemover;
740-}
741-
742-void UnityShowdesktopHandler::fadeOut ()
743-{
744- mState = UnityShowdesktopHandler::FadeOut;
745- mProgress = 1.0f;
746-
747- mWasHidden = mWindow->state () & CompWindowStateHiddenMask;
748-
749- if (!mWasHidden)
750- {
751- mWindow->changeState (mWindow->state () | CompWindowStateHiddenMask);
752- mWindow->windowNotify (CompWindowNotifyHide);
753- mRemover->save ();
754- mRemover->remove ();
755- }
756-
757- CompositeWindow::get (mWindow)->addDamage ();
758-
759- if (std::find (animating_windows.begin(),
760- animating_windows.end(),
761- mWindow) == animating_windows.end())
762- animating_windows.push_back(mWindow);
763-}
764-
765-void UnityShowdesktopHandler::fadeIn ()
766-{
767- mState = UnityShowdesktopHandler::FadeIn;
768-
769- if (!mWasHidden)
770- {
771- mWindow->changeState (mWindow->state () & ~CompWindowStateHiddenMask);
772- mWindow->windowNotify (CompWindowNotifyShow);
773- mRemover->restore ();
774- }
775-
776- CompositeWindow::get (mWindow)->addDamage ();
777-}
778-
779-bool UnityShowdesktopHandler::animate (unsigned int ms)
780-{
781- float inc = fade_time / (float) ms;
782-
783- if (mState == UnityShowdesktopHandler::FadeOut)
784- {
785- mProgress -= inc;
786- if (mProgress <= 0.0f)
787- {
788- mProgress = 0.0f;
789- mState = Invisible;
790- }
791- else
792- CompositeWindow::get (mWindow)->addDamage ();
793- }
794- else if (mState == FadeIn)
795- {
796- mProgress += inc;
797- if (mProgress >= 1.0f)
798- {
799- mProgress = 1.0f;
800- mState = Visible;
801-
802- return true;
803- }
804- else
805- CompositeWindow::get (mWindow)->addDamage ();
806- }
807-
808- return false;
809-}
810-
811-void UnityShowdesktopHandler::paintAttrib (GLWindowPaintAttrib &attrib)
812-{
813- attrib.opacity = static_cast <int> (static_cast <float> (attrib.opacity) * mProgress);
814-}
815-
816-unsigned int UnityShowdesktopHandler::getPaintMask ()
817-{
818- return 0;
819-}
820-
821-void UnityShowdesktopHandler::handleEvent (XEvent *event)
822-{
823- /* Ignore sent events from the InputRemover */
824- if (screen->XShape () && event->type ==
825- screen->shapeEvent () + ShapeNotify &&
826+ action = mShowdesktopHandler->Animate (ms);
827+
828+ return action;
829+}
830+
831+void UnityWindow::DoAddDamage ()
832+{
833+ cWindow->addDamage ();
834+}
835+
836+void UnityWindow::DoDeleteHandler ()
837+{
838+ delete mShowdesktopHandler;
839+ mShowdesktopHandler = NULL;
840+}
841+
842+compiz::WindowInputRemoverInterface::Ptr
843+UnityWindow::GetInputRemover ()
844+{
845+ return compiz::WindowInputRemoverInterface::Ptr (new compiz::WindowInputRemover (screen->dpy (), window->id ()));
846+}
847+
848+unsigned int
849+UnityWindow::GetNoCoreInstanceMask ()
850+{
851+ return PAINT_WINDOW_NO_CORE_INSTANCE_MASK;
852+}
853+
854+void UnityWindow::handleEvent (XEvent *event)
855+{
856+ if (screen->XShape () &&
857+ event->type == screen->shapeEvent () + ShapeNotify &&
858 !event->xany.send_event)
859 {
860- if (mRemover)
861- {
862- mRemover->save ();
863- mRemover->remove ();
864- }
865- }
866-}
867-
868-void UnityShowdesktopHandler::windowNotify (CompWindowNotify n)
869-{
870- if (n == CompWindowNotifyFocusChange && mWindow->minimized ())
871- {
872- for (CompWindow *w : animating_windows)
873- w->focusSetEnabled (UnityWindow::get (w), false);
874-
875- mWindow->moveInputFocusToOtherWindow ();
876-
877- for (CompWindow *w : animating_windows)
878- w->focusSetEnabled (UnityWindow::get (w), true);
879- }
880-}
881-
882-void UnityShowdesktopHandler::updateFrameRegion (CompRegion &r)
883-{
884- unsigned int oldUpdateFrameRegionIndex;
885- r = CompRegion ();
886-
887- /* Ensure no other plugins can touch this frame region */
888- oldUpdateFrameRegionIndex = mWindow->updateFrameRegionGetCurrentIndex ();
889- mWindow->updateFrameRegionSetCurrentIndex (MAXSHORT);
890- mWindow->updateFrameRegion (r);
891- mWindow->updateFrameRegionSetCurrentIndex (oldUpdateFrameRegionIndex);
892+ if (mShowdesktopHandler)
893+ mShowdesktopHandler->HandleShapeEvent ();
894+ }
895 }
896
897 /* called whenever we need to repaint parts of the screen */
898@@ -1275,16 +1209,10 @@
899
900 void UnityScreen::preparePaint(int ms)
901 {
902- CompWindowList remove_windows;
903-
904 cScreen->preparePaint(ms);
905
906- for (CompWindow *w : UnityShowdesktopHandler::animating_windows)
907- if (UnityWindow::get (w)->handleAnimations (ms))
908- remove_windows.push_back(w);
909-
910- for (CompWindow *w : remove_windows)
911- UnityShowdesktopHandler::animating_windows.remove (w);
912+ for (UnityShowdesktopHandlerWindowInterface *wi : UnityShowdesktopHandler::animating_windows)
913+ wi->HandleAnimations (ms);
914
915 if (damaged)
916 {
917@@ -1294,6 +1222,28 @@
918
919 }
920
921+void UnityScreen::donePaint()
922+{
923+ std::list <UnityShowdesktopHandlerWindowInterface *> remove_windows;
924+
925+ for (UnityShowdesktopHandlerWindowInterface *wi : UnityShowdesktopHandler::animating_windows)
926+ {
927+ UnityShowdesktopHandlerWindowInterface::PostPaintAction action = wi->HandleAnimations (0);
928+ if (action == UnityShowdesktopHandlerWindowInterface::PostPaintAction::Remove)
929+ remove_windows.push_back(wi);
930+ else if (action == UnityShowdesktopHandlerWindowInterface::PostPaintAction::Damage)
931+ wi->AddDamage ();
932+ }
933+
934+ for (UnityShowdesktopHandlerWindowInterface *wi : remove_windows)
935+ {
936+ wi->DeleteHandler ();
937+ UnityShowdesktopHandler::animating_windows.remove (wi);
938+ }
939+
940+ cScreen->donePaint ();
941+}
942+
943 /* Grab changed nux regions and add damage rects for them */
944 void UnityScreen::damageNuxRegions()
945 {
946@@ -1429,7 +1379,7 @@
947 break;
948 }
949 case MapRequest:
950- UnityShowdesktopHandler::inhibitLeaveShowdesktopMode (event->xmaprequest.window);
951+ UnityShowdesktopHandler::InhibitLeaveShowdesktopMode (event->xmaprequest.window);
952 break;
953 default:
954 if (screen->shapeEvent () + ShapeNotify == event->type)
955@@ -1441,8 +1391,7 @@
956 {
957 UnityWindow *uw = UnityWindow::get (w);
958
959- if (uw->mShowdesktopHandler)
960- uw->mShowdesktopHandler->handleEvent(event);
961+ uw->handleEvent(event);
962 }
963 }
964 break;
965@@ -1463,7 +1412,7 @@
966 }
967 break;
968 case MapRequest:
969- UnityShowdesktopHandler::allowLeaveShowdesktopMode (event->xmaprequest.window);
970+ UnityShowdesktopHandler::AllowLeaveShowdesktopMode (event->xmaprequest.window);
971 break;
972 }
973
974@@ -2149,8 +2098,8 @@
975 }
976 else if (mShowdesktopHandler)
977 {
978- mShowdesktopHandler->paintAttrib (wAttrib);
979- mask |= mShowdesktopHandler->getPaintMask ();
980+ mShowdesktopHandler->PaintOpacity (wAttrib.opacity);
981+ mask |= mShowdesktopHandler->GetPaintMask ();
982 }
983
984 if (uScreen->panel_controller_->GetTrayXid () == window->id () && !uScreen->allowWindowPaint)
985@@ -2280,7 +2229,7 @@
986 }
987
988 bool
989-UnityWindow::minimized ()
990+UnityWindow::Minimized ()
991 {
992 return mMinimizeHandler.get () != nullptr;
993 }
994@@ -2354,7 +2303,8 @@
995 }
996 else if (mShowdesktopHandler)
997 {
998- mShowdesktopHandler->windowNotify (n);
999+ if (n == CompWindowNotifyFocusChange)
1000+ mShowdesktopHandler->WindowFocusChangeNotify ();
1001 }
1002
1003 // We do this after the notify to ensure input focus has actually been moved.
1004@@ -2393,7 +2343,7 @@
1005 if (mMinimizeHandler)
1006 mMinimizeHandler->updateFrameRegion (region);
1007 else if (mShowdesktopHandler)
1008- mShowdesktopHandler->updateFrameRegion (region);
1009+ mShowdesktopHandler->UpdateFrameRegion (region);
1010 else
1011 window->updateFrameRegion (region);
1012 }
1013@@ -2933,7 +2883,7 @@
1014 window->minimize ();
1015 }
1016
1017- UnityShowdesktopHandler::animating_windows.remove (window);
1018+ UnityShowdesktopHandler::animating_windows.remove (static_cast <UnityShowdesktopHandlerWindowInterface *> (this));
1019
1020 if (mShowdesktopHandler)
1021 delete mShowdesktopHandler;
1022
1023=== modified file 'plugins/unityshell/src/unityshell.h'
1024--- plugins/unityshell/src/unityshell.h 2012-03-30 04:00:05 +0000
1025+++ plugins/unityshell/src/unityshell.h 2012-04-02 01:40:26 +0000
1026@@ -50,6 +50,7 @@
1027 #include "SwitcherController.h"
1028 #include "UBusWrapper.h"
1029 #include "UnityshellPrivate.h"
1030+#include "UnityShowdesktopHandler.h"
1031 #ifndef USE_GLES
1032 #include "ScreenEffectFramebufferObject.h"
1033 #endif
1034@@ -64,51 +65,6 @@
1035 namespace unity
1036 {
1037
1038-class UnityShowdesktopHandler
1039-{
1040- public:
1041-
1042- UnityShowdesktopHandler (CompWindow *w);
1043- ~UnityShowdesktopHandler ();
1044-
1045- typedef enum {
1046- Visible = 0,
1047- FadeOut = 1,
1048- FadeIn = 2,
1049- Invisible = 3
1050- } State;
1051-
1052-public:
1053-
1054- void fadeOut ();
1055- void fadeIn ();
1056- bool animate (unsigned int ms);
1057- void paintAttrib (GLWindowPaintAttrib &attrib);
1058- unsigned int getPaintMask ();
1059- void handleEvent (XEvent *);
1060- void windowNotify (CompWindowNotify n);
1061- void updateFrameRegion (CompRegion &r);
1062-
1063- UnityShowdesktopHandler::State state ();
1064-
1065- static const unsigned int fade_time;
1066- static CompWindowList animating_windows;
1067- static bool shouldHide (CompWindow *);
1068- static void inhibitLeaveShowdesktopMode (guint32 xid);
1069- static void allowLeaveShowdesktopMode (guint32 xid);
1070- static guint32 inhibitingXid ();
1071-
1072-private:
1073-
1074- CompWindow *mWindow;
1075- compiz::WindowInputRemover *mRemover;
1076- UnityShowdesktopHandler::State mState;
1077- float mProgress;
1078- bool mWasHidden;
1079- static guint32 mInhibitingXid;
1080-};
1081-
1082-
1083 /* base screen class */
1084 class UnityScreen :
1085 public unity::debug::Introspectable,
1086@@ -145,6 +101,7 @@
1087
1088 void preparePaint (int ms);
1089 void paintFboForOutput (CompOutput *output);
1090+ void donePaint ();
1091
1092 void RaiseInputWindows();
1093
1094@@ -351,6 +308,7 @@
1095 class UnityWindow :
1096 public WindowInterface,
1097 public GLWindowInterface,
1098+ public UnityShowdesktopHandlerWindowInterface,
1099 public BaseSwitchWindow,
1100 public PluginClassHandler <UnityWindow, CompWindow>
1101 {
1102@@ -365,7 +323,7 @@
1103
1104 void minimize ();
1105 void unminimize ();
1106- bool minimized ();
1107+ bool Minimized ();
1108 bool focus ();
1109 void activate ();
1110
1111@@ -407,7 +365,9 @@
1112
1113 void enterShowDesktop ();
1114 void leaveShowDesktop ();
1115- bool handleAnimations (unsigned int ms);
1116+ bool HandleAnimations (unsigned int ms);
1117+
1118+ void handleEvent (XEvent *event);
1119
1120 typedef compiz::CompizMinimizedWindowHandler<UnityScreen, UnityWindow>
1121 UnityMinimizedHandler;
1122@@ -419,6 +379,36 @@
1123
1124 guint focusdesktop_handle_;
1125 static gboolean FocusDesktopTimeout(gpointer data);
1126+
1127+ void DoEnableFocus ();
1128+ void DoDisableFocus ();
1129+
1130+ bool IsOverrideRedirect ();
1131+ bool IsManaged ();
1132+ bool IsGrabbed ();
1133+ bool IsDesktopOrDock ();
1134+ bool IsSkipTaskbarOrPager ();
1135+ bool IsHidden ();
1136+ bool IsInShowdesktopMode ();
1137+ bool IsShaded ();
1138+ bool IsMinimized ();
1139+ void DoOverrideFrameRegion (CompRegion &r);
1140+
1141+ void DoHide ();
1142+ void DoNotifyHidden ();
1143+ void DoShow ();
1144+ void DoNotifyShown ();
1145+
1146+ void DoAddDamage ();
1147+ UnityShowdesktopHandlerWindowInterface::PostPaintAction DoHandleAnimations (unsigned int ms);
1148+
1149+ void DoMoveFocusAway ();
1150+
1151+ void DoDeleteHandler ();
1152+
1153+ unsigned int GetNoCoreInstanceMask ();
1154+
1155+ compiz::WindowInputRemoverInterface::Ptr GetInputRemover ();
1156 };
1157
1158
1159
1160=== modified file 'tests/CMakeLists.txt'
1161--- tests/CMakeLists.txt 2012-03-31 10:47:22 +0000
1162+++ tests/CMakeLists.txt 2012-04-02 01:40:26 +0000
1163@@ -33,7 +33,7 @@
1164 )
1165 add_definitions (${CFLAGS})
1166
1167-set (LIBS ${TEST_UNIT_DEPS_LIBRARIES} "-lunity-core-${UNITY_API_VERSION} -lm")
1168+set (LIBS ${TEST_UNIT_DEPS_LIBRARIES} "-lunity-core-${UNITY_API_VERSION} -lcompiz_core -lm")
1169 link_libraries (${LIBS})
1170
1171 set (LIB_PATHS ${TEST_UNIT_DEPS_LIBRARY_DIRS})
1172@@ -140,6 +140,8 @@
1173 test_main_xless.cpp
1174 test_grabhandle.cpp
1175 test_unityshell_private.cpp
1176+ test_lensview_impl.cpp
1177+ test_showdesktop_handler.cpp
1178 ${UNITY_SRC}/AbstractLauncherIcon.cpp
1179 ${UNITY_SRC}/AbstractShortcutHint.h
1180 ${UNITY_SRC}/Animator.cpp
1181@@ -160,6 +162,7 @@
1182 ${UNITY_SRC}/Timer.cpp
1183 ${UNITY_SRC}/UnityshellPrivate.cpp
1184 ${UNITY_SRC}/WindowManager.cpp
1185+ ${UNITY_SRC}/UnityShowdesktopHandler.cpp
1186 ${CMAKE_SOURCE_DIR}/plugins/unity-mt-grab-handles/src/unity-mt-grab-handle.cpp
1187 ${CMAKE_SOURCE_DIR}/plugins/unity-mt-grab-handles/src/unity-mt-grab-handle-group.cpp
1188 ${CMAKE_SOURCE_DIR}/plugins/unity-mt-grab-handles/src/unity-mt-grab-handle-impl-factory.cpp
1189
1190=== added file 'tests/test_showdesktop_handler.cpp'
1191--- tests/test_showdesktop_handler.cpp 1970-01-01 00:00:00 +0000
1192+++ tests/test_showdesktop_handler.cpp 2012-04-02 01:40:26 +0000
1193@@ -0,0 +1,539 @@
1194+#include <list>
1195+#include <algorithm>
1196+#include <gtest/gtest.h>
1197+#include <gmock/gmock.h>
1198+#include <UnityShowdesktopHandler.h>
1199+
1200+using namespace unity;
1201+using ::testing::_;
1202+using ::testing::Return;
1203+using ::testing::Invoke;
1204+using ::testing::InSequence;
1205+
1206+compiz::WindowInputRemoverInterface::~WindowInputRemoverInterface () {}
1207+
1208+class MockWindowInputRemover :
1209+ public compiz::WindowInputRemoverInterface
1210+{
1211+ public:
1212+
1213+ MockWindowInputRemover ()
1214+ {
1215+ ON_CALL (*this, saveInput ()).WillByDefault (Return (true));
1216+ ON_CALL (*this, removeInput ()).WillByDefault (Return (true));
1217+ ON_CALL (*this, restoreInput ()).WillByDefault (Return (true));
1218+ }
1219+
1220+ MOCK_METHOD0 (saveInput, bool ());
1221+ MOCK_METHOD0 (removeInput, bool ());
1222+ MOCK_METHOD0 (restoreInput, bool ());
1223+};
1224+
1225+class UnityShowdesktopHandlerTest :
1226+ public ::testing::Test
1227+{
1228+public:
1229+
1230+ ~UnityShowdesktopHandlerTest ()
1231+ {
1232+ UnityShowdesktopHandler::animating_windows.clear ();
1233+ }
1234+
1235+ template <class T, class U> static typename T::Ptr makeShared () { return typename T::Ptr (new U); }
1236+
1237+};
1238+
1239+
1240+class MockUnityShowdesktopHandlerWindow :
1241+ public UnityShowdesktopHandlerWindowInterface
1242+{
1243+ public:
1244+
1245+ MockUnityShowdesktopHandlerWindow ()
1246+ {
1247+ ON_CALL (*this, IsOverrideRedirect ()).WillByDefault (Return (false));
1248+ ON_CALL (*this, IsManaged ()).WillByDefault (Return (true));
1249+ ON_CALL (*this, IsGrabbed ()).WillByDefault (Return (false));
1250+ ON_CALL (*this, IsDesktopOrDock ()).WillByDefault (Return (false));
1251+ ON_CALL (*this, IsSkipTaskbarOrPager ()).WillByDefault (Return (false));
1252+ ON_CALL (*this, IsHidden ()).WillByDefault (Return (false));
1253+ ON_CALL (*this, IsInShowdesktopMode ()).WillByDefault (Return (false));
1254+ ON_CALL (*this, IsShaded ()).WillByDefault (Return (false));
1255+ ON_CALL (*this, IsMinimized ()).WillByDefault (Return (false));
1256+
1257+ ON_CALL (*this, DoHandleAnimations (_)).WillByDefault (Return (UnityShowdesktopHandlerWindowInterface::PostPaintAction::Damage));
1258+ ON_CALL (*this, GetNoCoreInstanceMask ()).WillByDefault (Return (1));
1259+ ON_CALL (*this, GetInputRemover ()).WillByDefault (Invoke (UnityShowdesktopHandlerTest::makeShared<compiz::WindowInputRemoverInterface, MockWindowInputRemover>));
1260+ }
1261+
1262+ MOCK_METHOD0 (DoEnableFocus, void ());
1263+ MOCK_METHOD0 (DoDisableFocus, void ());
1264+ MOCK_METHOD0 (IsOverrideRedirect, bool ());
1265+ MOCK_METHOD0 (IsManaged, bool ());
1266+ MOCK_METHOD0 (IsGrabbed, bool ());
1267+ MOCK_METHOD0 (IsDesktopOrDock, bool ());
1268+ MOCK_METHOD0 (IsSkipTaskbarOrPager, bool ());
1269+ MOCK_METHOD0 (IsHidden, bool ());
1270+ MOCK_METHOD0 (IsInShowdesktopMode, bool ());
1271+ MOCK_METHOD0 (IsShaded, bool ());
1272+ MOCK_METHOD0 (IsMinimized, bool ());
1273+ MOCK_METHOD1 (DoOverrideFrameRegion, void (CompRegion &));
1274+ MOCK_METHOD0 (DoHide, void ());
1275+ MOCK_METHOD0 (DoNotifyHidden, void ());
1276+ MOCK_METHOD0 (DoShow, void ());
1277+ MOCK_METHOD0 (DoNotifyShown, void ());
1278+ MOCK_METHOD0 (DoMoveFocusAway, void ());
1279+ MOCK_METHOD1 (DoHandleAnimations, UnityShowdesktopHandlerWindowInterface::PostPaintAction (unsigned int));
1280+ MOCK_METHOD0 (DoAddDamage, void ());
1281+ MOCK_METHOD0 (GetNoCoreInstanceMask, unsigned int ());
1282+ MOCK_METHOD0 (GetInputRemover, compiz::WindowInputRemoverInterface::Ptr ());
1283+ MOCK_METHOD0 (DoDeleteHandler, void ());
1284+};
1285+
1286+TEST_F(UnityShowdesktopHandlerTest, TestNoORWindowsSD)
1287+{
1288+ MockUnityShowdesktopHandlerWindow mMockWindow;
1289+
1290+ EXPECT_CALL (mMockWindow, GetInputRemover ());
1291+
1292+ UnityShowdesktopHandler mMockHandler (static_cast <UnityShowdesktopHandlerWindowInterface *> (&mMockWindow));
1293+
1294+ EXPECT_CALL (mMockWindow, IsOverrideRedirect ()).WillOnce (Return (true));
1295+ EXPECT_FALSE (UnityShowdesktopHandler::ShouldHide (&mMockWindow));
1296+}
1297+
1298+TEST_F(UnityShowdesktopHandlerTest, TestNoUnmanagedWindowsSD)
1299+{
1300+ MockUnityShowdesktopHandlerWindow mMockWindow;
1301+
1302+ EXPECT_CALL (mMockWindow, GetInputRemover ());
1303+
1304+ UnityShowdesktopHandler mMockHandler (static_cast <UnityShowdesktopHandlerWindowInterface *> (&mMockWindow));
1305+
1306+ EXPECT_CALL (mMockWindow, IsOverrideRedirect ());
1307+ EXPECT_CALL (mMockWindow, IsManaged ()).WillOnce (Return (false));
1308+ EXPECT_FALSE (UnityShowdesktopHandler::ShouldHide (&mMockWindow));
1309+}
1310+
1311+TEST_F(UnityShowdesktopHandlerTest, TestNoGrabbedWindowsSD)
1312+{
1313+ MockUnityShowdesktopHandlerWindow mMockWindow;
1314+
1315+ EXPECT_CALL (mMockWindow, GetInputRemover ());
1316+
1317+ UnityShowdesktopHandler mMockHandler (static_cast <UnityShowdesktopHandlerWindowInterface *> (&mMockWindow));
1318+
1319+ EXPECT_CALL (mMockWindow, IsOverrideRedirect ());
1320+ EXPECT_CALL (mMockWindow, IsManaged ());
1321+ EXPECT_CALL (mMockWindow, IsGrabbed ()).WillOnce (Return (true));
1322+ EXPECT_FALSE (UnityShowdesktopHandler::ShouldHide (&mMockWindow));
1323+}
1324+
1325+TEST_F(UnityShowdesktopHandlerTest, TestNoDesktopOrDockWindowsSD)
1326+{
1327+ MockUnityShowdesktopHandlerWindow mMockWindow;
1328+
1329+ EXPECT_CALL (mMockWindow, GetInputRemover ());
1330+
1331+ UnityShowdesktopHandler mMockHandler (static_cast <UnityShowdesktopHandlerWindowInterface *> (&mMockWindow));
1332+
1333+ EXPECT_CALL (mMockWindow, IsOverrideRedirect ());
1334+ EXPECT_CALL (mMockWindow, IsManaged ());
1335+ EXPECT_CALL (mMockWindow, IsGrabbed ());
1336+ EXPECT_CALL (mMockWindow, IsDesktopOrDock ()).WillOnce (Return (true));
1337+ EXPECT_FALSE (UnityShowdesktopHandler::ShouldHide (&mMockWindow));
1338+}
1339+
1340+TEST_F(UnityShowdesktopHandlerTest, TestNoSkipTaskbarOrPagerWindowsSD)
1341+{
1342+ MockUnityShowdesktopHandlerWindow mMockWindow;
1343+
1344+ EXPECT_CALL (mMockWindow, GetInputRemover ());
1345+
1346+ UnityShowdesktopHandler mMockHandler (static_cast <UnityShowdesktopHandlerWindowInterface *> (&mMockWindow));
1347+
1348+ EXPECT_CALL (mMockWindow, IsOverrideRedirect ());
1349+ EXPECT_CALL (mMockWindow, IsManaged ());
1350+ EXPECT_CALL (mMockWindow, IsGrabbed ());
1351+ EXPECT_CALL (mMockWindow, IsDesktopOrDock ());
1352+ EXPECT_CALL (mMockWindow, IsSkipTaskbarOrPager ()).WillOnce (Return (true));
1353+ EXPECT_FALSE (UnityShowdesktopHandler::ShouldHide (&mMockWindow));
1354+}
1355+
1356+TEST_F(UnityShowdesktopHandlerTest, TestHiddenNotSDAndShadedWindowsNoSD)
1357+{
1358+ MockUnityShowdesktopHandlerWindow mMockWindow;
1359+
1360+ EXPECT_CALL (mMockWindow, GetInputRemover ());
1361+
1362+ UnityShowdesktopHandler mMockHandler (static_cast <UnityShowdesktopHandlerWindowInterface *> (&mMockWindow));
1363+
1364+ EXPECT_CALL (mMockWindow, IsOverrideRedirect ());
1365+ EXPECT_CALL (mMockWindow, IsManaged ());
1366+ EXPECT_CALL (mMockWindow, IsGrabbed ());
1367+ EXPECT_CALL (mMockWindow, IsDesktopOrDock ());
1368+ EXPECT_CALL (mMockWindow, IsSkipTaskbarOrPager ());
1369+ EXPECT_CALL (mMockWindow, IsHidden ()).WillOnce (Return (true));
1370+ EXPECT_CALL (mMockWindow, IsInShowdesktopMode ()).WillOnce (Return (false));
1371+ EXPECT_CALL (mMockWindow, IsShaded ()).WillOnce (Return (true));
1372+ EXPECT_FALSE (UnityShowdesktopHandler::ShouldHide (&mMockWindow));
1373+}
1374+
1375+TEST_F(UnityShowdesktopHandlerTest, TestHiddenSDAndShadedWindowsNoSD)
1376+{
1377+ MockUnityShowdesktopHandlerWindow mMockWindow;
1378+
1379+ EXPECT_CALL (mMockWindow, GetInputRemover ());
1380+
1381+ UnityShowdesktopHandler mMockHandler (static_cast <UnityShowdesktopHandlerWindowInterface *> (&mMockWindow));
1382+
1383+ EXPECT_CALL (mMockWindow, IsOverrideRedirect ());
1384+ EXPECT_CALL (mMockWindow, IsManaged ());
1385+ EXPECT_CALL (mMockWindow, IsGrabbed ());
1386+ EXPECT_CALL (mMockWindow, IsDesktopOrDock ());
1387+ EXPECT_CALL (mMockWindow, IsSkipTaskbarOrPager ());
1388+ EXPECT_CALL (mMockWindow, IsHidden ()).WillOnce (Return (true));
1389+ EXPECT_CALL (mMockWindow, IsInShowdesktopMode ()).WillOnce (Return (true));
1390+ EXPECT_FALSE (UnityShowdesktopHandler::ShouldHide (&mMockWindow));
1391+}
1392+
1393+TEST_F(UnityShowdesktopHandlerTest, TestHiddenNotSDAndNotShadedWindowsSD)
1394+{
1395+ MockUnityShowdesktopHandlerWindow mMockWindow;
1396+
1397+ EXPECT_CALL (mMockWindow, GetInputRemover ());
1398+
1399+ UnityShowdesktopHandler mMockHandler (static_cast <UnityShowdesktopHandlerWindowInterface *> (&mMockWindow));
1400+
1401+ EXPECT_CALL (mMockWindow, IsOverrideRedirect ());
1402+ EXPECT_CALL (mMockWindow, IsManaged ());
1403+ EXPECT_CALL (mMockWindow, IsGrabbed ());
1404+ EXPECT_CALL (mMockWindow, IsDesktopOrDock ());
1405+ EXPECT_CALL (mMockWindow, IsSkipTaskbarOrPager ());
1406+ EXPECT_CALL (mMockWindow, IsHidden ()).WillOnce (Return (true));
1407+ EXPECT_CALL (mMockWindow, IsInShowdesktopMode ()).WillOnce (Return (false));
1408+ EXPECT_CALL (mMockWindow, IsShaded ()).WillOnce (Return (false));
1409+ EXPECT_TRUE (UnityShowdesktopHandler::ShouldHide (&mMockWindow));
1410+}
1411+
1412+class MockWindowInputRemoverTestFadeOut :
1413+ public compiz::WindowInputRemoverInterface
1414+{
1415+ public:
1416+
1417+ MockWindowInputRemoverTestFadeOut ()
1418+ {
1419+ ON_CALL (*this, saveInput ()).WillByDefault (Return (true));
1420+ ON_CALL (*this, removeInput ()).WillByDefault (Return (true));
1421+ ON_CALL (*this, restoreInput ()).WillByDefault (Return (true));
1422+
1423+ EXPECT_CALL (*this, saveInput ()).WillOnce (Return (true));
1424+ EXPECT_CALL (*this, removeInput ()).WillOnce (Return (true));
1425+ }
1426+
1427+ MOCK_METHOD0 (saveInput, bool ());
1428+ MOCK_METHOD0 (removeInput, bool ());
1429+ MOCK_METHOD0 (restoreInput, bool ());
1430+};
1431+
1432+TEST_F(UnityShowdesktopHandlerTest, TestFadeOutHidesWindow)
1433+{
1434+ MockUnityShowdesktopHandlerWindow mMockWindow;
1435+
1436+ EXPECT_CALL (mMockWindow, GetInputRemover ()).WillOnce (Invoke (UnityShowdesktopHandlerTest::makeShared<compiz::WindowInputRemoverInterface, MockWindowInputRemoverTestFadeOut>));
1437+
1438+ UnityShowdesktopHandler mMockHandler (static_cast <UnityShowdesktopHandlerWindowInterface *> (&mMockWindow));
1439+
1440+ EXPECT_CALL (mMockWindow, IsHidden ());
1441+ EXPECT_CALL (mMockWindow, DoHide ());
1442+ EXPECT_CALL (mMockWindow, DoNotifyHidden ());
1443+
1444+ mMockHandler.FadeOut ();
1445+
1446+ EXPECT_EQ (UnityShowdesktopHandler::animating_windows.size (), 1);
1447+}
1448+
1449+class MockWindowInputRemoverTestFadeOutAlready :
1450+ public compiz::WindowInputRemoverInterface
1451+{
1452+ public:
1453+
1454+ MockWindowInputRemoverTestFadeOutAlready ()
1455+ {
1456+ ON_CALL (*this, saveInput ()).WillByDefault (Return (true));
1457+ ON_CALL (*this, removeInput ()).WillByDefault (Return (true));
1458+ ON_CALL (*this, restoreInput ()).WillByDefault (Return (true));
1459+ }
1460+
1461+ MOCK_METHOD0 (saveInput, bool ());
1462+ MOCK_METHOD0 (removeInput, bool ());
1463+ MOCK_METHOD0 (restoreInput, bool ());
1464+};
1465+
1466+TEST_F(UnityShowdesktopHandlerTest, TestFadeOutOnHiddenDoesntHideWindow)
1467+{
1468+ MockUnityShowdesktopHandlerWindow mMockWindow;
1469+
1470+ EXPECT_CALL (mMockWindow, GetInputRemover ()).WillOnce (Invoke (UnityShowdesktopHandlerTest::makeShared<compiz::WindowInputRemoverInterface, MockWindowInputRemoverTestFadeOutAlready>));
1471+
1472+ UnityShowdesktopHandler mMockHandler (static_cast <UnityShowdesktopHandlerWindowInterface *> (&mMockWindow));
1473+
1474+ EXPECT_CALL (mMockWindow, IsHidden ()).WillOnce (Return (true));
1475+
1476+ mMockHandler.FadeOut ();
1477+
1478+ EXPECT_EQ (UnityShowdesktopHandler::animating_windows.size (), 0);
1479+}
1480+
1481+TEST_F(UnityShowdesktopHandlerTest, TestFadeOutAlreadyFadedDoesntHideWindow)
1482+{
1483+ MockUnityShowdesktopHandlerWindow mMockWindow;
1484+
1485+ EXPECT_CALL (mMockWindow, GetInputRemover ()).WillOnce (Invoke (UnityShowdesktopHandlerTest::makeShared<compiz::WindowInputRemoverInterface, MockWindowInputRemoverTestFadeOut>));
1486+
1487+ UnityShowdesktopHandler mMockHandler (static_cast <UnityShowdesktopHandlerWindowInterface *> (&mMockWindow));
1488+
1489+ EXPECT_CALL (mMockWindow, IsHidden ());
1490+ EXPECT_CALL (mMockWindow, DoHide ());
1491+ EXPECT_CALL (mMockWindow, DoNotifyHidden ());
1492+
1493+ mMockHandler.FadeOut ();
1494+ mMockHandler.FadeOut ();
1495+
1496+ EXPECT_EQ (UnityShowdesktopHandler::animating_windows.size (), 1);
1497+}
1498+
1499+TEST_F(UnityShowdesktopHandlerTest, TestFadeInNonFadedDoesntShowWindow)
1500+{
1501+ MockUnityShowdesktopHandlerWindow mMockWindow;
1502+
1503+ EXPECT_CALL (mMockWindow, GetInputRemover ()).WillOnce (Invoke (UnityShowdesktopHandlerTest::makeShared<compiz::WindowInputRemoverInterface, MockWindowInputRemoverTestFadeOutAlready>));
1504+
1505+ UnityShowdesktopHandler mMockHandler (static_cast <UnityShowdesktopHandlerWindowInterface *> (&mMockWindow));
1506+
1507+ mMockHandler.FadeIn ();
1508+
1509+ EXPECT_EQ (UnityShowdesktopHandler::animating_windows.size (), 0);
1510+}
1511+
1512+class MockWindowInputRemoverTestFadeOutFadeIn :
1513+ public compiz::WindowInputRemoverInterface
1514+{
1515+ public:
1516+
1517+ MockWindowInputRemoverTestFadeOutFadeIn ()
1518+ {
1519+ ON_CALL (*this, saveInput ()).WillByDefault (Return (true));
1520+ ON_CALL (*this, removeInput ()).WillByDefault (Return (true));
1521+ ON_CALL (*this, restoreInput ()).WillByDefault (Return (true));
1522+
1523+ EXPECT_CALL (*this, saveInput ()).WillOnce (Return (true));
1524+ EXPECT_CALL (*this, removeInput ()).WillOnce (Return (true));
1525+ EXPECT_CALL (*this, restoreInput ()).WillOnce (Return (true));
1526+ }
1527+
1528+ MOCK_METHOD0 (saveInput, bool ());
1529+ MOCK_METHOD0 (removeInput, bool ());
1530+ MOCK_METHOD0 (restoreInput, bool ());
1531+};
1532+
1533+TEST_F(UnityShowdesktopHandlerTest, TestFadeOutHidesWindowFadeInShowsWindow)
1534+{
1535+ MockUnityShowdesktopHandlerWindow mMockWindow;
1536+
1537+ EXPECT_CALL (mMockWindow, GetInputRemover ()).WillOnce (Invoke (UnityShowdesktopHandlerTest::makeShared<compiz::WindowInputRemoverInterface, MockWindowInputRemoverTestFadeOutFadeIn>));
1538+
1539+ UnityShowdesktopHandler mMockHandler (static_cast <UnityShowdesktopHandlerWindowInterface *> (&mMockWindow));
1540+
1541+ EXPECT_CALL (mMockWindow, IsHidden ());
1542+ EXPECT_CALL (mMockWindow, DoHide ());
1543+ EXPECT_CALL (mMockWindow, DoNotifyHidden ());
1544+
1545+ mMockHandler.FadeOut ();
1546+
1547+ EXPECT_CALL (mMockWindow, DoShow ());
1548+ EXPECT_CALL (mMockWindow, DoNotifyShown ());
1549+
1550+ mMockHandler.FadeIn ();
1551+
1552+ EXPECT_EQ (UnityShowdesktopHandler::animating_windows.size (), 1);
1553+}
1554+
1555+TEST_F(UnityShowdesktopHandlerTest, TestAnimationPostPaintActions)
1556+{
1557+ MockUnityShowdesktopHandlerWindow mMockWindow;
1558+
1559+ EXPECT_CALL (mMockWindow, GetInputRemover ()).WillOnce (Invoke (UnityShowdesktopHandlerTest::makeShared<compiz::WindowInputRemoverInterface, MockWindowInputRemoverTestFadeOutFadeIn>));
1560+
1561+ UnityShowdesktopHandler mMockHandler (static_cast <UnityShowdesktopHandlerWindowInterface *> (&mMockWindow));
1562+
1563+ EXPECT_CALL (mMockWindow, IsHidden ());
1564+ EXPECT_CALL (mMockWindow, DoHide ());
1565+ EXPECT_CALL (mMockWindow, DoNotifyHidden ());
1566+
1567+ mMockHandler.FadeOut ();
1568+
1569+ EXPECT_CALL (mMockWindow, DoShow ());
1570+ EXPECT_CALL (mMockWindow, DoNotifyShown ());
1571+
1572+ for (unsigned int i = 0; i < UnityShowdesktopHandler::fade_time; i++)
1573+ {
1574+ UnityShowdesktopHandlerWindowInterface::PostPaintAction action = mMockHandler.Animate (1);
1575+
1576+ if (i == 300)
1577+ EXPECT_EQ (action, UnityShowdesktopHandlerWindowInterface::PostPaintAction::Wait);
1578+ else
1579+ EXPECT_EQ (action, UnityShowdesktopHandlerWindowInterface::PostPaintAction::Damage);
1580+ }
1581+
1582+ mMockHandler.FadeIn ();
1583+
1584+ for (unsigned int i = 0; i < UnityShowdesktopHandler::fade_time; i++)
1585+ {
1586+ UnityShowdesktopHandlerWindowInterface::PostPaintAction action = mMockHandler.Animate (1);
1587+
1588+ if (i == 300)
1589+ EXPECT_EQ (action, UnityShowdesktopHandlerWindowInterface::PostPaintAction::Remove);
1590+ else
1591+ EXPECT_EQ (action, UnityShowdesktopHandlerWindowInterface::PostPaintAction::Damage);
1592+ }
1593+
1594+ EXPECT_EQ (UnityShowdesktopHandler::animating_windows.size (), 1);
1595+}
1596+
1597+TEST_F(UnityShowdesktopHandlerTest, TestAnimationOpacity)
1598+{
1599+ MockUnityShowdesktopHandlerWindow mMockWindow;
1600+
1601+ EXPECT_CALL (mMockWindow, GetInputRemover ()).WillOnce (Invoke (UnityShowdesktopHandlerTest::makeShared<compiz::WindowInputRemoverInterface, MockWindowInputRemoverTestFadeOutFadeIn>));
1602+
1603+ UnityShowdesktopHandler mMockHandler (static_cast <UnityShowdesktopHandlerWindowInterface *> (&mMockWindow));
1604+
1605+ EXPECT_CALL (mMockWindow, IsHidden ());
1606+ EXPECT_CALL (mMockWindow, DoHide ());
1607+ EXPECT_CALL (mMockWindow, DoNotifyHidden ());
1608+
1609+ mMockHandler.FadeOut ();
1610+
1611+ EXPECT_CALL (mMockWindow, DoShow ());
1612+ EXPECT_CALL (mMockWindow, DoNotifyShown ());
1613+
1614+ /* The funny expectations here are to account for rounding errors that would
1615+ * otherwise make testing the code painful */
1616+
1617+ for (unsigned int i = 0; i < UnityShowdesktopHandler::fade_time; i++)
1618+ {
1619+ unsigned short opacity = std::numeric_limits <unsigned short>::max ();
1620+ mMockHandler.PaintOpacity (opacity);
1621+
1622+ mMockHandler.Animate (1);
1623+
1624+ if (i == 300)
1625+ EXPECT_EQ (opacity, std::numeric_limits <unsigned short>::max ());
1626+ else
1627+ {
1628+ float rem = opacity - std::numeric_limits <unsigned short>::max () * (1.0f - i / static_cast <float> (UnityShowdesktopHandler::fade_time));
1629+ EXPECT_TRUE (rem <= 1.0f && rem >= -1.0f);
1630+ }
1631+ }
1632+
1633+ mMockHandler.FadeIn ();
1634+
1635+ for (unsigned int i = 0; i < UnityShowdesktopHandler::fade_time; i++)
1636+ {
1637+ unsigned short opacity = std::numeric_limits <unsigned short>::max ();
1638+ mMockHandler.PaintOpacity (opacity);
1639+
1640+ mMockHandler.Animate (1);
1641+
1642+ if (i == 300)
1643+ EXPECT_EQ (opacity, std::numeric_limits <unsigned short>::max ());
1644+ else
1645+ {
1646+ float rem = opacity - std::numeric_limits <unsigned short>::max () * (i / static_cast <float> (UnityShowdesktopHandler::fade_time));
1647+ EXPECT_TRUE (rem <= 1.0f && rem >= -1.0f);
1648+ }
1649+ }
1650+
1651+ EXPECT_EQ (UnityShowdesktopHandler::animating_windows.size (), 1);
1652+}
1653+
1654+TEST_F(UnityShowdesktopHandlerTest, TestAnimationPaintMasks)
1655+{
1656+ MockUnityShowdesktopHandlerWindow mMockWindow;
1657+
1658+ EXPECT_CALL (mMockWindow, GetInputRemover ()).WillOnce (Invoke (UnityShowdesktopHandlerTest::makeShared<compiz::WindowInputRemoverInterface, MockWindowInputRemoverTestFadeOutFadeIn>));
1659+
1660+ UnityShowdesktopHandler mMockHandler (static_cast <UnityShowdesktopHandlerWindowInterface *> (&mMockWindow));
1661+
1662+ EXPECT_CALL (mMockWindow, IsHidden ());
1663+ EXPECT_CALL (mMockWindow, DoHide ());
1664+ EXPECT_CALL (mMockWindow, DoNotifyHidden ());
1665+
1666+ mMockHandler.FadeOut ();
1667+
1668+ EXPECT_CALL (mMockWindow, DoShow ());
1669+ EXPECT_CALL (mMockWindow, DoNotifyShown ());
1670+ EXPECT_CALL (mMockWindow, GetNoCoreInstanceMask ());
1671+
1672+ mMockHandler.Animate (UnityShowdesktopHandler::fade_time);
1673+
1674+ EXPECT_EQ (mMockHandler.GetPaintMask (), 1);
1675+
1676+ mMockHandler.FadeIn ();
1677+
1678+ mMockHandler.Animate (UnityShowdesktopHandler::fade_time);
1679+
1680+ EXPECT_EQ (mMockHandler.GetPaintMask (), 0);
1681+
1682+ EXPECT_EQ (UnityShowdesktopHandler::animating_windows.size (), 1);
1683+}
1684+
1685+class MockWindowInputRemoverTestFadeOutFadeInWithShapeEvent :
1686+ public compiz::WindowInputRemoverInterface
1687+{
1688+ public:
1689+
1690+ MockWindowInputRemoverTestFadeOutFadeInWithShapeEvent ()
1691+ {
1692+ ON_CALL (*this, saveInput ()).WillByDefault (Return (true));
1693+ ON_CALL (*this, removeInput ()).WillByDefault (Return (true));
1694+ ON_CALL (*this, restoreInput ()).WillByDefault (Return (true));
1695+
1696+ InSequence s;
1697+
1698+ EXPECT_CALL (*this, saveInput ()).WillOnce (Return (true));
1699+ EXPECT_CALL (*this, removeInput ()).WillOnce (Return (true));
1700+ EXPECT_CALL (*this, saveInput ()).WillOnce (Return (true));
1701+ EXPECT_CALL (*this, removeInput ()).WillOnce (Return (true));
1702+ EXPECT_CALL (*this, restoreInput ()).WillOnce (Return (true));
1703+ }
1704+
1705+ MOCK_METHOD0 (saveInput, bool ());
1706+ MOCK_METHOD0 (removeInput, bool ());
1707+ MOCK_METHOD0 (restoreInput, bool ());
1708+};
1709+
1710+TEST_F(UnityShowdesktopHandlerTest, TestShapeEvent)
1711+{
1712+ MockUnityShowdesktopHandlerWindow mMockWindow;
1713+
1714+ EXPECT_CALL (mMockWindow, GetInputRemover ()).WillOnce (Invoke (UnityShowdesktopHandlerTest::makeShared<compiz::WindowInputRemoverInterface, MockWindowInputRemoverTestFadeOutFadeInWithShapeEvent>));
1715+
1716+ UnityShowdesktopHandler mMockHandler (static_cast <UnityShowdesktopHandlerWindowInterface *> (&mMockWindow));
1717+
1718+ EXPECT_CALL (mMockWindow, IsHidden ());
1719+ EXPECT_CALL (mMockWindow, DoHide ());
1720+ EXPECT_CALL (mMockWindow, DoNotifyHidden ());
1721+
1722+ mMockHandler.FadeOut ();
1723+
1724+ EXPECT_CALL (mMockWindow, DoShow ());
1725+ EXPECT_CALL (mMockWindow, DoNotifyShown ());
1726+
1727+ mMockHandler.HandleShapeEvent ();
1728+
1729+ mMockHandler.FadeIn ();
1730+
1731+ EXPECT_EQ (UnityShowdesktopHandler::animating_windows.size (), 1);
1732+}