From 95f9c2d6806cf110597a992be45b17a3b13accd7 Mon Sep 17 00:00:00 2001 From: markt Date: Sun, 9 Dec 2007 20:47:41 +0000 Subject: added OnTitlebar modifier to keys file --- ChangeLog | 11 +++++ src/FbCommandFactory.cc | 6 +++ src/Keys.cc | 59 +++++++++++++++++++++----- src/Keys.hh | 11 +++-- src/Screen.cc | 3 +- src/Toolbar.cc | 2 +- src/Window.cc | 96 ++++++++++++++---------------------------- src/fluxbox.cc | 2 +- util/fluxbox-update_configs.cc | 63 +++++++++++++++++++++------ 9 files changed, 158 insertions(+), 95 deletions(-) diff --git a/ChangeLog b/ChangeLog index 5971f05..353af01 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,16 @@ (Format: Year/Month/Day) 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: * Added some new special keys to the keys file: FocusIn, FocusOut, MouseOver, MouseOut, ChangeWorkspace (Mark) diff --git a/src/FbCommandFactory.cc b/src/FbCommandFactory.cc index 8f5dcf8..902461c 100644 --- a/src/FbCommandFactory.cc +++ b/src/FbCommandFactory.cc @@ -257,6 +257,8 @@ FbCommandFactory::FbCommandFactory() { "setresourcevalue", "setresourcevaluedialog", "shade", + "shadeon", + "shadeoff", "shadewindow", "showdesktop", "startmoving", @@ -541,6 +543,10 @@ FbTk::Command *FbCommandFactory::stringToCommand(const std::string &command, return new WindowListCmd(FbTk::RefCount(new CurrentWindowCmd(&FluxboxWindow::kill)), arguments); else if (command == "shade" || command == "shadewindow") return new WindowListCmd(FbTk::RefCount(new CurrentWindowCmd(&FluxboxWindow::shade)), arguments); + else if (command == "shadeon" ) + return new WindowListCmd(FbTk::RefCount(new CurrentWindowCmd(&FluxboxWindow::shadeOn)), arguments); + else if (command == "shadeoff" ) + return new WindowListCmd(FbTk::RefCount(new CurrentWindowCmd(&FluxboxWindow::shadeOff)), arguments); else if (command == "stick" || command == "stickwindow") return new WindowListCmd(FbTk::RefCount(new CurrentWindowCmd(&FluxboxWindow::stick)), arguments); else if (command == "toggledecor") diff --git a/src/Keys.cc b/src/Keys.cc index f3cd092..06a0d48 100644 --- a/src/Keys.cc +++ b/src/Keys.cc @@ -212,7 +212,7 @@ bool Keys::load(const char *filename) { // free memory of previous grabs 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 @@ -245,7 +245,7 @@ void Keys::loadDefaults() { cerr<<"Loading default key bindings"<find(type, mod, key, context); + current_key = current_key->find(type, mod, key, context, + isdouble); 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; } else if (*current_key->m_command) // already being used return false; } 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 = temp_key; } @@ -375,6 +385,7 @@ bool Keys::addBinding(const string &linebuffer) { key = 0; type = 0; context = 0; + isdouble = false; } } else { // parse command line @@ -402,14 +413,40 @@ bool Keys::addBinding(const string &linebuffer) { // return true if bound to a command, else false 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; if (!next_key) next_key = m_keylist; 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 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_, - int context_, FbTk::RefCount command) { + int context_, bool isdouble_) { key = key_; mod = mod_; type = type_; context = context_ ? context_ : GLOBAL; - m_command = command; + isdouble = isdouble_; + m_command = 0; } Keys::t_key::t_key(t_key *k) { @@ -519,6 +557,7 @@ Keys::t_key::t_key(t_key *k) { mod = k->mod; type = k->type; context = k->context; + isdouble = k->isdouble; m_command = k->m_command; } diff --git a/src/Keys.hh b/src/Keys.hh index a8684ed..f5c8cea 100644 --- a/src/Keys.hh +++ b/src/Keys.hh @@ -79,7 +79,8 @@ public: /** 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 void registerWindow(Window win, FbTk::EventHandler &handler, int context); @@ -113,18 +114,19 @@ private: class t_key { public: t_key(int type, unsigned int mod, unsigned int key, int context, - FbTk::RefCount command = FbTk::RefCount(0)); + bool isdouble); t_key(t_key *k); ~t_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 context_ = context_ ? context_ : GLOBAL; keylist_t::iterator it = keylist.begin(), it_end = keylist.end(); for (; it != it_end; it++) { 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_)) return *it; } @@ -137,6 +139,7 @@ private: int type; // KeyPress or ButtonPress unsigned int key; // key code or button number unsigned int mod; + bool isdouble; keylist_t keylist; }; diff --git a/src/Screen.cc b/src/Screen.cc index ebcaaed..7682075 100644 --- a/src/Screen.cc +++ b/src/Screen.cc @@ -849,7 +849,8 @@ void BScreen::buttonPressEvent(XButtonEvent &be) { Keys *keys = Fluxbox::instance()->keys(); WindowCmd::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() { diff --git a/src/Toolbar.cc b/src/Toolbar.cc index 3639df7..f67311c 100644 --- a/src/Toolbar.cc +++ b/src/Toolbar.cc @@ -527,7 +527,7 @@ void Toolbar::reconfigure() { void Toolbar::buttonPressEvent(XButtonEvent &be) { WindowCmd::setWindow(0); if (Fluxbox::instance()->keys()->doAction(be.type, be.state, be.button, - Keys::ON_TOOLBAR)) + Keys::ON_TOOLBAR, be.time)) return; if (be.button == 1) raise(); diff --git a/src/Window.cc b/src/Window.cc index 6a12664..82bdc5e 100644 --- a/src/Window.cc +++ b/src/Window.cc @@ -905,29 +905,27 @@ void FluxboxWindow::moveClientTo(WinClient &win, int x, int y) { void FluxboxWindow::moveClientLeftOf(WinClient &win, WinClient &dest) { - frame().moveLabelButtonLeftOf(*m_labelbuttons[&win], *m_labelbuttons[&dest]); + frame().moveLabelButtonLeftOf(*m_labelbuttons[&win], *m_labelbuttons[&dest]); - ClientList::iterator it = find(m_clientlist.begin(), - m_clientlist.end(), - &win); - ClientList::iterator new_pos = find(m_clientlist.begin(), - m_clientlist.end(), - &dest); + ClientList::iterator it = find(m_clientlist.begin(), + m_clientlist.end(), + &win); + ClientList::iterator new_pos = find(m_clientlist.begin(), + m_clientlist.end(), + &dest); - // make sure we found them - if (it == m_clientlist.end() || new_pos==m_clientlist.end()) { - return; - } - //moving a button to the left of itself results in no change - if( new_pos == it) { - return; - } - //remove from list - m_clientlist.erase(it); - //insert on the new place - m_clientlist.insert(new_pos, &win); + // make sure we found them + if (it == m_clientlist.end() || new_pos==m_clientlist.end()) + return; + //moving a button to the left of itself results in no change + if (new_pos == it) + return; + //remove from list + m_clientlist.erase(it); + //insert on the new place + m_clientlist.insert(new_pos, &win); - updateClientLeftWindow(); + updateClientLeftWindow(); } @@ -2560,10 +2558,20 @@ void FluxboxWindow::buttonPressEvent(XButtonEvent &be) { m_last_button_x = be.x_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 WindowCmd::setWindow(this); - if (Fluxbox::instance()->keys()->doAction(be.type, be.state, be.button, - Keys::ON_WINDOW)) { + Keys *k = Fluxbox::instance()->keys(); + 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; } @@ -2572,13 +2580,6 @@ void FluxboxWindow::buttonPressEvent(XButtonEvent &be) { if (!m_focused && acceptsFocus()) //check 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 || frame().tabcontainer().window() == be.window) { if (screen().clickRaises()) @@ -2607,43 +2608,8 @@ void FluxboxWindow::buttonReleaseEvent(XButtonEvent &re) { stopResizing(); else if (m_attaching_tab) attachTo(re.x_root, re.y_root); - else { + else 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(); - } - } - } } diff --git a/src/fluxbox.cc b/src/fluxbox.cc index 3c30c14..7cf165e 100644 --- a/src/fluxbox.cc +++ b/src/fluxbox.cc @@ -643,7 +643,7 @@ void Fluxbox::setupConfigFiles() { if (create_init) FbTk::FileUtil::copyFile(DEFAULT_INITFILE, init_file.c_str()); -#define CONFIG_VERSION 5 +#define CONFIG_VERSION 6 FbTk::Resource config_version(m_resourcemanager, 0, "session.configVersion", "Session.ConfigVersion"); if (*config_version < CONFIG_VERSION) { diff --git a/util/fluxbox-update_configs.cc b/util/fluxbox-update_configs.cc index 89b355f..ac1d2a2 100644 --- a/util/fluxbox-update_configs.cc +++ b/util/fluxbox-update_configs.cc @@ -34,8 +34,8 @@ #endif // HAVE_SIGNAL_H //use GNU extensions -#ifndef _GNU_SOURCE -#define _GNU_SOURCE +#ifndef _GNU_SOURCE +#define _GNU_SOURCE #endif // _GNU_SOURCE #ifdef HAVE_CSTRING @@ -81,9 +81,9 @@ int run_updates(int old_version, FbTk::ResourceManager &rm) { 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 += "OnDesktop Mouse1 :hideMenus\n"; - new_keyfile += "OnDesktop Mouse2 :workspaceMenu\n"; - new_keyfile += "OnDesktop Mouse3 :rootMenu\n"; + new_keyfile += "OnDesktop Mouse1 :HideMenus\n"; + new_keyfile += "OnDesktop Mouse2 :WorkspaceMenu\n"; + new_keyfile += "OnDesktop Mouse3 :RootMenu\n"; // scrolling on desktop needs to match user's desktop wheeling settings // 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"); if (*rc_wheeling) { if (*rc_reverse) { // if you ask me, this should have been default - new_keyfile += "OnDesktop Mouse4 :prevWorkspace\n"; - new_keyfile += "OnDesktop Mouse5 :nextWorkspace\n"; + new_keyfile += "OnDesktop Mouse4 :PrevWorkspace\n"; + new_keyfile += "OnDesktop Mouse5 :NextWorkspace\n"; } else { - new_keyfile += "OnDesktop Mouse4 :nextWorkspace\n"; - new_keyfile += "OnDesktop Mouse5 :prevWorkspace\n"; + new_keyfile += "OnDesktop Mouse4 :NextWorkspace\n"; + new_keyfile += "OnDesktop Mouse5 :PrevWorkspace\n"; } } 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)) { keep_changes = true; if (*rc_reverse) { // if you ask me, this should have been default - new_keyfile += "OnToolbar Mouse4 :prevWorkspace\n"; - new_keyfile += "OnToolbar Mouse5 :nextWorkspace\n"; + new_keyfile += "OnToolbar Mouse4 :PrevWorkspace\n"; + new_keyfile += "OnToolbar Mouse5 :NextWorkspace\n"; } else { - new_keyfile += "OnToolbar Mouse4 :nextWorkspace\n"; - new_keyfile += "OnToolbar Mouse5 :prevWorkspace\n"; + new_keyfile += "OnToolbar Mouse4 :NextWorkspace\n"; + new_keyfile += "OnToolbar Mouse5 :PrevWorkspace\n"; } } new_keyfile += "\n"; // just for good looks @@ -239,6 +239,43 @@ int run_updates(int old_version, FbTk::ResourceManager &rm) { 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 rc_reverse(rm, false,"session.screen0.reversewheeling", "Session.Screen0.ReverseWheeling"); + FbTk::Resource 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; } -- cgit v0.11.2