haskellgtk2hs

Listening for "owner change" events for the clipboard in gtk2hs. How to set up?


Using Gtk2Hs, I want to set up a callback to listen for "Owner change" events for the clipboard.

I can find out if this is supported by the X server by querying:

display <- fmap fromJust displayGetDefault
canBeNotified <- displayRequestSelectionNotification display selectionPrimary

It should be straight forward to do like this in C:

GtkClipboard* clipboard = gtk_clipboard_get(GDK_SELECTION_PRIMARY);
g_signal_connect(clipboard, "owner-change",
G_CALLBACK(handle_owner_change), NULL);

I see that callbacks in Gtk2Hs are set up like this:

<widget> `on` <event> $ <action>

Problems

Either I have misunderstood how to wrap this together, or I have reached upon a yet not implemented part of gtk in Gtk2Hs.

I therefore looked at the definition of keyPressEvent which looks like this:

keyPressEvent :: WidgetClass self => Signal self (EventM EKey Bool)
keyPressEvent = Signal (eventM "key_press_event" [KeyPressMask])

So, I tested by simply adding a definition for ownerChangeEvent in gtk like keyPressEvent, but subsituted "key_press_event" for "owner_change_event".

That did not work as I got a runtime error about not finding the event. Naturally.

Any ideas on how to properly listen for "owner change" events in gtk if possible?


Solution

  • You're right that this is not implemented at the moment. Adding it shouldn't be too involved, and might be a fun project if you're looking to get into gtk2hs development. You'll want to add a new constructor to the Event type, together with a descriptive type alias like type EventOwnerChange = Event. You will need to extend marshalEvent to handle this new kind of event, and there may be an unmarshalEvent hanging around though I can't remember.

    Once that's all done, it should be pretty easy to connect to the appropriate signal using the connect_* family of functions (which are for gtk2hs internal use only and therefore are not exposed in the API). From the documentation for the owner-change event, you will probably need to use something like Signal (connect_OBJECT__NONE "owner-change").

    It may also be necessary to add to the EventMask type, though I'm not confident -- test it out and see.