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
=== modified file 'plugins/place/CMakeLists.txt'
--- plugins/place/CMakeLists.txt 2012-01-20 06:27:10 +0000
+++ plugins/place/CMakeLists.txt 2012-01-30 18:23:23 +0000
@@ -4,7 +4,10 @@
44
5include_directories (${CMAKE_CURRENT_SOURCE_DIR}/src/constrain-to-workarea/include/)5include_directories (${CMAKE_CURRENT_SOURCE_DIR}/src/constrain-to-workarea/include/)
6include_directories (${CMAKE_CURRENT_SOURCE_DIR}/src/screen-size-change/include/)6include_directories (${CMAKE_CURRENT_SOURCE_DIR}/src/screen-size-change/include/)
7include_directories (${CMAKE_CURRENT_SOURCE_DIR}/src/smart/include/)
78
8add_subdirectory (src/constrain-to-workarea)9add_subdirectory (src/constrain-to-workarea)
9add_subdirectory (src/screen-size-change)10add_subdirectory (src/screen-size-change)
10compiz_plugin (place LIBRARIES compiz_place_constrain_to_workarea compiz_place_screen_size_change)11add_subdirectory (src/smart)
12
13compiz_plugin (place LIBRARIES compiz_place_constrain_to_workarea compiz_place_screen_size_change compiz_place_smart)
1114
=== modified file 'plugins/place/src/place.cpp'
--- plugins/place/src/place.cpp 2012-01-25 09:20:47 +0000
+++ plugins/place/src/place.cpp 2012-01-30 18:23:23 +0000
@@ -65,7 +65,6 @@
65 return l;65 return l;
66}66}
6767
68
69void68void
70PlaceScreen::doHandleScreenSizeChange (int newWidth,69PlaceScreen::doHandleScreenSizeChange (int newWidth,
71 int newHeight)70 int newHeight)
@@ -101,12 +100,31 @@
101 return screen->getWorkareaForOutput (screen->outputDeviceForGeometry (g));100 return screen->getWorkareaForOutput (screen->outputDeviceForGeometry (g));
102}101}
103102
103const CompRect &
104PlaceWindow::getWorkarea () const
105{
106 return getWorkarea (window->serverGeometry ());
107}
108
104const compiz::window::extents::Extents &109const compiz::window::extents::Extents &
105PlaceWindow::getExtents () const110PlaceWindow::getExtents () const
106{111{
107 return window->border ();112 return window->border ();
108}113}
109114
115unsigned int
116PlaceWindow::getState () const
117{
118 unsigned int state = 0;
119
120 if (window->state () & CompWindowStateAboveMask)
121 state |= compiz::place::WindowAbove;
122 if (window->state () & CompWindowStateBelowMask)
123 state |= compiz::place::WindowBelow;
124
125 return state;
126}
127
110void128void
111PlaceWindow::applyGeometry (compiz::window::Geometry &ng,129PlaceWindow::applyGeometry (compiz::window::Geometry &ng,
112 compiz::window::Geometry &og)130 compiz::window::Geometry &og)
@@ -224,42 +242,42 @@
224/* sort functions */242/* sort functions */
225243
226static bool244static bool
227compareLeftmost (CompWindow *a,245compareLeftmost (compiz::place::Placeable *a,
228 CompWindow *b)246 compiz::place::Placeable *b)
229{247{
230 int ax, bx;248 int ax, bx;
231249
232 ax = a->serverX () - a->border ().left;250 ax = a->geometry ().x () - a->extents ().left;
233 bx = b->serverX () - b->border ().left;251 bx = b->geometry ().x () - a->extents ().left;
234252
235 return (ax <= bx);253 return (ax <= bx);
236}254}
237255
238static bool256static bool
239compareTopmost (CompWindow *a,257compareTopmost (compiz::place::Placeable *a,
240 CompWindow *b)258 compiz::place::Placeable *b)
241{259{
242 int ay, by;260 int ay, by;
243261
244 ay = a->serverY () - a->border ().top;262 ay = a->geometry ().y () - a->extents ().top;
245 by = b->serverY () - b->border ().top;263 by = b->geometry ().y () - a->extents ().top;
246264
247 return (ay <= by);265 return (ay <= by);
248}266}
249267
250static bool268static bool
251compareNorthWestCorner (CompWindow *a,269compareNorthWestCorner (compiz::place::Placeable *a,
252 CompWindow *b)270 compiz::place::Placeable *b)
253{271{
254 int fromOriginA;272 int fromOriginA;
255 int fromOriginB;273 int fromOriginB;
256 int ax, ay, bx, by;274 int ax, ay, bx, by;
257275
258 ax = a->serverX () - a->border ().left;276 ax = a->geometry ().x () - a->extents ().left;
259 ay = a->serverY () - a->border ().top;277 bx = b->geometry ().x () - a->extents ().left;
260278
261 bx = b->serverX () - b->border ().left;279 ay = a->geometry ().y () - a->extents ().top;
262 by = b->serverY () - b->border ().top;280 by = b->geometry ().y () - a->extents ().top;
263281
264 /* probably there's a fast good-enough-guess we could use here. */282 /* probably there's a fast good-enough-guess we could use here. */
265 fromOriginA = sqrt (ax * ax + ay * ay);283 fromOriginA = sqrt (ax * ax + ay * ay);
@@ -585,6 +603,17 @@
585603
586 if (strategy == PlaceOnly || strategy == PlaceAndConstrain)604 if (strategy == PlaceOnly || strategy == PlaceAndConstrain)
587 {605 {
606 /* Construct list of placeables */
607 compiz::place::Placeable::Vector placeables;
608
609 foreach (CompWindow *w, screen->windows ())
610 {
611 PLACE_WINDOW (w);
612
613 if (windowIsPlaceRelevant (w))
614 placeables.push_back (static_cast <compiz::place::Placeable *> (pw));
615 }
616
588 switch (mode) {617 switch (mode) {
589 case PlaceOptions::ModeCascade:618 case PlaceOptions::ModeCascade:
590 placeCascade (workArea, pos);619 placeCascade (workArea, pos);
@@ -602,7 +631,7 @@
602 sendMaximizationRequest ();631 sendMaximizationRequest ();
603 break;632 break;
604 case PlaceOptions::ModeSmart:633 case PlaceOptions::ModeSmart:
605 placeSmart (workArea, pos);634 placeSmart (pos, placeables);
606 break;635 break;
607 }636 }
608637
@@ -650,7 +679,7 @@
650PlaceWindow::placeCascade (const CompRect &workArea,679PlaceWindow::placeCascade (const CompRect &workArea,
651 CompPoint &pos)680 CompPoint &pos)
652{681{
653 CompWindowList windows;682 Placeable::Vector placeables;
654683
655 /* Find windows that matter (not minimized, on same workspace684 /* Find windows that matter (not minimized, on same workspace
656 * as placed window, may be shaded - if shaded we pretend it isn't685 * as placed window, may be shaded - if shaded we pretend it isn't
@@ -671,15 +700,15 @@
671 w->serverY () + w->serverGeometry ().height () <= workArea.y ())700 w->serverY () + w->serverGeometry ().height () <= workArea.y ())
672 continue;701 continue;
673702
674 windows.push_back (w);703 placeables.push_back (static_cast <Placeable *> (PlaceWindow::get (w)));
675 }704 }
676705
677 if (!cascadeFindFirstFit (windows, workArea, pos))706 if (!cascadeFindFirstFit (placeables, workArea, pos))
678 {707 {
679 /* if the window wasn't placed at the origin of screen,708 /* if the window wasn't placed at the origin of screen,
680 * cascade it onto the current screen709 * cascade it onto the current screen
681 */710 */
682 cascadeFindNext (windows, workArea, pos);711 cascadeFindNext (placeables, workArea, pos);
683 }712 }
684}713}
685714
@@ -727,201 +756,13 @@
727 placeCentered (workArea, pos);756 placeCentered (workArea, pos);
728}757}
729758
730759using namespace compiz::place;
731/* overlap types */
732#define NONE 0
733#define H_WRONG -1
734#define W_WRONG -2
735760
736void761void
737PlaceWindow::placeSmart (const CompRect &workArea,762PlaceWindow::placeSmart (CompPoint &pos,
738 CompPoint &pos)763 const compiz::place::Placeable::Vector &placeables)
739{764{
740 /*765 compiz::place::smart (this, pos, placeables);
741 * SmartPlacement by Cristian Tibirna (tibirna@kde.org)
742 * adapted for kwm (16-19jan98) and for kwin (16Nov1999) using (with
743 * permission) ideas from fvwm, authored by
744 * Anthony Martin (amartin@engr.csulb.edu).
745 * Xinerama supported added by Balaji Ramani (balaji@yablibli.com)
746 * with ideas from xfce.
747 * adapted for Compiz by Bellegarde Cedric (gnumdk(at)gmail.com)
748 */
749 int overlap, minOverlap = 0;
750 int xOptimal, yOptimal;
751 int possible;
752
753 /* temp coords */
754 int cxl, cxr, cyt, cyb;
755 /* temp coords */
756 int xl, xr, yt, yb;
757 /* temp holder */
758 int basket;
759 /* CT lame flag. Don't like it. What else would do? */
760 bool firstPass = true;
761
762 /* get the maximum allowed windows space */
763 int xTmp = workArea.x ();
764 int yTmp = workArea.y ();
765
766 /* client gabarit */
767 int cw = window->serverWidth () - 1;
768 int ch = window->serverHeight () - 1;
769
770 xOptimal = xTmp;
771 yOptimal = yTmp;
772
773 /* loop over possible positions */
774 do
775 {
776 /* test if enough room in x and y directions */
777 if (yTmp + ch > workArea.bottom () && ch < workArea.height ())
778 overlap = H_WRONG; /* this throws the algorithm to an exit */
779 else if (xTmp + cw > workArea.right ())
780 overlap = W_WRONG;
781 else
782 {
783 overlap = NONE; /* initialize */
784
785 cxl = xTmp;
786 cxr = xTmp + cw;
787 cyt = yTmp;
788 cyb = yTmp + ch;
789
790 foreach (CompWindow *w, screen->windows ())
791 {
792 if (!windowIsPlaceRelevant (w))
793 continue;
794
795 xl = w->serverX () - w->border ().left;
796 yt = w->serverY () - w->border ().top;
797 xr = w->serverX () + w->serverWidth () +
798 w->border ().right +
799 w->serverGeometry ().border () * 2;
800 yb = w->serverY () + w->serverHeight () +
801 w->border ().bottom +
802 w->serverGeometry ().border () * 2;
803
804 /* if windows overlap, calc the overall overlapping */
805 if (cxl < xr && cxr > xl && cyt < yb && cyb > yt)
806 {
807 xl = MAX (cxl, xl);
808 xr = MIN (cxr, xr);
809 yt = MAX (cyt, yt);
810 yb = MIN (cyb, yb);
811
812 if (w->state () & CompWindowStateAboveMask)
813 overlap += 16 * (xr - xl) * (yb - yt);
814 else if (w->state () & CompWindowStateBelowMask)
815 overlap += 0;
816 else
817 overlap += (xr - xl) * (yb - yt);
818 }
819 }
820 }
821
822 /* CT first time we get no overlap we stop */
823 if (overlap == NONE)
824 {
825 xOptimal = xTmp;
826 yOptimal = yTmp;
827 break;
828 }
829
830 if (firstPass)
831 {
832 firstPass = false;
833 minOverlap = overlap;
834 }
835 /* CT save the best position and the minimum overlap up to now */
836 else if (overlap >= NONE && overlap < minOverlap)
837 {
838 minOverlap = overlap;
839 xOptimal = xTmp;
840 yOptimal = yTmp;
841 }
842
843 /* really need to loop? test if there's any overlap */
844 if (overlap > NONE)
845 {
846 possible = workArea.right ();
847
848 if (possible - cw > xTmp)
849 possible -= cw;
850
851 /* compare to the position of each client on the same desk */
852 foreach (CompWindow *w, screen->windows ())
853 {
854 if (!windowIsPlaceRelevant (w))
855 continue;
856
857 xl = w->serverX () - w->border ().left;
858 yt = w->serverY () - w->border ().top;
859 xr = w->serverX () + w->serverWidth () +
860 w->border ().right +
861 w->serverGeometry ().border () * 2;
862 yb = w->serverY () + w->serverHeight () +
863 w->border ().bottom +
864 w->serverGeometry ().border () * 2;
865
866 /* if not enough room above or under the current
867 * client determine the first non-overlapped x position
868 */
869 if (yTmp < yb && yt < ch + yTmp)
870 {
871 if (xr > xTmp && possible > xr)
872 possible = xr;
873
874 basket = xl - cw;
875 if (basket > xTmp && possible > basket)
876 possible = basket;
877 }
878 }
879 xTmp = possible;
880 }
881 /* else ==> not enough x dimension (overlap was wrong on horizontal) */
882 else if (overlap == W_WRONG)
883 {
884 xTmp = workArea.x ();
885 possible = workArea.bottom ();
886
887 if (possible - ch > yTmp)
888 possible -= ch;
889
890 /* test the position of each window on the desk */
891 foreach (CompWindow *w, screen->windows ())
892 {
893 if (!windowIsPlaceRelevant (w))
894 continue;
895
896 xl = w->serverX () - w->border ().left;
897 yt = w->serverY () - w->border ().top;
898 xr = w->serverX () + w->serverWidth () +
899 w->border ().right +
900 w->serverGeometry ().border () * 2;
901 yb = w->serverY () + w->serverHeight () +
902 w->border ().bottom +
903 w->serverGeometry ().border () * 2;
904
905 /* if not enough room to the left or right of the current
906 * client determine the first non-overlapped y position
907 */
908 if (yb > yTmp && possible > yb)
909 possible = yb;
910
911 basket = yt - ch;
912 if (basket > yTmp && possible > basket)
913 possible = basket;
914 }
915 yTmp = possible;
916 }
917 }
918 while (overlap != NONE && overlap != H_WRONG && yTmp < workArea.bottom ());
919
920 if (ch >= workArea.height ())
921 yOptimal = workArea.y ();
922
923 pos.setX (xOptimal + window->border ().left);
924 pos.setY (yOptimal + window->border ().top);
925}766}
926767
927static void768static void
@@ -945,32 +786,22 @@
945786
946static bool787static bool
947rectOverlapsWindow (const CompRect &rect,788rectOverlapsWindow (const CompRect &rect,
948 const CompWindowList &windows)789 const compiz::place::Placeable::Vector &placeables)
949{790{
950 CompRect dest;791 CompRect dest;
951792
952 foreach (CompWindow *other, windows)793 foreach (compiz::place::Placeable *other, placeables)
953 {794 {
954 CompRect intersect;795 CompRect intersect;
796 CompRect sbr = other->geometry ();
797 sbr.setLeft (sbr.left () - other->extents ().left);
798 sbr.setRight (sbr.right () + other->extents ().right);
799 sbr.setTop (sbr.top () - other->extents ().top);
800 sbr.setBottom (sbr.bottom () - other->extents ().bottom);
955801
956 switch (other->type ()) {802 intersect = rect & sbr;
957 case CompWindowTypeDockMask:803 if (!intersect.isEmpty ())
958 case CompWindowTypeSplashMask:804 return true;
959 case CompWindowTypeDesktopMask:
960 case CompWindowTypeDialogMask:
961 case CompWindowTypeModalDialogMask:
962 case CompWindowTypeFullscreenMask:
963 case CompWindowTypeUnknownMask:
964 break;
965 case CompWindowTypeNormalMask:
966 case CompWindowTypeUtilMask:
967 case CompWindowTypeToolbarMask:
968 case CompWindowTypeMenuMask:
969 intersect = rect & other->serverBorderRect ();
970 if (!intersect.isEmpty ())
971 return true;
972 break;
973 }
974 }805 }
975806
976 return false;807 return false;
@@ -985,7 +816,7 @@
985 * don't want to create a 1x1 Emacs.816 * don't want to create a 1x1 Emacs.
986 */817 */
987bool818bool
988PlaceWindow::cascadeFindFirstFit (const CompWindowList &windows,819PlaceWindow::cascadeFindFirstFit (const Placeable::Vector &placeables,
989 const CompRect &workArea,820 const CompRect &workArea,
990 CompPoint &pos)821 CompPoint &pos)
991{822{
@@ -997,49 +828,59 @@
997 * existing window in each of those cases.828 * existing window in each of those cases.
998 */829 */
999 bool retval = false;830 bool retval = false;
1000 CompWindowList belowSorted, rightSorted;831 Placeable::Vector belowSorted, rightSorted;
1001 CompRect rect;
1002832
1003 /* Below each window */833 /* Below each window */
1004 belowSorted = windows;834 belowSorted = placeables;
1005 belowSorted.sort (compareLeftmost);835 std::sort (belowSorted.begin (), belowSorted.end (), compareLeftmost);
1006 belowSorted.sort (compareTopmost);836 std::sort (belowSorted.begin (), belowSorted.end (), compareTopmost);
1007837
1008 /* To the right of each window */838 /* To the right of each window */
1009 rightSorted = windows;839 rightSorted = placeables;
1010 rightSorted.sort (compareTopmost);840 std::sort (belowSorted.begin (), belowSorted.end (), compareTopmost);
1011 rightSorted.sort (compareLeftmost);841 std::sort (belowSorted.begin (), belowSorted.end (), compareLeftmost);
1012842
1013 rect = window->serverBorderRect ();843 CompRect rect = this->geometry ();
844
845 rect.setLeft (rect.left () - this->extents ().left);
846 rect.setRight (rect.right () + this->extents ().right);
847 rect.setTop (rect.top () - this->extents ().top);
848 rect.setBottom (rect.bottom () - this->extents ().bottom);
849
1014 centerTileRectInArea (rect, workArea);850 centerTileRectInArea (rect, workArea);
1015851
1016 if (workArea.contains (rect) && !rectOverlapsWindow (rect, windows))852 if (workArea.contains (rect) && !rectOverlapsWindow (rect, placeables))
1017 {853 {
1018 pos.setX (rect.x () + window->border ().left);854 pos.setX (rect.x () + this->extents ().left);
1019 pos.setY (rect.y () + window->border ().top);855 pos.setY (rect.y () + this->extents ().top);
1020 retval = true;856 retval = true;
1021 }857 }
1022858
1023 if (!retval)859 if (!retval)
1024 {860 {
1025 /* try below each window */861 /* try below each window */
1026 foreach (CompWindow *w, belowSorted)862 foreach (Placeable *p, belowSorted)
1027 {863 {
1028 CompRect outerRect;864 CompRect outerRect;
1029865
1030 if (retval)866 if (retval)
1031 break;867 break;
1032868
1033 outerRect = w->serverBorderRect ();869 outerRect = p->geometry ();
1034870
1035 rect.setX (outerRect.x ());871 outerRect.setLeft (rect.left () - this->extents ().left);
1036 rect.setY (outerRect.bottom ());872 outerRect.setRight (rect.right () + this->extents ().right);
873 outerRect.setTop (rect.top () - this->extents ().top);
874 outerRect.setBottom (rect.bottom () - this->extents ().bottom);
875
876 outerRect.setX (outerRect.x ());
877 outerRect.setY (outerRect.bottom ());
1037878
1038 if (workArea.contains (rect) &&879 if (workArea.contains (rect) &&
1039 !rectOverlapsWindow (rect, belowSorted))880 !rectOverlapsWindow (rect, belowSorted))
1040 {881 {
1041 pos.setX (rect.x () + window->border ().left);882 pos.setX (rect.x () + this->extents ().left);
1042 pos.setY (rect.y () + window->border ().top);883 pos.setY (rect.y () + this->extents ().top);
1043 retval = true;884 retval = true;
1044 }885 }
1045 }886 }
@@ -1048,23 +889,28 @@
1048 if (!retval)889 if (!retval)
1049 {890 {
1050 /* try to the right of each window */891 /* try to the right of each window */
1051 foreach (CompWindow *w, rightSorted)892 foreach (Placeable *p, rightSorted)
1052 {893 {
1053 CompRect outerRect;894 CompRect outerRect;
1054895
1055 if (retval)896 if (retval)
1056 break;897 break;
1057898
1058 outerRect = w->serverBorderRect ();899 outerRect = p->geometry ();
1059900
1060 rect.setX (outerRect.right ());901 outerRect.setLeft (rect.left () - this->extents ().left);
1061 rect.setY (outerRect.y ());902 outerRect.setRight (rect.right () + this->extents ().right);
903 outerRect.setTop (rect.top () - this->extents ().top);
904 outerRect.setBottom (rect.bottom () - this->extents ().bottom);
905
906 outerRect.setX (outerRect.right ());
907 outerRect.setY (outerRect.y ());
1062908
1063 if (workArea.contains (rect) &&909 if (workArea.contains (rect) &&
1064 !rectOverlapsWindow (rect, rightSorted))910 !rectOverlapsWindow (rect, rightSorted))
1065 {911 {
1066 pos.setX (rect.x () + w->border ().left);912 pos.setX (rect.x () + this->extents ().left);
1067 pos.setY (rect.y () + w->border ().top);913 pos.setY (rect.y () + this->extents ().top);
1068 retval = true;914 retval = true;
1069 }915 }
1070 }916 }
@@ -1074,19 +920,19 @@
1074}920}
1075921
1076void922void
1077PlaceWindow::cascadeFindNext (const CompWindowList &windows,923PlaceWindow::cascadeFindNext (const Placeable::Vector &placeables,
1078 const CompRect &workArea,924 const CompRect &workArea,
1079 CompPoint &pos)925 CompPoint &pos)
1080{926{
1081 CompWindowList sorted;927 Placeable::Vector sorted;
1082 CompWindowList::iterator iter;928 Placeable::Vector::iterator iter;
1083 int cascadeX, cascadeY;929 int cascadeX, cascadeY;
1084 int xThreshold, yThreshold;930 int xThreshold, yThreshold;
1085 int winWidth, winHeight;931 int winWidth, winHeight;
1086 int cascadeStage;932 int cascadeStage;
1087933
1088 sorted = windows;934 sorted = placeables;
1089 sorted.sort (compareNorthWestCorner);935 std::sort (sorted.begin (), sorted.end (), compareNorthWestCorner);
1090936
1091 /* This is a "fuzzy" cascade algorithm.937 /* This is a "fuzzy" cascade algorithm.
1092 * For each window in the list, we find where we'd cascade a938 * For each window in the list, we find where we'd cascade a
@@ -1099,8 +945,8 @@
1099 */945 */
1100#define CASCADE_FUZZ 15946#define CASCADE_FUZZ 15
1101947
1102 xThreshold = MAX (window->border ().left, CASCADE_FUZZ);948 xThreshold = MAX (this->extents ().left, CASCADE_FUZZ);
1103 yThreshold = MAX (window->border ().top, CASCADE_FUZZ);949 yThreshold = MAX (this->extents ().top, CASCADE_FUZZ);
1104950
1105 /* Find furthest-SE origin of all workspaces.951 /* Find furthest-SE origin of all workspaces.
1106 * cascade_x, cascade_y are the target position952 * cascade_x, cascade_y are the target position
@@ -1118,12 +964,12 @@
1118 cascadeStage = 0;964 cascadeStage = 0;
1119 for (iter = sorted.begin (); iter != sorted.end (); iter++)965 for (iter = sorted.begin (); iter != sorted.end (); iter++)
1120 {966 {
1121 CompWindow *w = *iter;967 Placeable *p = *iter;
1122 int wx, wy;968 int wx, wy;
1123969
1124 /* we want frame position, not window position */970 /* we want frame position, not window position */
1125 wx = w->serverX () - w->border ().left;971 wx = p->geometry ().x () - p->extents ().left;
1126 wy = w->serverY () - w->border ().top;972 wy = p->geometry ().y () - p->extents ().top;
1127973
1128 if (abs (wx - cascadeX) < xThreshold &&974 if (abs (wx - cascadeX) < xThreshold &&
1129 abs (wy - cascadeY) < yThreshold)975 abs (wy - cascadeY) < yThreshold)
@@ -1132,8 +978,8 @@
1132 * point. The new window frame should go at the origin978 * point. The new window frame should go at the origin
1133 * of the client window we're stacking above.979 * of the client window we're stacking above.
1134 */980 */
1135 wx = cascadeX = w->serverX ();981 wx = cascadeX = p->geometry ().x ();
1136 wy = cascadeY = w->serverY ();982 wy = cascadeY = p->geometry ().y ();
1137983
1138 /* If we go off the screen, start over with a new cascade */984 /* If we go off the screen, start over with a new cascade */
1139 if ((cascadeX + winWidth > workArea.right ()) ||985 if ((cascadeX + winWidth > workArea.right ()) ||
@@ -1174,8 +1020,8 @@
1174 */1020 */
11751021
1176 /* Convert coords to position of window, not position of frame. */1022 /* Convert coords to position of window, not position of frame. */
1177 pos.setX (cascadeX + window->border ().left);1023 pos.setX (cascadeX + this->extents ().left);
1178 pos.setY (cascadeY + window->border ().top);1024 pos.setY (cascadeY + this->extents ().top);
1179}1025}
11801026
1181bool1027bool
11821028
=== modified file 'plugins/place/src/place.h'
--- plugins/place/src/place.h 2012-01-21 17:16:07 +0000
+++ plugins/place/src/place.h 2012-01-30 18:23:23 +0000
@@ -31,6 +31,7 @@
3131
32#include "place_options.h"32#include "place_options.h"
33#include "screen-size-change.h"33#include "screen-size-change.h"
34#include "smart.h"
3435
35namespace compiz36namespace compiz
36{37{
@@ -39,7 +40,6 @@
39 {40 {
4041
41 CompWindowList collectStrutWindows (const CompWindowList &allWindows);42 CompWindowList collectStrutWindows (const CompWindowList &allWindows);
42
43 }43 }
4444
45}45}
@@ -74,6 +74,7 @@
74class PlaceWindow :74class PlaceWindow :
75 public PluginClassHandler<PlaceWindow, CompWindow>,75 public PluginClassHandler<PlaceWindow, CompWindow>,
76 public compiz::place::ScreenSizeChangeObject,76 public compiz::place::ScreenSizeChangeObject,
77 public compiz::place::Placeable,
77 public WindowInterface78 public WindowInterface
78{79{
79 public:80 public:
@@ -101,8 +102,11 @@
101 const compiz::window::Geometry & getGeometry () const;102 const compiz::window::Geometry & getGeometry () const;
102 const CompPoint & getViewport () const;103 const CompPoint & getViewport () const;
103 const CompRect & getWorkarea (const compiz::window::Geometry &g) const;104 const CompRect & getWorkarea (const compiz::window::Geometry &g) const;
105 const CompRect & getWorkarea () const;
104 const compiz::window::extents::Extents & getExtents () const;106 const compiz::window::extents::Extents & getExtents () const;
105107
108 unsigned int getState () const;
109
106 private:110 private:
107 typedef enum {111 typedef enum {
108 NoPlacement = 0,112 NoPlacement = 0,
@@ -129,12 +133,12 @@
129 void placeCentered (const CompRect& workArea, CompPoint& pos);133 void placeCentered (const CompRect& workArea, CompPoint& pos);
130 void placeRandom (const CompRect& workArea, CompPoint& pos);134 void placeRandom (const CompRect& workArea, CompPoint& pos);
131 void placePointer (const CompRect& workArea, CompPoint& pos);135 void placePointer (const CompRect& workArea, CompPoint& pos);
132 void placeSmart (const CompRect& workArea, CompPoint& pos);136 void placeSmart (CompPoint& pos, const compiz::place::Placeable::Vector &);
133137
134 bool cascadeFindFirstFit (const CompWindowList& windows,138 bool cascadeFindFirstFit (const Placeable::Vector &placeabless,
135 const CompRect& workArea,139 const CompRect& workArea,
136 CompPoint &pos);140 CompPoint &pos);
137 void cascadeFindNext (const CompWindowList& windows,141 void cascadeFindNext (const Placeable::Vector &placeables,
138 const CompRect& workArea,142 const CompRect& workArea,
139 CompPoint &pos);143 CompPoint &pos);
140144
141145
=== added directory 'plugins/place/src/smart'
=== added file 'plugins/place/src/smart/CMakeLists.txt'
--- plugins/place/src/smart/CMakeLists.txt 1970-01-01 00:00:00 +0000
+++ plugins/place/src/smart/CMakeLists.txt 2012-01-30 18:23:23 +0000
@@ -0,0 +1,62 @@
1pkg_check_modules (
2 GLIBMM
3 REQUIRED
4 glibmm-2.4 glib-2.0
5)
6
7INCLUDE_DIRECTORIES (
8 ${CMAKE_CURRENT_SOURCE_DIR}/include
9 ${CMAKE_CURRENT_SOURCE_DIR}/src
10
11 ${compiz_SOURCE_DIR}/src/point/include
12 ${compiz_SOURCE_DIR}/src/rect/include
13 ${compiz_SOURCE_DIR}/src/window/geometry/include
14 ${compiz_SOURCE_DIR}/src/window/geometry-saver/include
15 ${compiz_SOURCE_DIR}/src/window/extents/include
16 ${compiz_SOURCE_DIR}/include
17
18 ${Boost_INCLUDE_DIRS}
19
20 ${GLIBMM_INCLUDE_DIRS}
21)
22
23LINK_DIRECTORIES (${GLIBMM_LIBRARY_DIRS})
24
25SET (
26 PUBLIC_HEADERS
27)
28
29SET (
30 PRIVATE_HEADERS
31 ${CMAKE_CURRENT_SOURCE_DIR}/include/smart.h
32)
33
34SET(
35 SRCS
36 ${CMAKE_CURRENT_SOURCE_DIR}/src/smart.cpp
37)
38
39ADD_LIBRARY(
40 compiz_place_smart STATIC
41
42 ${SRCS}
43
44 ${PUBLIC_HEADERS}
45 ${PRIVATE_HEADERS}
46)
47
48if (COMPIZ_BUILD_TESTING)
49ADD_SUBDIRECTORY( ${CMAKE_CURRENT_SOURCE_DIR}/tests )
50endif (COMPIZ_BUILD_TESTING)
51
52SET_TARGET_PROPERTIES(
53 compiz_place_smart PROPERTIES
54 PUBLIC_HEADER "${PUBLIC_HEADERS}"
55)
56
57TARGET_LINK_LIBRARIES(
58 compiz_place_smart
59
60 compiz_core
61 ${GLIBMM_LIBRARIES}
62)
063
=== added directory 'plugins/place/src/smart/include'
=== added file 'plugins/place/src/smart/include/smart.h'
--- plugins/place/src/smart/include/smart.h 1970-01-01 00:00:00 +0000
+++ plugins/place/src/smart/include/smart.h 2012-01-30 18:23:23 +0000
@@ -0,0 +1,73 @@
1/*
2 * Copyright (C) 2001 Havoc Pennington
3 * Copyright (C) 2002, 2003 Red Hat, Inc.
4 * Copyright (C) 2003 Rob Adams
5 * Copyright (C) 2005 Novell, Inc.
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License as
9 * published by the Free Software Foundation; either version 2 of the
10 * License, or (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
20 * 02111-1307, USA.
21 */
22
23#ifndef _COMPIZ_PLACE_SMART_H
24#define _COMPIZ_PLACE_SMART_H
25
26#include <vector>
27#include <core/rect.h>
28#include <core/windowgeometry.h>
29#include <core/windowextents.h>
30#include <core/size.h>
31#include <core/point.h>
32
33namespace compiz
34{
35 namespace place
36 {
37
38 extern const unsigned int WindowAbove;
39 extern const unsigned int WindowBelow;
40
41 class Placeable
42 {
43 public:
44
45 typedef std::vector <Placeable *> Vector;
46
47 const compiz::window::Geometry & geometry () const { return getGeometry (); }
48 const compiz::window::extents::Extents & extents () const { return getExtents (); }
49 const CompRect & workArea () const { return getWorkarea (); }
50
51 unsigned int state () const { return getState (); }
52
53 virtual ~Placeable () = 0;
54
55 protected:
56
57 virtual const compiz::window::Geometry & getGeometry () const = 0;
58 virtual const compiz::window::extents::Extents & getExtents () const = 0;
59 virtual const CompRect & getWorkarea () const = 0;
60
61 virtual unsigned int getState () const = 0;
62
63 Placeable ();
64 };
65
66 void smart (Placeable *placeable,
67 CompPoint &pos,
68 const compiz::place::Placeable::Vector &placeables);
69
70 }
71}
72
73#endif
074
=== added directory 'plugins/place/src/smart/src'
=== added file 'plugins/place/src/smart/src/smart.cpp'
--- plugins/place/src/smart/src/smart.cpp 1970-01-01 00:00:00 +0000
+++ plugins/place/src/smart/src/smart.cpp 2012-01-30 18:23:23 +0000
@@ -0,0 +1,199 @@
1#include "smart.h"
2#include <boost/foreach.hpp>
3
4#ifndef foreach
5#define foreach BOOST_FOREACH
6#endif
7
8/* overlap types */
9#define NONE 0
10#define H_WRONG -1
11#define W_WRONG -2
12
13namespace compiz
14{
15 namespace place
16 {
17 const unsigned int WindowAbove = 1 << 0;
18 const unsigned int WindowBelow = 1 << 1;
19
20 Placeable::Placeable ()
21 {
22 }
23
24 Placeable::~Placeable ()
25 {
26 }
27
28 void smart (Placeable *placeable,
29 CompPoint &pos,
30 const compiz::place::Placeable::Vector &placeables)
31 {
32 /*
33 * SmartPlacement by Cristian Tibirna (tibirna@kde.org)
34 * adapted for kwm (16-19jan98) and for kwin (16Nov1999) using (with
35 * permission) ideas from fvwm, authored by
36 * Anthony Martin (amartin@engr.csulb.edu).
37 * Xinerama supported added by Balaji Ramani (balaji@yablibli.com)
38 * with ideas from xfce.
39 * adapted for Compiz by Bellegarde Cedric (gnumdk(at)gmail.com)
40 */
41 int overlap = 0, minOverlap = 0;
42
43 /* temp holder */
44 int basket = 0;
45 /* CT lame flag. Don't like it. What else would do? */
46 bool firstPass = true;
47
48 /* get the maximum allowed windows space */
49 int xTmp = placeable->workArea ().x ();
50 int yTmp = placeable->workArea ().y ();
51
52 /* client gabarit */
53 int cw = placeable->geometry ().width () - 1;
54 int ch = placeable->geometry ().height () - 1;
55
56 int xOptimal = xTmp;
57 int yOptimal = yTmp;
58
59 /* loop over possible positions */
60 do
61 {
62 /* test if enough room in x and y directions */
63 if (yTmp + ch > placeable->workArea ().bottom () && ch < placeable->workArea ().height ())
64 overlap = H_WRONG; /* this throws the algorithm to an exit */
65 else if (xTmp + cw > placeable->workArea ().right ())
66 overlap = W_WRONG;
67 else
68 {
69 overlap = NONE; /* initialize */
70
71 int cxl = xTmp;
72 int cxr = xTmp + cw;
73 int cyt = yTmp;
74 int cyb = yTmp + ch;
75
76 foreach (Placeable *p, placeables)
77 {
78 const compiz::window::Geometry &otherGeometry = p->geometry ();
79 const compiz::window::extents::Extents &otherExtents = p->extents ();
80
81 int xl = otherGeometry.x () - otherExtents.left;
82 int yt = otherGeometry.y () - otherExtents.top;
83 int xr = otherGeometry.x2 () + otherExtents.right + otherGeometry.border () * 2;
84 int yb = otherGeometry.y2 () + otherExtents.bottom + otherGeometry.border () * 2;
85
86 /* if windows overlap, calc the overall overlapping */
87 if (cxl < xr && cxr > xl && cyt < yb && cyb > yt)
88 {
89 xl = MAX (cxl, xl);
90 xr = MIN (cxr, xr);
91 yt = MAX (cyt, yt);
92 yb = MIN (cyb, yb);
93
94 if (p->state () & compiz::place::WindowAbove)
95 overlap += 16 * (xr - xl) * (yb - yt);
96 else if (p->state () & compiz::place::WindowBelow)
97 overlap += 0;
98 else
99 overlap += (xr - xl) * (yb - yt);
100 }
101 }
102 }
103
104 /* CT first time we get no overlap we stop */
105 if (overlap == NONE)
106 {
107 xOptimal = xTmp;
108 yOptimal = yTmp;
109 break;
110 }
111
112 if (firstPass)
113 {
114 firstPass = false;
115 minOverlap = overlap;
116 }
117 /* CT save the best position and the minimum overlap up to now */
118 else if (overlap >= NONE && overlap < minOverlap)
119 {
120 minOverlap = overlap;
121 xOptimal = xTmp;
122 yOptimal = yTmp;
123 }
124
125 /* really need to loop? test if there's any overlap */
126 if (overlap > NONE)
127 {
128 int possible = placeable->workArea ().right ();
129
130 if (possible - cw > xTmp)
131 possible -= cw;
132
133 /* compare to the position of each client on the same desk */
134 foreach (Placeable *p, placeables)
135 {
136 const compiz::window::Geometry &otherGeometry = p->geometry ();
137 const compiz::window::extents::Extents &otherExtents = p->extents ();
138
139 int xl = otherGeometry.x () - otherExtents.left;
140 int yt = otherGeometry.y () - otherExtents.top;
141 int xr = otherGeometry.x2 () + otherExtents.right + otherGeometry.border () * 2;
142 int yb = otherGeometry.y2 () + otherExtents.bottom + otherGeometry.border () * 2;
143
144 /* if not enough room above or under the current
145 * client determine the first non-overlapped x position
146 */
147 if (yTmp < yb && yt < ch + yTmp)
148 {
149 if (xr > xTmp && possible > xr)
150 possible = xr;
151
152 basket = xl - cw;
153 if (basket > xTmp && possible > basket)
154 possible = basket;
155 }
156 }
157 xTmp = possible;
158 }
159 /* else ==> not enough x dimension (overlap was wrong on horizontal) */
160 else if (overlap == W_WRONG)
161 {
162 xTmp = placeable->workArea ().x ();
163 int possible = placeable->workArea ().bottom ();
164
165 if (possible - ch > yTmp)
166 possible -= ch;
167
168 /* test the position of each window on the desk */
169 foreach (Placeable *p, placeables)
170 {
171 const compiz::window::Geometry &otherGeometry = p->geometry ();
172 const compiz::window::extents::Extents &otherExtents = p->extents ();
173
174 int yt = otherGeometry.y () - otherExtents.top;
175 int yb = otherGeometry.y2 () + otherExtents.bottom + otherGeometry.border () * 2;
176
177 /* if not enough room to the left or right of the current
178 * client determine the first non-overlapped y position
179 */
180 if (yb > yTmp && possible > yb)
181 possible = yb;
182
183 basket = yt - ch;
184 if (basket > yTmp && possible > basket)
185 possible = basket;
186 }
187 yTmp = possible;
188 }
189 }
190 while (overlap != NONE && overlap != H_WRONG && yTmp < placeable->workArea ().bottom ());
191
192 if (ch >= placeable->workArea ().height ())
193 yOptimal = placeable->workArea ().y ();
194
195 pos.setX (xOptimal + placeable->extents ().left);
196 pos.setY (yOptimal + placeable->extents ().top);
197 }
198 }
199}
0200
=== added directory 'plugins/place/src/smart/tests'
=== added file 'plugins/place/src/smart/tests/CMakeLists.txt'
--- plugins/place/src/smart/tests/CMakeLists.txt 1970-01-01 00:00:00 +0000
+++ plugins/place/src/smart/tests/CMakeLists.txt 2012-01-30 18:23:23 +0000
@@ -0,0 +1,14 @@
1include_directories(${CMAKE_CURRENT_SOURCE_DIR})
2
3add_executable (compiz_test_place_smart_on_screen
4 ${CMAKE_CURRENT_SOURCE_DIR}/offscreen/src/test-place-smart-on-screen.cpp)
5
6target_link_libraries (compiz_test_place_smart_on_screen
7 compiz_place_smart
8 ${GTEST_BOTH_LIBRARIES}
9 ${GMOCK_LIBRARY}
10 ${GMOCK_MAIN_LIBRARY}
11 ${CMAKE_THREAD_LIBS_INIT} # Link in pthread.
12 )
13
14add_test (compiz_place_smart_on_screen compiz_test_place_smart_on_screen)
015
=== added directory 'plugins/place/src/smart/tests/offscreen'
=== added directory 'plugins/place/src/smart/tests/offscreen/src'
=== added file 'plugins/place/src/smart/tests/offscreen/src/test-place-smart-on-screen.cpp'
--- plugins/place/src/smart/tests/offscreen/src/test-place-smart-on-screen.cpp 1970-01-01 00:00:00 +0000
+++ plugins/place/src/smart/tests/offscreen/src/test-place-smart-on-screen.cpp 2012-01-30 18:23:23 +0000
@@ -0,0 +1,156 @@
1/*
2 * Copyright © 2011 Canonical Ltd.
3 *
4 * Permission to use, copy, modify, distribute, and sell this software
5 * and its documentation for any purpose is hereby granted without
6 * fee, provided that the above copyright notice appear in all copies
7 * and that both that copyright notice and this permission notice
8 * appear in supporting documentation, and that the name of
9 * Canonical Ltd. not be used in advertising or publicity pertaining to
10 * distribution of the software without specific, written prior permission.
11 * Canonical Ltd. makes no representations about the suitability of this
12 * software for any purpose. It is provided "as is" without express or
13 * implied warranty.
14 *
15 * CANONICAL, LTD. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
16 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN
17 * NO EVENT SHALL CANONICAL, LTD. BE LIABLE FOR ANY SPECIAL, INDIRECT OR
18 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
19 * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
20 * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
21 * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
22 *
23 * Authored by: Sam Spilsbury <sam.spilsbury@canonical.com>
24 */
25
26#include <gtest/gtest.h>
27#include <gmock/gmock.h>
28#include "smart.h"
29#include <iostream>
30#include <stdlib.h>
31#include <cstring>
32
33#include <boost/foreach.hpp>
34
35#ifndef foreach
36#define foreach BOOST_FOREACH
37#endif
38
39class CompPlaceSmartOffscreenTest :
40 public ::testing::Test
41{
42};
43
44class MockPlaceableObject :
45 public compiz::place::Placeable
46{
47 public:
48
49 MockPlaceableObject (const compiz::window::Geometry &geometry,
50 const compiz::window::extents::Extents &extents,
51 const std::vector <CompRect *> &availableWorkareas);
52
53 const compiz::window::Geometry & getGeometry () const { return mGeometry; }
54 const CompRect & getWorkarea () const { return *mWorkarea; }
55 const compiz::window::extents::Extents & getExtents () const { return mExtents; }
56 unsigned int getState () const { return 0; }
57
58 private:
59
60 compiz::window::Geometry mGeometry;
61 CompRect *mWorkarea;
62 compiz::window::extents::Extents mExtents;
63};
64
65MockPlaceableObject::MockPlaceableObject (const compiz::window::Geometry &geometry,
66 const compiz::window::extents::Extents &extents,
67 const std::vector <CompRect *> &availableWorkareas) :
68 compiz::place::Placeable::Placeable (),
69 mGeometry (geometry),
70 mExtents (extents)
71{
72 unsigned int areaMax = 0;
73 CompRect *running = availableWorkareas.front ();
74
75 /* Pick the workarea that we best intersect */
76 foreach (CompRect *rect, availableWorkareas)
77 {
78 unsigned int area = abs ((*rect & static_cast <CompRect> (geometry)).area ());
79
80 if (area > areaMax)
81 {
82 running = rect;
83 areaMax = area;
84 }
85 }
86
87 mWorkarea = running;
88}
89
90TEST_F (CompPlaceSmartOffscreenTest, TestOffscreenOne)
91{
92 CompRect wa1 (0, 24, 1680, 1026);
93 CompRect wa2 (1680, 24, 1024, 744);
94 compiz::place::Placeable::Vector v;
95
96 std::vector <CompRect *> workAreas;
97 workAreas.push_back (&wa1);
98 workAreas.push_back (&wa2);
99
100 /* Intersects 1 */
101 compiz::window::Geometry g (0, 0, 640, 480, 0);
102 compiz::window::extents::Extents e;
103
104 e.left = 10;
105 e.right = 10;
106 e.top = 10;
107 e.bottom = 10;
108
109 MockPlaceableObject p (g, e, workAreas);
110
111 CompPoint pos (g.x (), g.y ());
112
113 compiz::place::smart (&p, pos, v);
114
115 EXPECT_EQ (pos, CompPoint (10, 34));
116
117 /* Intersects 2 */
118
119 g = compiz::window::Geometry (1681, 0, 640, 480, 0);
120
121 p = MockPlaceableObject (g, e, workAreas);
122
123 compiz::place::smart (&p, pos, v);
124
125 EXPECT_EQ (pos, CompPoint (1690, 34));
126
127 /* Intersects 2 partially */
128
129 g = compiz::window::Geometry (1681, 500, 640, 480, 0);
130
131 p = MockPlaceableObject (g, e, workAreas);
132
133 compiz::place::smart (&p, pos, v);
134
135 EXPECT_EQ (pos, CompPoint (1690, 34));
136
137 /* Intersects 1 + 2 partially (1 more) */
138
139 g = compiz::window::Geometry (1300, 500, 640, 480, 0);
140
141 p = MockPlaceableObject (g, e, workAreas);
142
143 compiz::place::smart (&p, pos, v);
144
145 EXPECT_EQ (pos, CompPoint (10, 34));
146
147 /* Intersects 1 + 2 partially (2 more) */
148
149 g = compiz::window::Geometry (1600, 500, 640, 480, 0);
150
151 p = MockPlaceableObject (g, e, workAreas);
152
153 compiz::place::smart (&p, pos, v);
154
155 EXPECT_EQ (pos, CompPoint (1690, 34));
156}
0157
=== added file 'plugins/place/src/smart/tests/offscreen/src/test-place-smart-onscren.cpp'
--- plugins/place/src/smart/tests/offscreen/src/test-place-smart-onscren.cpp 1970-01-01 00:00:00 +0000
+++ plugins/place/src/smart/tests/offscreen/src/test-place-smart-onscren.cpp 2012-01-30 18:23:23 +0000
@@ -0,0 +1,107 @@
1/*
2 * Copyright © 2011 Canonical Ltd.
3 *
4 * Permission to use, copy, modify, distribute, and sell this software
5 * and its documentation for any purpose is hereby granted without
6 * fee, provided that the above copyright notice appear in all copies
7 * and that both that copyright notice and this permission notice
8 * appear in supporting documentation, and that the name of
9 * Canonical Ltd. not be used in advertising or publicity pertaining to
10 * distribution of the software without specific, written prior permission.
11 * Canonical Ltd. makes no representations about the suitability of this
12 * software for any purpose. It is provided "as is" without express or
13 * implied warranty.
14 *
15 * CANONICAL, LTD. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
16 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN
17 * NO EVENT SHALL CANONICAL, LTD. BE LIABLE FOR ANY SPECIAL, INDIRECT OR
18 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
19 * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
20 * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
21 * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
22 *
23 * Authored by: Sam Spilsbury <sam.spilsbury@canonical.com>
24 */
25
26#include <gtest/gtest.h>
27#include <gmock/gmock.h>
28#include "smart.h"
29#include <iostream>
30#include <stdlib.h>
31#include <cstring>
32
33class CompPlaceSmartOffscreenTest :
34 public ::testing::Test
35{
36};
37
38class MockPlaceableObject :
39 public compiz::place::Placeable
40{
41 public:
42
43 MockPlaceableObject (const compiz::window::Geometry &geometry,
44 const compiz::window::extents::Extents &extents,
45 const std::vector <CompRect *> &availableWorkareas);
46
47 const compiz::window::Geometry & getGeometry () const { return mGeometry; }
48 const CompRect & getWorkarea () const { return *mWorkarea; }
49 const compiz::window::extents::Extents & getExtents () const { return mExtents; }
50
51 private:
52
53 compiz::window::Geometry mGeometry;
54 CompRect *mWorkarea;
55 compiz::window::extents::Extents mExtents;
56}
57
58MockPlaceableObject::MockPlaceableObject (const compiz::window::Geometry &geometry,
59 const compiz::window::extents::Extents &extents,
60 const std::vector <CompRect *> &availableWorkareas) :
61 compiz::place::Placeable::Placeable (),
62 mGeometry (geometry),
63 mExtents (extents)
64{
65 unsigned int areaMax = 0;
66 CompRect *running = availableWorkareas.front ();
67
68 /* Pick the workarea that we best intersect */
69 foreach (CompRect *rect, availableWorkareas)
70 {
71 unsigned int area = abs ((*rect & static_cast <CompRect &> (geometry)).area ());
72
73 if (area > areaMax)
74 {
75 running = rect;
76 areaMax = area;
77 }
78 }
79
80 mWorkarea = running;
81}
82
83TEST_F (CompPlaceSmartOffscreenTest, TestOffscreenOne)
84{
85 CompRect wa1 (0, 24, 1680, 1026);
86 CompRect wa2 (1680, 24, 1024, 744);
87 compiz::place::Placeable::Vector v;
88
89 std::vector <CompRect *> workAreas;
90 workAreas.push_back (&wa1);
91 workAreas.push_back (&wa2);
92
93 /* Intersects 1 */
94 compiz::window::Geometry g (0, 0, 640, 480);
95 compiz::window::extents::Extents e (10, 10, 10, 10);
96
97 MockPlaceableObject p (g, e, workAreas);
98
99 CompPoint pos (g.x (), g.y ());
100
101 compiz::place::smart (p, pos, v);
102
103 std::cout << pos.x () << pos.y () << std::endl;
104
105 EXPECT_EQ (pos, CompPoint (0, 0));
106}
107

Subscribers

People subscribed via source and target branches