On 04/11/13 02:18, MacArthur, Ian (Selex ES, UK) wrote:
>>      If I understand correctly, the capslock state info is correct during
>>      regular keypresses, just not when the capslock key is hit.
> 
> Yes - in all the tests I tried, the Caps Lock state was always "correct"
> during (and after) regular key presses.

        Yes.

> However, any attempt to discern the Caps Lock state immediately after
> the Caps Lock key was pressed / released a few times, with no other
> key pressed since, was "unreliable".

        Right, though this seems to be specific to your VM.

        Originally I thought the behavior was random, but looking closer,
        it's actually predictable and reliable (just not what I'd expect).

        Digging deeper, I found that the behavior across all versions of X
        I currently have access to (Irix/redhat9/centos5.6) is /consistent/
        and /predictable/ across all of them for this, with both X11 and FLTK 
code.

        I rewrote the two programs (see below) to show clearer output,
        including some fflush()s so that they would pipe correctly through 
grep(1).

        When capslock is toggled, the state info in the xevent and 
Fl::event_state()
        for the CapsLock key Press/Release and FL_PUSH/FL_RELEASE events is:

                KeyPress: what the state was BEFORE the key was pressed
                KeyRelease event: state is *always* 1.

        So the reliable info is on KeyPress, it tells you what the state of 
capslock
        WAS, and not what it will become.

        Ditto for FLTK.

        So if I pipe both programs thru "grep Press", I see the capslock state 
flag toggle
        "reliably", the state being what the key WAS before the key was hit, no 
matter how
        fast I toggle the key (And if I "grep Release", the flag is always "on")

        Here's the output of the below "X11" and "FLTK" programs piped through
        "grep Press" while I toggle capslock:

$ ./test-capslock-x11 | grep Press
X11   Press: off
X11   Press: on
X11   Press: off
X11   Press: on
X11   Press: off
X11   Press: on
..
$ ./test-capslock-fltk | grep Press
FLTK   Press: off
FLTK   Press: on
FLTK   Press: off
FLTK   Press: on
FLTK   Press: off
FLTK   Press: on

        Consistent and reliable behavior.

        I guess we should see how Win32 and OSX behave, and if they're 
"reliable"
        as well, we should either:

            1) Document the OS specific behavior, whether different or same, 
and leave the code alone
            2) Pick one behavior, and modify the code to enforce it, and 
document it

        In a perfect world I'd say (2), though if we start fiddling around with 
the
        FLTK event structure's state info, we might be asking for trouble, not 
sure..
        at very least we could do (1) for the short term.

        Anyway, here's the two test apps, X11 and FLTK, which basically do the
        exact same thing, but with clearer messages that are grep(1) friendly:

--- snip: start 
------------------------------------------------------------------------
//
// X11 CAPSLOCK TEST
// Slightly modified X windows hello world
//     ref: http://www.cuillin.demon.co.uk/nazz/trivia/hw/hw_c.html
// compile: g++ test-capslock-x11.c -o test-capslock-x11 -lXtst -lX11 -lXext

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <X11/Xlib.h>
#include <X11/Xutil.h>

int main(int argc, char *argv[]) {
    Display    *dpy;            /* X server connection */
    Window      win;            /* Window ID */
    XEvent      event;          /* Event received */

    // OPEN DISPLAY
    if ((dpy = XOpenDisplay(NULL)) == NULL) {
        fprintf(stderr, "%s: can't open %s\n", argv[0], XDisplayName(NULL));
        exit(1);
    }

    // CREATE WINDOW, SELECT EVENTS WE WANT, MAP WINDOW
    win = XCreateSimpleWindow(dpy, DefaultRootWindow(dpy),      // create 
500x500 window
                              50,50,500,500,                    // x,y,w,h
                              0,                                // border width
                              0,0);                             // border 
color, bg color
    XSelectInput(dpy, win, KeyPressMask|KeyReleaseMask);        // select input 
events we want
    XMapWindow(dpy, win);                                       // map window

    // EVENT LOOP
    while (1) {
        XNextEvent(dpy, &event);                                // get the event
        switch ( event.type ) {                                 // event 
received?
           case KeyPress:
           case KeyRelease: {
               const char *emsg = (event.type==KeyPress) ? "  Press" : 
"Release";
               const char *lmsg = (event.xkey.state&2) ? "on" : "off";
               printf("X11 %s: %s\n", emsg, lmsg); fflush(stdout);
               break;
           }
           default:
               fprintf(stderr, "* Ignored event '%d'\n", (int)event.type);
               break;
        }
    }
    return(0);
}
--- snip:end 
------------------------------------------------------------------------


--- snip:start 
------------------------------------------------------------------------
//
// FLTK CAPSLOCK TEST
// compile: fltk-config --compile test-capslock-fltk.cxx
//
#include <stdio.h>
#include <FL/Fl.H>
#include <FL/Fl_Window.H>

class MyWindow : public Fl_Window {
public:
     MyWindow(int W,int H) : Fl_Window(W,H) { }
     int handle(int e) {
         switch (e) {
             case FL_KEYDOWN:
             case FL_KEYUP: {
                 const char *emsg = (e==FL_KEYDOWN) ? "  Press" : "Release";
                 const char *lmsg = (Fl::event_state()&FL_CAPS_LOCK)?"on":"off";
                 printf("FLTK %s: %s\n", emsg, lmsg); fflush(stdout);
                 break;
             }
         }
         return(Fl_Window::handle(e));
     }
};
int main() {
    MyWindow *win = new MyWindow(500,500);
    win->show();
    return(Fl::run());
}
--- snip:end 
------------------------------------------------------------------------
_______________________________________________
fltk mailing list
fltk@easysw.com
http://lists.easysw.com/mailman/listinfo/fltk

Reply via email to