summaryrefslogtreecommitdiff
path: root/gi/_gtktemplate.py
diff options
context:
space:
mode:
authorJean Felder <jfelder@src.gnome.org>2020-04-25 02:23:51 +0200
committerJean Felder <jfelder@src.gnome.org>2020-12-06 15:04:09 +0100
commita4880dbc4575fadc0e3a494ca1c3d5374818deb9 (patch)
tree82bf92f05eb03caf5d880be77ef98915de54cc17 /gi/_gtktemplate.py
parent9215e3a1327b63e9036c6a45def9654e1e5d58d6 (diff)
downloadpygobject-a4880dbc4575fadc0e3a494ca1c3d5374818deb9.tar.gz
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
Diffstat (limited to 'gi/_gtktemplate.py')
-rw-r--r--gi/_gtktemplate.py42
1 files changed, 41 insertions, 1 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__ = \