diff options
Diffstat (limited to 'src/Workspace.cc')
-rw-r--r-- | src/Workspace.cc | 279 |
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 | ||
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 | } |