From 2b83355eef4b473b586bd48cca5816598e0d2be2 Mon Sep 17 00:00:00 2001 From: markt Date: Thu, 29 Mar 2007 19:19:26 +0000 Subject: removed groups file, fixed initial_state handling --- ChangeLog | 4 + src/ClientPattern.cc | 2 +- src/FbTk/Resource.cc | 4 +- src/FocusControl.cc | 13 ++- src/Screen.cc | 10 +-- src/Window.cc | 28 ++----- src/Workspace.cc | 100 +--------------------- src/Workspace.hh | 8 -- src/fluxbox.cc | 17 +--- src/fluxbox.hh | 2 +- util/fluxbox-update_configs.cc | 185 +++++++++++++++++++++++++++++++---------- 11 files changed, 174 insertions(+), 199 deletions(-) diff --git a/ChangeLog b/ChangeLog index c572ab9..6e368be 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,9 @@ (Format: Year/Month/Day) Changes for 1.1: +*07/03/29: + * Removed groups file; entries will be added to the apps file automatically + (Mark) + * Fixed a problem with programs starting in IconicState (Mark) *07/03/28: * Startup file wasn't being run properly when created the first time (Mark) util/startfluxbox.in diff --git a/src/ClientPattern.cc b/src/ClientPattern.cc index 339092d..d644767 100644 --- a/src/ClientPattern.cc +++ b/src/ClientPattern.cc @@ -173,7 +173,7 @@ string ClientPattern::toString() const { switch ((*it)->prop) { case NAME: - // do nothing -> this is the default + pat.append("name="); break; case CLASS: pat.append("class="); diff --git a/src/FbTk/Resource.cc b/src/FbTk/Resource.cc index 5d2dc3b..cb45eac 100644 --- a/src/FbTk/Resource.cc +++ b/src/FbTk/Resource.cc @@ -24,6 +24,7 @@ #include "XrmDatabaseHelper.hh" #include "Resource.hh" #include "I18n.hh" +#include "StringUtil.hh" #include #ifdef HAVE_CASSERT @@ -61,7 +62,7 @@ bool ResourceManager::m_init = false; @return true on success else false */ bool ResourceManager::load(const char *filename) { - m_filename = filename; + m_filename = StringUtil::expandFilename(filename).c_str(); // force reload (lock will ensure it exists) if (m_database) { @@ -106,6 +107,7 @@ bool ResourceManager::load(const char *filename) { */ bool ResourceManager::save(const char *filename, const char *mergefilename) { assert(filename); + filename = StringUtil::expandFilename(filename).c_str(); // empty database XrmDatabaseHelper database; diff --git a/src/FocusControl.cc b/src/FocusControl.cc index 71b289b..c5ee939 100644 --- a/src/FocusControl.cc +++ b/src/FocusControl.cc @@ -220,6 +220,16 @@ void FocusControl::setFocusBack(FluxboxWindow *fbwin) { if (m_focused_list.empty() || s_reverting) return; + // if the window isn't already in this list, we could accidentally add it + Focusables::iterator win_begin = m_focused_win_list.begin(), + win_end = m_focused_win_list.end(); + Focusables::iterator win_it = find(win_begin, win_end, fbwin); + if (win_it == win_end) + return; + + m_focused_win_list.erase(win_it); + m_focused_win_list.push_back(fbwin); + Focusables::iterator it = m_focused_list.begin(); // use back to avoid an infinite loop Focusables::iterator it_back = --m_focused_list.end(); @@ -237,9 +247,6 @@ void FocusControl::setFocusBack(FluxboxWindow *fbwin) { m_focused_list.erase(it); } - m_focused_win_list.remove(fbwin); - m_focused_win_list.push_back(fbwin); - } void FocusControl::stopCyclingFocus() { diff --git a/src/Screen.cc b/src/Screen.cc index c7b32db..071d253 100644 --- a/src/Screen.cc +++ b/src/Screen.cc @@ -699,15 +699,9 @@ void BScreen::initWindows() { continue; } - if (attrib.map_state != IsUnmapped) { - FluxboxWindow *win = createWindow(children[i]); + if (attrib.map_state != IsUnmapped) + createWindow(children[i]); - if (win) { - XMapRequestEvent mre; - mre.window = children[i]; - win->mapRequestEvent(mre); - } - } } children[i] = None; // we dont need this anymore, since we already created a window for it } diff --git a/src/Window.cc b/src/Window.cc index d5f75e1..d942482 100644 --- a/src/Window.cc +++ b/src/Window.cc @@ -544,7 +544,8 @@ void FluxboxWindow::init() { if (iconic) { iconic = false; iconify(); - } + } else + deiconify(false); sendConfigureNotify(); // no focus default @@ -2323,28 +2324,11 @@ void FluxboxWindow::mapRequestEvent(XMapRequestEvent &re) { return; } - // rest of current state checking is in initialisation - if (m_current_state == WithdrawnState) - withdraw(true); - else { - - // if this window was destroyed while autogrouping - bool destroyed = false; - - // check WM_CLASS only when we changed state to NormalState from - // WithdrawnState (ICCC 4.1.2.5) - client->updateWMClassHint(); + // Note: this function never gets called from WithdrawnState + // initial state is handled in restoreAttributes() and init() + setCurrentClient(*client, false); // focus handled on MapNotify + deiconify(false); - Workspace *wsp = screen().getWorkspace(m_workspace_number); - if (wsp != 0 && isGroupable()) - destroyed = wsp->checkGrouping(*this); - - // if we weren't grouped with another window we deiconify ourself - // make sure iconified windows stay that way on fluxbox start - if (!destroyed && !(iconic && Fluxbox::instance()->isStartup())) - deiconify(false); - - } } diff --git a/src/Workspace.cc b/src/Workspace.cc index e65a89f..05d8420 100644 --- a/src/Workspace.cc +++ b/src/Workspace.cc @@ -61,19 +61,15 @@ #endif #include -#include using std::string; -using std::vector; -using std::ifstream; #ifdef DEBUG +#include using std::cerr; using std::endl; #endif // DEBUG -Workspace::GroupList Workspace::m_groups; - Workspace::Workspace(BScreen &scrn, const string &name, unsigned int id): m_screen(scrn), m_clientmenu(scrn, m_windowlist, &m_clientlist_sig), @@ -181,100 +177,6 @@ size_t Workspace::numberOfWindows() const { return m_windowlist.size(); } -namespace { -// helper class for checkGrouping -class FindInGroup { -public: - FindInGroup(const FluxboxWindow &w):m_w(w) { } - bool operator ()(const string &name) const { - return (name == m_w.winClient().getWMClassName()); - } -private: - const FluxboxWindow &m_w; -}; - -}; - -//Note: this function doesn't check if the window is groupable -bool Workspace::checkGrouping(FluxboxWindow &win) { - if (win.numClients() == 0) - return false; -#ifdef DEBUG - cerr<<__FILE__<<"("<<__LINE__<<"): Checking grouping. ("<winClient().getWMClassName()<isGroupable() || (*wit)->winClient().fbwindow() == &win) - break; // try next name -#ifdef DEBUG - cerr<<__FILE__<<"("<<__FUNCTION__<<"): window ("<<*wit<<") attaching window ("<<&win<<")"<attachClient(win.winClient()); - (*wit)->raise(); - return true; // grouping done - - } - - } - - } - - } - - return false; -} - -bool Workspace::loadGroups(const string &filename) { - string real_filename = FbTk::StringUtil::expandFilename(filename); - FbTk::StringUtil::removeTrailingWhitespace(real_filename); - ifstream infile(real_filename.c_str()); - if (!infile) - return false; - - m_groups.clear(); // erase old groups - - // load new groups - while (!infile.eof()) { - string line; - vector names; - getline(infile, line); - FbTk::StringUtil::stringtok(names, line); - m_groups.push_back(names); - } - - return true; -} - void Workspace::setName(const string &name) { if (!name.empty() && name != "") { m_name = name; diff --git a/src/Workspace.hh b/src/Workspace.hh index e4fffd0..3f865ed 100644 --- a/src/Workspace.hh +++ b/src/Workspace.hh @@ -77,20 +77,12 @@ public: Windows &windowList() { return m_windowlist; } size_t numberOfWindows() const; - bool checkGrouping(FluxboxWindow &win); - - static bool loadGroups(const std::string &filename); private: void placeWindow(FluxboxWindow &win); BScreen &m_screen; - typedef std::vector Group; - typedef std::vector GroupList; - - static GroupList m_groups; ///< handle auto groupings - Windows m_windowlist; FbTk::Subject m_clientlist_sig; ClientMenu m_clientmenu; diff --git a/src/fluxbox.cc b/src/fluxbox.cc index 2393837..4441a7d 100644 --- a/src/fluxbox.cc +++ b/src/fluxbox.cc @@ -218,7 +218,6 @@ Fluxbox::Fluxbox(int argc, char **argv, const char *dpy_name, const char *rcfile m_rc_menufile(m_resourcemanager, DEFAULTMENU, "session.menuFile", "Session.MenuFile"), m_rc_keyfile(m_resourcemanager, DEFAULTKEYSFILE, "session.keyFile", "Session.KeyFile"), m_rc_slitlistfile(m_resourcemanager, "~/.fluxbox/slitlist", "session.slitlistFile", "Session.SlitlistFile"), - m_rc_groupfile(m_resourcemanager, "~/.fluxbox/groups", "session.groupFile", "Session.GroupFile"), m_rc_appsfile(m_resourcemanager, "~/.fluxbox/apps", "session.appsFile", "Session.AppsFile"), m_rc_tabs_attach_area(m_resourcemanager, ATTACH_AREA_WINDOW, "session.tabsAttachArea", "Session.TabsAttachArea"), m_rc_cache_life(m_resourcemanager, 5, "session.cacheLife", "Session.CacheLife"), @@ -781,7 +780,6 @@ void Fluxbox::handleEvent(XEvent * const e) { #endif // DEBUG WinClient *winclient = searchWindow(e->xmaprequest.window); - FluxboxWindow *win = 0; if (! winclient) { BScreen *screen = 0; @@ -807,15 +805,14 @@ void Fluxbox::handleEvent(XEvent * const e) { if (screen == 0) { cerr<<"Fluxbox "<<_FB_CONSOLETEXT(Fluxbox, CantMapWindow, "Warning! Could not find screen to map window on!", "")<createWindow(e->xmaprequest.window); + screen->createWindow(e->xmaprequest.window); } else { - win = winclient->fbwindow(); + // we don't handle MapRequest in FluxboxWindow::handleEvent + if (winclient->fbwindow()) + winclient->fbwindow()->mapRequestEvent(e->xmaprequest); } - // we don't handle MapRequest in FluxboxWindow::handleEvent - if (win) - win->mapRequestEvent(e->xmaprequest); } break; case MapNotify: @@ -1499,12 +1496,6 @@ void Fluxbox::load_rc() { if (m_rc_stylefile->empty()) *m_rc_stylefile = DEFAULTSTYLE; - - if (!Workspace::loadGroups(*m_rc_groupfile)) { -#ifdef DEBUG - cerr<<_FB_CONSOLETEXT(Fluxbox, CantLoadGroupFile, "Failed to load groupfile", "Couldn't load the groupfile")<<": "<<*m_rc_groupfile< m_rc_stylefile, m_rc_styleoverlayfile, m_rc_menufile, m_rc_keyfile, m_rc_slitlistfile, - m_rc_groupfile, m_rc_appsfile; + m_rc_appsfile; FbTk::Resource m_rc_tabs_attach_area; diff --git a/util/fluxbox-update_configs.cc b/util/fluxbox-update_configs.cc index de1fbb9..5aa0d6c 100644 --- a/util/fluxbox-update_configs.cc +++ b/util/fluxbox-update_configs.cc @@ -38,23 +38,17 @@ #define _GNU_SOURCE #endif // _GNU_SOURCE -#ifdef HAVE_CSTDIO - #include -#else - #include -#endif -#ifdef HAVE_CSTDLIB - #include -#else - #include -#endif #ifdef HAVE_CSTRING #include #else #include #endif + #include #include +#include +#include +#include using std::cout; using std::cerr; @@ -62,39 +56,29 @@ using std::endl; using std::string; using std::ifstream; using std::ofstream; +using std::set; +using std::map; +using std::list; -#define VERSION 1 +string read_file(string filename); +void write_file(string filename, string &contents); +void save_all_files(); int run_updates(int old_version, FbTk::ResourceManager rm) { int new_version = old_version; if (old_version < 1) { // add mouse events to keys file - FbTk::Resource rc_keyfile(rm, DEFAULTKEYSFILE, + FbTk::Resource rc_keyfile(rm, "~/.fluxbox/keys", "session.keyFile", "Session.KeyFile"); string keyfilename = FbTk::StringUtil::expandFilename(*rc_keyfile); - // ok, I don't know anything about file handling in c++ - // what's it to you?!?! - // I assume there should be some error handling in here, but I sure - // don't know how, and I don't have documentation - - ifstream in_keyfile(keyfilename.c_str()); - string whole_keyfile = ""; - - while (!in_keyfile.eof()) { - string linebuffer; - - getline(in_keyfile, linebuffer); - whole_keyfile += linebuffer + "\n"; - } - in_keyfile.close(); - - ofstream out_keyfile(keyfilename.c_str()); + string whole_keyfile = read_file(keyfilename); + string new_keyfile = ""; // let's put our new keybindings first, so they're easy to find - out_keyfile << "!mouse actions added by fluxbox-update_configs" << endl - << "OnDesktop Mouse1 :hideMenus" << endl - << "OnDesktop Mouse2 :workspaceMenu" << endl - << "OnDesktop Mouse3 :rootMenu" << endl; + new_keyfile += "!mouse actions added by fluxbox-update_configs\n"; + new_keyfile += "OnDesktop Mouse1 :hideMenus\n"; + new_keyfile += "OnDesktop Mouse2 :workspaceMenu\n"; + new_keyfile += "OnDesktop Mouse3 :rootMenu\n"; // scrolling on desktop needs to match user's desktop wheeling settings // hmmm, what are the odds that somebody wants this to be different on @@ -108,25 +92,66 @@ int run_updates(int old_version, FbTk::ResourceManager rm) { "Session.Screen0.ReverseWheeling"); if (*rc_wheeling) { if (*rc_reverse) { // if you ask me, this should have been default - out_keyfile << "OnDesktop Mouse4 :prevWorkspace" << endl - << "OnDesktop Mouse5 :nextWorkspace" << endl; + new_keyfile += "OnDesktop Mouse4 :prevWorkspace\n"; + new_keyfile += "OnDesktop Mouse5 :nextWorkspace\n"; } else { - out_keyfile << "OnDesktop Mouse4 :nextWorkspace" << endl - << "OnDesktop Mouse5 :prevWorkspace" << endl; + new_keyfile += "OnDesktop Mouse4 :nextWorkspace\n"; + new_keyfile += "OnDesktop Mouse5 :prevWorkspace\n"; } } - out_keyfile << endl; // just for good looks + new_keyfile += "\n"; // just for good looks + new_keyfile += whole_keyfile; // don't forget user's old keybindings - // now, restore user's old keybindings - out_keyfile << whole_keyfile; + write_file(keyfilename, new_keyfile); new_version = 1; } + if (old_version < 2) { // move groups entries to apps file + FbTk::Resource rc_groupfile(rm, "~/.fluxbox/groups", + "session.groupFile", "Session.GroupFile"); + string groupfilename = FbTk::StringUtil::expandFilename(*rc_groupfile); + string whole_groupfile = read_file(groupfilename); + + FbTk::Resource rc_appsfile(rm, "~/.fluxbox/apps", + "session.appsFile", "Session.AppsFile"); + string appsfilename = FbTk::StringUtil::expandFilename(*rc_appsfile); + string whole_appsfile = read_file(appsfilename); + + string new_appsfile = ""; + + list lines; + FbTk::StringUtil::stringtok(lines, whole_groupfile, "\n"); + + list::iterator line_it = lines.begin(); + list::iterator line_it_end = lines.end(); + for (; line_it != line_it_end; ++line_it) { + new_appsfile += "[group] (workspace)\n"; + + list apps; + FbTk::StringUtil::stringtok(apps, *line_it); + + list::iterator it = apps.begin(); + list::iterator it_end = apps.end(); + for (; it != it_end; ++it) { + new_appsfile += " [app] (name="; + new_appsfile += *it; + new_appsfile += ")\n"; + } + + new_appsfile += "[end]\n"; + } + + new_appsfile += whole_appsfile; + write_file(appsfilename, new_appsfile); + new_version = 2; + } + return new_version; } int main(int argc, char **argv) { string rc_filename; + set style_filenames; int i = 1; pid_t fb_pid = 0; @@ -165,11 +190,11 @@ int main(int argc, char **argv) { // couldn't load rc file if (!rc_filename.empty()) { cerr<<_FB_CONSOLETEXT(Fluxbox, CantLoadRCFile, "Failed to load database", "Failed trying to read rc file")<<":"< old_version) { + // configs were updated -- let's save our changes config_version = new_version; resource_manager.save(rc_filename.c_str(), rc_filename.c_str()); + save_all_files(); #ifdef HAVE_SIGNAL_H // if we were given a fluxbox pid, send it a reconfigure signal @@ -195,3 +222,75 @@ int main(int argc, char **argv) { return 0; } + +static set modified_files; +// we may want to put a size limit on this cache, so it doesn't grow too big +static map file_cache; + +// returns the contents of the file given, either from the cache or by reading +// the file from disk +string read_file(string filename) { + // check if we already have the file in memory + map::iterator it = file_cache.find(filename); + if (it != file_cache.end()) + return it->second; + + // nope, we'll have to read the file + ifstream infile(filename.c_str()); + string whole_file = ""; + + if (!infile) // failed to open file + return whole_file; + + while (!infile.eof()) { + string linebuffer; + + getline(infile, linebuffer); + whole_file += linebuffer + "\n"; + } + infile.close(); + + file_cache[filename] = whole_file; + return whole_file; +} + +#ifdef NOT_USED +// remove the file from the cache, writing to disk if it's been changed +void forget_file(string filename) { + map::iterator cache_it = file_cache.find(filename); + // check if we knew about the file to begin with + if (cache_it == file_cache.end()) + return; + + // check if we've actually modified it + set::iterator mod_it = modified_files.find(filename); + if (mod_it == modified_files.end()) { + file_cache.erase(cache_it); + return; + } + + // flush our changes to disk and remove all traces + ofstream outfile(filename.c_str()); + outfile << cache_it->second; + file_cache.erase(cache_it); + modified_files.erase(mod_it); +} +#endif // NOT_USED + +// updates the file contents in the cache and marks the file as modified so it +// gets saved later +void write_file(string filename, string &contents) { + modified_files.insert(filename); + file_cache[filename] = contents; +} + +// actually save all the files we've modified +void save_all_files() { + set::iterator it = modified_files.begin(); + set::iterator it_end = modified_files.end(); + for (; it != it_end; ++it) { + ofstream outfile(it->c_str()); + outfile << file_cache[it->c_str()]; + } + modified_files.clear(); +} -- cgit v0.11.2