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/KeyUtil.cc | |
parent | 7d4f711204ab0b51d45eaff332708f529c11c9f5 (diff) | |
download | fluxbox_pavel-6c057c6903151aab92309310087d5af455ecefce.zip fluxbox_pavel-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/KeyUtil.cc')
-rw-r--r-- | src/FbTk/KeyUtil.cc | 72 |
1 files changed, 34 insertions, 38 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 | } |