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