Add support for stacked tiling via ArrangeWindows*
This commit is contained in:
parent
58e09b7190
commit
57ec44e994
3 changed files with 124 additions and 17 deletions
|
@ -417,6 +417,23 @@ doing so.
|
|||
splits (windows on top of eachother). See *CLIENT PATTERNS* for more about the
|
||||
'pattern' arguments.
|
||||
|
||||
*ArrangeWindowsStackLeft* 'pattern' / *ArrangeWindowsStackRight* 'pattern'::
|
||||
Similar to *ArrangeWindows*, these commands arrange windows on the current
|
||||
workspace. The currently focussed window is used as the 'main' window, and
|
||||
will fill half the screen, while the other windows are tiled on the
|
||||
other half of the screen as if they were tiled with ArrangeWindows.
|
||||
*ArrangeWindowsStackLeft* puts the main window on the RIGHT hand side of the
|
||||
screen, and the tiled windows are on the LEFT hand side of the screen.
|
||||
*ArrangeWindowsStackRight* puts the main window on the LEFT hand side of the
|
||||
screen, and the tiled windows are on the RIGHT hand side of the screen.
|
||||
|
||||
*ArrangeWindowsStackTop* 'pattern' / *ArrangeWindowsStackBottom 'pattern'::
|
||||
Behaves just like *ArrangeWindowsStackLeft* and *ArrangeWindowsStackRight*.
|
||||
*ArrangeWindowsStackBottom* places the main window on the TOP half of the
|
||||
screen, and the tiled windows on the bottom half of the screen.
|
||||
*ArrangeWindowsStackTop* places the main window on the BOTTOM half of the
|
||||
screen and the tiled windows on the top half of the screen.
|
||||
|
||||
*ShowDesktop*::
|
||||
Minimizes all windows on the current workspace. If they are already all
|
||||
minimized, then it restores them.
|
||||
|
|
|
@ -186,7 +186,20 @@ FbTk::Command<void> *parseWindowList(const string &command,
|
|||
} else if (command == "arrangewindowshorizontal") {
|
||||
int method = ArrangeWindowsCmd::HORIZONTAL;
|
||||
return new ArrangeWindowsCmd(method,pat);
|
||||
} else if (command == "arrangewindowsstackleft") {
|
||||
int method = ArrangeWindowsCmd::STACKLEFT;
|
||||
return new ArrangeWindowsCmd(method,pat);
|
||||
} else if (command == "arrangewindowsstackright") {
|
||||
int method = ArrangeWindowsCmd::STACKRIGHT;
|
||||
return new ArrangeWindowsCmd(method,pat);
|
||||
} else if (command == "arrangewindowsstacktop") {
|
||||
int method = ArrangeWindowsCmd::STACKTOP;
|
||||
return new ArrangeWindowsCmd(method,pat);
|
||||
} else if (command == "arrangewindowsstackbottom") {
|
||||
int method = ArrangeWindowsCmd::STACKBOTTOM;
|
||||
return new ArrangeWindowsCmd(method,pat);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -198,6 +211,10 @@ REGISTER_COMMAND_PARSER(prevgroup, parseWindowList, void);
|
|||
REGISTER_COMMAND_PARSER(arrangewindows, parseWindowList, void);
|
||||
REGISTER_COMMAND_PARSER(arrangewindowsvertical, parseWindowList, void);
|
||||
REGISTER_COMMAND_PARSER(arrangewindowshorizontal, parseWindowList, void);
|
||||
REGISTER_COMMAND_PARSER(arrangewindowsstackleft, parseWindowList, void);
|
||||
REGISTER_COMMAND_PARSER(arrangewindowsstackright, parseWindowList, void);
|
||||
REGISTER_COMMAND_PARSER(arrangewindowsstacktop, parseWindowList, void);
|
||||
REGISTER_COMMAND_PARSER(arrangewindowsstackbottom, parseWindowList, void);
|
||||
|
||||
} // end anonymous namespace
|
||||
|
||||
|
@ -217,7 +234,7 @@ void AttachCmd::execute() {
|
|||
first->attachClient((*it)->fbwindow()->winClient());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -393,13 +410,33 @@ void ArrangeWindowsCmd::execute() {
|
|||
|
||||
Workspace::Windows normal_windows;
|
||||
Workspace::Windows shaded_windows;
|
||||
FluxboxWindow* main_window = NULL; // Main (big) window for stacked modes
|
||||
for(win = space->windowList().begin(); win != space->windowList().end(); ++win) {
|
||||
int winhead = screen->getHead((*win)->fbWindow());
|
||||
if ((winhead == head || winhead == 0) && m_pat.match(**win)) {
|
||||
if ((*win)->isShaded())
|
||||
shaded_windows.push_back(*win);
|
||||
else
|
||||
normal_windows.push_back(*win);
|
||||
// If using stacked tiling, and this window is focused, set it as main window
|
||||
if (((m_tile_method == STACKLEFT) || (m_tile_method == STACKRIGHT)
|
||||
|| (m_tile_method == STACKBOTTOM) || (m_tile_method == STACKTOP))
|
||||
&& (*win)->isFocused()){
|
||||
main_window = (*win);
|
||||
}
|
||||
else{
|
||||
if ((*win)->isShaded())
|
||||
shaded_windows.push_back(*win);
|
||||
else
|
||||
normal_windows.push_back(*win);
|
||||
}
|
||||
}
|
||||
}
|
||||
// if using stacked-left/right/top/bottom and we don't have a main window yet
|
||||
// (no focused window?), we'll fall back on using the last window in the
|
||||
// window list.
|
||||
if (main_window == NULL)
|
||||
{
|
||||
if ((m_tile_method == STACKLEFT) || (m_tile_method == STACKRIGHT)
|
||||
|| (m_tile_method == STACKTOP) || (m_tile_method == STACKBOTTOM)) {
|
||||
main_window = normal_windows.back();
|
||||
normal_windows.pop_back();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -408,8 +445,16 @@ void ArrangeWindowsCmd::execute() {
|
|||
if (win_count == 0)
|
||||
return;
|
||||
|
||||
const unsigned int max_width = screen->maxRight(head) - screen->maxLeft(head);
|
||||
unsigned int max_width = screen->maxRight(head) - screen->maxLeft(head);
|
||||
// If stacked left or right, max width is divided in 2
|
||||
if ((m_tile_method == STACKLEFT) || (m_tile_method == STACKRIGHT)){
|
||||
max_width = max_width / 2;
|
||||
}
|
||||
unsigned int max_height = screen->maxBottom(head) - screen->maxTop(head);
|
||||
// If stacked top or bottom, max height is divided in 2
|
||||
if ((m_tile_method == STACKTOP) || (m_tile_method == STACKBOTTOM)){
|
||||
max_height = max_height / 2;
|
||||
}
|
||||
|
||||
// try to get the same number of rows as columns.
|
||||
unsigned int cols = int(sqrt((float)win_count)); // truncate to lower
|
||||
|
@ -421,7 +466,26 @@ void ArrangeWindowsCmd::execute() {
|
|||
|
||||
unsigned int x_offs = screen->maxLeft(head); // window position offset in x
|
||||
unsigned int y_offs = screen->maxTop(head); // window position offset in y
|
||||
// unsigned int window = 0; // current window
|
||||
// Stacked mode only uses half the screen for tiled windows, so adjust offset to half the screen
|
||||
// (horizontal or vertical depending on stacking mode)
|
||||
switch(m_tile_method)
|
||||
{
|
||||
case STACKRIGHT:
|
||||
x_offs = int(abs((screen->maxLeft(head)-screen->maxRight(head)))/2);
|
||||
break;
|
||||
case STACKBOTTOM:
|
||||
y_offs = int(abs(screen->maxBottom(head) - screen->maxTop(head))/2);
|
||||
break;
|
||||
default:
|
||||
// no change needed for STACKLEFT/STACKTOP
|
||||
break;
|
||||
}
|
||||
// Since the placing algorithm loop below modifies the offsets, but we still need them to
|
||||
// position the main window, we save the calculated values.
|
||||
const unsigned int orig_x_offs = x_offs;
|
||||
const unsigned int orig_y_offs = y_offs;
|
||||
|
||||
// unsigned int window = 0; // current window
|
||||
const unsigned int cal_width = max_width/cols; // calculated width ratio (width of every window)
|
||||
unsigned int i;
|
||||
unsigned int j;
|
||||
|
@ -448,7 +512,7 @@ void ArrangeWindowsCmd::execute() {
|
|||
const unsigned int cal_height = max_height/rows; // height ratio (height of every window)
|
||||
// Resizes and sets windows positions in columns and rows.
|
||||
for (i = 0; i < rows; ++i) {
|
||||
x_offs = screen->maxLeft(head);
|
||||
x_offs = orig_x_offs;
|
||||
for (j = 0; j < cols && !normal_windows.empty(); ++j) {
|
||||
|
||||
|
||||
|
@ -461,7 +525,7 @@ void ArrangeWindowsCmd::execute() {
|
|||
|
||||
int win_center_x = (*win)->frame().x() + ((*win)->frame().x() + (*win)->frame().width() / 2);
|
||||
int win_center_y = (*win)->frame().y() + ((*win)->frame().y() + (*win)->frame().height() / 2);
|
||||
unsigned int dist = (win_center_x - cell_center_x) * (win_center_x - cell_center_x) +
|
||||
unsigned int dist = (win_center_x - cell_center_x) * (win_center_x - cell_center_x) +
|
||||
(win_center_y - cell_center_y) * (win_center_y - cell_center_y);
|
||||
|
||||
if (dist < closest_dist) {
|
||||
|
@ -472,14 +536,14 @@ void ArrangeWindowsCmd::execute() {
|
|||
|
||||
if (normal_windows.size() > 1) {
|
||||
(*closest)->moveResize(x_offs + (*closest)->xOffset(),
|
||||
y_offs + (*closest)->yOffset(),
|
||||
cal_width - (*closest)->widthOffset(),
|
||||
cal_height - (*closest)->heightOffset());
|
||||
y_offs + (*closest)->yOffset(),
|
||||
cal_width - (*closest)->widthOffset(),
|
||||
cal_height - (*closest)->heightOffset());
|
||||
} else { // the last window gets everything that is left.
|
||||
(*closest)->moveResize(x_offs + (*closest)->xOffset(),
|
||||
y_offs + (*closest)->yOffset(),
|
||||
screen->maxRight(head) - x_offs - (*closest)->widthOffset(),
|
||||
cal_height - (*closest)->heightOffset());
|
||||
y_offs + (*closest)->yOffset(),
|
||||
max_width - x_offs - (*closest)->widthOffset(),
|
||||
cal_height - (*closest)->heightOffset());
|
||||
}
|
||||
|
||||
normal_windows.erase(closest);
|
||||
|
@ -490,6 +554,28 @@ void ArrangeWindowsCmd::execute() {
|
|||
// next y offset
|
||||
y_offs += cal_height;
|
||||
}
|
||||
|
||||
// If using a stacked mechanism we now need to place the main window.
|
||||
if (main_window != NULL){
|
||||
switch (m_tile_method){
|
||||
case STACKLEFT:
|
||||
main_window->moveResize(max_width,orig_y_offs,max_width,max_height);
|
||||
break;
|
||||
case STACKRIGHT:
|
||||
main_window->moveResize(screen->maxLeft(head),screen->maxTop(head),max_width,max_height);
|
||||
break;
|
||||
case STACKTOP:
|
||||
main_window->moveResize(screen->maxLeft(head),max_height,max_width,max_height);
|
||||
break;
|
||||
case STACKBOTTOM:
|
||||
main_window->moveResize(screen->maxLeft(head),screen->maxTop(head),max_width,max_height);
|
||||
break;
|
||||
default:
|
||||
// Shouldn't happen.
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
REGISTER_COMMAND(showdesktop, ShowDesktopCmd, void);
|
||||
|
|
|
@ -86,7 +86,7 @@ private:
|
|||
|
||||
class PrevWindowCmd: public FbTk::Command<void> {
|
||||
public:
|
||||
explicit PrevWindowCmd(int option, std::string &pat):
|
||||
explicit PrevWindowCmd(int option, std::string &pat):
|
||||
m_option(option), m_pat(pat.c_str()) { }
|
||||
void execute();
|
||||
private:
|
||||
|
@ -173,7 +173,11 @@ public:
|
|||
enum {
|
||||
UNSPECIFIED,
|
||||
VERTICAL,
|
||||
HORIZONTAL
|
||||
HORIZONTAL,
|
||||
STACKLEFT,
|
||||
STACKRIGHT,
|
||||
STACKTOP,
|
||||
STACKBOTTOM
|
||||
};
|
||||
explicit ArrangeWindowsCmd(int tile_method, std::string &pat):
|
||||
m_tile_method( tile_method ), m_pat(pat.c_str()) { }
|
||||
|
|
Loading…
Reference in a new issue