diff options
author | John Sennesael <john@adminking.com> | 2013-08-02 06:56:07 (GMT) |
---|---|---|
committer | Mathias Gumz <akira at fluxbox dot org> | 2013-08-02 06:56:07 (GMT) |
commit | 57ec44e9940992554c8d55b09e885f9c020a209d (patch) | |
tree | 3bb61c8fff06cf677163d38f162dc86c9c4b5e7b /src | |
parent | 58e09b719077605efadac9b712acb8f5e752f732 (diff) | |
download | fluxbox-57ec44e9940992554c8d55b09e885f9c020a209d.zip fluxbox-57ec44e9940992554c8d55b09e885f9c020a209d.tar.bz2 |
Add support for stacked tiling via ArrangeWindows*
Diffstat (limited to 'src')
-rw-r--r-- | src/WorkspaceCmd.cc | 116 | ||||
-rw-r--r-- | src/WorkspaceCmd.hh | 8 |
2 files changed, 107 insertions, 17 deletions
diff --git a/src/WorkspaceCmd.cc b/src/WorkspaceCmd.cc index 42cc05e..2d4de03 100644 --- a/src/WorkspaceCmd.cc +++ b/src/WorkspaceCmd.cc | |||
@@ -186,7 +186,20 @@ FbTk::Command<void> *parseWindowList(const string &command, | |||
186 | } else if (command == "arrangewindowshorizontal") { | 186 | } else if (command == "arrangewindowshorizontal") { |
187 | int method = ArrangeWindowsCmd::HORIZONTAL; | 187 | int method = ArrangeWindowsCmd::HORIZONTAL; |
188 | return new ArrangeWindowsCmd(method,pat); | 188 | return new ArrangeWindowsCmd(method,pat); |
189 | } else if (command == "arrangewindowsstackleft") { | ||
190 | int method = ArrangeWindowsCmd::STACKLEFT; | ||
191 | return new ArrangeWindowsCmd(method,pat); | ||
192 | } else if (command == "arrangewindowsstackright") { | ||
193 | int method = ArrangeWindowsCmd::STACKRIGHT; | ||
194 | return new ArrangeWindowsCmd(method,pat); | ||
195 | } else if (command == "arrangewindowsstacktop") { | ||
196 | int method = ArrangeWindowsCmd::STACKTOP; | ||
197 | return new ArrangeWindowsCmd(method,pat); | ||
198 | } else if (command == "arrangewindowsstackbottom") { | ||
199 | int method = ArrangeWindowsCmd::STACKBOTTOM; | ||
200 | return new ArrangeWindowsCmd(method,pat); | ||
189 | } | 201 | } |
202 | |||
190 | return 0; | 203 | return 0; |
191 | } | 204 | } |
192 | 205 | ||
@@ -198,6 +211,10 @@ REGISTER_COMMAND_PARSER(prevgroup, parseWindowList, void); | |||
198 | REGISTER_COMMAND_PARSER(arrangewindows, parseWindowList, void); | 211 | REGISTER_COMMAND_PARSER(arrangewindows, parseWindowList, void); |
199 | REGISTER_COMMAND_PARSER(arrangewindowsvertical, parseWindowList, void); | 212 | REGISTER_COMMAND_PARSER(arrangewindowsvertical, parseWindowList, void); |
200 | REGISTER_COMMAND_PARSER(arrangewindowshorizontal, parseWindowList, void); | 213 | REGISTER_COMMAND_PARSER(arrangewindowshorizontal, parseWindowList, void); |
214 | REGISTER_COMMAND_PARSER(arrangewindowsstackleft, parseWindowList, void); | ||
215 | REGISTER_COMMAND_PARSER(arrangewindowsstackright, parseWindowList, void); | ||
216 | REGISTER_COMMAND_PARSER(arrangewindowsstacktop, parseWindowList, void); | ||
217 | REGISTER_COMMAND_PARSER(arrangewindowsstackbottom, parseWindowList, void); | ||
201 | 218 | ||
202 | } // end anonymous namespace | 219 | } // end anonymous namespace |
203 | 220 | ||
@@ -217,7 +234,7 @@ void AttachCmd::execute() { | |||
217 | first->attachClient((*it)->fbwindow()->winClient()); | 234 | first->attachClient((*it)->fbwindow()->winClient()); |
218 | } | 235 | } |
219 | } | 236 | } |
220 | 237 | ||
221 | } | 238 | } |
222 | } | 239 | } |
223 | 240 | ||
@@ -393,13 +410,33 @@ void ArrangeWindowsCmd::execute() { | |||
393 | 410 | ||
394 | Workspace::Windows normal_windows; | 411 | Workspace::Windows normal_windows; |
395 | Workspace::Windows shaded_windows; | 412 | Workspace::Windows shaded_windows; |
413 | FluxboxWindow* main_window = NULL; // Main (big) window for stacked modes | ||
396 | for(win = space->windowList().begin(); win != space->windowList().end(); ++win) { | 414 | for(win = space->windowList().begin(); win != space->windowList().end(); ++win) { |
397 | int winhead = screen->getHead((*win)->fbWindow()); | 415 | int winhead = screen->getHead((*win)->fbWindow()); |
398 | if ((winhead == head || winhead == 0) && m_pat.match(**win)) { | 416 | if ((winhead == head || winhead == 0) && m_pat.match(**win)) { |
399 | if ((*win)->isShaded()) | 417 | // If using stacked tiling, and this window is focused, set it as main window |
400 | shaded_windows.push_back(*win); | 418 | if (((m_tile_method == STACKLEFT) || (m_tile_method == STACKRIGHT) |
401 | else | 419 | || (m_tile_method == STACKBOTTOM) || (m_tile_method == STACKTOP)) |
402 | normal_windows.push_back(*win); | 420 | && (*win)->isFocused()){ |
421 | main_window = (*win); | ||
422 | } | ||
423 | else{ | ||
424 | if ((*win)->isShaded()) | ||
425 | shaded_windows.push_back(*win); | ||
426 | else | ||
427 | normal_windows.push_back(*win); | ||
428 | } | ||
429 | } | ||
430 | } | ||
431 | // 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 | ||
433 | // window list. | ||
434 | if (main_window == NULL) | ||
435 | { | ||
436 | if ((m_tile_method == STACKLEFT) || (m_tile_method == STACKRIGHT) | ||
437 | || (m_tile_method == STACKTOP) || (m_tile_method == STACKBOTTOM)) { | ||
438 | main_window = normal_windows.back(); | ||
439 | normal_windows.pop_back(); | ||
403 | } | 440 | } |
404 | } | 441 | } |
405 | 442 | ||
@@ -408,8 +445,16 @@ void ArrangeWindowsCmd::execute() { | |||
408 | if (win_count == 0) | 445 | if (win_count == 0) |
409 | return; | 446 | return; |
410 | 447 | ||
411 | const unsigned int max_width = screen->maxRight(head) - screen->maxLeft(head); | 448 | unsigned int max_width = screen->maxRight(head) - screen->maxLeft(head); |
449 | // If stacked left or right, max width is divided in 2 | ||
450 | if ((m_tile_method == STACKLEFT) || (m_tile_method == STACKRIGHT)){ | ||
451 | max_width = max_width / 2; | ||
452 | } | ||
412 | unsigned int max_height = screen->maxBottom(head) - screen->maxTop(head); | 453 | unsigned int max_height = screen->maxBottom(head) - screen->maxTop(head); |
454 | // If stacked top or bottom, max height is divided in 2 | ||
455 | if ((m_tile_method == STACKTOP) || (m_tile_method == STACKBOTTOM)){ | ||
456 | max_height = max_height / 2; | ||
457 | } | ||
413 | 458 | ||
414 | // try to get the same number of rows as columns. | 459 | // try to get the same number of rows as columns. |
415 | unsigned int cols = int(sqrt((float)win_count)); // truncate to lower | 460 | unsigned int cols = int(sqrt((float)win_count)); // truncate to lower |
@@ -421,7 +466,26 @@ void ArrangeWindowsCmd::execute() { | |||
421 | 466 | ||
422 | unsigned int x_offs = screen->maxLeft(head); // window position offset in x | 467 | unsigned int x_offs = screen->maxLeft(head); // window position offset in x |
423 | unsigned int y_offs = screen->maxTop(head); // window position offset in y | 468 | unsigned int y_offs = screen->maxTop(head); // window position offset in y |
424 | // unsigned int window = 0; // current window | 469 | // Stacked mode only uses half the screen for tiled windows, so adjust offset to half the screen |
470 | // (horizontal or vertical depending on stacking mode) | ||
471 | switch(m_tile_method) | ||
472 | { | ||
473 | case STACKRIGHT: | ||
474 | x_offs = int(abs((screen->maxLeft(head)-screen->maxRight(head)))/2); | ||
475 | break; | ||
476 | case STACKBOTTOM: | ||
477 | y_offs = int(abs(screen->maxBottom(head) - screen->maxTop(head))/2); | ||
478 | break; | ||
479 | default: | ||
480 | // no change needed for STACKLEFT/STACKTOP | ||
481 | break; | ||
482 | } | ||
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 | |||
488 | // unsigned int window = 0; // current window | ||
425 | const unsigned int cal_width = max_width/cols; // calculated width ratio (width of every window) | 489 | const unsigned int cal_width = max_width/cols; // calculated width ratio (width of every window) |
426 | unsigned int i; | 490 | unsigned int i; |
427 | unsigned int j; | 491 | unsigned int j; |
@@ -448,7 +512,7 @@ void ArrangeWindowsCmd::execute() { | |||
448 | 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) |
449 | // Resizes and sets windows positions in columns and rows. | 513 | // Resizes and sets windows positions in columns and rows. |
450 | for (i = 0; i < rows; ++i) { | 514 | for (i = 0; i < rows; ++i) { |
451 | x_offs = screen->maxLeft(head); | 515 | x_offs = orig_x_offs; |
452 | for (j = 0; j < cols && !normal_windows.empty(); ++j) { | 516 | for (j = 0; j < cols && !normal_windows.empty(); ++j) { |
453 | 517 | ||
454 | 518 | ||
@@ -461,7 +525,7 @@ void ArrangeWindowsCmd::execute() { | |||
461 | 525 | ||
462 | int win_center_x = (*win)->frame().x() + ((*win)->frame().x() + (*win)->frame().width() / 2); | 526 | int win_center_x = (*win)->frame().x() + ((*win)->frame().x() + (*win)->frame().width() / 2); |
463 | int win_center_y = (*win)->frame().y() + ((*win)->frame().y() + (*win)->frame().height() / 2); | 527 | int win_center_y = (*win)->frame().y() + ((*win)->frame().y() + (*win)->frame().height() / 2); |
464 | unsigned int dist = (win_center_x - cell_center_x) * (win_center_x - cell_center_x) + | 528 | unsigned int dist = (win_center_x - cell_center_x) * (win_center_x - cell_center_x) + |
465 | (win_center_y - cell_center_y) * (win_center_y - cell_center_y); | 529 | (win_center_y - cell_center_y) * (win_center_y - cell_center_y); |
466 | 530 | ||
467 | if (dist < closest_dist) { | 531 | if (dist < closest_dist) { |
@@ -472,14 +536,14 @@ void ArrangeWindowsCmd::execute() { | |||
472 | 536 | ||
473 | if (normal_windows.size() > 1) { | 537 | if (normal_windows.size() > 1) { |
474 | (*closest)->moveResize(x_offs + (*closest)->xOffset(), | 538 | (*closest)->moveResize(x_offs + (*closest)->xOffset(), |
475 | y_offs + (*closest)->yOffset(), | 539 | y_offs + (*closest)->yOffset(), |
476 | cal_width - (*closest)->widthOffset(), | 540 | cal_width - (*closest)->widthOffset(), |
477 | cal_height - (*closest)->heightOffset()); | 541 | cal_height - (*closest)->heightOffset()); |
478 | } else { // the last window gets everything that is left. | 542 | } else { // the last window gets everything that is left. |
479 | (*closest)->moveResize(x_offs + (*closest)->xOffset(), | 543 | (*closest)->moveResize(x_offs + (*closest)->xOffset(), |
480 | y_offs + (*closest)->yOffset(), | 544 | y_offs + (*closest)->yOffset(), |
481 | screen->maxRight(head) - x_offs - (*closest)->widthOffset(), | 545 | max_width - x_offs - (*closest)->widthOffset(), |
482 | cal_height - (*closest)->heightOffset()); | 546 | cal_height - (*closest)->heightOffset()); |
483 | } | 547 | } |
484 | 548 | ||
485 | normal_windows.erase(closest); | 549 | normal_windows.erase(closest); |
@@ -490,6 +554,28 @@ void ArrangeWindowsCmd::execute() { | |||
490 | // next y offset | 554 | // next y offset |
491 | y_offs += cal_height; | 555 | y_offs += cal_height; |
492 | } | 556 | } |
557 | |||
558 | // If using a stacked mechanism we now need to place the main window. | ||
559 | if (main_window != NULL){ | ||
560 | switch (m_tile_method){ | ||
561 | case STACKLEFT: | ||
562 | main_window->moveResize(max_width,orig_y_offs,max_width,max_height); | ||
563 | break; | ||
564 | case STACKRIGHT: | ||
565 | main_window->moveResize(screen->maxLeft(head),screen->maxTop(head),max_width,max_height); | ||
566 | break; | ||
567 | case STACKTOP: | ||
568 | main_window->moveResize(screen->maxLeft(head),max_height,max_width,max_height); | ||
569 | break; | ||
570 | case STACKBOTTOM: | ||
571 | main_window->moveResize(screen->maxLeft(head),screen->maxTop(head),max_width,max_height); | ||
572 | break; | ||
573 | default: | ||
574 | // Shouldn't happen. | ||
575 | break; | ||
576 | } | ||
577 | } | ||
578 | |||
493 | } | 579 | } |
494 | 580 | ||
495 | REGISTER_COMMAND(showdesktop, ShowDesktopCmd, void); | 581 | REGISTER_COMMAND(showdesktop, ShowDesktopCmd, void); |
diff --git a/src/WorkspaceCmd.hh b/src/WorkspaceCmd.hh index f4f90a6..f4609b6 100644 --- a/src/WorkspaceCmd.hh +++ b/src/WorkspaceCmd.hh | |||
@@ -86,7 +86,7 @@ private: | |||
86 | 86 | ||
87 | class PrevWindowCmd: public FbTk::Command<void> { | 87 | class PrevWindowCmd: public FbTk::Command<void> { |
88 | public: | 88 | public: |
89 | explicit PrevWindowCmd(int option, std::string &pat): | 89 | explicit PrevWindowCmd(int option, std::string &pat): |
90 | m_option(option), m_pat(pat.c_str()) { } | 90 | m_option(option), m_pat(pat.c_str()) { } |
91 | void execute(); | 91 | void execute(); |
92 | private: | 92 | private: |
@@ -173,7 +173,11 @@ public: | |||
173 | enum { | 173 | enum { |
174 | UNSPECIFIED, | 174 | UNSPECIFIED, |
175 | VERTICAL, | 175 | VERTICAL, |
176 | HORIZONTAL | 176 | HORIZONTAL, |
177 | STACKLEFT, | ||
178 | STACKRIGHT, | ||
179 | STACKTOP, | ||
180 | STACKBOTTOM | ||
177 | }; | 181 | }; |
178 | explicit ArrangeWindowsCmd(int tile_method, std::string &pat): | 182 | explicit ArrangeWindowsCmd(int tile_method, std::string &pat): |
179 | m_tile_method( tile_method ), m_pat(pat.c_str()) { } | 183 | m_tile_method( tile_method ), m_pat(pat.c_str()) { } |