diff options
author | Mathias Gumz <akira at fluxbox dot org> | 2013-08-02 09:19:26 (GMT) |
---|---|---|
committer | Mathias Gumz <akira at fluxbox dot org> | 2013-08-02 09:19:26 (GMT) |
commit | ff3635ad0aa55f781314ff8b43ed3183cfb12ab6 (patch) | |
tree | 8ae5cbc88d0d61d1b7665086d997f038c9f68289 /src | |
parent | 57ec44e9940992554c8d55b09e885f9c020a209d (diff) | |
download | fluxbox-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
Diffstat (limited to 'src')
-rw-r--r-- | src/WorkspaceCmd.cc | 129 |
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 | ||
581 | REGISTER_COMMAND(showdesktop, ShowDesktopCmd, void); | 586 | REGISTER_COMMAND(showdesktop, ShowDesktopCmd, void); |