Subject: Diff to work with Caps/Num/Scroll-Locks

From: [email-masked]
Date: Sun, 23 Apr 2000 00:34:03 -0500 (CDT)

Hi,

The 4 diff's below show how fvwm CAN work with CapsLock, NumLock
and ScrollLock, together with Click-to-Focus, at least when running
with an XFree86 server.  The core of the problem is that fvwm naively
treats all "modifer keys" the same; and for reason unkown to me, it
oversteps by grabbing buttons and pointer/key when only the CapsLock
is down.

These "lock keys" are not something the user can speicify in the RC
to setup short-cut commands, so have no interest to fvwm (in fact,
not even to apps, except those that do act on ScrollLock).  A window
manager should not look at them at all.

The "knowledge" shown below about XFree86 keys, isn't back art.
Anyone who cares to look at XFree86 header files can find them.  Hope
your team can pick this up, add lock keys used by other X11 servers
(see patched fvwm.c main() about this), and rid the "fvwm lock-key
syndrome" once and for all.  The diff's are against fvwm-2.2.4 release.

-huver  [email-masked]
 XFree86 member
========================================================================
diff -u fvwm/fvwm.c.224 fvwm/fvwm.c
--- fvwm/fvwm.c.224	Sat Oct  2 18:28:36 1999
+++ fvwm/fvwm.c		Sat Apr 22 23:45:53 2000
@@ -55,6 +55,21 @@
 Window BlackoutWin=None;        /* window to hide window captures */
 Bool fFvwmInStartup = True;     /* Set to False when startup has finished */
 
+unsigned int ignoreMods = 0;	/* 2000-04-21 huver: bits of key modifiers
+				 * to ignore when grabbing buttons or
+				 * deciding if a short-cut cmd key has
+				 * been entered.  These typically are the
+				 * "lock keys": CapsLock, NumLock and
+				 * ScrollLock; these lock keys should ALWAYS
+				 * be reserved for users.  Note fvwm sets up
+				 * bits here actually flipped, so a simple
+				 * '&' is all that's needed, e.g.,
+				 * "if (e->anyevent.state & ignoreMods)"
+				 * would exclude lock keys, rather than
+				 * "if (e->anyevent.state & ~ignoreMods)"
+				 * which is awkward to read.
+				*/
+
 char *default_config_command = "Read "FVWMRC;
 
 #define MAX_CFG_CMDS 10
@@ -297,6 +312,18 @@
   }
   Scr.screen= DefaultScreen(dpy);
   Scr.NumberOfScreens = ScreenCount(dpy);
+
+  /* 2000-04-21 huver
+  /* we set up ignoreMods at run-time because they are server dependent.
+   * code here is for XFree86 case.  Please add cases for other servers.
+  */
+  if (strstr(ServerVendor(dpy), "XFree86") != NULL) {
+    /* xfree86 use Mod2Mask for NumLock, and Mod5Mask for ScrollLock */
+    ignoreMods = LockMask | Mod2Mask | Mod5Mask;
+  }
+
+  /* for convenience latter on, we flip the bits here. */
+  ignoreMods = ~ignoreMods;
 
   master_pid = getpid();

diff -u fvwm/focus.c.224 fvwm/focus.c
--- fvwm/focus.c.224	Thu Feb 11 21:42:42 1999
+++ fvwm/focus.c	Sat Apr 22 23:49:13 2000
@@ -100,9 +100,13 @@
 		    XGrabButton(dpy,(i+1),0,Scr.Ungrabbed->frame,True,
 				ButtonPressMask, GrabModeSync,GrabModeAsync,
 				None,Scr.FvwmCursors[SYS]);
+
+/* 2000-04-21 huver: why grab buttons only with caps-lock down?
+   where is this stated in the man/doc pages?  and what purpose
+   does this serve?
 		    XGrabButton(dpy,(i+1),LockMask,Scr.Ungrabbed->frame,True,
 				ButtonPressMask, GrabModeSync,GrabModeAsync,
 				None,Scr.FvwmCursors[SYS]);
+*/
 		  }
 	      Scr.Focus = NULL;
 	      Scr.Ungrabbed = NULL;
@@ -158,7 +162,9 @@
 	if(Scr.buttons2grab & (1<<i))
 	  {
 	    XUngrabButton(dpy,(i+1),0,Fw->frame);
+/* 2000-04-21 huver
 	    XUngrabButton(dpy,(i+1),LockMask,Fw->frame);
+*/
 	  }
       Scr.Ungrabbed = Fw;
     }

diff -u fvwm/add_window.c.224 fvwm/add_window.c
--- fvwm/add_window.c.224	Sun Feb 14 09:48:56 1999
+++ fvwm/add_window.c		Sat Apr 22 23:57:16 2000
@@ -68,6 +68,9 @@
 extern char *IconPath;
 extern char *PixmapPath;
 
+/* 2000-04-21 huver: ignore keyboard lock keys */
+extern unsigned int ignoreMods;
+
 static void merge_styles(name_list *, name_list *); /* prototype */
 
 /***********************************************************************
@@ -801,7 +804,8 @@
 	{
 	  if(MouseEntry->Button_Key >0)
 	    {
-	      XGrabButton(dpy, MouseEntry->Button_Key, MouseEntry->Modifier,
+	      XGrabButton(dpy, MouseEntry->Button_Key,
+			  MouseEntry->Modifier & ignoreMods,
 			  tmp_win->w,
 			  True, ButtonPressMask | ButtonReleaseMask,
 			  GrabModeAsync, GrabModeAsync, None,
@@ -809,7 +813,7 @@
 	      if(MouseEntry->Modifier != AnyModifier)
 		{
 		  XGrabButton(dpy, MouseEntry->Button_Key,
-			      (MouseEntry->Modifier | LockMask),
+			      (MouseEntry->Modifier & ignoreMods),
 			      tmp_win->w,
 			      True, ButtonPressMask | ButtonReleaseMask,
 			      GrabModeAsync, GrabModeAsync, None,
@@ -818,17 +822,17 @@
 	    }
 	  else
 	    {
-	      XGrabButton(dpy, 1, MouseEntry->Modifier,
+	      XGrabButton(dpy, 1, MouseEntry->Modifier & ignoreMods,
 			  tmp_win->w,
 			  True, ButtonPressMask | ButtonReleaseMask,
 			  GrabModeAsync, GrabModeAsync, None,
 			  Scr.FvwmCursors[DEFAULT]);
-	      XGrabButton(dpy, 2, MouseEntry->Modifier,
+	      XGrabButton(dpy, 2, MouseEntry->Modifier & ignoreMods,
 			  tmp_win->w,
 			  True, ButtonPressMask | ButtonReleaseMask,
 			  GrabModeAsync, GrabModeAsync, None,
 			  Scr.FvwmCursors[DEFAULT]);
-	      XGrabButton(dpy, 3, MouseEntry->Modifier,
+	      XGrabButton(dpy, 3, MouseEntry->Modifier & ignoreMods,
 			  tmp_win->w,
 			  True, ButtonPressMask | ButtonReleaseMask,
 			  GrabModeAsync, GrabModeAsync, None,
@@ -836,19 +840,19 @@
 	      if(MouseEntry->Modifier != AnyModifier)
 		{
 		  XGrabButton(dpy, 1,
-			      (MouseEntry->Modifier | LockMask),
+			      (MouseEntry->Modifier & ignoreMods),
 			      tmp_win->w,
 			      True, ButtonPressMask | ButtonReleaseMask,
 			      GrabModeAsync, GrabModeAsync, None,
 			      Scr.FvwmCursors[DEFAULT]);
 		  XGrabButton(dpy, 2,
-			      (MouseEntry->Modifier | LockMask),
+			      (MouseEntry->Modifier & ignoreMods),
 			      tmp_win->w,
 			      True, ButtonPressMask | ButtonReleaseMask,
 			      GrabModeAsync, GrabModeAsync, None,
 			      Scr.FvwmCursors[DEFAULT]);
 		  XGrabButton(dpy, 3,
-			      (MouseEntry->Modifier | LockMask),
+			      (MouseEntry->Modifier & ignoreMods),
 			      tmp_win->w,
 			      True, ButtonPressMask | ButtonReleaseMask,
 			      GrabModeAsync, GrabModeAsync, None,
@@ -882,7 +886,7 @@
 		   GrabModeAsync, GrabModeAsync);
 	  if(tmp->Modifier != AnyModifier)
 	    {
-	      XGrabKey(dpy, tmp->Button_Key, tmp->Modifier|LockMask,
+	      XGrabKey(dpy, tmp->Button_Key, tmp->Modifier & ignoreMods,
 		       tmp_win->frame, True,
 		       GrabModeAsync, GrabModeAsync);
 	    }

diff -u fvwm/events.c.224 fvwm/events.c
--- fvwm/events.c.224	Sat Oct  2 18:28:41 1999
+++ fvwm/events.c	Sat Apr 22 23:53:49 2000
@@ -68,6 +68,9 @@
 			  Mod2Mask| Mod3Mask| Mod4Mask| Mod5Mask);
 extern int menuFromFrameOrWindowOrTitlebar;
 
+/* 2000-04-21 huver: ignore keyboard lock keys */
+extern unsigned int ignoreMods;
+
 extern Boolean debugging;
 
 int Context = C_NO_CONTEXT;	/* current button press context */
@@ -379,6 +382,9 @@
 
   DBUG("HandleKeyPress","Routine Entered");
 
+  /* 2000-04-21 huver: ignore lock keys when deciding if a hot-key cmd */
+  modifier &= ignoreMods;
+
   Context = GetContext(Tmp_win,&Event, &PressedW);
   PressedW = None;
 
@@ -391,7 +397,11 @@
   for (key = Scr.AllBindings; key != NULL; key = key->NextBinding)
     {
       if ((key->Button_Key == Event.xkey.keycode) &&
+/* 2000-04-21 huver: why the special interest in
+ * caps-lock alone and nothing else?
 	  ((key->Modifier == (modifier&(~LockMask)))||
+*/
+	  ((key->Modifier == modifier)||
 	   (key->Modifier == AnyModifier)) &&
 	  (key->Context & Context)&&
 	  (key->IsMouse == 0))
@@ -1080,13 +1090,17 @@
   Binding *MouseEntry;
   Window x;
   int LocalContext;
+  unsigned int btnmask =
+   (ControlMask|Mod1Mask|Mod2Mask|Mod3Mask|Mod4Mask|Mod5Mask);
+
+  /* 2000-04-21 huver: ignore keyboard lock keys */
+  btnmask &= ignoreMods;
 
   DBUG("HandleButtonPress","Routine Entered");
 
   /* click to focus stuff goes here */
   if((Tmp_win)&&(Tmp_win->flags & ClickToFocus)&&(Tmp_win != Scr.Ungrabbed) &&
-     ((Event.xbutton.state&
-       (ControlMask|Mod1Mask|Mod2Mask|Mod3Mask|Mod4Mask|Mod5Mask)) == 0))
+     ((Event.xbutton.state&btnmask) == 0))
   {
     SetFocus(Tmp_win->w,Tmp_win,1);
 /* #ifdef CLICKY_MODE_1 */
@@ -1120,8 +1134,7 @@
           Scr.MouseFocusClickRaises)
   {
     if (Tmp_win != Scr.LastWindowRaised &&
-        (Event.xbutton.state &
-         (ControlMask|Mod1Mask|Mod2Mask|Mod3Mask|Mod4Mask|Mod5Mask)) == 0 &&
+        (Event.xbutton.state & btnmask) == 0 &&
         GetContext(Tmp_win,&Event, &PressedW) == C_WINDOW)
     {
       RaiseWindow(Tmp_win);
@@ -1151,6 +1164,10 @@
    */
 
   modifier = (Event.xbutton.state & mods_used);
+
+  /* 2000-04-21 huver: ignore keyboard lock keys */
+  modifier &= ignoreMods;
+
   /* need to search for an appropriate mouse binding */
   for (MouseEntry = Scr.AllBindings; MouseEntry != NULL;
        MouseEntry= MouseEntry->NextBinding)
@@ -1159,7 +1176,7 @@
         (MouseEntry->Button_Key == 0))&&
        (MouseEntry->Context & Context)&&
        ((MouseEntry->Modifier == AnyModifier)||
-        (MouseEntry->Modifier == (modifier& (~LockMask))))&&
+        (MouseEntry->Modifier == modifier))&&
        (MouseEntry->IsMouse == 1))
     {
       /* got a match, now process it */
========================================================================
--
Visit the official FVWM web page at <URL:http://www.fvwm.org/>.
To unsubscribe from the list, send "unsubscribe fvwm-workers" in the
body of a message to [email-masked].
To report problems, send mail to [email-masked]

---

From: Michael Han <[email-masked]>
Date: Sun, 23 Apr 2000 14:06:11 -0700

Previously from [email-masked]
>oversteps by grabbing buttons and pointer/key when only the CapsLock

Thanks. Err, have you looked at the IgnoreModifiers command in the 2.3
series betas? I haven't compared your work to it, but AFAIK they
accomplish the same goal.
-- 
[email-masked]                         http://www.best.com/~mikehan/
coffee achiever                              San Francisco, California
Avoid cliches like the plague
--
Visit the official FVWM web page at <URL:http://www.fvwm.org/>.
To unsubscribe from the list, send "unsubscribe fvwm-workers" in the
body of a message to [email-masked].
To report problems, send mail to [email-masked]