[gjs: 1/2] overrides: support Gtk template callbacks



commit bcfa6ce71539df30de6e003be75cd963de7ae13c
Author: Andy Holmes <andrew g r holmes gmail com>
Date:   Mon Apr 16 13:41:00 2018 -0700

    overrides: support Gtk template callbacks
    
    * Throw an error if template signal uses the 'object' attribute since we don't support 
GObject.signal_connect_object()
    * Throw an error if template signal sets the 'swapped' attribute to 'true' since we don't support 
GObject.signal_connect_swapped() or @user_data
    * Respect the flag for GObject.signal_connect_after()
    
    * Throw an error if template signal uses the 'object' attribute
    * Amend error messages to make it clearer they are template errors
    * call set_connect_func() on the constructor object

 installed-tests/js/complex.ui |  1 +
 installed-tests/js/testGtk.js | 16 +++++++++++++++-
 modules/overrides/Gtk.js      | 14 ++++++++++++++
 3 files changed, 30 insertions(+), 1 deletion(-)
---
diff --git a/installed-tests/js/complex.ui b/installed-tests/js/complex.ui
index c11f1c1b..4096a4ad 100644
--- a/installed-tests/js/complex.ui
+++ b/installed-tests/js/complex.ui
@@ -10,6 +10,7 @@
       <object class="GtkLabel" id="label-child">
         <property name="label">Complex!</property>
         <property name="visible">True</property>
+        <signal name="grab-focus" handler="templateCallback" swapped="no"/>
       </object>
     </child>
     <child>
diff --git a/installed-tests/js/testGtk.js b/installed-tests/js/testGtk.js
index fdc7ab32..331555c6 100755
--- a/installed-tests/js/testGtk.js
+++ b/installed-tests/js/testGtk.js
@@ -17,6 +17,7 @@ const template = ' \
       <object class="GtkLabel" id="label-child"> \
         <property name="label">Complex!</property> \
         <property name="visible">True</property> \
+        <signal name="grab-focus" handler="templateCallback" swapped="no"/> \
       </object> \
     </child> \
     <child> \
@@ -39,7 +40,11 @@ const MyComplexGtkSubclass = GObject.registerClass({
     Children: ['label-child', 'label-child2'],
     InternalChildren: ['internal-label-child'],
     CssName: 'complex-subclass',
-}, class MyComplexGtkSubclass extends Gtk.Grid {});
+}, class MyComplexGtkSubclass extends Gtk.Grid {
+    templateCallback(widget) {
+        this.callbackEmittedBy = widget;
+    }
+});
 
 // Sadly, putting this in the body of the class will prevent calling
 // get_template_child, since MyComplexGtkSubclass will be bound to the ES6
@@ -62,6 +67,10 @@ const MyComplexGtkSubclassFromResource = GObject.registerClass({
         expect(this.label_child2).toEqual(jasmine.anything());
         expect(this._internal_label_child).toEqual(jasmine.anything());
     }
+
+    templateCallback(widget) {
+        this.callbackEmittedBy = widget;
+    }
 });
 
 const SubclassSubclass = GObject.registerClass(
@@ -74,6 +83,7 @@ function validateTemplate(description, ClassName, pending=false) {
         beforeEach(function () {
             win = new Gtk.Window({ type: Gtk.WindowType.TOPLEVEL });
             content = new ClassName();
+            content.label_child.emit('grab-focus');
             win.add(content);
         });
 
@@ -91,6 +101,10 @@ function validateTemplate(description, ClassName, pending=false) {
                 .toEqual('Complex and internal!');
         });
 
+        it('connects template callbacks to the correct handler', function () {
+            expect(content.callbackEmittedBy).toBe(content.label_child);
+        });
+
         afterEach(function () {
             win.destroy();
         });
diff --git a/modules/overrides/Gtk.js b/modules/overrides/Gtk.js
index a1f427e9..aa598759 100644
--- a/modules/overrides/Gtk.js
+++ b/modules/overrides/Gtk.js
@@ -45,6 +45,20 @@ 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) => {
+                if (connectObj !== null) {
+                    throw new Error('Unsupported template signal attribute "object"');
+                } else if (flags & GObject.ConnectFlags.SWAPPED) {
+                    throw new Error('Unsupported template signal flag "swapped"');
+                } else if (flags & GObject.ConnectFlags.AFTER) {
+                    obj.connect_after(signalName, this[handlerName].bind(this));
+                } else {
+                    obj.connect(signalName, this[handlerName].bind(this));
+                }
+            });
+        }
+
         GObject.Object.prototype._init.call(this, params);
 
         if (this.constructor[Gtk.template]) {


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