aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohn Sennesael <john@adminking.com>2013-08-02 06:56:07 (GMT)
committerMathias Gumz <akira at fluxbox dot org>2013-08-02 06:56:07 (GMT)
commit57ec44e9940992554c8d55b09e885f9c020a209d (patch)
tree3bb61c8fff06cf677163d38f162dc86c9c4b5e7b
parent58e09b719077605efadac9b712acb8f5e752f732 (diff)
downloadfluxbox-57ec44e9940992554c8d55b09e885f9c020a209d.zip
fluxbox-57ec44e9940992554c8d55b09e885f9c020a209d.tar.bz2
Add support for stacked tiling via ArrangeWindows*
-rw-r--r--doc/asciidoc/fluxbox-keys.txt17
-rw-r--r--src/WorkspaceCmd.cc116
-rw-r--r--src/WorkspaceCmd.hh8
3 files changed, 124 insertions, 17 deletions
diff --git a/doc/asciidoc/fluxbox-keys.txt b/doc/asciidoc/fluxbox-keys.txt
index 02fc745..4d92c43 100644
--- a/doc/asciidoc/fluxbox-keys.txt
+++ b/doc/asciidoc/fluxbox-keys.txt
@@ -417,6 +417,23 @@ doing so.
417 splits (windows on top of eachother). See *CLIENT PATTERNS* for more about the 417 splits (windows on top of eachother). See *CLIENT PATTERNS* for more about the
418 'pattern' arguments. 418 'pattern' arguments.
419 419
420*ArrangeWindowsStackLeft* 'pattern' / *ArrangeWindowsStackRight* 'pattern'::
421 Similar to *ArrangeWindows*, these commands arrange windows on the current
422 workspace. The currently focussed window is used as the 'main' window, and
423 will fill half the screen, while the other windows are tiled on the
424 other half of the screen as if they were tiled with ArrangeWindows.
425 *ArrangeWindowsStackLeft* puts the main window on the RIGHT hand side of the
426 screen, and the tiled windows are on the LEFT hand side of the screen.
427 *ArrangeWindowsStackRight* puts the main window on the LEFT hand side of the
428 screen, and the tiled windows are on the RIGHT hand side of the screen.
429
430*ArrangeWindowsStackTop* 'pattern' / *ArrangeWindowsStackBottom 'pattern'::
431 Behaves just like *ArrangeWindowsStackLeft* and *ArrangeWindowsStackRight*.
432 *ArrangeWindowsStackBottom* places the main window on the TOP half of the
433 screen, and the tiled windows on the bottom half of the screen.
434 *ArrangeWindowsStackTop* places the main window on the BOTTOM half of the
435 screen and the tiled windows on the top half of the screen.
436
420*ShowDesktop*:: 437*ShowDesktop*::
421 Minimizes all windows on the current workspace. If they are already all 438 Minimizes all windows on the current workspace. If they are already all
422 minimized, then it restores them. 439 minimized, then it restores them.
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);
198REGISTER_COMMAND_PARSER(arrangewindows, parseWindowList, void); 211REGISTER_COMMAND_PARSER(arrangewindows, parseWindowList, void);
199REGISTER_COMMAND_PARSER(arrangewindowsvertical, parseWindowList, void); 212REGISTER_COMMAND_PARSER(arrangewindowsvertical, parseWindowList, void);
200REGISTER_COMMAND_PARSER(arrangewindowshorizontal, parseWindowList, void); 213REGISTER_COMMAND_PARSER(arrangewindowshorizontal, parseWindowList, void);
214REGISTER_COMMAND_PARSER(arrangewindowsstackleft, parseWindowList, void);
215REGISTER_COMMAND_PARSER(arrangewindowsstackright, parseWindowList, void);
216REGISTER_COMMAND_PARSER(arrangewindowsstacktop, parseWindowList, void);
217REGISTER_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
495REGISTER_COMMAND(showdesktop, ShowDesktopCmd, void); 581REGISTER_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
87class PrevWindowCmd: public FbTk::Command<void> { 87class PrevWindowCmd: public FbTk::Command<void> {
88public: 88public:
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();
92private: 92private:
@@ -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()) { }