Subject: patch: selecting when alt is released in menus

From: Dominik Vogt <[email-masked]>
Date: Fri, 28 Jan 2000 15:26:23 +0100

I've made a patch against current CVS.  It contains the new
MenuStyle 'SelectOnRelease'.  It takes a key name as an
argument.  Releasing this key in a menu the triggers the
current item:

  Key Tab A M WindowList
  MenuStyle WindowList SelectOnRelease Meta_L

I won't apply this patch unless these conditions are met
(remember, we're in feature freeze):

 1) I get at least two votes to commit the patch and none
    against it.
 2) Someone checks the patch and confirms that it's not
    doing something stupid.

Bye

Dominik ^_^

--
Dominik Vogt, [email-masked]
Reply-To: [email-masked]
--- ChangeLog.orig	Fri Jan 28 14:23:40 2000
+++ ./ChangeLog	Fri Jan 28 15:10:04 2000
@@ -1,5 +1,18 @@
 2000-01-28  Dominik Vogt  <[email-masked]>
 
+	* fvwm/menus.h:
+	* libs/Bindings.c (FvwmStringToKeysym):
+	* fvwm/bindings.c (ParseBinding):
+	* fvwm/icccm2.c (SetupICCCM2):
+	* fvwm/fvwm.h (NO_FOCUS_WIN_MENU_EVMASK):
+	* fvwm/fvwm.c (main):
+	* fvwm/menus.c (do_menu):
+	(menuShortcuts):
+	(MenuInteraction):
+	(NewMenuStyle):
+	new menu style SelectOnRelease to better emulate Alt-Tab
+	new library function FvwmStringToKeysym
+
 	* fvwm/add_window.c (setup_style_and_decor):
 	* fvwm/style.c (check_window_style_change):
 	fixed core dump w/ ol_decor and noicontitle
--- fvwm/bindings.c.orig	Fri Jan 28 14:35:39 2000
+++ fvwm/bindings.c	Fri Jan 28 14:43:59 2000
@@ -185,30 +185,15 @@
     fvwm_msg(WARN,"ParseBinding","Illegal modifier in line %s", tline);
 
   if (type == KEY_BINDING)
-    {
-      /*
-       * Don't let a 0 keycode go through, since that means AnyKey to the
-       * XGrabKey call.
-       */
-      keysym = XStringToKeysym(key);
-      if (keysym == NoSymbol)
-      {
-        char c = 'X';
-        char d = 'X';
-
-        /* If the key name is in the form '<letter><digits>...' it's probably
-         * something like 'f10'. Convert the letter to upper case and try
-         * again. */
-        sscanf(key, "%c%c", &c, &d);
-        if (islower(c) && isdigit(d))
-        {
-          key[0] = toupper(key[0]);
-          keysym = XStringToKeysym(key);
-        }
-      }
-      if (keysym == NoSymbol || XKeysymToKeycode(dpy, keysym) == 0)
-        return 0;
-    }
+  {
+    keysym = FvwmStringToKeysym(dpy, key);
+    /*
+     * Don't let a 0 keycode go through, since that means AnyKey to the
+     * XGrabKey call.
+     */
+    if (keysym == 0)
+      return 0;
+  }
 
   /*
   ** strip leading whitespace from action if necessary
--- fvwm/fvwm2.1.orig	Fri Jan 28 14:16:25 2000
+++ fvwm/fvwm2.1	Fri Jan 28 15:21:33 2000
@@ -818,10 +818,10 @@
 AddToMenu Utilities Tools Title top
 .EE
 
-All text up to the first TAB in the menu label is aligned to the
-left side of the menu, all text right of the first TAB is aligned
+All text up to the first Tab in the menu label is aligned to the
+left side of the menu, all text right of the first Tab is aligned
 to the left in a second column and all text thereafter is placed
-right aligned in the third column. All other TABs are replaced by spaces.
+right aligned in the third column. All other Tabs are replaced by spaces.
 Note that you can change this format with the \fIMenuStyle\fP command
 (\fIItemFormat\fP) option.
 
@@ -1136,6 +1136,7 @@
 PopupAsRootMenu / PopupAsSubmenu,
 RemoveSubmenus / HoldSubmenus,
 SubmenusRight / SubmenusLeft,
+SelectOnRelease,
 ItemFormat,
 VerticalItemSpacing,
 VerticalTitleSpacing,
@@ -1366,6 +1367,12 @@
 You will probably want to use \fIHoldSubmenus\fP if you are using the
 \fIPopupDelayed\fP style.
 
+\fISelectOnRelease\fP takes an optional key name as an argument.  If the
+given key is release in a menu using this style, the current menu item
+is selected.  This is intended to navigate through the window list with
+Alt-Tab.  The key name is a standard X11 key name as defined in
+/usr/include/X11/keysymdef.h, with the leading XK_ omitted.
+
 \fIItemFormat\fP takes a special string as its argument that determines
 the layout of the menu items. Think of the format string as if it were
 a menu item. All you have to do is tell fvwm where to place the different
@@ -2155,9 +2162,13 @@
 these defaults do not suit you.
 
 The window list menu uses the 'WindowList' menu style if it is
-defines (see \fIMenuStyle\fP command).  Otherwise the default
+defined (see \fIMenuStyle\fP command).  Otherwise the default
 menu style is used.  To switch back to the default menu style,
 issue the command 'DestroyMenuStyle WindowList'.
+
+.EX
+MenuStyle WindowList SelectOnRelease Meta_L
+.EE
 
 The \fIconditions\fP can be used to exclude certain windows from
 the window list.  Please refer to the \fICurrent\fP command for
--- fvwm/fvwm.c.orig	Fri Jan 28 14:15:26 2000
+++ fvwm/fvwm.c	Fri Jan 28 14:18:16 2000
@@ -536,7 +536,7 @@
      windows have it */
   /* do this before any RC parsing as some GC's are created from this window
    * rather than the root window */
-  attributes.event_mask = KeyPressMask|FocusChangeMask;
+  attributes.event_mask = NO_FOCUS_WIN_EVMASK;
   attributes.override_redirect = True;
   attributes.colormap = Pcmap;
   attributes.background_pixmap = None;
--- fvwm/fvwm.h.orig	Fri Jan 28 14:15:14 2000
+++ fvwm/fvwm.h	Fri Jan 28 14:30:10 2000
@@ -82,6 +82,9 @@
 #define WithdrawnState 0
 #endif
 
+#define NO_FOCUS_WIN_EVMASK KeyPressMask|FocusChangeMask
+#define NO_FOCUS_WIN_MENU_EVMASK KeyPressMask|KeyReleaseMask|FocusChangeMask
+
 /* the maximum number of mouse buttons fvwm knows about */
 /* don't think that upping this to 5 will make everything
  * hunky-dory with 5 button mouses */
--- fvwm/icccm2.c.orig	Fri Jan 28 14:15:03 2000
+++ fvwm/icccm2.c	Fri Jan 28 14:16:49 2000
@@ -120,7 +120,7 @@
   }
 
   /* restore NoFocusWin event mask */
-  attr.event_mask = KeyPressMask|FocusChangeMask;
+  attr.event_mask = NO_FOCUS_WIN_EVMASK;
   XChangeWindowAttributes (dpy, Scr.NoFocusWin, CWEventMask, &attr);
 }
 
--- fvwm/menus.c.orig	Fri Jan 28 14:16:09 2000
+++ fvwm/menus.c	Fri Jan 28 15:01:24 2000
@@ -771,7 +771,9 @@
   }
   if (!fFailedPopup)
   {
+    XSelectInput(dpy, Scr.NoFocusWin, NO_FOCUS_WIN_MENU_EVMASK);
     MenuInteraction(pmp, pmret, &dkp, &do_warp_to_title);
+    XSelectInput(dpy, Scr.NoFocusWin, NO_FOCUS_WIN_EVMASK);
   }
   else
   {
@@ -856,6 +858,14 @@
   int items_to_move;
   Bool fSkipSection = False;
 
+  if (event->type == KeyRelease)
+  {
+    /* This function is only called with a KeyRelease event if the user released
+     * the 'select' key (s)he configured. */
+    pmret->rc = MENU_SELECTED;
+    return;
+  }
+
   /* handle double-keypress */
   if (pdkp->timestamp &&
       lastTimestamp - pdkp->timestamp < Menus.DoubleClickTime &&
@@ -1406,7 +1416,8 @@
 	  while (!XPending(dpy) ||
 		 !XCheckMaskEvent(
 		   dpy, ButtonPressMask|ButtonReleaseMask|ExposureMask|
-		   KeyPressMask|VisibilityChangeMask|ButtonMotionMask,
+		   KeyReleaseMask|KeyPressMask|VisibilityChangeMask|
+		   ButtonMotionMask,
 		   &Event))
 	  {
 	    usleep(10000 /* 10 ms*/);
@@ -1428,7 +1439,8 @@
 	  /* block until there is an event */
 	  XMaskEvent(dpy,
 		     ButtonPressMask|ButtonReleaseMask|ExposureMask |
-		     KeyPressMask|VisibilityChangeMask|ButtonMotionMask,
+		     KeyReleaseMask|KeyPressMask|VisibilityChangeMask|
+		     ButtonMotionMask,
 		     &Event);
 	  flags.is_popped_up_by_timeout = False;
 	}
@@ -1505,6 +1517,11 @@
     case VisibilityNotify:
       continue;
 
+    case KeyRelease:
+      if (Event.xkey.keycode != MST_SELECT_ON_RELEASE_KEY(pmp->menu))
+	continue;
+      /* fall through to KeyPress */
+
     case KeyPress:
       /* Handle a key press events to allow mouseless operation */
       flags.is_key_press = True;
@@ -5470,6 +5487,7 @@
     "VerticalItemSpacing",
     "VerticalTitleSpacing",
     "MenuColorset", "ActiveColorset", "GreyedColorset",
+    "SelectOnRelease",
     NULL
   };
   return GetTokenIndex(option, optlist, 0, NULL);
@@ -5492,6 +5510,7 @@
   int n;
   FvwmFont new_font;
   int i;
+  KeyCode keycode;
 
   action = GetNextToken(action, &name);
   if (!name)
@@ -5979,6 +5998,14 @@
 	AllocColorset(*val);
       }
       has_gc_changed = True;
+      break;
+    case 49: /* SelectOnRelease */
+      keycode = 0;
+      if (arg1)
+      {
+	keycode = XKeysymToKeycode(dpy, FvwmStringToKeysym(dpy, arg1));
+      }
+      ST_SELECT_ON_RELEASE_KEY(tmpms) = keycode;
       break;
 
 #if 0
--- fvwm/menus.h.orig	Fri Jan 28 14:25:31 2000
+++ fvwm/menus.h	Fri Jan 28 14:51:26 2000
@@ -97,6 +97,7 @@
   int PopupOffsetPercent;
   int PopupOffsetAdd;
   char *item_format;
+  KeyCode select_on_release_key;
 } MenuFeel;

@@ -292,6 +293,8 @@
 #define MST_POPUP_OFFSET_ADD(m)       ((m)->s->ms->feel.PopupOffsetAdd)
 #define ST_ITEM_FORMAT(s)             ((s)->feel.item_format)
 #define MST_ITEM_FORMAT(m)            ((m)->s->ms->feel.item_format)
+#define ST_SELECT_ON_RELEASE_KEY(s)   ((s)->feel.select_on_release_key)
+#define MST_SELECT_ON_RELEASE_KEY(m)  ((m)->s->ms->feel.select_on_release_key)

--- libs/Bindings.c.orig	Fri Jan 28 14:35:48 2000
+++ libs/Bindings.c	Fri Jan 28 14:54:27 2000
@@ -568,3 +568,39 @@
   XSync(dpy, 0);
   return;
 }
+
+/***********************************************************************
+ *
+ *  Procedure:
+ *	FvwmStringToKeysym
+ *
+ *  Like XStringToKeysym, but allows some typos and does some additional
+ *  error checking.
+ *
+ ***********************************************************************/
+KeySym FvwmStringToKeysym(Display *dpy, char *key)
+{
+  KeySym keysym;
+
+  keysym = XStringToKeysym(key);
+  if (keysym == NoSymbol)
+  {
+    char c = 'X';
+    char d = 'X';
+
+    /* If the key name is in the form '<letter><digits>...' it's probably
+     * something like 'f10'. Convert the letter to upper case and try
+     * again. */
+    sscanf(key, "%c%c", &c, &d);
+    if (islower(c) && isdigit(d))
+    {
+      d = key[0];
+      key[0] = toupper(c);
+      keysym = XStringToKeysym(key);
+      key[0] = d;
+    }
+  }
+  if (keysym == NoSymbol || XKeysymToKeycode(dpy, keysym) == 0)
+    return 0;
+  return keysym;
+}
--- libs/fvwmlib.h.orig	Fri Jan 28 14:36:28 2000
+++ libs/fvwmlib.h	Fri Jan 28 14:54:44 2000
@@ -406,6 +406,7 @@
 				 unsigned int contexts,
 				 unsigned int dead_modifiers,
 				 Cursor cursor, Bool fGrab);
+KeySym FvwmStringToKeysym(Display *dpy, char *key);
 
 /***********************************************************************
  * Target.c
--- NEWS.orig	Fri Jan 28 15:18:52 2000
+++ ./NEWS	Fri Jan 28 15:18:49 2000
@@ -3,6 +3,8 @@
 
 Changes in beta release 2.3.14 (not released yet)
 
+* New MenuStyle option SelectOnRelease to better emulate Alt-Tab.
+
 Changes in beta release 2.3.13 (January 2000)
 
 * New FvwmTheme option 'Transparent'.

---

From: Dan Espen <[email-masked]>
Date: Fri, 28 Jan 2000 10:11:10 -0500

>  2) Someone checks the patch and confirms that it's not

I haven't checked, it, just read it.

> +      keysym = XStringToKeysym(key);

Why did this second assignment become necessary, I don't see it
in the original code.

> +  if (keysym == NoSymbol || XKeysymToKeycode(dpy, keysym) == 0)

Its a pretty important change...

I'll try to get some time to try it out.
It would make sense to also change the builtin behavior.

--
Dan Espen
444 Hoes Lane  Room RRC 1C-214           E-mail: [email-masked]
Piscataway, NJ 08854                     Phone: (732) 699-5570
--
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: Dominik Vogt <[email-masked]>
Date: Fri, 28 Jan 2000 17:30:09 +0100

> Why did this second assignment become necessary, I don't see it

Since the function was moved to the library we can't know
if the caller of the function still needs the key name.

> It would make sense to also change the builtin behavior.

Definitely.  There is one potential problem:  Since only
the WindowList menu uses this style by default we have
to use 'MenuStyle WindowList ...'.  But then the WindowList
won't use the default menu style anymore.

Bye

Dominik ^_^

---

From: Dominik Vogt <[email-masked]>
Date: Sat, 29 Jan 2000 15:01:59 +0100

>  2) Someone checks the patch and confirms that it's not

Althought I don't have the necessary votes yet I'm going
to commit this patch for now.  The reason is that I'm
doing some clean up that will conflict with the patch.
I'll remove the patch if I don't get the necessary votes.

Bye

Dominik ^_^

---

From: "Paul D. Smith" <[email-masked]>
Date: 30 Jan 2000 13:56:46 -0500

I vote "yay!"... I mean, "yea!" :)

-- 
-------------------------------------------------------------------------------
 Paul D. Smith <[email-masked]>         Network Management Development
 "Please remain calm...I may be mad, but I am a professional." --Mad Scientist
-------------------------------------------------------------------------------
   These are my opinions---Nortel Networks takes no responsibility for them.
--
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: Brad Giaccio <[email-masked]>
Date: Mon, 31 Jan 2000 08:41:00 -0500

> won't use the default menu style anymore.

Dominik,
I've played with what you put into CVS and it seems to work well.
I also ran it through purify and no problems there either.  So you've
got my vote.

Since you would no best is there no way to make menustyles inherit from
* or add a UseMenuStyle command.  If the answer is yes but no until 2.5
thats fine it was more out of curiosity than anything else

Brad
-- 
--- There are two kinds of knowledge, you either know the answer or
			you know where to find it
		      -Kane, Johnson, and anonymous
--
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: Dan Espen <[email-masked]>
Date: Mon, 31 Jan 2000 08:47:35 -0500

> thats fine it was more out of curiosity than anything else

I don't see the need for the built in WindowList and the menus to
share an appearance, they are logically distinct anyway.

---

From: Dominik Vogt <[email-masked]>
Date: Mon, 31 Jan 2000 15:16:48 +0100

> share an appearance, they are logically distinct anyway.

I agree that there's no real need, but it's a bit cumbersome
to define the whole menu style again.  There was a patch to
copy menu styles a while ago, but it simply copied malloc'ed
pointers and would have failed miserably if the copied styles
had been modified or deleted.  Overall it wouldn't be too hard
to code a 'CopyMenuStyle' command, but I think it's too risky
for 2.5.  Although we've made lots of changes in the recent
past, the really dangerous patches have been well tested.

Bye

Dominik ^_^

-- 
Dominik Vogt, Agilent Technologies, Dept. BVS
Herrenberger Str.130, 71034 Boeblingen, Germany
phone: 07031/464-4596, fax: 07031/464-3883, [email-masked]
--
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]