C: Verfolgen der Mausbewegung mit GTk + - c, gtk

Betrachten Sie den folgenden Code:

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


static void destroy(GtkWidget*, gpointer);
static gboolean mouse_moved(GtkWidget *widget,GdkEvent *event,gpointer user_data);

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

GtkWidget *main_window;

// initializing
gtk_init(&argc, &argv);

main_window=gtk_window_new(GTK_WINDOW_TOPLEVEL);
gtk_window_set_title(GTK_WINDOW(main_window),"Test");
gtk_widget_set_size_request (main_window, 500, 300);

// connect the window with signals
g_signal_connect (G_OBJECT (main_window), "destroy",G_CALLBACK (destroy), NULL);
g_signal_connect (G_OBJECT (main_window), "motion-notify-event",G_CALLBACK (mouse_moved), NULL);

gtk_widget_set_events(main_window, GDK_POINTER_MOTION_MASK);

// show window
gtk_widget_show_all (main_window);

gtk_main();
return 0;
}


static void destroy(GtkWidget *window,gpointer data) {
gtk_main_quit ();
}


static gboolean mouse_moved(GtkWidget *widget,GdkEvent *event, gpointer user_data) {

if (event->type==GDK_MOTION_NOTIFY) {
GdkEventMotion* e=(GdkEventMotion*)event;
printf("Coordinates: (%u,%u)n", (guint)e->x,(guint)e->y);
}
}

Wenn ich diesen Code vom Terminal aus starte, öffnet er ein leeres Fenster und druckt jedes Mal die Mauskoordinaten aus.
Hier ist (s) der Ausgang der letzten Ausführung:

Coordinates: (390,17)
Coordinates: (390,18)
Coordinates: (390,18)
Coordinates: (390,18)
Coordinates: (390,18)
Coordinates: (390,19)
Coordinates: (390,19)
Coordinates: (390,19)
Coordinates: (391,22)
Coordinates: (391,22)
Coordinates: (391,22)
Coordinates: (391,22)
Coordinates: (391,22)
Coordinates: (391,22)
Coordinates: (391,22)
Coordinates: (391,23)
Coordinates: (391,23)
Coordinates: (391,23)
Coordinates: (390,23)
Coordinates: (390,23)
Coordinates: (390,23)
Coordinates: (390,23)
Coordinates: (390,24)
Coordinates: (390,24)
Coordinates: (390,24)
Coordinates: (390,24)
Coordinates: (390,24)
Coordinates: (390,24)
Coordinates: (390,24)
Coordinates: (390,24)
Coordinates: (390,24)
Coordinates: (390,24)
Coordinates: (390,24)
Coordinates: (390,25)
Coordinates: (390,25)
Coordinates: (390,25)
Coordinates: (390,25)
Coordinates: (390,25)
Coordinates: (390,25)
Coordinates: (390,26)
Coordinates: (390,26)
Coordinates: (390,26)
Coordinates: (390,26)
Coordinates: (390,26)
Coordinates: (390,26)
Coordinates: (390,26)
Coordinates: (390,27)
Coordinates: (390,27)
Coordinates: (390,27)
Coordinates: (390,27)
Coordinates: (390,27)
Coordinates: (390,28)
Coordinates: (390,28)
Coordinates: (390,28)
Coordinates: (390,28)
Coordinates: (390,28)
Coordinates: (390,28)
Coordinates: (390,28)
Coordinates: (390,28)
Coordinates: (390,29)
Coordinates: (390,29)
Coordinates: (390,29)
Coordinates: (390,30)
Coordinates: (390,30)
Coordinates: (390,30)
Coordinates: (390,30)
Coordinates: (390,31)
Coordinates: (390,31)
Coordinates: (390,32)
Coordinates: (390,32)
Coordinates: (390,32)
Coordinates: (390,33)
Coordinates: (390,33)
Coordinates: (390,33)
Coordinates: (390,33)
Coordinates: (390,33)
Coordinates: (390,34)
Coordinates: (390,34)
Coordinates: (390,34)
Coordinates: (389,34)
Coordinates: (389,35)
Coordinates: (389,36)
Coordinates: (389,36)
Coordinates: (389,36)
Coordinates: (389,37)
Coordinates: (389,36)
Coordinates: (389,37)
Coordinates: (389,37)
Coordinates: (389,37)
Coordinates: (389,37)
Coordinates: (389,38)
Coordinates: (389,38)
Coordinates: (388,38)
Coordinates: (388,38)
Coordinates: (388,38)
Coordinates: (388,38)
Coordinates: (388,39)
Coordinates: (388,39)
Coordinates: (388,39)
Coordinates: (388,39)
Coordinates: (388,39)
Coordinates: (388,40)
Coordinates: (387,40)
Coordinates: (387,40)
Coordinates: (387,40)
Coordinates: (387,40)
Coordinates: (387,40)
Coordinates: (387,40)
Coordinates: (387,40)
Coordinates: (386,41)
Coordinates: (386,41)
Coordinates: (386,41)
Coordinates: (386,41)
Coordinates: (386,41)
Coordinates: (386,41)
Coordinates: (385,41)
Coordinates: (385,41)
Coordinates: (385,41)
Coordinates: (385,41)
Coordinates: (384,42)
Coordinates: (384,42)
Coordinates: (384,42)
Coordinates: (384,42)
Coordinates: (384,42)
Coordinates: (384,42)
Coordinates: (384,42)
Coordinates: (383,42)
Coordinates: (383,42)
Coordinates: (383,42)
Coordinates: (383,42)
Coordinates: (383,43)
Coordinates: (382,43)
Coordinates: (382,43)
Coordinates: (382,43)
Coordinates: (382,43)
Coordinates: (381,43)
Coordinates: (381,43)
Coordinates: (381,43)
Coordinates: (380,43)
Coordinates: (380,44)
Coordinates: (380,44)
Coordinates: (380,44)
Coordinates: (380,44)
Coordinates: (379,44)
Coordinates: (378,44)
Coordinates: (378,44)
Coordinates: (377,44)
Coordinates: (377,44)

und so weiter...

Was mich verwirrt, ist folgendes: Wie kann es zwei aufeinander folgende Ereignisse geben, die dieselben Koordinaten haben? Nehmen Sie zum Beispiel diese zwei Zeilen:

Coordinates: (380,44)
Coordinates: (380,44)

Dies bedeutet im Grunde genommen, dass sich die Maus nicht bewegt hat (sie ging von (380,44) zu (380,44)), also wie könnte es möglicherweise ein Bewegungsereignis geben, um den Handler für diese zweite Eingabezeile zu starten?


Ein weiteres, weniger wichtiges und (vielleicht) unabhängiges Thema:
Warum ist diese Linie notwendig?

gtk_widget_set_events(main_window, GDK_POINTER_MOTION_MASK);

In dem Buch Foundation Of Gtk + Development heißt es:

Als Nächstes müssen Sie dem Ereignis eine Ereignismaske hinzufügenBox, damit es weiß Welche Art von Ereignissen wird das Widget erhalten? Werte für die Die GdkEventMask-Enumeration, die Ereignismasken angibt, wird in Tabelle gezeigt 3-3. Eine bitweise Liste von GdkEventMask-Werten kann übergeben werden gtk_widget_set_events (), wenn Sie mehr als eins setzen müssen.

Aber ist dieser Aufruf nicht redundant, da wir bereits g_signal_connect () haben, was laut Dokumentation heißt:

Verbindet eine GCallback-Funktion mit einem Signal für ein bestimmtes Objekt.

Der Handler wird vor dem Standard-Handler des Signals aufgerufen.

Warum muss ich mich zweimal für ein Signal anmelden?
Einmal mit gtk_widget_set_events() und zweitens mit g_signal_connect()?

Antworten:

3 für die Antwort № 1

Ich habe versucht, die Mausbewegung im X zu überwachenServer, der direkt xev verwendet und es scheint so zu sein, dass xorg mehrere Mausereignisse mit denselben Koordinaten, aber unterschiedlichen Zeitstempeln meldet. Bei der Verwendung des Pointing Sticks auf der Tastatur tut dies dies jedoch nicht, nur mit dem Trackpad oder einer externen Maus.

Meine Vermutung wäre, dass die Genauigkeit tatsächlich höher ist, aber die Ereignisse werden für ein Pixel auf dem Bildschirm gemeldet. Dies könnte dazu führen, dass der Treiber mehr Mausereignisse als nötig meldet.