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

Reply via email to