Create the key combination Ctr+Alt+A which is tied to a widget and should trigger the signal "notify"

, ,

I have derived a MyWidget from GtkWidget and implemented the signal “key-press”.

static void
my_widget_class_init (MyWidgetClass *class)
{
  GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (class);

  widget_class->snapshot = my_widget_snapshot;
  widget_class->measure = my_widget_measure;

  my_widget_signals[KEY_PRESS] = g_signal_new ("key_press",
                                 G_TYPE_FROM_CLASS (class),
                                 G_SIGNAL_ACTION, 
                                 0 /* class offset */,
                                 NULL /* accumulator */,
                                 NULL /* accumulator data */,
                                 NULL /* C marshaller */,
                                 G_TYPE_NONE /* return_type */,
                                 0     /* n_params */
                                 );
}

Now I want to trigger this signal and the signal “notify” with GtkShortcut.

#include"shortcout-signal.h"
#include"class-my-widget.h"

void click_event_1 (MyWidget *mywidget, gpointer user_data)

{
    g_print("MyWidget with  Str+Alt+S clicked\n");
}

void click_event_2 (MyWidget *mywidget, gpointer user_data)

{
    g_print("MyWidget with  Str+Alt+A clicked\n");
}

void activate (GtkApplication *app, gpointer data)
{
  GtkWidget *window;
  GtkEventController *shortcut_controller_1;
  GtkEventController *shortcut_controller_2;
  GtkShortcut *shortcut_1;
  GtkShortcut *shortcut_2;
  GtkShortcutTrigger *trigger_1;
  GtkShortcutTrigger *trigger_2;
  GtkShortcutAction *action_1;
  GtkShortcutAction *action_2;

  window =gtk_application_window_new(app);
  gtk_widget_set_size_request(window,50,50);
   
  // create GtkShortCutTriggers  
  trigger_1 = gtk_shortcut_trigger_parse_string ("<Control><Alt>S");
  trigger_2 = gtk_shortcut_trigger_parse_string ("<Control><Alt>A");

  // create GtkShortCutAction ( signal "key_press" / "notify" );  
  action_1 = gtk_signal_action_new ("key_press");
  action_2 = gtk_signal_action_new ("notify");

  // create ShortCut - action bind on trigger
  shortcut_1 = gtk_shortcut_new (trigger_1, action_1);
  shortcut_2 = gtk_shortcut_new (trigger_2, action_2);
 
  // create Shortcut-Controllers 
  shortcut_controller_1 = gtk_shortcut_controller_new();
  shortcut_controller_2 = gtk_shortcut_controller_new();
  gtk_shortcut_controller_set_scope (GTK_SHORTCUT_CONTROLLER(shortcut_controller_1),GTK_SHORTCUT_SCOPE_GLOBAL);
  gtk_shortcut_controller_set_scope (GTK_SHORTCUT_CONTROLLER(shortcut_controller_2),GTK_SHORTCUT_SCOPE_GLOBAL);

  //  add Shortcut to ShortCutController
  gtk_shortcut_controller_add_shortcut (GTK_SHORTCUT_CONTROLLER(shortcut_controller_1),shortcut_1);
  gtk_shortcut_controller_add_shortcut (GTK_SHORTCUT_CONTROLLER(shortcut_controller_2),shortcut_2);
  
  // create MyWidget 
   GtkWidget * my_widget = my_widget_new(); 
  
   // add ShortCutControllers to My Widget 
   gtk_widget_add_controller (my_widget,shortcut_controller_1);
   gtk_widget_add_controller (my_widget,shortcut_controller_2);

   g_signal_connect (my_widget, "key-press", G_CALLBACK (click_event_1), NULL);
   g_signal_connect (my_widget, "notify", G_CALLBACK (click_event_2), NULL);
  
   GtkWidget *box = gtk_box_new(GTK_ORIENTATION_HORIZONTAL,10);
   gtk_box_append(GTK_BOX(box),my_widget);
   gtk_window_set_child(GTK_WINDOW(window),box);
 

 gtk_widget_set_visible(window,TRUE);
}

“key-press” works fine, but “notify” gives me the following error message:

(_main-shortcout-signal:10278): Gtk-WARNING **: 16:03:42.319: gtk_signal_action_activate(): signature mismatch for signal "notify" in the 'MyWidget' class ancestry

How can I design the call in such a way that no signatur mismatch
is reported?

Hi,

Is suppose it’s because notify is already defined at GObject level: GObject.Object::notify

Can you try renaming your signal?

Thank you for being interested in my problem. You are right, I could rename the signal or implement your own signal, as I did in the example.

my_widget_signals[KEY_PRESS] = g_signal_new ("key_press",
                                 G_TYPE_FROM_CLASS (class),
                                 G_SIGNAL_ACTION, 
                                 0 /* class offset */,
                                 NULL /* accumulator */,
                                 NULL /* accumulator data */,
                                 NULL /* C marshaller */,
                                 G_TYPE_NONE /* return_type */,
                                 0     /* n_params */
                                 );

The important thing here is G-SIGNAL-ACTION to generate this signal from the outside (I could already determine this possible ).
However, this is also used in the source code of GObject.

  gobject_signals[NOTIFY] =
    g_signal_new (g_intern_static_string ("notify"),
		  G_TYPE_FROM_CLASS (class),
		  G_SIGNAL_RUN_FIRST | G_SIGNAL_NO_RECURSE | G_SIGNAL_DETAILED | G_SIGNAL_NO_HOOKS | G_SIGNAL_ACTION,
		  G_STRUCT_OFFSET (GObjectClass, notify),
		  NULL, NULL,
		  NULL,
		  G_TYPE_NONE,
		  1, G_TYPE_PARAM);

Nevertheless, it does not work here.
By means of an answer, I hope to expand my knowledge of GObject and GTK4.

The handler of notify has this signature:

void click_event_2 (MyWidget *mywidget, GParamSpec *pspec, gpointer user_data)
{
    g_print("MyWidget with  Str+Alt+A clicked\n");
}

Note that connecting to notify will trigger the callback every time a property of the object changes. For watching a single property, use notify::prop-name.

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.