aboutsummaryrefslogtreecommitdiff
path: root/src
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 /src
parent58e09b719077605efadac9b712acb8f5e752f732 (diff)
downloadfluxbox-57ec44e9940992554c8d55b09e885f9c020a209d.zip
fluxbox-57ec44e9940992554c8d55b09e885f9c020a209d.tar.bz2
Add support for stacked tiling via ArrangeWindows*
Diffstat (limited to 'src')
-rw-r--r--src/WorkspaceCmd.cc116
-rw-r--r--src/WorkspaceCmd.hh8
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);
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()) { }