Merge lp:~smspillaz/compiz-core/compiz-core.tests_915950 into lp:compiz-core/0.9.5

Proposed by Sam Spilsbury
Status: Merged
Merged at revision: 2979
Proposed branch: lp:~smspillaz/compiz-core/compiz-core.tests_915950
Merge into: lp:compiz-core/0.9.5
Diff against target: 1328 lines (+749/-285)
9 files modified
plugins/place/CMakeLists.txt (+4/-1)
plugins/place/src/place.cpp (+126/-280)
plugins/place/src/place.h (+8/-4)
plugins/place/src/smart/CMakeLists.txt (+62/-0)
plugins/place/src/smart/include/smart.h (+73/-0)
plugins/place/src/smart/src/smart.cpp (+199/-0)
plugins/place/src/smart/tests/CMakeLists.txt (+14/-0)
plugins/place/src/smart/tests/offscreen/src/test-place-smart-on-screen.cpp (+156/-0)
plugins/place/src/smart/tests/offscreen/src/test-place-smart-onscren.cpp (+107/-0)
To merge this branch: bzr merge lp:~smspillaz/compiz-core/compiz-core.tests_915950
Reviewer Review Type Date Requested Status
Sam Spilsbury Approve
Alan Griffiths Approve
Review via email: mp+90751@code.launchpad.net

Description of the change

Tests that smart placement does not put windows offscreen on two different sized monitors

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

Whoops, missing a commit here

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

Or rather, there's a useless file here.

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

Maybe it's just me, but I'm concerned about the amount of core code being rewritten here (and wasn't reviewed). If it were up to me I wouldn't modify so much core code so close to release. I don't think all the changes are relevant to writing test cases either.

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

Sam reverted the merge. Needs review again.

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

Code was unintentionally pushed to trunk. thats now reverted.

As for this change - all it does is add an interface for a placeable object. the diff is large because things moved around etc

Revision history for this message
Alan Griffiths (alan-griffiths) wrote :

This *looks* OK, but like Daniel says it looks like several (sequential) changes overlayed on each other which makes it hard to validate.

I'd prefer to see separate commits for refactoring (moving/renaming stuff) and functional changes (making it work). (But I'm as guilty of mixing the two.)

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

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'plugins/place/CMakeLists.txt'
2--- plugins/place/CMakeLists.txt 2012-01-20 06:27:10 +0000
3+++ plugins/place/CMakeLists.txt 2012-01-30 18:23:23 +0000
4@@ -4,7 +4,10 @@
5
6 include_directories (${CMAKE_CURRENT_SOURCE_DIR}/src/constrain-to-workarea/include/)
7 include_directories (${CMAKE_CURRENT_SOURCE_DIR}/src/screen-size-change/include/)
8+include_directories (${CMAKE_CURRENT_SOURCE_DIR}/src/smart/include/)
9
10 add_subdirectory (src/constrain-to-workarea)
11 add_subdirectory (src/screen-size-change)
12-compiz_plugin (place LIBRARIES compiz_place_constrain_to_workarea compiz_place_screen_size_change)
13+add_subdirectory (src/smart)
14+
15+compiz_plugin (place LIBRARIES compiz_place_constrain_to_workarea compiz_place_screen_size_change compiz_place_smart)
16
17=== modified file 'plugins/place/src/place.cpp'
18--- plugins/place/src/place.cpp 2012-01-25 09:20:47 +0000
19+++ plugins/place/src/place.cpp 2012-01-30 18:23:23 +0000
20@@ -65,7 +65,6 @@
21 return l;
22 }
23
24-
25 void
26 PlaceScreen::doHandleScreenSizeChange (int newWidth,
27 int newHeight)
28@@ -101,12 +100,31 @@
29 return screen->getWorkareaForOutput (screen->outputDeviceForGeometry (g));
30 }
31
32+const CompRect &
33+PlaceWindow::getWorkarea () const
34+{
35+ return getWorkarea (window->serverGeometry ());
36+}
37+
38 const compiz::window::extents::Extents &
39 PlaceWindow::getExtents () const
40 {
41 return window->border ();
42 }
43
44+unsigned int
45+PlaceWindow::getState () const
46+{
47+ unsigned int state = 0;
48+
49+ if (window->state () & CompWindowStateAboveMask)
50+ state |= compiz::place::WindowAbove;
51+ if (window->state () & CompWindowStateBelowMask)
52+ state |= compiz::place::WindowBelow;
53+
54+ return state;
55+}
56+
57 void
58 PlaceWindow::applyGeometry (compiz::window::Geometry &ng,
59 compiz::window::Geometry &og)
60@@ -224,42 +242,42 @@
61 /* sort functions */
62
63 static bool
64-compareLeftmost (CompWindow *a,
65- CompWindow *b)
66+compareLeftmost (compiz::place::Placeable *a,
67+ compiz::place::Placeable *b)
68 {
69 int ax, bx;
70
71- ax = a->serverX () - a->border ().left;
72- bx = b->serverX () - b->border ().left;
73+ ax = a->geometry ().x () - a->extents ().left;
74+ bx = b->geometry ().x () - a->extents ().left;
75
76 return (ax <= bx);
77 }
78
79 static bool
80-compareTopmost (CompWindow *a,
81- CompWindow *b)
82+compareTopmost (compiz::place::Placeable *a,
83+ compiz::place::Placeable *b)
84 {
85 int ay, by;
86
87- ay = a->serverY () - a->border ().top;
88- by = b->serverY () - b->border ().top;
89+ ay = a->geometry ().y () - a->extents ().top;
90+ by = b->geometry ().y () - a->extents ().top;
91
92 return (ay <= by);
93 }
94
95 static bool
96-compareNorthWestCorner (CompWindow *a,
97- CompWindow *b)
98+compareNorthWestCorner (compiz::place::Placeable *a,
99+ compiz::place::Placeable *b)
100 {
101 int fromOriginA;
102 int fromOriginB;
103 int ax, ay, bx, by;
104
105- ax = a->serverX () - a->border ().left;
106- ay = a->serverY () - a->border ().top;
107+ ax = a->geometry ().x () - a->extents ().left;
108+ bx = b->geometry ().x () - a->extents ().left;
109
110- bx = b->serverX () - b->border ().left;
111- by = b->serverY () - b->border ().top;
112+ ay = a->geometry ().y () - a->extents ().top;
113+ by = b->geometry ().y () - a->extents ().top;
114
115 /* probably there's a fast good-enough-guess we could use here. */
116 fromOriginA = sqrt (ax * ax + ay * ay);
117@@ -585,6 +603,17 @@
118
119 if (strategy == PlaceOnly || strategy == PlaceAndConstrain)
120 {
121+ /* Construct list of placeables */
122+ compiz::place::Placeable::Vector placeables;
123+
124+ foreach (CompWindow *w, screen->windows ())
125+ {
126+ PLACE_WINDOW (w);
127+
128+ if (windowIsPlaceRelevant (w))
129+ placeables.push_back (static_cast <compiz::place::Placeable *> (pw));
130+ }
131+
132 switch (mode) {
133 case PlaceOptions::ModeCascade:
134 placeCascade (workArea, pos);
135@@ -602,7 +631,7 @@
136 sendMaximizationRequest ();
137 break;
138 case PlaceOptions::ModeSmart:
139- placeSmart (workArea, pos);
140+ placeSmart (pos, placeables);
141 break;
142 }
143
144@@ -650,7 +679,7 @@
145 PlaceWindow::placeCascade (const CompRect &workArea,
146 CompPoint &pos)
147 {
148- CompWindowList windows;
149+ Placeable::Vector placeables;
150
151 /* Find windows that matter (not minimized, on same workspace
152 * as placed window, may be shaded - if shaded we pretend it isn't
153@@ -671,15 +700,15 @@
154 w->serverY () + w->serverGeometry ().height () <= workArea.y ())
155 continue;
156
157- windows.push_back (w);
158+ placeables.push_back (static_cast <Placeable *> (PlaceWindow::get (w)));
159 }
160
161- if (!cascadeFindFirstFit (windows, workArea, pos))
162+ if (!cascadeFindFirstFit (placeables, workArea, pos))
163 {
164 /* if the window wasn't placed at the origin of screen,
165 * cascade it onto the current screen
166 */
167- cascadeFindNext (windows, workArea, pos);
168+ cascadeFindNext (placeables, workArea, pos);
169 }
170 }
171
172@@ -727,201 +756,13 @@
173 placeCentered (workArea, pos);
174 }
175
176-
177-/* overlap types */
178-#define NONE 0
179-#define H_WRONG -1
180-#define W_WRONG -2
181+using namespace compiz::place;
182
183 void
184-PlaceWindow::placeSmart (const CompRect &workArea,
185- CompPoint &pos)
186+PlaceWindow::placeSmart (CompPoint &pos,
187+ const compiz::place::Placeable::Vector &placeables)
188 {
189- /*
190- * SmartPlacement by Cristian Tibirna (tibirna@kde.org)
191- * adapted for kwm (16-19jan98) and for kwin (16Nov1999) using (with
192- * permission) ideas from fvwm, authored by
193- * Anthony Martin (amartin@engr.csulb.edu).
194- * Xinerama supported added by Balaji Ramani (balaji@yablibli.com)
195- * with ideas from xfce.
196- * adapted for Compiz by Bellegarde Cedric (gnumdk(at)gmail.com)
197- */
198- int overlap, minOverlap = 0;
199- int xOptimal, yOptimal;
200- int possible;
201-
202- /* temp coords */
203- int cxl, cxr, cyt, cyb;
204- /* temp coords */
205- int xl, xr, yt, yb;
206- /* temp holder */
207- int basket;
208- /* CT lame flag. Don't like it. What else would do? */
209- bool firstPass = true;
210-
211- /* get the maximum allowed windows space */
212- int xTmp = workArea.x ();
213- int yTmp = workArea.y ();
214-
215- /* client gabarit */
216- int cw = window->serverWidth () - 1;
217- int ch = window->serverHeight () - 1;
218-
219- xOptimal = xTmp;
220- yOptimal = yTmp;
221-
222- /* loop over possible positions */
223- do
224- {
225- /* test if enough room in x and y directions */
226- if (yTmp + ch > workArea.bottom () && ch < workArea.height ())
227- overlap = H_WRONG; /* this throws the algorithm to an exit */
228- else if (xTmp + cw > workArea.right ())
229- overlap = W_WRONG;
230- else
231- {
232- overlap = NONE; /* initialize */
233-
234- cxl = xTmp;
235- cxr = xTmp + cw;
236- cyt = yTmp;
237- cyb = yTmp + ch;
238-
239- foreach (CompWindow *w, screen->windows ())
240- {
241- if (!windowIsPlaceRelevant (w))
242- continue;
243-
244- xl = w->serverX () - w->border ().left;
245- yt = w->serverY () - w->border ().top;
246- xr = w->serverX () + w->serverWidth () +
247- w->border ().right +
248- w->serverGeometry ().border () * 2;
249- yb = w->serverY () + w->serverHeight () +
250- w->border ().bottom +
251- w->serverGeometry ().border () * 2;
252-
253- /* if windows overlap, calc the overall overlapping */
254- if (cxl < xr && cxr > xl && cyt < yb && cyb > yt)
255- {
256- xl = MAX (cxl, xl);
257- xr = MIN (cxr, xr);
258- yt = MAX (cyt, yt);
259- yb = MIN (cyb, yb);
260-
261- if (w->state () & CompWindowStateAboveMask)
262- overlap += 16 * (xr - xl) * (yb - yt);
263- else if (w->state () & CompWindowStateBelowMask)
264- overlap += 0;
265- else
266- overlap += (xr - xl) * (yb - yt);
267- }
268- }
269- }
270-
271- /* CT first time we get no overlap we stop */
272- if (overlap == NONE)
273- {
274- xOptimal = xTmp;
275- yOptimal = yTmp;
276- break;
277- }
278-
279- if (firstPass)
280- {
281- firstPass = false;
282- minOverlap = overlap;
283- }
284- /* CT save the best position and the minimum overlap up to now */
285- else if (overlap >= NONE && overlap < minOverlap)
286- {
287- minOverlap = overlap;
288- xOptimal = xTmp;
289- yOptimal = yTmp;
290- }
291-
292- /* really need to loop? test if there's any overlap */
293- if (overlap > NONE)
294- {
295- possible = workArea.right ();
296-
297- if (possible - cw > xTmp)
298- possible -= cw;
299-
300- /* compare to the position of each client on the same desk */
301- foreach (CompWindow *w, screen->windows ())
302- {
303- if (!windowIsPlaceRelevant (w))
304- continue;
305-
306- xl = w->serverX () - w->border ().left;
307- yt = w->serverY () - w->border ().top;
308- xr = w->serverX () + w->serverWidth () +
309- w->border ().right +
310- w->serverGeometry ().border () * 2;
311- yb = w->serverY () + w->serverHeight () +
312- w->border ().bottom +
313- w->serverGeometry ().border () * 2;
314-
315- /* if not enough room above or under the current
316- * client determine the first non-overlapped x position
317- */
318- if (yTmp < yb && yt < ch + yTmp)
319- {
320- if (xr > xTmp && possible > xr)
321- possible = xr;
322-
323- basket = xl - cw;
324- if (basket > xTmp && possible > basket)
325- possible = basket;
326- }
327- }
328- xTmp = possible;
329- }
330- /* else ==> not enough x dimension (overlap was wrong on horizontal) */
331- else if (overlap == W_WRONG)
332- {
333- xTmp = workArea.x ();
334- possible = workArea.bottom ();
335-
336- if (possible - ch > yTmp)
337- possible -= ch;
338-
339- /* test the position of each window on the desk */
340- foreach (CompWindow *w, screen->windows ())
341- {
342- if (!windowIsPlaceRelevant (w))
343- continue;
344-
345- xl = w->serverX () - w->border ().left;
346- yt = w->serverY () - w->border ().top;
347- xr = w->serverX () + w->serverWidth () +
348- w->border ().right +
349- w->serverGeometry ().border () * 2;
350- yb = w->serverY () + w->serverHeight () +
351- w->border ().bottom +
352- w->serverGeometry ().border () * 2;
353-
354- /* if not enough room to the left or right of the current
355- * client determine the first non-overlapped y position
356- */
357- if (yb > yTmp && possible > yb)
358- possible = yb;
359-
360- basket = yt - ch;
361- if (basket > yTmp && possible > basket)
362- possible = basket;
363- }
364- yTmp = possible;
365- }
366- }
367- while (overlap != NONE && overlap != H_WRONG && yTmp < workArea.bottom ());
368-
369- if (ch >= workArea.height ())
370- yOptimal = workArea.y ();
371-
372- pos.setX (xOptimal + window->border ().left);
373- pos.setY (yOptimal + window->border ().top);
374+ compiz::place::smart (this, pos, placeables);
375 }
376
377 static void
378@@ -945,32 +786,22 @@
379
380 static bool
381 rectOverlapsWindow (const CompRect &rect,
382- const CompWindowList &windows)
383+ const compiz::place::Placeable::Vector &placeables)
384 {
385 CompRect dest;
386
387- foreach (CompWindow *other, windows)
388+ foreach (compiz::place::Placeable *other, placeables)
389 {
390 CompRect intersect;
391+ CompRect sbr = other->geometry ();
392+ sbr.setLeft (sbr.left () - other->extents ().left);
393+ sbr.setRight (sbr.right () + other->extents ().right);
394+ sbr.setTop (sbr.top () - other->extents ().top);
395+ sbr.setBottom (sbr.bottom () - other->extents ().bottom);
396
397- switch (other->type ()) {
398- case CompWindowTypeDockMask:
399- case CompWindowTypeSplashMask:
400- case CompWindowTypeDesktopMask:
401- case CompWindowTypeDialogMask:
402- case CompWindowTypeModalDialogMask:
403- case CompWindowTypeFullscreenMask:
404- case CompWindowTypeUnknownMask:
405- break;
406- case CompWindowTypeNormalMask:
407- case CompWindowTypeUtilMask:
408- case CompWindowTypeToolbarMask:
409- case CompWindowTypeMenuMask:
410- intersect = rect & other->serverBorderRect ();
411- if (!intersect.isEmpty ())
412- return true;
413- break;
414- }
415+ intersect = rect & sbr;
416+ if (!intersect.isEmpty ())
417+ return true;
418 }
419
420 return false;
421@@ -985,7 +816,7 @@
422 * don't want to create a 1x1 Emacs.
423 */
424 bool
425-PlaceWindow::cascadeFindFirstFit (const CompWindowList &windows,
426+PlaceWindow::cascadeFindFirstFit (const Placeable::Vector &placeables,
427 const CompRect &workArea,
428 CompPoint &pos)
429 {
430@@ -997,49 +828,59 @@
431 * existing window in each of those cases.
432 */
433 bool retval = false;
434- CompWindowList belowSorted, rightSorted;
435- CompRect rect;
436+ Placeable::Vector belowSorted, rightSorted;
437
438 /* Below each window */
439- belowSorted = windows;
440- belowSorted.sort (compareLeftmost);
441- belowSorted.sort (compareTopmost);
442+ belowSorted = placeables;
443+ std::sort (belowSorted.begin (), belowSorted.end (), compareLeftmost);
444+ std::sort (belowSorted.begin (), belowSorted.end (), compareTopmost);
445
446 /* To the right of each window */
447- rightSorted = windows;
448- rightSorted.sort (compareTopmost);
449- rightSorted.sort (compareLeftmost);
450-
451- rect = window->serverBorderRect ();
452+ rightSorted = placeables;
453+ std::sort (belowSorted.begin (), belowSorted.end (), compareTopmost);
454+ std::sort (belowSorted.begin (), belowSorted.end (), compareLeftmost);
455+
456+ CompRect rect = this->geometry ();
457+
458+ rect.setLeft (rect.left () - this->extents ().left);
459+ rect.setRight (rect.right () + this->extents ().right);
460+ rect.setTop (rect.top () - this->extents ().top);
461+ rect.setBottom (rect.bottom () - this->extents ().bottom);
462+
463 centerTileRectInArea (rect, workArea);
464
465- if (workArea.contains (rect) && !rectOverlapsWindow (rect, windows))
466+ if (workArea.contains (rect) && !rectOverlapsWindow (rect, placeables))
467 {
468- pos.setX (rect.x () + window->border ().left);
469- pos.setY (rect.y () + window->border ().top);
470+ pos.setX (rect.x () + this->extents ().left);
471+ pos.setY (rect.y () + this->extents ().top);
472 retval = true;
473 }
474
475 if (!retval)
476 {
477 /* try below each window */
478- foreach (CompWindow *w, belowSorted)
479+ foreach (Placeable *p, belowSorted)
480 {
481 CompRect outerRect;
482
483 if (retval)
484 break;
485
486- outerRect = w->serverBorderRect ();
487-
488- rect.setX (outerRect.x ());
489- rect.setY (outerRect.bottom ());
490+ outerRect = p->geometry ();
491+
492+ outerRect.setLeft (rect.left () - this->extents ().left);
493+ outerRect.setRight (rect.right () + this->extents ().right);
494+ outerRect.setTop (rect.top () - this->extents ().top);
495+ outerRect.setBottom (rect.bottom () - this->extents ().bottom);
496+
497+ outerRect.setX (outerRect.x ());
498+ outerRect.setY (outerRect.bottom ());
499
500 if (workArea.contains (rect) &&
501 !rectOverlapsWindow (rect, belowSorted))
502 {
503- pos.setX (rect.x () + window->border ().left);
504- pos.setY (rect.y () + window->border ().top);
505+ pos.setX (rect.x () + this->extents ().left);
506+ pos.setY (rect.y () + this->extents ().top);
507 retval = true;
508 }
509 }
510@@ -1048,23 +889,28 @@
511 if (!retval)
512 {
513 /* try to the right of each window */
514- foreach (CompWindow *w, rightSorted)
515+ foreach (Placeable *p, rightSorted)
516 {
517 CompRect outerRect;
518
519 if (retval)
520 break;
521
522- outerRect = w->serverBorderRect ();
523-
524- rect.setX (outerRect.right ());
525- rect.setY (outerRect.y ());
526+ outerRect = p->geometry ();
527+
528+ outerRect.setLeft (rect.left () - this->extents ().left);
529+ outerRect.setRight (rect.right () + this->extents ().right);
530+ outerRect.setTop (rect.top () - this->extents ().top);
531+ outerRect.setBottom (rect.bottom () - this->extents ().bottom);
532+
533+ outerRect.setX (outerRect.right ());
534+ outerRect.setY (outerRect.y ());
535
536 if (workArea.contains (rect) &&
537 !rectOverlapsWindow (rect, rightSorted))
538 {
539- pos.setX (rect.x () + w->border ().left);
540- pos.setY (rect.y () + w->border ().top);
541+ pos.setX (rect.x () + this->extents ().left);
542+ pos.setY (rect.y () + this->extents ().top);
543 retval = true;
544 }
545 }
546@@ -1074,19 +920,19 @@
547 }
548
549 void
550-PlaceWindow::cascadeFindNext (const CompWindowList &windows,
551- const CompRect &workArea,
552- CompPoint &pos)
553+PlaceWindow::cascadeFindNext (const Placeable::Vector &placeables,
554+ const CompRect &workArea,
555+ CompPoint &pos)
556 {
557- CompWindowList sorted;
558- CompWindowList::iterator iter;
559- int cascadeX, cascadeY;
560- int xThreshold, yThreshold;
561- int winWidth, winHeight;
562- int cascadeStage;
563+ Placeable::Vector sorted;
564+ Placeable::Vector::iterator iter;
565+ int cascadeX, cascadeY;
566+ int xThreshold, yThreshold;
567+ int winWidth, winHeight;
568+ int cascadeStage;
569
570- sorted = windows;
571- sorted.sort (compareNorthWestCorner);
572+ sorted = placeables;
573+ std::sort (sorted.begin (), sorted.end (), compareNorthWestCorner);
574
575 /* This is a "fuzzy" cascade algorithm.
576 * For each window in the list, we find where we'd cascade a
577@@ -1099,8 +945,8 @@
578 */
579 #define CASCADE_FUZZ 15
580
581- xThreshold = MAX (window->border ().left, CASCADE_FUZZ);
582- yThreshold = MAX (window->border ().top, CASCADE_FUZZ);
583+ xThreshold = MAX (this->extents ().left, CASCADE_FUZZ);
584+ yThreshold = MAX (this->extents ().top, CASCADE_FUZZ);
585
586 /* Find furthest-SE origin of all workspaces.
587 * cascade_x, cascade_y are the target position
588@@ -1118,12 +964,12 @@
589 cascadeStage = 0;
590 for (iter = sorted.begin (); iter != sorted.end (); iter++)
591 {
592- CompWindow *w = *iter;
593+ Placeable *p = *iter;
594 int wx, wy;
595
596 /* we want frame position, not window position */
597- wx = w->serverX () - w->border ().left;
598- wy = w->serverY () - w->border ().top;
599+ wx = p->geometry ().x () - p->extents ().left;
600+ wy = p->geometry ().y () - p->extents ().top;
601
602 if (abs (wx - cascadeX) < xThreshold &&
603 abs (wy - cascadeY) < yThreshold)
604@@ -1132,8 +978,8 @@
605 * point. The new window frame should go at the origin
606 * of the client window we're stacking above.
607 */
608- wx = cascadeX = w->serverX ();
609- wy = cascadeY = w->serverY ();
610+ wx = cascadeX = p->geometry ().x ();
611+ wy = cascadeY = p->geometry ().y ();
612
613 /* If we go off the screen, start over with a new cascade */
614 if ((cascadeX + winWidth > workArea.right ()) ||
615@@ -1174,8 +1020,8 @@
616 */
617
618 /* Convert coords to position of window, not position of frame. */
619- pos.setX (cascadeX + window->border ().left);
620- pos.setY (cascadeY + window->border ().top);
621+ pos.setX (cascadeX + this->extents ().left);
622+ pos.setY (cascadeY + this->extents ().top);
623 }
624
625 bool
626
627=== modified file 'plugins/place/src/place.h'
628--- plugins/place/src/place.h 2012-01-21 17:16:07 +0000
629+++ plugins/place/src/place.h 2012-01-30 18:23:23 +0000
630@@ -31,6 +31,7 @@
631
632 #include "place_options.h"
633 #include "screen-size-change.h"
634+#include "smart.h"
635
636 namespace compiz
637 {
638@@ -39,7 +40,6 @@
639 {
640
641 CompWindowList collectStrutWindows (const CompWindowList &allWindows);
642-
643 }
644
645 }
646@@ -74,6 +74,7 @@
647 class PlaceWindow :
648 public PluginClassHandler<PlaceWindow, CompWindow>,
649 public compiz::place::ScreenSizeChangeObject,
650+ public compiz::place::Placeable,
651 public WindowInterface
652 {
653 public:
654@@ -101,8 +102,11 @@
655 const compiz::window::Geometry & getGeometry () const;
656 const CompPoint & getViewport () const;
657 const CompRect & getWorkarea (const compiz::window::Geometry &g) const;
658+ const CompRect & getWorkarea () const;
659 const compiz::window::extents::Extents & getExtents () const;
660
661+ unsigned int getState () const;
662+
663 private:
664 typedef enum {
665 NoPlacement = 0,
666@@ -129,12 +133,12 @@
667 void placeCentered (const CompRect& workArea, CompPoint& pos);
668 void placeRandom (const CompRect& workArea, CompPoint& pos);
669 void placePointer (const CompRect& workArea, CompPoint& pos);
670- void placeSmart (const CompRect& workArea, CompPoint& pos);
671+ void placeSmart (CompPoint& pos, const compiz::place::Placeable::Vector &);
672
673- bool cascadeFindFirstFit (const CompWindowList& windows,
674+ bool cascadeFindFirstFit (const Placeable::Vector &placeabless,
675 const CompRect& workArea,
676 CompPoint &pos);
677- void cascadeFindNext (const CompWindowList& windows,
678+ void cascadeFindNext (const Placeable::Vector &placeables,
679 const CompRect& workArea,
680 CompPoint &pos);
681
682
683=== added directory 'plugins/place/src/smart'
684=== added file 'plugins/place/src/smart/CMakeLists.txt'
685--- plugins/place/src/smart/CMakeLists.txt 1970-01-01 00:00:00 +0000
686+++ plugins/place/src/smart/CMakeLists.txt 2012-01-30 18:23:23 +0000
687@@ -0,0 +1,62 @@
688+pkg_check_modules (
689+ GLIBMM
690+ REQUIRED
691+ glibmm-2.4 glib-2.0
692+)
693+
694+INCLUDE_DIRECTORIES (
695+ ${CMAKE_CURRENT_SOURCE_DIR}/include
696+ ${CMAKE_CURRENT_SOURCE_DIR}/src
697+
698+ ${compiz_SOURCE_DIR}/src/point/include
699+ ${compiz_SOURCE_DIR}/src/rect/include
700+ ${compiz_SOURCE_DIR}/src/window/geometry/include
701+ ${compiz_SOURCE_DIR}/src/window/geometry-saver/include
702+ ${compiz_SOURCE_DIR}/src/window/extents/include
703+ ${compiz_SOURCE_DIR}/include
704+
705+ ${Boost_INCLUDE_DIRS}
706+
707+ ${GLIBMM_INCLUDE_DIRS}
708+)
709+
710+LINK_DIRECTORIES (${GLIBMM_LIBRARY_DIRS})
711+
712+SET (
713+ PUBLIC_HEADERS
714+)
715+
716+SET (
717+ PRIVATE_HEADERS
718+ ${CMAKE_CURRENT_SOURCE_DIR}/include/smart.h
719+)
720+
721+SET(
722+ SRCS
723+ ${CMAKE_CURRENT_SOURCE_DIR}/src/smart.cpp
724+)
725+
726+ADD_LIBRARY(
727+ compiz_place_smart STATIC
728+
729+ ${SRCS}
730+
731+ ${PUBLIC_HEADERS}
732+ ${PRIVATE_HEADERS}
733+)
734+
735+if (COMPIZ_BUILD_TESTING)
736+ADD_SUBDIRECTORY( ${CMAKE_CURRENT_SOURCE_DIR}/tests )
737+endif (COMPIZ_BUILD_TESTING)
738+
739+SET_TARGET_PROPERTIES(
740+ compiz_place_smart PROPERTIES
741+ PUBLIC_HEADER "${PUBLIC_HEADERS}"
742+)
743+
744+TARGET_LINK_LIBRARIES(
745+ compiz_place_smart
746+
747+ compiz_core
748+ ${GLIBMM_LIBRARIES}
749+)
750
751=== added directory 'plugins/place/src/smart/include'
752=== added file 'plugins/place/src/smart/include/smart.h'
753--- plugins/place/src/smart/include/smart.h 1970-01-01 00:00:00 +0000
754+++ plugins/place/src/smart/include/smart.h 2012-01-30 18:23:23 +0000
755@@ -0,0 +1,73 @@
756+/*
757+ * Copyright (C) 2001 Havoc Pennington
758+ * Copyright (C) 2002, 2003 Red Hat, Inc.
759+ * Copyright (C) 2003 Rob Adams
760+ * Copyright (C) 2005 Novell, Inc.
761+ *
762+ * This program is free software; you can redistribute it and/or
763+ * modify it under the terms of the GNU General Public License as
764+ * published by the Free Software Foundation; either version 2 of the
765+ * License, or (at your option) any later version.
766+ *
767+ * This program is distributed in the hope that it will be useful, but
768+ * WITHOUT ANY WARRANTY; without even the implied warranty of
769+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
770+ * General Public License for more details.
771+ *
772+ * You should have received a copy of the GNU General Public License
773+ * along with this program; if not, write to the Free Software
774+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
775+ * 02111-1307, USA.
776+ */
777+
778+#ifndef _COMPIZ_PLACE_SMART_H
779+#define _COMPIZ_PLACE_SMART_H
780+
781+#include <vector>
782+#include <core/rect.h>
783+#include <core/windowgeometry.h>
784+#include <core/windowextents.h>
785+#include <core/size.h>
786+#include <core/point.h>
787+
788+namespace compiz
789+{
790+ namespace place
791+ {
792+
793+ extern const unsigned int WindowAbove;
794+ extern const unsigned int WindowBelow;
795+
796+ class Placeable
797+ {
798+ public:
799+
800+ typedef std::vector <Placeable *> Vector;
801+
802+ const compiz::window::Geometry & geometry () const { return getGeometry (); }
803+ const compiz::window::extents::Extents & extents () const { return getExtents (); }
804+ const CompRect & workArea () const { return getWorkarea (); }
805+
806+ unsigned int state () const { return getState (); }
807+
808+ virtual ~Placeable () = 0;
809+
810+ protected:
811+
812+ virtual const compiz::window::Geometry & getGeometry () const = 0;
813+ virtual const compiz::window::extents::Extents & getExtents () const = 0;
814+ virtual const CompRect & getWorkarea () const = 0;
815+
816+ virtual unsigned int getState () const = 0;
817+
818+ Placeable ();
819+ };
820+
821+ void smart (Placeable *placeable,
822+ CompPoint &pos,
823+ const compiz::place::Placeable::Vector &placeables);
824+
825+ }
826+}
827+
828+#endif
829
830=== added directory 'plugins/place/src/smart/src'
831=== added file 'plugins/place/src/smart/src/smart.cpp'
832--- plugins/place/src/smart/src/smart.cpp 1970-01-01 00:00:00 +0000
833+++ plugins/place/src/smart/src/smart.cpp 2012-01-30 18:23:23 +0000
834@@ -0,0 +1,199 @@
835+#include "smart.h"
836+#include <boost/foreach.hpp>
837+
838+#ifndef foreach
839+#define foreach BOOST_FOREACH
840+#endif
841+
842+/* overlap types */
843+#define NONE 0
844+#define H_WRONG -1
845+#define W_WRONG -2
846+
847+namespace compiz
848+{
849+ namespace place
850+ {
851+ const unsigned int WindowAbove = 1 << 0;
852+ const unsigned int WindowBelow = 1 << 1;
853+
854+ Placeable::Placeable ()
855+ {
856+ }
857+
858+ Placeable::~Placeable ()
859+ {
860+ }
861+
862+ void smart (Placeable *placeable,
863+ CompPoint &pos,
864+ const compiz::place::Placeable::Vector &placeables)
865+ {
866+ /*
867+ * SmartPlacement by Cristian Tibirna (tibirna@kde.org)
868+ * adapted for kwm (16-19jan98) and for kwin (16Nov1999) using (with
869+ * permission) ideas from fvwm, authored by
870+ * Anthony Martin (amartin@engr.csulb.edu).
871+ * Xinerama supported added by Balaji Ramani (balaji@yablibli.com)
872+ * with ideas from xfce.
873+ * adapted for Compiz by Bellegarde Cedric (gnumdk(at)gmail.com)
874+ */
875+ int overlap = 0, minOverlap = 0;
876+
877+ /* temp holder */
878+ int basket = 0;
879+ /* CT lame flag. Don't like it. What else would do? */
880+ bool firstPass = true;
881+
882+ /* get the maximum allowed windows space */
883+ int xTmp = placeable->workArea ().x ();
884+ int yTmp = placeable->workArea ().y ();
885+
886+ /* client gabarit */
887+ int cw = placeable->geometry ().width () - 1;
888+ int ch = placeable->geometry ().height () - 1;
889+
890+ int xOptimal = xTmp;
891+ int yOptimal = yTmp;
892+
893+ /* loop over possible positions */
894+ do
895+ {
896+ /* test if enough room in x and y directions */
897+ if (yTmp + ch > placeable->workArea ().bottom () && ch < placeable->workArea ().height ())
898+ overlap = H_WRONG; /* this throws the algorithm to an exit */
899+ else if (xTmp + cw > placeable->workArea ().right ())
900+ overlap = W_WRONG;
901+ else
902+ {
903+ overlap = NONE; /* initialize */
904+
905+ int cxl = xTmp;
906+ int cxr = xTmp + cw;
907+ int cyt = yTmp;
908+ int cyb = yTmp + ch;
909+
910+ foreach (Placeable *p, placeables)
911+ {
912+ const compiz::window::Geometry &otherGeometry = p->geometry ();
913+ const compiz::window::extents::Extents &otherExtents = p->extents ();
914+
915+ int xl = otherGeometry.x () - otherExtents.left;
916+ int yt = otherGeometry.y () - otherExtents.top;
917+ int xr = otherGeometry.x2 () + otherExtents.right + otherGeometry.border () * 2;
918+ int yb = otherGeometry.y2 () + otherExtents.bottom + otherGeometry.border () * 2;
919+
920+ /* if windows overlap, calc the overall overlapping */
921+ if (cxl < xr && cxr > xl && cyt < yb && cyb > yt)
922+ {
923+ xl = MAX (cxl, xl);
924+ xr = MIN (cxr, xr);
925+ yt = MAX (cyt, yt);
926+ yb = MIN (cyb, yb);
927+
928+ if (p->state () & compiz::place::WindowAbove)
929+ overlap += 16 * (xr - xl) * (yb - yt);
930+ else if (p->state () & compiz::place::WindowBelow)
931+ overlap += 0;
932+ else
933+ overlap += (xr - xl) * (yb - yt);
934+ }
935+ }
936+ }
937+
938+ /* CT first time we get no overlap we stop */
939+ if (overlap == NONE)
940+ {
941+ xOptimal = xTmp;
942+ yOptimal = yTmp;
943+ break;
944+ }
945+
946+ if (firstPass)
947+ {
948+ firstPass = false;
949+ minOverlap = overlap;
950+ }
951+ /* CT save the best position and the minimum overlap up to now */
952+ else if (overlap >= NONE && overlap < minOverlap)
953+ {
954+ minOverlap = overlap;
955+ xOptimal = xTmp;
956+ yOptimal = yTmp;
957+ }
958+
959+ /* really need to loop? test if there's any overlap */
960+ if (overlap > NONE)
961+ {
962+ int possible = placeable->workArea ().right ();
963+
964+ if (possible - cw > xTmp)
965+ possible -= cw;
966+
967+ /* compare to the position of each client on the same desk */
968+ foreach (Placeable *p, placeables)
969+ {
970+ const compiz::window::Geometry &otherGeometry = p->geometry ();
971+ const compiz::window::extents::Extents &otherExtents = p->extents ();
972+
973+ int xl = otherGeometry.x () - otherExtents.left;
974+ int yt = otherGeometry.y () - otherExtents.top;
975+ int xr = otherGeometry.x2 () + otherExtents.right + otherGeometry.border () * 2;
976+ int yb = otherGeometry.y2 () + otherExtents.bottom + otherGeometry.border () * 2;
977+
978+ /* if not enough room above or under the current
979+ * client determine the first non-overlapped x position
980+ */
981+ if (yTmp < yb && yt < ch + yTmp)
982+ {
983+ if (xr > xTmp && possible > xr)
984+ possible = xr;
985+
986+ basket = xl - cw;
987+ if (basket > xTmp && possible > basket)
988+ possible = basket;
989+ }
990+ }
991+ xTmp = possible;
992+ }
993+ /* else ==> not enough x dimension (overlap was wrong on horizontal) */
994+ else if (overlap == W_WRONG)
995+ {
996+ xTmp = placeable->workArea ().x ();
997+ int possible = placeable->workArea ().bottom ();
998+
999+ if (possible - ch > yTmp)
1000+ possible -= ch;
1001+
1002+ /* test the position of each window on the desk */
1003+ foreach (Placeable *p, placeables)
1004+ {
1005+ const compiz::window::Geometry &otherGeometry = p->geometry ();
1006+ const compiz::window::extents::Extents &otherExtents = p->extents ();
1007+
1008+ int yt = otherGeometry.y () - otherExtents.top;
1009+ int yb = otherGeometry.y2 () + otherExtents.bottom + otherGeometry.border () * 2;
1010+
1011+ /* if not enough room to the left or right of the current
1012+ * client determine the first non-overlapped y position
1013+ */
1014+ if (yb > yTmp && possible > yb)
1015+ possible = yb;
1016+
1017+ basket = yt - ch;
1018+ if (basket > yTmp && possible > basket)
1019+ possible = basket;
1020+ }
1021+ yTmp = possible;
1022+ }
1023+ }
1024+ while (overlap != NONE && overlap != H_WRONG && yTmp < placeable->workArea ().bottom ());
1025+
1026+ if (ch >= placeable->workArea ().height ())
1027+ yOptimal = placeable->workArea ().y ();
1028+
1029+ pos.setX (xOptimal + placeable->extents ().left);
1030+ pos.setY (yOptimal + placeable->extents ().top);
1031+ }
1032+ }
1033+}
1034
1035=== added directory 'plugins/place/src/smart/tests'
1036=== added file 'plugins/place/src/smart/tests/CMakeLists.txt'
1037--- plugins/place/src/smart/tests/CMakeLists.txt 1970-01-01 00:00:00 +0000
1038+++ plugins/place/src/smart/tests/CMakeLists.txt 2012-01-30 18:23:23 +0000
1039@@ -0,0 +1,14 @@
1040+include_directories(${CMAKE_CURRENT_SOURCE_DIR})
1041+
1042+add_executable (compiz_test_place_smart_on_screen
1043+ ${CMAKE_CURRENT_SOURCE_DIR}/offscreen/src/test-place-smart-on-screen.cpp)
1044+
1045+target_link_libraries (compiz_test_place_smart_on_screen
1046+ compiz_place_smart
1047+ ${GTEST_BOTH_LIBRARIES}
1048+ ${GMOCK_LIBRARY}
1049+ ${GMOCK_MAIN_LIBRARY}
1050+ ${CMAKE_THREAD_LIBS_INIT} # Link in pthread.
1051+ )
1052+
1053+add_test (compiz_place_smart_on_screen compiz_test_place_smart_on_screen)
1054
1055=== added directory 'plugins/place/src/smart/tests/offscreen'
1056=== added directory 'plugins/place/src/smart/tests/offscreen/src'
1057=== added file 'plugins/place/src/smart/tests/offscreen/src/test-place-smart-on-screen.cpp'
1058--- plugins/place/src/smart/tests/offscreen/src/test-place-smart-on-screen.cpp 1970-01-01 00:00:00 +0000
1059+++ plugins/place/src/smart/tests/offscreen/src/test-place-smart-on-screen.cpp 2012-01-30 18:23:23 +0000
1060@@ -0,0 +1,156 @@
1061+/*
1062+ * Copyright © 2011 Canonical Ltd.
1063+ *
1064+ * Permission to use, copy, modify, distribute, and sell this software
1065+ * and its documentation for any purpose is hereby granted without
1066+ * fee, provided that the above copyright notice appear in all copies
1067+ * and that both that copyright notice and this permission notice
1068+ * appear in supporting documentation, and that the name of
1069+ * Canonical Ltd. not be used in advertising or publicity pertaining to
1070+ * distribution of the software without specific, written prior permission.
1071+ * Canonical Ltd. makes no representations about the suitability of this
1072+ * software for any purpose. It is provided "as is" without express or
1073+ * implied warranty.
1074+ *
1075+ * CANONICAL, LTD. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
1076+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN
1077+ * NO EVENT SHALL CANONICAL, LTD. BE LIABLE FOR ANY SPECIAL, INDIRECT OR
1078+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
1079+ * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
1080+ * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
1081+ * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
1082+ *
1083+ * Authored by: Sam Spilsbury <sam.spilsbury@canonical.com>
1084+ */
1085+
1086+#include <gtest/gtest.h>
1087+#include <gmock/gmock.h>
1088+#include "smart.h"
1089+#include <iostream>
1090+#include <stdlib.h>
1091+#include <cstring>
1092+
1093+#include <boost/foreach.hpp>
1094+
1095+#ifndef foreach
1096+#define foreach BOOST_FOREACH
1097+#endif
1098+
1099+class CompPlaceSmartOffscreenTest :
1100+ public ::testing::Test
1101+{
1102+};
1103+
1104+class MockPlaceableObject :
1105+ public compiz::place::Placeable
1106+{
1107+ public:
1108+
1109+ MockPlaceableObject (const compiz::window::Geometry &geometry,
1110+ const compiz::window::extents::Extents &extents,
1111+ const std::vector <CompRect *> &availableWorkareas);
1112+
1113+ const compiz::window::Geometry & getGeometry () const { return mGeometry; }
1114+ const CompRect & getWorkarea () const { return *mWorkarea; }
1115+ const compiz::window::extents::Extents & getExtents () const { return mExtents; }
1116+ unsigned int getState () const { return 0; }
1117+
1118+ private:
1119+
1120+ compiz::window::Geometry mGeometry;
1121+ CompRect *mWorkarea;
1122+ compiz::window::extents::Extents mExtents;
1123+};
1124+
1125+MockPlaceableObject::MockPlaceableObject (const compiz::window::Geometry &geometry,
1126+ const compiz::window::extents::Extents &extents,
1127+ const std::vector <CompRect *> &availableWorkareas) :
1128+ compiz::place::Placeable::Placeable (),
1129+ mGeometry (geometry),
1130+ mExtents (extents)
1131+{
1132+ unsigned int areaMax = 0;
1133+ CompRect *running = availableWorkareas.front ();
1134+
1135+ /* Pick the workarea that we best intersect */
1136+ foreach (CompRect *rect, availableWorkareas)
1137+ {
1138+ unsigned int area = abs ((*rect & static_cast <CompRect> (geometry)).area ());
1139+
1140+ if (area > areaMax)
1141+ {
1142+ running = rect;
1143+ areaMax = area;
1144+ }
1145+ }
1146+
1147+ mWorkarea = running;
1148+}
1149+
1150+TEST_F (CompPlaceSmartOffscreenTest, TestOffscreenOne)
1151+{
1152+ CompRect wa1 (0, 24, 1680, 1026);
1153+ CompRect wa2 (1680, 24, 1024, 744);
1154+ compiz::place::Placeable::Vector v;
1155+
1156+ std::vector <CompRect *> workAreas;
1157+ workAreas.push_back (&wa1);
1158+ workAreas.push_back (&wa2);
1159+
1160+ /* Intersects 1 */
1161+ compiz::window::Geometry g (0, 0, 640, 480, 0);
1162+ compiz::window::extents::Extents e;
1163+
1164+ e.left = 10;
1165+ e.right = 10;
1166+ e.top = 10;
1167+ e.bottom = 10;
1168+
1169+ MockPlaceableObject p (g, e, workAreas);
1170+
1171+ CompPoint pos (g.x (), g.y ());
1172+
1173+ compiz::place::smart (&p, pos, v);
1174+
1175+ EXPECT_EQ (pos, CompPoint (10, 34));
1176+
1177+ /* Intersects 2 */
1178+
1179+ g = compiz::window::Geometry (1681, 0, 640, 480, 0);
1180+
1181+ p = MockPlaceableObject (g, e, workAreas);
1182+
1183+ compiz::place::smart (&p, pos, v);
1184+
1185+ EXPECT_EQ (pos, CompPoint (1690, 34));
1186+
1187+ /* Intersects 2 partially */
1188+
1189+ g = compiz::window::Geometry (1681, 500, 640, 480, 0);
1190+
1191+ p = MockPlaceableObject (g, e, workAreas);
1192+
1193+ compiz::place::smart (&p, pos, v);
1194+
1195+ EXPECT_EQ (pos, CompPoint (1690, 34));
1196+
1197+ /* Intersects 1 + 2 partially (1 more) */
1198+
1199+ g = compiz::window::Geometry (1300, 500, 640, 480, 0);
1200+
1201+ p = MockPlaceableObject (g, e, workAreas);
1202+
1203+ compiz::place::smart (&p, pos, v);
1204+
1205+ EXPECT_EQ (pos, CompPoint (10, 34));
1206+
1207+ /* Intersects 1 + 2 partially (2 more) */
1208+
1209+ g = compiz::window::Geometry (1600, 500, 640, 480, 0);
1210+
1211+ p = MockPlaceableObject (g, e, workAreas);
1212+
1213+ compiz::place::smart (&p, pos, v);
1214+
1215+ EXPECT_EQ (pos, CompPoint (1690, 34));
1216+}
1217
1218=== added file 'plugins/place/src/smart/tests/offscreen/src/test-place-smart-onscren.cpp'
1219--- plugins/place/src/smart/tests/offscreen/src/test-place-smart-onscren.cpp 1970-01-01 00:00:00 +0000
1220+++ plugins/place/src/smart/tests/offscreen/src/test-place-smart-onscren.cpp 2012-01-30 18:23:23 +0000
1221@@ -0,0 +1,107 @@
1222+/*
1223+ * Copyright © 2011 Canonical Ltd.
1224+ *
1225+ * Permission to use, copy, modify, distribute, and sell this software
1226+ * and its documentation for any purpose is hereby granted without
1227+ * fee, provided that the above copyright notice appear in all copies
1228+ * and that both that copyright notice and this permission notice
1229+ * appear in supporting documentation, and that the name of
1230+ * Canonical Ltd. not be used in advertising or publicity pertaining to
1231+ * distribution of the software without specific, written prior permission.
1232+ * Canonical Ltd. makes no representations about the suitability of this
1233+ * software for any purpose. It is provided "as is" without express or
1234+ * implied warranty.
1235+ *
1236+ * CANONICAL, LTD. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
1237+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN
1238+ * NO EVENT SHALL CANONICAL, LTD. BE LIABLE FOR ANY SPECIAL, INDIRECT OR
1239+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
1240+ * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
1241+ * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
1242+ * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
1243+ *
1244+ * Authored by: Sam Spilsbury <sam.spilsbury@canonical.com>
1245+ */
1246+
1247+#include <gtest/gtest.h>
1248+#include <gmock/gmock.h>
1249+#include "smart.h"
1250+#include <iostream>
1251+#include <stdlib.h>
1252+#include <cstring>
1253+
1254+class CompPlaceSmartOffscreenTest :
1255+ public ::testing::Test
1256+{
1257+};
1258+
1259+class MockPlaceableObject :
1260+ public compiz::place::Placeable
1261+{
1262+ public:
1263+
1264+ MockPlaceableObject (const compiz::window::Geometry &geometry,
1265+ const compiz::window::extents::Extents &extents,
1266+ const std::vector <CompRect *> &availableWorkareas);
1267+
1268+ const compiz::window::Geometry & getGeometry () const { return mGeometry; }
1269+ const CompRect & getWorkarea () const { return *mWorkarea; }
1270+ const compiz::window::extents::Extents & getExtents () const { return mExtents; }
1271+
1272+ private:
1273+
1274+ compiz::window::Geometry mGeometry;
1275+ CompRect *mWorkarea;
1276+ compiz::window::extents::Extents mExtents;
1277+}
1278+
1279+MockPlaceableObject::MockPlaceableObject (const compiz::window::Geometry &geometry,
1280+ const compiz::window::extents::Extents &extents,
1281+ const std::vector <CompRect *> &availableWorkareas) :
1282+ compiz::place::Placeable::Placeable (),
1283+ mGeometry (geometry),
1284+ mExtents (extents)
1285+{
1286+ unsigned int areaMax = 0;
1287+ CompRect *running = availableWorkareas.front ();
1288+
1289+ /* Pick the workarea that we best intersect */
1290+ foreach (CompRect *rect, availableWorkareas)
1291+ {
1292+ unsigned int area = abs ((*rect & static_cast <CompRect &> (geometry)).area ());
1293+
1294+ if (area > areaMax)
1295+ {
1296+ running = rect;
1297+ areaMax = area;
1298+ }
1299+ }
1300+
1301+ mWorkarea = running;
1302+}
1303+
1304+TEST_F (CompPlaceSmartOffscreenTest, TestOffscreenOne)
1305+{
1306+ CompRect wa1 (0, 24, 1680, 1026);
1307+ CompRect wa2 (1680, 24, 1024, 744);
1308+ compiz::place::Placeable::Vector v;
1309+
1310+ std::vector <CompRect *> workAreas;
1311+ workAreas.push_back (&wa1);
1312+ workAreas.push_back (&wa2);
1313+
1314+ /* Intersects 1 */
1315+ compiz::window::Geometry g (0, 0, 640, 480);
1316+ compiz::window::extents::Extents e (10, 10, 10, 10);
1317+
1318+ MockPlaceableObject p (g, e, workAreas);
1319+
1320+ CompPoint pos (g.x (), g.y ());
1321+
1322+ compiz::place::smart (p, pos, v);
1323+
1324+ std::cout << pos.x () << pos.y () << std::endl;
1325+
1326+ EXPECT_EQ (pos, CompPoint (0, 0));
1327+}
1328+

Subscribers

People subscribed via source and target branches