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
[email protected]
http://lists.easysw.com/mailman/listinfo/fltk