added OnTitlebar modifier to keys file

This commit is contained in:
markt 2007-12-09 20:47:41 +00:00
parent 0b41660077
commit 95f9c2d680
9 changed files with 158 additions and 95 deletions

View file

@ -1,5 +1,16 @@
(Format: Year/Month/Day) (Format: Year/Month/Day)
Changes for 1.0.1: Changes for 1.0.1:
*07/12/09:
* Added OnTitlebar and Double modifiers to the keys file for clicks on the
titlebar and double clicks, respectively (Mark, thanks Matteo Galiazzo)
- For example, `OnTitlebar Double Mouse3 :Maximize' will maximize a window
when you double click on the titlebar with the right mouse button
- Note: if you have commands bound to both a single and double click, the
single click command will still be executed on the first half of a double
click
- Added new key commands ShadeOn and ShadeOff that set whether or not a
window is shaded, rather than toggling the current state
Window.cc Keys.cc/hh FbCommandFactory.cc
*07/11/22: *07/11/22:
* Added some new special keys to the keys file: FocusIn, FocusOut, MouseOver, * Added some new special keys to the keys file: FocusIn, FocusOut, MouseOver,
MouseOut, ChangeWorkspace (Mark) MouseOut, ChangeWorkspace (Mark)

View file

@ -257,6 +257,8 @@ FbCommandFactory::FbCommandFactory() {
"setresourcevalue", "setresourcevalue",
"setresourcevaluedialog", "setresourcevaluedialog",
"shade", "shade",
"shadeon",
"shadeoff",
"shadewindow", "shadewindow",
"showdesktop", "showdesktop",
"startmoving", "startmoving",
@ -541,6 +543,10 @@ FbTk::Command *FbCommandFactory::stringToCommand(const std::string &command,
return new WindowListCmd(FbTk::RefCount<FbTk::Command>(new CurrentWindowCmd(&FluxboxWindow::kill)), arguments); return new WindowListCmd(FbTk::RefCount<FbTk::Command>(new CurrentWindowCmd(&FluxboxWindow::kill)), arguments);
else if (command == "shade" || command == "shadewindow") else if (command == "shade" || command == "shadewindow")
return new WindowListCmd(FbTk::RefCount<FbTk::Command>(new CurrentWindowCmd(&FluxboxWindow::shade)), arguments); return new WindowListCmd(FbTk::RefCount<FbTk::Command>(new CurrentWindowCmd(&FluxboxWindow::shade)), arguments);
else if (command == "shadeon" )
return new WindowListCmd(FbTk::RefCount<FbTk::Command>(new CurrentWindowCmd(&FluxboxWindow::shadeOn)), arguments);
else if (command == "shadeoff" )
return new WindowListCmd(FbTk::RefCount<FbTk::Command>(new CurrentWindowCmd(&FluxboxWindow::shadeOff)), arguments);
else if (command == "stick" || command == "stickwindow") else if (command == "stick" || command == "stickwindow")
return new WindowListCmd(FbTk::RefCount<FbTk::Command>(new CurrentWindowCmd(&FluxboxWindow::stick)), arguments); return new WindowListCmd(FbTk::RefCount<FbTk::Command>(new CurrentWindowCmd(&FluxboxWindow::stick)), arguments);
else if (command == "toggledecor") else if (command == "toggledecor")

View file

@ -212,7 +212,7 @@ bool Keys::load(const char *filename) {
// free memory of previous grabs // free memory of previous grabs
deleteTree(); deleteTree();
m_map["default:"] = new t_key(0,0,0,0); m_map["default:"] = new t_key(0,0,0,0,false);
unsigned int current_line = 0; //so we can tell the user where the fault is unsigned int current_line = 0; //so we can tell the user where the fault is
@ -245,7 +245,7 @@ void Keys::loadDefaults() {
cerr<<"Loading default key bindings"<<endl; cerr<<"Loading default key bindings"<<endl;
#endif #endif
deleteTree(); deleteTree();
m_map["default:"] = new t_key(0,0,0,0); m_map["default:"] = new t_key(0,0,0,0,false);
addBinding("OnDesktop Mouse1 :HideMenus"); addBinding("OnDesktop Mouse1 :HideMenus");
addBinding("OnDesktop Mouse2 :WorkspaceMenu"); addBinding("OnDesktop Mouse2 :WorkspaceMenu");
addBinding("OnDesktop Mouse3 :RootMenu"); addBinding("OnDesktop Mouse3 :RootMenu");
@ -280,6 +280,7 @@ bool Keys::addBinding(const string &linebuffer) {
unsigned int key = 0, mod = 0; unsigned int key = 0, mod = 0;
int type = 0, context = 0; int type = 0, context = 0;
bool isdouble = false;
size_t argc = 0; size_t argc = 0;
t_key *current_key=m_map["default:"]; t_key *current_key=m_map["default:"];
t_key *first_new_keylist = current_key, *first_new_key=0; t_key *first_new_keylist = current_key, *first_new_key=0;
@ -288,7 +289,7 @@ bool Keys::addBinding(const string &linebuffer) {
argc++; argc++;
keyspace_t::iterator it = m_map.find(val[0]); keyspace_t::iterator it = m_map.find(val[0]);
if (it == m_map.end()) if (it == m_map.end())
m_map[val[0]] = new t_key(0,0,0,0); m_map[val[0]] = new t_key(0,0,0,0,false);
current_key = m_map[val[0]]; current_key = m_map[val[0]];
} }
// for each argument // for each argument
@ -305,6 +306,10 @@ bool Keys::addBinding(const string &linebuffer) {
context |= ON_TOOLBAR; context |= ON_TOOLBAR;
else if (strcasecmp("onwindow", val[argc].c_str()) == 0) else if (strcasecmp("onwindow", val[argc].c_str()) == 0)
context |= ON_WINDOW; context |= ON_WINDOW;
else if (strcasecmp("ontitlebar", val[argc].c_str()) == 0)
context |= ON_TITLEBAR;
else if (strcasecmp("double", val[argc].c_str()) == 0)
isdouble = true;
else if (strcasecmp("NONE",val[argc].c_str())) { else if (strcasecmp("NONE",val[argc].c_str())) {
// check if it's a mouse button // check if it's a mouse button
if (strcasecmp("focusin", val[argc].c_str()) == 0) { if (strcasecmp("focusin", val[argc].c_str()) == 0) {
@ -358,16 +363,21 @@ bool Keys::addBinding(const string &linebuffer) {
if (key == 0 && (type == KeyPress || type == ButtonPress)) if (key == 0 && (type == KeyPress || type == ButtonPress))
return false; return false;
if (type != ButtonPress)
isdouble = false;
if (!first_new_key) { if (!first_new_key) {
first_new_keylist = current_key; first_new_keylist = current_key;
current_key = current_key->find(type, mod, key, context); current_key = current_key->find(type, mod, key, context,
isdouble);
if (!current_key) { if (!current_key) {
first_new_key = new t_key(type, mod, key, context); first_new_key = new t_key(type, mod, key, context,
isdouble);
current_key = first_new_key; current_key = first_new_key;
} else if (*current_key->m_command) // already being used } else if (*current_key->m_command) // already being used
return false; return false;
} else { } else {
t_key *temp_key = new t_key(type, mod, key, context); t_key *temp_key = new t_key(type, mod, key, context,
isdouble);
current_key->keylist.push_back(temp_key); current_key->keylist.push_back(temp_key);
current_key = temp_key; current_key = temp_key;
} }
@ -375,6 +385,7 @@ bool Keys::addBinding(const string &linebuffer) {
key = 0; key = 0;
type = 0; type = 0;
context = 0; context = 0;
isdouble = false;
} }
} else { // parse command line } else { // parse command line
@ -402,14 +413,40 @@ bool Keys::addBinding(const string &linebuffer) {
// return true if bound to a command, else false // return true if bound to a command, else false
bool Keys::doAction(int type, unsigned int mods, unsigned int key, bool Keys::doAction(int type, unsigned int mods, unsigned int key,
int context) { int context, Time time) {
static Time last_button_time = 0;
static unsigned int last_button = 0;
// need to remember whether or not this is a double-click, e.g. when
// double-clicking on the titlebar when there's an OnWindow Double command
// we just don't update it if timestamp is the same
static bool double_click = false;
// actual value used for searching
bool isdouble = false;
if (type == ButtonPress) {
if (time > last_button_time)
double_click = (time - last_button_time <
Fluxbox::instance()->getDoubleClickInterval()) &&
last_button == key;
last_button_time = time;
last_button = key;
isdouble = double_click;
}
static t_key* next_key = m_keylist; static t_key* next_key = m_keylist;
if (!next_key) if (!next_key)
next_key = m_keylist; next_key = m_keylist;
mods = FbTk::KeyUtil::instance().cleanMods(mods); mods = FbTk::KeyUtil::instance().cleanMods(mods);
t_key *temp_key = next_key->find(type, mods, key, context); t_key *temp_key = next_key->find(type, mods, key, context, isdouble);
// just because we double-clicked doesn't mean we shouldn't look for single
// click commands
if (!temp_key && isdouble)
temp_key = next_key->find(type, mods, key, context, false);
// need to save this for emacs-style keybindings // need to save this for emacs-style keybindings
static t_key *saved_keymode = 0; static t_key *saved_keymode = 0;
@ -506,12 +543,13 @@ void Keys::setKeyMode(t_key *keyMode) {
} }
Keys::t_key::t_key(int type_, unsigned int mod_, unsigned int key_, Keys::t_key::t_key(int type_, unsigned int mod_, unsigned int key_,
int context_, FbTk::RefCount<FbTk::Command> command) { int context_, bool isdouble_) {
key = key_; key = key_;
mod = mod_; mod = mod_;
type = type_; type = type_;
context = context_ ? context_ : GLOBAL; context = context_ ? context_ : GLOBAL;
m_command = command; isdouble = isdouble_;
m_command = 0;
} }
Keys::t_key::t_key(t_key *k) { Keys::t_key::t_key(t_key *k) {
@ -519,6 +557,7 @@ Keys::t_key::t_key(t_key *k) {
mod = k->mod; mod = k->mod;
type = k->type; type = k->type;
context = k->context; context = k->context;
isdouble = k->isdouble;
m_command = k->m_command; m_command = k->m_command;
} }

View file

@ -79,7 +79,8 @@ public:
/** /**
do action from XKeyEvent; return false if not bound to anything do action from XKeyEvent; return false if not bound to anything
*/ */
bool doAction(int type, unsigned int mods, unsigned int key, int context); bool doAction(int type, unsigned int mods, unsigned int key, int context,
Time time = 0);
/// register a window so that proper keys/buttons get grabbed on it /// register a window so that proper keys/buttons get grabbed on it
void registerWindow(Window win, FbTk::EventHandler &handler, int context); void registerWindow(Window win, FbTk::EventHandler &handler, int context);
@ -113,18 +114,19 @@ private:
class t_key { class t_key {
public: public:
t_key(int type, unsigned int mod, unsigned int key, int context, t_key(int type, unsigned int mod, unsigned int key, int context,
FbTk::RefCount<FbTk::Command> command = FbTk::RefCount<FbTk::Command>(0)); bool isdouble);
t_key(t_key *k); t_key(t_key *k);
~t_key(); ~t_key();
t_key *find(int type_, unsigned int mod_, unsigned int key_, t_key *find(int type_, unsigned int mod_, unsigned int key_,
int context_) { int context_, bool isdouble_) {
// t_key ctor sets context_ of 0 to GLOBAL, so we must here too // t_key ctor sets context_ of 0 to GLOBAL, so we must here too
context_ = context_ ? context_ : GLOBAL; context_ = context_ ? context_ : GLOBAL;
keylist_t::iterator it = keylist.begin(), it_end = keylist.end(); keylist_t::iterator it = keylist.begin(), it_end = keylist.end();
for (; it != it_end; it++) { for (; it != it_end; it++) {
if ((*it)->type == type_ && (*it)->key == key_ && if ((*it)->type == type_ && (*it)->key == key_ &&
((*it)->context & context_) > 0 && (*it)->mod == ((*it)->context & context_) > 0 &&
isdouble_ == (*it)->isdouble && (*it)->mod ==
FbTk::KeyUtil::instance().isolateModifierMask(mod_)) FbTk::KeyUtil::instance().isolateModifierMask(mod_))
return *it; return *it;
} }
@ -137,6 +139,7 @@ private:
int type; // KeyPress or ButtonPress int type; // KeyPress or ButtonPress
unsigned int key; // key code or button number unsigned int key; // key code or button number
unsigned int mod; unsigned int mod;
bool isdouble;
keylist_t keylist; keylist_t keylist;
}; };

View file

@ -849,7 +849,8 @@ void BScreen::buttonPressEvent(XButtonEvent &be) {
Keys *keys = Fluxbox::instance()->keys(); Keys *keys = Fluxbox::instance()->keys();
WindowCmd<void>::setWindow(FocusControl::focusedFbWindow()); WindowCmd<void>::setWindow(FocusControl::focusedFbWindow());
keys->doAction(be.type, be.state, be.button, Keys::GLOBAL|Keys::ON_DESKTOP); keys->doAction(be.type, be.state, be.button, Keys::GLOBAL|Keys::ON_DESKTOP,
be.time);
} }
void BScreen::notifyUngrabKeyboard() { void BScreen::notifyUngrabKeyboard() {

View file

@ -527,7 +527,7 @@ void Toolbar::reconfigure() {
void Toolbar::buttonPressEvent(XButtonEvent &be) { void Toolbar::buttonPressEvent(XButtonEvent &be) {
WindowCmd<void>::setWindow(0); WindowCmd<void>::setWindow(0);
if (Fluxbox::instance()->keys()->doAction(be.type, be.state, be.button, if (Fluxbox::instance()->keys()->doAction(be.type, be.state, be.button,
Keys::ON_TOOLBAR)) Keys::ON_TOOLBAR, be.time))
return; return;
if (be.button == 1) if (be.button == 1)
raise(); raise();

View file

@ -915,13 +915,11 @@ void FluxboxWindow::moveClientLeftOf(WinClient &win, WinClient &dest) {
&dest); &dest);
// make sure we found them // make sure we found them
if (it == m_clientlist.end() || new_pos==m_clientlist.end()) { if (it == m_clientlist.end() || new_pos==m_clientlist.end())
return; return;
}
//moving a button to the left of itself results in no change //moving a button to the left of itself results in no change
if( new_pos == it) { if (new_pos == it)
return; return;
}
//remove from list //remove from list
m_clientlist.erase(it); m_clientlist.erase(it);
//insert on the new place //insert on the new place
@ -2560,10 +2558,20 @@ void FluxboxWindow::buttonPressEvent(XButtonEvent &be) {
m_last_button_x = be.x_root; m_last_button_x = be.x_root;
m_last_button_y = be.y_root; m_last_button_y = be.y_root;
bool onTitlebar = frame().gripLeft().window() != be.window &&
frame().gripRight().window() != be.window &&
frame().clientArea().window() != be.window &&
frame().window() != be.window;
if (onTitlebar && be.button == 1)
raise();
// check keys file first // check keys file first
WindowCmd<void>::setWindow(this); WindowCmd<void>::setWindow(this);
if (Fluxbox::instance()->keys()->doAction(be.type, be.state, be.button, Keys *k = Fluxbox::instance()->keys();
Keys::ON_WINDOW)) { if (onTitlebar && k->doAction(be.type, be.state, be.button,
Keys::ON_TITLEBAR, be.time) ||
k->doAction(be.type, be.state, be.button, Keys::ON_WINDOW, be.time)) {
return; return;
} }
@ -2572,13 +2580,6 @@ void FluxboxWindow::buttonPressEvent(XButtonEvent &be) {
if (!m_focused && acceptsFocus()) //check focus if (!m_focused && acceptsFocus()) //check focus
focus(); focus();
// click on titlebar
if (frame().gripLeft().window() != be.window &&
frame().gripRight().window() != be.window &&
frame().clientArea().window() != be.window &&
frame().window() != be.window)
raise();
if (frame().window().window() == be.window || if (frame().window().window() == be.window ||
frame().tabcontainer().window() == be.window) { frame().tabcontainer().window() == be.window) {
if (screen().clickRaises()) if (screen().clickRaises())
@ -2607,43 +2608,8 @@ void FluxboxWindow::buttonReleaseEvent(XButtonEvent &re) {
stopResizing(); stopResizing();
else if (m_attaching_tab) else if (m_attaching_tab)
attachTo(re.x_root, re.y_root); attachTo(re.x_root, re.y_root);
else { else
frame().tabcontainer().tryButtonReleaseEvent(re); frame().tabcontainer().tryButtonReleaseEvent(re);
if (frame().gripLeft().window() == re.window ||
frame().gripRight().window() == re.window ||
frame().clientArea().window() == re.window ||
frame().handle().window() == re.window ||
frame().window() == re.window)
return;
static Time last_release_time = 0;
bool double_click = (re.time - last_release_time <=
Fluxbox::instance()->getDoubleClickInterval());
last_release_time = re.time;
if (re.button == 1 && double_click)
shade();
if (re.button == 3)
popupMenu();
if (re.button == 2)
lower();
unsigned int reverse = (screen().getScrollReverse() ? 1 : 0);
if (re.button == 4 || re.button == 5) {
if (StringUtil::toLower(screen().getScrollAction()) == "shade") {
if (re.button == 5 - reverse)
shadeOn();
else
shadeOff();
}
if (StringUtil::toLower(screen().getScrollAction()) == "nexttab") {
if (re.button == 5 - reverse)
nextClient();
else
prevClient();
}
}
}
} }

View file

@ -643,7 +643,7 @@ void Fluxbox::setupConfigFiles() {
if (create_init) if (create_init)
FbTk::FileUtil::copyFile(DEFAULT_INITFILE, init_file.c_str()); FbTk::FileUtil::copyFile(DEFAULT_INITFILE, init_file.c_str());
#define CONFIG_VERSION 5 #define CONFIG_VERSION 6
FbTk::Resource<int> config_version(m_resourcemanager, 0, FbTk::Resource<int> config_version(m_resourcemanager, 0,
"session.configVersion", "Session.ConfigVersion"); "session.configVersion", "Session.ConfigVersion");
if (*config_version < CONFIG_VERSION) { if (*config_version < CONFIG_VERSION) {

View file

@ -81,9 +81,9 @@ int run_updates(int old_version, FbTk::ResourceManager &rm) {
string new_keyfile = ""; string new_keyfile = "";
// let's put our new keybindings first, so they're easy to find // let's put our new keybindings first, so they're easy to find
new_keyfile += "!mouse actions added by fluxbox-update_configs\n"; new_keyfile += "!mouse actions added by fluxbox-update_configs\n";
new_keyfile += "OnDesktop Mouse1 :hideMenus\n"; new_keyfile += "OnDesktop Mouse1 :HideMenus\n";
new_keyfile += "OnDesktop Mouse2 :workspaceMenu\n"; new_keyfile += "OnDesktop Mouse2 :WorkspaceMenu\n";
new_keyfile += "OnDesktop Mouse3 :rootMenu\n"; new_keyfile += "OnDesktop Mouse3 :RootMenu\n";
// scrolling on desktop needs to match user's desktop wheeling settings // scrolling on desktop needs to match user's desktop wheeling settings
// hmmm, what are the odds that somebody wants this to be different on // hmmm, what are the odds that somebody wants this to be different on
@ -97,11 +97,11 @@ int run_updates(int old_version, FbTk::ResourceManager &rm) {
"Session.Screen0.ReverseWheeling"); "Session.Screen0.ReverseWheeling");
if (*rc_wheeling) { if (*rc_wheeling) {
if (*rc_reverse) { // if you ask me, this should have been default if (*rc_reverse) { // if you ask me, this should have been default
new_keyfile += "OnDesktop Mouse4 :prevWorkspace\n"; new_keyfile += "OnDesktop Mouse4 :PrevWorkspace\n";
new_keyfile += "OnDesktop Mouse5 :nextWorkspace\n"; new_keyfile += "OnDesktop Mouse5 :NextWorkspace\n";
} else { } else {
new_keyfile += "OnDesktop Mouse4 :nextWorkspace\n"; new_keyfile += "OnDesktop Mouse4 :NextWorkspace\n";
new_keyfile += "OnDesktop Mouse5 :prevWorkspace\n"; new_keyfile += "OnDesktop Mouse5 :PrevWorkspace\n";
} }
} }
new_keyfile += "\n"; // just for good looks new_keyfile += "\n"; // just for good looks
@ -167,11 +167,11 @@ int run_updates(int old_version, FbTk::ResourceManager &rm) {
(strcasecmp((*rc_wheeling).c_str(), "Screen") && *rc_screen)) { (strcasecmp((*rc_wheeling).c_str(), "Screen") && *rc_screen)) {
keep_changes = true; keep_changes = true;
if (*rc_reverse) { // if you ask me, this should have been default if (*rc_reverse) { // if you ask me, this should have been default
new_keyfile += "OnToolbar Mouse4 :prevWorkspace\n"; new_keyfile += "OnToolbar Mouse4 :PrevWorkspace\n";
new_keyfile += "OnToolbar Mouse5 :nextWorkspace\n"; new_keyfile += "OnToolbar Mouse5 :NextWorkspace\n";
} else { } else {
new_keyfile += "OnToolbar Mouse4 :nextWorkspace\n"; new_keyfile += "OnToolbar Mouse4 :NextWorkspace\n";
new_keyfile += "OnToolbar Mouse5 :prevWorkspace\n"; new_keyfile += "OnToolbar Mouse5 :PrevWorkspace\n";
} }
} }
new_keyfile += "\n"; // just for good looks new_keyfile += "\n"; // just for good looks
@ -239,6 +239,43 @@ int run_updates(int old_version, FbTk::ResourceManager &rm) {
new_version = 5; new_version = 5;
} }
if (old_version < 6) { // move titlebar actions to keys file
string whole_keyfile = read_file(keyfilename);
string new_keyfile = "";
// let's put our new keybindings first, so they're easy to find
new_keyfile += "!mouse actions added by fluxbox-update_configs\n";
new_keyfile += "OnTitlebar Double Mouse1 :Shade\n";
new_keyfile += "OnTitlebar Mouse3 :Windowmenu\n";
new_keyfile += "OnTitlebar Mouse2 :Lower\n";
FbTk::Resource<bool> rc_reverse(rm, false,"session.screen0.reversewheeling", "Session.Screen0.ReverseWheeling");
FbTk::Resource<std::string> scroll_action(rm, "", "session.screen0.windowScrollAction", "Session.Screen0.WindowScrollAction");
if (strcasecmp((*scroll_action).c_str(), "shade") == 0) {
if (*rc_reverse) {
new_keyfile += "OnTitlebar Mouse5 :ShadeOn\n";
new_keyfile += "OnTitlebar Mouse4 :ShadeOff\n";
} else {
new_keyfile += "OnTitlebar Mouse4 :ShadeOn\n";
new_keyfile += "OnTitlebar Mouse5 :ShadeOff\n";
}
} else if (strcasecmp((*scroll_action).c_str(), "nexttab") == 0) {
if (*rc_reverse) {
new_keyfile += "OnTitlebar Mouse5 :PrevTab\n";
new_keyfile += "OnTitlebar Mouse4 :NextTab\n";
} else {
new_keyfile += "OnTitlebar Mouse4 :PrevTab\n";
new_keyfile += "OnTitlebar Mouse5 :NextTab\n";
}
}
new_keyfile += "\n"; // just for good looks
new_keyfile += whole_keyfile; // don't forget user's old keybindings
write_file(keyfilename, new_keyfile);
new_version = 6;
}
return new_version; return new_version;
} }