[pygobject/wip/jfelder/template-gtk4: 2/8] Gtk.Template: Fix template support for GTK4
- From: Jean Felder <jfelder src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [pygobject/wip/jfelder/template-gtk4: 2/8] Gtk.Template: Fix template support for GTK4
- Date: Sun, 6 Dec 2020 14:06:21 +0000 (UTC)
commit a4880dbc4575fadc0e3a494ca1c3d5374818deb9
Author: Jean Felder <jfelder src gnome org>
Date: Sat Apr 25 02:23:51 2020 +0200
Gtk.Template: Fix template support for GTK4
Gtk.Widget.set_connect_func() does not exist anymore and signals are
automatically connected. Instead, a GtkBuilderScope needs to be used
to create GtkBuilder's closure functions.
pygobject closure support is extended to support
functools.partial. This is used to create a GtkBuilder closure
function with an object different from the current object.
See MR https://gitlab.gnome.org/GNOME/gtk/-/merge_requests/1204 and
https://gitlab.gnome.org/GNOME/gtk/-/merge_requests/1230
Closes: #380
gi/_gtktemplate.py | 42 +++++++++++++++++++++++++++++++++++++++++-
gi/pygi-struct-marshal.c | 36 +++++++++++++++++++++++++++++++++---
2 files changed, 74 insertions(+), 4 deletions(-)
---
diff --git a/gi/_gtktemplate.py b/gi/_gtktemplate.py
index 4b80106c..15f6b2c5 100644
--- a/gi/_gtktemplate.py
+++ b/gi/_gtktemplate.py
@@ -17,9 +17,43 @@
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
# USA
+from functools import partial
+
from gi.repository import GLib, GObject, Gio
+def define_builder_scope():
+ from gi.repository import Gtk
+
+ class BuilderScope(GObject.GObject, Gtk.BuilderScope):
+
+ def __init__(self):
+ super().__init__()
+
+ def do_create_closure(self, builder, func_name, flags, obj):
+ current_object = builder.get_current_object()
+
+ if func_name not in current_object.__gtktemplate_methods__:
+ return None
+
+ current_object.__gtktemplate_handlers__.add(func_name)
+
+ swapped = int(flags & Gtk.BuilderClosureFlags.SWAPPED)
+ if swapped:
+ raise RuntimeError(
+ "%r not supported" % GObject.ConnectFlags.SWAPPED)
+ return None
+
+ handler_name = current_object.__gtktemplate_methods__[func_name]
+ handler = getattr(current_object, handler_name)
+ if obj:
+ return partial(handler, swap_data=obj)
+
+ return handler
+
+ return BuilderScope
+
+
def connect_func(builder, obj, signal_name, handler_name,
connect_object, flags, cls):
@@ -52,6 +86,8 @@ def connect_func(builder, obj, signal_name, handler_name,
def register_template(cls):
+ from gi.repository import Gtk
+
bound_methods = {}
bound_widgets = {}
@@ -88,7 +124,11 @@ def register_template(cls):
cls.__gtktemplate_methods__ = bound_methods
cls.__gtktemplate_widgets__ = bound_widgets
- cls.set_connect_func(connect_func, cls)
+ if Gtk._version == "4.0":
+ BuilderScope = define_builder_scope()
+ cls.set_template_scope(BuilderScope())
+ else:
+ cls.set_connect_func(connect_func, cls)
base_init_template = cls.init_template
cls.__dontuse_ginstance_init__ = \
diff --git a/gi/pygi-struct-marshal.c b/gi/pygi-struct-marshal.c
index 6daf317c..13715888 100644
--- a/gi/pygi-struct-marshal.c
+++ b/gi/pygi-struct-marshal.c
@@ -182,9 +182,39 @@ pygi_arg_gclosure_from_py_marshal (PyObject *py_arg,
g_closure_ref (closure);
}
} else {
- closure = pyg_closure_new (py_arg, NULL, NULL);
- g_closure_ref (closure);
- g_closure_sink (closure);
+ PyObject *functools;
+ PyObject *partial = NULL;
+
+ functools = PyImport_ImportModule ("functools");
+ if (functools) {
+ partial = PyObject_GetAttrString (functools, "partial");
+ Py_DECREF (functools);
+ }
+
+ if (partial && PyObject_IsInstance (py_arg, partial) > 0) {
+ PyObject *partial_func;
+ PyObject *partial_keywords;
+ PyObject *swap_data;
+
+ partial_func = PyObject_GetAttrString (py_arg, "func");
+ partial_keywords = PyObject_GetAttrString (py_arg, "keywords");
+ swap_data = PyDict_GetItemString (partial_keywords, "swap_data");
+
+ closure = pyg_closure_new (partial_func, NULL, swap_data);
+
+ Py_DECREF (partial_func);
+ Py_DECREF (partial_keywords);
+ g_closure_ref (closure);
+ g_closure_sink (closure);
+ } else {
+ closure = pyg_closure_new (py_arg, NULL, NULL);
+ g_closure_ref (closure);
+ g_closure_sink (closure);
+ }
+
+ if (partial) {
+ Py_DECREF (partial);
+ }
}
if (closure == NULL) {
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]