summaryrefslogtreecommitdiff
path: root/src/FbTk
diff options
context:
space:
mode:
authormathias <mathias>2005-05-06 09:22:53 (GMT)
committermathias <mathias>2005-05-06 09:22:53 (GMT)
commit6c057c6903151aab92309310087d5af455ecefce (patch)
tree1d4c98ad1637df09b89593b3e6a4a70245db4602 /src/FbTk
parent7d4f711204ab0b51d45eaff332708f529c11c9f5 (diff)
downloadfluxbox_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.cc72
-rw-r--r--src/FbTk/KeyUtil.hh9
-rw-r--r--src/FbTk/TextBox.cc9
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
29namespace {
30
31struct 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
39const 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
29namespace FbTk { 53namespace FbTk {
30 54
31std::auto_ptr<KeyUtil> KeyUtil::s_keyutil; 55std::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
167struct 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*/
178unsigned int KeyUtil::getModifier(const char *modstr) { 183unsigned 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() {
210unsigned int KeyUtil::keycodeToModmask(unsigned int keycode) { 205unsigned 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
81private: 90private:
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
211void TextBox::keyPressEvent(XKeyEvent &event) { 211void 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];