some fixes for grouping with the apps file
This commit is contained in:
parent
cf6e471fbf
commit
e4488da120
4 changed files with 73 additions and 37 deletions
|
@ -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
|
||||
|
|
|
@ -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}
|
||||
|
|
|
@ -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<ClientPattern *> 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<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 @@ 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 "<<row<<"."<<endl;
|
||||
|
||||
|
@ -733,7 +737,11 @@ void Remember::save() {
|
|||
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 @@ 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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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<Patterns> m_pats;
|
||||
Clients m_clients;
|
||||
|
|
Loading…
Reference in a new issue