Re: Capturing global key press events



Lex Trotman wrote:


On 2 March 2010 15:29, Vikram Noel Ambrose <noel ambrose gmail com <mailto:noel ambrose gmail com>> wrote:

    I'd like to capture global key press events to enable a "Global
    Shortcuts" feature in my application.

    I've looked at a few other projects that have such capabilities
    and they all seem to hook straight into xlib. Is there a more GTK
    way of doing it?

    At the moment I'm using,
    XKeysymToKeycode($DISPLAY,XStringToKeysym("some key in here"));

    And then passing the resulting key code to XGrabKey,
    XGrabKey($DISPLAY,key,Mod4Mask|ShiftMask,$WINDOW,True,GrabModeAsync,GrabModeAsync);

    Then I call XSync($DISPLAY,0); I dont know why, but if I dont, gtk
    segfaults.
    I then wait for events with XNextEvent($DISPLAY,&event); inside a
    pthread and when an event comes by, i call a signal callback
    surrounded with gdk_threads_enter and _leave.

    Now all this worked nicely for a while, but somehow I've managed
    to break it :(

    It doesnt seem to pick up the events from the keys I passed to
    XGrabKeys anymore. If I switch to AnyModifier, it picks things up,
    but obviously the keyboard becomes unusable for other applications
    then.

    I believe XGrabKeys will alert me with a BadAccess error if i try
    to use a key that is already being grabbed by another x client,
    but I dont know how well this mechanism works.

    Mod4Mask seems to refer to the Super Key, aka, "Windows Key". So
    in my example I have modifiers Shift+Super and keycode "key".

    When it worked, I had Shift+Super+{z,x,c,v,b} setup. Now nothing
    works and for the best of me, I can't seem to understand what I've
    changed.

    A little background information: My app is heavily threaded, there
    are about 12+ threads at any given time. They are all created with
    pthread_create, and use gdk_threads_enter/leave before touching
    anything gdk/gtk/glib related.

    In main() I call g_thread_init( NULL ); and gdk_threads_init();
    before gtk_init(argc,argv);

    I've read in some places one should surround gtk_main() with
    gdk_threads_enter/leave, but this absolutely doesnt make any sense
    to me.  If I try to do that, the app locks in gtk_main and doesnt
    startup.

    My assumption is that gdk_threads_enter() "acts" like sem_wait()
    and gdk_threads_leave() acts like sem_post(), where
    gdk_threads_init() sets the value of the semaphore to 1.

    With this assumption I've used gdk_threads_enter/leave throughout
    my app and it definitely works.

    I'm guessing there is some sort of conflict between the
    key-press-event for the top level GtkWindow and my xlib key
    grabbing, but I don't know how to debug the situation further. Any
    ideas whats going on?

    thanks,


    Vikram.
    PS: GTK docs are much better than X11 docs :)


I assume you've looked at accelerator groups and accelerator maps then, what don't they do?

By "global" I meant from any keyboard on a particular X Display. ie, my gtk application will not be the focus of input.

[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]