Search code examples
cgtk4

How to use eventcontroller in gtk4


I would like to add onclick event handling to a GtkBox widget. I see that only GtkButton has clicked signal, so I feel like the only option is to attach a GtkEventController to my widget.

As per the doc, gtk_get_current_event(GtkEventController *ctr) returns the events if there are any and NULL otherwise. How do I listen to this function? Should I implement manual while loop for the main application loop? It feels like there must be a best practice for this.

Thank you in advance


Solution

  • To determine events over a GtkBox, you can create a new event controller to listen to events and add a signal callback for the events you care.

    For your case, you can create a new gesture event controller with gtk_gesture_click_new () and add a callback to the signal released.

    Here is a minimal example:

    /* button-event.c
     *
     * Compile: cc -ggdb button-event.c -o button-event $(pkg-config --cflags --libs gtk4)
     * Run: ./button-event
     *
     * Author: Mohammed Sadiq <www.sadiqpk.org>
     *
     * SPDX-License-Identifier: LGPL-2.1-or-later OR CC0-1.0
     */
    
    #include <gtk/gtk.h>
    
    static gboolean
    gesture_released_cb (GtkWidget *widget)
    {
      g_warning ("do something");
    
      return GDK_EVENT_STOP;
    }
    
    static void
    app_activated_cb (GtkApplication *app)
    {
      GtkGesture *gesture;
      GtkWindow *window;
      GtkWidget *box, *label;
    
      window = GTK_WINDOW (gtk_application_window_new (app));
      gtk_window_set_default_size (window, 400, 300);
    
      box = gtk_box_new (GTK_ORIENTATION_VERTICAL, 6);
      label = gtk_label_new ("Hello");
      gtk_box_append (GTK_BOX (box), label);
      gtk_window_set_child (window, box);
    
      gesture = gtk_gesture_click_new ();
    
      g_signal_connect_object (gesture, "released",
                               G_CALLBACK (gesture_released_cb),
                               box, G_CONNECT_SWAPPED);
      gtk_widget_add_controller (label, GTK_EVENT_CONTROLLER (gesture));
    
      gtk_window_present (window);
    }
    
    int
    main (int   argc,
          char *argv[])
    {
      g_autoptr(GtkApplication) app = gtk_application_new (NULL, 0);
    
      g_signal_connect (app, "activate", G_CALLBACK (app_activated_cb), NULL);
    
      return g_application_run (G_APPLICATION (app), argc, argv);
    }