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

Proposed by Sam Spilsbury
Status: Merged
Approved by: Andrea Cimitan
Approved revision: no longer in the source branch.
Merged at revision: 2245
Proposed branch: lp:~smspillaz/unity/unity.fix_877778
Merge into: lp:unity
Diff against target: 1721 lines (+1167/-284)
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 (+180/-228)
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) Approve
Gord Allott Pending
Review via email: mp+101065@code.launchpad.net

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

Commit message

Fixes LP #877778 - Introduces tests for UnityShowdesktopHandler

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.
Revision history for this message
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
Revision history for this message
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_/

Revision history for this message
Omer Akram (om26er) wrote : Posted in a previous version of this proposal

has conflicts.

Revision history for this message
Unity Merger (unity-merger) wrote : Posted in a previous version of this proposal

No commit message specified.

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

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
Revision history for this message
Tim Penhey (thumper) wrote : Posted in a previous version of this proposal

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

s/should/should not/

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

Style pedantry fixed.

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

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

As far as I can tell the tests are not calling virtual methods directly (in fact, they can't doing so would raise a compile error ...)

The ON_CALL and EXPECT_CALL macros however do need to be on the virtual methods, because that's what they are mocking.

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

When testing, entering show desktop, then out again (using Ctrl-Alt-D twice), the title bars of non-maximised windows aren't accepting the mouse, and clicks through. Focusing the window using alt left mouse to move it a bit fixed it.

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

This is fine now. We can fix the style later :)

review: Approve
Revision history for this message
Unity Merger (unity-merger) wrote :

No commit message specified.

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-06 08:44:20 +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+ShowdesktopHandlerWindowInterface::~ShowdesktopHandlerWindowInterface()
33+{
34+}
35+
36+/* 300 ms */
37+const unsigned int ShowdesktopHandler::fade_time = 300;
38+std::list <ShowdesktopHandlerWindowInterface *> ShowdesktopHandler::animating_windows (0);
39+
40+bool ShowdesktopHandler::ShouldHide (ShowdesktopHandlerWindowInterface *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 ShowdesktopHandler::inhibiting_xid = 0;
65+
66+void
67+ShowdesktopHandler::InhibitLeaveShowdesktopMode (guint32 xid)
68+{
69+ if (!inhibiting_xid)
70+ inhibiting_xid = xid;
71+}
72+
73+void
74+ShowdesktopHandler::AllowLeaveShowdesktopMode (guint32 xid)
75+{
76+ if (inhibiting_xid == xid)
77+ inhibiting_xid = 0;
78+}
79+
80+guint32
81+ShowdesktopHandler::InhibitingXid()
82+{
83+ return inhibiting_xid;
84+}
85+
86+ShowdesktopHandler::ShowdesktopHandler (ShowdesktopHandlerWindowInterface *wi) :
87+ showdesktop_handler_window_interface_ (wi),
88+ remover_ (wi->InputRemover()),
89+ state_ (StateVisible),
90+ progress_ (0.0f)
91+{
92+}
93+
94+ShowdesktopHandler::~ShowdesktopHandler()
95+{
96+}
97+
98+void ShowdesktopHandler::FadeOut()
99+{
100+ if (state_ != StateVisible && state_ != StateFadeIn)
101+ return;
102+
103+ state_ = ShowdesktopHandler::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 ShowdesktopHandler::FadeIn()
124+{
125+ if (state_ != StateInvisible && state_ != StateFadeOut)
126+ return;
127+
128+ state_ = ShowdesktopHandler::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+ShowdesktopHandlerWindowInterface::PostPaintAction ShowdesktopHandler::Animate (unsigned int ms)
144+{
145+ float inc = ms / static_cast <float> (fade_time);
146+
147+ if (state_ == ShowdesktopHandler::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 ShowdesktopHandlerWindowInterface::PostPaintAction::Remove;
167+ else if (state_ == StateInvisible)
168+ return ShowdesktopHandlerWindowInterface::PostPaintAction::Wait;
169+
170+ return ShowdesktopHandlerWindowInterface::PostPaintAction::Damage;
171+}
172+
173+void ShowdesktopHandler::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 ShowdesktopHandler::GetPaintMask()
182+{
183+ return (progress_ == 1.0f) ? showdesktop_handler_window_interface_->NoCoreInstanceMask() : 0;
184+}
185+
186+void ShowdesktopHandler::HandleShapeEvent()
187+{
188+ /* Ignore sent events from the InputRemover */
189+ if (remover_)
190+ {
191+ remover_->save();
192+ remover_->remove();
193+ }
194+}
195+
196+void ShowdesktopHandler::WindowFocusChangeNotify()
197+{
198+ if (showdesktop_handler_window_interface_->Minimized())
199+ {
200+ for (ShowdesktopHandlerWindowInterface *w : animating_windows)
201+ w->DisableFocus();
202+
203+ showdesktop_handler_window_interface_->MoveFocusAway();
204+
205+ for (ShowdesktopHandlerWindowInterface *w : animating_windows)
206+ w->EnableFocus();
207+ }
208+}
209+
210+void ShowdesktopHandler::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-06 08:44:20 +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 ShowdesktopHandlerWindowInterface
260+{
261+ public:
262+
263+ enum class PostPaintAction {
264+ Wait = 0,
265+ Damage = 1,
266+ Remove = 2
267+ };
268+
269+ virtual ~ShowdesktopHandlerWindowInterface ();
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+ private:
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 ShowdesktopHandler
336+{
337+ public:
338+
339+ ShowdesktopHandler (ShowdesktopHandlerWindowInterface *uwi);
340+ ~ShowdesktopHandler ();
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+ ShowdesktopHandlerWindowInterface::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+ ShowdesktopHandler::State GetState ();
361+
362+ static const unsigned int fade_time;
363+ static std::list <ShowdesktopHandlerWindowInterface *> animating_windows;
364+ static bool ShouldHide (ShowdesktopHandlerWindowInterface *);
365+ static void InhibitLeaveShowdesktopMode (guint32 xid);
366+ static void AllowLeaveShowdesktopMode (guint32 xid);
367+ static guint32 InhibitingXid ();
368+
369+private:
370+
371+ ShowdesktopHandlerWindowInterface *showdesktop_handler_window_interface_;
372+ compiz::WindowInputRemoverInterface::Ptr remover_;
373+ ShowdesktopHandler::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-06 08:44:20 +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-06 08:44:20 +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-04-05 23:28:43 +0000
486+++ plugins/unityshell/src/unityshell.cpp 2012-04-06 08:44:20 +0000
487@@ -963,7 +963,9 @@
488 {
489 for (CompWindow *w : screen->windows ())
490 {
491- if (UnityShowdesktopHandler::shouldHide (w))
492+ UnityWindow *uw = UnityWindow::get (w);
493+
494+ if (ShowdesktopHandler::ShouldHide (static_cast <ShowdesktopHandlerWindowInterface *> (uw)))
495 {
496 UnityWindow::get (w)->enterShowDesktop ();
497 // the animation plugin does strange things here ...
498@@ -1000,16 +1002,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 (!ShowdesktopHandler::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@@ -1019,12 +1021,12 @@
521 }
522 else
523 {
524- CompWindow *cw = screen->findWindow (UnityShowdesktopHandler::inhibitingXid ());
525+ CompWindow *cw = screen->findWindow (ShowdesktopHandler::InhibitingXid ());
526 if (cw)
527 {
528 if (cw->inShowDesktopMode ())
529 {
530- UnityWindow::get (cw)->leaveShowDesktop ();
531+ UnityWindow::get (cw)->leaveShowDesktop ();
532 }
533 }
534 }
535@@ -1033,227 +1035,161 @@
536 void UnityWindow::enterShowDesktop ()
537 {
538 if (!mShowdesktopHandler)
539- mShowdesktopHandler = new UnityShowdesktopHandler (window);
540+ mShowdesktopHandler = new ShowdesktopHandler (static_cast <ShowdesktopHandlerWindowInterface *> (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+ ShowdesktopHandler::InhibitLeaveShowdesktopMode (window->id ());
563 window->activate ();
564- UnityShowdesktopHandler::allowLeaveShowdesktopMode (window->id ());
565-}
566-
567-bool UnityWindow::handleAnimations (unsigned int ms)
568-{
569+ ShowdesktopHandler::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+ShowdesktopHandlerWindowInterface::PostPaintAction UnityWindow::DoHandleAnimations (unsigned int ms)
662+{
663+ ShowdesktopHandlerWindowInterface::PostPaintAction action = ShowdesktopHandlerWindowInterface::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+ window->updateFrameRegion ();
842+}
843+
844+compiz::WindowInputRemoverInterface::Ptr
845+UnityWindow::GetInputRemover ()
846+{
847+ return compiz::WindowInputRemoverInterface::Ptr (new compiz::WindowInputRemover (screen->dpy (), window->id ()));
848+}
849+
850+unsigned int
851+UnityWindow::GetNoCoreInstanceMask ()
852+{
853+ return PAINT_WINDOW_NO_CORE_INSTANCE_MASK;
854+}
855+
856+void UnityWindow::handleEvent (XEvent *event)
857+{
858+ if (screen->XShape () &&
859+ event->type == screen->shapeEvent () + ShapeNotify &&
860 !event->xany.send_event)
861 {
862- if (mRemover)
863- {
864- mRemover->save ();
865- mRemover->remove ();
866- }
867- }
868-}
869-
870-void UnityShowdesktopHandler::windowNotify (CompWindowNotify n)
871-{
872- if (n == CompWindowNotifyFocusChange && mWindow->minimized ())
873- {
874- for (CompWindow *w : animating_windows)
875- w->focusSetEnabled (UnityWindow::get (w), false);
876-
877- mWindow->moveInputFocusToOtherWindow ();
878-
879- for (CompWindow *w : animating_windows)
880- w->focusSetEnabled (UnityWindow::get (w), true);
881- }
882-}
883-
884-void UnityShowdesktopHandler::updateFrameRegion (CompRegion &r)
885-{
886- unsigned int oldUpdateFrameRegionIndex;
887- r = CompRegion ();
888-
889- /* Ensure no other plugins can touch this frame region */
890- oldUpdateFrameRegionIndex = mWindow->updateFrameRegionGetCurrentIndex ();
891- mWindow->updateFrameRegionSetCurrentIndex (MAXSHORT);
892- mWindow->updateFrameRegion (r);
893- mWindow->updateFrameRegionSetCurrentIndex (oldUpdateFrameRegionIndex);
894+ if (mShowdesktopHandler)
895+ mShowdesktopHandler->HandleShapeEvent ();
896+ }
897 }
898
899 /* called whenever we need to repaint parts of the screen */
900@@ -1335,16 +1271,10 @@
901
902 void UnityScreen::preparePaint(int ms)
903 {
904- CompWindowList remove_windows;
905-
906 cScreen->preparePaint(ms);
907
908- for (CompWindow *w : UnityShowdesktopHandler::animating_windows)
909- if (UnityWindow::get (w)->handleAnimations (ms))
910- remove_windows.push_back(w);
911-
912- for (CompWindow *w : remove_windows)
913- UnityShowdesktopHandler::animating_windows.remove (w);
914+ for (ShowdesktopHandlerWindowInterface *wi : ShowdesktopHandler::animating_windows)
915+ wi->HandleAnimations (ms);
916
917 if (damaged)
918 {
919@@ -1354,6 +1284,28 @@
920
921 }
922
923+void UnityScreen::donePaint()
924+{
925+ std::list <ShowdesktopHandlerWindowInterface *> remove_windows;
926+
927+ for (ShowdesktopHandlerWindowInterface *wi : ShowdesktopHandler::animating_windows)
928+ {
929+ ShowdesktopHandlerWindowInterface::PostPaintAction action = wi->HandleAnimations (0);
930+ if (action == ShowdesktopHandlerWindowInterface::PostPaintAction::Remove)
931+ remove_windows.push_back(wi);
932+ else if (action == ShowdesktopHandlerWindowInterface::PostPaintAction::Damage)
933+ wi->AddDamage ();
934+ }
935+
936+ for (ShowdesktopHandlerWindowInterface *wi : remove_windows)
937+ {
938+ wi->DeleteHandler ();
939+ ShowdesktopHandler::animating_windows.remove (wi);
940+ }
941+
942+ cScreen->donePaint ();
943+}
944+
945 /* Grab changed nux regions and add damage rects for them */
946 void UnityScreen::damageNuxRegions()
947 {
948@@ -1489,7 +1441,7 @@
949 break;
950 }
951 case MapRequest:
952- UnityShowdesktopHandler::inhibitLeaveShowdesktopMode (event->xmaprequest.window);
953+ ShowdesktopHandler::InhibitLeaveShowdesktopMode (event->xmaprequest.window);
954 break;
955 default:
956 if (screen->shapeEvent () + ShapeNotify == event->type)
957@@ -1501,8 +1453,7 @@
958 {
959 UnityWindow *uw = UnityWindow::get (w);
960
961- if (uw->mShowdesktopHandler)
962- uw->mShowdesktopHandler->handleEvent(event);
963+ uw->handleEvent(event);
964 }
965 }
966 break;
967@@ -1523,7 +1474,7 @@
968 }
969 break;
970 case MapRequest:
971- UnityShowdesktopHandler::allowLeaveShowdesktopMode (event->xmaprequest.window);
972+ ShowdesktopHandler::AllowLeaveShowdesktopMode (event->xmaprequest.window);
973 break;
974 }
975
976@@ -2235,8 +2186,8 @@
977 }
978 else if (mShowdesktopHandler)
979 {
980- mShowdesktopHandler->paintAttrib (wAttrib);
981- mask |= mShowdesktopHandler->getPaintMask ();
982+ mShowdesktopHandler->PaintOpacity (wAttrib.opacity);
983+ mask |= mShowdesktopHandler->GetPaintMask ();
984 }
985
986 std::vector<Window> const& tray_xids = uScreen->panel_controller_->GetTrayXids();
987@@ -2460,7 +2411,8 @@
988 }
989 else if (mShowdesktopHandler)
990 {
991- mShowdesktopHandler->windowNotify (n);
992+ if (n == CompWindowNotifyFocusChange)
993+ mShowdesktopHandler->WindowFocusChangeNotify ();
994 }
995
996 // We do this after the notify to ensure input focus has actually been moved.
997@@ -2499,7 +2451,7 @@
998 if (mMinimizeHandler)
999 mMinimizeHandler->updateFrameRegion (region);
1000 else if (mShowdesktopHandler)
1001- mShowdesktopHandler->updateFrameRegion (region);
1002+ mShowdesktopHandler->UpdateFrameRegion (region);
1003 else
1004 window->updateFrameRegion (region);
1005 }
1006@@ -3039,7 +2991,7 @@
1007 window->minimize ();
1008 }
1009
1010- UnityShowdesktopHandler::animating_windows.remove (window);
1011+ ShowdesktopHandler::animating_windows.remove (static_cast <ShowdesktopHandlerWindowInterface *> (this));
1012
1013 if (mShowdesktopHandler)
1014 delete mShowdesktopHandler;
1015
1016=== modified file 'plugins/unityshell/src/unityshell.h'
1017--- plugins/unityshell/src/unityshell.h 2012-04-05 16:10:46 +0000
1018+++ plugins/unityshell/src/unityshell.h 2012-04-06 08:44:20 +0000
1019@@ -50,6 +50,7 @@
1020 #include "SwitcherController.h"
1021 #include "UBusWrapper.h"
1022 #include "UnityshellPrivate.h"
1023+#include "UnityShowdesktopHandler.h"
1024 #ifndef USE_GLES
1025 #include "ScreenEffectFramebufferObject.h"
1026 #endif
1027@@ -64,51 +65,6 @@
1028 namespace unity
1029 {
1030
1031-class UnityShowdesktopHandler
1032-{
1033- public:
1034-
1035- UnityShowdesktopHandler (CompWindow *w);
1036- ~UnityShowdesktopHandler ();
1037-
1038- typedef enum {
1039- Visible = 0,
1040- FadeOut = 1,
1041- FadeIn = 2,
1042- Invisible = 3
1043- } State;
1044-
1045-public:
1046-
1047- void fadeOut ();
1048- void fadeIn ();
1049- bool animate (unsigned int ms);
1050- void paintAttrib (GLWindowPaintAttrib &attrib);
1051- unsigned int getPaintMask ();
1052- void handleEvent (XEvent *);
1053- void windowNotify (CompWindowNotify n);
1054- void updateFrameRegion (CompRegion &r);
1055-
1056- UnityShowdesktopHandler::State state ();
1057-
1058- static const unsigned int fade_time;
1059- static CompWindowList animating_windows;
1060- static bool shouldHide (CompWindow *);
1061- static void inhibitLeaveShowdesktopMode (guint32 xid);
1062- static void allowLeaveShowdesktopMode (guint32 xid);
1063- static guint32 inhibitingXid ();
1064-
1065-private:
1066-
1067- CompWindow *mWindow;
1068- compiz::WindowInputRemover *mRemover;
1069- UnityShowdesktopHandler::State mState;
1070- float mProgress;
1071- bool mWasHidden;
1072- static guint32 mInhibitingXid;
1073-};
1074-
1075-
1076 /* base screen class */
1077 class UnityScreen :
1078 public unity::debug::Introspectable,
1079@@ -145,6 +101,7 @@
1080
1081 void preparePaint (int ms);
1082 void paintFboForOutput (CompOutput *output);
1083+ void donePaint ();
1084
1085 void RaiseInputWindows();
1086
1087@@ -358,6 +315,7 @@
1088 class UnityWindow :
1089 public WindowInterface,
1090 public GLWindowInterface,
1091+ public ShowdesktopHandlerWindowInterface,
1092 public BaseSwitchWindow,
1093 public PluginClassHandler <UnityWindow, CompWindow>
1094 {
1095@@ -414,18 +372,50 @@
1096
1097 void enterShowDesktop ();
1098 void leaveShowDesktop ();
1099- bool handleAnimations (unsigned int ms);
1100+ bool HandleAnimations (unsigned int ms);
1101+
1102+ void handleEvent (XEvent *event);
1103
1104 typedef compiz::CompizMinimizedWindowHandler<UnityScreen, UnityWindow>
1105 UnityMinimizedHandler;
1106 std::unique_ptr <UnityMinimizedHandler> mMinimizeHandler;
1107
1108- UnityShowdesktopHandler *mShowdesktopHandler;
1109+ ShowdesktopHandler *mShowdesktopHandler;
1110
1111 private:
1112
1113 guint focusdesktop_handle_;
1114 static gboolean FocusDesktopTimeout(gpointer data);
1115+
1116+ void DoEnableFocus ();
1117+ void DoDisableFocus ();
1118+
1119+ bool IsOverrideRedirect ();
1120+ bool IsManaged ();
1121+ bool IsGrabbed ();
1122+ bool IsDesktopOrDock ();
1123+ bool IsSkipTaskbarOrPager ();
1124+ bool IsHidden ();
1125+ bool IsInShowdesktopMode ();
1126+ bool IsShaded ();
1127+ bool IsMinimized ();
1128+ void DoOverrideFrameRegion (CompRegion &r);
1129+
1130+ void DoHide ();
1131+ void DoNotifyHidden ();
1132+ void DoShow ();
1133+ void DoNotifyShown ();
1134+
1135+ void DoAddDamage ();
1136+ ShowdesktopHandlerWindowInterface::PostPaintAction DoHandleAnimations (unsigned int ms);
1137+
1138+ void DoMoveFocusAway ();
1139+
1140+ void DoDeleteHandler ();
1141+
1142+ unsigned int GetNoCoreInstanceMask ();
1143+
1144+ compiz::WindowInputRemoverInterface::Ptr GetInputRemover ();
1145 };
1146
1147
1148
1149=== modified file 'tests/CMakeLists.txt'
1150--- tests/CMakeLists.txt 2012-04-06 02:11:51 +0000
1151+++ tests/CMakeLists.txt 2012-04-06 08:44:20 +0000
1152@@ -33,7 +33,8 @@
1153 )
1154 add_definitions (${CFLAGS})
1155
1156-set (LIBS ${TEST_UNIT_DEPS_LIBRARIES} "-lunity-core-${UNITY_API_VERSION} -lm")
1157+set (LIBS ${TEST_UNIT_DEPS_LIBRARIES} "-lunity-core-${UNITY_API_VERSION} -lcompiz_core -lm")
1158+link_libraries (${LIBS})
1159
1160 set (LIB_PATHS ${TEST_UNIT_DEPS_LIBRARY_DIRS})
1161 link_directories (${CMAKE_BINARY_DIR}/UnityCore ${LIB_PATHS})
1162@@ -141,6 +142,7 @@
1163 test_main_xless.cpp
1164 test_grabhandle.cpp
1165 test_unityshell_private.cpp
1166+ test_showdesktop_handler.cpp
1167 ${UNITY_SRC}/AbstractLauncherIcon.cpp
1168 ${UNITY_SRC}/AbstractShortcutHint.h
1169 ${UNITY_SRC}/Animator.cpp
1170@@ -161,6 +163,7 @@
1171 ${UNITY_SRC}/Timer.cpp
1172 ${UNITY_SRC}/UnityshellPrivate.cpp
1173 ${UNITY_SRC}/WindowManager.cpp
1174+ ${UNITY_SRC}/UnityShowdesktopHandler.cpp
1175 ${CMAKE_SOURCE_DIR}/plugins/unity-mt-grab-handles/src/unity-mt-grab-handle.cpp
1176 ${CMAKE_SOURCE_DIR}/plugins/unity-mt-grab-handles/src/unity-mt-grab-handle-group.cpp
1177 ${CMAKE_SOURCE_DIR}/plugins/unity-mt-grab-handles/src/unity-mt-grab-handle-impl-factory.cpp
1178
1179=== added file 'tests/test_showdesktop_handler.cpp'
1180--- tests/test_showdesktop_handler.cpp 1970-01-01 00:00:00 +0000
1181+++ tests/test_showdesktop_handler.cpp 2012-04-06 08:44:20 +0000
1182@@ -0,0 +1,539 @@
1183+#include <list>
1184+#include <algorithm>
1185+#include <gtest/gtest.h>
1186+#include <gmock/gmock.h>
1187+#include <UnityShowdesktopHandler.h>
1188+
1189+using namespace unity;
1190+using ::testing::_;
1191+using ::testing::Return;
1192+using ::testing::Invoke;
1193+using ::testing::InSequence;
1194+
1195+compiz::WindowInputRemoverInterface::~WindowInputRemoverInterface () {}
1196+
1197+class MockWindowInputRemover :
1198+ public compiz::WindowInputRemoverInterface
1199+{
1200+ public:
1201+
1202+ MockWindowInputRemover ()
1203+ {
1204+ ON_CALL (*this, saveInput ()).WillByDefault (Return (true));
1205+ ON_CALL (*this, removeInput ()).WillByDefault (Return (true));
1206+ ON_CALL (*this, restoreInput ()).WillByDefault (Return (true));
1207+ }
1208+
1209+ MOCK_METHOD0 (saveInput, bool ());
1210+ MOCK_METHOD0 (removeInput, bool ());
1211+ MOCK_METHOD0 (restoreInput, bool ());
1212+};
1213+
1214+class UnityShowdesktopHandlerTest :
1215+ public ::testing::Test
1216+{
1217+public:
1218+
1219+ ~UnityShowdesktopHandlerTest ()
1220+ {
1221+ ShowdesktopHandler::animating_windows.clear ();
1222+ }
1223+
1224+ template <class T, class U> static typename T::Ptr makeShared () { return typename T::Ptr (new U); }
1225+
1226+};
1227+
1228+
1229+class MockUnityShowdesktopHandlerWindow :
1230+ public ShowdesktopHandlerWindowInterface
1231+{
1232+ public:
1233+
1234+ MockUnityShowdesktopHandlerWindow ()
1235+ {
1236+ ON_CALL (*this, IsOverrideRedirect ()).WillByDefault (Return (false));
1237+ ON_CALL (*this, IsManaged ()).WillByDefault (Return (true));
1238+ ON_CALL (*this, IsGrabbed ()).WillByDefault (Return (false));
1239+ ON_CALL (*this, IsDesktopOrDock ()).WillByDefault (Return (false));
1240+ ON_CALL (*this, IsSkipTaskbarOrPager ()).WillByDefault (Return (false));
1241+ ON_CALL (*this, IsHidden ()).WillByDefault (Return (false));
1242+ ON_CALL (*this, IsInShowdesktopMode ()).WillByDefault (Return (false));
1243+ ON_CALL (*this, IsShaded ()).WillByDefault (Return (false));
1244+ ON_CALL (*this, IsMinimized ()).WillByDefault (Return (false));
1245+
1246+ ON_CALL (*this, DoHandleAnimations (_)).WillByDefault (Return (ShowdesktopHandlerWindowInterface::PostPaintAction::Damage));
1247+ ON_CALL (*this, GetNoCoreInstanceMask ()).WillByDefault (Return (1));
1248+ ON_CALL (*this, GetInputRemover ()).WillByDefault (Invoke (UnityShowdesktopHandlerTest::makeShared<compiz::WindowInputRemoverInterface, MockWindowInputRemover>));
1249+ }
1250+
1251+ MOCK_METHOD0 (DoEnableFocus, void ());
1252+ MOCK_METHOD0 (DoDisableFocus, void ());
1253+ MOCK_METHOD0 (IsOverrideRedirect, bool ());
1254+ MOCK_METHOD0 (IsManaged, bool ());
1255+ MOCK_METHOD0 (IsGrabbed, bool ());
1256+ MOCK_METHOD0 (IsDesktopOrDock, bool ());
1257+ MOCK_METHOD0 (IsSkipTaskbarOrPager, bool ());
1258+ MOCK_METHOD0 (IsHidden, bool ());
1259+ MOCK_METHOD0 (IsInShowdesktopMode, bool ());
1260+ MOCK_METHOD0 (IsShaded, bool ());
1261+ MOCK_METHOD0 (IsMinimized, bool ());
1262+ MOCK_METHOD1 (DoOverrideFrameRegion, void (CompRegion &));
1263+ MOCK_METHOD0 (DoHide, void ());
1264+ MOCK_METHOD0 (DoNotifyHidden, void ());
1265+ MOCK_METHOD0 (DoShow, void ());
1266+ MOCK_METHOD0 (DoNotifyShown, void ());
1267+ MOCK_METHOD0 (DoMoveFocusAway, void ());
1268+ MOCK_METHOD1 (DoHandleAnimations, ShowdesktopHandlerWindowInterface::PostPaintAction (unsigned int));
1269+ MOCK_METHOD0 (DoAddDamage, void ());
1270+ MOCK_METHOD0 (GetNoCoreInstanceMask, unsigned int ());
1271+ MOCK_METHOD0 (GetInputRemover, compiz::WindowInputRemoverInterface::Ptr ());
1272+ MOCK_METHOD0 (DoDeleteHandler, void ());
1273+};
1274+
1275+TEST_F(UnityShowdesktopHandlerTest, TestNoORWindowsSD)
1276+{
1277+ MockUnityShowdesktopHandlerWindow mMockWindow;
1278+
1279+ EXPECT_CALL (mMockWindow, GetInputRemover ());
1280+
1281+ ShowdesktopHandler mMockHandler (static_cast <ShowdesktopHandlerWindowInterface *> (&mMockWindow));
1282+
1283+ EXPECT_CALL (mMockWindow, IsOverrideRedirect ()).WillOnce (Return (true));
1284+ EXPECT_FALSE (ShowdesktopHandler::ShouldHide (&mMockWindow));
1285+}
1286+
1287+TEST_F(UnityShowdesktopHandlerTest, TestNoUnmanagedWindowsSD)
1288+{
1289+ MockUnityShowdesktopHandlerWindow mMockWindow;
1290+
1291+ EXPECT_CALL (mMockWindow, GetInputRemover ());
1292+
1293+ ShowdesktopHandler mMockHandler (static_cast <ShowdesktopHandlerWindowInterface *> (&mMockWindow));
1294+
1295+ EXPECT_CALL (mMockWindow, IsOverrideRedirect ());
1296+ EXPECT_CALL (mMockWindow, IsManaged ()).WillOnce (Return (false));
1297+ EXPECT_FALSE (ShowdesktopHandler::ShouldHide (&mMockWindow));
1298+}
1299+
1300+TEST_F(UnityShowdesktopHandlerTest, TestNoGrabbedWindowsSD)
1301+{
1302+ MockUnityShowdesktopHandlerWindow mMockWindow;
1303+
1304+ EXPECT_CALL (mMockWindow, GetInputRemover ());
1305+
1306+ ShowdesktopHandler mMockHandler (static_cast <ShowdesktopHandlerWindowInterface *> (&mMockWindow));
1307+
1308+ EXPECT_CALL (mMockWindow, IsOverrideRedirect ());
1309+ EXPECT_CALL (mMockWindow, IsManaged ());
1310+ EXPECT_CALL (mMockWindow, IsGrabbed ()).WillOnce (Return (true));
1311+ EXPECT_FALSE (ShowdesktopHandler::ShouldHide (&mMockWindow));
1312+}
1313+
1314+TEST_F(UnityShowdesktopHandlerTest, TestNoDesktopOrDockWindowsSD)
1315+{
1316+ MockUnityShowdesktopHandlerWindow mMockWindow;
1317+
1318+ EXPECT_CALL (mMockWindow, GetInputRemover ());
1319+
1320+ ShowdesktopHandler mMockHandler (static_cast <ShowdesktopHandlerWindowInterface *> (&mMockWindow));
1321+
1322+ EXPECT_CALL (mMockWindow, IsOverrideRedirect ());
1323+ EXPECT_CALL (mMockWindow, IsManaged ());
1324+ EXPECT_CALL (mMockWindow, IsGrabbed ());
1325+ EXPECT_CALL (mMockWindow, IsDesktopOrDock ()).WillOnce (Return (true));
1326+ EXPECT_FALSE (ShowdesktopHandler::ShouldHide (&mMockWindow));
1327+}
1328+
1329+TEST_F(UnityShowdesktopHandlerTest, TestNoSkipTaskbarOrPagerWindowsSD)
1330+{
1331+ MockUnityShowdesktopHandlerWindow mMockWindow;
1332+
1333+ EXPECT_CALL (mMockWindow, GetInputRemover ());
1334+
1335+ ShowdesktopHandler mMockHandler (static_cast <ShowdesktopHandlerWindowInterface *> (&mMockWindow));
1336+
1337+ EXPECT_CALL (mMockWindow, IsOverrideRedirect ());
1338+ EXPECT_CALL (mMockWindow, IsManaged ());
1339+ EXPECT_CALL (mMockWindow, IsGrabbed ());
1340+ EXPECT_CALL (mMockWindow, IsDesktopOrDock ());
1341+ EXPECT_CALL (mMockWindow, IsSkipTaskbarOrPager ()).WillOnce (Return (true));
1342+ EXPECT_FALSE (ShowdesktopHandler::ShouldHide (&mMockWindow));
1343+}
1344+
1345+TEST_F(UnityShowdesktopHandlerTest, TestHiddenNotSDAndShadedWindowsNoSD)
1346+{
1347+ MockUnityShowdesktopHandlerWindow mMockWindow;
1348+
1349+ EXPECT_CALL (mMockWindow, GetInputRemover ());
1350+
1351+ ShowdesktopHandler mMockHandler (static_cast <ShowdesktopHandlerWindowInterface *> (&mMockWindow));
1352+
1353+ EXPECT_CALL (mMockWindow, IsOverrideRedirect ());
1354+ EXPECT_CALL (mMockWindow, IsManaged ());
1355+ EXPECT_CALL (mMockWindow, IsGrabbed ());
1356+ EXPECT_CALL (mMockWindow, IsDesktopOrDock ());
1357+ EXPECT_CALL (mMockWindow, IsSkipTaskbarOrPager ());
1358+ EXPECT_CALL (mMockWindow, IsHidden ()).WillOnce (Return (true));
1359+ EXPECT_CALL (mMockWindow, IsInShowdesktopMode ()).WillOnce (Return (false));
1360+ EXPECT_CALL (mMockWindow, IsShaded ()).WillOnce (Return (true));
1361+ EXPECT_FALSE (ShowdesktopHandler::ShouldHide (&mMockWindow));
1362+}
1363+
1364+TEST_F(UnityShowdesktopHandlerTest, TestHiddenSDAndShadedWindowsNoSD)
1365+{
1366+ MockUnityShowdesktopHandlerWindow mMockWindow;
1367+
1368+ EXPECT_CALL (mMockWindow, GetInputRemover ());
1369+
1370+ ShowdesktopHandler mMockHandler (static_cast <ShowdesktopHandlerWindowInterface *> (&mMockWindow));
1371+
1372+ EXPECT_CALL (mMockWindow, IsOverrideRedirect ());
1373+ EXPECT_CALL (mMockWindow, IsManaged ());
1374+ EXPECT_CALL (mMockWindow, IsGrabbed ());
1375+ EXPECT_CALL (mMockWindow, IsDesktopOrDock ());
1376+ EXPECT_CALL (mMockWindow, IsSkipTaskbarOrPager ());
1377+ EXPECT_CALL (mMockWindow, IsHidden ()).WillOnce (Return (true));
1378+ EXPECT_CALL (mMockWindow, IsInShowdesktopMode ()).WillOnce (Return (true));
1379+ EXPECT_FALSE (ShowdesktopHandler::ShouldHide (&mMockWindow));
1380+}
1381+
1382+TEST_F(UnityShowdesktopHandlerTest, TestHiddenNotSDAndNotShadedWindowsSD)
1383+{
1384+ MockUnityShowdesktopHandlerWindow mMockWindow;
1385+
1386+ EXPECT_CALL (mMockWindow, GetInputRemover ());
1387+
1388+ ShowdesktopHandler mMockHandler (static_cast <ShowdesktopHandlerWindowInterface *> (&mMockWindow));
1389+
1390+ EXPECT_CALL (mMockWindow, IsOverrideRedirect ());
1391+ EXPECT_CALL (mMockWindow, IsManaged ());
1392+ EXPECT_CALL (mMockWindow, IsGrabbed ());
1393+ EXPECT_CALL (mMockWindow, IsDesktopOrDock ());
1394+ EXPECT_CALL (mMockWindow, IsSkipTaskbarOrPager ());
1395+ EXPECT_CALL (mMockWindow, IsHidden ()).WillOnce (Return (true));
1396+ EXPECT_CALL (mMockWindow, IsInShowdesktopMode ()).WillOnce (Return (false));
1397+ EXPECT_CALL (mMockWindow, IsShaded ()).WillOnce (Return (false));
1398+ EXPECT_TRUE (ShowdesktopHandler::ShouldHide (&mMockWindow));
1399+}
1400+
1401+class MockWindowInputRemoverTestFadeOut :
1402+ public compiz::WindowInputRemoverInterface
1403+{
1404+ public:
1405+
1406+ MockWindowInputRemoverTestFadeOut ()
1407+ {
1408+ ON_CALL (*this, saveInput ()).WillByDefault (Return (true));
1409+ ON_CALL (*this, removeInput ()).WillByDefault (Return (true));
1410+ ON_CALL (*this, restoreInput ()).WillByDefault (Return (true));
1411+
1412+ EXPECT_CALL (*this, saveInput ()).WillOnce (Return (true));
1413+ EXPECT_CALL (*this, removeInput ()).WillOnce (Return (true));
1414+ }
1415+
1416+ MOCK_METHOD0 (saveInput, bool ());
1417+ MOCK_METHOD0 (removeInput, bool ());
1418+ MOCK_METHOD0 (restoreInput, bool ());
1419+};
1420+
1421+TEST_F(UnityShowdesktopHandlerTest, TestFadeOutHidesWindow)
1422+{
1423+ MockUnityShowdesktopHandlerWindow mMockWindow;
1424+
1425+ EXPECT_CALL (mMockWindow, GetInputRemover ()).WillOnce (Invoke (UnityShowdesktopHandlerTest::makeShared<compiz::WindowInputRemoverInterface, MockWindowInputRemoverTestFadeOut>));
1426+
1427+ ShowdesktopHandler mMockHandler (static_cast <ShowdesktopHandlerWindowInterface *> (&mMockWindow));
1428+
1429+ EXPECT_CALL (mMockWindow, IsHidden ());
1430+ EXPECT_CALL (mMockWindow, DoHide ());
1431+ EXPECT_CALL (mMockWindow, DoNotifyHidden ());
1432+
1433+ mMockHandler.FadeOut ();
1434+
1435+ EXPECT_EQ (ShowdesktopHandler::animating_windows.size (), 1);
1436+}
1437+
1438+class MockWindowInputRemoverTestFadeOutAlready :
1439+ public compiz::WindowInputRemoverInterface
1440+{
1441+ public:
1442+
1443+ MockWindowInputRemoverTestFadeOutAlready ()
1444+ {
1445+ ON_CALL (*this, saveInput ()).WillByDefault (Return (true));
1446+ ON_CALL (*this, removeInput ()).WillByDefault (Return (true));
1447+ ON_CALL (*this, restoreInput ()).WillByDefault (Return (true));
1448+ }
1449+
1450+ MOCK_METHOD0 (saveInput, bool ());
1451+ MOCK_METHOD0 (removeInput, bool ());
1452+ MOCK_METHOD0 (restoreInput, bool ());
1453+};
1454+
1455+TEST_F(UnityShowdesktopHandlerTest, TestFadeOutOnHiddenDoesntHideWindow)
1456+{
1457+ MockUnityShowdesktopHandlerWindow mMockWindow;
1458+
1459+ EXPECT_CALL (mMockWindow, GetInputRemover ()).WillOnce (Invoke (UnityShowdesktopHandlerTest::makeShared<compiz::WindowInputRemoverInterface, MockWindowInputRemoverTestFadeOutAlready>));
1460+
1461+ ShowdesktopHandler mMockHandler (static_cast <ShowdesktopHandlerWindowInterface *> (&mMockWindow));
1462+
1463+ EXPECT_CALL (mMockWindow, IsHidden ()).WillOnce (Return (true));
1464+
1465+ mMockHandler.FadeOut ();
1466+
1467+ EXPECT_EQ (ShowdesktopHandler::animating_windows.size (), 0);
1468+}
1469+
1470+TEST_F(UnityShowdesktopHandlerTest, TestFadeOutAlreadyFadedDoesntHideWindow)
1471+{
1472+ MockUnityShowdesktopHandlerWindow mMockWindow;
1473+
1474+ EXPECT_CALL (mMockWindow, GetInputRemover ()).WillOnce (Invoke (UnityShowdesktopHandlerTest::makeShared<compiz::WindowInputRemoverInterface, MockWindowInputRemoverTestFadeOut>));
1475+
1476+ ShowdesktopHandler mMockHandler (static_cast <ShowdesktopHandlerWindowInterface *> (&mMockWindow));
1477+
1478+ EXPECT_CALL (mMockWindow, IsHidden ());
1479+ EXPECT_CALL (mMockWindow, DoHide ());
1480+ EXPECT_CALL (mMockWindow, DoNotifyHidden ());
1481+
1482+ mMockHandler.FadeOut ();
1483+ mMockHandler.FadeOut ();
1484+
1485+ EXPECT_EQ (ShowdesktopHandler::animating_windows.size (), 1);
1486+}
1487+
1488+TEST_F(UnityShowdesktopHandlerTest, TestFadeInNonFadedDoesntShowWindow)
1489+{
1490+ MockUnityShowdesktopHandlerWindow mMockWindow;
1491+
1492+ EXPECT_CALL (mMockWindow, GetInputRemover ()).WillOnce (Invoke (UnityShowdesktopHandlerTest::makeShared<compiz::WindowInputRemoverInterface, MockWindowInputRemoverTestFadeOutAlready>));
1493+
1494+ ShowdesktopHandler mMockHandler (static_cast <ShowdesktopHandlerWindowInterface *> (&mMockWindow));
1495+
1496+ mMockHandler.FadeIn ();
1497+
1498+ EXPECT_EQ (ShowdesktopHandler::animating_windows.size (), 0);
1499+}
1500+
1501+class MockWindowInputRemoverTestFadeOutFadeIn :
1502+ public compiz::WindowInputRemoverInterface
1503+{
1504+ public:
1505+
1506+ MockWindowInputRemoverTestFadeOutFadeIn ()
1507+ {
1508+ ON_CALL (*this, saveInput ()).WillByDefault (Return (true));
1509+ ON_CALL (*this, removeInput ()).WillByDefault (Return (true));
1510+ ON_CALL (*this, restoreInput ()).WillByDefault (Return (true));
1511+
1512+ EXPECT_CALL (*this, saveInput ()).WillOnce (Return (true));
1513+ EXPECT_CALL (*this, removeInput ()).WillOnce (Return (true));
1514+ EXPECT_CALL (*this, restoreInput ()).WillOnce (Return (true));
1515+ }
1516+
1517+ MOCK_METHOD0 (saveInput, bool ());
1518+ MOCK_METHOD0 (removeInput, bool ());
1519+ MOCK_METHOD0 (restoreInput, bool ());
1520+};
1521+
1522+TEST_F(UnityShowdesktopHandlerTest, TestFadeOutHidesWindowFadeInShowsWindow)
1523+{
1524+ MockUnityShowdesktopHandlerWindow mMockWindow;
1525+
1526+ EXPECT_CALL (mMockWindow, GetInputRemover ()).WillOnce (Invoke (UnityShowdesktopHandlerTest::makeShared<compiz::WindowInputRemoverInterface, MockWindowInputRemoverTestFadeOutFadeIn>));
1527+
1528+ ShowdesktopHandler mMockHandler (static_cast <ShowdesktopHandlerWindowInterface *> (&mMockWindow));
1529+
1530+ EXPECT_CALL (mMockWindow, IsHidden ());
1531+ EXPECT_CALL (mMockWindow, DoHide ());
1532+ EXPECT_CALL (mMockWindow, DoNotifyHidden ());
1533+
1534+ mMockHandler.FadeOut ();
1535+
1536+ EXPECT_CALL (mMockWindow, DoShow ());
1537+ EXPECT_CALL (mMockWindow, DoNotifyShown ());
1538+
1539+ mMockHandler.FadeIn ();
1540+
1541+ EXPECT_EQ (ShowdesktopHandler::animating_windows.size (), 1);
1542+}
1543+
1544+TEST_F(UnityShowdesktopHandlerTest, TestAnimationPostPaintActions)
1545+{
1546+ MockUnityShowdesktopHandlerWindow mMockWindow;
1547+
1548+ EXPECT_CALL (mMockWindow, GetInputRemover ()).WillOnce (Invoke (UnityShowdesktopHandlerTest::makeShared<compiz::WindowInputRemoverInterface, MockWindowInputRemoverTestFadeOutFadeIn>));
1549+
1550+ ShowdesktopHandler mMockHandler (static_cast <ShowdesktopHandlerWindowInterface *> (&mMockWindow));
1551+
1552+ EXPECT_CALL (mMockWindow, IsHidden ());
1553+ EXPECT_CALL (mMockWindow, DoHide ());
1554+ EXPECT_CALL (mMockWindow, DoNotifyHidden ());
1555+
1556+ mMockHandler.FadeOut ();
1557+
1558+ EXPECT_CALL (mMockWindow, DoShow ());
1559+ EXPECT_CALL (mMockWindow, DoNotifyShown ());
1560+
1561+ for (unsigned int i = 0; i < ShowdesktopHandler::fade_time; i++)
1562+ {
1563+ ShowdesktopHandlerWindowInterface::PostPaintAction action = mMockHandler.Animate (1);
1564+
1565+ if (i == 300)
1566+ EXPECT_EQ (action, ShowdesktopHandlerWindowInterface::PostPaintAction::Wait);
1567+ else
1568+ EXPECT_EQ (action, ShowdesktopHandlerWindowInterface::PostPaintAction::Damage);
1569+ }
1570+
1571+ mMockHandler.FadeIn ();
1572+
1573+ for (unsigned int i = 0; i < ShowdesktopHandler::fade_time; i++)
1574+ {
1575+ ShowdesktopHandlerWindowInterface::PostPaintAction action = mMockHandler.Animate (1);
1576+
1577+ if (i == 300)
1578+ EXPECT_EQ (action, ShowdesktopHandlerWindowInterface::PostPaintAction::Remove);
1579+ else
1580+ EXPECT_EQ (action, ShowdesktopHandlerWindowInterface::PostPaintAction::Damage);
1581+ }
1582+
1583+ EXPECT_EQ (ShowdesktopHandler::animating_windows.size (), 1);
1584+}
1585+
1586+TEST_F(UnityShowdesktopHandlerTest, TestAnimationOpacity)
1587+{
1588+ MockUnityShowdesktopHandlerWindow mMockWindow;
1589+
1590+ EXPECT_CALL (mMockWindow, GetInputRemover ()).WillOnce (Invoke (UnityShowdesktopHandlerTest::makeShared<compiz::WindowInputRemoverInterface, MockWindowInputRemoverTestFadeOutFadeIn>));
1591+
1592+ ShowdesktopHandler mMockHandler (static_cast <ShowdesktopHandlerWindowInterface *> (&mMockWindow));
1593+
1594+ EXPECT_CALL (mMockWindow, IsHidden ());
1595+ EXPECT_CALL (mMockWindow, DoHide ());
1596+ EXPECT_CALL (mMockWindow, DoNotifyHidden ());
1597+
1598+ mMockHandler.FadeOut ();
1599+
1600+ EXPECT_CALL (mMockWindow, DoShow ());
1601+ EXPECT_CALL (mMockWindow, DoNotifyShown ());
1602+
1603+ /* The funny expectations here are to account for rounding errors that would
1604+ * otherwise make testing the code painful */
1605+
1606+ for (unsigned int i = 0; i < ShowdesktopHandler::fade_time; i++)
1607+ {
1608+ unsigned short opacity = std::numeric_limits <unsigned short>::max ();
1609+ mMockHandler.PaintOpacity (opacity);
1610+
1611+ mMockHandler.Animate (1);
1612+
1613+ if (i == 300)
1614+ EXPECT_EQ (opacity, std::numeric_limits <unsigned short>::max ());
1615+ else
1616+ {
1617+ float rem = opacity - std::numeric_limits <unsigned short>::max () * (1.0f - i / static_cast <float> (ShowdesktopHandler::fade_time));
1618+ EXPECT_TRUE (rem <= 1.0f && rem >= -1.0f);
1619+ }
1620+ }
1621+
1622+ mMockHandler.FadeIn ();
1623+
1624+ for (unsigned int i = 0; i < ShowdesktopHandler::fade_time; i++)
1625+ {
1626+ unsigned short opacity = std::numeric_limits <unsigned short>::max ();
1627+ mMockHandler.PaintOpacity (opacity);
1628+
1629+ mMockHandler.Animate (1);
1630+
1631+ if (i == 300)
1632+ EXPECT_EQ (opacity, std::numeric_limits <unsigned short>::max ());
1633+ else
1634+ {
1635+ float rem = opacity - std::numeric_limits <unsigned short>::max () * (i / static_cast <float> (ShowdesktopHandler::fade_time));
1636+ EXPECT_TRUE (rem <= 1.0f && rem >= -1.0f);
1637+ }
1638+ }
1639+
1640+ EXPECT_EQ (ShowdesktopHandler::animating_windows.size (), 1);
1641+}
1642+
1643+TEST_F(UnityShowdesktopHandlerTest, TestAnimationPaintMasks)
1644+{
1645+ MockUnityShowdesktopHandlerWindow mMockWindow;
1646+
1647+ EXPECT_CALL (mMockWindow, GetInputRemover ()).WillOnce (Invoke (UnityShowdesktopHandlerTest::makeShared<compiz::WindowInputRemoverInterface, MockWindowInputRemoverTestFadeOutFadeIn>));
1648+
1649+ ShowdesktopHandler mMockHandler (static_cast <ShowdesktopHandlerWindowInterface *> (&mMockWindow));
1650+
1651+ EXPECT_CALL (mMockWindow, IsHidden ());
1652+ EXPECT_CALL (mMockWindow, DoHide ());
1653+ EXPECT_CALL (mMockWindow, DoNotifyHidden ());
1654+
1655+ mMockHandler.FadeOut ();
1656+
1657+ EXPECT_CALL (mMockWindow, DoShow ());
1658+ EXPECT_CALL (mMockWindow, DoNotifyShown ());
1659+ EXPECT_CALL (mMockWindow, GetNoCoreInstanceMask ());
1660+
1661+ mMockHandler.Animate (ShowdesktopHandler::fade_time);
1662+
1663+ EXPECT_EQ (mMockHandler.GetPaintMask (), 1);
1664+
1665+ mMockHandler.FadeIn ();
1666+
1667+ mMockHandler.Animate (ShowdesktopHandler::fade_time);
1668+
1669+ EXPECT_EQ (mMockHandler.GetPaintMask (), 0);
1670+
1671+ EXPECT_EQ (ShowdesktopHandler::animating_windows.size (), 1);
1672+}
1673+
1674+class MockWindowInputRemoverTestFadeOutFadeInWithShapeEvent :
1675+ public compiz::WindowInputRemoverInterface
1676+{
1677+ public:
1678+
1679+ MockWindowInputRemoverTestFadeOutFadeInWithShapeEvent ()
1680+ {
1681+ ON_CALL (*this, saveInput ()).WillByDefault (Return (true));
1682+ ON_CALL (*this, removeInput ()).WillByDefault (Return (true));
1683+ ON_CALL (*this, restoreInput ()).WillByDefault (Return (true));
1684+
1685+ InSequence s;
1686+
1687+ EXPECT_CALL (*this, saveInput ()).WillOnce (Return (true));
1688+ EXPECT_CALL (*this, removeInput ()).WillOnce (Return (true));
1689+ EXPECT_CALL (*this, saveInput ()).WillOnce (Return (true));
1690+ EXPECT_CALL (*this, removeInput ()).WillOnce (Return (true));
1691+ EXPECT_CALL (*this, restoreInput ()).WillOnce (Return (true));
1692+ }
1693+
1694+ MOCK_METHOD0 (saveInput, bool ());
1695+ MOCK_METHOD0 (removeInput, bool ());
1696+ MOCK_METHOD0 (restoreInput, bool ());
1697+};
1698+
1699+TEST_F(UnityShowdesktopHandlerTest, TestShapeEvent)
1700+{
1701+ MockUnityShowdesktopHandlerWindow mMockWindow;
1702+
1703+ EXPECT_CALL (mMockWindow, GetInputRemover ()).WillOnce (Invoke (UnityShowdesktopHandlerTest::makeShared<compiz::WindowInputRemoverInterface, MockWindowInputRemoverTestFadeOutFadeInWithShapeEvent>));
1704+
1705+ ShowdesktopHandler mMockHandler (static_cast <ShowdesktopHandlerWindowInterface *> (&mMockWindow));
1706+
1707+ EXPECT_CALL (mMockWindow, IsHidden ());
1708+ EXPECT_CALL (mMockWindow, DoHide ());
1709+ EXPECT_CALL (mMockWindow, DoNotifyHidden ());
1710+
1711+ mMockHandler.FadeOut ();
1712+
1713+ EXPECT_CALL (mMockWindow, DoShow ());
1714+ EXPECT_CALL (mMockWindow, DoNotifyShown ());
1715+
1716+ mMockHandler.HandleShapeEvent ();
1717+
1718+ mMockHandler.FadeIn ();
1719+
1720+ EXPECT_EQ (ShowdesktopHandler::animating_windows.size (), 1);
1721+}