rewritten fluxbox-restart code, all destructors are called before the new program is started. the former method didnt do that.
@@ -22,7 +22,7 @@ // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. -// $Id: fluxbox.cc,v 1.258 2004/10/10 16:06:23 akir Exp $ +// $Id: fluxbox.cc,v 1.259 2004/10/18 01:26:54 akir Exp $ #include "fluxbox.hh"@@ -238,6 +238,7 @@ m_masked(0),
m_rc_file(rcfilename ? rcfilename : ""), m_argv(argv), m_argc(argc), m_starting(true), + m_restarting(false), m_shutdown(false), m_server_grabs(0), m_randr_event_type(0),@@ -457,6 +458,7 @@ }
Fluxbox::~Fluxbox() { + // destroy toolbars while (!m_toolbars.empty()) { delete m_toolbars.back();@@ -1357,14 +1359,11 @@ /// restarts fluxbox
void Fluxbox::restart(const char *prog) { shutdown(); + m_restarting = true; + if (prog) { - execlp(prog, prog, 0); - perror(prog); + m_restart_argument = prog; } - - // fall back in case the above execlp doesn't work - execvp(m_argv[0], m_argv); - execvp(StringUtil::basename(m_argv[0]).c_str(), m_argv); } /// prepares fluxbox for a shutdown@@ -1377,7 +1376,8 @@
XSetInputFocus(FbTk::App::instance()->display(), PointerRoot, None, CurrentTime); //send shutdown to all screens - for_each(m_screen_list.begin(), m_screen_list.end(), mem_fun(&BScreen::shutdown)); + for_each(m_screen_list.begin(), + m_screen_list.end(), mem_fun(&BScreen::shutdown)); sync(false);
@@ -22,7 +22,7 @@ // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. -// $Id: fluxbox.hh,v 1.92 2004/10/10 16:06:24 akir Exp $ +// $Id: fluxbox.hh,v 1.93 2004/10/18 01:26:54 akir Exp $ #ifndef FLUXBOX_HH #define FLUXBOX_HH@@ -83,7 +83,7 @@ public:
Fluxbox(int argc, char **argv, const char * dpy_name= 0, const char *rcfilename = 0); virtual ~Fluxbox(); - + static Fluxbox *instance() { return s_singleton; } /// main event loop void eventLoop();@@ -98,7 +98,7 @@ //WinClient *searchGroup(Window);
WinClient *searchWindow(Window); inline WinClient *getFocusedWindow() { return m_focused_window; } - + BScreen *searchScreen(Window w); inline unsigned int getDoubleClickInterval() const { return *m_rc_double_click_interval; }@@ -138,7 +138,7 @@ explicit Layer(int i) : m_num(i) {};
inline int getNum() const { return m_num; } Layer &operator=(int num) { m_num = num; return *this; } - + private: int m_num; };@@ -193,17 +193,20 @@ /// reloads the menus if the timestamps changed
void checkMenu(); void hideExtraMenus(BScreen &screen); - + /// handle any system signal sent to the application void handleSignal(int signum); void update(FbTk::Subject *changed); void attachSignals(FluxboxWindow &win); void attachSignals(WinClient &winclient); - + void timed_reconfigure(); bool isStartup() const { return m_starting; } + bool isRestarting() const { return m_restarting; } + + const std::string &getRestartArgument() const { return m_restart_argument; } /// get screen from number BScreen *findScreen(int num);@@ -221,6 +224,7 @@ BScreen *keyScreen() { return m_keyscreen; }
// screen we are watching for modifier changes BScreen *watchingScreen() { return m_watching_screen; } const XEvent &lastEvent() const { return m_last_event; } + private: typedef struct MenuTimestamp {@@ -232,24 +236,24 @@
std::string getRcFilename(); void load_rc(); - void reload_rc(); + void real_rereadMenu(); void real_reconfigure(); void handleEvent(XEvent *xe); - + void setupConfigFiles(); void handleButtonEvent(XButtonEvent &be); void handleUnmapNotify(XUnmapEvent &ue); void handleClientMessage(XClientMessageEvent &ce); void handleKeyEvent(XKeyEvent &ke); void setTitlebar(std::vector<Fluxbox::Titlebar>& dir, const char *arg); - + std::auto_ptr<FbAtoms> m_fbatoms; FbTk::ResourceManager m_resourcemanager, &m_screen_rm; - + //--- Resources FbTk::Resource<bool> m_rc_tabs, m_rc_ignoreborder;@@ -258,11 +262,11 @@ FbTk::Resource<int> m_rc_colors_per_channel, m_rc_numlayers,
m_rc_double_click_interval, m_rc_update_delay_time, m_rc_tabs_padding, m_rc_focused_tab_min_width; - FbTk::Resource<std::string> m_rc_stylefile, + FbTk::Resource<std::string> m_rc_stylefile, m_rc_menufile, m_rc_keyfile, m_rc_slitlistfile, m_rc_groupfile; - + FbTk::Resource<TitlebarList> m_rc_titlebar_left, m_rc_titlebar_right; FbTk::Resource<TabsAttachArea> m_rc_tabs_attach_area; FbTk::Resource<unsigned int> m_rc_cache_life, m_rc_cache_max;@@ -277,7 +281,7 @@ // See ICCCM section 4.1.11
// The group leader (which may not be mapped, so may not have a WinClient) // will have it's window being the group index std::multimap<Window, WinClient *> m_group_search; - + std::list<MenuTimestamp *> m_menu_timestamps; typedef std::list<BScreen *> ScreenList; ScreenList m_screen_list;@@ -297,6 +301,9 @@ Window m_masked;
std::string m_rc_file; ///< resource filename char **m_argv; int m_argc; + + std::string m_restart_argument; ///< what to restart + XEvent m_last_event; FbTk::Timer m_reconfig_timer; ///< when we execute reconfig command we must wait at least to next event round@@ -315,6 +322,7 @@ typedef std::vector<Toolbar *> Toolbars;
Toolbars m_toolbars; bool m_starting; + bool m_restarting; bool m_shutdown; int m_server_grabs; int m_randr_event_type; ///< the type number of randr event
@@ -20,7 +20,7 @@ // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. -// $Id: main.cc,v 1.32 2004/10/11 22:48:35 rathnor Exp $ +// $Id: main.cc,v 1.33 2004/10/18 01:26:54 akir Exp $ #include "fluxbox.hh" #include "version.h"@@ -28,6 +28,7 @@ #include "defaults.hh"
#include "FbTk/Theme.hh" #include "FbTk/I18n.hh" +#include "FbTk/StringUtil.hh" #ifdef HAVE_CONFIG_H #include "config.h"@@ -73,10 +74,10 @@ ostr<<_FBTEXT(Common, CompilerVersion, "Compiler version", "Compiler version used to build fluxbox")<<": "<<__fluxbox_compiler_version<<endl;
#endif // __fluxbox_compiler_version ostr<<endl<<_FBTEXT(Common, Defaults, "Defaults", "Default values compiled in")<<":"<<endl; - + ostr<<_FBTEXT(Common, DefaultMenuFile, " menu", "default menu file (right aligned - make sure same width as other default values)")<<": "<<DEFAULTMENU<<endl; ostr<<_FBTEXT(Common, DefaultStyle, " style", "default style (right aligned - make sure same width as other default values)")<<": "<<DEFAULTSTYLE<<endl; - + ostr<<_FBTEXT(Common, DefaultKeyFile, " keys", "default key file (right aligned - make sure same width as other default values)")<<": "<<DEFAULTKEYSFILE<<endl; ostr<<_FBTEXT(Common, DefaultInitFile, " init", "default init file (right aligned - make sure same width as other default values)")<<": "<<DEFAULT_INITFILE<<endl;@@ -87,7 +88,7 @@ <<" ("<<NOT<<" => "<<
_FBTEXT(Common, Disabled, "disabled", "option is turned off")<<"): "<<endl<< #ifndef DEBUG NOT<< -#endif // DEBUG +#endif // DEBUG "DEBUG"<<endl<< #ifndef SLIT@@ -107,7 +108,7 @@ "XPM"<<endl<<
#ifndef USE_GNOME NOT<< -#endif // USE_GNOME +#endif // USE_GNOME "GNOME"<<endl<< #ifndef KDE@@ -153,14 +154,14 @@ endl;
} int main(int argc, char **argv) { - + std::string session_display = ""; std::string rc_file; std::string log_filename; FbTk::NLSInit("fluxbox.cat"); _FB_USES_NLS; - + int i; for (i = 1; i < argc; ++i) { if (! strcmp(argv[i], "-rc")) {@@ -249,11 +250,11 @@ errbuf = cerr.rdbuf(log_file.rdbuf());
} try { - + fluxbox.reset(new Fluxbox(argc, argv, session_display.c_str(), rc_file.c_str())); fluxbox->eventLoop(); - exitcode = EXIT_SUCCESS; + exitcode = EXIT_SUCCESS; } catch (std::out_of_range &oor) { cerr<<"Fluxbox: "<<_FBTEXT(main, ErrorOutOfRange, "Out of range", "Error message")<<": "<<oor.what()<<endl;@@ -271,6 +272,10 @@ } catch (...) {
cerr<<"Fluxbox: "<<_FBTEXT(main, ErrorUnknown, "Unknown error", "Error message")<<"."<<endl; abort(); } + + bool restarting = fluxbox->isRestarting(); + const std::string restart_argument(fluxbox->getRestartArgument()); + // destroy fluxbox fluxbox.reset(0);@@ -279,6 +284,17 @@ if (outbuf != 0)
cout.rdbuf(outbuf); if (errbuf != 0) cerr.rdbuf(errbuf); + + if (restarting) { + if (restart_argument.c_str()) { + execlp(restart_argument.c_str(), restart_argument.c_str(), 0); + perror(restart_argument.c_str()); + } + + // fall back in case the above execlp doesn't work + execvp(argv[0], argv); + execvp(FbTk::StringUtil::basename(argv[0]).c_str(), argv); + } return exitcode; }