Search code examples
cgtk3

How to print a continuous message while mouse button pressed (g_timeout_add)?


I have this code:

#include <stdio.h>
#include <gtk/gtk.h>
#include <glib/gi18n.h>

guint threadID = 0;
guint serial_counter = 0;

static gboolean
serial_data (gpointer user_data)
{
    printf("hello\n");
    printf("counter: %d\n", serial_counter);
    serial_counter++;
    return user_data;
}

static void
on_pressed (GtkButton* button, gpointer user_data)
{
    if (user_data == 1)
    {
        threadID = g_timeout_add(250, serial_data, user_data);
    }
    else if (user_data == 0)
    {
        g_source_remove(threadID);
        threadID = 0;   
    }
}

int
main (int argc, char *argv[])
{
    GtkWidget *window;
    gtk_init (&argc, &argv);
    GtkWidget *stop_button;
    GtkWidget *box;

    window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
    gtk_window_set_title (GTK_WINDOW (window), "test.c");

    box = gtk_box_new (GTK_ORIENTATION_VERTICAL, 5);

    stop_button = gtk_button_new_with_label (_("Stop"));

    gtk_box_pack_start (GTK_BOX (box), stop_button, FALSE, FALSE, 0);

    gtk_container_add (GTK_CONTAINER (window), box);

    g_signal_connect (window, "button-press-event", G_CALLBACK (on_pressed), 1);
    g_signal_connect (stop_button, "clicked", G_CALLBACK (on_pressed), 0);
    g_signal_connect (window, "destroy", G_CALLBACK (gtk_main_quit), NULL);
    gtk_widget_show_all (window);

    gtk_main ();
    return 0;
}

Which can be compiled by using:

gcc prueba.c `pkg-config --cflags gtk+-3.0` `pkg-config --libs gtk+-3.0` -o test

I want to print a message only when the button of the mouse is pressed (clicked but not released). Can this be achieved by modifying this code? The objective is to press the right button of the mouse in any part of the current window and get a message printed, until the button is released.


Solution

  • I have no idea where you got the declaration of your signal handler function. It should look different according to GTK manual

    This is some stripped example where I use "pressed" and "released" events to indicate button state and depending on the state I handle "mouse moved" events accordingly. For your purpose you can add the print function and the timer.

    static gboolean on_mouse_button_event(GtkWidget *widget, GdkEvent *event, gpointer user_data)
    {
      if (event->button.button != 3) // right button
        return FALSE;
    
      if (event->button.type == GDK_BUTTON_PRESS)
      {
        if (!button_pressed)
        {
          button_pressed = TRUE;
          // Start timer
        }
      }
      else if (event->button.type == GDK_BUTTON_RELEASE)
      {
        if (button_pressed)
        {
          button_pressed = FALSE;
          // Stop timer
        }
      }
    
      return TRUE;
    }
    
    ...
      g_signal_connect(G_OBJECT(widget), "button-press-event", G_CALLBACK(on_mouse_button_event), NULL);
      g_signal_connect(G_OBJECT(widget), "button-release-event", G_CALLBACK(on_mouse_button_event), NULL);