Merge branch 'master' of fluxbox@git.fluxbox.org:fluxbox
This commit is contained in:
commit
7f45bae462
17 changed files with 359 additions and 343 deletions
|
@ -1,5 +1,13 @@
|
|||
(Format: Year/Month/Day)
|
||||
Changes for 1.1
|
||||
*08/05/13:
|
||||
* Only reload custom menus when necessary (Mark)
|
||||
FbCommands.cc/hh
|
||||
*08/05/12:
|
||||
* Only reload the keys file if the contents have changed (Mark)
|
||||
Keys.cc/hh fluxbox.cc/hh
|
||||
* Modifying the apps file no longer requires a reconfigure (Mark)
|
||||
Remember.cc/hh
|
||||
*08/05/09:
|
||||
* Made tooltip in toolbar update when the title changes (Henrik)
|
||||
Tooltip.cc/hh, Screen.cc/cc, OSDWindow.hh
|
||||
|
|
|
@ -73,16 +73,11 @@ namespace {
|
|||
|
||||
void showMenu(const BScreen &screen, FbTk::Menu &menu) {
|
||||
|
||||
// special case for root menu
|
||||
if (&menu == &screen.rootMenu()) {
|
||||
Fluxbox* fb = Fluxbox::instance();
|
||||
if(fb->menuTimestampsChanged()) {
|
||||
// we dont show the menu here because fluxbox
|
||||
// will bring up the rootmenu after the timed
|
||||
// reread of the menu
|
||||
fb->rereadMenu(true);
|
||||
return;
|
||||
}
|
||||
// check if menu has changed
|
||||
if (typeid(menu) == typeid(FbMenu)) {
|
||||
FbMenu *fbmenu = static_cast<FbMenu *>(&menu);
|
||||
if (fbmenu->reloadHelper())
|
||||
fbmenu->reloadHelper()->checkReload();
|
||||
}
|
||||
|
||||
Window root_ret; // not used
|
||||
|
@ -335,8 +330,8 @@ void ShowClientMenuCmd::execute() {
|
|||
m_list.push_back(static_cast<FluxboxWindow *>(*it));
|
||||
}
|
||||
|
||||
m_menu = new ClientMenu(*screen, m_list, 0);
|
||||
::showMenu(*screen, **m_menu);
|
||||
m_menu.reset(new ClientMenu(*screen, m_list, 0));
|
||||
::showMenu(*screen, *m_menu.get());
|
||||
}
|
||||
|
||||
REGISTER_COMMAND_WITH_ARGS(custommenu, FbCommands::ShowCustomMenuCmd, void);
|
||||
|
@ -347,11 +342,22 @@ void ShowCustomMenuCmd::execute() {
|
|||
BScreen *screen = Fluxbox::instance()->mouseScreen();
|
||||
if (screen == 0)
|
||||
return;
|
||||
m_menu = MenuCreator::createFromFile(custom_menu_file,
|
||||
screen->screenNumber());
|
||||
if (!m_menu.get())
|
||||
return;
|
||||
::showMenu(*screen, **m_menu);
|
||||
|
||||
if (!m_menu.get() || screen->screenNumber() != m_menu->screenNumber()) {
|
||||
m_menu.reset(screen->createMenu(""));
|
||||
m_menu->setReloadHelper(new FbTk::AutoReloadHelper());
|
||||
m_menu->reloadHelper()->setReloadCmd(FbTk::RefCount<FbTk::Command<void> >(new FbTk::SimpleCommand<ShowCustomMenuCmd>(*this, &ShowCustomMenuCmd::reload)));
|
||||
m_menu->reloadHelper()->setMainFile(custom_menu_file);
|
||||
} else
|
||||
m_menu->reloadHelper()->checkReload();
|
||||
|
||||
::showMenu(*screen, *m_menu.get());
|
||||
}
|
||||
|
||||
void ShowCustomMenuCmd::reload() {
|
||||
m_menu->removeAll();
|
||||
m_menu->setLabel("");
|
||||
MenuCreator::createFromFile(custom_menu_file, *m_menu.get(), m_menu->reloadHelper());
|
||||
}
|
||||
|
||||
REGISTER_COMMAND(rootmenu, FbCommands::ShowRootMenuCmd, void);
|
||||
|
|
|
@ -25,7 +25,8 @@
|
|||
#define FBCOMMANDS_HH
|
||||
|
||||
#include "FbTk/Command.hh"
|
||||
#include "FbTk/RefCount.hh"
|
||||
|
||||
#include <memory>
|
||||
|
||||
#include "ClientMenu.hh"
|
||||
#include "ClientPattern.hh"
|
||||
|
@ -124,16 +125,17 @@ private:
|
|||
const int m_option;
|
||||
const ClientPattern m_pat;
|
||||
std::list<FluxboxWindow *> m_list;
|
||||
FbTk::RefCount<ClientMenu> m_menu;
|
||||
std::auto_ptr<ClientMenu> m_menu;
|
||||
};
|
||||
|
||||
class ShowCustomMenuCmd: public FbTk::Command<void> {
|
||||
public:
|
||||
explicit ShowCustomMenuCmd(const std::string &arguments);
|
||||
void execute();
|
||||
void reload();
|
||||
private:
|
||||
std::string custom_menu_file;
|
||||
FbTk::RefCount<FbTk::Menu> m_menu;
|
||||
std::auto_ptr<FbMenu> m_menu;
|
||||
};
|
||||
|
||||
class ShowRootMenuCmd: public FbTk::Command<void> {
|
||||
|
|
|
@ -22,8 +22,11 @@
|
|||
#ifndef FBMENU_HH
|
||||
#define FBMENU_HH
|
||||
|
||||
#include <memory>
|
||||
|
||||
#include "FbTk/Menu.hh"
|
||||
#include "FbTk/XLayerItem.hh"
|
||||
#include "FbTk/AutoReloadHelper.hh"
|
||||
|
||||
class FluxboxWindow;
|
||||
|
||||
|
@ -44,11 +47,15 @@ public:
|
|||
void buttonReleaseEvent(XButtonEvent &be);
|
||||
void keyPressEvent(XKeyEvent &ke);
|
||||
|
||||
void setReloadHelper(FbTk::AutoReloadHelper *helper) { m_reloader.reset(helper); }
|
||||
FbTk::AutoReloadHelper *reloadHelper() { return m_reloader.get(); }
|
||||
|
||||
static void setWindow(FluxboxWindow *win) { s_window = win; }
|
||||
static FluxboxWindow *window() { return s_window; }
|
||||
|
||||
private:
|
||||
FbTk::XLayerItem m_layeritem;
|
||||
std::auto_ptr<FbTk::AutoReloadHelper> m_reloader;
|
||||
static FluxboxWindow *s_window;
|
||||
};
|
||||
|
||||
|
|
66
src/FbTk/AutoReloadHelper.cc
Normal file
66
src/FbTk/AutoReloadHelper.cc
Normal file
|
@ -0,0 +1,66 @@
|
|||
// AutoReloadHelper.cc
|
||||
// Copyright (c) 2008 Fluxbox Team (fluxgen at fluxbox dot org)
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a
|
||||
// copy of this software and associated documentation files (the "Software"),
|
||||
// to deal in the Software without restriction, including without limitation
|
||||
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
// and/or sell copies of the Software, and to permit persons to whom the
|
||||
// Software is furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// 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.
|
||||
|
||||
#include "AutoReloadHelper.hh"
|
||||
|
||||
#include "FileUtil.hh"
|
||||
#include "StringUtil.hh"
|
||||
|
||||
namespace FbTk {
|
||||
|
||||
void AutoReloadHelper::checkReload() {
|
||||
if (!m_reload_cmd.get())
|
||||
return;
|
||||
TimestampMap::const_iterator it = m_timestamps.begin();
|
||||
TimestampMap::const_iterator it_end = m_timestamps.end();
|
||||
for (; it != it_end; ++it) {
|
||||
if (FileUtil::getLastStatusChangeTimestamp(it->first.c_str()) !=
|
||||
it->second) {
|
||||
reload();
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void AutoReloadHelper::setMainFile(std::string file) {
|
||||
file = StringUtil::expandFilename(file);
|
||||
if (file == m_main_file)
|
||||
return;
|
||||
m_main_file = file;
|
||||
reload();
|
||||
}
|
||||
|
||||
void AutoReloadHelper::addFile(std::string file) {
|
||||
if (file.empty())
|
||||
return;
|
||||
file = StringUtil::expandFilename(file);
|
||||
m_timestamps[file] = FileUtil::getLastStatusChangeTimestamp(file.c_str());
|
||||
}
|
||||
|
||||
void AutoReloadHelper::reload() {
|
||||
if (!m_reload_cmd.get())
|
||||
return;
|
||||
m_timestamps.clear();
|
||||
addFile(m_main_file);
|
||||
m_reload_cmd->execute();
|
||||
}
|
||||
|
||||
} // end namespace FbTk
|
54
src/FbTk/AutoReloadHelper.hh
Normal file
54
src/FbTk/AutoReloadHelper.hh
Normal file
|
@ -0,0 +1,54 @@
|
|||
// AutoReloadHelper.hh
|
||||
// Copyright (c) 2008 Fluxbox Team (fluxgen at fluxbox dot org)
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a
|
||||
// copy of this software and associated documentation files (the "Software"),
|
||||
// to deal in the Software without restriction, including without limitation
|
||||
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
// and/or sell copies of the Software, and to permit persons to whom the
|
||||
// Software is furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// 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.
|
||||
|
||||
#ifndef AUTORELOADHELPER_HH
|
||||
#define AUTORELOADHELPER_HH
|
||||
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include <sys/types.h>
|
||||
|
||||
#include "Command.hh"
|
||||
#include "RefCount.hh"
|
||||
|
||||
namespace FbTk {
|
||||
|
||||
class AutoReloadHelper {
|
||||
public:
|
||||
|
||||
void setMainFile(std::string filename);
|
||||
void addFile(std::string filename);
|
||||
void setReloadCmd(RefCount<Command<void> > cmd) { m_reload_cmd = cmd; }
|
||||
|
||||
void checkReload();
|
||||
void reload();
|
||||
|
||||
private:
|
||||
RefCount<Command<void> > m_reload_cmd;
|
||||
std::string m_main_file;
|
||||
|
||||
typedef std::map<std::string, time_t> TimestampMap;
|
||||
TimestampMap m_timestamps;
|
||||
};
|
||||
|
||||
} // end namespace FbTk
|
||||
|
||||
#endif // AUTORELOADHELPER_HH
|
|
@ -45,6 +45,7 @@ libFbTk_a_SOURCES = App.hh App.cc Color.cc Color.hh Command.hh \
|
|||
RegExp.hh RegExp.cc \
|
||||
FbString.hh FbString.cc \
|
||||
Subject.hh Subject.cc Observer.hh Observer.cc SimpleObserver.hh \
|
||||
AutoReloadHelper.hh AutoReloadHelper.cc \
|
||||
Transparent.hh Transparent.cc \
|
||||
FbPixmap.hh FbPixmap.cc \
|
||||
FbDrawable.hh FbDrawable.cc \
|
||||
|
|
37
src/Keys.cc
37
src/Keys.cc
|
@ -170,7 +170,9 @@ Keys::t_key::~t_key() {
|
|||
|
||||
|
||||
|
||||
Keys::Keys() : next_key(0) { }
|
||||
Keys::Keys(): next_key(0) {
|
||||
m_reloader.setReloadCmd(FbTk::RefCount<FbTk::Command<void> >(new FbTk::SimpleCommand<Keys>(*this, &Keys::reload)));
|
||||
}
|
||||
|
||||
Keys::~Keys() {
|
||||
ungrabKeys();
|
||||
|
@ -255,27 +257,25 @@ void Keys::grabWindow(Window win) {
|
|||
/**
|
||||
Load and grab keys
|
||||
TODO: error checking
|
||||
@return true on success else false
|
||||
*/
|
||||
bool Keys::load(const char *filename) {
|
||||
void Keys::reload() {
|
||||
// an intentionally empty file will still have one root mapping
|
||||
bool firstload = m_map.empty();
|
||||
|
||||
if (!filename) {
|
||||
if (m_filename.empty()) {
|
||||
if (firstload)
|
||||
loadDefaults();
|
||||
return false;
|
||||
return;
|
||||
}
|
||||
|
||||
FbTk::App::instance()->sync(false);
|
||||
|
||||
// open the file
|
||||
ifstream infile(filename);
|
||||
ifstream infile(m_filename.c_str());
|
||||
if (!infile) {
|
||||
if (firstload)
|
||||
loadDefaults();
|
||||
|
||||
return false; // failed to open file
|
||||
return; // failed to open file
|
||||
}
|
||||
|
||||
// free memory of previous grabs
|
||||
|
@ -301,9 +301,7 @@ bool Keys::load(const char *filename) {
|
|||
}
|
||||
} // end while eof
|
||||
|
||||
m_filename = filename;
|
||||
keyMode("default");
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -321,19 +319,6 @@ void Keys::loadDefaults() {
|
|||
keyMode("default");
|
||||
}
|
||||
|
||||
bool Keys::save(const char *filename) const {
|
||||
//!!
|
||||
//!! TODO: fix keybinding saving
|
||||
//!! (we probably need to save key actions
|
||||
//!! as strings instead of creating new Commands)
|
||||
|
||||
// open file for writing
|
||||
// ofstream outfile(filename);
|
||||
// if (!outfile)
|
||||
return false;
|
||||
// return true;
|
||||
}
|
||||
|
||||
bool Keys::addBinding(const string &linebuffer) {
|
||||
|
||||
vector<string> val;
|
||||
|
@ -583,8 +568,10 @@ void Keys::unregisterWindow(Window win) {
|
|||
deletes the tree and load configuration
|
||||
returns true on success else false
|
||||
*/
|
||||
bool Keys::reconfigure(const char *filename) {
|
||||
return load(filename);
|
||||
void Keys::reconfigure() {
|
||||
m_filename = FbTk::StringUtil::expandFilename(Fluxbox::instance()->getKeysFilename());
|
||||
m_reloader.setMainFile(m_filename);
|
||||
m_reloader.checkReload();
|
||||
}
|
||||
|
||||
void Keys::keyMode(const string& keyMode) {
|
||||
|
|
23
src/Keys.hh
23
src/Keys.hh
|
@ -23,6 +23,7 @@
|
|||
#define KEYS_HH
|
||||
|
||||
#include "FbTk/NotCopyable.hh"
|
||||
#include "FbTk/AutoReloadHelper.hh"
|
||||
|
||||
#include <X11/Xlib.h>
|
||||
#include <string>
|
||||
|
@ -57,17 +58,6 @@ public:
|
|||
/// destructor
|
||||
~Keys();
|
||||
|
||||
/**
|
||||
Load configuration from file
|
||||
@return true on success, else false
|
||||
*/
|
||||
bool load(const char *filename = 0);
|
||||
/**
|
||||
Save keybindings to a file
|
||||
Note: the file will be overwritten
|
||||
@return true on success, else false
|
||||
*/
|
||||
bool save(const char *filename = 0) const;
|
||||
/// bind a key action from a string
|
||||
/// @return false on failure
|
||||
bool addBinding(const std::string &binding);
|
||||
|
@ -83,12 +73,12 @@ public:
|
|||
/// unregister window
|
||||
void unregisterWindow(Window win);
|
||||
|
||||
const std::string& filename() const { return m_filename; }
|
||||
/**
|
||||
Reload configuration from filename
|
||||
@return true on success, else false
|
||||
*/
|
||||
bool reconfigure(const char *filename);
|
||||
const std::string& filename() const { return m_filename; }
|
||||
void reconfigure();
|
||||
void keyMode(const std::string& keyMode);
|
||||
private:
|
||||
class t_key; // helper class to build a 'keytree'
|
||||
|
@ -104,13 +94,18 @@ private:
|
|||
void ungrabButtons();
|
||||
void grabWindow(Window win);
|
||||
|
||||
// Load default keybindings for when there are errors loading the initial one
|
||||
/**
|
||||
Load configuration from file
|
||||
*/
|
||||
void reload();
|
||||
// Load default keybindings for when there are errors loading the keys file
|
||||
void loadDefaults();
|
||||
void setKeyMode(t_key *keyMode);
|
||||
|
||||
|
||||
// member variables
|
||||
std::string m_filename;
|
||||
FbTk::AutoReloadHelper m_reloader;
|
||||
t_key *m_keylist;
|
||||
keyspace_t m_map;
|
||||
|
||||
|
|
|
@ -59,6 +59,7 @@ using std::string;
|
|||
using std::vector;
|
||||
using std::list;
|
||||
using std::less;
|
||||
using FbTk::AutoReloadHelper;
|
||||
|
||||
list<string> MenuCreator::encoding_stack;
|
||||
list<size_t> MenuCreator::stacksize_stack;
|
||||
|
@ -68,13 +69,16 @@ FbTk::StringConvertor MenuCreator::m_stringconvertor(FbTk::StringConvertor::ToFb
|
|||
namespace {
|
||||
|
||||
void createStyleMenu(FbTk::Menu &parent, const string &label,
|
||||
const string &directory) {
|
||||
AutoReloadHelper *reloader, const string &directory) {
|
||||
// perform shell style ~ home directory expansion
|
||||
string stylesdir(FbTk::StringUtil::expandFilename(directory));
|
||||
|
||||
if (!FbTk::FileUtil::isDirectory(stylesdir.c_str()))
|
||||
return;
|
||||
|
||||
if (reloader)
|
||||
reloader->addFile(stylesdir);
|
||||
|
||||
FbTk::Directory dir(stylesdir.c_str());
|
||||
|
||||
// create a vector of all the filenames in the directory
|
||||
|
@ -99,18 +103,21 @@ void createStyleMenu(FbTk::Menu &parent, const string &label,
|
|||
}
|
||||
// update menu graphics
|
||||
parent.updateMenu();
|
||||
Fluxbox::instance()->saveMenuFilename(stylesdir.c_str());
|
||||
|
||||
}
|
||||
|
||||
void createRootCmdMenu(FbTk::Menu &parent, const string &label,
|
||||
const string &directory, const string &cmd) {
|
||||
const string &directory, AutoReloadHelper *reloader,
|
||||
const string &cmd) {
|
||||
// perform shell style ~ home directory expansion
|
||||
string rootcmddir(FbTk::StringUtil::expandFilename(directory));
|
||||
|
||||
if (!FbTk::FileUtil::isDirectory(rootcmddir.c_str()))
|
||||
return;
|
||||
|
||||
if (reloader)
|
||||
reloader->addFile(rootcmddir);
|
||||
|
||||
FbTk::Directory dir(rootcmddir.c_str());
|
||||
|
||||
// create a vector of all the filenames in the directory
|
||||
|
@ -134,7 +141,6 @@ void createRootCmdMenu(FbTk::Menu &parent, const string &label,
|
|||
}
|
||||
// update menu graphics
|
||||
parent.updateMenu();
|
||||
Fluxbox::instance()->saveMenuFilename(rootcmddir.c_str());
|
||||
|
||||
}
|
||||
|
||||
|
@ -172,20 +178,26 @@ public:
|
|||
|
||||
};
|
||||
|
||||
void translateMenuItem(FbTk::Parser &parse, ParseItem &item, FbTk::StringConvertor &labelconvertor);
|
||||
void translateMenuItem(FbTk::Parser &parse, ParseItem &item,
|
||||
FbTk::StringConvertor &labelconvertor,
|
||||
AutoReloadHelper *reloader);
|
||||
|
||||
|
||||
void parseMenu(FbTk::Parser &pars, FbTk::Menu &menu, FbTk::StringConvertor &label_convertor) {
|
||||
void parseMenu(FbTk::Parser &pars, FbTk::Menu &menu,
|
||||
FbTk::StringConvertor &label_convertor,
|
||||
AutoReloadHelper *reloader) {
|
||||
ParseItem pitem(&menu);
|
||||
while (!pars.eof()) {
|
||||
pitem.load(pars, label_convertor);
|
||||
if (pitem.key() == "end")
|
||||
return;
|
||||
translateMenuItem(pars, pitem, label_convertor);
|
||||
translateMenuItem(pars, pitem, label_convertor, reloader);
|
||||
}
|
||||
}
|
||||
|
||||
void translateMenuItem(FbTk::Parser &parse, ParseItem &pitem, FbTk::StringConvertor &labelconvertor) {
|
||||
void translateMenuItem(FbTk::Parser &parse, ParseItem &pitem,
|
||||
FbTk::StringConvertor &labelconvertor,
|
||||
AutoReloadHelper *reloader) {
|
||||
if (pitem.menu() == 0)
|
||||
throw string("translateMenuItem: We must have a menu in ParseItem!");
|
||||
|
||||
|
@ -255,13 +267,13 @@ void translateMenuItem(FbTk::Parser &parse, ParseItem &pitem, FbTk::StringConver
|
|||
if (FbTk::FileUtil::isRegularFile(thisfile.c_str()) &&
|
||||
(filelist[file_index][0] != '.') &&
|
||||
(thisfile[thisfile.length() - 1] != '~')) {
|
||||
MenuCreator::createFromFile(thisfile, menu);
|
||||
MenuCreator::createFromFile(thisfile, menu, reloader, false);
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
// inject this file into the current menu
|
||||
MenuCreator::createFromFile(newfile, menu);
|
||||
MenuCreator::createFromFile(newfile, menu, reloader, false);
|
||||
}
|
||||
|
||||
safe_counter--;
|
||||
|
@ -278,26 +290,22 @@ void translateMenuItem(FbTk::Parser &parse, ParseItem &pitem, FbTk::StringConver
|
|||
else
|
||||
submenu->setLabel(str_label);
|
||||
|
||||
parseMenu(parse, *submenu, labelconvertor);
|
||||
parseMenu(parse, *submenu, labelconvertor, reloader);
|
||||
submenu->updateMenu();
|
||||
menu.insert(str_label, submenu);
|
||||
// save to screen list so we can delete it later
|
||||
BScreen *screen = Fluxbox::instance()->findScreen(screen_number);
|
||||
if (screen != 0)
|
||||
screen->saveMenu(*submenu);
|
||||
|
||||
} // end of submenu
|
||||
else if (str_key == "stylesdir" || str_key == "stylesmenu") {
|
||||
createStyleMenu(menu, str_label,
|
||||
createStyleMenu(menu, str_label, reloader,
|
||||
str_key == "stylesmenu" ? str_cmd : str_label);
|
||||
} // end of stylesdir
|
||||
else if (str_key == "themesdir" || str_key == "themesmenu") {
|
||||
createStyleMenu(menu, str_label,
|
||||
createStyleMenu(menu, str_label, reloader,
|
||||
str_key == "themesmenu" ? str_cmd : str_label);
|
||||
} // end of themesdir
|
||||
else if (str_key == "wallpapers" || str_key == "wallpapermenu" ||
|
||||
str_key == "rootcommands") {
|
||||
createRootCmdMenu(menu, str_label, str_label,
|
||||
createRootCmdMenu(menu, str_label, str_label, reloader,
|
||||
str_cmd == "" ? realProgramName("fbsetbg") : str_cmd);
|
||||
} // end of wallpapers
|
||||
else if (str_key == "workspaces") {
|
||||
|
@ -339,7 +347,9 @@ void translateMenuItem(FbTk::Parser &parse, ParseItem &pitem, FbTk::StringConver
|
|||
}
|
||||
|
||||
|
||||
void parseWindowMenu(FbTk::Parser &parse, FbTk::Menu &menu, FbTk::StringConvertor &labelconvertor) {
|
||||
void parseWindowMenu(FbTk::Parser &parse, FbTk::Menu &menu,
|
||||
FbTk::StringConvertor &labelconvertor,
|
||||
AutoReloadHelper *reloader) {
|
||||
|
||||
ParseItem pitem(&menu);
|
||||
while (!parse.eof()) {
|
||||
|
@ -347,16 +357,16 @@ void parseWindowMenu(FbTk::Parser &parse, FbTk::Menu &menu, FbTk::StringConverto
|
|||
if (MenuCreator::createWindowMenuItem(pitem.key(), pitem.label(), menu))
|
||||
continue;
|
||||
|
||||
if (pitem.key() == "end") {
|
||||
if (pitem.key() == "end")
|
||||
return;
|
||||
} else if (pitem.key() == "submenu") {
|
||||
if (pitem.key() == "submenu") {
|
||||
FbTk::Menu *submenu = MenuCreator::createMenu(pitem.label(), menu.screenNumber());
|
||||
parseWindowMenu(parse, *submenu, labelconvertor);
|
||||
parseWindowMenu(parse, *submenu, labelconvertor, reloader);
|
||||
submenu->updateMenu();
|
||||
menu.insert(pitem.label(), submenu);
|
||||
|
||||
} else { // try non window menu specific stuff
|
||||
translateMenuItem(parse, pitem, labelconvertor);
|
||||
translateMenuItem(parse, pitem, labelconvertor, reloader);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -380,12 +390,12 @@ bool getStart(FbMenuParser &parser, string &label, FbTk::StringConvertor &labelc
|
|||
|
||||
}; // end of anonymous namespace
|
||||
|
||||
FbTk::Menu *MenuCreator::createMenu(const string &label, int screen_number) {
|
||||
FbMenu *MenuCreator::createMenu(const string &label, int screen_number) {
|
||||
BScreen *screen = Fluxbox::instance()->findScreen(screen_number);
|
||||
if (screen == 0)
|
||||
return 0;
|
||||
|
||||
FbTk::Menu *menu = new FbMenu(screen->menuTheme(),
|
||||
FbMenu *menu = new FbMenu(screen->menuTheme(),
|
||||
screen->imageControl(),
|
||||
*screen->layerManager().getLayer(Layer::MENU));
|
||||
if (!label.empty())
|
||||
|
@ -394,33 +404,9 @@ FbTk::Menu *MenuCreator::createMenu(const string &label, int screen_number) {
|
|||
return menu;
|
||||
}
|
||||
|
||||
FbTk::Menu *MenuCreator::createFromFile(const string &filename, int screen_number) {
|
||||
string real_filename = FbTk::StringUtil::expandFilename(filename);
|
||||
Fluxbox::instance()->saveMenuFilename(real_filename.c_str());
|
||||
|
||||
FbMenuParser parser(real_filename);
|
||||
if (!parser.isLoaded())
|
||||
return 0;
|
||||
|
||||
startFile();
|
||||
string label;
|
||||
if (!getStart(parser, label, m_stringconvertor)) {
|
||||
endFile();
|
||||
return 0;
|
||||
}
|
||||
|
||||
FbTk::Menu *menu = createMenu(label, screen_number);
|
||||
if (menu != 0)
|
||||
parseMenu(parser, *menu, m_stringconvertor);
|
||||
|
||||
endFile();
|
||||
|
||||
return menu;
|
||||
}
|
||||
|
||||
|
||||
bool MenuCreator::createFromFile(const string &filename,
|
||||
FbTk::Menu &inject_into) {
|
||||
FbTk::Menu &inject_into,
|
||||
AutoReloadHelper *reloader, bool begin) {
|
||||
string real_filename = FbTk::StringUtil::expandFilename(filename);
|
||||
|
||||
FbMenuParser parser(real_filename);
|
||||
|
@ -428,75 +414,59 @@ bool MenuCreator::createFromFile(const string &filename,
|
|||
return false;
|
||||
|
||||
startFile();
|
||||
if (begin) {
|
||||
string label;
|
||||
if (!getStart(parser, label, m_stringconvertor)) {
|
||||
endFile();
|
||||
return false;
|
||||
}
|
||||
inject_into.setLabel(label);
|
||||
}
|
||||
|
||||
// save menu filename, so we can check if it changes
|
||||
Fluxbox::instance()->saveMenuFilename(real_filename.c_str());
|
||||
if (reloader)
|
||||
reloader->addFile(real_filename);
|
||||
|
||||
parseMenu(parser, inject_into, m_stringconvertor);
|
||||
parseMenu(parser, inject_into, m_stringconvertor, reloader);
|
||||
endFile();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool MenuCreator::createWindowMenuFromFile(const string &filename,
|
||||
FbTk::Menu &inject_into) {
|
||||
void MenuCreator::createWindowMenuFromFile(const string &filename,
|
||||
FbTk::Menu &inject_into,
|
||||
AutoReloadHelper *reloader) {
|
||||
string real_filename = FbTk::StringUtil::expandFilename(filename);
|
||||
FbMenuParser parser(real_filename);
|
||||
if (!parser.isLoaded())
|
||||
return false;
|
||||
return;
|
||||
|
||||
string label;
|
||||
|
||||
startFile();
|
||||
if (!getStart(parser, label, m_stringconvertor)) {
|
||||
endFile();
|
||||
return false;
|
||||
return;
|
||||
}
|
||||
|
||||
parseWindowMenu(parser, inject_into, m_stringconvertor);
|
||||
if (reloader)
|
||||
reloader->addFile(real_filename);
|
||||
|
||||
parseWindowMenu(parser, inject_into, m_stringconvertor, reloader);
|
||||
endFile();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
FbTk::Menu *MenuCreator::createMenuType(const string &type, int screen_num) {
|
||||
FbMenu *MenuCreator::createMenuType(const string &type, int screen_num) {
|
||||
BScreen *screen = Fluxbox::instance()->findScreen(screen_num);
|
||||
if (screen == 0)
|
||||
return 0;
|
||||
if (type == "iconmenu") {
|
||||
if (type == "iconmenu")
|
||||
return new ClientMenu(*screen, screen->iconList(),
|
||||
&screen->iconListSig());
|
||||
} else if (type == "workspacemenu") {
|
||||
else if (type == "workspacemenu")
|
||||
return new WorkspaceMenu(*screen);
|
||||
} else if (type == "windowmenu") {
|
||||
FbTk::Menu *menu = screen->createMenu("");
|
||||
|
||||
menu->disableTitle(); // not titlebar
|
||||
if (screen->windowMenuFilename().empty() ||
|
||||
! createWindowMenuFromFile(screen->windowMenuFilename(), *menu)) {
|
||||
const char *default_menu[] = {
|
||||
"shade",
|
||||
"stick",
|
||||
"maximize",
|
||||
"iconify",
|
||||
"raise",
|
||||
"lower",
|
||||
"sendto",
|
||||
"layer",
|
||||
"alpha",
|
||||
"extramenus",
|
||||
"separator",
|
||||
"close",
|
||||
0
|
||||
};
|
||||
for (unsigned int i=0; default_menu[i]; ++i)
|
||||
createWindowMenuItem(default_menu[i], "", *menu);
|
||||
}
|
||||
menu->reconfigure(); // update graphics
|
||||
return menu;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -28,18 +28,24 @@
|
|||
#include <list>
|
||||
|
||||
namespace FbTk {
|
||||
class AutoReloadHelper;
|
||||
class Menu;
|
||||
}
|
||||
|
||||
class FbMenu;
|
||||
class FluxboxWindow;
|
||||
|
||||
class MenuCreator {
|
||||
public:
|
||||
static FbTk::Menu *createMenu(const std::string &label, int screen_num);
|
||||
static FbTk::Menu *createFromFile(const std::string &filename, int screen_num);
|
||||
static FbTk::Menu *createMenuType(const std::string &label, int screen_num);
|
||||
static bool createFromFile(const std::string &filename, FbTk::Menu &inject_into);
|
||||
static bool createWindowMenuFromFile(const std::string &filename, FbTk::Menu &inject_into);
|
||||
static FbMenu *createMenu(const std::string &label, int screen_num);
|
||||
static FbMenu *createMenuType(const std::string &label, int screen_num);
|
||||
static bool createFromFile(const std::string &filename,
|
||||
FbTk::Menu &inject_into,
|
||||
FbTk::AutoReloadHelper *reloader = NULL,
|
||||
bool begin = true);
|
||||
static void createWindowMenuFromFile(const std::string &filename,
|
||||
FbTk::Menu &inject_into,
|
||||
FbTk::AutoReloadHelper *reloader);
|
||||
static bool createWindowMenuItem(const std::string &type, const std::string &label,
|
||||
FbTk::Menu &inject_into);
|
||||
|
||||
|
|
|
@ -120,7 +120,7 @@ public:
|
|||
|
||||
void click(int button, int time, unsigned int mods) {
|
||||
// reconfigure only does stuff if the apps file has changed
|
||||
Remember::instance().reconfigure();
|
||||
Remember::instance().checkReload();
|
||||
if (WindowCmd<void>::window() != 0) {
|
||||
if (isSelected()) {
|
||||
Remember::instance().forgetAttrib(WindowCmd<void>::window()->winClient(), m_attrib);
|
||||
|
@ -281,14 +281,14 @@ void Application::reset() {
|
|||
Remember *Remember::s_instance = 0;
|
||||
|
||||
Remember::Remember():
|
||||
m_pats(new Patterns()),
|
||||
m_last_timestamp(0)
|
||||
{
|
||||
m_pats(new Patterns()) {
|
||||
if (s_instance != 0)
|
||||
throw string("Can not create more than one instance of Remember");
|
||||
|
||||
s_instance = this;
|
||||
enableUpdate();
|
||||
|
||||
m_reloader.setReloadCmd(FbTk::RefCount<FbTk::Command<void> >(new FbTk::SimpleCommand<Remember>(*this, &Remember::reload)));
|
||||
reconfigure();
|
||||
}
|
||||
|
||||
|
@ -579,11 +579,15 @@ Application *Remember::findMatchingPatterns(ClientPattern *pat, Patterns *patlis
|
|||
|
||||
|
||||
void Remember::reconfigure() {
|
||||
string apps_string = FbTk::StringUtil::expandFilename(Fluxbox::instance()->getAppsFilename());
|
||||
m_reloader.setMainFile(Fluxbox::instance()->getAppsFilename());
|
||||
}
|
||||
|
||||
time_t timestamp = FbTk::FileUtil::getLastStatusChangeTimestamp(apps_string.c_str());
|
||||
if (m_last_timestamp > 0 && m_last_timestamp == timestamp)
|
||||
return;
|
||||
void Remember::checkReload() {
|
||||
m_reloader.checkReload();
|
||||
}
|
||||
|
||||
void Remember::reload() {
|
||||
string apps_string = FbTk::StringUtil::expandFilename(Fluxbox::instance()->getAppsFilename());
|
||||
|
||||
#ifdef DEBUG
|
||||
cerr<<__FILE__<<"("<<__FUNCTION__<<"): Loading apps file ["<<apps_string<<"]"<<endl;
|
||||
|
@ -598,7 +602,6 @@ void Remember::reconfigure() {
|
|||
m_startups.clear();
|
||||
|
||||
if (!apps_file.fail()) {
|
||||
m_last_timestamp = timestamp;
|
||||
if (!apps_file.eof()) {
|
||||
string line;
|
||||
int row = 0;
|
||||
|
@ -687,7 +690,7 @@ void Remember::reconfigure() {
|
|||
#endif
|
||||
}
|
||||
} else {
|
||||
cerr << "apps file failure" << endl;
|
||||
cerr << "failed to open apps file" << endl;
|
||||
}
|
||||
|
||||
// Clean up old state
|
||||
|
@ -895,11 +898,8 @@ void Remember::save() {
|
|||
apps_file << "[end]" << endl;
|
||||
}
|
||||
apps_file.close();
|
||||
|
||||
time_t timestamp = FbTk::FileUtil::getLastStatusChangeTimestamp(apps_string.c_str());
|
||||
if (timestamp > 0)
|
||||
m_last_timestamp = timestamp;
|
||||
|
||||
// update timestamp to avoid unnecessary reload
|
||||
m_reloader.addFile(Fluxbox::instance()->getAppsFilename());
|
||||
}
|
||||
|
||||
bool Remember::isRemembered(WinClient &winclient, Attribute attrib) {
|
||||
|
@ -1216,6 +1216,9 @@ void Remember::setupClient(WinClient &winclient) {
|
|||
if (winclient.screen().isRestart())
|
||||
return;
|
||||
|
||||
// check if apps file has changed
|
||||
checkReload();
|
||||
|
||||
Application *app = find(winclient);
|
||||
if (app == 0)
|
||||
return; // nothing to do
|
||||
|
@ -1249,7 +1252,7 @@ FluxboxWindow *Remember::findGroup(Application *app, BScreen &screen) {
|
|||
}
|
||||
|
||||
void Remember::updateClientClose(WinClient &winclient) {
|
||||
reconfigure(); // reload if it's changed
|
||||
checkReload(); // reload if it's changed
|
||||
Application *app = find(winclient);
|
||||
|
||||
if (app && (app->save_on_close_remember && app->save_on_close)) {
|
||||
|
|
|
@ -29,6 +29,7 @@
|
|||
#include "AtomHandler.hh"
|
||||
#include "ClientPattern.hh"
|
||||
|
||||
#include "FbTk/AutoReloadHelper.hh"
|
||||
#include "FbTk/RefCount.hh"
|
||||
|
||||
#include <fstream>
|
||||
|
@ -223,7 +224,9 @@ public:
|
|||
Application* add(WinClient &winclient);
|
||||
FluxboxWindow* findGroup(Application *, BScreen &screen);
|
||||
|
||||
void reconfigure(); // was load
|
||||
void reconfigure();
|
||||
void checkReload();
|
||||
void reload();
|
||||
void save();
|
||||
|
||||
bool isRemembered(WinClient &win, Attribute attrib);
|
||||
|
@ -277,7 +280,7 @@ private:
|
|||
Startups m_startups;
|
||||
static Remember *s_instance;
|
||||
|
||||
time_t m_last_timestamp;
|
||||
FbTk::AutoReloadHelper m_reloader;
|
||||
};
|
||||
|
||||
#endif // REMEMBER_HH
|
||||
|
|
111
src/Screen.cc
111
src/Screen.cc
|
@ -283,7 +283,7 @@ BScreen::ScreenResource::ScreenResource(FbTk::ResourceManager &rm,
|
|||
follow_model(rm, IGNORE_OTHER_WORKSPACES, scrname+".followModel", altscrname+".followModel"),
|
||||
user_follow_model(rm, FOLLOW_ACTIVE_WINDOW, scrname+".userFollowModel", altscrname+".UserFollowModel"),
|
||||
workspaces(rm, 1, scrname+".workspaces", altscrname+".Workspaces"),
|
||||
edge_snap_threshold(rm, 0, scrname+".edgeSnapThreshold", altscrname+".EdgeSnapThreshold"),
|
||||
edge_snap_threshold(rm, 10, scrname+".edgeSnapThreshold", altscrname+".EdgeSnapThreshold"),
|
||||
focused_alpha(rm, 255, scrname+".window.focus.alpha", altscrname+".Window.Focus.Alpha"),
|
||||
unfocused_alpha(rm, 255, scrname+".window.unfocus.alpha", altscrname+".Window.Unfocus.Alpha"),
|
||||
menu_alpha(rm, 255, scrname+".menu.alpha", altscrname+".Menu.Alpha"),
|
||||
|
@ -502,6 +502,15 @@ BScreen::BScreen(FbTk::ResourceManager &rm,
|
|||
// own resources we must do this.
|
||||
fluxbox->load_rc(*this);
|
||||
|
||||
m_windowmenu.reset(createMenu(""));
|
||||
m_windowmenu->setInternalMenu();
|
||||
m_windowmenu->setReloadHelper(new FbTk::AutoReloadHelper());
|
||||
m_windowmenu->reloadHelper()->setReloadCmd(FbTk::RefCount<FbTk::Command<void> >(new FbTk::SimpleCommand<BScreen>(*this, &BScreen::rereadWindowMenu)));
|
||||
|
||||
m_rootmenu.reset(createMenu(""));
|
||||
m_rootmenu->setReloadHelper(new FbTk::AutoReloadHelper());
|
||||
m_rootmenu->reloadHelper()->setReloadCmd(FbTk::RefCount<FbTk::Command<void> >(new FbTk::SimpleCommand<BScreen>(*this, &BScreen::rereadMenu)));
|
||||
|
||||
m_configmenu.reset(createMenu(_FB_XTEXT(Menu, Configuration,
|
||||
"Configuration", "Title of configuration menu")));
|
||||
setupConfigmenu(*m_configmenu.get());
|
||||
|
@ -889,8 +898,8 @@ void BScreen::cycleFocus(int options, const ClientPattern *pat, bool reverse) {
|
|||
|
||||
}
|
||||
|
||||
FbTk::Menu *BScreen::createMenu(const string &label) {
|
||||
FbTk::Menu *menu = new FbMenu(menuTheme(),
|
||||
FbMenu *BScreen::createMenu(const string &label) {
|
||||
FbMenu *menu = new FbMenu(menuTheme(),
|
||||
imageControl(),
|
||||
*layerManager().getLayer(Layer::MENU));
|
||||
if (!label.empty())
|
||||
|
@ -898,8 +907,9 @@ FbTk::Menu *BScreen::createMenu(const string &label) {
|
|||
|
||||
return menu;
|
||||
}
|
||||
FbTk::Menu *BScreen::createToggleMenu(const string &label) {
|
||||
FbTk::Menu *menu = new ToggleMenu(menuTheme(),
|
||||
|
||||
FbMenu *BScreen::createToggleMenu(const string &label) {
|
||||
FbMenu *menu = new ToggleMenu(menuTheme(),
|
||||
imageControl(),
|
||||
*layerManager().getLayer(Layer::MENU));
|
||||
if (!label.empty())
|
||||
|
@ -912,9 +922,7 @@ void BScreen::addExtraWindowMenu(const FbTk::FbString &label, FbTk::Menu *menu)
|
|||
menu->setInternalMenu();
|
||||
menu->disableTitle();
|
||||
m_extramenus.push_back(make_pair(label, menu));
|
||||
// recreate window menu
|
||||
m_windowmenu.reset(MenuCreator::createMenuType("windowmenu", screenNumber()));
|
||||
m_windowmenu->setInternalMenu();
|
||||
rereadWindowMenu();
|
||||
}
|
||||
|
||||
void BScreen::reconfigure() {
|
||||
|
@ -956,21 +964,9 @@ void BScreen::reconfigure() {
|
|||
}
|
||||
}
|
||||
|
||||
// if timestamp hasn't changed, then just a reconfigure is fine
|
||||
// and that seems to happen somewhere else, anyway
|
||||
if (fluxbox->menuTimestampsChanged()) {
|
||||
// all bets are off, so just hide the menu and reset the filenames
|
||||
fluxbox->clearMenuFilenames();
|
||||
m_rootmenu->hide();
|
||||
rereadMenu();
|
||||
}
|
||||
|
||||
//reconfigure menus
|
||||
m_workspacemenu->reconfigure();
|
||||
m_configmenu->reconfigure();
|
||||
// recreate window menu
|
||||
m_windowmenu.reset(MenuCreator::createMenuType("windowmenu", screenNumber()));
|
||||
m_windowmenu->setInternalMenu();
|
||||
// update menu filenames
|
||||
m_rootmenu->reloadHelper()->setMainFile(fluxbox->getMenuFilename());
|
||||
m_windowmenu->reloadHelper()->setMainFile(windowMenuFilename());
|
||||
|
||||
// reconfigure workspaces
|
||||
for_each(m_workspaces_list.begin(),
|
||||
|
@ -1003,12 +999,6 @@ void BScreen::reconfigureTabs() {
|
|||
(*it)->fbwindow()->applyDecorations();
|
||||
}
|
||||
|
||||
|
||||
void BScreen::rereadMenu() {
|
||||
initMenu();
|
||||
m_rootmenu->reconfigure();
|
||||
}
|
||||
|
||||
void BScreen::updateWorkspaceName(unsigned int w) {
|
||||
Workspace *space = getWorkspace(w);
|
||||
if (space) {
|
||||
|
@ -1500,34 +1490,24 @@ void BScreen::reassociateWindow(FluxboxWindow *w, unsigned int wkspc_id,
|
|||
|
||||
void BScreen::initMenus() {
|
||||
m_workspacemenu.reset(MenuCreator::createMenuType("workspacemenu", screenNumber()));
|
||||
m_windowmenu.reset(MenuCreator::createMenuType("windowmenu", screenNumber()));
|
||||
m_windowmenu->setInternalMenu();
|
||||
initMenu();
|
||||
m_rootmenu->reloadHelper()->setMainFile(Fluxbox::instance()->getMenuFilename());
|
||||
m_windowmenu->reloadHelper()->setMainFile(windowMenuFilename());
|
||||
}
|
||||
|
||||
|
||||
void BScreen::initMenu() {
|
||||
void BScreen::rereadMenu() {
|
||||
|
||||
if (m_rootmenu.get()) {
|
||||
// since all menus in root is submenus in m_rootmenu
|
||||
// just remove every item in m_rootmenu and then clear m_rootmenu_list
|
||||
while (m_rootmenu->numberOfItems())
|
||||
m_rootmenu->remove(0);
|
||||
m_rootmenu_list.clear();
|
||||
|
||||
} else
|
||||
m_rootmenu.reset(createMenu(""));
|
||||
m_rootmenu->removeAll();
|
||||
m_rootmenu->setLabel("");
|
||||
|
||||
Fluxbox * const fb = Fluxbox::instance();
|
||||
if (!fb->getMenuFilename().empty()) {
|
||||
m_rootmenu.reset(MenuCreator::createFromFile(fb->getMenuFilename(),
|
||||
screenNumber()));
|
||||
if (!fb->getMenuFilename().empty())
|
||||
MenuCreator::createFromFile(fb->getMenuFilename(), *m_rootmenu,
|
||||
m_rootmenu->reloadHelper());
|
||||
|
||||
}
|
||||
|
||||
if (m_rootmenu.get() == 0 || m_rootmenu->numberOfItems() == 0) {
|
||||
if (m_rootmenu->numberOfItems() == 0) {
|
||||
_FB_USES_NLS;
|
||||
m_rootmenu.reset(createMenu(_FB_XTEXT(Menu, DefaultRootMenu, "Fluxbox default menu", "Title of fallback root menu")));
|
||||
m_rootmenu->setLabel(_FB_XTEXT(Menu, DefaultRootMenu, "Fluxbox default menu", "Title of fallback root menu"));
|
||||
FbTk::RefCount<FbTk::Command<void> > restart_fb(FbTk::CommandParser<void>::instance().parse("restart"));
|
||||
FbTk::RefCount<FbTk::Command<void> > exit_fb(FbTk::CommandParser<void>::instance().parse("exit"));
|
||||
FbTk::RefCount<FbTk::Command<void> > execute_xterm(FbTk::CommandParser<void>::instance().parse("exec xterm"));
|
||||
|
@ -1539,14 +1519,39 @@ void BScreen::initMenu() {
|
|||
restart_fb);
|
||||
m_rootmenu->insert(_FB_XTEXT(Menu, Exit, "Exit", "Exit command"),
|
||||
exit_fb);
|
||||
// still save the menu filename, in case it becomes valid later
|
||||
if (!fb->getMenuFilename().empty())
|
||||
fb->saveMenuFilename(fb->getMenuFilename().c_str());
|
||||
}
|
||||
|
||||
m_rootmenu->updateMenu();
|
||||
}
|
||||
|
||||
void BScreen::rereadWindowMenu() {
|
||||
|
||||
m_windowmenu->removeAll();
|
||||
if (!windowMenuFilename().empty())
|
||||
MenuCreator::createWindowMenuFromFile(windowMenuFilename(),
|
||||
*m_windowmenu,
|
||||
m_windowmenu->reloadHelper());
|
||||
|
||||
if (m_windowmenu->numberOfItems() == 0) {
|
||||
const char *defaults[] = {
|
||||
"shade",
|
||||
"stick",
|
||||
"maximize",
|
||||
"iconify",
|
||||
"raise",
|
||||
"lower",
|
||||
"sendto",
|
||||
"layer",
|
||||
"alpha",
|
||||
"extramenus",
|
||||
"separator",
|
||||
"close",
|
||||
0
|
||||
};
|
||||
for (unsigned int i=0; defaults[i]; ++i)
|
||||
MenuCreator::createWindowMenuItem(defaults[i], "", *m_windowmenu);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void BScreen::addConfigMenu(const FbTk::FbString &label, FbTk::Menu &menu) {
|
||||
m_configmenu_list.push_back(make_pair(label, &menu));
|
||||
|
|
|
@ -54,6 +54,7 @@
|
|||
#include <map>
|
||||
|
||||
class ClientPattern;
|
||||
class FbMenu;
|
||||
class Focusable;
|
||||
class FluxboxWindow;
|
||||
class WinClient;
|
||||
|
@ -122,12 +123,12 @@ public:
|
|||
const std::string &windowMenuFilename() const { return *resource.windowmenufile; }
|
||||
FbTk::ImageControl &imageControl() { return *m_image_control.get(); }
|
||||
// menus
|
||||
const FbTk::Menu &rootMenu() const { return *m_rootmenu.get(); }
|
||||
FbTk::Menu &rootMenu() { return *m_rootmenu.get(); }
|
||||
const FbTk::Menu &configMenu() const { return *m_configmenu.get(); }
|
||||
FbTk::Menu &configMenu() { return *m_configmenu.get(); }
|
||||
const FbTk::Menu &windowMenu() const { return *m_windowmenu.get(); }
|
||||
FbTk::Menu &windowMenu() { return *m_windowmenu.get(); }
|
||||
const FbMenu &rootMenu() const { return *m_rootmenu.get(); }
|
||||
FbMenu &rootMenu() { return *m_rootmenu.get(); }
|
||||
const FbMenu &configMenu() const { return *m_configmenu.get(); }
|
||||
FbMenu &configMenu() { return *m_configmenu.get(); }
|
||||
const FbMenu &windowMenu() const { return *m_windowmenu.get(); }
|
||||
FbMenu &windowMenu() { return *m_windowmenu.get(); }
|
||||
ExtraMenus &extraWindowMenus() { return m_extramenus; }
|
||||
const ExtraMenus &extraWindowMenus() const { return m_extramenus; }
|
||||
|
||||
|
@ -166,9 +167,9 @@ public:
|
|||
Workspace *currentWorkspace() { return m_current_workspace; }
|
||||
const Workspace *currentWorkspace() const { return m_current_workspace; }
|
||||
/// @return the workspace menu
|
||||
const FbTk::Menu &workspaceMenu() const { return *m_workspacemenu.get(); }
|
||||
const FbMenu &workspaceMenu() const { return *m_workspacemenu.get(); }
|
||||
/// @return the workspace menu
|
||||
FbTk::Menu &workspaceMenu() { return *m_workspacemenu.get(); }
|
||||
FbMenu &workspaceMenu() { return *m_workspacemenu.get(); }
|
||||
/// @return focus control handler
|
||||
const FocusControl &focusControl() const { return *m_focus_control; }
|
||||
/// @return focus control handler
|
||||
|
@ -251,15 +252,15 @@ public:
|
|||
/**
|
||||
* Creates an empty menu with specified label
|
||||
* @param label for the menu
|
||||
* @return create menu
|
||||
* @return created menu
|
||||
*/
|
||||
FbTk::Menu *createMenu(const std::string &label);
|
||||
FbMenu *createMenu(const std::string &label);
|
||||
/**
|
||||
* Creates an empty toggle menu with a specific label
|
||||
* @param label
|
||||
* @return created menu
|
||||
*/
|
||||
FbTk::Menu *createToggleMenu(const std::string &label);
|
||||
FbMenu *createToggleMenu(const std::string &label);
|
||||
|
||||
/**
|
||||
* For extras to add menus.
|
||||
|
@ -276,8 +277,6 @@ public:
|
|||
|
||||
void saveWorkspaces(int w) { *resource.workspaces = w; }
|
||||
|
||||
void saveMenu(FbTk::Menu &menu) { m_rootmenu_list.push_back(&menu); }
|
||||
|
||||
FbTk::ThemeProxy<FbWinFrameTheme> &focusedWinFrameTheme() { return *m_focused_windowtheme.get(); }
|
||||
const FbTk::ThemeProxy<FbWinFrameTheme> &focusedWinFrameTheme() const { return *m_focused_windowtheme.get(); }
|
||||
FbTk::ThemeProxy<FbWinFrameTheme> &unfocusedWinFrameTheme() { return *m_unfocused_windowtheme.get(); }
|
||||
|
@ -385,6 +384,7 @@ public:
|
|||
void reconfigure();
|
||||
void reconfigureTabs();
|
||||
void rereadMenu();
|
||||
void rereadWindowMenu();
|
||||
void shutdown();
|
||||
/// show position window centered on the screen with "X x Y" text
|
||||
void showPosition(int x, int y);
|
||||
|
@ -491,7 +491,6 @@ public:
|
|||
|
||||
private:
|
||||
void setupConfigmenu(FbTk::Menu &menu);
|
||||
void initMenu();
|
||||
void renderGeomWindow();
|
||||
void renderPosWindow();
|
||||
|
||||
|
@ -517,15 +516,13 @@ private:
|
|||
|
||||
|
||||
std::auto_ptr<FbTk::ImageControl> m_image_control;
|
||||
std::auto_ptr<FbTk::Menu> m_configmenu, m_rootmenu, m_workspacemenu, m_windowmenu;
|
||||
std::auto_ptr<FbMenu> m_configmenu, m_rootmenu, m_workspacemenu, m_windowmenu;
|
||||
|
||||
ExtraMenus m_extramenus;
|
||||
|
||||
typedef std::list<FbTk::Menu *> Rootmenus;
|
||||
typedef std::list<std::pair<FbTk::FbString, FbTk::Menu *> > Configmenus;
|
||||
|
||||
|
||||
Rootmenus m_rootmenu_list;
|
||||
Configmenus m_configmenu_list;
|
||||
Icons m_icon_list;
|
||||
|
||||
|
|
|
@ -307,7 +307,7 @@ Fluxbox::Fluxbox(int argc, char **argv, const char *dpy_name, const char *rcfile
|
|||
// Create keybindings handler and load keys file
|
||||
// Note: this needs to be done before creating screens
|
||||
m_key.reset(new Keys);
|
||||
m_key->load(StringUtil::expandFilename(*m_rc_keyfile).c_str());
|
||||
m_key->reconfigure();
|
||||
|
||||
vector<int> screens;
|
||||
int i;
|
||||
|
@ -399,7 +399,7 @@ Fluxbox::Fluxbox(int argc, char **argv, const char *dpy_name, const char *rcfile
|
|||
//XSynchronize(disp, False);
|
||||
sync(false);
|
||||
|
||||
m_reconfigure_wait = m_reread_menu_wait = false;
|
||||
m_reconfigure_wait = false;
|
||||
|
||||
m_resourcemanager.unlock();
|
||||
ungrab();
|
||||
|
@ -437,8 +437,6 @@ Fluxbox::~Fluxbox() {
|
|||
delete (*it).first;
|
||||
}
|
||||
m_atomhandler.clear();
|
||||
|
||||
clearMenuFilenames();
|
||||
}
|
||||
|
||||
|
||||
|
@ -753,7 +751,7 @@ void Fluxbox::handleEvent(XEvent * const e) {
|
|||
XRefreshKeyboardMapping(&e->xmapping);
|
||||
FbTk::KeyUtil::instance().init(); // reinitialise the key utils
|
||||
// reconfigure keys (if the mapping changes, they don't otherwise update
|
||||
m_key->reconfigure(StringUtil::expandFilename(*m_rc_keyfile).c_str());
|
||||
m_key->reconfigure();
|
||||
}
|
||||
break;
|
||||
case CreateNotify:
|
||||
|
@ -1445,7 +1443,7 @@ void Fluxbox::real_reconfigure() {
|
|||
for_each(m_screen_list.begin(), m_screen_list.end(), mem_fun(&BScreen::reconfigure));
|
||||
|
||||
//reconfigure keys
|
||||
m_key->reconfigure(StringUtil::expandFilename(*m_rc_keyfile).c_str());
|
||||
m_key->reconfigure();
|
||||
|
||||
// and atomhandlers
|
||||
for (AtomHandlerContainerIt it= m_atomhandler.begin();
|
||||
|
@ -1469,87 +1467,11 @@ BScreen *Fluxbox::findScreen(int id) {
|
|||
return *it;
|
||||
}
|
||||
|
||||
bool Fluxbox::menuTimestampsChanged() const {
|
||||
list<MenuTimestamp *>::const_iterator it = m_menu_timestamps.begin();
|
||||
list<MenuTimestamp *>::const_iterator it_end = m_menu_timestamps.end();
|
||||
for (; it != it_end; ++it) {
|
||||
|
||||
time_t timestamp = FbTk::FileUtil::getLastStatusChangeTimestamp((*it)->filename.c_str());
|
||||
|
||||
if (timestamp != (*it)->timestamp)
|
||||
return true;
|
||||
}
|
||||
|
||||
// no timestamp changed
|
||||
return false;
|
||||
}
|
||||
|
||||
void Fluxbox::rereadMenu(bool show_after_reread) {
|
||||
m_reread_menu_wait = true;
|
||||
m_show_menu_after_reread = show_after_reread;
|
||||
m_reconfig_timer.start();
|
||||
}
|
||||
|
||||
|
||||
void Fluxbox::real_rereadMenu() {
|
||||
|
||||
clearMenuFilenames();
|
||||
|
||||
for_each(m_screen_list.begin(),
|
||||
m_screen_list.end(),
|
||||
mem_fun(&BScreen::rereadMenu));
|
||||
|
||||
if(m_show_menu_after_reread) {
|
||||
|
||||
FbCommands::ShowRootMenuCmd showcmd;
|
||||
showcmd.execute();
|
||||
|
||||
m_show_menu_after_reread = false;
|
||||
}
|
||||
}
|
||||
|
||||
void Fluxbox::saveMenuFilename(const char *filename) {
|
||||
if (filename == 0)
|
||||
return;
|
||||
|
||||
bool found = false;
|
||||
|
||||
list<MenuTimestamp *>::iterator it = m_menu_timestamps.begin();
|
||||
list<MenuTimestamp *>::iterator it_end = m_menu_timestamps.end();
|
||||
for (; it != it_end; ++it) {
|
||||
if ((*it)->filename == filename) {
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (! found) {
|
||||
time_t timestamp = FbTk::FileUtil::getLastStatusChangeTimestamp(filename);
|
||||
|
||||
MenuTimestamp *ts = new MenuTimestamp;
|
||||
|
||||
ts->filename = filename;
|
||||
ts->timestamp = timestamp;
|
||||
|
||||
m_menu_timestamps.push_back(ts);
|
||||
}
|
||||
}
|
||||
|
||||
void Fluxbox::clearMenuFilenames() {
|
||||
while(!m_menu_timestamps.empty()) {
|
||||
delete m_menu_timestamps.back();
|
||||
m_menu_timestamps.pop_back();
|
||||
}
|
||||
}
|
||||
|
||||
void Fluxbox::timed_reconfigure() {
|
||||
if (m_reconfigure_wait)
|
||||
real_reconfigure();
|
||||
|
||||
if (m_reread_menu_wait)
|
||||
real_rereadMenu();
|
||||
|
||||
m_reconfigure_wait = m_reread_menu_wait = false;
|
||||
m_reconfigure_wait = false;
|
||||
}
|
||||
|
||||
void Fluxbox::revertFocus() {
|
||||
|
|
|
@ -120,6 +120,7 @@ public:
|
|||
const std::string &getMenuFilename() const { return *m_rc_menufile; }
|
||||
const std::string &getSlitlistFilename() const { return *m_rc_slitlistfile; }
|
||||
const std::string &getAppsFilename() const { return *m_rc_appsfile; }
|
||||
const std::string &getKeysFilename() const { return *m_rc_keyfile; }
|
||||
int colorsPerChannel() const { return *m_rc_colors_per_channel; }
|
||||
int getTabsPadding() const { return *m_rc_tabs_padding; }
|
||||
|
||||
|
@ -136,8 +137,6 @@ public:
|
|||
void shutdown();
|
||||
void load_rc(BScreen &scr);
|
||||
void saveStyleFilename(const char *val) { m_rc_stylefile = (val == 0 ? "" : val); }
|
||||
void saveMenuFilename(const char *);
|
||||
void clearMenuFilenames();
|
||||
void saveWindowSearch(Window win, WinClient *winclient);
|
||||
// some windows relate to the group, not the client, so we record separately
|
||||
// searchWindow on these windows will give the active client in the group
|
||||
|
@ -149,8 +148,6 @@ public:
|
|||
void removeGroupSearch(Window win);
|
||||
void restart(const char *command = 0);
|
||||
void reconfigure();
|
||||
void rereadMenu(bool show_after_reread = false);
|
||||
/// reloads the menus if the timestamps changed
|
||||
|
||||
/// handle any system signal sent to the application
|
||||
void handleSignal(int signum);
|
||||
|
@ -176,8 +173,6 @@ public:
|
|||
typedef std::list<BScreen *> ScreenList;
|
||||
const ScreenList screenList() const { return m_screen_list; }
|
||||
|
||||
/// @return whether the timestamps on the menu changed
|
||||
bool menuTimestampsChanged() const;
|
||||
bool haveShape() const { return m_have_shape; }
|
||||
int shapeEventbase() const { return m_shape_eventbase; }
|
||||
void getDefaultDataFilename(const char *name, std::string &) const;
|
||||
|
@ -190,18 +185,9 @@ public:
|
|||
AttentionNoticeHandler &attentionHandler() { return m_attention_handler; }
|
||||
|
||||
private:
|
||||
|
||||
typedef struct MenuTimestamp {
|
||||
std::string filename;
|
||||
time_t timestamp;
|
||||
} MenuTimestamp;
|
||||
|
||||
|
||||
|
||||
std::string getRcFilename();
|
||||
void load_rc();
|
||||
|
||||
void real_rereadMenu();
|
||||
void real_reconfigure();
|
||||
|
||||
void handleEvent(XEvent *xe);
|
||||
|
@ -242,7 +228,6 @@ private:
|
|||
// will have it's window being the group index
|
||||
std::multimap<Window, WinClient *> m_group_search;
|
||||
|
||||
std::list<MenuTimestamp *> m_menu_timestamps;
|
||||
ScreenList m_screen_list;
|
||||
|
||||
FluxboxWindow *m_masked_window;
|
||||
|
@ -251,7 +236,7 @@ private:
|
|||
|
||||
Atom m_fluxbox_pid;
|
||||
|
||||
bool m_reconfigure_wait, m_reread_menu_wait;
|
||||
bool m_reconfigure_wait;
|
||||
Time m_last_time;
|
||||
Window m_masked;
|
||||
std::string m_rc_file; ///< resource filename
|
||||
|
@ -279,7 +264,6 @@ private:
|
|||
bool m_starting;
|
||||
bool m_restarting;
|
||||
bool m_shutdown;
|
||||
bool m_show_menu_after_reread;
|
||||
int m_server_grabs;
|
||||
int m_randr_event_type; ///< the type number of randr event
|
||||
int m_shape_eventbase; ///< event base for shape events
|
||||
|
|
Loading…
Reference in a new issue