From 491c0e523429f45c02f5da04f8b7fbb45095e1e1 Mon Sep 17 00:00:00 2001 From: markt Date: Sat, 31 Mar 2007 17:11:59 +0000 Subject: pattern matching for window commands and [group] in apps file --- ChangeLog | 22 ++++++ src/CurrentWindowCmd.cc | 46 +++++------- src/CurrentWindowCmd.hh | 29 ++++--- src/FbCommandFactory.cc | 195 +++++++++++++++++++++++++++++------------------- src/Remember.cc | 45 ++++++----- src/Remember.hh | 19 ++--- src/WorkspaceCmd.cc | 32 ++++---- src/WorkspaceCmd.hh | 21 ++++-- 8 files changed, 238 insertions(+), 171 deletions(-) diff --git a/ChangeLog b/ChangeLog index 4cf0b0a..480f5f3 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,27 @@ (Format: Year/Month/Day) Changes for 1.1: +*07/03/31: + * [group] tag in apps file may now have a pattern appended to it, and a new + window will only be automatically attached to the group if the group + matches that pattern -- e.g. [group] (workspace) (shaded=no) will only + automatically group with windows on the current workspace that are not + shaded (Mark) + Remember.cc/hh + * Lots of window commands now take a client pattern as an additional + argument, and the command will then be applied to all matching windows + (Mark) + - For example: `SendToWorkspace 2 (xterm)' will send all xterm windows to + workspace 2 + - Here is the full list of affected commands (which is not to imply they + all necessarily make sense to do): Fullscreen, Minimize, Maximize, + MaximizeVertical, MaximizeHorizontal, SetAlpha, Resize, ResizeTo, + ResizeHorizontal, ResizeVertical, MoveTo, Move, MoveRight, MoveLeft, + MoveUp, MoveDown, Raise, RaiseLayer, Lower, LowerLayer, Close, Kill, + Shade, Stick, ToggleDecor, SetHead, Tab, SendToNextWorkspace, + SendToPrevWorkspace, TakeToNextWorkspace, TakeToPrevWorkspace, + SendToWorkspace, TakeToWorkspace, NextTab, PrevTab, MoveTabLeft, + MoveTabRight, DetachClient + WorkspaceCmd.cc/hh CurrentWindowCmd.cc/hh FbCommandFactory.cc *07/03/30: * Added fi_FI support (Thanks Pasi Juvonen, loudvr at yahoo ca) nls/fi_FI/*, util/fluxbox-generate_menu.in diff --git a/src/CurrentWindowCmd.cc b/src/CurrentWindowCmd.cc index fcc141b..f411f83 100644 --- a/src/CurrentWindowCmd.cc +++ b/src/CurrentWindowCmd.cc @@ -31,17 +31,24 @@ #include "FocusControl.hh" -CurrentWindowCmd::CurrentWindowCmd(Action act):m_action(act) { } +void WindowHelperCmd::execute() { + m_win = 0; + if (FocusControl::focusedFbWindow()) // guarantee that fbwindow() exists too + real_execute(); +} -void CurrentWindowCmd::execute() { - FluxboxWindow *win = FocusControl::focusedFbWindow(); - if (win) - (win->*m_action)(); +void WindowHelperCmd::execute(FluxboxWindow &win) { + m_win = &win; + real_execute(); } +FluxboxWindow &WindowHelperCmd::fbwindow() { + // will exist from execute above + return (m_win ? *m_win : *FocusControl::focusedFbWindow()); +} -void KillWindowCmd::real_execute() { - winclient().sendClose(true); +void CurrentWindowCmd::real_execute() { + (fbwindow().*m_action)(); } void SetHeadCmd::real_execute() { @@ -54,13 +61,14 @@ void SendToWorkspaceCmd::real_execute() { void SendToNextWorkspaceCmd::real_execute() { const int ws_nr = - ( fbwindow().screen().currentWorkspaceID() + m_workspace_num ) % + ( fbwindow().workspaceNumber() + m_workspace_num ) % fbwindow().screen().numberOfWorkspaces(); fbwindow().screen().sendToWorkspace(ws_nr, &fbwindow(), false); } void SendToPrevWorkspaceCmd::real_execute() { - int ws_nr = fbwindow().screen().currentWorkspaceID() - m_workspace_num; + int ws_nr = (fbwindow().workspaceNumber() - m_workspace_num) % + fbwindow().screen().numberOfWorkspaces(); if ( ws_nr < 0 ) ws_nr += fbwindow().screen().numberOfWorkspaces(); fbwindow().screen().sendToWorkspace(ws_nr, &fbwindow(), false); @@ -72,13 +80,14 @@ void TakeToWorkspaceCmd::real_execute() { void TakeToNextWorkspaceCmd::real_execute() { unsigned int workspace_num= - ( fbwindow().screen().currentWorkspaceID() + m_workspace_num ) % + ( fbwindow().workspaceNumber() + m_workspace_num ) % fbwindow().screen().numberOfWorkspaces(); fbwindow().screen().sendToWorkspace(workspace_num, &fbwindow()); } void TakeToPrevWorkspaceCmd::real_execute() { - int workspace_num= fbwindow().screen().currentWorkspaceID() - m_workspace_num; + int workspace_num = (fbwindow().workspaceNumber() - m_workspace_num) % + fbwindow().screen().numberOfWorkspaces(); if ( workspace_num < 0 ) workspace_num += fbwindow().screen().numberOfWorkspaces(); fbwindow().screen().sendToWorkspace(workspace_num, &fbwindow()); @@ -96,21 +105,6 @@ void GoToTabCmd::real_execute() { (*it)->focus(); } -void WindowHelperCmd::execute() { - if (FocusControl::focusedFbWindow()) // guarantee that fbwindow() exists too - real_execute(); -} - -WinClient &WindowHelperCmd::winclient() { - // will exist from execute above - return *FocusControl::focusedWindow(); -} - -FluxboxWindow &WindowHelperCmd::fbwindow() { - // will exist from execute above - return *FocusControl::focusedFbWindow(); -} - MoveCmd::MoveCmd(const int step_size_x, const int step_size_y) : m_step_size_x(step_size_x), m_step_size_y(step_size_y) { } diff --git a/src/CurrentWindowCmd.hh b/src/CurrentWindowCmd.hh index c1b9140..172f9c0 100644 --- a/src/CurrentWindowCmd.hh +++ b/src/CurrentWindowCmd.hh @@ -28,36 +28,33 @@ #include "Command.hh" class FluxboxWindow; -class WinClient; - -/// command that calls FluxboxWindow:: on execute() -/// similar to FbTk::SimpleCommand -class CurrentWindowCmd: public FbTk::Command { -public: - typedef void (FluxboxWindow::* Action)(); - explicit CurrentWindowCmd(Action action); - void execute(); -private: - Action m_action; -}; /// helper class for window commands /// calls real_execute if there's a focused window or a window in button press/release window class WindowHelperCmd: public FbTk::Command { public: + explicit WindowHelperCmd(FluxboxWindow *win = 0): m_win(win) { } + void execute(); + void execute(FluxboxWindow &fbwin); protected: - - WinClient &winclient(); FluxboxWindow &fbwindow(); virtual void real_execute() = 0; +private: + FluxboxWindow *m_win; }; -class KillWindowCmd: public WindowHelperCmd { -protected: +/// command that calls FluxboxWindow:: on execute() +/// similar to FbTk::SimpleCommand +class CurrentWindowCmd: public WindowHelperCmd { +public: + typedef void (FluxboxWindow::* Action)(); + explicit CurrentWindowCmd(Action action): m_action(action) { } void real_execute(); +private: + Action m_action; }; class SetHeadCmd : public WindowHelperCmd { diff --git a/src/FbCommandFactory.cc b/src/FbCommandFactory.cc index 1ae8d44..dc1d9e9 100644 --- a/src/FbCommandFactory.cc +++ b/src/FbCommandFactory.cc @@ -261,21 +261,15 @@ FbTk::Command *FbCommandFactory::stringToCommand(const std::string &command, // Current focused window commands // else if (command == "fullscreen") - return new FullscreenCmd(); - else if (command == "minimizewindow" || command == "minimize" || command == "iconify") { - string cmd; - if (FbTk::StringUtil::getStringBetween(cmd, arguments.c_str() + - 0, '(', ')', " \t\n", true) - && cmd == "layer") - return new MinimizeLayerCmd(); - else - return new CurrentWindowCmd(&FluxboxWindow::iconify); - } else if (command == "maximizewindow" || command == "maximize") - return new CurrentWindowCmd(&FluxboxWindow::maximizeFull); + return new WindowListCmd(FbTk::RefCount(new FullscreenCmd()), arguments); + else if (command == "minimizewindow" || command == "minimize" || command == "iconify") + return new WindowListCmd(FbTk::RefCount(new CurrentWindowCmd(&FluxboxWindow::iconify)), arguments); + else if (command == "maximizewindow" || command == "maximize") + return new WindowListCmd(FbTk::RefCount(new CurrentWindowCmd(&FluxboxWindow::maximizeFull)), arguments); else if (command == "maximizevertical") - return new CurrentWindowCmd(&FluxboxWindow::maximizeVertical); + return new WindowListCmd(FbTk::RefCount(new CurrentWindowCmd(&FluxboxWindow::maximizeVertical)), arguments); else if (command == "maximizehorizontal") - return new CurrentWindowCmd(&FluxboxWindow::maximizeHorizontal); + return new WindowListCmd(FbTk::RefCount(new CurrentWindowCmd(&FluxboxWindow::maximizeHorizontal)), arguments); else if (command == "setalpha") { typedef vector StringTokens; StringTokens tokens; @@ -297,24 +291,37 @@ FbTk::Command *FbCommandFactory::stringToCommand(const std::string &command, unfocused = atoi(tokens[1].c_str()); } - return new SetAlphaCmd(focused, relative, unfocused, un_rel); - } else if (command == "resize") { - FbTk_istringstream is(arguments.c_str()); - int dx = 0, dy = 0; - is >> dx >> dy; - return new ResizeCmd(dx, dy); - } - else if (command == "resizeto") { + string pat; + string::size_type pos = arguments.find('('); + if (pos != string::npos && pos != arguments.size()) + pat = arguments.c_str() + pos; + + return new WindowListCmd(FbTk::RefCount(new SetAlphaCmd(focused, relative, unfocused, un_rel)), pat); + } else if (command == "resize" || command == "resizeto" || + command == "resizehorizontal" || command == "resizevertical") { FbTk_istringstream is(arguments.c_str()); int dx = 0, dy = 0; is >> dx >> dy; - return new ResizeToCmd(dx, dy); - } - else if (command == "resizehorizontal") - return new ResizeCmd(atoi(arguments.c_str()),0); - else if (command == "resizevertical") - return new ResizeCmd(0,atoi(arguments.c_str())); - else if (command == "moveto") { + if (command == "resizehorizontal") + dy = 0; + else if (command == "resizevertical") { + dy = dx; + dx = 0; + } + + string pat; + string::size_type pos = arguments.find('('); + if (pos != string::npos && pos != arguments.size()) + pat = arguments.c_str() + pos; + + FbTk::RefCount cmd; + if (command == "resizeto") + cmd = new ResizeToCmd(dx, dy); + else if (command == "resizeto") + cmd = new ResizeCmd(dx, dy); + + return new WindowListCmd(cmd, pat); + } else if (command == "moveto") { typedef vector StringTokens; StringTokens tokens; FbTk::StringUtil::stringtok(tokens, arguments); @@ -357,70 +364,107 @@ FbTk::Command *FbCommandFactory::stringToCommand(const std::string &command, } } - return new MoveToCmd(dx, dy, refc); - } - else if (command == "move") { + string pat; + string::size_type pos = arguments.find('('); + if (pos != string::npos && pos != arguments.size()) + pat = arguments.c_str() + pos; + + return new WindowListCmd(FbTk::RefCount(new MoveToCmd(dx, dy, refc)), pat); + } else if (command == "move" || command == "moveright" || + command == "moveleft" || command == "moveup" || + command == "movedown") { FbTk_istringstream is(arguments.c_str()); int dx = 0, dy = 0; is >> dx >> dy; - return new MoveCmd(dx, dy); - } - else if (command == "moveright") - return new MoveCmd(atoi(arguments.c_str()),0); - else if (command == "moveleft") - return new MoveCmd(-atoi(arguments.c_str()),0); - else if (command == "moveup") - return new MoveCmd(0,-atoi(arguments.c_str())); - else if (command == "movedown") - return new MoveCmd(0,atoi(arguments.c_str())); - else if (command == "raise") - return new CurrentWindowCmd(&FluxboxWindow::raise); + + if (command == "moveright") + dy = 0; + else if (command == "moveleft") { + dy = 0; + dx = -dx; + } else if (command == "movedown") { + dy = dx; + dx = 0; + } else if (command == "moveup") { + dy = -dx; + dx = 0; + } + + string pat; + string::size_type pos = arguments.find('('); + if (pos != string::npos && pos != arguments.size()) + pat = arguments.c_str() + pos; + + return new WindowListCmd(FbTk::RefCount(new MoveCmd(dx, dy)), pat); + } else if (command == "raise") + return new WindowListCmd(FbTk::RefCount(new CurrentWindowCmd(&FluxboxWindow::raise)), arguments); else if (command == "raiselayer") - return new CurrentWindowCmd(&FluxboxWindow::raiseLayer); + return new WindowListCmd(FbTk::RefCount(new CurrentWindowCmd(&FluxboxWindow::raiseLayer)), arguments); else if (command == "lower") - return new CurrentWindowCmd(&FluxboxWindow::lower); + return new WindowListCmd(FbTk::RefCount(new CurrentWindowCmd(&FluxboxWindow::lower)), arguments); else if (command == "lowerlayer") - return new CurrentWindowCmd(&FluxboxWindow::lowerLayer); + return new WindowListCmd(FbTk::RefCount(new CurrentWindowCmd(&FluxboxWindow::lowerLayer)), arguments); else if (command == "close") - return new CurrentWindowCmd(&FluxboxWindow::close); + return new WindowListCmd(FbTk::RefCount(new CurrentWindowCmd(&FluxboxWindow::close)), arguments); else if (command == "closeallwindows") return new CloseAllWindowsCmd(); + else if (command == "killwindow" || command == "kill") + return new WindowListCmd(FbTk::RefCount(new CurrentWindowCmd(&FluxboxWindow::kill)), arguments); else if (command == "shade" || command == "shadewindow") - return new CurrentWindowCmd(&FluxboxWindow::shade); + return new WindowListCmd(FbTk::RefCount(new CurrentWindowCmd(&FluxboxWindow::shade)), arguments); else if (command == "stick" || command == "stickwindow") - return new CurrentWindowCmd(&FluxboxWindow::stick); + return new WindowListCmd(FbTk::RefCount(new CurrentWindowCmd(&FluxboxWindow::stick)), arguments); else if (command == "toggledecor") - return new CurrentWindowCmd(&FluxboxWindow::toggleDecoration); - else if (command == "sethead") - return new SetHeadCmd(atoi(arguments.c_str())); - else if (command == "sendtoworkspace") - // workspaces appear 1-indexed to the user, hence the minus 1 - return new SendToWorkspaceCmd(getint(arguments.c_str(), 1) - 1); - else if (command == "sendtonextworkspace") - return new SendToNextWorkspaceCmd(getint(arguments.c_str(), 1)); - else if (command == "sendtoprevworkspace") - return new SendToPrevWorkspaceCmd(getint(arguments.c_str(), 1)); - else if (command == "taketoworkspace") + return new WindowListCmd(FbTk::RefCount(new CurrentWindowCmd(&FluxboxWindow::toggleDecoration)), arguments); + else if (command == "sethead") { + int num = 0; + string pat; + FbTk_istringstream iss(arguments.c_str()); + iss >> num; + string::size_type pos = arguments.find('('); + if (pos != string::npos && pos != arguments.size()) + pat = arguments.c_str() + pos; + return new WindowListCmd(FbTk::RefCount(new SetHeadCmd(num)), pat); + } else if (command == "tab" || command == "sendtonextworkspace" || + command == "sendtoprevworkspace" || + command == "taketonextworkspace" || + command == "taketoprevworkspace" || + command == "sendtoworkspace" || command == "taketoworkspace") { // workspaces appear 1-indexed to the user, hence the minus 1 - return new TakeToWorkspaceCmd(getint(arguments.c_str(), 1) - 1); - else if (command == "taketonextworkspace") - return new TakeToNextWorkspaceCmd(getint(arguments.c_str(), 1)); - else if (command == "taketoprevworkspace") - return new TakeToPrevWorkspaceCmd(getint(arguments.c_str(), 1)); - else if (command == "killwindow" || command == "kill") - return new KillWindowCmd(); - else if (command == "tab") - return new GoToTabCmd(getint(arguments.c_str(), 1)); - else if (command == "nexttab") - return new CurrentWindowCmd(&FluxboxWindow::nextClient); + int num = 1; + string pat; + FbTk_istringstream iss(arguments.c_str()); + iss >> num; + string::size_type pos = arguments.find('('); + if (pos != string::npos && pos != arguments.size()) + pat = arguments.c_str() + pos; + FbTk::RefCount cmd; + + if (command == "tab") + cmd = new GoToTabCmd(num); + else if (command == "sendtonextworkspace") + cmd = new SendToNextWorkspaceCmd(num); + else if (command == "sendtoprevworkspace") + cmd = new SendToPrevWorkspaceCmd(num); + else if (command == "taketonextworkspace") + cmd = new TakeToNextWorkspaceCmd(num); + else if (command == "taketoprevworkspace") + cmd = new TakeToPrevWorkspaceCmd(num); + else if (command == "sendtoworkspace") + cmd = new SendToWorkspaceCmd(num-1); + else + cmd = new TakeToWorkspaceCmd(num-1); + return new WindowListCmd(cmd, pat); + } else if (command == "nexttab") + return new WindowListCmd(FbTk::RefCount(new CurrentWindowCmd(&FluxboxWindow::nextClient)), arguments); else if (command == "prevtab") - return new CurrentWindowCmd(&FluxboxWindow::prevClient); + return new WindowListCmd(FbTk::RefCount(new CurrentWindowCmd(&FluxboxWindow::prevClient)), arguments); else if (command == "movetableft") - return new CurrentWindowCmd(&FluxboxWindow::moveClientLeft); + return new WindowListCmd(FbTk::RefCount(new CurrentWindowCmd(&FluxboxWindow::moveClientLeft)), arguments); else if (command == "movetabright") - return new CurrentWindowCmd(&FluxboxWindow::moveClientRight); + return new WindowListCmd(FbTk::RefCount(new CurrentWindowCmd(&FluxboxWindow::moveClientRight)), arguments); else if (command == "detachclient") - return new CurrentWindowCmd(&FluxboxWindow::detachCurrentClient); + return new WindowListCmd(FbTk::RefCount(new CurrentWindowCmd(&FluxboxWindow::detachCurrentClient)), arguments); else if (command == "windowmenu") return new CurrentWindowCmd(&FluxboxWindow::popupMenu); // @@ -476,7 +520,6 @@ FbTk::Command *FbCommandFactory::stringToCommand(const std::string &command, string::size_type pos = arguments.find_first_of("({"); if (pos != string::npos && pos != arguments.size()) args = arguments.c_str() + pos; -std::cerr << "GoToWindow args: " << args << std::endl; parseNextWindowArgs(args, opts, pat); return new GoToWindowCmd(num, opts, pat); } else if (command == "focusup") diff --git a/src/Remember.cc b/src/Remember.cc index e0a7b0f..6f86ade 100644 --- a/src/Remember.cc +++ b/src/Remember.cc @@ -230,8 +230,8 @@ bool handleStartupItem(const string &line, int offset) { }; // end anonymous namespace -Application::Application(int grouped) - : is_grouped(grouped) +Application::Application(bool grouped, ClientPattern *pat) + : is_grouped(grouped), group_pattern(pat) { decostate_remember = dimensions_remember = @@ -337,7 +337,7 @@ Application* Remember::find(WinClient &winclient) { Application * Remember::add(WinClient &winclient) { ClientPattern *p = new ClientPattern(); - Application *app = new Application(0); + Application *app = new Application(false); // by default, we match against the WMClass of a window. string win_name = p->getProperty(ClientPattern::NAME, winclient); @@ -530,11 +530,13 @@ int Remember::parseApp(ifstream &file, Application &app, string *first_line) { effectively moved into the new */ -Application *Remember::findMatchingPatterns(ClientPattern *pat, Patterns *patlist, int is_group) { +Application *Remember::findMatchingPatterns(ClientPattern *pat, Patterns *patlist, bool is_group, ClientPattern *match_pat) { Patterns::iterator it = patlist->begin(); Patterns::iterator it_end = patlist->end(); for (; it != it_end; ++it) { - if (it->first->equals(*pat) && is_group == it->second->is_grouped) { + if (it->first->equals(*pat) && is_group == it->second->is_grouped && + ((match_pat == 0 && *it->second->group_pattern == 0) || + (match_pat && match_pat->equals(**it->second->group_pattern)))) { Application *ret = it->second; // find any previous or subsequent matching ones and delete @@ -586,7 +588,8 @@ void Remember::reconfigure() { if (!apps_file.eof()) { string line; int row = 0; - int in_group = 0; + bool in_group = false; + ClientPattern *pat = 0; list grouped_pats; while (getline(apps_file, line) && ! apps_file.eof()) { row++; @@ -602,11 +605,11 @@ void Remember::reconfigure() { if (pos > 0 && strcasecmp(key.c_str(), "app") == 0) { ClientPattern *pat = new ClientPattern(line.c_str() + pos); - if (in_group == 0) { + if (!in_group) { if ((err = pat->error()) == 0) { - Application *app = findMatchingPatterns(pat, old_pats, 0); + Application *app = findMatchingPatterns(pat, old_pats, false); if (!app) - app = new Application(0); + app = new Application(false); m_pats->push_back(make_pair(pat, app)); row += parseApp(apps_file, *app); @@ -625,12 +628,9 @@ void Remember::reconfigure() { // save the item even if it was bad (aren't we nice) m_startups.push_back(line.substr(pos)); } else if (pos > 0 && strcasecmp(key.c_str(), "group") == 0) { - in_group = Application::IS_GROUPED; - pos = FbTk::StringUtil::getStringBetween(key, - line.c_str() + pos, - '(', ')'); - if (pos > 0 && strcasecmp(key.c_str(), "workspace") == 0) - in_group |= Application::MATCH_WORKSPACE; + in_group = true; + if (line.find('(') != string::npos) + pat = new ClientPattern(line.c_str() + pos); } else if (in_group) { // otherwise assume that it is the start of the attributes Application *app = 0; @@ -638,12 +638,12 @@ void Remember::reconfigure() { list::iterator it = grouped_pats.begin(); list::iterator it_end = grouped_pats.end(); while (!app && it != it_end) { - app = findMatchingPatterns(*it, old_pats, in_group); + app = findMatchingPatterns(*it, old_pats, in_group, pat); ++it; } if (!app) - app = new Application(in_group); + app = new Application(in_group, pat); while (!grouped_pats.empty()) { // associate all the patterns with this app @@ -657,7 +657,7 @@ void Remember::reconfigure() { if (!(pos>0 && strcasecmp(key.c_str(), "end") == 0)) { row += parseApp(apps_file, *app, &line); } - in_group = 0; + in_group = false; } else cerr<<"Error in apps file on line "<toString(); apps_file << endl; Patterns::iterator git = m_pats->begin(); @@ -1159,10 +1159,7 @@ FluxboxWindow *Remember::findGroup(Application *app, BScreen &screen) { for (; it != it_end; ++it) { if (it->second == app && it->first->fbwindow() && &screen == &it->first->screen() && - (!(app->is_grouped & Application::MATCH_WORKSPACE) || - it->first->fbwindow()->workspaceNumber() == - screen.currentWorkspaceID())) - + (!*app->group_pattern || app->group_pattern->match(*it->first))) return it->first->fbwindow(); } diff --git a/src/Remember.hh b/src/Remember.hh index a1e75da..3a6d636 100644 --- a/src/Remember.hh +++ b/src/Remember.hh @@ -29,6 +29,9 @@ #define REMEMBER_HH #include "AtomHandler.hh" +#include "ClientPattern.hh" + +#include "FbTk/RefCount.hh" #include #include @@ -40,11 +43,10 @@ class FluxboxWindow; class BScreen; class WinClient; -class ClientPattern; class Application { public: - Application(int grouped); + Application(bool grouped, ClientPattern *pat = 0); inline void forgetWorkspace() { workspace_remember = false; } inline void forgetHead() { head_remember = false; } inline void forgetDimensions() { dimensions_remember = false; } @@ -137,14 +139,8 @@ public: bool save_on_close_remember; bool save_on_close; - enum { - IS_GROUPED = 0x01, - MATCH_WORKSPACE = 0x02 - // MATCH_HEAD, STUCK, ICONIFIED, etc.? - // this will probably evolve into a ClientPattern as soon as they - // match things like currentworkspace - }; - int is_grouped; + bool is_grouped; + FbTk::RefCount group_pattern; }; @@ -256,7 +252,8 @@ private: // optionally can give a line to read before the first (lookahead line) int parseApp(std::ifstream &file, Application &app, std::string *first_line = 0); - Application *findMatchingPatterns(ClientPattern *pat, Patterns *patlist, int is_group); + Application *findMatchingPatterns(ClientPattern *pat, Patterns *patlist, + bool is_group, ClientPattern *match_pat = 0); std::auto_ptr m_pats; Clients m_clients; diff --git a/src/WorkspaceCmd.cc b/src/WorkspaceCmd.cc index 2d0f501..75cf4d3 100644 --- a/src/WorkspaceCmd.cc +++ b/src/WorkspaceCmd.cc @@ -41,6 +41,25 @@ #include #include +void WindowListCmd::execute() { + if (m_pat.error()) { + m_cmd->execute(); + return; + } + + BScreen *screen = Fluxbox::instance()->keyScreen(); + if (screen != 0) { + FocusControl::Focusables *win_list = &screen->focusControl().creationOrderWinList(); + + FocusControl::Focusables::iterator it = win_list->begin(), + it_end = win_list->end(); + for (; it != it_end; ++it) { + if (m_pat.match(**it) && (*it)->fbwindow()) + m_cmd->execute(*(*it)->fbwindow()); + } + } +} + void NextWindowCmd::execute() { BScreen *screen = Fluxbox::instance()->keyScreen(); if (screen != 0) @@ -266,19 +285,6 @@ void ShowDesktopCmd::execute() { std::mem_fun(&FluxboxWindow::iconify)); } -void MinimizeLayerCmd::execute() { - FluxboxWindow *win = FocusControl::focusedFbWindow(); - if (!win) - return; - - Workspace::Windows windows(win->screen().currentWorkspace()->windowList()); - Workspace::Windows::iterator it = windows.begin(), it_end = windows.end(); - for (; it != it_end; ++it) { - if (win->layerNum() == (*it)->layerNum()) - (*it)->iconify(); - } -} - void CloseAllWindowsCmd::execute() { BScreen *screen = Fluxbox::instance()->mouseScreen(); if (screen == 0) diff --git a/src/WorkspaceCmd.hh b/src/WorkspaceCmd.hh index 0e24a17..7687175 100644 --- a/src/WorkspaceCmd.hh +++ b/src/WorkspaceCmd.hh @@ -27,8 +27,24 @@ #include "Command.hh" #include "ClientPattern.hh" +#include "CurrentWindowCmd.hh" #include "FocusControl.hh" +#include "FbTk/RefCount.hh" + +class WindowHelperCmd; + +class WindowListCmd: public FbTk::Command { +public: + WindowListCmd(FbTk::RefCount cmd, const std::string &pat): + m_cmd(cmd), m_pat(pat.c_str()) { } + + void execute(); + +private: + FbTk::RefCount m_cmd; + ClientPattern m_pat; +}; class NextWindowCmd: public FbTk::Command { public: @@ -130,11 +146,6 @@ public: void execute(); }; -class MinimizeLayerCmd: public FbTk::Command { -public: - void execute(); -}; - class CloseAllWindowsCmd: public FbTk::Command { public: void execute(); -- cgit v0.11.2