diff options
author | mathias <mathias> | 2005-05-06 09:22:53 (GMT) |
---|---|---|
committer | mathias <mathias> | 2005-05-06 09:22:53 (GMT) |
commit | 6c057c6903151aab92309310087d5af455ecefce (patch) | |
tree | 1d4c98ad1637df09b89593b3e6a4a70245db4602 /src/FbTk | |
parent | 7d4f711204ab0b51d45eaff332708f529c11c9f5 (diff) | |
download | fluxbox_lack-6c057c6903151aab92309310087d5af455ecefce.zip fluxbox_lack-6c057c6903151aab92309310087d5af455ecefce.tar.bz2 |
Fix for #1160244, #1099704, #1094107:
if the xkb-extension is enabled and the user switches between his/her
keyboardlayouts fluxbox's keybhandling doesn't work well anymore because
xkeyevent.state contains also xkb-related flags and thus we have to handle
that with caution.
KeyUtils now contain 'isolateModifierMask()' to really work only on the
modifiers. why not as part of cleanMods() ? because the XLookupString return
false results, eg TextBox's would only print chars from the first
keyboardlayout.
Diffstat (limited to 'src/FbTk')
-rw-r--r-- | src/FbTk/KeyUtil.cc | 72 | ||||
-rw-r--r-- | src/FbTk/KeyUtil.hh | 9 | ||||
-rw-r--r-- | src/FbTk/TextBox.cc | 9 |
3 files changed, 48 insertions, 42 deletions
diff --git a/src/FbTk/KeyUtil.cc b/src/FbTk/KeyUtil.cc index 7760254..05e5413 100644 --- a/src/FbTk/KeyUtil.cc +++ b/src/FbTk/KeyUtil.cc | |||
@@ -26,6 +26,30 @@ | |||
26 | 26 | ||
27 | #include <string> | 27 | #include <string> |
28 | 28 | ||
29 | namespace { | ||
30 | |||
31 | struct t_modlist{ | ||
32 | char *str; | ||
33 | unsigned int mask; | ||
34 | bool operator == (const char *modstr) const { | ||
35 | return (strcasecmp(str, modstr) == 0 && mask !=0); | ||
36 | } | ||
37 | }; | ||
38 | |||
39 | const struct t_modlist modlist[] = { | ||
40 | {"SHIFT", ShiftMask}, | ||
41 | {"LOCK", LockMask}, | ||
42 | {"CONTROL", ControlMask}, | ||
43 | {"MOD1", Mod1Mask}, | ||
44 | {"MOD2", Mod2Mask}, | ||
45 | {"MOD3", Mod3Mask}, | ||
46 | {"MOD4", Mod4Mask}, | ||
47 | {"MOD5", Mod5Mask}, | ||
48 | {0, 0} | ||
49 | }; | ||
50 | |||
51 | }; | ||
52 | |||
29 | namespace FbTk { | 53 | namespace FbTk { |
30 | 54 | ||
31 | std::auto_ptr<KeyUtil> KeyUtil::s_keyutil; | 55 | std::auto_ptr<KeyUtil> KeyUtil::s_keyutil; |
@@ -57,19 +81,7 @@ void KeyUtil::loadModmap() { | |||
57 | XFreeModifiermap(m_modmap); | 81 | XFreeModifiermap(m_modmap); |
58 | 82 | ||
59 | m_modmap = XGetModifierMapping(App::instance()->display()); | 83 | m_modmap = XGetModifierMapping(App::instance()->display()); |
60 | // mask to use for modifier | 84 | |
61 | static const int mods[] = { | ||
62 | ShiftMask, | ||
63 | LockMask, | ||
64 | ControlMask, | ||
65 | Mod1Mask, | ||
66 | Mod2Mask, | ||
67 | Mod3Mask, | ||
68 | Mod4Mask, | ||
69 | Mod5Mask, | ||
70 | 0 | ||
71 | }; | ||
72 | |||
73 | // find modifiers and set them | 85 | // find modifiers and set them |
74 | for (int i=0, realkey=0; i<8; ++i) { | 86 | for (int i=0, realkey=0; i<8; ++i) { |
75 | for (int key=0; key<m_modmap->max_keypermod; ++key, ++realkey) { | 87 | for (int key=0; key<m_modmap->max_keypermod; ++key, ++realkey) { |
@@ -77,17 +89,18 @@ void KeyUtil::loadModmap() { | |||
77 | if (m_modmap->modifiermap[realkey] == 0) | 89 | if (m_modmap->modifiermap[realkey] == 0) |
78 | continue; | 90 | continue; |
79 | 91 | ||
80 | KeySym ks = XKeycodeToKeysym(App::instance()->display(), m_modmap->modifiermap[realkey], 0); | 92 | KeySym ks = XKeycodeToKeysym(App::instance()->display(), |
93 | m_modmap->modifiermap[realkey], 0); | ||
81 | 94 | ||
82 | switch (ks) { | 95 | switch (ks) { |
83 | case XK_Caps_Lock: | 96 | case XK_Caps_Lock: |
84 | m_capslock = mods[i]; | 97 | m_capslock = modlist[i].mask; |
85 | break; | 98 | break; |
86 | case XK_Scroll_Lock: | 99 | case XK_Scroll_Lock: |
87 | m_scrolllock = mods[i]; | 100 | m_scrolllock = modlist[i].mask; |
88 | break; | 101 | break; |
89 | case XK_Num_Lock: | 102 | case XK_Num_Lock: |
90 | m_numlock = mods[i]; | 103 | m_numlock = modlist[i].mask; |
91 | break; | 104 | break; |
92 | } | 105 | } |
93 | } | 106 | } |
@@ -164,31 +177,13 @@ unsigned int KeyUtil::getKey(const char *keystr) { | |||
164 | } | 177 | } |
165 | 178 | ||
166 | 179 | ||
167 | struct t_modlist{ | ||
168 | char *str; | ||
169 | unsigned int mask; | ||
170 | bool operator == (const char *modstr) const { | ||
171 | return (strcasecmp(str, modstr) == 0 && mask !=0); | ||
172 | } | ||
173 | }; | ||
174 | |||
175 | /** | 180 | /** |
176 | @return the modifier for the modstr else zero on failure. | 181 | @return the modifier for the modstr else zero on failure. |
177 | */ | 182 | */ |
178 | unsigned int KeyUtil::getModifier(const char *modstr) { | 183 | unsigned int KeyUtil::getModifier(const char *modstr) { |
179 | if (!modstr) | 184 | if (!modstr) |
180 | return 0; | 185 | return 0; |
181 | const static struct t_modlist modlist[] = { | 186 | |
182 | {"SHIFT", ShiftMask}, | ||
183 | {"CONTROL", ControlMask}, | ||
184 | {"MOD1", Mod1Mask}, | ||
185 | {"MOD2", Mod2Mask}, | ||
186 | {"MOD3", Mod3Mask}, | ||
187 | {"MOD4", Mod4Mask}, | ||
188 | {"MOD5", Mod5Mask}, | ||
189 | {0, 0} | ||
190 | }; | ||
191 | |||
192 | // find mod mask string | 187 | // find mod mask string |
193 | for (unsigned int i=0; modlist[i].str !=0; i++) { | 188 | for (unsigned int i=0; modlist[i].str !=0; i++) { |
194 | if (modlist[i] == modstr) | 189 | if (modlist[i] == modstr) |
@@ -210,7 +205,8 @@ void KeyUtil::ungrabKeys() { | |||
210 | unsigned int KeyUtil::keycodeToModmask(unsigned int keycode) { | 205 | unsigned int KeyUtil::keycodeToModmask(unsigned int keycode) { |
211 | XModifierKeymap *modmap = instance().m_modmap; | 206 | XModifierKeymap *modmap = instance().m_modmap; |
212 | 207 | ||
213 | if (!modmap) return 0; | 208 | if (!modmap) |
209 | return 0; | ||
214 | 210 | ||
215 | // search through modmap for this keycode | 211 | // search through modmap for this keycode |
216 | for (int mod=0; mod < 8; mod++) { | 212 | for (int mod=0; mod < 8; mod++) { |
@@ -218,7 +214,7 @@ unsigned int KeyUtil::keycodeToModmask(unsigned int keycode) { | |||
218 | // modifiermap is an array with 8 sets of keycodes | 214 | // modifiermap is an array with 8 sets of keycodes |
219 | // each max_keypermod long, but in a linear array. | 215 | // each max_keypermod long, but in a linear array. |
220 | if (modmap->modifiermap[modmap->max_keypermod*mod + key] == keycode) { | 216 | if (modmap->modifiermap[modmap->max_keypermod*mod + key] == keycode) { |
221 | return (1<<mod); | 217 | return modlist[mod].mask; |
222 | } | 218 | } |
223 | } | 219 | } |
224 | } | 220 | } |
diff --git a/src/FbTk/KeyUtil.hh b/src/FbTk/KeyUtil.hh index 4cafcdd..e32384f 100644 --- a/src/FbTk/KeyUtil.hh +++ b/src/FbTk/KeyUtil.hh | |||
@@ -70,6 +70,14 @@ public: | |||
70 | return mods & ~(capslock() | numlock() ); | 70 | return mods & ~(capslock() | numlock() ); |
71 | } | 71 | } |
72 | 72 | ||
73 | /** | ||
74 | strip away everything which is actually not a modifier | ||
75 | eg, xkb-keyboardgroups are encoded as bit 13 and 14 | ||
76 | */ | ||
77 | unsigned int isolateModifierMask(unsigned int mods) { | ||
78 | return mods & (ShiftMask|LockMask|ControlMask|Mod1Mask|Mod2Mask|Mod3Mask|Mod4Mask|Mod5Mask); | ||
79 | } | ||
80 | |||
73 | /** | 81 | /** |
74 | Convert the specified key into appropriate modifier mask | 82 | Convert the specified key into appropriate modifier mask |
75 | @return corresponding modifier mask | 83 | @return corresponding modifier mask |
@@ -78,6 +86,7 @@ public: | |||
78 | int numlock() const { return Mod2Mask; } //m_numlock; } | 86 | int numlock() const { return Mod2Mask; } //m_numlock; } |
79 | int capslock() const { return LockMask; } //m_capslock; } | 87 | int capslock() const { return LockMask; } //m_capslock; } |
80 | int scrolllock() const { return Mod5Mask; } //m_scrolllock; } | 88 | int scrolllock() const { return Mod5Mask; } //m_scrolllock; } |
89 | |||
81 | private: | 90 | private: |
82 | void loadModmap(); | 91 | void loadModmap(); |
83 | 92 | ||
diff --git a/src/FbTk/TextBox.cc b/src/FbTk/TextBox.cc index 0db8856..2ebd6c0 100644 --- a/src/FbTk/TextBox.cc +++ b/src/FbTk/TextBox.cc | |||
@@ -209,7 +209,7 @@ void TextBox::buttonPressEvent(XButtonEvent &event) { | |||
209 | } | 209 | } |
210 | 210 | ||
211 | void TextBox::keyPressEvent(XKeyEvent &event) { | 211 | void TextBox::keyPressEvent(XKeyEvent &event) { |
212 | // strip numlock and scrolllock mask | 212 | |
213 | event.state = KeyUtil::instance().cleanMods(event.state); | 213 | event.state = KeyUtil::instance().cleanMods(event.state); |
214 | 214 | ||
215 | KeySym ks; | 215 | KeySym ks; |
@@ -218,8 +218,8 @@ void TextBox::keyPressEvent(XKeyEvent &event) { | |||
218 | // a modifier key by itself doesn't do anything | 218 | // a modifier key by itself doesn't do anything |
219 | if (IsModifierKey(ks)) return; | 219 | if (IsModifierKey(ks)) return; |
220 | 220 | ||
221 | if (event.state) { // handle keybindings with state | 221 | if (FbTk::KeyUtil::instance().isolateModifierMask(event.state)) { // handle keybindings with state |
222 | if (event.state == ControlMask) { | 222 | if ((event.state & ControlMask) == ControlMask) { |
223 | 223 | ||
224 | switch (ks) { | 224 | switch (ks) { |
225 | case XK_b: | 225 | case XK_b: |
@@ -248,7 +248,8 @@ void TextBox::keyPressEvent(XKeyEvent &event) { | |||
248 | m_end_pos = 0; | 248 | m_end_pos = 0; |
249 | break; | 249 | break; |
250 | } | 250 | } |
251 | } else if (event.state == ShiftMask || event.state == 0x80) { // shif and altgr | 251 | } else if ((event.state & ShiftMask)== ShiftMask || |
252 | (event.state & 0x80) == 0x80) { // shif and altgr | ||
252 | if (isprint(keychar[0])) { | 253 | if (isprint(keychar[0])) { |
253 | std::string val; | 254 | std::string val; |
254 | val += keychar[0]; | 255 | val += keychar[0]; |