GNOME Bugzilla – Bug 156948
Incorrect implementation of gdk_window_add_filter() in gdk.c/gdk.everride (pygdk_filter_func_marshal is incorrect)
Last modified: 2018-08-17 13:35:52 UTC
Please describe the problem: The C definition of the GdkFilterFunc() is: GdkFilterReturn (*GdkFilterFunc) (GdkXEvent *xevent, GdkEvent *event, gpointer data); Where xevent is the native event to filter, event is a GDK event to which the X event will be translated, and data is the user data set when the filter was installed. The filter function in python should be: def filter_func(event, data): Where event is the *GDK event* This is wrong because the GdkEvent is just a shell used for translating the XEvent to a GdkEvent by hand. (If you do this you have to return GDK_FILTER_TRANSLATE.) Because of this, the event.type in the python filter function will always be gtk.gdk.NOTHING. pygdk_filter_func_marshal should be changed so that either the XEvent is translated into a GdkEvent, or add the xevent to the filter_function. *gtk/gdk.override: pygdk_filter_func_marshal Steps to reproduce: 1. create a gtk.gdk.Window 2. perform gtk.gdk.Window.add_filter(filter_func) 3. in filter_func(event, data) print event.type Actual results: It'll always print "<enum GDK_NOTHING of type GdkEventType>" On each event. Expected results: event should either hold a pre-translated XEvent, or xevent should be added to the filter function. Does this happen every time? Yes Other information:
I would like to at least try to fix this. Seems like we can either 1) pre-translate the GdkEvent, or 2) provide the raw XEvent and the empty GdkEvent as the C API does. 1 might be easier to use for developers, and wouldn't require an API change - on the other hand, it might be less flexible, and the behavior is different from the C API. In what situations would it be useful to do the translation manually? 2 would need an API change, by adding the XEvent as the first arg to the callback. What is the policy on this? Is this an acceptable change for a minor number release? Finally; are there any good workarounds for this issue? Can one get the currently handled event from somewhere else when in the filter callback?
The filter function needs to be given the platform specific event (XEvent on X11, MSG on win32, ?? on framebuffer) and an uninitialized GdkEvent structure to fill in. Filters can be used to look at platform specific events that are not directly translatable to gdk events, including custom event types. The thing to probably do is to pass the native event structure pointer in wrapped in a PyCObject so that extension modules can be written that cast it to the correct structure.
is comment #2 still relevant? It sounds like it would make this function useful for things like http://lists.laptop.org/pipermail/sugar/2008-May/006202.html .
I really need this, cause xklavier.Engine.filter_events requires GdkXEvent, but gdk calls filter func only with empty GdkEvent
pygtk is not under active development anymore and had its last code changes in 2013. Its codebase has been archived: https://gitlab.gnome.org/Archive/pygtk/commits/master PyGObject at https://gitlab.gnome.org/GNOME/pygobject is its successor. See https://pygobject.readthedocs.io/en/latest/guide/porting.html for porting info. Closing this report as WONTFIX as part of Bugzilla Housekeeping to reflect reality. Feel free to open a task in GNOME Gitlab if the issue described in this task still applies to a recent version of PyGObject. Thanks!