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