GTK: как получить события отпускания кнопки на верхней границе окна - PullRequest
2 голосов
/ 01 августа 2020

У меня есть программа, которой действительно нужно знать, когда пользователь отпустил кнопку мыши после изменения размера окна. Я попросил получить сигналы отпускания кнопки для окна, и я получаю их, когда щелкают мышью ВНУТРИ окна, но НЕ, когда я изменяю размер окна и отпускаю кнопку мыши. Ниже представлена ​​короткая программа, демонстрирующая это. Может ли кто-нибудь сказать мне, что мне нужно сделать, чтобы получить эти события?

Люди предлагают «просто использовать для этого сигналы настройки», но последний сигнал настройки возникает, когда мышь перестает двигаться. После этого пользователь может долго удерживать кнопку мыши.

C код: '' '

#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>

'' '

1 Ответ

1 голос
/ 03 августа 2020

Так как щелкните на границе окна и верхняя панель находится ВНЕ окна, при щелчке вы получите сигнал focus-out-event. Что еще более важно, когда вы отпускаете кнопку мыши, она отправляет focus-in-event, когда окно снова становится активным. Таким образом, вы можете попробовать использовать от gboolean on_focus_in (GtkWidget* w, GdkEventFocus* ef, gpointer p) и от g_signal_connect до focus-in-event для обнаружения отпусканий щелчков мыши, происходящих из щелчков за пределами окна. Проблема, похоже, игнорирует другой фокус в сигнале, такой как открытие окна, нажатия, которые не находятся на границе, что потенциально может быть выполнено с помощью gdk_device_get_position ( этот ответ может привести вас на правильный путь), et c ...

Но вот общая идея, которую, возможно, стоит попробовать взломать:

#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;
}

изменить размер мероприятия

...