[gjs: 1/3] overrides/Gtk: Fix template support with Gtk4



commit 4644ea7072ae467b701fcf2e01c805b91b3a303c
Author: Florian Müllner <fmuellner gnome org>
Date:   Thu Apr 16 03:25:47 2020 +0200

    overrides/Gtk: Fix template support with Gtk4
    
    The way how language bindings can hook into GtkBuilder's closure
    creation has changed in Gtk4. As Gtk.Widget.set_connect_func() was
    removed on the way, any custom Gtk4 widget that uses a template
    throws as a result.
    
    Fix this by adding a separate code path for Gtk4.

 modules/core/overrides/Gtk.js | 61 +++++++++++++++++++++++++++++++++----------
 1 file changed, 47 insertions(+), 14 deletions(-)
---
diff --git a/modules/core/overrides/Gtk.js b/modules/core/overrides/Gtk.js
index cfe52d53..dde10db7 100644
--- a/modules/core/overrides/Gtk.js
+++ b/modules/core/overrides/Gtk.js
@@ -23,6 +23,7 @@ const Legacy = imports._legacy;
 const {Gio, GjsPrivate, GObject} = imports.gi;
 
 let Gtk;
+let BuilderScope;
 
 function _init() {
 
@@ -44,20 +45,22 @@ function _init() {
 
     Gtk.Widget.prototype._init = function (params) {
         if (this.constructor[Gtk.template]) {
-            Gtk.Widget.set_connect_func.call(this.constructor, (builder, obj, signalName, handlerName, 
connectObj, flags) => {
-                connectObj = connectObj || this;
-
-                if (flags & GObject.ConnectFlags.SWAPPED) {
-                    throw new Error('Unsupported template signal flag "swapped"');
-                } else if (typeof this[handlerName] === 'undefined') {
-                    throw new Error(`A handler called ${handlerName} was not ` +
-                        `defined for signal ${signalName} on ${this}`);
-                } else if (flags & GObject.ConnectFlags.AFTER) {
-                    obj.connect_after(signalName, this[handlerName].bind(connectObj));
-                } else {
-                    obj.connect(signalName, this[handlerName].bind(connectObj));
-                }
-            });
+            if (BuilderScope) {
+                Gtk.Widget.set_template_scope.call(this.constructor,
+                    new BuilderScope(this));
+            } else {
+                Gtk.Widget.set_connect_func.call(this.constructor,
+                    (builder, obj, signalName, handlerName, connectObj, flags) => {
+                        const swapped = flags & GObject.ConnectFlags.SWAPPED;
+                        const closure = _createClosure(
+                            builder, this, handlerName, swapped, connectObj);
+
+                        if (flags & GObject.ConnectFlags.AFTER)
+                            obj.connect_after(signalName, closure);
+                        else
+                            obj.connect(signalName, closure);
+                    });
+            }
         }
 
         GObject.Object.prototype._init.call(this, params);
@@ -121,4 +124,34 @@ function _init() {
 
         return klass;
     };
+
+    if (Gtk.BuilderScope) {
+        BuilderScope = GObject.registerClass({
+            Implements: [Gtk.BuilderScope],
+        }, class extends GObject.Object {
+            _init(thisArg) {
+                super._init();
+                this._this = thisArg;
+            }
+
+            vfunc_create_closure(builder, handlerName, flags, connectObject) {
+                const swapped = flags & Gtk.BuilderClosureFlags.SWAPPED;
+                return _createClosure(
+                    builder, this._this, handlerName, swapped, connectObject);
+            }
+        });
+    }
+}
+
+function _createClosure(builder, thisArg, handlerName, swapped, connectObject) {
+    connectObject = connectObject || thisArg;
+
+    if (swapped) {
+        throw new Error('Unsupported template signal flag "swapped"');
+    } else if (typeof thisArg[handlerName] === 'undefined') {
+        throw new Error(`A handler called ${handlerName} was not ` +
+            `defined on ${thisArg}`);
+    }
+
+    return thisArg[handlerName].bind(connectObject);
 }


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]