diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/Screen.cc | 145 | ||||
-rw-r--r-- | src/Screen.hh | 13 | ||||
-rw-r--r-- | src/Slit.cc | 4 | ||||
-rw-r--r-- | src/Toolbar.cc | 33 |
4 files changed, 116 insertions, 79 deletions
diff --git a/src/Screen.cc b/src/Screen.cc index 8372f0f..e4ede29 100644 --- a/src/Screen.cc +++ b/src/Screen.cc | |||
@@ -22,7 +22,7 @@ | |||
22 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER | 22 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER |
23 | // DEALINGS IN THE SOFTWARE. | 23 | // DEALINGS IN THE SOFTWARE. |
24 | 24 | ||
25 | // $Id: Screen.cc,v 1.289 2004/09/09 14:29:03 akir Exp $ | 25 | // $Id: Screen.cc,v 1.290 2004/09/11 13:30:37 fluxgen Exp $ |
26 | 26 | ||
27 | 27 | ||
28 | #include "Screen.hh" | 28 | #include "Screen.hh" |
@@ -55,6 +55,7 @@ | |||
55 | #include "Strut.hh" | 55 | #include "Strut.hh" |
56 | #include "CommandParser.hh" | 56 | #include "CommandParser.hh" |
57 | #include "AtomHandler.hh" | 57 | #include "AtomHandler.hh" |
58 | #include "HeadArea.hh" | ||
58 | 59 | ||
59 | 60 | ||
60 | #include "FbTk/I18n.hh" | 61 | #include "FbTk/I18n.hh" |
@@ -226,7 +227,6 @@ BScreen::BScreen(FbTk::ResourceManager &rm, | |||
226 | m_name(screenname), | 227 | m_name(screenname), |
227 | m_altname(altscreenname), | 228 | m_altname(altscreenname), |
228 | m_resource_manager(rm), | 229 | m_resource_manager(rm), |
229 | m_available_workspace_area(new Strut(0, 0, 0, 0)), | ||
230 | m_xinerama_headinfo(0), | 230 | m_xinerama_headinfo(0), |
231 | m_shutdown(false) { | 231 | m_shutdown(false) { |
232 | 232 | ||
@@ -250,6 +250,9 @@ BScreen::BScreen(FbTk::ResourceManager &rm, | |||
250 | managed = running; | 250 | managed = running; |
251 | if (! managed) | 251 | if (! managed) |
252 | return; | 252 | return; |
253 | |||
254 | // TODO fluxgen: check if this is the right place | ||
255 | m_head_areas = new HeadArea[numHeads() ? numHeads() : 1]; | ||
253 | 256 | ||
254 | _FB_USES_NLS; | 257 | _FB_USES_NLS; |
255 | 258 | ||
@@ -434,6 +437,9 @@ BScreen::~BScreen() { | |||
434 | if (hasXinerama() && m_xinerama_headinfo) { | 437 | if (hasXinerama() && m_xinerama_headinfo) { |
435 | delete [] m_xinerama_headinfo; | 438 | delete [] m_xinerama_headinfo; |
436 | } | 439 | } |
440 | |||
441 | // TODO fluxgen: check if this is the right place | ||
442 | delete [] m_head_areas; | ||
437 | } | 443 | } |
438 | 444 | ||
439 | void BScreen::initWindows() { | 445 | void BScreen::initWindows() { |
@@ -548,32 +554,36 @@ unsigned int BScreen::currentWorkspaceID() const { | |||
548 | return m_current_workspace->workspaceID(); | 554 | return m_current_workspace->workspaceID(); |
549 | } | 555 | } |
550 | 556 | ||
557 | const Strut* BScreen::availableWorkspaceArea(int head) const { | ||
558 | return m_head_areas[head ? head-1 : 0].availableWorkspaceArea(); | ||
559 | } | ||
560 | |||
551 | unsigned int BScreen::maxLeft(int head) const { | 561 | unsigned int BScreen::maxLeft(int head) const { |
562 | |||
552 | // we ignore strut if we're doing full maximization | 563 | // we ignore strut if we're doing full maximization |
553 | if (hasXinerama()) | 564 | if (hasXinerama()) |
554 | return doFullMax() ? getHeadX(head) : | 565 | return doFullMax() ? getHeadX(head) : |
555 | getHeadX(head) + m_available_workspace_area->left(); | 566 | getHeadX(head) + availableWorkspaceArea(head)->left(); |
556 | else | 567 | else |
557 | return doFullMax() ? 0 : m_available_workspace_area->left(); | 568 | return doFullMax() ? 0 : availableWorkspaceArea(head)->left(); |
558 | } | 569 | } |
559 | 570 | ||
560 | unsigned int BScreen::maxRight(int head) const { | 571 | unsigned int BScreen::maxRight(int head) const { |
561 | // we ignore strut if we're doing full maximization | 572 | // we ignore strut if we're doing full maximization |
562 | if (hasXinerama()) | 573 | if (hasXinerama()) |
563 | return doFullMax() ? getHeadX(head) + getHeadWidth(head) : | 574 | return doFullMax() ? getHeadX(head) + getHeadWidth(head) : |
564 | getHeadX(head) + getHeadWidth(head) - m_available_workspace_area->right(); | 575 | getHeadX(head) + getHeadWidth(head) - availableWorkspaceArea(head)->right(); |
565 | else | 576 | else |
566 | return doFullMax() ? width() : width() - m_available_workspace_area->right(); | 577 | return doFullMax() ? width() : width() - availableWorkspaceArea(head)->right(); |
567 | } | 578 | } |
568 | 579 | ||
569 | unsigned int BScreen::maxTop(int head) const { | 580 | unsigned int BScreen::maxTop(int head) const { |
570 | |||
571 | // we ignore strut if we're doing full maximization | 581 | // we ignore strut if we're doing full maximization |
572 | 582 | ||
573 | if (hasXinerama()) | 583 | if (hasXinerama()) |
574 | return doFullMax() ? getHeadY(head) : getHeadY(head) + m_available_workspace_area->top(); | 584 | return doFullMax() ? getHeadY(head) : getHeadY(head) + availableWorkspaceArea(head)->top(); |
575 | else | 585 | else |
576 | return doFullMax() ? 0 : m_available_workspace_area->top(); | 586 | return doFullMax() ? 0 : availableWorkspaceArea(head)->top(); |
577 | } | 587 | } |
578 | 588 | ||
579 | unsigned int BScreen::maxBottom(int head) const { | 589 | unsigned int BScreen::maxBottom(int head) const { |
@@ -581,9 +591,9 @@ unsigned int BScreen::maxBottom(int head) const { | |||
581 | 591 | ||
582 | if (hasXinerama()) | 592 | if (hasXinerama()) |
583 | return doFullMax() ? getHeadY(head) + getHeadHeight(head) : | 593 | return doFullMax() ? getHeadY(head) + getHeadHeight(head) : |
584 | getHeadY(head) + getHeadHeight(head) - m_available_workspace_area->bottom(); | 594 | getHeadY(head) + getHeadHeight(head) - availableWorkspaceArea(head)->bottom(); |
585 | else | 595 | else |
586 | return doFullMax() ? height() : height() - m_available_workspace_area->bottom(); | 596 | return doFullMax() ? height() : height() - availableWorkspaceArea(head)->bottom(); |
587 | } | 597 | } |
588 | 598 | ||
589 | void BScreen::update(FbTk::Subject *subj) { | 599 | void BScreen::update(FbTk::Subject *subj) { |
@@ -1260,58 +1270,46 @@ FluxboxWindow *BScreen::createWindow(WinClient &client) { | |||
1260 | return win; | 1270 | return win; |
1261 | } | 1271 | } |
1262 | 1272 | ||
1263 | Strut *BScreen::requestStrut(int left, int right, int top, int bottom) { | 1273 | Strut *BScreen::requestStrut(int head, int left, int right, int top, int bottom) { |
1264 | Strut *str = new Strut(left, right, top, bottom); | 1274 | if (head > numHeads() && head != 1) { |
1265 | m_strutlist.push_back(str); | 1275 | // head does not exist (if head == 1, then numHeads() == 0, |
1266 | return str; | 1276 | // which means no xinerama, but there's a head after all |
1267 | } | 1277 | head = numHeads(); |
1278 | } | ||
1268 | 1279 | ||
1269 | void BScreen::clearStrut(Strut *str) { | 1280 | int begin = head-1; |
1270 | if (str == 0) | 1281 | int end = head; |
1271 | return; | ||
1272 | // find strut and erase it | ||
1273 | std::list<Strut *>::iterator pos = find(m_strutlist.begin(), | ||
1274 | m_strutlist.end(), | ||
1275 | str); | ||
1276 | if (pos == m_strutlist.end()) | ||
1277 | return; | ||
1278 | m_strutlist.erase(pos); | ||
1279 | delete str; | ||
1280 | } | ||
1281 | 1282 | ||
1282 | /// helper class for for_each in BScreen::updateAvailableWorkspaceArea() | 1283 | if (head == 0) { // all heads (or no xinerama) |
1283 | namespace { | 1284 | begin = 0; |
1284 | class MaxArea { | 1285 | end = (numHeads() ? numHeads() : 1); |
1285 | public: | ||
1286 | MaxArea(Strut &max_area):m_max_area(max_area) { } | ||
1287 | void operator ()(const Strut *str) { | ||
1288 | static int left, right, bottom, top; | ||
1289 | left = std::max(m_max_area.left(), str->left()); | ||
1290 | right = std::max(m_max_area.right(), str->right()); | ||
1291 | bottom = std::max(m_max_area.bottom(), str->bottom()); | ||
1292 | top = std::max(m_max_area.top(), str->top()); | ||
1293 | m_max_area = Strut(left, right, top, bottom); | ||
1294 | } | 1286 | } |
1295 | private: | ||
1296 | Strut &m_max_area; | ||
1297 | }; | ||
1298 | 1287 | ||
1299 | } // end anonymous namespace | 1288 | Strut* next = 0; |
1289 | for (int i = begin; i != end; i++) { | ||
1290 | next = m_head_areas[i].requestStrut(i+1, left, right, top, bottom, next); | ||
1291 | } | ||
1292 | |||
1293 | return next; | ||
1294 | } | ||
1295 | |||
1296 | void BScreen::clearStrut(Strut *str) { | ||
1297 | if (str->next()) | ||
1298 | clearStrut(str->next()); | ||
1299 | int head = str->head() ? str->head() - 1 : 0; | ||
1300 | m_head_areas[head].clearStrut(str); | ||
1301 | // str is invalid now | ||
1302 | } | ||
1300 | 1303 | ||
1301 | void BScreen::updateAvailableWorkspaceArea() { | 1304 | void BScreen::updateAvailableWorkspaceArea() { |
1302 | // find max of left, right, top and bottom and set avaible workspace area | 1305 | size_t n = (numHeads() ? numHeads() : 1); |
1306 | bool updated = false; | ||
1303 | 1307 | ||
1304 | // clear old area | 1308 | for (size_t i = 0; i < n; i++) { |
1305 | Strut oldarea = *(m_available_workspace_area.get()); | 1309 | updated = m_head_areas[i].updateAvailableWorkspaceArea() || updated; |
1306 | m_available_workspace_area.reset(new Strut(0, 0, 0, 0)); | 1310 | } |
1307 | |||
1308 | // calculate max area | ||
1309 | for_each(m_strutlist.begin(), | ||
1310 | m_strutlist.end(), | ||
1311 | MaxArea(*m_available_workspace_area.get())); | ||
1312 | 1311 | ||
1313 | // only notify if the area changed | 1312 | if (updated) |
1314 | if (oldarea == *(m_available_workspace_area.get())) | ||
1315 | m_workspace_area_sig.notify(); | 1313 | m_workspace_area_sig.notify(); |
1316 | } | 1314 | } |
1317 | 1315 | ||
@@ -2204,11 +2202,17 @@ void BScreen::initXinerama() { | |||
2204 | Display *display = FbTk::App::instance()->display(); | 2202 | Display *display = FbTk::App::instance()->display(); |
2205 | 2203 | ||
2206 | if (!XineramaIsActive(display)) { | 2204 | if (!XineramaIsActive(display)) { |
2205 | #ifdef DEBUG | ||
2206 | cerr<<"BScreen::initXinerama(): dont have Xinerama"<<endl; | ||
2207 | #endif // DEBUG | ||
2207 | m_xinerama_avail = false; | 2208 | m_xinerama_avail = false; |
2208 | m_xinerama_headinfo = 0; | 2209 | m_xinerama_headinfo = 0; |
2209 | m_xinerama_num_heads = 0; | 2210 | m_xinerama_num_heads = 0; |
2210 | return; | 2211 | return; |
2211 | } | 2212 | } |
2213 | #ifdef DEBUG | ||
2214 | cerr<<"BScreen::initXinerama(): have Xinerama"<<endl; | ||
2215 | #endif // DEBUG | ||
2212 | m_xinerama_avail = true; | 2216 | m_xinerama_avail = true; |
2213 | 2217 | ||
2214 | XineramaScreenInfo *screen_info; | 2218 | XineramaScreenInfo *screen_info; |
@@ -2222,6 +2226,10 @@ void BScreen::initXinerama() { | |||
2222 | m_xinerama_headinfo[i].width = screen_info[i].width; | 2226 | m_xinerama_headinfo[i].width = screen_info[i].width; |
2223 | m_xinerama_headinfo[i].height = screen_info[i].height; | 2227 | m_xinerama_headinfo[i].height = screen_info[i].height; |
2224 | } | 2228 | } |
2229 | #ifdef DEBUG | ||
2230 | cerr<<"BScreen::initXinerama(): number of heads ="<<number<<endl; | ||
2231 | #endif // DEBUG | ||
2232 | |||
2225 | #else // XINERAMA | 2233 | #else // XINERAMA |
2226 | // no xinerama | 2234 | // no xinerama |
2227 | m_xinerama_avail = false; | 2235 | m_xinerama_avail = false; |
@@ -2308,6 +2316,31 @@ int BScreen::getHeadHeight(int head) const { | |||
2308 | #endif // XINERAMA | 2316 | #endif // XINERAMA |
2309 | } | 2317 | } |
2310 | 2318 | ||
2319 | pair<int,int> BScreen::clampToHead(int head, int x, int y, int w, int h) const { | ||
2320 | |||
2321 | // if there are multiple heads, head=0 is not valid | ||
2322 | // a better way would be to search the closest head | ||
2323 | if (head == 0 && numHeads() != 0) | ||
2324 | head = 1; | ||
2325 | |||
2326 | int hx = getHeadX(head); | ||
2327 | int hy = getHeadY(head); | ||
2328 | int hw = getHeadWidth(head); | ||
2329 | int hh = getHeadHeight(head); | ||
2330 | |||
2331 | if (x + w > hx + hw) | ||
2332 | x = hx + hw - w; | ||
2333 | if (y + h > hy + hh) | ||
2334 | y = hy + hh - h; | ||
2335 | |||
2336 | if (x < hx) | ||
2337 | x = hx; | ||
2338 | if (y < hy) | ||
2339 | y = hy; | ||
2340 | |||
2341 | return make_pair(x,y); | ||
2342 | } | ||
2343 | |||
2311 | // TODO: when toolbar gets its resources moved into Toolbar.hh/cc, then | 2344 | // TODO: when toolbar gets its resources moved into Toolbar.hh/cc, then |
2312 | // this can be gone and a consistent interface for the two used | 2345 | // this can be gone and a consistent interface for the two used |
2313 | // on the actual objects | 2346 | // on the actual objects |
diff --git a/src/Screen.hh b/src/Screen.hh index 076ee63..ad460a8 100644 --- a/src/Screen.hh +++ b/src/Screen.hh | |||
@@ -22,7 +22,7 @@ | |||
22 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER | 22 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER |
23 | // DEALINGS IN THE SOFTWARE. | 23 | // DEALINGS IN THE SOFTWARE. |
24 | 24 | ||
25 | // $Id: Screen.hh,v 1.144 2004/09/09 14:29:04 akir Exp $ | 25 | // $Id: Screen.hh,v 1.145 2004/09/11 13:29:35 fluxgen Exp $ |
26 | 26 | ||
27 | #ifndef SCREEN_HH | 27 | #ifndef SCREEN_HH |
28 | #define SCREEN_HH | 28 | #define SCREEN_HH |
@@ -61,6 +61,7 @@ class WinClient; | |||
61 | class Workspace; | 61 | class Workspace; |
62 | class Strut; | 62 | class Strut; |
63 | class Slit; | 63 | class Slit; |
64 | class HeadArea; | ||
64 | 65 | ||
65 | namespace FbTk { | 66 | namespace FbTk { |
66 | class Menu; | 67 | class Menu; |
@@ -304,6 +305,9 @@ public: | |||
304 | int getHeadWidth(int head) const; | 305 | int getHeadWidth(int head) const; |
305 | int getHeadHeight(int head) const; | 306 | int getHeadHeight(int head) const; |
306 | 307 | ||
308 | // returns the new (x,y) for a rectangle fitted on a head | ||
309 | std::pair<int,int> clampToHead(int head, int x, int y, int w, int h) const; | ||
310 | |||
307 | // magic to allow us to have "on head" placement (menu) without | 311 | // magic to allow us to have "on head" placement (menu) without |
308 | // the object really knowing about it. | 312 | // the object really knowing about it. |
309 | template <typename OnHeadObject> | 313 | template <typename OnHeadObject> |
@@ -333,7 +337,7 @@ public: | |||
333 | FluxboxWindow *createWindow(WinClient &client); | 337 | FluxboxWindow *createWindow(WinClient &client); |
334 | void setupWindowActions(FluxboxWindow &win); | 338 | void setupWindowActions(FluxboxWindow &win); |
335 | /// request workspace space, i.e "don't maximize over this area" | 339 | /// request workspace space, i.e "don't maximize over this area" |
336 | Strut *requestStrut(int left, int right, int top, int bottom); | 340 | Strut *requestStrut(int head, int left, int right, int top, int bottom); |
337 | /// remove requested space and destroy strut | 341 | /// remove requested space and destroy strut |
338 | void clearStrut(Strut *strut); | 342 | void clearStrut(Strut *strut); |
339 | /// updates max avaible area for the workspace | 343 | /// updates max avaible area for the workspace |
@@ -363,6 +367,8 @@ private: | |||
363 | void renderGeomWindow(); | 367 | void renderGeomWindow(); |
364 | void renderPosWindow(); | 368 | void renderPosWindow(); |
365 | 369 | ||
370 | const Strut* availableWorkspaceArea(int head) const; | ||
371 | |||
366 | ScreenSubject | 372 | ScreenSubject |
367 | m_clientlist_sig, ///< client signal | 373 | m_clientlist_sig, ///< client signal |
368 | m_iconlist_sig, ///< notify if a window gets iconified/deiconified | 374 | m_iconlist_sig, ///< notify if a window gets iconified/deiconified |
@@ -455,13 +461,12 @@ private: | |||
455 | 461 | ||
456 | int m_xinerama_center_x, m_xinerama_center_y; | 462 | int m_xinerama_center_x, m_xinerama_center_y; |
457 | 463 | ||
458 | std::auto_ptr<Strut> m_available_workspace_area; | 464 | HeadArea *m_head_areas; |
459 | 465 | ||
460 | struct XineramaHeadInfo { | 466 | struct XineramaHeadInfo { |
461 | int x, y, width, height; | 467 | int x, y, width, height; |
462 | } *m_xinerama_headinfo; | 468 | } *m_xinerama_headinfo; |
463 | 469 | ||
464 | std::list<Strut *> m_strutlist; | ||
465 | bool m_shutdown; | 470 | bool m_shutdown; |
466 | }; | 471 | }; |
467 | 472 | ||
diff --git a/src/Slit.cc b/src/Slit.cc index f960ac8..dc14d42 100644 --- a/src/Slit.cc +++ b/src/Slit.cc | |||
@@ -22,7 +22,7 @@ | |||
22 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER | 22 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER |
23 | // DEALINGS IN THE SOFTWARE. | 23 | // DEALINGS IN THE SOFTWARE. |
24 | 24 | ||
25 | // $Id: Slit.cc,v 1.99 2004/08/31 19:27:21 akir Exp $ | 25 | // $Id: Slit.cc,v 1.100 2004/09/11 13:31:36 fluxgen Exp $ |
26 | 26 | ||
27 | #include "Slit.hh" | 27 | #include "Slit.hh" |
28 | 28 | ||
@@ -407,7 +407,7 @@ void Slit::updateStrut() { | |||
407 | right = width(); | 407 | right = width(); |
408 | break; | 408 | break; |
409 | } | 409 | } |
410 | m_strut = screen().requestStrut(left, right, top, bottom); | 410 | m_strut = screen().requestStrut(getOnHead(), left, right, top, bottom); |
411 | screen().updateAvailableWorkspaceArea(); | 411 | screen().updateAvailableWorkspaceArea(); |
412 | } | 412 | } |
413 | 413 | ||
diff --git a/src/Toolbar.cc b/src/Toolbar.cc index 2c19518..d35e872 100644 --- a/src/Toolbar.cc +++ b/src/Toolbar.cc | |||
@@ -22,7 +22,7 @@ | |||
22 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER | 22 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER |
23 | // DEALINGS IN THE SOFTWARE. | 23 | // DEALINGS IN THE SOFTWARE. |
24 | 24 | ||
25 | // $Id: Toolbar.cc,v 1.152 2004/08/31 19:38:42 akir Exp $ | 25 | // $Id: Toolbar.cc,v 1.153 2004/09/11 13:33:07 fluxgen Exp $ |
26 | 26 | ||
27 | #include "Toolbar.hh" | 27 | #include "Toolbar.hh" |
28 | 28 | ||
@@ -328,7 +328,7 @@ void Toolbar::updateStrut() { | |||
328 | left = width(); | 328 | left = width(); |
329 | break; | 329 | break; |
330 | }; | 330 | }; |
331 | m_strut = screen().requestStrut(left, right, top, bottom); | 331 | m_strut = screen().requestStrut(getOnHead(), left, right, top, bottom); |
332 | screen().updateAvailableWorkspaceArea(); | 332 | screen().updateAvailableWorkspaceArea(); |
333 | } | 333 | } |
334 | 334 | ||
@@ -485,22 +485,21 @@ void Toolbar::buttonPressEvent(XButtonEvent &be) { | |||
485 | screen().hideMenus(); | 485 | screen().hideMenus(); |
486 | 486 | ||
487 | if (! menu().isVisible()) { | 487 | if (! menu().isVisible()) { |
488 | int x, y; | ||
489 | 488 | ||
490 | x = be.x_root - (menu().width() / 2); | 489 | int head = screen().getHead(be.x_root, be.y_root); |
491 | y = be.y_root - (menu().height() / 2); | 490 | int borderw = menu().fbwindow().borderWidth(); |
492 | 491 | pair<int, int> m = screen().clampToHead( head, | |
493 | if (x < 0) | 492 | be.x_root - (menu().width() / 2), |
494 | x = 0; | 493 | be.y_root - (menu().titleWindow().height() / 2), |
495 | else if (x + menu().width() > screen().width()) | 494 | menu().width() + 2*borderw, |
496 | x = screen().width() - menu().width(); | 495 | menu().height() + 2*borderw); |
497 | 496 | ||
498 | if (y < 0) | 497 | menu().setScreen( |
499 | y = 0; | 498 | screen().getHeadX(head), |
500 | else if (y + menu().height() > screen().height()) | 499 | screen().getHeadY(head), |
501 | y = screen().height() - menu().height(); | 500 | screen().getHeadWidth(head), |
502 | 501 | screen().getHeadHeight(head)); | |
503 | menu().move(x, y); | 502 | menu().move(m.first, m.second); |
504 | menu().show(); | 503 | menu().show(); |
505 | menu().grabInputFocus(); | 504 | menu().grabInputFocus(); |
506 | } else | 505 | } else |