diff options
author | fluxgen <fluxgen> | 2006-02-19 11:11:22 (GMT) |
---|---|---|
committer | fluxgen <fluxgen> | 2006-02-19 11:11:22 (GMT) |
commit | b772fd969f039f7683d2bd666b7573eeb9d468e3 (patch) | |
tree | 3d1ae639f5f314f9f55005aa3dad912524afa181 | |
parent | d099e7673a51f76b2e6f54484152901288f90ae2 (diff) | |
download | fluxbox-b772fd969f039f7683d2bd666b7573eeb9d468e3.zip fluxbox-b772fd969f039f7683d2bd666b7573eeb9d468e3.tar.bz2 |
moved placement strategies to different PlacementStrategy classes
-rw-r--r-- | src/CascadePlacement.cc | 75 | ||||
-rw-r--r-- | src/CascadePlacement.hh | 45 | ||||
-rw-r--r-- | src/ColSmartPlacement.cc | 136 | ||||
-rw-r--r-- | src/ColSmartPlacement.hh | 36 | ||||
-rw-r--r-- | src/Makefile.am | 5 | ||||
-rw-r--r-- | src/RowSmartPlacement.cc | 155 | ||||
-rw-r--r-- | src/RowSmartPlacement.hh | 37 | ||||
-rw-r--r-- | src/Screen.cc | 9 | ||||
-rw-r--r-- | src/Screen.hh | 23 | ||||
-rw-r--r-- | src/ScreenPlacement.cc | 207 | ||||
-rw-r--r-- | src/ScreenPlacement.hh | 77 | ||||
-rw-r--r-- | src/ScreenResources.cc | 76 | ||||
-rw-r--r-- | src/UnderMousePlacement.cc | 75 | ||||
-rw-r--r-- | src/UnderMousePlacement.hh | 36 | ||||
-rw-r--r-- | src/Workspace.cc | 279 |
15 files changed, 905 insertions, 366 deletions
diff --git a/src/CascadePlacement.cc b/src/CascadePlacement.cc new file mode 100644 index 0000000..4cad9d0 --- /dev/null +++ b/src/CascadePlacement.cc | |||
@@ -0,0 +1,75 @@ | |||
1 | // CascadePlacement.cc | ||
2 | // Copyright (c) 2006 Fluxbox Team (fluxgen at fluxbox dot org) | ||
3 | // | ||
4 | // Permission is hereby granted, free of charge, to any person obtaining a | ||
5 | // copy of this software and associated documentation files (the "Software"), | ||
6 | // to deal in the Software without restriction, including without limitation | ||
7 | // the rights to use, copy, modify, merge, publish, distribute, sublicense, | ||
8 | // and/or sell copies of the Software, and to permit persons to whom the | ||
9 | // Software is furnished to do so, subject to the following conditions: | ||
10 | // | ||
11 | // The above copyright notice and this permission notice shall be included in | ||
12 | // all copies or substantial portions of the Software. | ||
13 | // | ||
14 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
15 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
16 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | ||
17 | // THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
18 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING | ||
19 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER | ||
20 | // DEALINGS IN THE SOFTWARE. | ||
21 | |||
22 | // $Id$ | ||
23 | |||
24 | #include "CascadePlacement.hh" | ||
25 | |||
26 | #include "Window.hh" | ||
27 | #include "Screen.hh" | ||
28 | |||
29 | CascadePlacement::CascadePlacement(const BScreen &screen) { | ||
30 | // +1 ? | ||
31 | m_cascade_x = new int[screen.numHeads() + 1]; | ||
32 | m_cascade_y = new int[screen.numHeads() + 1]; | ||
33 | for (int i=0; i < screen.numHeads() + 1; i++) { | ||
34 | m_cascade_x[i] = 32 + screen.getHeadX(i); | ||
35 | m_cascade_y[i] = 32 + screen.getHeadY(i); | ||
36 | } | ||
37 | |||
38 | } | ||
39 | |||
40 | CascadePlacement::~CascadePlacement() { | ||
41 | delete [] m_cascade_x; | ||
42 | delete [] m_cascade_y; | ||
43 | } | ||
44 | |||
45 | bool CascadePlacement::placeWindow(const std::vector<FluxboxWindow *> &windowlist, | ||
46 | const FluxboxWindow &win, | ||
47 | int &place_x, int &place_y) { | ||
48 | |||
49 | int head = (signed) win.screen().getCurrHead(); | ||
50 | int head_left = (signed) win.screen().maxLeft(head); | ||
51 | int head_right = (signed) win.screen().maxRight(head); | ||
52 | int head_top = (signed) win.screen().maxTop(head); | ||
53 | int head_bot = (signed) win.screen().maxBottom(head); | ||
54 | |||
55 | if ((m_cascade_x[head] > ((head_left + head_right) / 2)) || | ||
56 | (m_cascade_y[head] > ((head_top + head_bot) / 2))) { | ||
57 | m_cascade_x[head] = head_left + 32; | ||
58 | m_cascade_y[head] = head_top + 32; | ||
59 | } | ||
60 | |||
61 | place_x = m_cascade_x[head]; | ||
62 | place_y = m_cascade_y[head]; | ||
63 | |||
64 | // just one borderwidth, so they can share a borderwidth (looks better) | ||
65 | int titlebar_height = | ||
66 | win.titlebarHeight() + win.fbWindow().borderWidth(); | ||
67 | if (titlebar_height < 4) // make sure it is not insignificant | ||
68 | titlebar_height = 32; | ||
69 | |||
70 | m_cascade_x[head] += titlebar_height; | ||
71 | m_cascade_y[head] += titlebar_height; | ||
72 | |||
73 | return true; | ||
74 | } | ||
75 | |||
diff --git a/src/CascadePlacement.hh b/src/CascadePlacement.hh new file mode 100644 index 0000000..6fde194 --- /dev/null +++ b/src/CascadePlacement.hh | |||
@@ -0,0 +1,45 @@ | |||
1 | // CascadePlacement.hh | ||
2 | // Copyright (c) 2006 Fluxbox Team (fluxgen at fluxbox dot org) | ||
3 | // | ||
4 | // Permission is hereby granted, free of charge, to any person obtaining a | ||
5 | // copy of this software and associated documentation files (the "Software"), | ||
6 | // to deal in the Software without restriction, including without limitation | ||
7 | // the rights to use, copy, modify, merge, publish, distribute, sublicense, | ||
8 | // and/or sell copies of the Software, and to permit persons to whom the | ||
9 | // Software is furnished to do so, subject to the following conditions: | ||
10 | // | ||
11 | // The above copyright notice and this permission notice shall be included in | ||
12 | // all copies or substantial portions of the Software. | ||
13 | // | ||
14 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
15 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
16 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | ||
17 | // THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
18 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING | ||
19 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER | ||
20 | // DEALINGS IN THE SOFTWARE. | ||
21 | |||
22 | // $Id$ | ||
23 | |||
24 | #ifndef CASCADEPLACEMENT_HH | ||
25 | #define CASCADEPLACEMENT_HH | ||
26 | |||
27 | #include "PlacementStrategy.hh" | ||
28 | #include "FbTk/NotCopyable.hh" | ||
29 | |||
30 | class BScreen; | ||
31 | |||
32 | class CascadePlacement: public PlacementStrategy, | ||
33 | private FbTk::NotCopyable { | ||
34 | public: | ||
35 | explicit CascadePlacement(const BScreen &screen); | ||
36 | ~CascadePlacement(); | ||
37 | bool placeWindow(const std::vector<FluxboxWindow *> &windowlist, | ||
38 | const FluxboxWindow &window, | ||
39 | int &place_x, int &place_y); | ||
40 | private: | ||
41 | int *m_cascade_x; ///< need a cascade for each head (Xinerama) | ||
42 | int *m_cascade_y; ///< need a cascade for each head (Xinerama) | ||
43 | }; | ||
44 | |||
45 | #endif // CASCADEPLACEMENT_HH | ||
diff --git a/src/ColSmartPlacement.cc b/src/ColSmartPlacement.cc new file mode 100644 index 0000000..abb74d7 --- /dev/null +++ b/src/ColSmartPlacement.cc | |||
@@ -0,0 +1,136 @@ | |||
1 | // ColSmartPlacement.cc | ||
2 | // Copyright (c) 2006 Fluxbox Team (fluxgen at fluxbox dot org) | ||
3 | // | ||
4 | // Permission is hereby granted, free of charge, to any person obtaining a | ||
5 | // copy of this software and associated documentation files (the "Software"), | ||
6 | // to deal in the Software without restriction, including without limitation | ||
7 | // the rights to use, copy, modify, merge, publish, distribute, sublicense, | ||
8 | // and/or sell copies of the Software, and to permit persons to whom the | ||
9 | // Software is furnished to do so, subject to the following conditions: | ||
10 | // | ||
11 | // The above copyright notice and this permission notice shall be included in | ||
12 | // all copies or substantial portions of the Software. | ||
13 | // | ||
14 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
15 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
16 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | ||
17 | // THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
18 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING | ||
19 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER | ||
20 | // DEALINGS IN THE SOFTWARE. | ||
21 | |||
22 | // $Id$ | ||
23 | |||
24 | #include "ColSmartPlacement.hh" | ||
25 | |||
26 | #include "Screen.hh" | ||
27 | #include "ScreenPlacement.hh" | ||
28 | #include "Window.hh" | ||
29 | |||
30 | bool ColSmartPlacement::placeWindow(const std::vector<FluxboxWindow *> &windowlist, | ||
31 | const FluxboxWindow &win, | ||
32 | int &place_x, int &place_y) { | ||
33 | |||
34 | // xinerama head constraints | ||
35 | int head = (signed) win.screen().getCurrHead(); | ||
36 | int head_left = (signed) win.screen().maxLeft(head); | ||
37 | int head_right = (signed) win.screen().maxRight(head); | ||
38 | int head_top = (signed) win.screen().maxTop(head); | ||
39 | int head_bot = (signed) win.screen().maxBottom(head); | ||
40 | |||
41 | bool placed = false; | ||
42 | int next_x, next_y; | ||
43 | const ScreenPlacement &screen_placement = | ||
44 | dynamic_cast<const ScreenPlacement &>(win.screen().placementStrategy()); | ||
45 | |||
46 | bool top_bot = screen_placement.colDirection() == ScreenPlacement::TOPBOTTOM; | ||
47 | bool left_right = screen_placement.rowDirection() == ScreenPlacement::LEFTRIGHT; | ||
48 | |||
49 | int test_x; | ||
50 | |||
51 | int win_w = win.width() + win.fbWindow().borderWidth()*2; | ||
52 | int win_h = win.height() + win.fbWindow().borderWidth()*2; | ||
53 | |||
54 | if (left_right) | ||
55 | test_x = head_left; | ||
56 | else | ||
57 | test_x = head_right - win_w; | ||
58 | |||
59 | int change_y = 1; | ||
60 | if (screen_placement.colDirection() == ScreenPlacement::BOTTOMTOP) | ||
61 | change_y = -1; | ||
62 | |||
63 | while (!placed && | ||
64 | (left_right ? test_x + win_w <= head_right | ||
65 | : test_x >= head_left)) { | ||
66 | |||
67 | if (left_right) | ||
68 | next_x = head_right; // it will get shrunk | ||
69 | else | ||
70 | next_x = head_left-1; | ||
71 | |||
72 | int test_y; | ||
73 | if (top_bot) | ||
74 | test_y = head_top; | ||
75 | else | ||
76 | test_y = head_bot - win_h; | ||
77 | |||
78 | while (!placed && | ||
79 | (top_bot ? test_y + win_h <= head_bot | ||
80 | : test_y >= head_top)) { | ||
81 | placed = true; | ||
82 | |||
83 | next_y = test_y + change_y; | ||
84 | |||
85 | std::vector<FluxboxWindow *>::const_iterator it = | ||
86 | windowlist.begin(); | ||
87 | std::vector<FluxboxWindow *>::const_iterator it_end = | ||
88 | windowlist.end(); | ||
89 | for (; it != it_end && placed; ++it) { | ||
90 | int curr_x = (*it)->x(); | ||
91 | int curr_y = (*it)->y(); | ||
92 | int curr_w = (*it)->width() + (*it)->fbWindow().borderWidth()*2; | ||
93 | int curr_h = (*it)->height() + (*it)->fbWindow().borderWidth()*2; | ||
94 | |||
95 | if (curr_x < test_x + win_w && | ||
96 | curr_x + curr_w > test_x && | ||
97 | curr_y < test_y + win_h && | ||
98 | curr_y + curr_h > test_y) { | ||
99 | // this window is in the way | ||
100 | placed = false; | ||
101 | |||
102 | // we find the next y that we can go to (a window will be in the way | ||
103 | // all the way to its bottom) | ||
104 | if (top_bot) { | ||
105 | if (curr_y + curr_h > next_y) | ||
106 | next_y = curr_y + curr_h; | ||
107 | } else { | ||
108 | if (curr_y - win_h < next_y) | ||
109 | next_y = curr_y - win_h; | ||
110 | } | ||
111 | |||
112 | // but we can only go to the nearest x, since that is where the | ||
113 | // next time current windows in the way will change | ||
114 | if (left_right) { | ||
115 | if (curr_x + curr_w < next_x) | ||
116 | next_x = curr_x + curr_w; | ||
117 | } else { | ||
118 | if (curr_x - win_w > next_x) | ||
119 | next_x = curr_x - win_w; | ||
120 | } | ||
121 | } | ||
122 | } | ||
123 | |||
124 | if (placed) { | ||
125 | place_x = test_x; | ||
126 | place_y = test_y; | ||
127 | } | ||
128 | |||
129 | test_y = next_y; | ||
130 | } // end while | ||
131 | |||
132 | test_x = next_x; | ||
133 | } // end while | ||
134 | |||
135 | return placed; | ||
136 | } | ||
diff --git a/src/ColSmartPlacement.hh b/src/ColSmartPlacement.hh new file mode 100644 index 0000000..ad17d3b --- /dev/null +++ b/src/ColSmartPlacement.hh | |||
@@ -0,0 +1,36 @@ | |||
1 | // ColSmartPlacement.hh | ||
2 | // Copyright (c) 2006 Fluxbox Team (fluxgen at fluxbox dot org) | ||
3 | // | ||
4 | // Permission is hereby granted, free of charge, to any person obtaining a | ||
5 | // copy of this software and associated documentation files (the "Software"), | ||
6 | // to deal in the Software without restriction, including without limitation | ||
7 | // the rights to use, copy, modify, merge, publish, distribute, sublicense, | ||
8 | // and/or sell copies of the Software, and to permit persons to whom the | ||
9 | // Software is furnished to do so, subject to the following conditions: | ||
10 | // | ||
11 | // The above copyright notice and this permission notice shall be included in | ||
12 | // all copies or substantial portions of the Software. | ||
13 | // | ||
14 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
15 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
16 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | ||
17 | // THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
18 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING | ||
19 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER | ||
20 | // DEALINGS IN THE SOFTWARE. | ||
21 | |||
22 | // $Id$ | ||
23 | |||
24 | #ifndef COLSMARTPLACEMENT_HH | ||
25 | #define COLSMARTPLACEMENT_HH | ||
26 | |||
27 | #include "PlacementStrategy.hh" | ||
28 | |||
29 | class ColSmartPlacement: public PlacementStrategy { | ||
30 | public: | ||
31 | bool placeWindow(const std::vector<FluxboxWindow *> &windowlist, | ||
32 | const FluxboxWindow &win, | ||
33 | int &place_x, int &place_y); | ||
34 | }; | ||
35 | |||
36 | #endif // COLSMARTPLACEMENT_HH | ||
diff --git a/src/Makefile.am b/src/Makefile.am index f2f515d..156eff8 100644 --- a/src/Makefile.am +++ b/src/Makefile.am | |||
@@ -128,6 +128,11 @@ fluxbox_SOURCES = AtomHandler.hh ArrowButton.hh ArrowButton.cc \ | |||
128 | Resources.cc \ | 128 | Resources.cc \ |
129 | WindowCmd.hh WindowCmd.cc \ | 129 | WindowCmd.hh WindowCmd.cc \ |
130 | FocusControl.hh FocusControl.cc \ | 130 | FocusControl.hh FocusControl.cc \ |
131 | CascadePlacement.hh CascadePlacement.cc \ | ||
132 | ColSmartPlacement.hh ColSmartPlacement.cc \ | ||
133 | RowSmartPlacement.hh RowSmartPlacement.cc \ | ||
134 | ScreenPlacement.hh ScreenPlacement.cc \ | ||
135 | UnderMousePlacement.hh UnderMousePlacement.cc \ | ||
131 | ${newwmspec_SOURCE} ${gnome_SOURCE} \ | 136 | ${newwmspec_SOURCE} ${gnome_SOURCE} \ |
132 | ${REMEMBER_SOURCE} ${TOOLBAR_SOURCE} | 137 | ${REMEMBER_SOURCE} ${TOOLBAR_SOURCE} |
133 | 138 | ||
diff --git a/src/RowSmartPlacement.cc b/src/RowSmartPlacement.cc new file mode 100644 index 0000000..eb2956b --- /dev/null +++ b/src/RowSmartPlacement.cc | |||
@@ -0,0 +1,155 @@ | |||
1 | // RowSmartPlacement.cc | ||
2 | // Copyright (c) 2006 Fluxbox Team (fluxgen at fluxbox dot org) | ||
3 | // | ||
4 | // Permission is hereby granted, free of charge, to any person obtaining a | ||
5 | // copy of this software and associated documentation files (the "Software"), | ||
6 | // to deal in the Software without restriction, including without limitation | ||
7 | // the rights to use, copy, modify, merge, publish, distribute, sublicense, | ||
8 | // and/or sell copies of the Software, and to permit persons to whom the | ||
9 | // Software is furnished to do so, subject to the following conditions: | ||
10 | // | ||
11 | // The above copyright notice and this permission notice shall be included in | ||
12 | // all copies or substantial portions of the Software. | ||
13 | // | ||
14 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
15 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
16 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | ||
17 | // THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
18 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING | ||
19 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER | ||
20 | // DEALINGS IN THE SOFTWARE. | ||
21 | |||
22 | // $Id$ | ||
23 | |||
24 | #include "RowSmartPlacement.hh" | ||
25 | |||
26 | #include "Window.hh" | ||
27 | #include "Screen.hh" | ||
28 | #include "ScreenPlacement.hh" | ||
29 | |||
30 | bool RowSmartPlacement::placeWindow(const std::vector<FluxboxWindow *> &windowlist, | ||
31 | const FluxboxWindow &win, | ||
32 | int &place_x, int &place_y) { | ||
33 | |||
34 | bool placed = false; | ||
35 | int next_x, next_y; | ||
36 | |||
37 | // view (screen + head) constraints | ||
38 | int head = (signed) win.screen().getCurrHead(); | ||
39 | int head_left = (signed) win.screen().maxLeft(head); | ||
40 | int head_right = (signed) win.screen().maxRight(head); | ||
41 | int head_top = (signed) win.screen().maxTop(head); | ||
42 | int head_bot = (signed) win.screen().maxBottom(head); | ||
43 | |||
44 | const ScreenPlacement &screen_placement = | ||
45 | dynamic_cast<const ScreenPlacement &>(win.screen().placementStrategy()); | ||
46 | |||
47 | bool top_bot = | ||
48 | screen_placement.colDirection() == ScreenPlacement::TOPBOTTOM; | ||
49 | bool left_right = | ||
50 | screen_placement.rowDirection() == ScreenPlacement::LEFTRIGHT; | ||
51 | |||
52 | int change_x = 1, change_y = 1; | ||
53 | |||
54 | if (screen_placement.colDirection() == ScreenPlacement::BOTTOMTOP) | ||
55 | change_y = -1; | ||
56 | |||
57 | if (screen_placement.rowDirection() == ScreenPlacement::RIGHTLEFT) | ||
58 | change_x = -1; | ||
59 | |||
60 | |||
61 | |||
62 | |||
63 | int win_h = win.height() + win.fbWindow().borderWidth()*2; | ||
64 | int win_w = win.width() + win.fbWindow().borderWidth()*2; | ||
65 | int test_y; | ||
66 | if (top_bot) | ||
67 | test_y = head_top; | ||
68 | else | ||
69 | test_y = head_bot - win_h; | ||
70 | |||
71 | while (!placed && | ||
72 | (top_bot ? test_y + win_h <= head_bot | ||
73 | : test_y >= head_top)) { | ||
74 | |||
75 | int test_x; | ||
76 | if (left_right) | ||
77 | test_x = head_left; | ||
78 | else | ||
79 | test_x = head_right - win_w; | ||
80 | |||
81 | // The trick here is that we set it to the furthest away one, | ||
82 | // then the code brings it back down to the safest one that | ||
83 | // we can go to (i.e. the next untested area) | ||
84 | if (top_bot) | ||
85 | next_y = head_bot; // will be shrunk | ||
86 | else | ||
87 | next_y = head_top-1; | ||
88 | |||
89 | while (!placed && | ||
90 | (left_right ? test_x + win_w <= head_right | ||
91 | : test_x >= head_left)) { | ||
92 | |||
93 | placed = true; | ||
94 | |||
95 | next_x = test_x + change_x; | ||
96 | |||
97 | std::vector<FluxboxWindow *>::const_iterator win_it = | ||
98 | windowlist.begin(); | ||
99 | std::vector<FluxboxWindow *>::const_iterator win_it_end = | ||
100 | windowlist.end(); | ||
101 | |||
102 | for (; win_it != win_it_end && placed; ++win_it) { | ||
103 | FluxboxWindow &window = **win_it; | ||
104 | |||
105 | int curr_x = window.x(); | ||
106 | int curr_y = window.y(); | ||
107 | int curr_w = window.width() + window.fbWindow().borderWidth()*2; | ||
108 | int curr_h = window.height() + window.fbWindow().borderWidth()*2; | ||
109 | |||
110 | if (curr_x < test_x + win_w && | ||
111 | curr_x + curr_w > test_x && | ||
112 | curr_y < test_y + win_h && | ||
113 | curr_y + curr_h > test_y) { | ||
114 | // this window is in the way | ||
115 | placed = false; | ||
116 | |||
117 | // we find the next x that we can go to (a window will be in the way | ||
118 | // all the way to its far side) | ||
119 | if (left_right) { | ||
120 | if (curr_x + curr_w > next_x) | ||
121 | next_x = curr_x + curr_w; | ||
122 | } else { | ||
123 | if (curr_x - win_w < next_x) | ||
124 | next_x = curr_x - win_w; | ||
125 | } | ||
126 | |||
127 | // but we can only go to the nearest y, since that is where the | ||
128 | // next time current windows in the way will change | ||
129 | if (top_bot) { | ||
130 | if (curr_y + curr_h < next_y) | ||
131 | next_y = curr_y + curr_h; | ||
132 | } else { | ||
133 | if (curr_y - win_h > next_y) | ||
134 | next_y = curr_y - win_h; | ||
135 | } | ||
136 | } | ||
137 | } | ||
138 | |||
139 | |||
140 | if (placed) { | ||
141 | place_x = test_x; | ||
142 | place_y = test_y; | ||
143 | |||
144 | break; | ||
145 | } | ||
146 | |||
147 | test_x = next_x; | ||
148 | } // end while | ||
149 | |||
150 | test_y = next_y; | ||
151 | } // end while | ||
152 | |||
153 | |||
154 | return placed; | ||
155 | } | ||
diff --git a/src/RowSmartPlacement.hh b/src/RowSmartPlacement.hh new file mode 100644 index 0000000..43dbf55 --- /dev/null +++ b/src/RowSmartPlacement.hh | |||
@@ -0,0 +1,37 @@ | |||
1 | // RowSmartPlacement.hh | ||
2 | // Copyright (c) 2006 Fluxbox Team (fluxgen at fluxbox dot org) | ||
3 | // | ||
4 | // Permission is hereby granted, free of charge, to any person obtaining a | ||
5 | // copy of this software and associated documentation files (the "Software"), | ||
6 | // to deal in the Software without restriction, including without limitation | ||
7 | // the rights to use, copy, modify, merge, publish, distribute, sublicense, | ||
8 | // and/or sell copies of the Software, and to permit persons to whom the | ||
9 | // Software is furnished to do so, subject to the following conditions: | ||
10 | // | ||
11 | // The above copyright notice and this permission notice shall be included in | ||
12 | // all copies or substantial portions of the Software. | ||
13 | // | ||
14 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
15 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
16 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | ||
17 | // THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
18 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING | ||
19 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER | ||
20 | // DEALINGS IN THE SOFTWARE. | ||
21 | |||
22 | // $Id$ | ||
23 | |||
24 | #ifndef ROWSMARTPLACEMENT_HH | ||
25 | #define ROWSMARTPLACEMENT_HH | ||
26 | |||
27 | #include "PlacementStrategy.hh" | ||
28 | |||
29 | class RowSmartPlacement: public PlacementStrategy { | ||
30 | public: | ||
31 | bool placeWindow(const std::vector<FluxboxWindow *> &windowlist, | ||
32 | const FluxboxWindow &win, | ||
33 | int &place_x, int &place_y); | ||
34 | }; | ||
35 | |||
36 | #endif // ROWSMARTPLACEMENT_HH | ||
37 | |||
diff --git a/src/Screen.cc b/src/Screen.cc index 8128384..2d58a01 100644 --- a/src/Screen.cc +++ b/src/Screen.cc | |||
@@ -33,6 +33,7 @@ | |||
33 | #include "Netizen.hh" | 33 | #include "Netizen.hh" |
34 | 34 | ||
35 | #include "FocusControl.hh" | 35 | #include "FocusControl.hh" |
36 | #include "ScreenPlacement.hh" | ||
36 | 37 | ||
37 | // themes | 38 | // themes |
38 | #include "FbWinFrameTheme.hh" | 39 | #include "FbWinFrameTheme.hh" |
@@ -184,9 +185,7 @@ BScreen::ScreenResource::ScreenResource(FbTk::ResourceManager &rm, | |||
184 | menu_delay(rm, 0, scrname + ".menuDelay", altscrname+".MenuDelay"), | 185 | menu_delay(rm, 0, scrname + ".menuDelay", altscrname+".MenuDelay"), |
185 | menu_delay_close(rm, 0, scrname + ".menuDelayClose", altscrname+".MenuDelayClose"), | 186 | menu_delay_close(rm, 0, scrname + ".menuDelayClose", altscrname+".MenuDelayClose"), |
186 | menu_mode(rm, FbTk::MenuTheme::DELAY_OPEN, scrname+".menuMode", altscrname+".MenuMode"), | 187 | menu_mode(rm, FbTk::MenuTheme::DELAY_OPEN, scrname+".menuMode", altscrname+".MenuMode"), |
187 | placement_policy(rm, ROWSMARTPLACEMENT, scrname+".windowPlacement", altscrname+".WindowPlacement"), | 188 | |
188 | row_direction(rm, LEFTRIGHT, scrname+".rowPlacementDirection", altscrname+".RowPlacementDirection"), | ||
189 | col_direction(rm, TOPBOTTOM, scrname+".colPlacementDirection", altscrname+".ColPlacementDirection"), | ||
190 | gc_line_width(rm, 1, scrname+".overlay.lineWidth", altscrname+".Overlay.LineWidth"), | 189 | gc_line_width(rm, 1, scrname+".overlay.lineWidth", altscrname+".Overlay.LineWidth"), |
191 | gc_line_style(rm, | 190 | gc_line_style(rm, |
192 | FbTk::GContext::LINESOLID, | 191 | FbTk::GContext::LINESOLID, |
@@ -238,6 +237,7 @@ BScreen::BScreen(FbTk::ResourceManager &rm, | |||
238 | m_name(screenname), | 237 | m_name(screenname), |
239 | m_altname(altscreenname), | 238 | m_altname(altscreenname), |
240 | m_focus_control(new FocusControl(*this)), | 239 | m_focus_control(new FocusControl(*this)), |
240 | m_placement_strategy(new ScreenPlacement(*this)), | ||
241 | m_xinerama_headinfo(0), | 241 | m_xinerama_headinfo(0), |
242 | m_shutdown(false) { | 242 | m_shutdown(false) { |
243 | 243 | ||
@@ -446,7 +446,10 @@ BScreen::~BScreen() { | |||
446 | 446 | ||
447 | // TODO fluxgen: check if this is the right place | 447 | // TODO fluxgen: check if this is the right place |
448 | delete [] m_head_areas; | 448 | delete [] m_head_areas; |
449 | |||
449 | delete m_focus_control; | 450 | delete m_focus_control; |
451 | delete m_placement_strategy; | ||
452 | |||
450 | } | 453 | } |
451 | 454 | ||
452 | void BScreen::initWindows() { | 455 | void BScreen::initWindows() { |
diff --git a/src/Screen.hh b/src/Screen.hh index bb5db3a..4f91d9c 100644 --- a/src/Screen.hh +++ b/src/Screen.hh | |||
@@ -30,6 +30,7 @@ | |||
30 | 30 | ||
31 | #include "FbRootWindow.hh" | 31 | #include "FbRootWindow.hh" |
32 | #include "MenuTheme.hh" | 32 | #include "MenuTheme.hh" |
33 | #include "PlacementStrategy.hh" | ||
33 | 34 | ||
34 | #include "FbTk/Resource.hh" | 35 | #include "FbTk/Resource.hh" |
35 | #include "FbTk/Subject.hh" | 36 | #include "FbTk/Subject.hh" |
@@ -63,6 +64,7 @@ class Strut; | |||
63 | class Slit; | 64 | class Slit; |
64 | class HeadArea; | 65 | class HeadArea; |
65 | class FocusControl; | 66 | class FocusControl; |
67 | class PlacementStrategy; | ||
66 | 68 | ||
67 | namespace FbTk { | 69 | namespace FbTk { |
68 | class Menu; | 70 | class Menu; |
@@ -90,15 +92,6 @@ public: | |||
90 | QUADRANTRESIZE, | 92 | QUADRANTRESIZE, |
91 | DEFAULTRESIZE = BOTTOMRESIZE }; | 93 | DEFAULTRESIZE = BOTTOMRESIZE }; |
92 | 94 | ||
93 | enum PlacementPolicy { | ||
94 | ROWSMARTPLACEMENT, | ||
95 | COLSMARTPLACEMENT, | ||
96 | CASCADEPLACEMENT, | ||
97 | UNDERMOUSEPLACEMENT | ||
98 | }; | ||
99 | |||
100 | enum RowDirection { LEFTRIGHT, RIGHTLEFT}; | ||
101 | enum ColumnDirection { TOPBOTTOM, BOTTOMTOP}; | ||
102 | 95 | ||
103 | typedef std::vector<FluxboxWindow *> Icons; | 96 | typedef std::vector<FluxboxWindow *> Icons; |
104 | 97 | ||
@@ -218,10 +211,7 @@ public: | |||
218 | /// hide all windowmenus except the given one (if given) | 211 | /// hide all windowmenus except the given one (if given) |
219 | void hideWindowMenus(const FluxboxWindow* except= 0); | 212 | void hideWindowMenus(const FluxboxWindow* except= 0); |
220 | 213 | ||
221 | inline PlacementPolicy getPlacementPolicy() const { return *resource.placement_policy; } | ||
222 | inline int getEdgeSnapThreshold() const { return *resource.edge_snap_threshold; } | 214 | inline int getEdgeSnapThreshold() const { return *resource.edge_snap_threshold; } |
223 | inline RowDirection getRowPlacementDirection() const { return *resource.row_direction; } | ||
224 | inline ColumnDirection getColPlacementDirection() const { return *resource.col_direction; } | ||
225 | 215 | ||
226 | void setRootColormapInstalled(bool r) { root_colormap_installed = r; } | 216 | void setRootColormapInstalled(bool r) { root_colormap_installed = r; } |
227 | void saveRootCommand(std::string rootcmd) { *resource.rootcommand = rootcmd; } | 217 | void saveRootCommand(std::string rootcmd) { *resource.rootcommand = rootcmd; } |
@@ -249,7 +239,9 @@ public: | |||
249 | const std::string &altName() const { return m_altname; } | 239 | const std::string &altName() const { return m_altname; } |
250 | bool isShuttingdown() const { return m_shutdown; } | 240 | bool isShuttingdown() const { return m_shutdown; } |
251 | 241 | ||
252 | 242 | PlacementStrategy &placementStrategy() { return *m_placement_strategy; } | |
243 | const PlacementStrategy &placementStrategy() const { return *m_placement_strategy; } | ||
244 | |||
253 | int addWorkspace(); | 245 | int addWorkspace(); |
254 | int removeLastWorkspace(); | 246 | int removeLastWorkspace(); |
255 | // scroll workspaces | 247 | // scroll workspaces |
@@ -442,9 +434,7 @@ private: | |||
442 | FbTk::Resource<int> workspaces, edge_snap_threshold, focused_alpha, | 434 | FbTk::Resource<int> workspaces, edge_snap_threshold, focused_alpha, |
443 | unfocused_alpha, menu_alpha, menu_delay, menu_delay_close; | 435 | unfocused_alpha, menu_alpha, menu_delay, menu_delay_close; |
444 | FbTk::Resource<FbTk::MenuTheme::MenuMode> menu_mode; | 436 | FbTk::Resource<FbTk::MenuTheme::MenuMode> menu_mode; |
445 | FbTk::Resource<PlacementPolicy> placement_policy; | 437 | |
446 | FbTk::Resource<RowDirection> row_direction; | ||
447 | FbTk::Resource<ColumnDirection> col_direction; | ||
448 | FbTk::Resource<int> gc_line_width; | 438 | FbTk::Resource<int> gc_line_width; |
449 | FbTk::Resource<FbTk::GContext::LineStyle> gc_line_style; | 439 | FbTk::Resource<FbTk::GContext::LineStyle> gc_line_style; |
450 | FbTk::Resource<FbTk::GContext::JoinStyle> gc_join_style; | 440 | FbTk::Resource<FbTk::GContext::JoinStyle> gc_join_style; |
@@ -458,6 +448,7 @@ private: | |||
458 | const std::string m_name, m_altname; | 448 | const std::string m_name, m_altname; |
459 | 449 | ||
460 | FocusControl *m_focus_control; | 450 | FocusControl *m_focus_control; |
451 | PlacementStrategy *m_placement_strategy; | ||
461 | 452 | ||
462 | // This is a map of windows to clients for clients that had a left | 453 | // This is a map of windows to clients for clients that had a left |
463 | // window set, but that window wasn't present at the time | 454 | // window set, but that window wasn't present at the time |
diff --git a/src/ScreenPlacement.cc b/src/ScreenPlacement.cc new file mode 100644 index 0000000..b455fc7 --- /dev/null +++ b/src/ScreenPlacement.cc | |||
@@ -0,0 +1,207 @@ | |||
1 | // ScreenPlacement.cc | ||
2 | // Copyright (c) 2006 Fluxbox Team (fluxgen at fluxbox dot org) | ||
3 | // | ||
4 | // Permission is hereby granted, free of charge, to any person obtaining a | ||
5 | // copy of this software and associated documentation files (the "Software"), | ||
6 | // to deal in the Software without restriction, including without limitation | ||
7 | // the rights to use, copy, modify, merge, publish, distribute, sublicense, | ||
8 | // and/or sell copies of the Software, and to permit persons to whom the | ||
9 | // Software is furnished to do so, subject to the following conditions: | ||
10 | // | ||
11 | // The above copyright notice and this permission notice shall be included in | ||
12 | // all copies or substantial portions of the Software. | ||
13 | // | ||
14 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
15 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
16 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | ||
17 | // THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
18 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING | ||
19 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER | ||
20 | // DEALINGS IN THE SOFTWARE. | ||
21 | |||
22 | // $Id$ | ||
23 | |||
24 | #include "ScreenPlacement.hh" | ||
25 | |||
26 | |||
27 | #include "RowSmartPlacement.hh" | ||
28 | #include "UnderMousePlacement.hh" | ||
29 | #include "ColSmartPlacement.hh" | ||
30 | #include "CascadePlacement.hh" | ||
31 | |||
32 | #include "Screen.hh" | ||
33 | #include "Window.hh" | ||
34 | |||
35 | #include <iostream> | ||
36 | #include <exception> | ||
37 | using std::cerr; | ||
38 | using std::endl; | ||
39 | |||
40 | ScreenPlacement::ScreenPlacement(BScreen &screen): | ||
41 | m_row_direction(screen.resourceManager(), LEFTRIGHT, | ||
42 | screen.name()+".rowPlacementDirection", | ||
43 | screen.altName()+".RowPlacementDirection"), | ||
44 | m_col_direction(screen.resourceManager(), TOPBOTTOM, | ||
45 | screen.name()+".colPlacementDirection", | ||
46 | screen.altName()+".ColPlacementDirection"), | ||
47 | m_placement_policy(screen.resourceManager(), ROWSMARTPLACEMENT, | ||
48 | screen.name()+".windowPlacement", | ||
49 | screen.altName()+".WindowPlacement"), | ||
50 | m_old_policy(*m_placement_policy), | ||
51 | m_strategy(new RowSmartPlacement()) | ||
52 | { | ||
53 | } | ||
54 | |||
55 | bool ScreenPlacement::placeWindow(const std::vector<FluxboxWindow *> &windowlist, | ||
56 | const FluxboxWindow &win, | ||
57 | int &place_x, int &place_y) { | ||
58 | |||
59 | // check the resource placement and see if has changed | ||
60 | // and if so update the strategy | ||
61 | if (m_old_policy != *m_placement_policy) { | ||
62 | m_old_policy = *m_placement_policy; | ||
63 | switch (*m_placement_policy) { | ||
64 | case ROWSMARTPLACEMENT: | ||
65 | m_strategy.reset(new RowSmartPlacement()); | ||
66 | break; | ||
67 | case COLSMARTPLACEMENT: | ||
68 | m_strategy.reset(new ColSmartPlacement()); | ||
69 | break; | ||
70 | case CASCADEPLACEMENT: | ||
71 | m_strategy.reset(new CascadePlacement(win.screen())); | ||
72 | break; | ||
73 | case UNDERMOUSEPLACEMENT: | ||
74 | m_strategy.reset(new UnderMousePlacement()); | ||
75 | break; | ||
76 | } | ||
77 | } | ||
78 | |||
79 | // view (screen + head) constraints | ||
80 | int head = (signed) win.screen().getCurrHead(); | ||
81 | int head_left = (signed) win.screen().maxLeft(head); | ||
82 | int head_right = (signed) win.screen().maxRight(head); | ||
83 | int head_top = (signed) win.screen().maxTop(head); | ||
84 | int head_bot = (signed) win.screen().maxBottom(head); | ||
85 | |||
86 | // start placement, top left corner | ||
87 | place_x = head_left; | ||
88 | place_y = head_top; | ||
89 | |||
90 | bool placed = false; | ||
91 | try { | ||
92 | placed = m_strategy->placeWindow(windowlist, | ||
93 | win, | ||
94 | place_x, place_y); | ||
95 | } catch (std::bad_cast cast) { | ||
96 | // This should not happen. | ||
97 | // If for some reason we change the PlacementStrategy in Screen | ||
98 | // from ScreenPlacement to something else then we might get | ||
99 | // bad_cast from some placement strategies. | ||
100 | cerr<<"Failed to place window: "<<cast.what()<<endl; | ||
101 | } | ||
102 | |||
103 | if (!placed) { | ||
104 | // Create fallback strategy, when we need it the first time | ||
105 | // This strategy must succeed! | ||
106 | if (m_fallback_strategy.get() == 0) | ||
107 | m_fallback_strategy.reset(new CascadePlacement(win.screen())); | ||
108 | |||
109 | m_fallback_strategy->placeWindow(windowlist, | ||
110 | win, | ||
111 | place_x, place_y); | ||
112 | } | ||
113 | |||
114 | |||
115 | |||
116 | int win_w = win.width() + win.fbWindow().borderWidth()*2, | ||
117 | win_h = win.height() + win.fbWindow().borderWidth()*2; | ||
118 | |||
119 | |||
120 | // make sure the window is inside our screen(head) area | ||
121 | if (place_x + win_w > head_right) | ||
122 | place_x = (head_right - win_w) / 2; | ||
123 | if (place_y + win_h > head_bot) | ||
124 | place_y = (head_bot - win_h) / 2; | ||
125 | |||
126 | return true; | ||
127 | } | ||
128 | |||
129 | |||
130 | |||
131 | ////////////////////// Placement Resources | ||
132 | template <> | ||
133 | void FbTk::Resource<ScreenPlacement::PlacementPolicy>::setFromString(const char *str) { | ||
134 | if (strcasecmp("RowSmartPlacement", str) == 0) | ||
135 | *(*this) = ScreenPlacement::ROWSMARTPLACEMENT; | ||
136 | else if (strcasecmp("ColSmartPlacement", str) == 0) | ||
137 | *(*this) = ScreenPlacement::COLSMARTPLACEMENT; | ||
138 | else if (strcasecmp("UnderMousePlacement", str) == 0) | ||
139 | *(*this) = ScreenPlacement::UNDERMOUSEPLACEMENT; | ||
140 | else if (strcasecmp("CascadePlacement", str) == 0) | ||
141 | *(*this) = ScreenPlacement::CASCADEPLACEMENT; | ||
142 | else | ||
143 | setDefaultValue(); | ||
144 | } | ||
145 | |||
146 | template <> | ||
147 | std::string FbTk::Resource<ScreenPlacement::PlacementPolicy>::getString() const { | ||
148 | switch (*(*this)) { | ||
149 | case ScreenPlacement::ROWSMARTPLACEMENT: | ||
150 | return "RowSmartPlacement"; | ||
151 | case ScreenPlacement::COLSMARTPLACEMENT: | ||
152 | return "ColSmartPlacement"; | ||
153 | case ScreenPlacement::UNDERMOUSEPLACEMENT: | ||
154 | return "UnderMousePlacement"; | ||
155 | case ScreenPlacement::CASCADEPLACEMENT: | ||
156 | return "CascadePlacement"; | ||
157 | } | ||
158 | |||
159 | return "RowSmartPlacement"; | ||
160 | } | ||
161 | |||
162 | template <> | ||
163 | void FbTk::Resource<ScreenPlacement::RowDirection>::setFromString(const char *str) { | ||
164 | if (strcasecmp("LeftToRight", str) == 0) | ||
165 | *(*this) = ScreenPlacement::LEFTRIGHT; | ||
166 | else if (strcasecmp("RightToLeft", str) == 0) | ||
167 | *(*this) = ScreenPlacement::RIGHTLEFT; | ||
168 | else | ||
169 | setDefaultValue(); | ||
170 | |||
171 | } | ||
172 | |||
173 | template <> | ||
174 | std::string FbTk::Resource<ScreenPlacement::RowDirection>::getString() const { | ||
175 | switch (*(*this)) { | ||
176 | case ScreenPlacement::LEFTRIGHT: | ||
177 | return "LeftToRight"; | ||
178 | case ScreenPlacement::RIGHTLEFT: | ||
179 | return "RightToLeft"; | ||
180 | } | ||
181 | |||
182 | return "LeftToRight"; | ||
183 | } | ||
184 | |||
185 | |||
186 | template <> | ||
187 | void FbTk::Resource<ScreenPlacement::ColumnDirection>::setFromString(const char *str) { | ||
188 | if (strcasecmp("TopToBottom", str) == 0) | ||
189 | *(*this) = ScreenPlacement::TOPBOTTOM; | ||
190 | else if (strcasecmp("BottomToTop", str) == 0) | ||
191 | *(*this) = ScreenPlacement::BOTTOMTOP; | ||
192 | else | ||
193 | setDefaultValue(); | ||
194 | |||
195 | } | ||
196 | |||
197 | template <> | ||
198 | std::string FbTk::Resource<ScreenPlacement::ColumnDirection>::getString() const { | ||
199 | switch (*(*this)) { | ||
200 | case ScreenPlacement::TOPBOTTOM: | ||
201 | return "TopToBottom"; | ||
202 | case ScreenPlacement::BOTTOMTOP: | ||
203 | return "BottomToTop"; | ||
204 | } | ||
205 | |||
206 | return "TopToBottom"; | ||
207 | } | ||
diff --git a/src/ScreenPlacement.hh b/src/ScreenPlacement.hh new file mode 100644 index 0000000..93e6a82 --- /dev/null +++ b/src/ScreenPlacement.hh | |||
@@ -0,0 +1,77 @@ | |||
1 | // ScreenPlacement.hh | ||
2 | // Copyright (c) 2006 Fluxbox Team (fluxgen at fluxbox dot org) | ||
3 | // | ||
4 | // Permission is hereby granted, free of charge, to any person obtaining a | ||
5 | // copy of this software and associated documentation files (the "Software"), | ||
6 | // to deal in the Software without restriction, including without limitation | ||
7 | // the rights to use, copy, modify, merge, publish, distribute, sublicense, | ||
8 | // and/or sell copies of the Software, and to permit persons to whom the | ||
9 | // Software is furnished to do so, subject to the following conditions: | ||
10 | // | ||
11 | // The above copyright notice and this permission notice shall be included in | ||
12 | // all copies or substantial portions of the Software. | ||
13 | // | ||
14 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
15 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
16 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | ||
17 | // THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
18 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING | ||
19 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER | ||
20 | // DEALINGS IN THE SOFTWARE. | ||
21 | |||
22 | // $Id$ | ||
23 | |||
24 | #ifndef SCREENPLACEMENT_HH | ||
25 | #define SCREENPLACEMENT_HH | ||
26 | |||
27 | #include "PlacementStrategy.hh" | ||
28 | #include "FbTk/Resource.hh" | ||
29 | |||
30 | class BScreen; | ||
31 | |||
32 | /** | ||
33 | * Main class for strategy handling | ||
34 | * This is a bridge between screen and | ||
35 | * the real placement strategy (rowcol, undermouse etc) | ||
36 | * The placeWindow function in this class is guaranteed to succeed. | ||
37 | * It holds a pointer to the real placement strategy which is | ||
38 | * called upon placeWindow, it also holds the placement resources | ||
39 | */ | ||
40 | class ScreenPlacement: public PlacementStrategy { | ||
41 | public: | ||
42 | enum PlacementPolicy { | ||
43 | ROWSMARTPLACEMENT, | ||
44 | COLSMARTPLACEMENT, | ||
45 | CASCADEPLACEMENT, | ||
46 | UNDERMOUSEPLACEMENT | ||
47 | }; | ||
48 | |||
49 | enum RowDirection { | ||
50 | LEFTRIGHT, ///< from left to right | ||
51 | RIGHTLEFT ///< from right to left | ||
52 | }; | ||
53 | enum ColumnDirection { | ||
54 | TOPBOTTOM, ///< from top to bottom | ||
55 | BOTTOMTOP ///< from bottom to top | ||
56 | }; | ||
57 | |||
58 | explicit ScreenPlacement(BScreen &screen); | ||
59 | /// placeWindow is guaranteed to succeed, ignore return value | ||
60 | /// @return true | ||
61 | bool placeWindow(const std::vector<FluxboxWindow *> &windowlist, | ||
62 | const FluxboxWindow &window, | ||
63 | int &place_x, int &place_y); | ||
64 | |||
65 | RowDirection rowDirection() const { return *m_row_direction; } | ||
66 | ColumnDirection colDirection() const { return *m_col_direction; } | ||
67 | |||
68 | private: | ||
69 | FbTk::Resource<RowDirection> m_row_direction; ///< row direction resource | ||
70 | FbTk::Resource<ColumnDirection> m_col_direction; ///< column direction resource | ||
71 | FbTk::Resource<PlacementPolicy> m_placement_policy; ///< placement policy resource | ||
72 | PlacementPolicy m_old_policy; ///< holds old policy, used to determine if resources has changed | ||
73 | std::auto_ptr<PlacementStrategy> m_strategy; ///< main strategy | ||
74 | std::auto_ptr<PlacementStrategy> m_fallback_strategy; ///< a fallback strategy if the main strategy fails | ||
75 | }; | ||
76 | |||
77 | #endif // SCREENPLACEMENT_HH | ||
diff --git a/src/ScreenResources.cc b/src/ScreenResources.cc index 7b4d0c2..f26a376 100644 --- a/src/ScreenResources.cc +++ b/src/ScreenResources.cc | |||
@@ -29,82 +29,6 @@ | |||
29 | #include <string> | 29 | #include <string> |
30 | using namespace std; | 30 | using namespace std; |
31 | 31 | ||
32 | template <> | ||
33 | void FbTk::Resource<BScreen::PlacementPolicy>::setFromString(const char *str) { | ||
34 | if (strcasecmp("RowSmartPlacement", str) == 0) | ||
35 | *(*this) = BScreen::ROWSMARTPLACEMENT; | ||
36 | else if (strcasecmp("ColSmartPlacement", str) == 0) | ||
37 | *(*this) = BScreen::COLSMARTPLACEMENT; | ||
38 | else if (strcasecmp("UnderMousePlacement", str) == 0) | ||
39 | *(*this) = BScreen::UNDERMOUSEPLACEMENT; | ||
40 | else if (strcasecmp("CascadePlacement", str) == 0) | ||
41 | *(*this) = BScreen::CASCADEPLACEMENT; | ||
42 | else | ||
43 | setDefaultValue(); | ||
44 | } | ||
45 | |||
46 | template <> | ||
47 | string FbTk::Resource<BScreen::PlacementPolicy>::getString() const { | ||
48 | switch (*(*this)) { | ||
49 | case BScreen::ROWSMARTPLACEMENT: | ||
50 | return "RowSmartPlacement"; | ||
51 | case BScreen::COLSMARTPLACEMENT: | ||
52 | return "ColSmartPlacement"; | ||
53 | case BScreen::UNDERMOUSEPLACEMENT: | ||
54 | return "UnderMousePlacement"; | ||
55 | case BScreen::CASCADEPLACEMENT: | ||
56 | return "CascadePlacement"; | ||
57 | } | ||
58 | |||
59 | return "RowSmartPlacement"; | ||
60 | } | ||
61 | |||
62 | template <> | ||
63 | void FbTk::Resource<BScreen::RowDirection>::setFromString(const char *str) { | ||
64 | if (strcasecmp("LeftToRight", str) == 0) | ||
65 | *(*this) = BScreen::LEFTRIGHT; | ||
66 | else if (strcasecmp("RightToLeft", str) == 0) | ||
67 | *(*this) = BScreen::RIGHTLEFT; | ||
68 | else | ||
69 | setDefaultValue(); | ||
70 | |||
71 | } | ||
72 | |||
73 | template <> | ||
74 | string FbTk::Resource<BScreen::RowDirection>::getString() const { | ||
75 | switch (*(*this)) { | ||
76 | case BScreen::LEFTRIGHT: | ||
77 | return "LeftToRight"; | ||
78 | case BScreen::RIGHTLEFT: | ||
79 | return "RightToLeft"; | ||
80 | } | ||
81 | |||
82 | return "LeftToRight"; | ||
83 | } | ||
84 | |||
85 | |||
86 | template <> | ||
87 | void FbTk::Resource<BScreen::ColumnDirection>::setFromString(const char *str) { | ||
88 | if (strcasecmp("TopToBottom", str) == 0) | ||
89 | *(*this) = BScreen::TOPBOTTOM; | ||
90 | else if (strcasecmp("BottomToTop", str) == 0) | ||
91 | *(*this) = BScreen::BOTTOMTOP; | ||
92 | else | ||
93 | setDefaultValue(); | ||
94 | |||
95 | } | ||
96 | |||
97 | template <> | ||
98 | string FbTk::Resource<BScreen::ColumnDirection>::getString() const { | ||
99 | switch (*(*this)) { | ||
100 | case BScreen::TOPBOTTOM: | ||
101 | return "TopToBottom"; | ||
102 | case BScreen::BOTTOMTOP: | ||
103 | return "BottomToTop"; | ||
104 | } | ||
105 | |||
106 | return "TopToBottom"; | ||
107 | } | ||
108 | 32 | ||
109 | template <> | 33 | template <> |
110 | string FbTk::Resource<FbTk::MenuTheme::MenuMode>::getString() const { | 34 | string FbTk::Resource<FbTk::MenuTheme::MenuMode>::getString() const { |
diff --git a/src/UnderMousePlacement.cc b/src/UnderMousePlacement.cc new file mode 100644 index 0000000..3e2bc41 --- /dev/null +++ b/src/UnderMousePlacement.cc | |||
@@ -0,0 +1,75 @@ | |||
1 | // UnderMousePlacement.cc | ||
2 | // Copyright (c) 2006 Fluxbox Team (fluxgen at fluxbox dot org) | ||
3 | // | ||
4 | // Permission is hereby granted, free of charge, to any person obtaining a | ||
5 | // copy of this software and associated documentation files (the "Software"), | ||
6 | // to deal in the Software without restriction, including without limitation | ||
7 | // the rights to use, copy, modify, merge, publish, distribute, sublicense, | ||
8 | // and/or sell copies of the Software, and to permit persons to whom the | ||
9 | // Software is furnished to do so, subject to the following conditions: | ||
10 | // | ||
11 | // The above copyright notice and this permission notice shall be included in | ||
12 | // all copies or substantial portions of the Software. | ||
13 | // | ||
14 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
15 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
16 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | ||
17 | // THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
18 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING | ||
19 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER | ||
20 | // DEALINGS IN THE SOFTWARE. | ||
21 | |||
22 | // $Id$ | ||
23 | |||
24 | #include "UnderMousePlacement.hh" | ||
25 | |||
26 | #include "FbTk/App.hh" | ||
27 | #include "Screen.hh" | ||
28 | #include "Window.hh" | ||
29 | |||
30 | bool UnderMousePlacement::placeWindow(const std::vector<FluxboxWindow *> &list, | ||
31 | const FluxboxWindow &win, | ||
32 | int &place_x, int &place_y) { | ||
33 | |||
34 | int root_x, root_y, ignore_i; | ||
35 | |||
36 | unsigned int ignore_ui; | ||
37 | |||
38 | Window ignore_w; | ||
39 | |||
40 | XQueryPointer(FbTk::App::instance()->display(), | ||
41 | win.screen().rootWindow().window(), &ignore_w, | ||
42 | &ignore_w, &root_x, &root_y, | ||
43 | &ignore_i, &ignore_i, &ignore_ui); | ||
44 | |||
45 | // 2*border = border on each side of the screen | ||
46 | int win_w = win.width() + win.fbWindow().borderWidth()*2, | ||
47 | win_h = win.height() + win.fbWindow().borderWidth()*2; | ||
48 | |||
49 | int test_x = root_x - (win_w / 2); | ||
50 | int test_y = root_y - (win_h / 2); | ||
51 | |||
52 | // keep the window inside the screen | ||
53 | int head = (signed) win.screen().getCurrHead(); | ||
54 | int head_left = (signed) win.screen().maxLeft(head); | ||
55 | int head_right = (signed) win.screen().maxRight(head); | ||
56 | int head_top = (signed) win.screen().maxTop(head); | ||
57 | int head_bot = (signed) win.screen().maxBottom(head); | ||
58 | |||
59 | if (test_x < head_left) | ||
60 | test_x = head_left; | ||
61 | |||
62 | if (test_x + win_w > head_right) | ||
63 | test_x = head_right - win_w; | ||
64 | |||
65 | if (test_y < head_top) | ||
66 | test_y = head_top; | ||
67 | |||
68 | if (test_y + win_h > head_bot) | ||
69 | test_y = head_bot - win_h; | ||
70 | |||
71 | place_x = test_x; | ||
72 | place_y = test_y; | ||
73 | |||
74 | return true; | ||
75 | } | ||
diff --git a/src/UnderMousePlacement.hh b/src/UnderMousePlacement.hh new file mode 100644 index 0000000..d89133c --- /dev/null +++ b/src/UnderMousePlacement.hh | |||
@@ -0,0 +1,36 @@ | |||
1 | // UnderMousePlacement.hh | ||
2 | // Copyright (c) 2006 Fluxbox Team (fluxgen at fluxbox dot org) | ||
3 | // | ||
4 | // Permission is hereby granted, free of charge, to any person obtaining a | ||
5 | // copy of this software and associated documentation files (the "Software"), | ||
6 | // to deal in the Software without restriction, including without limitation | ||
7 | // the rights to use, copy, modify, merge, publish, distribute, sublicense, | ||
8 | // and/or sell copies of the Software, and to permit persons to whom the | ||
9 | // Software is furnished to do so, subject to the following conditions: | ||
10 | // | ||
11 | // The above copyright notice and this permission notice shall be included in | ||
12 | // all copies or substantial portions of the Software. | ||
13 | // | ||
14 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
15 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
16 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | ||
17 | // THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
18 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING | ||
19 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER | ||
20 | // DEALINGS IN THE SOFTWARE. | ||
21 | |||
22 | // $Id$ | ||
23 | |||
24 | #ifndef UNDERMOUSEPLACEMENT_HH | ||
25 | #define UNDERMOUSEPLACEMENT_HH | ||
26 | |||
27 | #include "PlacementStrategy.hh" | ||
28 | |||
29 | class UnderMousePlacement: public PlacementStrategy { | ||
30 | public: | ||
31 | bool placeWindow(const std::vector<FluxboxWindow *> &windowlist, | ||
32 | const FluxboxWindow &win, | ||
33 | int &place_x, int &place_y); | ||
34 | }; | ||
35 | |||
36 | #endif // UNDERMOUSEPLACEMENT_HH | ||
diff --git a/src/Workspace.cc b/src/Workspace.cc index 07e76f0..7d53381 100644 --- a/src/Workspace.cc +++ b/src/Workspace.cc | |||
@@ -33,6 +33,7 @@ | |||
33 | #include "FbWinFrame.hh" | 33 | #include "FbWinFrame.hh" |
34 | #include "WindowCmd.hh" | 34 | #include "WindowCmd.hh" |
35 | #include "FocusControl.hh" | 35 | #include "FocusControl.hh" |
36 | #include "PlacementStrategy.hh" | ||
36 | 37 | ||
37 | #include "FbTk/I18n.hh" | 38 | #include "FbTk/I18n.hh" |
38 | #include "FbTk/MenuItem.hh" | 39 | #include "FbTk/MenuItem.hh" |
@@ -140,21 +141,13 @@ Workspace::Workspace(BScreen &scrn, FbTk::MultLayers &layermanager, | |||
140 | m_name(name), | 141 | m_name(name), |
141 | m_id(id) { | 142 | m_id(id) { |
142 | 143 | ||
143 | |||
144 | m_cascade_x = new int[scrn.numHeads() + 1]; | ||
145 | m_cascade_y = new int[scrn.numHeads() + 1]; | ||
146 | for (int i=0; i < scrn.numHeads()+1; i++) { | ||
147 | m_cascade_x[i] = 32 + scrn.getHeadX(i); | ||
148 | m_cascade_y[i] = 32 + scrn.getHeadY(i); | ||
149 | } | ||
150 | menu().setInternalMenu(); | 144 | menu().setInternalMenu(); |
151 | setName(name); | 145 | setName(name); |
146 | |||
152 | } | 147 | } |
153 | 148 | ||
154 | 149 | ||
155 | Workspace::~Workspace() { | 150 | Workspace::~Workspace() { |
156 | delete [] m_cascade_x; | ||
157 | delete [] m_cascade_y; | ||
158 | } | 151 | } |
159 | 152 | ||
160 | void Workspace::setLastFocusedWindow(FluxboxWindow *win) { | 153 | void Workspace::setLastFocusedWindow(FluxboxWindow *win) { |
@@ -427,268 +420,12 @@ void Workspace::updateClientmenu() { | |||
427 | } | 420 | } |
428 | 421 | ||
429 | void Workspace::placeWindow(FluxboxWindow &win) { | 422 | void Workspace::placeWindow(FluxboxWindow &win) { |
430 | 423 | int place_x, place_y; | |
431 | bool placed = false; | 424 | // we ignore the return value, |
432 | 425 | // the screen placement strategy is guaranteed to succeed. | |
433 | // restrictions | 426 | screen().placementStrategy().placeWindow(m_windowlist, |
434 | int head = (signed) screen().getCurrHead(); | 427 | win, |
435 | int head_left = (signed) screen().maxLeft(head); | 428 | place_x, place_y); |
436 | int head_right = (signed) screen().maxRight(head); | ||
437 | int head_top = (signed) screen().maxTop(head); | ||
438 | int head_bot = (signed) screen().maxBottom(head); | ||
439 | |||
440 | int place_x = head_left, place_y = head_top, change_x = 1, change_y = 1; | ||
441 | |||
442 | if (screen().getColPlacementDirection() == BScreen::BOTTOMTOP) | ||
443 | change_y = -1; | ||
444 | if (screen().getRowPlacementDirection() == BScreen::RIGHTLEFT) | ||
445 | change_x = -1; | ||
446 | |||
447 | int win_w = win.width() + win.fbWindow().borderWidth()*2, | ||
448 | win_h = win.height() + win.fbWindow().borderWidth()*2; | ||
449 | |||
450 | |||
451 | int test_x, test_y, curr_x, curr_y, curr_w, curr_h; | ||
452 | |||
453 | switch (screen().getPlacementPolicy()) { | ||
454 | case BScreen::UNDERMOUSEPLACEMENT: { | ||
455 | int root_x, root_y, ignore_i; | ||
456 | |||
457 | unsigned int ignore_ui; | ||
458 | |||
459 | Window ignore_w; | ||
460 | |||
461 | XQueryPointer(FbTk::App::instance()->display(), | ||
462 | screen().rootWindow().window(), &ignore_w, | ||
463 | &ignore_w, &root_x, &root_y, | ||
464 | &ignore_i, &ignore_i, &ignore_ui); | ||
465 | |||
466 | test_x = root_x - (win_w / 2); | ||
467 | test_y = root_y - (win_h / 2); | ||
468 | |||
469 | // keep the window inside the screen | ||
470 | |||
471 | if (test_x < head_left) | ||
472 | test_x = head_left; | ||
473 | |||
474 | if (test_x + win_w > head_right) | ||
475 | test_x = head_right - win_w; | ||
476 | |||
477 | if (test_y < head_top) | ||
478 | test_y = head_top; | ||
479 | |||
480 | if (test_y + win_h > head_bot) | ||
481 | test_y = head_bot - win_h; | ||
482 | |||
483 | place_x = test_x; | ||
484 | place_y = test_y; | ||
485 | |||
486 | placed = true; | ||
487 | |||
488 | break; | ||
489 | } // end case UNDERMOUSEPLACEMENT | ||
490 | |||
491 | case BScreen::ROWSMARTPLACEMENT: { | ||
492 | int next_x, next_y; | ||
493 | bool top_bot = screen().getColPlacementDirection() == BScreen::TOPBOTTOM; | ||
494 | bool left_right = screen().getRowPlacementDirection() == BScreen::LEFTRIGHT; | ||
495 | |||
496 | if (top_bot) | ||
497 | test_y = head_top; | ||
498 | else | ||
499 | test_y = head_bot - win_h; | ||
500 | |||
501 | while (!placed && | ||
502 | (top_bot ? test_y + win_h <= head_bot | ||
503 | : test_y >= head_top)) { | ||
504 | |||
505 | if (left_right) | ||
506 | test_x = head_left; | ||
507 | else | ||
508 | test_x = head_right - win_w; | ||
509 | |||
510 | // The trick here is that we set it to the furthest away one, | ||
511 | // then the code brings it back down to the safest one that | ||
512 | // we can go to (i.e. the next untested area) | ||
513 | if (top_bot) | ||
514 | next_y = head_bot; // will be shrunk | ||
515 | else | ||
516 | next_y = head_top-1; | ||
517 | |||
518 | while (!placed && | ||
519 | (left_right ? test_x + win_w <= head_right | ||
520 | : test_x >= head_left)) { | ||
521 | |||
522 | placed = true; | ||
523 | |||
524 | next_x = test_x + change_x; | ||
525 | |||
526 | Windows::iterator win_it = m_windowlist.begin(); | ||
527 | const Windows::iterator win_it_end = m_windowlist.end(); | ||
528 | |||
529 | for (; win_it != win_it_end && placed; ++win_it) { | ||
530 | FluxboxWindow &window = **win_it; | ||
531 | |||
532 | curr_x = window.x(); | ||
533 | curr_y = window.y(); | ||
534 | curr_w = window.width() + window.fbWindow().borderWidth()*2; | ||
535 | curr_h = window.height() + window.fbWindow().borderWidth()*2; | ||
536 | |||
537 | if (curr_x < test_x + win_w && | ||
538 | curr_x + curr_w > test_x && | ||
539 | curr_y < test_y + win_h && | ||
540 | curr_y + curr_h > test_y) { | ||
541 | // this window is in the way | ||
542 | placed = false; | ||
543 | |||
544 | // we find the next x that we can go to (a window will be in the way | ||
545 | // all the way to its far side) | ||
546 | if (left_right) { | ||
547 | if (curr_x + curr_w > next_x) | ||
548 | next_x = curr_x + curr_w; | ||
549 | } else { | ||
550 | if (curr_x - win_w < next_x) | ||
551 | next_x = curr_x - win_w; | ||
552 | } | ||
553 | |||
554 | // but we can only go to the nearest y, since that is where the | ||
555 | // next time current windows in the way will change | ||
556 | if (top_bot) { | ||
557 | if (curr_y + curr_h < next_y) | ||
558 | next_y = curr_y + curr_h; | ||
559 | } else { | ||
560 | if (curr_y - win_h > next_y) | ||
561 | next_y = curr_y - win_h; | ||
562 | } | ||
563 | } | ||
564 | } | ||
565 | |||
566 | |||
567 | if (placed) { | ||
568 | place_x = test_x; | ||
569 | place_y = test_y; | ||
570 | |||
571 | break; | ||
572 | } | ||
573 | |||
574 | test_x = next_x; | ||
575 | } // end while | ||
576 | |||
577 | test_y = next_y; | ||
578 | } // end while | ||
579 | |||
580 | break; | ||
581 | } // end case ROWSMARTPLACEMENT | ||
582 | |||
583 | case BScreen::COLSMARTPLACEMENT: { | ||
584 | int next_x, next_y; | ||
585 | bool top_bot = screen().getColPlacementDirection() == BScreen::TOPBOTTOM; | ||
586 | bool left_right = screen().getRowPlacementDirection() == BScreen::LEFTRIGHT; | ||
587 | |||
588 | if (left_right) | ||
589 | test_x = head_left; | ||
590 | else | ||
591 | test_x = head_right - win_w; | ||
592 | |||
593 | while (!placed && | ||
594 | (left_right ? test_x + win_w <= head_right | ||
595 | : test_x >= head_left)) { | ||
596 | |||
597 | if (left_right) | ||
598 | next_x = head_right; // it will get shrunk | ||
599 | else | ||
600 | next_x = head_left-1; | ||
601 | |||
602 | if (top_bot) | ||
603 | test_y = head_top; | ||
604 | else | ||
605 | test_y = head_bot - win_h; | ||
606 | |||
607 | while (!placed && | ||
608 | (top_bot ? test_y + win_h <= head_bot | ||
609 | : test_y >= head_top)) { | ||
610 | placed = True; | ||
611 | |||
612 | next_y = test_y + change_y; | ||
613 | |||
614 | Windows::iterator it = m_windowlist.begin(); | ||
615 | Windows::iterator it_end = m_windowlist.end(); | ||
616 | for (; it != it_end && placed; ++it) { | ||
617 | curr_x = (*it)->x(); | ||
618 | curr_y = (*it)->y(); | ||
619 | curr_w = (*it)->width() + (*it)->fbWindow().borderWidth()*2; | ||
620 | curr_h = (*it)->height() + (*it)->fbWindow().borderWidth()*2; | ||
621 | |||
622 | if (curr_x < test_x + win_w && | ||
623 | curr_x + curr_w > test_x && | ||
624 | curr_y < test_y + win_h && | ||
625 | curr_y + curr_h > test_y) { | ||
626 | // this window is in the way | ||
627 | placed = False; | ||
628 | |||
629 | // we find the next y that we can go to (a window will be in the way | ||
630 | // all the way to its bottom) | ||
631 | if (top_bot) { | ||
632 | if (curr_y + curr_h > next_y) | ||
633 | next_y = curr_y + curr_h; | ||
634 | } else { | ||
635 | if (curr_y - win_h < next_y) | ||
636 | next_y = curr_y - win_h; | ||
637 | } | ||
638 | |||
639 | // but we can only go to the nearest x, since that is where the | ||
640 | // next time current windows in the way will change | ||
641 | if (left_right) { | ||
642 | if (curr_x + curr_w < next_x) | ||
643 | next_x = curr_x + curr_w; | ||
644 | } else { | ||
645 | if (curr_x - win_w > next_x) | ||
646 | next_x = curr_x - win_w; | ||
647 | } | ||
648 | } | ||
649 | } | ||
650 | |||
651 | if (placed) { | ||
652 | place_x = test_x; | ||
653 | place_y = test_y; | ||
654 | } | ||
655 | |||
656 | test_y = next_y; | ||
657 | } // end while | ||
658 | |||
659 | test_x = next_x; | ||
660 | } // end while | ||
661 | |||
662 | break; | ||
663 | } // end COLSMARTPLACEMENT | ||
664 | |||
665 | } | ||
666 | |||
667 | // cascade placement or smart placement failed | ||
668 | if (! placed) { | ||
669 | |||
670 | if ((m_cascade_x[head] > ((head_left + head_right) / 2)) || | ||
671 | (m_cascade_y[head] > ((head_top + head_bot) / 2))) { | ||
672 | m_cascade_x[head] = head_left + 32; | ||
673 | m_cascade_y[head] = head_top + 32; | ||
674 | } | ||
675 | |||
676 | place_x = m_cascade_x[head]; | ||
677 | place_y = m_cascade_y[head]; | ||
678 | |||
679 | // just one borderwidth, so they can share a borderwidth (looks better) | ||
680 | int titlebar_height = win.titlebarHeight() + win.fbWindow().borderWidth(); | ||
681 | if (titlebar_height < 4) // make sure it is not insignificant | ||
682 | titlebar_height = 32; | ||
683 | m_cascade_x[head] += titlebar_height; | ||
684 | m_cascade_y[head] += titlebar_height; | ||
685 | } | ||
686 | |||
687 | if (place_x + win_w > head_right) | ||
688 | place_x = (head_right - win_w) / 2; | ||
689 | if (place_y + win_h > head_bot) | ||
690 | place_y = (head_bot - win_h) / 2; | ||
691 | |||
692 | 429 | ||
693 | win.moveResize(place_x, place_y, win.width(), win.height()); | 430 | win.moveResize(place_x, place_y, win.width(), win.height()); |
694 | } | 431 | } |