Results 1 to 6 of 6

Thread: Grabbing a key in X11

  1. #1
    Join Date
    Feb 2008
    Posts
    98
    Thanks
    2
    Thanked 24 Times in 24 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Grabbing a key in X11

    I'm trying to grab a key to use it as a global shortcut in X11. I reduced my code to a simple test:

    Qt Code:
    1. #include <QtGui>
    2. #include <QX11Info>
    3.  
    4. #include <X11/X.h>
    5. #include <X11/Xlib.h>
    6. #include <X11/keysym.h>
    7.  
    8. #ifdef KeyPress
    9. const int XKeyPress = KeyPress;
    10. const int XKeyRelease = KeyRelease;
    11. #undef KeyPress
    12. #undef KeyRelease
    13. #endif
    14.  
    15. class GrabWidget : public QTextBrowser
    16. {
    17. Q_OBJECT
    18.  
    19. public:
    20. GrabWidget(QWidget *parent)
    21. : QTextBrowser(parent)
    22. {
    23. qApp->installEventFilter(this);
    24.  
    25. m_keyCode = XKeysymToKeycode(QX11Info::display(), XK_F11);
    26. XGrabKey(QX11Info::display(), m_keyCode, ControlMask|ShiftMask, QX11Info::appRootWindow(), False, GrabModeAsync, GrabModeAsync);
    27. XFlush(QX11Info::display());
    28. }
    29.  
    30. ~GrabWidget()
    31. {
    32. XUngrabKey(QX11Info::display(), m_keyCode, ControlMask|ShiftMask, QX11Info::appRootWindow());
    33. }
    34.  
    35. bool GrabWidget::eventFilter(QObject */*watched*/, QEvent *event)
    36. {
    37. if(event->type() == QEvent::KeyPress) {
    38. QKeyEvent *keyEvent = static_cast<QKeyEvent*>(event);
    39. int qtKey = keyEvent->key();
    40. if(keyEvent->modifiers() == (Qt::ControlModifier|Qt::ShiftModifier) && qtKey == Qt::Key_F11) {
    41. insertPlainText("Ctrl+Shift+F11 pressed!\n");
    42. return false;
    43. }
    44. }
    45. return true;
    46. }
    47.  
    48. private:
    49. int m_keyCode;
    50. };
    To copy to clipboard, switch view to plain text mode 

    Grabbing the key seems to be working since I don't get any error message from Xlib (whereas I get BadAccess if I try to grab a different key which is already grabbed by another application) but I don't get any key press events, nor even if I press that key combination when my own widget has focus. So, what's wrong? How should I receive KeyPress events when I grab a key? I also tried with x11Event() but I get events only when my widget has focus not when another has it.

    Thanks.

    PS: I know it's not portable but I already made an implementation for Windows using RegisterHotKey() and now I'm just trying to implement it for X11.

  2. #2
    Join Date
    Feb 2006
    Location
    Oslo, Norway
    Posts
    6,264
    Thanks
    36
    Thanked 1,519 Times in 1,389 Posts
    Qt products
    Qt4
    Platforms
    MacOS X Unix/X11 Windows Symbian S60 Maemo/MeeGo

    Default Re: Grabbing a key in X11

    J-P Nurmi

  3. #3
    Join Date
    Feb 2008
    Posts
    98
    Thanks
    2
    Thanked 24 Times in 24 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: Grabbing a key in X11

    I already tried subclassing QApplication to reimplement x11EventFilter(), which is what QxtGlobalShortcut does. In fact I've tried it and it doesn't work. It has the same problem: XGrabKey seems to work but no key press notifications are received when the application doesn't have focus. Even when the application has it, QxtGlobalShortcut doesn't emit the activated() signal!

    Qt Code:
    1. int main(int argc, char **argv)
    2. {
    3. QxtApplication app(argc, argv);
    4. TestWidget t;
    5. t.show();
    6. return app.exec();
    7. }
    To copy to clipboard, switch view to plain text mode 

    Qt Code:
    1. class TestWidget : public QTextBrowser
    2. {
    3. Q_OBJECT
    4.  
    5. public:
    6. TestWidget(QWidget *parent = 0) : QTextBrowser(parent)
    7. {
    8. m_globalShortcut.setShortcut(QKeySequence("Ctrl+Shift+F11"));
    9. m_globalShortcut.setEnabled(true);
    10. connect(&m_globalShortcut, SIGNAL(activated()),
    11. this, SLOT(logActivation()));
    12. }
    13.  
    14. public slots:
    15. void logActivation()
    16. {
    17. insertPlainText("+ Ctrl+Shift+F11 pressed!\n");
    18. }
    19.  
    20. private:
    21. QxtGlobalShortcut m_globalShortcut;
    22. };
    To copy to clipboard, switch view to plain text mode 

  4. #4
    Join Date
    Feb 2006
    Location
    Oslo, Norway
    Posts
    6,264
    Thanks
    36
    Thanked 1,519 Times in 1,389 Posts
    Qt products
    Qt4
    Platforms
    MacOS X Unix/X11 Windows Symbian S60 Maemo/MeeGo

    Default Re: Grabbing a key in X11

    What does setShortcut() return? "Ctrl+Shift+F11" is probably reserved, thus registering the shortcut fails.
    J-P Nurmi

  5. #5
    Join Date
    Feb 2008
    Posts
    98
    Thanks
    2
    Thanked 24 Times in 24 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: Grabbing a key in X11

    It always returns true, no matter which key combination I use. I tried with other key combinations, such as Ctrl+Shift+J, Ctrl+Alt+J or Ctrl+Alt+R, for instance. The only difference is that with the last one the following message is printed in the console:

    Qt Code:
    1. X Error: BadAccess (attempt to access private resource denied) 10
    2. Major opcode: 33 (X_GrabKey)
    3. Resource id: 0x5d
    To copy to clipboard, switch view to plain text mode 

    So Ctrl+Alt+R is already grabbed by another application but the former key combinations aren't and they still don't work. :-( I have openSUSE 10.3 with X.org 7.2 here but I've also tried in openSUSE 11.0 with X.org 7.3 and got the same results. Key grabbing works in my system, as I have Yakuake here and whenever I press F12 it opens as expected.

  6. #6
    Join Date
    Feb 2006
    Location
    Oslo, Norway
    Posts
    6,264
    Thanks
    36
    Thanked 1,519 Times in 1,389 Posts
    Qt products
    Qt4
    Platforms
    MacOS X Unix/X11 Windows Symbian S60 Maemo/MeeGo

    Default Re: Grabbing a key in X11

    Sorry, I almost forgot this thread. Anyway, I can confirm that the test application above works as it is just fine on my system (Kubuntu 8.04.1, X.org 7.3, Qt 4.4.0, Qxt 0.4.0).
    J-P Nurmi

Similar Threads

  1. grabbing position of mouse
    By safknw in forum Qt Programming
    Replies: 10
    Last Post: 28th June 2008, 16:00
  2. Replies: 6
    Last Post: 14th September 2006, 21:02
  3. Grabbing widget's background
    By jpn in forum Qt Programming
    Replies: 4
    Last Post: 14th May 2006, 08:58

Tags for this Thread

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
Digia, Qt and their respective logos are trademarks of Digia Plc in Finland and/or other countries worldwide.