changed the way we create the '~/.fluxbox' directory to avoid race conditions
before bringing up the first instance of Fluxbox we prepare the directory and the files it needs. if the config version of exiting files is lower than what we expect, we upgrade the config files. after that we bring up Fluxbox. the old way was problematic because setupConfigFiles() calls 'fluxbox-update_configs' which does its job in the background while fluxbox continues to boot. 'fluxbox-update_configs' sends a USR2 signal to the booting fluxbox (it might even be finished, no one knows) which triggers 'load_rc()' which triggered 'setupConfigFiles()' again which might trigger 'fluxbox-update_configs' again (on my machine 'fluxbox-update_configs' was called 3 times and left a pretty crippled 'keys' file when it was done). bootstrapping before bringing up fluxbox resolves the issue. as a bonus: no need to send USR2 to fluxbox to reload the config file because fluxbox has not even tried to read it yet.
This commit is contained in:
parent
c9c741c88d
commit
0ef76292c5
5 changed files with 141 additions and 104 deletions
|
@ -53,14 +53,14 @@ defaults.hh: Makefile
|
|||
echo '#define DEFAULT_WINDOWMENU "$(DEFAULT_WINDOWMENU)"'; \
|
||||
echo '#define PROGRAM_PREFIX "$(PROGRAM_PREFIX:NONE=)"'; \
|
||||
echo '#define PROGRAM_SUFFIX "$(PROGRAM_SUFFIX:NONE=)"'; \
|
||||
echo 'std::string realProgramName(std::string name);'; \
|
||||
echo 'std::string realProgramName(const std::string& name);'; \
|
||||
echo 'const char* gitrevision();' ) > defaults.hh
|
||||
|
||||
defaults.cc: force
|
||||
@( \
|
||||
echo '#include "defaults.hh"'; \
|
||||
echo ''; \
|
||||
echo 'std::string realProgramName(std::string name) {'; \
|
||||
echo 'std::string realProgramName(const std::string& name) {'; \
|
||||
echo ' return PROGRAM_PREFIX + name + PROGRAM_SUFFIX;'; \
|
||||
echo '}'; \
|
||||
echo ''; \
|
||||
|
|
103
src/fluxbox.cc
103
src/fluxbox.cc
|
@ -185,13 +185,17 @@ int handleXErrors(Display *d, XErrorEvent *e) {
|
|||
//static singleton var
|
||||
Fluxbox *Fluxbox::s_singleton=0;
|
||||
|
||||
Fluxbox::Fluxbox(int argc, char **argv, const char *dpy_name,
|
||||
const char *rcfilename, bool xsync)
|
||||
: FbTk::App(dpy_name),
|
||||
Fluxbox::Fluxbox(int argc, char **argv,
|
||||
const std::string& dpy_name,
|
||||
const std::string& rc_path, const std::string& rc_filename, bool xsync)
|
||||
: FbTk::App(dpy_name.c_str()),
|
||||
m_fbatoms(FbAtoms::instance()),
|
||||
m_resourcemanager(rcfilename, true),
|
||||
m_resourcemanager(rc_filename.c_str(), true),
|
||||
// TODO: shouldn't need a separate one for screen
|
||||
m_screen_rm(m_resourcemanager),
|
||||
|
||||
m_RC_PATH(rc_path),
|
||||
m_RC_INIT_FILE("init"),
|
||||
m_rc_ignoreborder(m_resourcemanager, false, "session.ignoreBorder", "Session.IgnoreBorder"),
|
||||
m_rc_pseudotrans(m_resourcemanager, false, "session.forcePseudoTransparency", "Session.forcePseudoTransparency"),
|
||||
m_rc_colors_per_channel(m_resourcemanager, 4,
|
||||
|
@ -199,11 +203,11 @@ Fluxbox::Fluxbox(int argc, char **argv, const char *dpy_name,
|
|||
m_rc_double_click_interval(m_resourcemanager, 250, "session.doubleClickInterval", "Session.DoubleClickInterval"),
|
||||
m_rc_tabs_padding(m_resourcemanager, 0, "session.tabPadding", "Session.TabPadding"),
|
||||
m_rc_stylefile(m_resourcemanager, DEFAULTSTYLE, "session.styleFile", "Session.StyleFile"),
|
||||
m_rc_styleoverlayfile(m_resourcemanager, "~/." + realProgramName("fluxbox") + "/overlay", "session.styleOverlay", "Session.StyleOverlay"),
|
||||
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, "~/." + realProgramName("fluxbox") + "/slitlist", "session.slitlistFile", "Session.SlitlistFile"),
|
||||
m_rc_appsfile(m_resourcemanager, "~/." + realProgramName("fluxbox") + "/apps", "session.appsFile", "Session.AppsFile"),
|
||||
m_rc_styleoverlayfile(m_resourcemanager, m_RC_PATH + "/overlay", "session.styleOverlay", "Session.StyleOverlay"),
|
||||
m_rc_menufile(m_resourcemanager, m_RC_PATH + "/menu", "session.menuFile", "Session.MenuFile"),
|
||||
m_rc_keyfile(m_resourcemanager, m_RC_PATH + "/keys", "session.keyFile", "Session.KeyFile"),
|
||||
m_rc_slitlistfile(m_resourcemanager, m_RC_PATH + "/slitlist", "session.slitlistFile", "Session.SlitlistFile"),
|
||||
m_rc_appsfile(m_resourcemanager, m_RC_PATH + "/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"),
|
||||
m_rc_cache_max(m_resourcemanager, 200, "session.cacheMax", "Session.CacheMax"),
|
||||
|
@ -213,16 +217,14 @@ Fluxbox::Fluxbox(int argc, char **argv, const char *dpy_name,
|
|||
m_keyscreen(0),
|
||||
m_last_time(0),
|
||||
m_masked(0),
|
||||
m_rc_file(rcfilename ? rcfilename : ""),
|
||||
m_rc_file(rc_filename),
|
||||
m_argv(argv), m_argc(argc),
|
||||
m_showing_dialog(false),
|
||||
m_starting(true),
|
||||
m_restarting(false),
|
||||
m_shutdown(false),
|
||||
m_server_grabs(0),
|
||||
m_randr_event_type(0),
|
||||
m_RC_PATH(realProgramName("fluxbox")),
|
||||
m_RC_INIT_FILE("init") {
|
||||
m_randr_event_type(0) {
|
||||
|
||||
_FB_USES_NLS;
|
||||
if (s_singleton != 0)
|
||||
|
@ -288,8 +290,6 @@ Fluxbox::Fluxbox(int argc, char **argv, const char *dpy_name,
|
|||
|
||||
grab();
|
||||
|
||||
setupConfigFiles();
|
||||
|
||||
if (! XSupportsLocale())
|
||||
cerr<<_FB_CONSOLETEXT(Fluxbox, WarningLocale,
|
||||
"Warning: X server does not support locale",
|
||||
|
@ -512,76 +512,6 @@ void Fluxbox::ungrab() {
|
|||
m_server_grabs = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
setup the configutation files in
|
||||
home directory
|
||||
*/
|
||||
void Fluxbox::setupConfigFiles() {
|
||||
|
||||
string dirname = getDefaultDataFilename("");
|
||||
|
||||
// is file/dir already there?
|
||||
const bool create_dir = FbTk::FileUtil::isDirectory(dirname.c_str());
|
||||
|
||||
struct CFInfo {
|
||||
bool create_file;
|
||||
const char* default_name;
|
||||
const std::string filename;
|
||||
} cfiles[] = {
|
||||
{ create_dir, DEFAULT_INITFILE, getDefaultDataFilename(m_RC_INIT_FILE) },
|
||||
{ create_dir, DEFAULTKEYSFILE, getDefaultDataFilename("keys") },
|
||||
{ create_dir, DEFAULTMENU, getDefaultDataFilename("menu") },
|
||||
{ create_dir, DEFAULT_APPSFILE, getDefaultDataFilename("apps") },
|
||||
{ create_dir, DEFAULT_OVERLAY, getDefaultDataFilename("overlay") },
|
||||
{ create_dir, DEFAULT_WINDOWMENU, getDefaultDataFilename("windowmenu") }
|
||||
};
|
||||
const size_t nr_of_cfiles = sizeof(cfiles)/sizeof(CFInfo);
|
||||
|
||||
if (create_dir) { // check if anything with those name exists, if not create new
|
||||
for (size_t i = 0; i < nr_of_cfiles; ++i) {
|
||||
cfiles[i].create_file = access(cfiles[i].filename.c_str(), F_OK);
|
||||
}
|
||||
} else{
|
||||
fbdbg<<"Creating dir: " << dirname.c_str() << endl;
|
||||
_FB_USES_NLS;
|
||||
// create directory with perm 700
|
||||
if (mkdir(dirname.c_str(), 0700)) {
|
||||
fprintf(stderr, _FB_CONSOLETEXT(Fluxbox, ErrorCreatingDirectory,
|
||||
"Can't create %s directory",
|
||||
"Can't create a directory, one %s for directory name").c_str(),
|
||||
dirname.c_str());
|
||||
cerr<<endl;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// copy default files if needed
|
||||
for (size_t i = 0; i < nr_of_cfiles; ++i) {
|
||||
if (cfiles[i].create_file) {
|
||||
FbTk::FileUtil::copyFile(cfiles[i].default_name, cfiles[i].filename.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
#define CONFIG_VERSION 13
|
||||
FbTk::Resource<int> config_version(m_resourcemanager, 0,
|
||||
"session.configVersion", "Session.ConfigVersion");
|
||||
if (*config_version < CONFIG_VERSION) {
|
||||
// configs are out of date, so run fluxbox-update_configs
|
||||
|
||||
string commandargs = realProgramName("fluxbox-update_configs");
|
||||
commandargs += " -rc " + cfiles[0].filename;
|
||||
|
||||
#ifdef HAVE_GETPID
|
||||
// add the fluxbox pid so fbuc can have us reload rc if necessary
|
||||
commandargs += " -pid ";
|
||||
commandargs += FbTk::StringUtil::number2String(getpid());
|
||||
#endif // HAVE_GETPID
|
||||
|
||||
FbCommands::ExecuteCmd fbuc(commandargs, 0);
|
||||
fbuc.execute();
|
||||
}
|
||||
}
|
||||
|
||||
void Fluxbox::handleEvent(XEvent * const e) {
|
||||
_FB_USES_NLS;
|
||||
m_last_event = *e;
|
||||
|
@ -1216,7 +1146,7 @@ string Fluxbox::getRcFilename() {
|
|||
|
||||
/// Provides default filename of data file
|
||||
string Fluxbox::getDefaultDataFilename(const char *name) const {
|
||||
return (getenv("HOME") + string("/.") + m_RC_PATH + string("/") + name);
|
||||
return m_RC_PATH + string("/") + name;
|
||||
}
|
||||
|
||||
/// loads resources
|
||||
|
@ -1311,7 +1241,6 @@ void Fluxbox::load_rc(BScreen &screen) {
|
|||
}
|
||||
|
||||
void Fluxbox::reconfigure() {
|
||||
setupConfigFiles();
|
||||
load_rc();
|
||||
m_reconfigure_wait = true;
|
||||
m_reconfig_timer.start();
|
||||
|
|
|
@ -79,8 +79,10 @@ class Fluxbox : public FbTk::App,
|
|||
public FbTk::Observer,
|
||||
private FbTk::SignalTracker {
|
||||
public:
|
||||
Fluxbox(int argc, char **argv, const char * dpy_name= 0,
|
||||
const char *rcfilename = 0, bool xsync = false);
|
||||
Fluxbox(int argc, char **argv,
|
||||
const std::string& dpy_name,
|
||||
const std::string& rc_path, const std::string& rc_filename,
|
||||
bool xsync = false);
|
||||
virtual ~Fluxbox();
|
||||
|
||||
static Fluxbox *instance() { return s_singleton; }
|
||||
|
@ -197,7 +199,6 @@ private:
|
|||
|
||||
void handleEvent(XEvent *xe);
|
||||
|
||||
void setupConfigFiles();
|
||||
void handleUnmapNotify(XUnmapEvent &ue);
|
||||
void handleClientMessage(XClientMessageEvent &ce);
|
||||
|
||||
|
@ -221,6 +222,9 @@ private:
|
|||
|
||||
FbTk::ResourceManager m_resourcemanager, &m_screen_rm;
|
||||
|
||||
std::string m_RC_PATH;
|
||||
const char *m_RC_INIT_FILE;
|
||||
|
||||
//--- Resources
|
||||
|
||||
FbTk::Resource<bool> m_rc_ignoreborder;
|
||||
|
@ -289,8 +293,6 @@ private:
|
|||
int m_randr_event_type; ///< the type number of randr event
|
||||
int m_shape_eventbase; ///< event base for shape events
|
||||
bool m_have_shape; ///< if shape is supported by server
|
||||
std::string m_RC_PATH;
|
||||
const char *m_RC_INIT_FILE;
|
||||
Atom m_kwm1_dockwindow, m_kwm2_dockwindow;
|
||||
|
||||
AttentionNoticeHandler m_attention_handler;
|
||||
|
|
124
src/main.cc
124
src/main.cc
|
@ -20,17 +20,21 @@
|
|||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
// DEALINGS IN THE SOFTWARE.
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif // HAVE_CONFIG_H
|
||||
|
||||
#include "fluxbox.hh"
|
||||
#include "version.h"
|
||||
#include "defaults.hh"
|
||||
|
||||
#include "Debug.hh"
|
||||
#include "FbCommands.hh"
|
||||
|
||||
#include "FbTk/Theme.hh"
|
||||
#include "FbTk/I18n.hh"
|
||||
#include "FbTk/CommandParser.hh"
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif // HAVE_CONFIG_H
|
||||
#include "FbTk/FileUtil.hh"
|
||||
|
||||
//use GNU extensions
|
||||
#ifndef _GNU_SOURCE
|
||||
|
@ -49,7 +53,11 @@
|
|||
#include <string.h>
|
||||
#endif
|
||||
|
||||
#include <iostream>
|
||||
#ifdef HAVE_SYS_STAT_H
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#endif // HAVE_SYS_STAT_H
|
||||
|
||||
#include <fstream>
|
||||
#include <stdexcept>
|
||||
#include <typeinfo>
|
||||
|
@ -209,8 +217,16 @@ static void showInfo(ostream &ostr) {
|
|||
}
|
||||
|
||||
struct Options {
|
||||
Options() : xsync(false) { }
|
||||
Options() :
|
||||
session_display(getenv("DISPLAY")),
|
||||
rc_path(std::string(getenv("HOME")) + "/." + realProgramName("fluxbox")),
|
||||
rc_file(rc_path + "/init"),
|
||||
xsync(false) {
|
||||
|
||||
}
|
||||
|
||||
std::string session_display;
|
||||
std::string rc_path;
|
||||
std::string rc_file;
|
||||
std::string log_filename;
|
||||
bool xsync;
|
||||
|
@ -298,6 +314,92 @@ static void parseOptions(int argc, char** argv, Options& opts) {
|
|||
}
|
||||
|
||||
|
||||
/**
|
||||
setup the configutation files in
|
||||
home directory
|
||||
*/
|
||||
void setupConfigFiles(const std::string& dirname, const std::string& rc) {
|
||||
|
||||
_FB_USES_NLS;
|
||||
|
||||
const bool has_dir = FbTk::FileUtil::isDirectory(dirname.c_str());
|
||||
|
||||
|
||||
struct CFInfo {
|
||||
bool create_file;
|
||||
const char* default_name;
|
||||
const std::string filename;
|
||||
} cfiles[] = {
|
||||
{ !has_dir, DEFAULT_INITFILE, rc },
|
||||
{ !has_dir, DEFAULTKEYSFILE, dirname + "/keys" },
|
||||
{ !has_dir, DEFAULTMENU, dirname + "/menu" },
|
||||
{ !has_dir, DEFAULT_APPSFILE, dirname + "/apps" },
|
||||
{ !has_dir, DEFAULT_OVERLAY, dirname + "/overlay" },
|
||||
{ !has_dir, DEFAULT_WINDOWMENU, dirname + "/windowmenu" }
|
||||
};
|
||||
const size_t nr_of_cfiles = sizeof(cfiles)/sizeof(CFInfo);
|
||||
|
||||
|
||||
if (has_dir) { // check if anything with these names exists, if not create new
|
||||
for (size_t i = 0; i < nr_of_cfiles; ++i) {
|
||||
cfiles[i].create_file = access(cfiles[i].filename.c_str(), F_OK);
|
||||
}
|
||||
} else {
|
||||
|
||||
fbdbg << "Creating dir: " << dirname << endl;
|
||||
if (mkdir(dirname.c_str(), 0700)) {
|
||||
fprintf(stderr, _FB_CONSOLETEXT(Fluxbox, ErrorCreatingDirectory,
|
||||
"Can't create %s directory",
|
||||
"Can't create a directory, one %s for directory name").c_str(),
|
||||
dirname.c_str());
|
||||
cerr << endl;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// copy default files if needed
|
||||
for (size_t i = 0; i < nr_of_cfiles; ++i) {
|
||||
if (cfiles[i].create_file) {
|
||||
FbTk::FileUtil::copyFile(cfiles[i].default_name, cfiles[i].filename.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
// configs might be out of date, so run fluxbox-update_configs
|
||||
// if necassary.
|
||||
void updateConfigFilesIfNeeded(const std::string& rc_file) {
|
||||
|
||||
const int CONFIG_VERSION = 13; // TODO: move this to 'defaults.hh' or 'config.h'
|
||||
|
||||
FbTk::ResourceManager r_mgr(rc_file.c_str(), false);
|
||||
FbTk::Resource<int> c_version(r_mgr, 0, "session.configVersion", "Session.ConfigVersion");
|
||||
|
||||
if (!r_mgr.load(rc_file.c_str())) {
|
||||
_FB_USES_NLS;
|
||||
cerr << _FB_CONSOLETEXT(Fluxbox, CantLoadRCFile, "Failed to load database", "")
|
||||
<< ": "
|
||||
<< rc_file << endl;
|
||||
return;
|
||||
}
|
||||
|
||||
if (*c_version < CONFIG_VERSION) {
|
||||
|
||||
fbdbg << "updating config files from version "
|
||||
<< *c_version
|
||||
<< " to "
|
||||
<< CONFIG_VERSION
|
||||
<< endl;
|
||||
|
||||
string commandargs = realProgramName("fluxbox-update_configs");
|
||||
commandargs += " -rc " + rc_file;
|
||||
|
||||
FbCommands::ExecuteCmd fbuc(commandargs, 0);
|
||||
fbuc.execute();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
|
||||
|
@ -309,7 +411,6 @@ int main(int argc, char **argv) {
|
|||
#ifdef __EMX__
|
||||
_chdir2(getenv("X11ROOT"));
|
||||
#endif // __EMX__
|
||||
auto_ptr<Fluxbox> fluxbox;
|
||||
|
||||
streambuf *outbuf = 0;
|
||||
streambuf *errbuf = 0;
|
||||
|
@ -338,11 +439,16 @@ int main(int argc, char **argv) {
|
|||
|
||||
int exitcode = EXIT_FAILURE;
|
||||
|
||||
setupConfigFiles(opts.rc_path, opts.rc_file);
|
||||
updateConfigFilesIfNeeded(opts.rc_file);
|
||||
|
||||
auto_ptr<Fluxbox> fluxbox;
|
||||
try {
|
||||
|
||||
fluxbox.reset(new Fluxbox(argc, argv,
|
||||
opts.session_display.c_str(),
|
||||
opts.rc_file.c_str(),
|
||||
opts.session_display,
|
||||
opts.rc_path,
|
||||
opts.rc_file,
|
||||
opts.xsync));
|
||||
fluxbox->eventLoop();
|
||||
|
||||
|
|
|
@ -563,7 +563,7 @@ int run_updates(int old_version, FbTk::ResourceManager &rm) {
|
|||
string appsfilename = FbTk::StringUtil::expandFilename(*rc_appsfile);
|
||||
string keyfilename = FbTk::StringUtil::expandFilename(*rc_keyfile);
|
||||
|
||||
size_t i;
|
||||
int i;
|
||||
for (i = 0; i < sizeof(UPDATES) / sizeof(Update); ++i) {
|
||||
if (old_version < UPDATES[i].version) {
|
||||
UPDATES[i].update(rm, keyfilename, appsfilename);
|
||||
|
|
Loading…
Reference in a new issue