From 707df7d81b6df25fa98f3a867485cb7bbbbf74b8 Mon Sep 17 00:00:00 2001 From: Pavel Labath Date: Tue, 2 Aug 2011 13:56:31 +0200 Subject: Automatically save init file when a resource is modified previously, init was autosaved only when a resource was modified using the menu. I have also included modifications through lua code. To avoid wasting resources, the file is not saved immediately, but with a 5 second delay (to enable saving a bunch of changes in one go) --- src/FbTk/LResource.cc | 21 +++++++++++++++++++-- src/FbTk/LResource.hh | 11 ++++++++++- src/FbTk/Resource.hh | 11 +++++++++-- src/Screen.cc | 52 +++++++++++++++++++++------------------------------ src/fluxbox.cc | 2 +- 5 files changed, 60 insertions(+), 37 deletions(-) diff --git a/src/FbTk/LResource.cc b/src/FbTk/LResource.cc index 31362bd..de90b95 100644 --- a/src/FbTk/LResource.cc +++ b/src/FbTk/LResource.cc @@ -26,8 +26,11 @@ #include "I18n.hh" #include "LuaUtil.hh" +#include "MemFun.hh" #include "Resource.hh" +// defined in LResourceHelper-lua.cc +// contains the compiled code of LResourceHelper.lua extern const char LResourceHelper[]; extern const unsigned int LResourceHelper_size; @@ -101,8 +104,15 @@ void LResourceManager::convert(ResourceManager &old, const std::string &new_file new_rm.save(new_file.c_str(), NULL); } -LResourceManager::LResourceManager(const std::string &root, Lua &l) - : ResourceManager_base(root), m_l(&l) { +LResourceManager::LResourceManager(const std::string &root, Lua &l, unsigned int autosave) + : ResourceManager_base(root), m_l(&l) { + + m_savetimer.setInterval(autosave); + m_savetimer.fireOnce(true); + m_savetimer.setFunctor( MemFunBind(*this, &LResourceManager::save, + static_cast(NULL), static_cast(NULL) + ) ); + setLua(l); } @@ -143,6 +153,8 @@ bool LResourceManager::save(const char *filename, const char *) { if(filename == NULL) filename = m_filename.c_str(); + std::cerr << "XXX SAVING " << filename << std::endl; + m_l->getfield(lua::REGISTRYINDEX, dump_resources); m_l->getfield(lua::GLOBALSINDEX, m_root.c_str()); m_l->pushstring(filename); @@ -194,6 +206,11 @@ void LResourceManager::doRemoveResource(Resource_base &r) { m_l->pop(); } +void LResourceManager::resourceChanged(Resource_base &r) { + if(! m_savetimer.isTiming()) + m_savetimer.start(); +} + void LResourceManager::setLua(Lua &l) { l.checkstack(2); lua::stack_sentry s(l); diff --git a/src/FbTk/LResource.hh b/src/FbTk/LResource.hh index f0f8050..30f0e02 100644 --- a/src/FbTk/LResource.hh +++ b/src/FbTk/LResource.hh @@ -28,6 +28,7 @@ #include #include "Resource.hh" +#include "Timer.hh" namespace FbTk { @@ -37,11 +38,18 @@ class LResourceManager: public ResourceManager_base { public: static void convert(ResourceManager &old, const std::string &new_file); - LResourceManager(const std::string &root, Lua &l); + /** + * @param root the name of the table where settings will reside + * @param l lua context + * @param autosave delay (in seconds) for automatic saving of resources. Modifying a resource + * starts a timer. If another resource is modified, the timer is restarted. 0 = disabled + */ + LResourceManager(const std::string &root, Lua &l, unsigned int autosave = 0); void load(const std::string &filename, const std::string &fallback); virtual bool save(const char *filename, const char *); virtual void addResource(Resource_base &r); virtual void removeResource(Resource_base &r); + virtual void resourceChanged(Resource_base &r); void setLua(Lua &l); private: @@ -50,6 +58,7 @@ private: Lua *m_l; std::string m_filename; + Timer m_savetimer; }; } // end namespace FbTk diff --git a/src/FbTk/Resource.hh b/src/FbTk/Resource.hh index 7a797a1..c4a7951 100644 --- a/src/FbTk/Resource.hh +++ b/src/FbTk/Resource.hh @@ -96,8 +96,6 @@ public: /// @return true on success virtual bool save(const char *filename, const char *mergefilename=0) = 0; - - /// Add resource to list, only used in Resource virtual void addResource(Resource_base &r); @@ -106,6 +104,9 @@ public: m_resourcelist.remove(&r); } + /// Called by Resources when their value changes + virtual void resourceChanged(Resource_base &r) = 0; + /// searches for the resource with the resourcename /// @return pointer to resource base on success, else 0. Resource_base *findResource(const std::string &resourcename); @@ -154,6 +155,8 @@ public: /// Add resource to list, only used in Resource virtual void addResource(Resource_base &r); + virtual void resourceChanged(Resource_base &r) {}; + // this marks the database as "in use" and will avoid reloading // resources unless it is zero. // It returns this resource manager. Useful for passing to @@ -211,12 +214,14 @@ public: void setDefaultValue() { m_value = m_defaultval; + m_rm.resourceChanged(*this); m_modified_sig.emit(m_value); } /// sets resource from string, specialized, must be implemented void setFromString(const char *strval) { try { m_value = Traits::fromString(strval); + m_rm.resourceChanged(*this); m_modified_sig.emit(m_value); } catch(ConversionError &e) { @@ -226,6 +231,7 @@ public: } Accessor &operator =(const T& newvalue) { m_value = newvalue; + m_rm.resourceChanged(*this); m_modified_sig.emit(m_value); return *this; } @@ -236,6 +242,7 @@ public: virtual void setFromLua(lua::state &l) { try { m_value = Traits::fromLua(l); + m_rm.resourceChanged(*this); m_modified_sig.emit(m_value); } catch(ConversionError &e) { diff --git a/src/Screen.cc b/src/Screen.cc index 1e3d1c4..1acefc1 100644 --- a/src/Screen.cc +++ b/src/Screen.cc @@ -184,9 +184,8 @@ int calcSquareDistance(int x1, int y1, int x2, int y2) { class TabPlacementMenuItem: public FbTk::RadioMenuItem { public: TabPlacementMenuItem(const FbTk::FbString & label, BScreen &screen, - FbWinFrame::TabPlacement place, - FbTk::RefCount > &cmd): - FbTk::RadioMenuItem(label, cmd), + FbWinFrame::TabPlacement place): + FbTk::RadioMenuItem(label), m_screen(screen), m_place(place) { setCloseOnClick(false); @@ -1442,15 +1441,8 @@ void BScreen::setupConfigmenu(FbTk::Menu &menu) { menu.removeAll(); - FbTk::MacroCommand *s_a_reconf_macro = new FbTk::MacroCommand(); - FbTk::RefCount > saverc_cmd(new FbTk::SimpleCommand( - *Fluxbox::instance(), - &Fluxbox::save_rc)); FbTk::RefCount > reconf_cmd(FbTk::CommandParser::instance().parse("reconfigure")); - s_a_reconf_macro->add(saverc_cmd); - s_a_reconf_macro->add(reconf_cmd); - FbTk::RefCount > save_and_reconfigure(s_a_reconf_macro); // create focus menu // we don't set this to internal menu so will // be deleted toghether with the parent @@ -1459,12 +1451,12 @@ void BScreen::setupConfigmenu(FbTk::Menu &menu) { "Method used to give focus to windows"); FbTk::RefCount focus_menu( createMenu(focusmenu_label) ); -#define _BOOLITEM(m,a, b, c, d, e, f) (m).insert(new FbTk::BoolMenuItem(_FB_XTEXT(a, b, c, d), e, f)) +#define _BOOLITEM(m,a, b, c, d, e) (m).insert(new FbTk::BoolMenuItem(_FB_XTEXT(a, b, c, d), e)) #define _FOCUSITEM(a, b, c, d, e) \ focus_menu->insert(new FocusModelMenuItem(_FB_XTEXT(a, b, c, d), focusControl(), \ - e, save_and_reconfigure)) + e, reconf_cmd)) _FOCUSITEM(Configmenu, ClickFocus, "Click To Focus", "Click to focus", @@ -1482,27 +1474,26 @@ void BScreen::setupConfigmenu(FbTk::Menu &menu) { focus_menu->insert(new FbTk::MenuSeparator()); focus_menu->insert(new TabFocusModelMenuItem(_FB_XTEXT(Configmenu, ClickTabFocus, "ClickTabFocus", "Click tab to focus windows"), - focusControl(), FocusControl::CLICKTABFOCUS, save_and_reconfigure)); + focusControl(), FocusControl::CLICKTABFOCUS, reconf_cmd)); focus_menu->insert(new TabFocusModelMenuItem(_FB_XTEXT(Configmenu, MouseTabFocus, "MouseTabFocus", "Hover over tab to focus windows"), - focusControl(), FocusControl::MOUSETABFOCUS, save_and_reconfigure)); + focusControl(), FocusControl::MOUSETABFOCUS, reconf_cmd)); focus_menu->insert(new FbTk::MenuSeparator()); try { focus_menu->insert(new FbTk::BoolMenuItem(_FB_XTEXT(Configmenu, FocusNew, "Focus New Windows", "Focus newly created windows"), - m_resource_manager.getResource(name() + ".focusNewWindows"), - saverc_cmd)); + m_resource_manager.getResource(name() + ".focusNewWindows"))); } catch (FbTk::ResourceException e) { cerr<updateMenu(); @@ -1518,17 +1509,17 @@ void BScreen::setupConfigmenu(FbTk::Menu &menu) { _BOOLITEM(*maxmenu, Configmenu, FullMax, "Full Maximization", "Maximise over slit, toolbar, etc", - resource.full_max, saverc_cmd); + resource.full_max); _BOOLITEM(*maxmenu, Configmenu, MaxIgnoreInc, "Ignore Resize Increment", "Maximizing Ignores Resize Increment (e.g. xterm)", - resource.max_ignore_inc, saverc_cmd); + resource.max_ignore_inc); _BOOLITEM(*maxmenu, Configmenu, MaxDisableMove, "Disable Moving", "Don't Allow Moving While Maximized", - resource.max_disable_move, saverc_cmd); + resource.max_disable_move); _BOOLITEM(*maxmenu, Configmenu, MaxDisableResize, "Disable Resizing", "Don't Allow Resizing While Maximized", - resource.max_disable_resize, saverc_cmd); + resource.max_disable_resize); maxmenu->updateMenu(); menu.insert(maxmenu_label, maxmenu); @@ -1548,13 +1539,13 @@ void BScreen::setupConfigmenu(FbTk::Menu &menu) { _BOOLITEM(*tab_menu,Configmenu, TabsInTitlebar, "Tabs in Titlebar", "Tabs in Titlebar", - resource.default_internal_tabs, saverc_cmd); + resource.default_internal_tabs); tab_menu->insert(new FbTk::BoolMenuItem(_FB_XTEXT(Common, MaximizeOver, "Maximize Over", "Maximize over this thing when maximizing"), - resource.max_over_tabs, save_and_reconfigure)); + resource.max_over_tabs, reconf_cmd)); tab_menu->insert(new FbTk::BoolMenuItem(_FB_XTEXT(Toolbar, ShowIcons, "Show Pictures", "chooses if little icons are shown next to title in the iconbar"), - resource.tabs_use_pixmap, save_and_reconfigure)); + resource.tabs_use_pixmap, reconf_cmd)); FbTk::MenuItem *tab_width_item = new FbTk::IntMenuItem(_FB_XTEXT(Configmenu, ExternalTabWidth, @@ -1562,7 +1553,6 @@ void BScreen::setupConfigmenu(FbTk::Menu &menu) { "Width of external-style tabs"), resource.tab_width, 10, 3000, /* silly number */ *tab_menu); - tab_width_item->setCommand(saverc_cmd); tab_menu->insert(tab_width_item); // menu is 3 wide, 5 down @@ -1597,7 +1587,7 @@ void BScreen::setupConfigmenu(FbTk::Menu &menu) { tabplacement_menu->insert(p.label); tabplacement_menu->setItemEnabled(i, false); } else - tabplacement_menu->insert(new TabPlacementMenuItem(p.label, *this, p.placement, saverc_cmd)); + tabplacement_menu->insert(new TabPlacementMenuItem(p.label, *this, p.placement)); } tabplacement_menu->updateMenu(); @@ -1616,13 +1606,13 @@ void BScreen::setupConfigmenu(FbTk::Menu &menu) { alpha_menu->insert(new FbTk::BoolMenuItem(_FB_XTEXT(Configmenu, ForcePseudoTrans, "Force Pseudo-Transparency", "When composite is available, still use old pseudo-transparency"), - Fluxbox::instance()->getPseudoTransResource(), save_and_reconfigure)); + Fluxbox::instance()->getPseudoTransResource(), reconf_cmd)); } // in order to save system resources, don't save or reconfigure alpha // settings until after the user is done changing them FbTk::RefCount > delayed_save_and_reconf( - new FbTk::DelayedCmd(save_and_reconfigure)); + new FbTk::DelayedCmd(reconf_cmd)); FbTk::MenuItem *focused_alpha_item = new FbTk::IntMenuItem(_FB_XTEXT(Configmenu, FocusedAlpha, @@ -1662,11 +1652,11 @@ void BScreen::setupConfigmenu(FbTk::Menu &menu) { _BOOLITEM(menu, Configmenu, OpaqueMove, "Opaque Window Moving", "Window Moving with whole window visible (as opposed to outline moving)", - resource.opaque_move, saverc_cmd); + resource.opaque_move); _BOOLITEM(menu, Configmenu, WorkspaceWarping, "Workspace Warping", "Workspace Warping - dragging windows to the edge and onto the next workspace", - resource.workspace_warping, saverc_cmd); + resource.workspace_warping); #undef _BOOLITEM diff --git a/src/fluxbox.cc b/src/fluxbox.cc index fb5c208..1dc3105 100644 --- a/src/fluxbox.cc +++ b/src/fluxbox.cc @@ -235,7 +235,7 @@ Fluxbox::Fluxbox(int argc, char **argv, : FbTk::App(dpy_name.c_str()), m_l(new Lua), m_fbatoms(FbAtoms::instance()), - m_resourcemanager("session", *m_l), + m_resourcemanager("session", *m_l, 5), m_RC_PATH(rc_path), m_RC_INIT_FILE("init"), -- cgit v0.11.2