PDA

View Full Version : how to determine if CapsLock is on [crossplatform]



papius_vtualetius
26th April 2010, 08:23
hi all!
i'll tell you how to determine the state of CapsLock (this code can be modifyed for NumLock/ScrollLock, but you are to do that by yourself)

note: this will work under windows and any system that uses X11.

the function is simple:



bool QMyClass::checkCapsLock()
{
// platform dependent method of determining if CAPS LOCK is on
#ifdef Q_OS_WIN32 // MS Windows version
return GetKeyState(VK_CAPITAL) == 1;
#else // X11 version (Linux/Unix/Mac OS X/etc...)
Display * d = XOpenDisplay((char*)0);
bool caps_state = false;
if (d)
{
unsigned n;
XkbGetIndicatorState(d, XkbUseCoreKbd, &n);
caps_state = (n & 0x01) == 1;
}
return caps_state;
#endif
}


but we must have some includes:



#ifdef Q_OS_WIN32
# include <windows.h>
#else
# include <X11/XKBlib.h>
#endif


to use X11/XKBLib.h, you have to install libx11-dev and link with -lX11

but there are some troubles!

for example, let's see eventFilter:



bool QMyClass::eventFilter(QObject* obj, QEvent* event)
{
if (event->type() == QEvent::KeyPress) {
// ...
}
}


look's good, but won't work under X11:



error: expected token ':' got '2'


why? what happened?
everything is simple. just look at X11/X.h:



[186] #define KeyPress 2


so that's that! we need to #undef those defines that conflicts with QEvent::Type enum:



#ifdef Q_OS_WIN32
# include <windows.h>
#else
# include <X11/XKBlib.h>
# undef KeyPress
# undef KeyRelease
# undef FocusIn
# undef FocusOut
// etc...
#endif


this will make some troubles if you want to use some specific X11 features, but i think if you are using Qt, you don't need that ;]

that's all, see ya =)

PS: sorry for my bad english

Lesiok
26th April 2010, 09:21
Just read Qt docs (http://doc.trolltech.com/4.6/qapplication.html#keyboardModifiers)

MaikoID
2nd May 2011, 12:44
Hi, I've a similar problem. I need to check which is the physical modifiers' positions, Control, Shift and Alt. On Windows I did it handling the winEvents I'm trying to do the same in linunx handling the x11events but I can't check if the current XEvent is a KeyPress event. One of the problems is what you mentioned, I needed to undef the X11 KeyPress macro. I have tried to compare the XEvent type with 2 because this is the constant declared in X11/X.h but didn't work.


maiko@cits-d530:~/Projetos/Positivo$ grep -i keypress /usr/include/X11/X.h
#define KeyPressMask (1L<<0)
#define KeyPress 2

this is my current code


bool MainWindow::x11Event(XEvent *xe)
{
//TODO: remove #undef KeyPress
if(xe->type == 2)
{
switch (xe->xkey.keycode)
{
case 37://Control_L
keyPressEvent(xe->xkey.keycode, "Key_ControlL");
break;
case 105://Control_R
keyPressEvent(xe->xkey.keycode, "Key_ControlR");
break;
case 50://Shift_L
keyPressEvent(xe->xkey.keycode, "Key_ShiftL");
break;
case 62://Shift_R
keyPressEvent(xe->xkey.keycode, "Key_ShiftR");
break;
default:
return false;
}
return true;
}
return false;
}


Bye and thx.

d_stranz
3rd May 2011, 04:06
Just read Qt docs (http://doc.trolltech.com/4.6/qapplication.html#keyboardModifiers)

Looked at QApplication::keyboardModifiers(). I don't see anything there that you could use to tell the state of the NumLock, CapsLock, or ScrollLock keys. My interpretation of this method is that if I had pressed Shift, Alt, or one of the other modifier keys while pressing another key, this would tell me that. The "Lock" keys are not modifier keys.

dswartz
7th September 2011, 21:16
I am also curious about num, scroll, and kana locks. If

XkbGetIndicatorState(d, XkbUseCoreKbd, &n);
caps_state = (n & 0x01) == 1;

will give us caps lock's state, and I know that

num_state = (n & 0x02) == 2;

will give us number lock's state, and I believe that

scroll_state = (n & 0x04) == 4;

should give us the scroll lock's state, but what about Kana lock? 0x08????