On Wed, Dec 15, 2010 at 02:22:52PM -0800, tiger...@martins.cc wrote:
>
> > I'm having a problem where a modifier key (usually Alt) gets stuck on.
> > This seems to happen when I press multiple modifiers at once, and don't
> > release them in the correct order.
> > ...
> > Sometimes just pressing and releasing Alt will unstick it, but sometimes
> > it doesn't. The only sure way to unstick it is to repeat the
> > combination of modifiers that got it stuck, and release them in the
> > correct order. Since I use Emacs, this happens fairly often, and it's
> > annoying.
>
> Since I use XEmacs, this happens fairly often, and it's very
> annoying :-) I may have posted that same question here, or on
> some vnc or tiger-vnc related forum and/or bugzilla, and never
> got an answer.
Ok, this is annoying issue and I tried to bake a patch for it. It is
attached, Can you please test it? You should be able to cleanly apply
it to the SVN trunk.
Thank you in advance.
Regards, Adam
--
Adam Tkac, Red Hat, Inc.
Index: unix/xserver/hw/vnc/Input.cc
===================================================================
--- unix/xserver/hw/vnc/Input.cc (revision 4225)
+++ unix/xserver/hw/vnc/Input.cc (working copy)
@@ -520,6 +520,49 @@
#define FREE_MAPS
#endif
+#if XORG >= 17
+/*
+ * Modifier keysyms must be handled differently. Instead of finding
+ * the right row and collumn in the keymap, directly press/release
+ * the keycode which is mapped as modifier with the same keysym.
+ *
+ * This will avoid issues when there are multiple modifier keysyms
+ * in the keymap but only some of them are mapped as modifiers in
+ * the modmap.
+ *
+ * Returns keycode of the modifier key.
+ */
+
+static inline int isModifier(KeySymsPtr keymap, KeyCode *modmap,
+ int maxKeysPerMod, rdr::U32 keysym)
+{
+ KeySym *map = keymap->map;
+ KeyCode minKeyCode = keymap->minKeyCode;
+ int mapWidth = keymap->mapWidth;
+ int i, j, k;
+
+ /* Find modifier index in the modmap */
+ for (i = 0; i < 8; i++) {
+ for (k = 0; k < maxKeysPerMod; k++) {
+ int index = i * maxKeysPerMod + k;
+ int keycode = modmap[index];
+
+ if (keycode == 0)
+ continue;
+
+ for (j = 0; j < mapWidth; j++) {
+ if (map[(keycode - minKeyCode) * mapWidth + j]
+ == keysym) {
+ return keycode;
+ }
+ }
+ }
+ }
+
+ return -1; /* Not a modifier */
+}
+#endif
+
void InputDevice::keyEvent(rdr::U32 keysym, bool down)
{
#if XORG < 17
@@ -603,7 +646,26 @@
}
ModeSwitchFound:
+ int kc;
int col = 0;
+
+#if XORG >= 17
+ if ((kc = isModifier(keymap, modmap, maxKeysPerMod, keysym)) != -1) {
+ /*
+ * It is a modifier key event.
+ *
+ * Don't do any auto-repeat because the X server will translate
+ * each press into a release followed by a press.
+ */
+ if (IS_PRESSED(keyc, kc) && down) {
+ FREE_MAPS;
+ return;
+ }
+
+ goto press;
+ }
+#endif
+
if (maxKeysPerMod != 0) {
if ((state & (1 << ShiftMapIndex)) != 0)
col |= 1;
@@ -612,7 +674,7 @@
col |= 2;
}
- int kc = KeysymToKeycode(keymap, keysym, &col);
+ kc = KeysymToKeycode(keymap, keysym, &col);
/*
* Sort out the "shifted Tab" mess. If we are sent a shifted Tab,
@@ -689,6 +751,7 @@
return;
}
+#if XORG < 17
/*
* See if it's a modifier key. If so, then don't do any auto-repeat,
* because the X server will translate each press into a release
@@ -703,6 +766,7 @@
}
}
}
+#endif
if (maxKeysPerMod != 0) {
ModifierState shift(keyboardDev, ShiftMapIndex);
@@ -724,8 +788,10 @@
* pressKey call, otherwise fake modifier keypress can be lost.
*/
pressKey(keyboardDev, kc, down, "keycode");
- } else
+ } else {
+press:
pressKey(keyboardDev, kc, down, "keycode");
+ }
FREE_MAPS;
------------------------------------------------------------------------------
Lotusphere 2011
Register now for Lotusphere 2011 and learn how
to connect the dots, take your collaborative environment
to the next level, and enter the era of Social Business.
http://p.sf.net/sfu/lotusphere-d2d
_______________________________________________
Tigervnc-users mailing list
Tigervnc-users@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/tigervnc-users