shuffle bunch of stuff from Keys into FbTk/KeyUtil
@@ -1,6 +1,10 @@
(Format: Year/Month/Day) Changes for 0.9.6: *03/10/05: + * Move a bunch of functionality from Keys into FbTk::KeyUtil (Simon) + - also fix issue where Capslock mod was taken to be whatever caps + key was mapped to (why??). Now uses LockMask (ditto num,scroll). + Keys.hh/cc KeyUtil.hh/cc TextBox.cc fluxbox.cc * Fix reading of auto raise delay (Simon) fluxbox.hh/cc Screen.cc Timer.hh/cc * Make focusLast work for sloppy focus when changing workspace or
@@ -19,63 +19,175 @@ // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. -// $Id: KeyUtil.cc,v 1.2 2003/09/08 19:18:22 fluxgen Exp $ +// $Id: KeyUtil.cc,v 1.3 2003/10/05 07:20:16 rathnor Exp $ #include "KeyUtil.hh" #include "App.hh" -#include <X11/keysym.h> +#include <string> namespace FbTk { -int KeyUtil::s_capslock_mod = 0; -int KeyUtil::s_numlock_mod = 0; -int KeyUtil::s_scrolllock_mod = 0; -bool KeyUtil::s_init = false; +KeyUtil *KeyUtil::s_keyutil = 0; + +KeyUtil *KeyUtil::instance() { + if (s_keyutil == 0) + s_keyutil = new KeyUtil(); + return s_keyutil; +} + + +KeyUtil::KeyUtil() + : m_modmap(0) +{ + init(); +} void KeyUtil::init() { - Display *disp = FbTk::App::instance()->display(); + loadModmap(); +} - XModifierKeymap *modmap = XGetModifierMapping(disp); +KeyUtil::~KeyUtil() { + if (m_modmap) + XFreeModifiermap(m_modmap); +} + +void KeyUtil::loadModmap() { + if (m_modmap) + XFreeModifiermap(m_modmap); + + m_modmap = XGetModifierMapping(App::instance()->display()); +} + + + +/** + Grabs a key with the modifier + and with numlock,capslock and scrollock +*/ +void KeyUtil::grabKey(unsigned int key, unsigned int mod) { + Display *display = App::instance()->display(); + const unsigned int capsmod = LockMask; + const unsigned int nummod = Mod2Mask; + const unsigned int scrollmod = Mod5Mask; + + for (int screen=0; screen<ScreenCount(display); screen++) { + + Window root = RootWindow(display, screen); + + XGrabKey(display, key, mod, + root, True, + GrabModeAsync, GrabModeAsync); + + // Grab with numlock, capslock and scrlock - // mask to use for modifier - int mods[] = { - ShiftMask, - LockMask, - ControlMask, - Mod1Mask, - Mod2Mask, - Mod3Mask, - Mod4Mask, - Mod5Mask, - 0 - }; + //numlock + XGrabKey(display, key, mod|nummod, + root, True, + GrabModeAsync, GrabModeAsync); + //scrolllock + XGrabKey(display, key, mod|scrollmod, + root, True, + GrabModeAsync, GrabModeAsync); + //capslock + XGrabKey(display, key, mod|capsmod, + root, True, + GrabModeAsync, GrabModeAsync); - // find modifiers and set them - for (int i = 0, realkey = 0; i < 8; ++i) { - for (int key = 0; key < modmap->max_keypermod; ++key, ++realkey) { + //capslock+numlock + XGrabKey(display, key, mod|capsmod|nummod, + root, True, + GrabModeAsync, GrabModeAsync); - if (modmap->modifiermap[realkey] == 0) - continue; + //capslock+scrolllock + XGrabKey(display, key, mod|capsmod|scrollmod, + root, True, + GrabModeAsync, GrabModeAsync); + + //capslock+numlock+scrolllock + XGrabKey(display, key, mod|capsmod|scrollmod|nummod, + root, True, + GrabModeAsync, GrabModeAsync); - KeySym ks = XKeycodeToKeysym(disp, modmap->modifiermap[realkey], 0); + //numlock+scrollLock + XGrabKey(display, key, mod|nummod|scrollmod, + root, True, + GrabModeAsync, GrabModeAsync); + + } + +} - switch (ks) { - case XK_Caps_Lock: - s_capslock_mod = mods[i]; - break; - case XK_Scroll_Lock: - s_scrolllock_mod = mods[i]; - break; - case XK_Num_Lock: - s_numlock_mod = mods[i]; - break; - } +/** + @return keycode of keystr on success else 0 +*/ +unsigned int KeyUtil::getKey(const char *keystr) { + if (!keystr) + return 0; + return XKeysymToKeycode(App::instance()->display(), + XStringToKeysym(keystr)); +} + +/** + @return the modifier for the modstr else zero on failure. +*/ +unsigned int KeyUtil::getModifier(const char *modstr) { + if (!modstr) + return 0; + struct t_modlist{ + char *str; + unsigned int mask; + bool operator == (const char *modstr) { + return (strcasecmp(str, modstr) == 0 && mask !=0); } + } modlist[] = { + {"SHIFT", ShiftMask}, + {"CONTROL", ControlMask}, + {"MOD1", Mod1Mask}, + {"MOD2", Mod2Mask}, + {"MOD3", Mod3Mask}, + {"MOD4", Mod4Mask}, + {"MOD5", Mod5Mask}, + {0, 0} + }; + + // find mod mask string + for (unsigned int i=0; modlist[i].str !=0; i++) { + if (modlist[i] == modstr) + return modlist[i].mask; } + + return 0; +} - s_init = true; - XFreeModifiermap(modmap); +/// Ungrabs the keys +void KeyUtil::ungrabKeys() { + Display * display = App::instance()->display(); + for (int screen=0; screen<ScreenCount(display); screen++) { + XUngrabKey(display, AnyKey, AnyModifier, + RootWindow(display, screen)); + } +} + +unsigned int KeyUtil::keycodeToModmask(unsigned int keycode) { + XModifierKeymap *modmap = instance()->m_modmap; + + if (!modmap) return 0; + + // search through modmap for this keycode + for (int mod=0; mod < 8; mod++) { + for (int key=0; key < modmap->max_keypermod; ++key) { + // modifiermap is an array with 8 sets of keycodes + // each max_keypermod long, but in a linear array. + if (modmap->modifiermap[modmap->max_keypermod*mod + key] == keycode) { + return (1<<mod); + } + } + } + // no luck + return 0; } + + } // end namespace FbTk
@@ -19,34 +19,66 @@ // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. -// $Id: KeyUtil.hh,v 1.1 2003/09/06 15:46:00 fluxgen Exp $ +// $Id: KeyUtil.hh,v 1.2 2003/10/05 07:20:35 rathnor Exp $ #ifndef FBTK_KEYUTIL_HH #define FBTK_KEYUTIL_HH +#include <X11/Xlib.h> +#include <X11/keysym.h> + namespace FbTk { class KeyUtil { public: + + KeyUtil(); + ~KeyUtil(); + + void init(); + static KeyUtil *instance(); + + /** + Grab the specified key + */ + static void grabKey(unsigned int key, unsigned int mod); + + /** + convert the string to the keysym + @return the keysym corresponding to the string, or zero + */ + static unsigned int getKey(const char *keystr); + + /** + @return the modifier for the modstr else zero on failure. + */ + static unsigned int KeyUtil::getModifier(const char *modstr); + + /** + ungrabs all keys + */ + static void ungrabKeys(); + /** Strip out modifiers we want to ignore @return the cleaned state number */ static unsigned int cleanMods(unsigned int mods) { - if (!s_init) - init(); - //remove numlock, capslock and scrolllock - return mods & (~s_capslock_mod & ~s_numlock_mod & ~s_scrolllock_mod); + //remove numlock(Mod2), capslock and scrolllock(Mod5) + return mods & ~(LockMask | Mod2Mask | Mod5Mask); } - static int capslockMod() { if (!s_init) init(); return s_capslock_mod; } - static int numlockMod() { if (!s_init) init(); return s_numlock_mod; } - static int scrolllockMod() { if (!s_init) init(); return s_scrolllock_mod; } - /// so one can force a reinit of modifiers - static void init(); + /** + Convert the specified key into appropriate modifier mask + @return corresponding modifier mask + */ + static unsigned int keycodeToModmask(unsigned int keycode); + private: - static int s_capslock_mod, s_numlock_mod, s_scrolllock_mod; ///< modifiers - static bool s_init; + void loadModmap(); + + XModifierKeymap *m_modmap; + static KeyUtil *s_keyutil; }; } // end namespace FbTk
@@ -19,7 +19,7 @@ // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. -// $Id: TextBox.cc,v 1.2 2003/09/08 21:26:19 fluxgen Exp $ +// $Id: TextBox.cc,v 1.3 2003/10/05 07:20:47 rathnor Exp $ #include "TextBox.hh" #include "Font.hh"@@ -185,8 +185,7 @@ }
void TextBox::keyPressEvent(XKeyEvent &event) { // strip numlock and scrolllock mask - event.state &= ~FbTk::KeyUtil::numlockMod(); - event.state &= ~FbTk::KeyUtil::scrolllockMod(); + event.state = KeyUtil::cleanMods(event.state); KeySym ks; char keychar[1];
@@ -19,7 +19,7 @@ // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. -//$Id: Keys.cc,v 1.37 2003/09/06 13:58:06 fluxgen Exp $ +//$Id: Keys.cc,v 1.38 2003/10/05 07:19:30 rathnor Exp $ #include "Keys.hh"@@ -74,20 +74,16 @@
using namespace std; Keys::Keys(const char *filename): - m_display(FbTk::App::instance()->display()), - m_modmap(0) { - - loadModmap(); + m_display(FbTk::App::instance()->display()) +{ if (filename != 0) load(filename); } Keys::~Keys() { - if (m_modmap) - XFreeModifiermap(m_modmap); - ungrabKeys(); + FbTk::KeyUtil::ungrabKeys(); deleteTree(); }@@ -97,14 +93,6 @@ while (!m_keylist.empty()) {
if (m_keylist.back()) delete m_keylist.back(); m_keylist.pop_back(); - } -} - -/// Ungrabs the keys -void Keys::ungrabKeys() { - for (int screen=0; screen<ScreenCount(m_display); screen++) { - XUngrabKey(m_display, AnyKey, AnyModifier, - RootWindow(m_display, screen)); } }@@ -118,7 +106,7 @@ if (!filename)
return false; //ungrab all keys - ungrabKeys(); + FbTk::KeyUtil::ungrabKeys(); //free memory of previous grabs deleteTree();@@ -158,15 +146,15 @@
if (val[argc][0] != ':') { // parse key(s) keyarg++; if (keyarg==1) //first arg is modifier - mod = getModifier(val[argc].c_str()); + mod = FbTk::KeyUtil::getModifier(val[argc].c_str()); else if (keyarg>1) { //keyarg=0; - int tmpmod = getModifier(val[argc].c_str()); + int tmpmod = FbTk::KeyUtil::getModifier(val[argc].c_str()); if(tmpmod) mod|=tmpmod; //If it's a modifier else { - key = getKey(val[argc].c_str()); // else get the key + key = FbTk::KeyUtil::getKey(val[argc].c_str()); // else get the key if (key == 0) { cerr<<"["<<filename<<"]: Invalid key/modifier on line("<< line<<"): "<<linebuffer<<endl;@@ -221,114 +209,6 @@
return true; } -void Keys::loadModmap() { - if (m_modmap) - XFreeModifiermap(m_modmap); - - m_modmap = XGetModifierMapping(m_display); - // force reinit of modifiers - FbTk::KeyUtil::init(); -} - -/** - Grabs a key with the modifier - and with numlock,capslock and scrollock -*/ -void Keys::grabKey(unsigned int key, unsigned int mod) { - const int capsmod = FbTk::KeyUtil::capslockMod(); - const int nummod = FbTk::KeyUtil::numlockMod(); - const int scrollmod = FbTk::KeyUtil::scrolllockMod(); - - for (int screen=0; screen<ScreenCount(m_display); screen++) { - - Window root = RootWindow(m_display, screen); - - XGrabKey(m_display, key, mod, - root, True, - GrabModeAsync, GrabModeAsync); - - // Grab with numlock, capslock and scrlock - - //numlock - XGrabKey(m_display, key, mod|nummod, - root, True, - GrabModeAsync, GrabModeAsync); - //scrolllock - XGrabKey(m_display, key, mod|scrollmod, - root, True, - GrabModeAsync, GrabModeAsync); - //capslock - XGrabKey(m_display, key, mod|capsmod, - root, True, - GrabModeAsync, GrabModeAsync); - - //capslock+numlock - XGrabKey(m_display, key, mod|capsmod|nummod, - root, True, - GrabModeAsync, GrabModeAsync); - - //capslock+scrolllock - XGrabKey(m_display, key, mod|capsmod|scrollmod, - root, True, - GrabModeAsync, GrabModeAsync); - - //capslock+numlock+scrolllock - XGrabKey(m_display, key, mod|capsmod|scrollmod|nummod, - root, True, - GrabModeAsync, GrabModeAsync); - - //numlock+scrollLock - XGrabKey(m_display, key, mod|nummod|scrollmod, - root, True, - GrabModeAsync, GrabModeAsync); - - } - -} - -/** - @return the modifier for the modstr else zero on failure. - TODO fix more masks -*/ -unsigned int Keys::getModifier(const char *modstr) { - if (!modstr) - return 0; - struct t_modlist{ - char *str; - unsigned int mask; - bool operator == (const char *modstr) { - return (strcasecmp(str, modstr) == 0 && mask !=0); - } - } modlist[] = { - {"SHIFT", ShiftMask}, - {"CONTROL", ControlMask}, - {"MOD1", Mod1Mask}, - {"MOD2", Mod2Mask}, - {"MOD3", Mod3Mask}, - {"MOD4", Mod4Mask}, - {"MOD5", Mod5Mask}, - {0, 0} - }; - - // find mod mask string - for (unsigned int i=0; modlist[i].str !=0; i++) { - if (modlist[i] == modstr) - return modlist[i].mask; - } - - return 0; -} - -/** - @return keycode of keystr on success else 0 -*/ -unsigned int Keys::getKey(const char *keystr) { - if (!keystr) - return 0; - return XKeysymToKeycode(m_display, - XStringToKeysym(keystr)); -} - /** @return the KeyAction of the XKeyEvent */@@ -399,7 +279,7 @@ }
} if (baselist_i == m_keylist.size()) { - grabKey(newtree->key, newtree->mod); + FbTk::KeyUtil::grabKey(newtree->key, newtree->mod); m_keylist.push_back(new t_key(newtree)); if (newtree->keylist.size()) return mergeTree(newtree->keylist[0], m_keylist.back());@@ -420,7 +300,7 @@ }
} //if it wasn't in the list grab the key and add it to the list if (baselist_i==basetree->keylist.size()) { - grabKey(newtree->key, newtree->mod); + FbTk::KeyUtil::grabKey(newtree->key, newtree->mod); basetree->keylist.push_back(new t_key(newtree)); if (newtree->keylist.size()) return mergeTree(newtree->keylist[0], basetree->keylist.back());@@ -453,20 +333,3 @@ }
} } - -unsigned int Keys::keycodeToModmask(unsigned int keycode) { - if (!m_modmap) return 0; - - // search through modmap for this keycode - for (int mod=0; mod < 8; mod++) { - for (int key=0; key < m_modmap->max_keypermod; ++key) { - // modifiermap is an array with 8 sets of keycodes - // each max_keypermod long, but in a linear array. - if (m_modmap->modifiermap[m_modmap->max_keypermod*mod + key] == keycode) { - return (1<<mod); - } - } - } - // no luck - return 0; -}
@@ -19,7 +19,7 @@ // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. -// $Id: Keys.hh,v 1.28 2003/09/06 13:58:06 fluxgen Exp $ +// $Id: Keys.hh,v 1.29 2003/10/05 07:19:36 rathnor Exp $ #ifndef KEYS_HH #define KEYS_HH@@ -46,9 +46,6 @@ explicit Keys(const char *filename=0);
/// destructor ~Keys(); - unsigned int keycodeToModmask(unsigned int keycode); - - void loadModmap(); /** Load configuration from file @return true on success, else false@@ -66,24 +63,13 @@ bool reconfigure(const char *filename);
private: void deleteTree(); - void ungrabKeys(); + void bindKey(unsigned int key, unsigned int mod); /** @param modstr modifier string (i.e Mod4, Mod5) @return modifier number that match modstr */ - unsigned int getModifier(const char *modstr); - /** - @param keystr a key string (i.e F1, Enter) - @return key number that match keystr - */ - unsigned int getKey(const char *keystr); - /** - grab a key - @param key the key - @param mod the modifier - */ - void grabKey(unsigned int key, unsigned int mod); + std::string filename; class t_key {@@ -127,7 +113,6 @@
std::vector<t_key *> m_keylist; Display *m_display; ///< display connection - XModifierKeymap *m_modmap; };
@@ -22,7 +22,7 @@ // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. -// $Id: fluxbox.cc,v 1.195 2003/10/05 06:28:47 rathnor Exp $ +// $Id: fluxbox.cc,v 1.196 2003/10/05 07:19:38 rathnor Exp $ #include "fluxbox.hh"@@ -43,6 +43,7 @@ #include "FbAtoms.hh"
#include "defaults.hh" #include "FbTk/Image.hh" +#include "FbTk/KeyUtil.hh" //Use GNU extensions #ifndef _GNU_SOURCE@@ -840,9 +841,9 @@ // Update stored modifier mapping
#ifdef DEBUG cerr<<__FILE__<<"("<<__FUNCTION__<<"): MappingNotify"<<endl; #endif // DEBUG - if (m_key.get()) { - m_key->loadModmap(); - } + + FbTk::KeyUtil::instance()->init(); // reinitialise the key utils + break; case CreateNotify: break;@@ -1182,7 +1183,7 @@ // we notify if _all_ of the watched modifiers are released
if (m_watching_screen && m_watch_keyrelease) { // mask the mod of the released key out // won't mask anything if it isn't a mod - ke.state &= ~m_key->keycodeToModmask(ke.keycode); + ke.state &= ~FbTk::KeyUtil::keycodeToModmask(ke.keycode); if ((m_watch_keyrelease & ke.state) == 0) {