commit 3bcbb88ad5889e97e9255847e8a50b563b6eae3b
Author: Federico Mena Quintero <federico@gnome.org>
Date:   Tue Jan 10 14:56:59 2012 -0600

    bgo#457288 - update the tool's modifier state upon motion-notify to keep selection modes from getting stuck
    
    When 'both shift keys change the keyboard layout' is used in the desktop,
    releasing the Shift key may not produce a GDK_KEY_Shift_L keysym; instead
    it produces something weird like GDK_KEY_ISO_Prev_Group.  This causes
    the mode of selection tools to get stuck (in addition/subtraction/etc.)
    as we never get the key-release we expected for the Shift key.
    
    So, we check the modifier state again in the motion-notify handler.
    
    Signed-off-by: Federico Mena Quintero <federico@gnome.org>

diff --git a/app/display/gimpdisplayshell-tool-events.c b/app/display/gimpdisplayshell-tool-events.c
index bcf321e..fa242ab 100644
--- a/app/display/gimpdisplayshell-tool-events.c
+++ b/app/display/gimpdisplayshell-tool-events.c
@@ -924,6 +924,24 @@ gimp_display_shell_canvas_tool_events (GtkWidget        *canvas,
                   }
               }
           }
+	else
+	  {
+	    /* bgo#457288:  Due to the intricacies of keyboard maps in XKB, sometimes
+	     * the "both shift keys switch the keyboard layout" option causes the following
+	     * to happen.  You press Shift to toggle the mode of a selection tool (which we
+	     * catch as a GDK_KEY_PRESS of a GDK_KEY_Shift_L or whatever), but then
+	     * the GDK_KEY_RELEASE doesn't come in for the same keysym - instead we get
+	     * something weird like GDK_KEY_ISO_Prev_Group.  During *that* key-release event,
+	     * the event's state still contains a GDK_SHIFT_MASK, so we can't use the event's
+	     * state to figure out what actually changed.  So, we'll deal with the change in
+	     * event state right here, when the mouse moves but a button is not pressed.
+	     * This keeps the selection tools from getting stuck in a particular mode.
+	     */
+	    if (! gimp_image_is_empty (image))
+	      {
+		tool_manager_active_modifier_state_active (gimp, state, display);
+	      }
+	  }
 
         if (! (state &
                (GDK_BUTTON1_MASK | GDK_BUTTON2_MASK | GDK_BUTTON3_MASK)))
