aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMathias Gumz <akira at fluxbox dot org>2013-08-02 09:19:26 (GMT)
committerMathias Gumz <akira at fluxbox dot org>2013-08-02 09:19:26 (GMT)
commitff3635ad0aa55f781314ff8b43ed3183cfb12ab6 (patch)
tree8ae5cbc88d0d61d1b7665086d997f038c9f68289
parent57ec44e9940992554c8d55b09e885f9c020a209d (diff)
downloadfluxbox-ff3635ad0aa55f781314ff8b43ed3183cfb12ab6.zip
fluxbox-ff3635ad0aa55f781314ff8b43ed3183cfb12ab6.tar.bz2
Fix ArrangeWindowsStack* for multi-head displays
* Fix integer wrap around for some situations (resulting in a very wide window): w = max_width - x_offs - (*closest)->widthOffset() If the given window is on the right most display and thus 'x_offs' is bigger than 'max_width' (half of the display width), the resulting 'w' wraps around and becomes very large. * Place a single window via ArrangeWindowsStack* as well * Some minor code styling / reordering along the way
-rw-r--r--src/WorkspaceCmd.cc129
1 files changed, 67 insertions, 62 deletions
diff --git a/src/WorkspaceCmd.cc b/src/WorkspaceCmd.cc
index 2d4de03..ea4d617 100644
--- a/src/WorkspaceCmd.cc
+++ b/src/WorkspaceCmd.cc
@@ -407,20 +407,17 @@ void ArrangeWindowsCmd::execute() {
407 // - only on current head 407 // - only on current head
408 const int head = screen->getCurrHead(); 408 const int head = screen->getCurrHead();
409 Workspace::Windows::iterator win; 409 Workspace::Windows::iterator win;
410
411 Workspace::Windows normal_windows; 410 Workspace::Windows normal_windows;
412 Workspace::Windows shaded_windows; 411 Workspace::Windows shaded_windows;
413 FluxboxWindow* main_window = NULL; // Main (big) window for stacked modes 412 FluxboxWindow* main_window = NULL; // Main (big) window for stacked modes
414 for(win = space->windowList().begin(); win != space->windowList().end(); ++win) { 413
414 for (win = space->windowList().begin(); win != space->windowList().end(); ++win) {
415 int winhead = screen->getHead((*win)->fbWindow()); 415 int winhead = screen->getHead((*win)->fbWindow());
416 if ((winhead == head || winhead == 0) && m_pat.match(**win)) { 416 if ((winhead == head || winhead == 0) && m_pat.match(**win)) {
417 // If using stacked tiling, and this window is focused, set it as main window 417
418 if (((m_tile_method == STACKLEFT) || (m_tile_method == STACKRIGHT) 418 if ((m_tile_method >= STACKLEFT) && (*win)->isFocused()) {
419 || (m_tile_method == STACKBOTTOM) || (m_tile_method == STACKTOP))
420 && (*win)->isFocused()){
421 main_window = (*win); 419 main_window = (*win);
422 } 420 } else {
423 else{
424 if ((*win)->isShaded()) 421 if ((*win)->isShaded())
425 shaded_windows.push_back(*win); 422 shaded_windows.push_back(*win);
426 else 423 else
@@ -428,31 +425,35 @@ void ArrangeWindowsCmd::execute() {
428 } 425 }
429 } 426 }
430 } 427 }
428
431 // if using stacked-left/right/top/bottom and we don't have a main window yet 429 // if using stacked-left/right/top/bottom and we don't have a main window yet
432 // (no focused window?), we'll fall back on using the last window in the 430 // (no focused window?), we'll fall back on using the last window in the
433 // window list. 431 // window list.
434 if (main_window == NULL) 432 if (main_window == NULL && (m_tile_method >= STACKLEFT)) {
435 { 433 main_window = normal_windows.back();
436 if ((m_tile_method == STACKLEFT) || (m_tile_method == STACKRIGHT) 434 normal_windows.pop_back();
437 || (m_tile_method == STACKTOP) || (m_tile_method == STACKBOTTOM)) {
438 main_window = normal_windows.back();
439 normal_windows.pop_back();
440 }
441 } 435 }
442 436
443 // to arrange only shaded windows is a bit pointless imho (mathias) 437 // to arrange only shaded windows is a bit pointless imho (mathias)
444 size_t win_count = normal_windows.size(); 438 size_t win_count = normal_windows.size();
445 if (win_count == 0) 439 if (win_count == 0) {
446 return; 440 if (!main_window) {
441 return;
442 }
443 win_count = 1;
444 }
447 445
446
447 int x_offs = screen->maxLeft(head); // window position offset in x
448 int y_offs = screen->maxTop(head); // window position offset in y
448 unsigned int max_width = screen->maxRight(head) - screen->maxLeft(head); 449 unsigned int max_width = screen->maxRight(head) - screen->maxLeft(head);
449 // If stacked left or right, max width is divided in 2 450 unsigned int max_height = screen->maxBottom(head) - screen->maxTop(head);
450 if ((m_tile_method == STACKLEFT) || (m_tile_method == STACKRIGHT)){ 451
452 if ((m_tile_method == STACKLEFT) || (m_tile_method == STACKRIGHT)) {
451 max_width = max_width / 2; 453 max_width = max_width / 2;
452 } 454 }
453 unsigned int max_height = screen->maxBottom(head) - screen->maxTop(head); 455
454 // If stacked top or bottom, max height is divided in 2 456 if ((m_tile_method == STACKTOP) || (m_tile_method == STACKBOTTOM)) {
455 if ((m_tile_method == STACKTOP) || (m_tile_method == STACKBOTTOM)){
456 max_height = max_height / 2; 457 max_height = max_height / 2;
457 } 458 }
458 459
@@ -464,29 +465,27 @@ void ArrangeWindowsCmd::execute() {
464 std::swap(cols, rows); 465 std::swap(cols, rows);
465 } 466 }
466 467
467 unsigned int x_offs = screen->maxLeft(head); // window position offset in x 468 // Stacked mode only uses half the screen for tiled windows, so adjust
468 unsigned int y_offs = screen->maxTop(head); // window position offset in y 469 // offset to half the screen (horizontal or vertical depending on
469 // Stacked mode only uses half the screen for tiled windows, so adjust offset to half the screen 470 // stacking mode)
470 // (horizontal or vertical depending on stacking mode) 471 switch (m_tile_method) {
471 switch(m_tile_method) 472 case STACKRIGHT:
472 { 473 x_offs += static_cast<int>(max_width);
473 case STACKRIGHT: 474 break;
474 x_offs = int(abs((screen->maxLeft(head)-screen->maxRight(head)))/2); 475 case STACKBOTTOM:
475 break; 476 y_offs += static_cast<int>(max_height);
476 case STACKBOTTOM: 477 break;
477 y_offs = int(abs(screen->maxBottom(head) - screen->maxTop(head))/2); 478 default:
478 break; 479 // no change needed for STACKLEFT/STACKTOP
479 default: 480 break;
480 // no change needed for STACKLEFT/STACKTOP
481 break;
482 } 481 }
483 // Since the placing algorithm loop below modifies the offsets, but we still need them to
484 // position the main window, we save the calculated values.
485 const unsigned int orig_x_offs = x_offs;
486 const unsigned int orig_y_offs = y_offs;
487 482
488 // unsigned int window = 0; // current window 483 // Since the placing algorithm loop below modifies the offsets, but we
489 const unsigned int cal_width = max_width/cols; // calculated width ratio (width of every window) 484 // still need them to position the main window, we save the calculated
485 // values.
486 const int orig_x_offs = x_offs;
487 const int orig_y_offs = y_offs;
488
490 unsigned int i; 489 unsigned int i;
491 unsigned int j; 490 unsigned int j;
492 491
@@ -509,7 +508,9 @@ void ArrangeWindowsCmd::execute() {
509 if (!shaded_windows.empty()) 508 if (!shaded_windows.empty())
510 max_height -= i * (*shaded_windows.begin())->frame().height(); 509 max_height -= i * (*shaded_windows.begin())->frame().height();
511 510
511 const unsigned int cal_width = max_width/cols; // width ratio (width of every window)
512 const unsigned int cal_height = max_height/rows; // height ratio (height of every window) 512 const unsigned int cal_height = max_height/rows; // height ratio (height of every window)
513
513 // Resizes and sets windows positions in columns and rows. 514 // Resizes and sets windows positions in columns and rows.
514 for (i = 0; i < rows; ++i) { 515 for (i = 0; i < rows; ++i) {
515 x_offs = orig_x_offs; 516 x_offs = orig_x_offs;
@@ -534,48 +535,52 @@ void ArrangeWindowsCmd::execute() {
534 } 535 }
535 } 536 }
536 537
537 if (normal_windows.size() > 1) { 538 int x = x_offs + (*closest)->xOffset();
538 (*closest)->moveResize(x_offs + (*closest)->xOffset(), 539 int y = y_offs + (*closest)->yOffset();
539 y_offs + (*closest)->yOffset(), 540 unsigned int w = cal_width - (*closest)->widthOffset();
540 cal_width - (*closest)->widthOffset(), 541 unsigned int h = cal_height - (*closest)->heightOffset();
541 cal_height - (*closest)->heightOffset()); 542
542 } else { // the last window gets everything that is left. 543 // the last window gets everything that is left.
543 (*closest)->moveResize(x_offs + (*closest)->xOffset(), 544 if (normal_windows.size() == 1) {
544 y_offs + (*closest)->yOffset(), 545
545 max_width - x_offs - (*closest)->widthOffset(), 546 w = static_cast<int>(screen->maxRight(head)) - x_offs - (*closest)->widthOffset();
546 cal_height - (*closest)->heightOffset()); 547 h = static_cast<int>(cal_height) - (*closest)->heightOffset();
548
549 if (m_tile_method == STACKLEFT) {
550 w -= max_width;
551 }
547 } 552 }
548 553
554 (*closest)->moveResize(x, y, w, h);
549 normal_windows.erase(closest); 555 normal_windows.erase(closest);
550 556
551 // next x offset 557 x_offs += static_cast<int>(cal_width);
552 x_offs += cal_width;
553 } 558 }
554 // next y offset 559
555 y_offs += cal_height; 560 y_offs += static_cast<int>(cal_height);
556 } 561 }
557 562
558 // If using a stacked mechanism we now need to place the main window. 563 // If using a stacked mechanism we now need to place the main window.
559 if (main_window != NULL){ 564 if (main_window != NULL){
565 x_offs = screen->maxLeft(head);
560 switch (m_tile_method){ 566 switch (m_tile_method){
561 case STACKLEFT: 567 case STACKLEFT:
562 main_window->moveResize(max_width,orig_y_offs,max_width,max_height); 568 main_window->moveResize(x_offs + max_width, orig_y_offs, max_width, max_height);
563 break; 569 break;
564 case STACKRIGHT: 570 case STACKRIGHT:
565 main_window->moveResize(screen->maxLeft(head),screen->maxTop(head),max_width,max_height); 571 main_window->moveResize(x_offs, screen->maxTop(head), max_width, max_height);
566 break; 572 break;
567 case STACKTOP: 573 case STACKTOP:
568 main_window->moveResize(screen->maxLeft(head),max_height,max_width,max_height); 574 main_window->moveResize(x_offs, max_height, max_width, max_height);
569 break; 575 break;
570 case STACKBOTTOM: 576 case STACKBOTTOM:
571 main_window->moveResize(screen->maxLeft(head),screen->maxTop(head),max_width,max_height); 577 main_window->moveResize(x_offs, screen->maxTop(head), max_width, max_height);
572 break; 578 break;
573 default: 579 default:
574 // Shouldn't happen. 580 // Shouldn't happen.
575 break; 581 break;
576 } 582 }
577 } 583 }
578
579} 584}
580 585
581REGISTER_COMMAND(showdesktop, ShowDesktopCmd, void); 586REGISTER_COMMAND(showdesktop, ShowDesktopCmd, void);