[sawfish] Keyboard layout switching support. * In 5-button mode, event's state is masked to drop the key group



commit ae9cfcee55c30a0971e16e8ea815fd9ddd7b52b6
Author: Teika kazura <teika lavabit com>
Date:   Sat Jul 3 13:18:19 2010 +0900

    Keyboard layout switching support.
    * In 5-button mode, event's state is masked to drop the key group, and
      lower 13 = 8 + 5 bits are taken. (8 for modifiers, 5 for buttons.)
      This fixes the bug that keyboard layout switching messed bindings.
    * 5-button is now a command line option, not any more the build-time option.

 configure.in  |   17 --------------
 man/news.texi |   28 +++++++++++++++++++++++
 man/sawfish.1 |    8 ++++--
 src/events.c  |    4 +++
 src/keys.c    |   68 ++++++++++++++++++++++++++++++++++++++------------------
 src/keys.h    |   25 ---------------------
 6 files changed, 83 insertions(+), 67 deletions(-)
---
diff --git a/configure.in b/configure.in
index 3330d65..213c913 100644
--- a/configure.in
+++ b/configure.in
@@ -273,19 +273,6 @@ if test "$with_gdk_pixbuf" = "no"; then
 			  ,AC_MSG_ERROR([cannot locate imlib1 library]))
 fi
 
-dnl Check wether to add 9 mouse buttons support
-
-AC_ARG_WITH(nine-mousebuttons,
-  [  --with-nine-mousebuttons  Add support for mouse-buttons 6 - 9
-  --without-nine-mousebuttons], [], [with_nine_mbtns=yes])
-
-if test "$with_nine_mbtns" = "yes"; then
-	AC_DEFINE(HAVE_NINE_MOUSEBUTTONS, 1, [Support for 9 Mouse Buttons])
-	MOUSE_BUTTONS="9"
-else
-	MOUSE_BUTTONS="5"
-fi
-
 dnl Check wether to install mo files
 
 AC_ARG_WITH(nls,
@@ -481,10 +468,6 @@ echo "
 
   == == == == == == == == == == == == ==
 
-  mouse:	$MOUSE_BUTTONS buttons supported
-
-  == == == == == == == == == == == == ==
-
   image loader:	$IMAGE_LOADER
 
   == == == == == == == == == == == == ==
diff --git a/man/news.texi b/man/news.texi
index 102d1be..7aa1b24 100644
--- a/man/news.texi
+++ b/man/news.texi
@@ -13,8 +13,33 @@ they occurred between. For more detailed information see the
 
 @itemize @bullet
 
+ item Notice
+
+Sawfish is claimed to support mouse buttons 1 - 9, but it is found
+that drag of buttons 6 - 8 may not work. The button 9 doesn't work at
+all, so we drop it.
+
+ item Build and Installation
+ itemize @minus
+ item Configuration option @code{--with-nine-mousebuttons} is dropped  *
+See the item ``Keyboard layout switching support'' below.
+ end itemize
+
 @item Bug Fixes
 @itemize @minus
+ item Keyboard layout switching support [Teika Kazura]
+
+Previously, when you switch the keyboard layout, or more correctly
+the keyboard ``group'', which is mainly for multilinguals, keyboard
+and mouse bindings get messed.
+
+Now, this can be prevented by passing a new commandline option
+ code{--5-buttons} at Sawfish invocation.
+
+By doing so, you won't be able to bind Sawfish commands to mouse
+buttons 6 - 8. This may be fixed in future, but not now because
+the current code for buttons 6 - 8 is hackish.
+
 @item Atom handling fix on 32-bit architecture. [Teika Kazura]
 
 Function @code{x-atom-name} now accepts all 32 bits. Previously only
@@ -36,6 +61,9 @@ let statements. [Jeremy Hankins]
 
 @item New Features
 @itemize @minus
+ item New command line option @code{--5-buttons} *
+See the item ``Keyboard layout switching support'' above.
+
 @item New frame parts @code{border-width} and @code{border-color}
 [Alexey I. Froloff]
 
diff --git a/man/sawfish.1 b/man/sawfish.1
index ff5bf88..59286ff 100644
--- a/man/sawfish.1
+++ b/man/sawfish.1
@@ -8,14 +8,14 @@ sawfish \(em Sawfish window manager.
 .PP
 Sawfish is a lisp-extensible window manager for X11. Its aim is to
 allow all areas of window management (decoration, manipulation) to be
-customized as far as is possible, yet still remain as fast or faster
-than existing window managers.
+customized as far as is possible, yet still remain as fast as existing
+window managers.
 .SH "OPTIONS"
 .IP "\fB\-\-disable-nls\fP" 10
 Disable internationalization of messages.
 .IP "\fBFILE\fP 	" 10
 Load the Lisp file \fIFILE\fR (from the
-cwd if possible, implies \fI\-\-batch\fR mode).
+cwd if possible, implies \fI\-\-batch\fR).
 .IP "\fB\-\-batch\fP 	" 10
 Batch mode: process options and exit.
 .IP "\fB\-\-interp\fP 	" 10
@@ -30,6 +30,8 @@ Print version details.
 Don't load rc or site-init files.
 .IP "\fB-q, \-\-quit\fP" 10
 Terminate the interpreter process.
+.IP "\fB-\-5-buttons\fP" 10
+Support keyboard layout switching, but drop mouse buttons 6 - 8 support.
 .SS Display Options
 .IP "\fB\-\-display=\fIDPY\fR\fP" 10
 Connect to X display \fIDPY\fR.
diff --git a/src/events.c b/src/events.c
index 8e9ed65..9b6a1db 100644
--- a/src/events.c
+++ b/src/events.c
@@ -35,8 +35,10 @@
 /* Lookup table of event handlers */
 void (*event_handlers[LASTEvent])(XEvent *ev);
 
+#ifdef DEBUG
 /* Map events to their names for debugging */
 static char *event_names[LASTEvent];
+#endif
 
 /* Map events to the mask selecting them */
 static long event_masks[LASTEvent];
@@ -1761,6 +1763,7 @@ events_init (void)
     event_handlers[CirculateNotify] = circulate_notify;
     event_handlers[MappingNotify] = mapping_notify;
 
+#ifdef DEBUG
     event_names[KeyPress] = "KeyPress";
     event_names[KeyRelease] = "KeyRelease";
     event_names[ButtonPress] = "ButtonPress";
@@ -1794,6 +1797,7 @@ events_init (void)
     event_names[ColormapNotify] = "ColormapNotify";
     event_names[ClientMessage] = "ClientMessage";
     event_names[MappingNotify] = "MappingNotify";
+#endif
 
     event_masks[KeyPress] = KeyPressMask;
     event_masks[KeyRelease] = KeyReleaseMask;
diff --git a/src/keys.c b/src/keys.c
index f7a859d..cb4ebf8 100644
--- a/src/keys.c
+++ b/src/keys.c
@@ -98,11 +98,12 @@ DEFSYM(super_keysyms, "super-keysyms");
 static void grab_keymap_event (repv km, long code, long mods, bool grab);
 static void grab_all_keylist_events (repv map, bool grab);
 
-#ifdef HAVE_NINE_MOUSEBUTTONS
+/* Button number support */
+static unsigned int ev_mod_button_mask;
+static unsigned int state_mask;
+static int button_num;
+
 static int all_buttons[9] = { Button1, Button2, Button3, Button4, Button5, Button6, Button7, Button8, Button9 };
-#else
-static int all_buttons[5] = { Button1, Button2, Button3, Button4, Button5 };
-#endif
 
 /*
   locks: currently LockMask, num_lock, and scroll_lock.
@@ -166,6 +167,7 @@ translate_event(unsigned long *code, unsigned long *mods, XEvent *xev)
 
     case KeyPress:
 	*mods = xev->xkey.state & ~all_lock_mask;
+	*mods &= state_mask;
 	if (xev->type == KeyRelease)
 	    *mods |= EV_MOD_RELEASE;
 	if(*mods & ShiftMask)
@@ -254,6 +256,7 @@ translate_event(unsigned long *code, unsigned long *mods, XEvent *xev)
 
     button:
 	*mods = xev->xbutton.state & ~all_lock_mask;
+	*mods &= state_mask;
 	*mods |= EV_TYPE_MOUSE;
 	switch(xev->xbutton.button)
 	{
@@ -272,7 +275,6 @@ translate_event(unsigned long *code, unsigned long *mods, XEvent *xev)
 	case Button5:
 	    *mods |= Button5Mask;
 	    break;
-#ifdef HAVE_NINE_MOUSEBUTTONS
 	case Button6:
 	    *mods |= Button6Mask;
 	    break;
@@ -285,7 +287,6 @@ translate_event(unsigned long *code, unsigned long *mods, XEvent *xev)
 	case Button9:
 	    *mods |= Button9Mask;
 	    break;
-#endif
 	}
 	ret = TRUE;
 	break;
@@ -293,6 +294,7 @@ translate_event(unsigned long *code, unsigned long *mods, XEvent *xev)
     case MotionNotify:
 	*code = EV_CODE_MOUSE_MOVE;
 	*mods = xev->xmotion.state & ~all_lock_mask;
+	*mods &= state_mask;
 	*mods |= EV_TYPE_MOUSE;
 	ret = TRUE;
 	break;
@@ -362,17 +364,15 @@ translate_event_to_x_button (repv ev, unsigned int *button, unsigned int *state)
 	    { Button3, Button3Mask },
 	    { Button4, Button4Mask },
 	    { Button5, Button5Mask },
-#ifdef HAVE_NINE_MOUSEBUTTONS
 	    { Button6, Button6Mask },
 	    { Button7, Button7Mask },
 	    { Button8, Button8Mask },
 	    { Button9, Button9Mask },
-#endif
 	    { 0, 0 }
 	};
 	int i;
 
-	for (i = 0; buttons[i].button != 0; i++)
+	for (i = 0; i < button_num  ; i++)
 	{
 	    if (mods & buttons[i].mask)
 	    {
@@ -692,12 +692,10 @@ static struct key_def default_mods[] = {
     { "Button3",  Button3Mask },
     { "Button4",  Button4Mask },
     { "Button5",  Button5Mask },
-#ifdef HAVE_NINE_MOUSEBUTTONS
     { "Button6",  Button6Mask },
     { "Button7",  Button7Mask },
     { "Button8",  Button8Mask },
     { "Button9",  Button9Mask },
-#endif
     { "Any",      EV_MOD_ANY },
     { "Release",  EV_MOD_RELEASE },
     { 0, 0 }
@@ -803,7 +801,7 @@ lookup_event(unsigned long *code, unsigned long *mods, char *desc)
 		*mods |= x->mods;
 		*code = x->code;
 		if ((x->mods == EV_TYPE_MOUSE)
-		    && (*mods & (EV_MOD_BUTTON_MASK | EV_MOD_ANY)) == 0)
+		    && (*mods & (ev_mod_button_mask | EV_MOD_ANY)) == 0)
 		{
 		    /* Button events must include at least one of the button
 		       modifiers (otherwise they can never be generated) */
@@ -1730,11 +1728,7 @@ grab_event (Window grab_win, repv ev)
 	    {
 		/* sawfish treats mouse buttons as modifiers, not as
 		   codes, so for us AnyModifier includes all buttons.. */
-#ifdef HAVE_NINE_MOUSEBUTTONS
-		for (i = 0; i < 9; i++)
-#else
-		for (i = 0; i < 5; i++)
-#endif
+		for (i = 0; i < button_num; i++)
 		{
 		    XGrabButton (dpy, all_buttons[i], AnyModifier,
 				 grab_win, False, POINTER_GRAB_EVENTS,
@@ -1786,12 +1780,10 @@ ungrab_event (Window grab_win, repv ev)
 	    }
 	    else
 	    {
-#ifdef HAVE_NINE_MOUSEBUTTONS
-		for (i = 0; i < 9; i++)
-#else
-		for (i = 0; i < 5; i++)
-#endif
+		for (i = 0; i < button_num; i++)
+		  {
 		    XUngrabButton (dpy, all_buttons[i], AnyModifier, grab_win);
+		  }
 	    }
 	}
     }
@@ -1889,9 +1881,41 @@ keymap_prop_change (Lisp_Window *w, repv prop, repv old, repv new)
 
 /* initialisation */
 
+static void button_num_init(void){
+  if(rep_get_option("--5-buttons", 0)){
+    button_num = 5;
+    ev_mod_button_mask = (Button1Mask | Button2Mask | Button3Mask \
+			  | Button4Mask | Button5Mask);
+    state_mask = (1 << 13) - 1;
+    {
+      /* delete Button6 - 9 entries from default_mods[] */
+      int i, j = 0, k;
+      char str[10];
+      for ( i = 6; i <= 9; i++){
+	snprintf(str, 8, "Button%d", i);
+	for (j = 0; default_mods[j].name != 0; j++){
+	  if ( strncmp(default_mods[j].name, str, 8) == 0){
+	    for( k = j; default_mods[k].name != 0; k++){
+	      default_mods[k] = default_mods[k + 1];
+	    }
+	  }
+	}
+      }
+    }
+  }else{
+    button_num = 9;
+    ev_mod_button_mask = (Button1Mask | Button2Mask | Button3Mask   \
+			  | Button4Mask | Button5Mask | Button6Mask \
+			  | Button7Mask | Button8Mask | Button9Mask);
+    state_mask = 0xffffffff;
+  }
+}
+
 void
 keys_init(void)
 {
+    button_num_init();
+
     repv tem;
 
     rep_INTERN_SPECIAL(global_keymap);
diff --git a/src/keys.h b/src/keys.h
index f9d7006..46eccfa 100644
--- a/src/keys.h
+++ b/src/keys.h
@@ -71,7 +71,6 @@ enum {
     EV_VIRT_MOD_MASK = 0x0ff00000
 };
 
-#ifdef HAVE_NINE_MOUSEBUTTONS
 /* Support for buttons 6, 7, 8 and 9.
 
    <X11/X.h> doesn't define these, even though XFree supports them.. */
@@ -104,30 +103,6 @@ enum {
 # define Button9Mask (1<<16)
 #endif
 
-#if !defined (Button6)
-# define EV_MOD_BUTTON_MASK (Button1Mask | Button2Mask | Button3Mask \
-			     | Button4Mask | Button5Mask)
-#elif !defined (Button7)
-# define EV_MOD_BUTTON_MASK (Button1Mask | Button2Mask | Button3Mask \
-			     | Button4Mask | Button5Mask | Button6Mask)
-#elif !defined (Button8)
-# define EV_MOD_BUTTON_MASK (Button1Mask | Button2Mask | Button3Mask \
-			     | Button4Mask | Button5Mask | Button6Mask \
-			     | Button7Mask)
-#elif !defined (Button9)
-# define EV_MOD_BUTTON_MASK (Button1Mask | Button2Mask | Button3Mask \
-			     | Button4Mask | Button5Mask | Button6Mask \
-                             | Button7Mask | Button8Mask)
-#else
-# define EV_MOD_BUTTON_MASK (Button1Mask | Button2Mask | Button3Mask \
-			     | Button4Mask | Button5Mask | Button6Mask \
-			     | Button7Mask | Button8Mask | Button9Mask)
-#endif
-#else
-# define EV_MOD_BUTTON_MASK (Button1Mask | Button2Mask | Button3Mask \
-			     | Button4Mask | Button5Mask)
-#endif
-
 /* In key maps, a `key' is (COMMAND . EVENT) */
 
 #define KEYP(v)		(rep_CONSP(v) && rep_CONSP(rep_CDR(v)))



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]