all repos — fluxbox @ e4488da12009aeb2d6d1624bd42a877c95db468e

custom fork of the fluxbox windowmanager

some fixes for grouping with the apps file
markt markt
commit

e4488da12009aeb2d6d1624bd42a877c95db468e

parent

cf6e471fbf027a1ba08693d6562ae5d63aaa9e24

4 files changed, 73 insertions(+), 37 deletions(-)

jump to
M ChangeLogChangeLog

@@ -1,5 +1,14 @@

(Format: Year/Month/Day) Changes for 1.0rc3: +*07/02/05: + * Made some changes to the way autogrouping in the apps file works (Mark) + - Introduced new syntax [group] (workspace) to group new windows only with + windows on the current workspace + - Fixed an unreported bug with grouping windows on multiple screens + - Groups are now associated with clients rather than windows, so they + will be more robust when attaching or detaching tabs and when restarting + fluxbox + Remember.cc/hh *07/02/04: * Layer wasn't set properly on remembered windows, and the layer menu wasn't getting updated properly, bugs #1535304, #1572683, #1646740
M doc/asciidoc/fluxbox.txtdoc/asciidoc/fluxbox.txt

@@ -1510,9 +1510,10 @@ If no `property' is specified, the name property is assumed. You can find out

the value for these fields for a particular window by running xprop(1). You can also place [group] tag around several [app] tags, with an [end] tag to -indicate the end of the group. You can also specify dimensions, positions, -etc. for the group as for normal app entries. Here is a short example -of an `apps' file: +indicate the end of the group. If you place (workspace) after the [group] tag, a +new window will only get grouped with other windows on the current workspace. +You can also specify dimensions, positions, etc. for the group as for normal app +entries. Here is a short example of an `apps' file: ......................................................... [startup] {xterm}
M src/Remember.ccsrc/Remember.cc

@@ -230,9 +230,8 @@

}; // end anonymous namespace -Application::Application(bool grouped) - : is_grouped(grouped), - group(0) +Application::Application(int grouped) + : is_grouped(grouped) { decostate_remember = dimensions_remember =

@@ -312,7 +311,7 @@ }

Application * Remember::add(WinClient &winclient) { ClientPattern *p = new ClientPattern(); - Application *app = new Application(false); + Application *app = new Application(0); // by default, we match against the WMClass of a window. string win_name = p->getProperty(ClientPattern::NAME, winclient);

@@ -534,7 +533,7 @@ We REMOVE and delete any matching patterns from the old list, as they're

effectively moved into the new */ -Application *Remember::findMatchingPatterns(ClientPattern *pat, Patterns *patlist, bool is_group) { +Application *Remember::findMatchingPatterns(ClientPattern *pat, Patterns *patlist, int is_group) { Patterns::iterator it = patlist->begin(); Patterns::iterator it_end = patlist->end(); for (; it != it_end; ++it) {

@@ -590,7 +589,7 @@ m_last_timestamp = timestamp;

if (!apps_file.eof()) { string line; int row = 0; - bool in_group = false; + int in_group = 0; list<ClientPattern *> grouped_pats; while (getline(apps_file, line) && ! apps_file.eof()) { row++;

@@ -606,11 +605,11 @@ '[', ']');

if (pos > 0 && strcasecmp(key.c_str(), "app") == 0) { ClientPattern *pat = new ClientPattern(line.c_str() + pos); - if (!in_group) { + if (in_group == 0) { if ((err = pat->error()) == 0) { - Application *app = findMatchingPatterns(pat, old_pats, false); + Application *app = findMatchingPatterns(pat, old_pats, 0); if (!app) - app = new Application(false); + app = new Application(0); m_pats->push_back(make_pair(pat, app)); row += parseApp(apps_file, *app);

@@ -629,7 +628,12 @@ }

// 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 = true; + 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; } else if (in_group) { // otherwise assume that it is the start of the attributes Application *app = 0;

@@ -637,12 +641,12 @@ // search for a matching app

list<ClientPattern *>::iterator it = grouped_pats.begin(); list<ClientPattern *>::iterator it_end = grouped_pats.end(); while (!app && it != it_end) { - app = findMatchingPatterns(*it, old_pats, true); + app = findMatchingPatterns(*it, old_pats, in_group); ++it; } if (!app) - app = new Application(true); + app = new Application(in_group); while (!grouped_pats.empty()) { // associate all the patterns with this app

@@ -656,7 +660,7 @@ // otherwise parse the app

if (!(pos>0 && strcasecmp(key.c_str(), "end") == 0)) { row += parseApp(apps_file, *app, &line); } - in_group = false; + in_group = 0; } else cerr<<"Error in apps file on line "<<row<<"."<<endl;

@@ -733,7 +737,11 @@ if (grouped_apps.find(&a) != grouped_apps.end())

continue; grouped_apps.insert(&a); // otherwise output this whole group - apps_file << "[group]" << endl; + apps_file << "[group]"; + if (a.is_grouped & Application::MATCH_WORKSPACE) + apps_file << " (workspace)"; + apps_file << endl; + Patterns::iterator git = m_pats->begin(); Patterns::iterator git_end = m_pats->end(); for (; git != git_end; git++) {

@@ -1035,9 +1043,6 @@

// first, set the options that aren't preserved as window properties on // restart, then return if fluxbox is restarting -- we want restart to // disturb the current window state as little as possible - Window leftwin = winclient.getGroupLeftWindow(); - if (app->is_grouped && app->group == 0 && leftwin == None) - app->group = &win; if (app->focushiddenstate_remember) win.setFocusHidden(app->focushiddenstate);

@@ -1133,12 +1138,35 @@ Application *app = find(winclient);

if (app == 0) return; // nothing to do - if (winclient.fbwindow() == 0 && app->is_grouped && app->group) { - app->group->attachClient(winclient); + FluxboxWindow *group; + if (winclient.fbwindow() == 0 && app->is_grouped && + (group = findGroup(app, winclient.screen()))) { + group->attachClient(winclient); if (app->jumpworkspace_remember && app->jumpworkspace) // jump to window, not saved workspace - winclient.screen().changeWorkspaceID(app->group->workspaceNumber()); + winclient.screen().changeWorkspaceID(group->workspaceNumber()); + } +} + +FluxboxWindow *Remember::findGroup(Application *app, BScreen &screen) { + if (!app || !app->is_grouped) + return 0; + + // find the first client associated with the app and return its fbwindow + Clients::iterator it = m_clients.begin(); + Clients::iterator it_end = m_clients.end(); + 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())) + + return it->first->fbwindow(); } + + // there weren't any open, but that's ok + return 0; } void Remember::updateClientClose(WinClient &winclient) {

@@ -1172,12 +1200,3 @@ screen.addExtraWindowMenu(_FB_XTEXT(Remember, MenuItemName, "Remember...", "Remember item in menu"),

createRememberMenu(screen)); } - -void Remember::updateFrameClose(FluxboxWindow &win) { - // scan all applications and remove this fbw if it is a recorded group - Patterns::iterator it = m_pats->begin(); - for (; it != m_pats->end(); ++it) { - if (&win == it->second->group) - it->second->group = 0; - } -}
M src/Remember.hhsrc/Remember.hh

@@ -44,7 +44,7 @@ class ClientPattern;

class Application { public: - Application(bool grouped); + Application(int grouped); inline void forgetWorkspace() { workspace_remember = false; } inline void forgetHead() { head_remember = false; } inline void forgetDimensions() { dimensions_remember = false; }

@@ -137,8 +137,14 @@

bool save_on_close_remember; bool save_on_close; - bool is_grouped; - FluxboxWindow *group; + 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; };

@@ -201,6 +207,7 @@ ~Remember();

Application* find(WinClient &winclient); Application* add(WinClient &winclient); + FluxboxWindow* findGroup(Application *, BScreen &screen); void reconfigure(); // was load void save();

@@ -214,7 +221,6 @@

// Functions we actually use void setupFrame(FluxboxWindow &win); void setupClient(WinClient &winclient); - void updateFrameClose(FluxboxWindow &win); void updateClientClose(WinClient &winclient); void initForScreen(BScreen &screen);

@@ -233,6 +239,7 @@ void updateWorkspace(FluxboxWindow &win) {}

void updateState(FluxboxWindow &win) {} void updateHints(FluxboxWindow &win) {} void updateLayer(FluxboxWindow &win) {} + void updateFrameClose(FluxboxWindow &win) {} bool checkClientMessage(const XClientMessageEvent &ce, BScreen * screen, WinClient * const winclient) { return false; }

@@ -247,7 +254,7 @@ // returns number of lines read

// 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, bool is_group); + Application *findMatchingPatterns(ClientPattern *pat, Patterns *patlist, int is_group); std::auto_ptr<Patterns> m_pats; Clients m_clients;