From e4488da12009aeb2d6d1624bd42a877c95db468e Mon Sep 17 00:00:00 2001 From: markt Date: Mon, 5 Feb 2007 17:20:01 +0000 Subject: some fixes for grouping with the apps file --- ChangeLog | 9 ++++++ doc/asciidoc/fluxbox.txt | 7 +++-- src/Remember.cc | 77 ++++++++++++++++++++++++++++++------------------ src/Remember.hh | 17 +++++++---- 4 files changed, 73 insertions(+), 37 deletions(-) diff --git a/ChangeLog b/ChangeLog index 328f320..4976b30 100644 --- a/ChangeLog +++ b/ChangeLog @@ -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 diff --git a/doc/asciidoc/fluxbox.txt b/doc/asciidoc/fluxbox.txt index 409163f..24e4bc0 100644 --- a/doc/asciidoc/fluxbox.txt +++ b/doc/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} diff --git a/src/Remember.cc b/src/Remember.cc index 6db1f9c..62c0d18 100644 --- a/src/Remember.cc +++ b/src/Remember.cc @@ -230,9 +230,8 @@ bool handleStartupItem(const string &line, int offset) { }; // 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::find(WinClient &winclient) { 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 @@ int Remember::parseApp(ifstream &file, Application &app, string *first_line) { 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 @@ void Remember::reconfigure() { if (!apps_file.eof()) { string line; int row = 0; - bool in_group = false; + int in_group = 0; list grouped_pats; while (getline(apps_file, line) && ! apps_file.eof()) { row++; @@ -606,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) { + 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 @@ 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 = 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 @@ 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, 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 @@ void Remember::reconfigure() { 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 "<begin(); Patterns::iterator git_end = m_pats->end(); for (; git != git_end; git++) { @@ -1035,9 +1043,6 @@ void Remember::setupFrame(FluxboxWindow &win) { // 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,14 +1138,37 @@ void Remember::setupClient(WinClient &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) { reconfigure(); // reload if it's changed Application *app = find(winclient); @@ -1172,12 +1200,3 @@ void Remember::initForScreen(BScreen &screen) { 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; - } -} diff --git a/src/Remember.hh b/src/Remember.hh index d78e226..581e525 100644 --- a/src/Remember.hh +++ b/src/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 @@ public: 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 @@ public: Application* find(WinClient &winclient); Application* add(WinClient &winclient); + FluxboxWindow* findGroup(Application *, BScreen &screen); void reconfigure(); // was load void save(); @@ -214,7 +221,6 @@ public: // 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 @@ public: 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 @@ 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, bool is_group); + Application *findMatchingPatterns(ClientPattern *pat, Patterns *patlist, int is_group); std::auto_ptr m_pats; Clients m_clients; -- cgit v0.11.2