clutterplgi

get GdkWindow from Stage to enable event handling


while porting this example to PLGI, I stumbled into a problem I'm unable to solve: the keyboards events aren't released, while the button ones yes. I find in documentation that an event mask should be set on the GdkWindow, so I was attempting to add GDK_KEY_RELEASE_MASK calling

gdk_window_set_events(GdkWindow, ['GDK_BUTTON_PRESS_MASK','GDK_KEY_RELEASE_MASK']),

but I can't get the GdkWindow.

Calling

clutter_gdk_get_stage_window(Stage, GdkWindow),

I get

Clutter-CRITICAL **: The Clutter backend is not a GDK backend

What could be a way to solve this problem ? Of course, I don't know if once solved this one, the keyboard events will be delivered, and the reason behind the fact that button events are released instead.

The behaviour should not be related at all to PLGI, since also the C sample doesn't 'answer' to keyboard events...

Also, changing the typelib import from

:- plgi_use_namespace('ClutterGdk').

to

:- plgi_use_namespace('ClutterX11').

has no effect...


Solution

  • There is no need to set the event mask on the Clutter stage: it's automatically set by the GDK backend, and it does include the GDK_KEY_RELEASE_MASK flag, as you can see from here: https://git.gnome.org/browse/clutter/tree/clutter/gdk/clutter-stage-gdk.h#n66

    #define CLUTTER_STAGE_GDK_EVENT_MASK \
      (GDK_STRUCTURE_MASK |          \
       GDK_FOCUS_CHANGE_MASK |       \
       GDK_EXPOSURE_MASK |           \
       GDK_PROPERTY_CHANGE_MASK |    \
       GDK_ENTER_NOTIFY_MASK |       \
       GDK_LEAVE_NOTIFY_MASK |       \
       GDK_KEY_PRESS_MASK |          \
       GDK_KEY_RELEASE_MASK |        \
       GDK_BUTTON_PRESS_MASK |       \
       GDK_BUTTON_RELEASE_MASK |     \
       GDK_POINTER_MOTION_MASK |     \
       GDK_TOUCH_MASK |              \
       GDK_SCROLL_MASK)
    

    Which gets applied when the stage creates the backing GDK window: https://git.gnome.org/browse/clutter/tree/clutter/gdk/clutter-stage-gdk.c#n342

    gdk_window_ensure_native (stage_gdk->window);
    gdk_window_set_events (stage_gdk->window, CLUTTER_STAGE_GDK_EVENT_MASK);
    

    If you are not getting key release events, you should look into the rest of the stack.

    As for the different backend: the GDK backend is the default since Clutter 1.22; prior to that release, the default backend is the X11 one — which also selects for KeyRelease events. In order to use a specific backend, you must use the CLUTTER_BACKEND environment variable.