On 05.04.2013 22:02, Howard Rubin wrote: > Thanks for the quick reply. Here's what I have now. It's reporting the > opposite of of the Caps Lock state. In other words, (Fl::event_state() & > FL_CAPS_LOCK) is zero when Caps Lock is on, and nonzero when it's off. > > Is that what you meant in your last message? > > I'm less than enthusiastic about displaying the 'Caps Lock is on' > message when the test in the code says it's off. > > Is there really no alternative?
Well, there should be a better way, but it looks like you found a bug or at least some inconsistency. I'll post two different modified test programs (derived from yours) that do unfortunately show inconsistent behavior on Windows and Linux on my test systems, i.e. Windows 7 and Linux Ubuntu 12.04 an a Virtualbox VM. Maybe someone can test it on a real Linux box and on Mac OS X ? Howard, what's your environment ? Here's #1 that shows more events and gives a clue how to handle the key, and it works well on Windows, but doesn't on my Linux VM: $ cat capslock.cxx #include <FL/Fl.H> #include <FL/Fl_Window.H> #include <FL/Fl_Button.H> #include <FL/Fl_Secret_Input.H> #include <FL/names.h> #include <iostream> class myWindow : public Fl_Window { public: myWindow(int x, int y, const char* l) : Fl_Window(x, y, l) { } virtual int handle(int event) { if (event == FL_FOCUS) { std::cout << "event = " << fl_eventnames[event] << " ... "; if (Fl::event_state() & FL_CAPS_LOCK) std::cout << "WARNING: CAPS LOCK is set"; std::cout << std::endl; return 1; } if ((event == FL_SHORTCUT || event == FL_KEYDOWN || event == FL_KEYUP) && Fl::event_key() == FL_Caps_Lock) { std::cout << "event = " << fl_eventnames[event] << " ... "; static int n = 0; if (Fl::event_state() & FL_CAPS_LOCK) { std::cout << "caps lock" << " " << ++n << std::endl; } else { std::cout << "caps unlock" << " " << ++n << std::endl << std::endl; } return 1; } else return Fl_Window::handle(event); } }; int main(int argc, char* argv[]) { myWindow* win = new myWindow(300, 200, ""); new Fl_Secret_Input(20, 20, 100, 20, ""); new Fl_Button(20, 120, 100, 20, "Test"); win->end(); win->show(); return Fl::run(); } // end of file Compilation and output on Windows: $ fltk-config --compile capslock.cxx && ./capslock.exe g++ -I/fltk/svn/fltk-1.3 -I/fltk/svn/fltk-1.3/png -I/fltk/svn/fltk-1.3/zlib -I/fltk/svn/fltk-1.3/jpeg -mwindows -DWIN32 -DUSE_OPENGL32 -D_LARGEFILE_SOURCE -D_LARGEFILE64_SOURCE -o 'capslock' 'capslock.cxx' -mwindows -static-libgcc -static-libstdc++ /fltk/svn/fltk-1.3/lib/libfltk.a -lole32 -luuid -lcomctl32 event = FL_FOCUS ... event = FL_KEYDOWN ... caps lock 1 event = FL_KEYUP ... caps lock 2 event = FL_KEYDOWN ... caps lock 3 event = FL_KEYUP ... caps unlock 4 event = FL_KEYDOWN ... caps lock 5 event = FL_KEYUP ... caps lock 6 event = FL_KEYDOWN ... caps lock 7 event = FL_KEYUP ... caps unlock 8 event = FL_KEYDOWN ... caps lock 9 event = FL_KEYUP ... caps lock 10 event = FL_KEYDOWN ... caps lock 11 event = FL_KEYUP ... caps unlock 12 You can see (or guess) that the CAPS LOCK state is updated *before* the handle message is called on FL_KEYDOWN events, if CAPS LOCK is being turned ON, but *after* the FL_KEYDOWN event, if it is turned OFF. That's why the program shows the "caps unlock" message only on FL_KEYDOWN events. Obviously it's a little difficult to get the state of these toggle keys in a platform independent way, and hence this doesn't seem to work well on my Linux VM: $ fltk-config --compile capslock.cxx && ./capslock g++ -I/home/albrecht/svn/fltk-1.3 -I/home/albrecht/svn/fltk-1.3/png -I/home/albrecht/svn/fltk-1.3/zlib -I/home/albrecht/svn/fltk-1.3/jpeg -I/usr/include/freetype2 -D_LARGEFILE_SOURCE -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 -D_THREAD_SAFE -D_REENTRANT -o 'capslock' 'capslock.cxx' -static-libgcc -static-libstdc++ /home/albrecht/svn/fltk-1.3/lib/libfltk.a -lXext -lfontconfig -lXinerama -lpthread -ldl -lm -lX11 event = FL_FOCUS ... event = FL_KEYDOWN ... caps unlock 1 event = FL_KEYDOWN ... caps lock 2 event = FL_KEYUP ... caps lock 3 event = FL_KEYDOWN ... caps unlock 4 event = FL_KEYDOWN ... caps lock 5 event = FL_KEYDOWN ... caps lock 6 event = FL_KEYUP ... caps lock 7 event = FL_KEYDOWN ... caps lock 8 event = FL_KEYUP ... caps lock 9 event = FL_KEYDOWN ... caps unlock 10 event = FL_KEYUP ... caps lock 11 event = FL_KEYDOWN ... caps lock 12 event = FL_KEYUP ... caps lock 13 event = FL_KEYDOWN ... caps unlock 14 event = FL_KEYDOWN ... caps lock 15 event = FL_KEYUP ... caps lock 16 event = FL_KEYDOWN ... caps unlock 17 event = FL_KEYDOWN ... caps lock 18 event = FL_KEYDOWN ... caps lock 19 event = FL_KEYUP ... caps lock 20 event = FL_KEYDOWN ... caps lock 21 event = FL_KEYUP ... caps lock 22 event = FL_KEYDOWN ... caps unlock 23 event = FL_KEYUP ... caps lock 24 event = FL_KEYDOWN ... caps lock 25 event = FL_KEYUP ... caps lock 26 event = FL_KEYDOWN ... caps unlock 27 event = FL_KEYDOWN ... caps lock 28 event = FL_KEYUP ... caps lock 29 event = FL_FOCUS ... event = FL_KEYDOWN ... caps unlock 30 event = FL_KEYUP ... caps lock 31 You can see an irregular pattern of messages, although I did exactly the same: press CAPS LOCK and release it regularly, with a small delay between two press/release cycles. Greg, regarding your question about test/keyboard: I can also see different (and wrong) behavior with ALL OF shift/ctrl/alt/caps-lock keys on Linux: if I only press and release one of these modifier keys, then the yellow light on this key stays ON (on Linux), but goes OFF on Windows. Can anybody confirm this ? Is it maybe something on my Linux VM ? Note that the key flags mentioned above *are* turned off as expected whenever a text inserting key is pressed, as opposed to modifier keys only. Now to my 2nd modified test. This works so far okay on Win 7, but does not at all give the expected results on my Ubuntu VM: $ cat capslock2.cxx #include <FL/Fl.H> #include <FL/Fl_Window.H> #include <FL/Fl_Button.H> #include <FL/Fl_Secret_Input.H> #include <FL/names.h> #include <iostream> class myWindow : public Fl_Window { public: myWindow(int x, int y, const char* l) : Fl_Window(x, y, l) { } virtual int handle(int event) { if (event == FL_FOCUS) { std::cout << "event = " << fl_eventnames[event] << " ... "; if (Fl::event_state() & FL_CAPS_LOCK) std::cout << "WARNING: CAPS LOCK is set"; std::cout << std::endl; return 1; } if ((event == FL_KEYUP) && Fl::event_key() == FL_Caps_Lock) { std::cout << "event = " << fl_eventnames[event] << " ... "; static int n = 0; if (Fl::event_state() & FL_CAPS_LOCK) { std::cout << "caps lock" << " " << ++n << std::endl; } else { std::cout << "caps unlock" << " " << ++n << std::endl << std::endl; } return 1; } else return Fl_Window::handle(event); } }; int main(int argc, char* argv[]) { myWindow* win = new myWindow(300, 200, ""); new Fl_Secret_Input(20, 20, 100, 20, ""); new Fl_Button(20, 120, 100, 20, "Test"); win->end(); win->show(); return Fl::run(); } This one is simplified so that it does only outputs the key state on FL_KEYUP events, and it looks like this on Windows: $ fltk-config --compile capslock2.cxx && ./capslock2.exe g++ -I/fltk/svn/fltk-1.3 -I/fltk/svn/fltk-1.3/png -I/fltk/svn/fltk-1.3/zlib -I/fltk/svn/fltk-1.3/jpeg -mwindows -DWIN32 -DUSE_OPENGL32 -D_LARGEFILE_SOURCE -D_LARGEFILE64_SOURCE -o 'capslock2' 'capslock2.cxx' -mwindows -static-libgcc -static-libstdc++ /fltk/svn/fltk-1.3/lib/libfltk.a -lole32 -luuid -lcomctl32 event = FL_FOCUS ... event = FL_KEYUP ... caps lock 1 event = FL_KEYUP ... caps unlock 2 event = FL_KEYUP ... caps lock 3 event = FL_KEYUP ... caps unlock 4 event = FL_KEYUP ... caps lock 5 event = FL_KEYUP ... caps unlock 6 event = FL_KEYUP ... caps lock 7 event = FL_KEYUP ... caps unlock 8 This is what I expected, and this is probably what Howard would like to achieve. Same on my Ubuntu VM: $ cat x.tmp albrecht@ubuntu-test:/transfer/fltk/test$ fltk-config --compile capslock2.cxx && ./capslock2 g++ -I/home/albrecht/svn/fltk-1.3 -I/home/albrecht/svn/fltk-1.3/png -I/home/albrecht/svn/fltk-1.3/zlib -I/home/albrecht/svn/fltk-1.3/jpeg -I/usr/include/freetype2 -D_LARGEFILE_SOURCE -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 -D_THREAD_SAFE -D_REENTRANT -o 'capslock2' 'capslock2.cxx' -static-libgcc -static-libstdc++ /home/albrecht/svn/fltk-1.3/lib/libfltk.a -lXext -lfontconfig -lXinerama -lpthread -ldl -lm -lX11 event = FL_FOCUS ... event = FL_KEYUP ... caps lock 1 event = FL_KEYUP ... caps lock 2 event = FL_KEYUP ... caps lock 3 event = FL_KEYUP ... caps lock 4 event = FL_KEYUP ... caps lock 5 event = FL_KEYUP ... caps lock 6 event = FL_KEYUP ... caps lock 7 event = FL_KEYUP ... caps lock 8 event = FL_KEYUP ... caps lock 9 Note that I pressed and released CAPS LOCK exactly 7 times. I saw two messages (3 and 4) on key press #3 and again 2 (8 and 9) on key press and release #7. That's something that needs to be fixed, if possible. :-( --- That said, you can always detect the state of modifier keys correctly (AFAICT) if you check them in the handle() method on FL_KEYDOWN events of other (text) keys, i.e. not on modifier keys only, particularly not when testing the state of a key that is handled in this event. I'd recommend to derive an own input class (as you did in your first example) from Fl_Secret_Input and handle the key press of every key. Then you can pop up a warning message whenever the caps lock state is on for each character typed. If you don't want to annoy the user, you can set a state variable to suppress follow-up warnings, until the caps lock state has been turned off. Or similar... Albrecht _______________________________________________ fltk mailing list fltk@easysw.com http://lists.easysw.com/mailman/listinfo/fltk