fluxbox/src/WorkspaceCmd.cc
Thomas Lübking a5b5be5e09 Add "Unclutter" command
Unclutter the desktop by using the MinOverlapPlacement
for all matching windows.

REQUEST: 248
2016-08-30 22:02:59 +02:00

754 lines
26 KiB
C++

// WorkspaceCmd.cc for Fluxbox - an X11 Window manager
// Copyright (c) 2003 - 2006 Henrik Kinnunen (fluxgen at fluxbox dot org)
// and Simon Bowden (rathnor at users.sourceforge.net)
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the "Software"),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
// and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
#include "WorkspaceCmd.hh"
#include "Layer.hh"
#include "MinOverlapPlacement.hh"
#include "Workspace.hh"
#include "Window.hh"
#include "Screen.hh"
#include "Slit.hh"
#include "Toolbar.hh"
#include "fluxbox.hh"
#include "WinClient.hh"
#include "FocusControl.hh"
#include "WindowCmd.hh"
#include "FbTk/KeyUtil.hh"
#include "FbTk/CommandParser.hh"
#include "FbTk/stringstream.hh"
#include "FbTk/StringUtil.hh"
#ifdef HAVE_CMATH
#include <cmath>
#else
#include <math.h>
#endif
#include <algorithm>
#include <functional>
#include <vector>
using std::string;
REGISTER_COMMAND_PARSER(map, WindowListCmd::parse, void);
REGISTER_COMMAND_PARSER(foreach, WindowListCmd::parse, void);
FbTk::Command<void> *WindowListCmd::parse(const string &command, const string &args,
bool trusted) {
FbTk::Command<void> *cmd = 0;
FbTk::Command<bool> *filter = 0;
std::vector<string> tokens;
int opts = 0;
string pat;
FbTk::StringUtil::stringTokensBetween(tokens, args, pat, '{', '}');
if (tokens.empty())
return 0;
cmd = FbTk::CommandParser<void>::instance().parse(tokens[0], trusted);
if (!cmd)
return 0;
if (tokens.size() > 1) {
FocusableList::parseArgs(tokens[1], opts, pat);
filter = FbTk::CommandParser<bool>::instance().parse(pat, trusted);
}
return new WindowListCmd(FbTk::RefCount<FbTk::Command<void> >(cmd), opts,
FbTk::RefCount<FbTk::Command<bool> >(filter));
}
void WindowListCmd::execute() {
BScreen *screen = Fluxbox::instance()->keyScreen();
if (screen != 0) {
FocusableList::Focusables win_list(FocusableList::getListFromOptions(*screen, m_opts)->clientList());
FocusableList::Focusables::iterator it = win_list.begin(),
it_end = win_list.end();
// save old value, so we can restore it later
WinClient *old = WindowCmd<void>::client();
for (; it != it_end; ++it) {
Focusable* wptr = *it;
if (typeid(*wptr) == typeid(FluxboxWindow)) {
WindowCmd<void>::setWindow((wptr)->fbwindow());
} else if (typeid(*wptr) == typeid(WinClient)) {
WindowCmd<void>::setClient(dynamic_cast<WinClient *>(wptr));
}
if (!m_filter || m_filter->execute()) {
m_cmd->execute();
}
}
WindowCmd<void>::setClient(old);
}
}
FbTk::Command<bool> *SomeCmd::parse(const string &command, const string &args,
bool trusted) {
FbTk::Command<bool> *boolcmd =
FbTk::CommandParser<bool>::instance().parse(args,
trusted);
if (!boolcmd)
return 0;
if (command == "some")
return new SomeCmd(FbTk::RefCount<FbTk::Command<bool> >(boolcmd));
return new EveryCmd(FbTk::RefCount<FbTk::Command<bool> >(boolcmd));
}
REGISTER_COMMAND_PARSER(some, SomeCmd::parse, bool);
REGISTER_COMMAND_PARSER(every, SomeCmd::parse, bool);
bool SomeCmd::execute() {
BScreen *screen = Fluxbox::instance()->keyScreen();
if (screen != 0) {
FocusControl::Focusables win_list(screen->focusControl().creationOrderList().clientList());
FocusControl::Focusables::iterator it = win_list.begin(),
it_end = win_list.end();
// save old value, so we can restore it later
WinClient *old = WindowCmd<void>::client();
for (; it != it_end; ++it) {
WinClient *client = dynamic_cast<WinClient *>(*it);
if (!client) continue;
WindowCmd<void>::setClient(client);
if (m_cmd->execute()) {
WindowCmd<void>::setClient(old);
return true;
}
}
WindowCmd<void>::setClient(old);
}
return false;
}
bool EveryCmd::execute() {
BScreen *screen = Fluxbox::instance()->keyScreen();
if (screen != 0) {
FocusControl::Focusables win_list(screen->focusControl().creationOrderList().clientList());
FocusControl::Focusables::iterator it = win_list.begin(),
it_end = win_list.end();
// save old value, so we can restore it later
WinClient *old = WindowCmd<void>::client();
for (; it != it_end; ++it) {
WinClient *client = dynamic_cast<WinClient *>(*it);
if (!client) continue;
WindowCmd<void>::setClient(client);
if (!m_cmd->execute()) {
WindowCmd<void>::setClient(old);
return false;
}
}
WindowCmd<void>::setClient(old);
}
return true;
}
namespace {
FbTk::Command<void> *parseWindowList(const string &command,
const string &args, bool trusted) {
int opts;
string pat;
FocusableList::parseArgs(args, opts, pat);
if (command == "attach")
return new AttachCmd(pat);
else if (command == "nextwindow")
return new NextWindowCmd(opts, pat);
else if (command == "nextgroup") {
opts |= FocusableList::LIST_GROUPS;
return new NextWindowCmd(opts, pat);
} else if (command == "prevwindow")
return new PrevWindowCmd(opts, pat);
else if (command == "prevgroup") {
opts |= FocusableList::LIST_GROUPS;
return new PrevWindowCmd(opts, pat);
} else if (command == "arrangewindows") {
int method = ArrangeWindowsCmd::UNSPECIFIED;
return new ArrangeWindowsCmd(method,pat);
} else if (command == "arrangewindowsvertical") {
int method = ArrangeWindowsCmd::VERTICAL;
return new ArrangeWindowsCmd(method,pat);
} 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);
} else if (command == "unclutter") {
return new UnclutterCmd(pat);
}
return 0;
}
REGISTER_COMMAND_PARSER(attach, parseWindowList, void);
REGISTER_COMMAND_PARSER(nextwindow, parseWindowList, void);
REGISTER_COMMAND_PARSER(nextgroup, parseWindowList, void);
REGISTER_COMMAND_PARSER(prevwindow, parseWindowList, void);
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);
REGISTER_COMMAND_PARSER(unclutter, parseWindowList, void);
} // end anonymous namespace
void AttachCmd::execute() {
BScreen *screen = Fluxbox::instance()->keyScreen();
if (screen != 0) {
FocusControl::Focusables win_list(screen->focusControl().focusedOrderWinList().clientList());
FocusControl::Focusables::iterator it = win_list.begin(),
it_end = win_list.end();
FluxboxWindow *first = 0;
for (; it != it_end; ++it) {
if (m_pat.match(**it) && (*it)->fbwindow()) {
if (first == 0)
first = (*it)->fbwindow();
else
first->attachClient((*it)->fbwindow()->winClient());
}
}
}
}
void NextWindowCmd::execute() {
BScreen *screen = Fluxbox::instance()->keyScreen();
if (screen != 0)
screen->cycleFocus(m_option, &m_pat, false);
}
void PrevWindowCmd::execute() {
BScreen *screen = Fluxbox::instance()->keyScreen();
if (screen != 0)
screen->cycleFocus(m_option, &m_pat, true);
}
FbTk::Command<void> *GoToWindowCmd::parse(const string &command,
const string &arguments, bool trusted) {
int num, opts;
string args, pat;
FbTk_istringstream iss(arguments.c_str());
iss >> num;
string::size_type pos = arguments.find_first_of("({");
if (pos != string::npos && pos != arguments.size())
args = arguments.c_str() + pos;
FocusableList::parseArgs(args, opts, pat);
return new GoToWindowCmd(num, opts, pat);
}
REGISTER_COMMAND_PARSER(gotowindow, GoToWindowCmd::parse, void);
void GoToWindowCmd::execute() {
BScreen *screen = Fluxbox::instance()->keyScreen();
if (screen != 0) {
const FocusableList *win_list =
FocusableList::getListFromOptions(*screen, m_option);
screen->focusControl().goToWindowNumber(*win_list, m_num, &m_pat);
}
}
FbTk::Command<void> *DirFocusCmd::parse(const string &command,
const string &args, bool trusted) {
if (command == "focusup")
return new DirFocusCmd(FocusControl::FOCUSUP);
else if (command == "focusdown")
return new DirFocusCmd(FocusControl::FOCUSDOWN);
else if (command == "focusleft")
return new DirFocusCmd(FocusControl::FOCUSLEFT);
else if (command == "focusright")
return new DirFocusCmd(FocusControl::FOCUSRIGHT);
return 0;
}
REGISTER_COMMAND_PARSER(focusup, DirFocusCmd::parse, void);
REGISTER_COMMAND_PARSER(focusdown, DirFocusCmd::parse, void);
REGISTER_COMMAND_PARSER(focusleft, DirFocusCmd::parse, void);
REGISTER_COMMAND_PARSER(focusright, DirFocusCmd::parse, void);
void DirFocusCmd::execute() {
BScreen *screen = Fluxbox::instance()->keyScreen();
if (screen == 0)
return;
FluxboxWindow *win = FocusControl::focusedFbWindow();
if (win)
screen->focusControl().dirFocus(*win, m_dir);
}
REGISTER_COMMAND(addworkspace, AddWorkspaceCmd, void);
void AddWorkspaceCmd::execute() {
BScreen *screen = Fluxbox::instance()->mouseScreen();
if (screen != 0)
screen->addWorkspace();
}
REGISTER_COMMAND(removelastworkspace, RemoveLastWorkspaceCmd, void);
void RemoveLastWorkspaceCmd::execute() {
BScreen *screen = Fluxbox::instance()->mouseScreen();
if (screen != 0)
screen->removeLastWorkspace();
}
namespace {
FbTk::Command<void> *parseIntCmd(const string &command, const string &args,
bool trusted) {
int num = 1;
FbTk_istringstream iss(args.c_str());
iss >> num;
if (command == "nextworkspace")
return new NextWorkspaceCmd(num);
else if (command == "prevworkspace")
return new PrevWorkspaceCmd(num);
else if (command == "rightworkspace")
return new RightWorkspaceCmd(num);
else if (command == "leftworkspace")
return new LeftWorkspaceCmd(num);
else if (command == "workspace")
// workspaces appear 1-indexed to the user, hence the minus 1
return new JumpToWorkspaceCmd(num - 1);
return 0;
}
REGISTER_COMMAND_PARSER(nextworkspace, parseIntCmd, void);
REGISTER_COMMAND_PARSER(prevworkspace, parseIntCmd, void);
REGISTER_COMMAND_PARSER(rightworkspace, parseIntCmd, void);
REGISTER_COMMAND_PARSER(leftworkspace, parseIntCmd, void);
REGISTER_COMMAND_PARSER(workspace, parseIntCmd, void);
} // end anonymous namespace
void NextWorkspaceCmd::execute() {
BScreen *screen = Fluxbox::instance()->mouseScreen();
if (screen != 0)
screen->nextWorkspace(m_option == 0 ? 1 : m_option);
}
void PrevWorkspaceCmd::execute() {
BScreen *screen = Fluxbox::instance()->mouseScreen();
if (screen != 0)
screen->prevWorkspace(m_option == 0 ? 1 : m_option);
}
void LeftWorkspaceCmd::execute() {
BScreen *screen = Fluxbox::instance()->mouseScreen();
if (screen != 0)
screen->leftWorkspace(m_param);
}
void RightWorkspaceCmd::execute() {
BScreen *screen = Fluxbox::instance()->mouseScreen();
if (screen != 0)
screen->rightWorkspace(m_param);
}
JumpToWorkspaceCmd::JumpToWorkspaceCmd(int workspace_num):m_workspace_num(workspace_num) { }
void JumpToWorkspaceCmd::execute() {
BScreen *screen = Fluxbox::instance()->mouseScreen();
if (screen != 0) {
int num = screen->numberOfWorkspaces();
int actual = m_workspace_num;
// we need an extra +1, since it's subtracted in FbCommandFactory
if (actual < 0) actual += num+1;
if (actual < 0) actual = 0;
if (actual >= num) actual = num - 1;
screen->changeWorkspaceID(actual);
}
}
/**
try to arrange the windows on the current workspace in a 'clever' way.
we take the shaded-windows and put them ontop of the workspace and put the
normal windows underneath it.
*/
void ArrangeWindowsCmd::execute() {
BScreen *screen = Fluxbox::instance()->mouseScreen();
if (screen == 0)
return;
Workspace *space = screen->currentWorkspace();
if (space->windowList().empty())
return;
// TODO: choice between
// - arrange using all windows on all heads
// - arrange for each head
// - only on current head
const int head = screen->getCurrHead();
Workspace::Windows::iterator win;
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 ((m_tile_method >= STACKLEFT) && (*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 && (m_tile_method >= STACKLEFT)) {
main_window = normal_windows.back();
normal_windows.pop_back();
}
// to arrange only shaded windows is a bit pointless imho (mathias)
size_t win_count = normal_windows.size();
if (win_count == 0) {
if (!main_window) {
return;
}
win_count = 1;
}
int x_offs = screen->maxLeft(head); // window position offset in x
int y_offs = screen->maxTop(head); // window position offset in y
unsigned int max_width = screen->maxRight(head) - screen->maxLeft(head);
unsigned int max_height = screen->maxBottom(head) - screen->maxTop(head);
if ((m_tile_method == STACKLEFT) || (m_tile_method == STACKRIGHT)) {
max_width = max_width / 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
unsigned int rows = int(0.99 + float(win_count) / float(cols));
if ( (m_tile_method == VERTICAL) || // rotate if the user has asked for it or automagically
( (m_tile_method == UNSPECIFIED) && (max_width<max_height)) ) {
std::swap(cols, rows);
}
// 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 += static_cast<int>(max_width);
break;
case STACKBOTTOM:
y_offs += static_cast<int>(max_height);
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 int orig_x_offs = x_offs;
const int orig_y_offs = y_offs;
unsigned int i;
unsigned int j;
// place the shaded windows
// TODO: until i resolve the shadedwindow->moveResize() issue to place
// them in the same columns as the normal windows i just place the shaded
// windows unchanged ontop of the current head
for (i = 0, win = shaded_windows.begin(); win != shaded_windows.end(); ++win, ++i) {
if (i & 1)
(*win)->move(x_offs, y_offs);
else
(*win)->move(screen->maxRight(head) - (*win)->frame().width(), y_offs);
y_offs += (*win)->frame().height();
}
// TODO: what if the number of shaded windows is really big and we end up
// with really little space left for the normal windows? how to handle
// this?
if (!shaded_windows.empty())
max_height -= i * (*shaded_windows.begin())->frame().height();
const unsigned int cal_width = max_width/cols; // width ratio (width of every window)
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 = orig_x_offs;
for (j = 0; j < cols && !normal_windows.empty(); ++j) {
int cell_center_x = x_offs + (x_offs + cal_width) / 2;
int cell_center_y = y_offs + (y_offs + cal_height) / 2;
unsigned int closest_dist = ~0;
Workspace::Windows::iterator closest = normal_windows.end();
for (win = normal_windows.begin(); win != normal_windows.end(); ++win) {
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) +
(win_center_y - cell_center_y) * (win_center_y - cell_center_y);
if (dist < closest_dist) {
closest = win;
closest_dist = dist;
}
}
int x = x_offs + (*closest)->xOffset();
int y = y_offs + (*closest)->yOffset();
unsigned int w = cal_width - (*closest)->widthOffset();
unsigned int h = cal_height - (*closest)->heightOffset();
// the last window gets everything that is left.
if (normal_windows.size() == 1) {
w = static_cast<int>(screen->maxRight(head)) - x_offs - (*closest)->widthOffset();
h = static_cast<int>(cal_height) - (*closest)->heightOffset();
if (m_tile_method == STACKLEFT) {
w -= max_width;
}
}
(*closest)->moveResize(x, y, w, h);
normal_windows.erase(closest);
x_offs += static_cast<int>(cal_width);
}
y_offs += static_cast<int>(cal_height);
}
// If using a stacked mechanism we now need to place the main window.
if (main_window != NULL){
x_offs = screen->maxLeft(head);
switch (m_tile_method){
case STACKLEFT:
main_window->moveResize(x_offs + max_width, orig_y_offs, max_width, max_height);
break;
case STACKRIGHT:
main_window->moveResize(x_offs, screen->maxTop(head), max_width, max_height);
break;
case STACKTOP:
main_window->moveResize(x_offs, max_height, max_width, max_height);
break;
case STACKBOTTOM:
main_window->moveResize(x_offs, screen->maxTop(head), max_width, max_height);
break;
default:
// Shouldn't happen.
break;
}
}
}
void UnclutterCmd::execute() {
BScreen *screen = Fluxbox::instance()->mouseScreen();
if (screen == 0)
return;
Workspace *space = screen->currentWorkspace();
if (space->windowList().empty())
return;
const int head = screen->getCurrHead();
Workspace::Windows::iterator win;
Workspace::Windows placed_windows;
// list and clean up
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)) {
placed_windows.push_back(*win);
(*win)->move(-(*win)->width(), -(*win)->height());
}
}
if (placed_windows.empty())
return;
// place
MinOverlapPlacement mopp;
int x, y;
for (win = placed_windows.begin(); win != placed_windows.end(); ++win) {
mopp.placeWindow(**win, head, x, y);
(*win)->move(x, y);
}
}
REGISTER_COMMAND(showdesktop, ShowDesktopCmd, void);
void ShowDesktopCmd::execute() {
BScreen *screen = Fluxbox::instance()->mouseScreen();
if (screen == 0)
return;
// iconify windows in focus order, so it gets restored properly
const std::list<Focusable *> wins =
screen->focusControl().focusedOrderWinList().clientList();
std::list<Focusable *>::const_iterator it = wins.begin(),
it_end = wins.end();
unsigned int space = screen->currentWorkspaceID();
unsigned int count = 0;
XGrabServer(Fluxbox::instance()->display());
for (; it != it_end; ++it) {
if (!(*it)->fbwindow()->isIconic() && ((*it)->fbwindow()->isStuck() ||
(*it)->fbwindow()->workspaceNumber() == space) &&
(*it)->fbwindow()->layerNum() < ResourceLayer::DESKTOP) {
(*it)->fbwindow()->iconify();
count++;
}
}
if (count == 0) {
BScreen::Icons icon_list = screen->iconList();
BScreen::Icons::reverse_iterator iconit = icon_list.rbegin();
BScreen::Icons::reverse_iterator itend= icon_list.rend();
for(; iconit != itend; ++iconit) {
if ((*iconit)->workspaceNumber() == space || (*iconit)->isStuck())
(*iconit)->deiconify(false);
}
} else
FocusControl::revertFocus(*screen);
XUngrabServer(Fluxbox::instance()->display());
}
REGISTER_COMMAND(toggleslitbarabove, ToggleSlitAboveCmd, void);
void ToggleSlitAboveCmd::execute() {
#if USE_SLIT
if (BScreen *screen = Fluxbox::instance()->mouseScreen()) {
screen->slit()->toggleAboveDock();
const_cast<FbTk::FbWindow&>(screen->slit()->window()).raise();
}
#endif
}
REGISTER_COMMAND(toggleslithidden, ToggleSlitHiddenCmd, void);
void ToggleSlitHiddenCmd::execute() {
#if USE_SLIT
if (BScreen *screen = Fluxbox::instance()->mouseScreen()) {
screen->slit()->toggleHidden();
const_cast<FbTk::FbWindow&>(screen->slit()->window()).raise();
}
#endif
}
REGISTER_COMMAND(toggletoolbarabove, ToggleToolbarAboveCmd, void);
void ToggleToolbarAboveCmd::execute() {
#if USE_TOOLBAR
if (BScreen *screen = Fluxbox::instance()->mouseScreen()) {
screen->toolbar()->toggleAboveDock();
const_cast<FbTk::FbWindow&>(screen->toolbar()->window()).raise();
}
#endif
}
REGISTER_COMMAND(toggletoolbarvisible, ToggleToolbarHiddenCmd, void);
void ToggleToolbarHiddenCmd::execute() {
#if USE_TOOLBAR
if (BScreen *screen = Fluxbox::instance()->mouseScreen()) {
screen->toolbar()->toggleHidden();
const_cast<FbTk::FbWindow&>(screen->toolbar()->window()).raise();
}
#endif
}
REGISTER_COMMAND(closeallwindows, CloseAllWindowsCmd, void);
void CloseAllWindowsCmd::execute() {
BScreen *screen = Fluxbox::instance()->mouseScreen();
if (screen == 0)
return;
Workspace::Windows windows;
BScreen::Workspaces::iterator workspace_it = screen->getWorkspacesList().begin();
BScreen::Workspaces::iterator workspace_it_end = screen->getWorkspacesList().end();
for (; workspace_it != workspace_it_end; ++workspace_it) {
windows = (*workspace_it)->windowList();
std::for_each(windows.begin(), windows.end(),
std::mem_fun(&FluxboxWindow::close));
}
windows = screen->iconList();
std::for_each(windows.begin(),
windows.end(), std::mem_fun(&FluxboxWindow::close));
}
void RelabelButtonCmd::execute() {
#if USE_TOOLBAR
if (BScreen *screen = Fluxbox::instance()->mouseScreen())
screen->relabelToolButton(m_button, m_label);
#endif
}
FbTk::Command<void> *RelabelButtonCmd::parse(const std::string &command,
const std::string &args, bool trusted) {
std::string button, label;
std::size_t ws = args.find_first_of(" \t\n");
if (ws != std::string::npos) {
button = args.substr(0, ws);
if (button.find("button.") == 0) {
label = args.substr(ws + 1, std::string::npos);
} else {
button.clear();
}
}
return new RelabelButtonCmd(button, label);
}
REGISTER_COMMAND_PARSER(relabelbutton, RelabelButtonCmd::parse, void);