discuss-gnustep
[Top][All Lists]
Advanced

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

Re: SHIFT keys on X11


From: Fred Kiefer
Subject: Re: SHIFT keys on X11
Date: Mon, 08 May 2006 14:57:54 +0200
User-agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.7.13) Gecko/20060411

Hi Stephane,

most of what you write makes sense to me, but what do you need this
static variable shiftPressed for? My impression is that this will get
you into trouble. If the shift key gets pressed or released while
another application has the focus, your counter will get out of step.
Why cann't you make the decision, if the eventflags should include
NSShiftKeyMask, just in the state of the keyboard and on the fact, if
the shift key was pressed in this event?

I am suggesting something similar to:

  if (keysym_is_X_modifier (keysym))
    {
    switch (keysym)
      {
      case XK_Shift_L:
      case XK_Shift_R:
        if(xEvent->xkey.type==KeyPress)
          {
            eventFlags|= NSShiftKeyMask;
          }
        else
          {
            // KeyRelease
            eventFlags&= ~NSShiftKeyMask;
          }
      default:
        break;
      }
      eventType = NSFlagsChanged;
    }

(With the correct GNUstep indentation of course)
Could you please try if this code wors for you, or if you experiance any
problems with it.

Cheers
Fred


Stéphane Goujet wrote:
> Hello,
> 
> I was about to post the solution of my problem with [NSEvent isARepeat],
> but now I have a problem with the SHIFT modifier key.
> 
>   In a NSView, I have :
> 
> ------------------------------------------------
> -(void) flagsChanged:(NSEvent *) event {
>   if(([event modifierFlags]&NSShiftKeyMask)==NSShiftKeyMask) {
>     NSLog(@"SHIFT ON\n");
>   } else {
>     NSLog(@"SHIFT OFF\n");
>   }
> }
> ------------------------------------------------
> 
>   When I press the SHIFT key and then release it, on Cocoa, I get the
> expected behaviour :
> SHIFT ON
> SHIFT OFF
> 
>   But on GNUstep/linux/X11, I get :
> SHIFT OFF
> SHIFT ON
> 
>   The reason of it is explained in back/Source/x11/XGServerEvent.m :
> 
> In the function process_key_event() :
> 
> ------------------------------------------------
>   /* Process modifiers */
>   eventFlags = process_modifier_flags (xEvent->xkey.state);
> 
>   /* Add NSNumericPadKeyMask if the key is in the KeyPad */
>   if (IsKeypadKey (keysym))
>     eventFlags = eventFlags | NSNumericPadKeyMask;
> 
>   NSDebugLLog (@"NSKeyEvent", @"keysym=%d, keyCode=%d flags=%d
> (state=%d)",
>           keysym, keyCode, eventFlags, ((XKeyEvent *)xEvent)->state);
> 
>   /* Add NSFunctionKeyMask if the key is a function or a misc function key
> */
>   /* We prefer not to do this and do it manually in process_char
>      because X's idea of what is a function key seems to be different
>      from OPENSTEP's one */
>   /* if (IsFunctionKey (keysym) || IsMiscFunctionKey (keysym))
>        eventFlags = eventFlags | NSFunctionKeyMask; */
> 
>   /* First, check to see if the key event if a Shift, NumLock or
>      CapsLock or ShiftLock keypress/keyrelease.  If it is, then use a
>      NSFlagsChanged event type.  This will generate a NSFlagsChanged
>      event each time you press/release a shift key, even if the flags
>      haven't actually changed.  I don't see this as a problem - if we
>      didn't, the shift keypress/keyrelease event would never be
>      notified to the application.
> 
>      NB - to know if shift was pressed, we need to check the X keysym
>      - it doesn't work to compare the X modifier flags of this
>      keypress X event with the ones of the previous one, because when
>      you press Shift, the X shift keypress event has the *same* X
>      modifiers flags as the X keypress event before it - only
>      keypresses coming *after* the shift keypress will get a different
>      X modifier mask.  */
> 
>   if (keysym_is_X_modifier (keysym))
>     {
>       eventType = NSFlagsChanged;
>     }
> ------------------------------------------------
> 
>   The process_modifier_flags() function is as follows :
> 
> ------------------------------------------------
> // process_modifier_flags() determines which modifier keys (Command,
> Control,
> // Shift,  and so forth) were held down while the event occured.
> static unsigned int
> process_modifier_flags(unsigned int state)
> {
>   unsigned int eventModifierFlags = 0;
> 
>   if (state & ShiftMask)
>     eventModifierFlags = eventModifierFlags | NSShiftKeyMask;
> 
>   if (state & LockMask)
>     eventModifierFlags = eventModifierFlags | NSAlphaShiftKeyMask;
> 
>   if (_control_pressed != 0)
>     eventModifierFlags = eventModifierFlags | NSControlKeyMask;
> 
>   if (_command_pressed != 0)
>     eventModifierFlags = eventModifierFlags | NSCommandKeyMask;
> 
>   if (_alt_pressed != 0)
>     eventModifierFlags = eventModifierFlags | NSAlternateKeyMask;
> 
>   // Other modifiers ignored for now.
> 
>   return eventModifierFlags;
> }
> ------------------------------------------------
> 
> and the function keysym_is_X_modifier() is :
> 
> ------------------------------------------------
> static BOOL
> keysym_is_X_modifier (KeySym keysym)
> {
>   switch (keysym)
>     {
>     case XK_Num_Lock:
>     case XK_Shift_L:
>     case XK_Shift_R:
>     case XK_Caps_Lock:
>     case XK_Shift_Lock:
>       return YES;
> 
>     default:
>       return NO;
>     }
> }
> ------------------------------------------------
> 
> 
>   xEvent->xkey.state does not get updated when one presses the SHIFT key
> but later, so it is updated when one releases that key, which causes the
> "inverted" behaviour.
>   Nevertheless, the needed information is available through the keysym,
> 
>   I made the following Q&D fix in process_key_event:
> 
> I added the variable
> 
> static unsigned shiftPressed=0;
> 
> and I replaced
> ------------------------------------------------
>   if (keysym_is_X_modifier (keysym))
>     {
>       eventType = NSFlagsChanged;
>     }
> ------------------------------------------------
> by
> ------------------------------------------------
>   if (keysym_is_X_modifier (keysym))
>     {
>     switch (keysym)
>       {
>       case XK_Shift_L:
>       case XK_Shift_R:
>         if(xEvent->xkey.type==KeyPress) {
>           shiftpressed++;
>         } else { // KeyRelease
>           shiftpressed--;
>         }
>         if(shiftpressed) {
>           eventFlags|= NSShiftKeyMask;
>         } else {
>           eventFlags&= ~NSShiftKeyMask;
>         }
>       default:
>         break;
>       }
>       eventType = NSFlagsChanged;
>     }
> ------------------------------------------------
> 
>  so that eventFlags (which will be available as [NSEvent modifierFlags])
> reflect the real position of the SHIFT key.
> 
>   Do you see any bad side-effect of this change ?
> 
> Goodbye,
>          Stéphane.
> 
> 
> _______________________________________________
> Discuss-gnustep mailing list
> Discuss-gnustep@gnu.org
> http://lists.gnu.org/mailman/listinfo/discuss-gnustep
> 
> 





reply via email to

[Prev in Thread] Current Thread [Next in Thread]