tgphelps
tgphelps

Reputation: 57

GTK: how to get button-release events on top window border

I have a program that really needs to know when the user has released the mouse button after resizing the window. I asked to get button-release signals for the window, and I get them when the mouse is clicked INSIDE the window, but NOT when I resize the window and release the mouse button. Below is a short program that demonstrates this. Can anyone tell me what I need to do to get these events?

People have suggested "just use configure signals to do that", but the last configure signal occurs when the mouse stops moving. The user might hold down the mouse button long after that.

C code: '''

#include <stdlib.h>
#include <gtk/gtk.h>

GtkWidget   *window;
GtkBuilder  *builder; 

int
main(int argc, char *argv[]) {

    gtk_init(0, NULL); // init Gtk

    builder = gtk_builder_new_from_file ("test.glade");
    window = GTK_WIDGET(gtk_builder_get_object(builder, "window"));
    g_signal_connect(window, "destroy", G_CALLBACK(gtk_main_quit), NULL);
    gtk_builder_connect_signals(builder, NULL);
    gtk_widget_show(window);
    gtk_main();

    return 0;
}

gboolean
on_window_button_release_event(GtkWidget *w, GdkEvent *e, gpointer p)
{
    printf("button release\n");
    return FALSE;
}

'''

<?xml version="1.0" encoding="UTF-8"?>
<!-- Generated with glade 3.20.4 -->
<interface>
  <requires lib="gtk+" version="3.20"/>
  <object class="GtkWindow" id="window">
    <property name="can_focus">False</property>
    <signal name="button-release-event" handler="on_window_button_release_event" swapped="no"/>
    <child>
      <object class="GtkFixed" id="fixed1">
        <property name="visible">True</property>
        <property name="can_focus">False</property>
        <child>
          <object class="GtkLabel">
            <property name="width_request">100</property>
            <property name="height_request">80</property>
            <property name="visible">True</property>
            <property name="can_focus">False</property>
            <property name="label" translatable="yes">Label</property>
          </object>
          <packing>
            <property name="x">113</property>
            <property name="y">93</property>
          </packing>
        </child>
      </object>
    </child>
    <child type="titlebar">
      <placeholder/>
    </child>
  </object>
</interface>

'''

Upvotes: 2

Views: 622

Answers (1)

jackw11111
jackw11111

Reputation: 1547

Since click on the boundary of the window and top bar is OUTSIDE the window, you will get a focus-out-event signal sent when you click. More importantly, when you release the mouse button, it sends a focus-in-event as the window becomes active again. So you could try using gboolean on_focus_in (GtkWidget* w, GdkEventFocus* ef, gpointer p) and g_signal_connect to focus-in-event to detect mouse click releases originating from clicks outside the window. Issue seems to be ignoring other focus in signal such as opening window, presses that aren't on the boundary, which could potentially be done with gdk_device_get_position (this answer might get you on the right path), etc...

But here is the general idea that might be worth trying to hack it:

#include <stdlib.h>
#include <gtk/gtk.h>

GtkWidget   *window;

gboolean on_focus_in (GtkWidget* w, GdkEventFocus* ef, gpointer p) {
  printf("release\n");
  return TRUE;
}
gboolean on_focus_out (GtkWidget* w, GdkEventFocus* ef, gpointer p) {
    printf("press\n");
    return TRUE;
}

int
main(int argc, char *argv[]) {

    gtk_init(0, NULL); // init Gtk

    window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
    g_signal_connect(window, "destroy", G_CALLBACK(gtk_main_quit), NULL);
    g_signal_connect (window,
              "focus-in-event",
              G_CALLBACK (on_focus_in),
              NULL);
    g_signal_connect (window,
              "focus-out-event",
              G_CALLBACK (on_focus_out),
              NULL);
    gtk_widget_show(window);
    gtk_main();

    return 0;
}

resize event

Upvotes: 1

Related Questions