GTK4: need button pressed and released signals

Here is a little more advanced version for testing with GTK-BUTTON, LABEL and DRAWING-AREA (the last two work fine):

Yes stopped is happening :frowning:

And just for fun recreated a simple push button via drawing area. But can’t be a good solution or fix. I like to use the default button and get a simple pressed signal (most straightforward for me) or make use of the getsure if needed.

#include <gtk/gtk.h>

static void
wid_clicked (GtkWidget *widget,
	     gpointer   user_data)
{
  g_message ("Hello World:  Clicked %s", (const gchar*)user_data);
}

static void
wid_pressed (GtkGesture *gesture, int n_press, double x, double y, gpointer user_data)
{
  if (g_object_get_data( G_OBJECT (gesture), "area")){
    g_object_set_data( G_OBJECT (g_object_get_data( G_OBJECT (gesture), "area")), "state", GINT_TO_POINTER (1));
    gtk_widget_queue_draw (g_object_get_data( G_OBJECT (gesture), "area"));
  }
  g_message ("Hello World:  Pressed %s at (%g,%g)", (const gchar*)user_data, x,y);
}

static void
wid_released (GtkGesture *gesture, int n_press, double x, double y, gpointer user_data)
{
  if (g_object_get_data( G_OBJECT (gesture), "area")){
    g_object_set_data( G_OBJECT (g_object_get_data( G_OBJECT (gesture), "area")), "state", GINT_TO_POINTER (0));
    gtk_widget_queue_draw (g_object_get_data( G_OBJECT (gesture), "area"));
  }
  g_message ("Hello World: Released %s at (%g,%g)", (const gchar*)user_data, x,y);
}

static void
wid_stopped (GtkGesture *gesture, gpointer user_data)
{
  g_message ("Hello World: Gesture Stopped for %s", (const gchar*)user_data);
}


static void
draw_button (cairo_t *cr, int x, int y, int w, int h, int r)
{
    cairo_new_sub_path (cr);
    cairo_arc (cr, x + r, y + r, r, M_PI, 3 * M_PI / 2);
    cairo_arc (cr, x + w - r, y + r, r, 3 *M_PI / 2, 2 * M_PI);
    cairo_arc (cr, x + w - r, y + h - r, r, 0, M_PI / 2);
    cairo_arc (cr, x + r, y + h - r, r, M_PI / 2, M_PI);
    cairo_close_path (cr);
}

static void
draw_function (GtkDrawingArea *area, cairo_t *cr,
	       int             width,
	       int             height,
	       gpointer user_data)
{
  double b=5;
  double x0,y0;
  cairo_text_extents_t te;
  int state;
  
  gchar *l = user_data;
  if (!l)
    l = "DA: Push Me";

  x0=width/2;
  y0=height/2;
      
  state = GPOINTER_TO_INT (g_object_get_data( G_OBJECT (area), "state"));

  
  cairo_set_line_width (cr, 2);
  draw_button (cr, b, b, width-2*b, height-2*b, 5);
  cairo_set_fill_rule (cr, CAIRO_FILL_RULE_EVEN_ODD);

  if (state == 0)
    cairo_set_source_rgb (cr, 0.8, 0.8, 0.8);
  else
    cairo_set_source_rgb (cr, 0.6, 0.6, 0.6);
  cairo_fill(cr);
  draw_button (cr, b, b, width-2*b, height-2*b, 5);
  if (state == 0)
    cairo_set_source_rgb (cr, 0.9, 0.7, 0.7);
  else
    cairo_set_source_rgb (cr, 1.0, 0.0, 0.0);
  cairo_stroke(cr);

  cairo_set_source_rgb (cr, 0.0, 0.0, 0.0);
  cairo_translate (cr, x0,y0);
  cairo_set_font_size (cr, 12);
  cairo_text_extents (cr, l, &te);
  cairo_move_to (cr, -te.width/2, te.height/2);
  cairo_show_text (cr, l);

}

static void
activate (GtkApplication *app,
          gpointer        user_data)
{
  GtkWidget *box;
  GtkWidget *window;
  GtkWidget *pushwid;
  GtkGesture *gesture;

  window = gtk_application_window_new (app);
  gtk_window_set_title (GTK_WINDOW (window), "Gesture Tests");
  box = gtk_box_new(GTK_ORIENTATION_VERTICAL,10);
  
  // ====
  pushwid = gtk_button_new_with_label ("BTN: Push Me");
  gtk_box_append (GTK_BOX (box), pushwid);

  gesture = gtk_gesture_click_new ();
  // gtk_gesture_single_set_pushwid (GTK_GESTURE_SINGLE (gesture), 1);
  g_signal_connect (gesture, "pressed", G_CALLBACK (wid_pressed), "GTK-BUTTON");
  g_signal_connect (gesture, "released", G_CALLBACK (wid_released), "GTK-BUTTON");
  g_signal_connect (gesture, "stopped", G_CALLBACK (wid_stopped), "GTK-BUTTON");
  g_signal_connect (pushwid, "clicked", G_CALLBACK (wid_clicked), "GTK-BUTTON");
  gtk_widget_add_controller (pushwid, GTK_EVENT_CONTROLLER (gesture));

  // ====
  pushwid = gtk_label_new ("LAB: Push Me");
  gtk_box_append (GTK_BOX (box), pushwid);

  gesture = gtk_gesture_click_new ();
  // gtk_gesture_single_set_pushwid (GTK_GESTURE_SINGLE (gesture), 1);
  g_signal_connect (gesture, "pressed", G_CALLBACK (wid_pressed), "GTK-LABEL");
  g_signal_connect (gesture, "released", G_CALLBACK (wid_released), "GTK-LABEL");
  gtk_widget_add_controller (pushwid, GTK_EVENT_CONTROLLER (gesture));

  // ====
  pushwid = gtk_drawing_area_new ();
  gtk_drawing_area_set_content_width (GTK_DRAWING_AREA (pushwid), 150);
  gtk_drawing_area_set_content_height (GTK_DRAWING_AREA (pushwid), 50);
  gtk_drawing_area_set_draw_func (GTK_DRAWING_AREA (pushwid), draw_function, NULL, NULL);
  gtk_box_append (GTK_BOX (box), pushwid);

  gesture = gtk_gesture_click_new ();
  g_object_set_data( G_OBJECT (gesture), "area", pushwid);
  g_object_set_data( G_OBJECT (pushwid), "state", GINT_TO_POINTER (0));
  // gtk_gesture_single_set_pushwid (GTK_GESTURE_SINGLE (gesture), 1);
  g_signal_connect (gesture, "pressed", G_CALLBACK (wid_pressed), "GTK-DAREA");
  g_signal_connect (gesture, "released", G_CALLBACK (wid_released), "GTK-DAREA");
  gtk_widget_add_controller (pushwid, GTK_EVENT_CONTROLLER (gesture));
  
  //g_signal_connect_swapped (pushwid, "clicked", G_CALLBACK (gtk_window_destroy), window);
  gtk_window_set_child (GTK_WINDOW (window), box);
  gtk_widget_show (window);
}

int
main (int    argc,
      char **argv)
{
  GtkApplication *app;
  int status;
  app = gtk_application_new ("org.gtk.example", G_APPLICATION_FLAGS_NONE);
  g_signal_connect (app, "activate", G_CALLBACK (activate), NULL);
  status = g_application_run (G_APPLICATION (app), argc, argv);
  g_object_unref (app);
  return status;
}