summaryrefslogtreecommitdiff
path: root/src/Workspace.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/Workspace.cc')
-rw-r--r--src/Workspace.cc279
1 files changed, 8 insertions, 271 deletions
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
155Workspace::~Workspace() { 150Workspace::~Workspace() {
156 delete [] m_cascade_x;
157 delete [] m_cascade_y;
158} 151}
159 152
160void Workspace::setLastFocusedWindow(FluxboxWindow *win) { 153void Workspace::setLastFocusedWindow(FluxboxWindow *win) {
@@ -427,268 +420,12 @@ void Workspace::updateClientmenu() {
427} 420}
428 421
429void Workspace::placeWindow(FluxboxWindow &win) { 422void 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}