At the beginning of my Gtk-Gdk-Cairo-Pango application, I create a window:
GtkWidget *window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
First, there is GtkWindow , but gtk_create_window returns GtkWidget , not GtkWindow , why?
Then, some functions, such as gdk_window_process_updates(..) , require GdkWindow* .
gtk_window_set_geometry_hints() , on the other hand, requires GtkWindow* .
There is also GdkWindow* gdk_window_new() in the documentation that returns GdkWindow .
Of course there is documentation saying :
A GdkWindow is a rectangular area on the screen. This is a low-level object used to implement high-level objects such as GtkWidget and GtkWindow at the GTK + level. GtkWindow is a top-level window, a thing that a user can imagine as a βwindowβ with a title, etc .; GtkWindow can contain a lot of GdkWindow.
But he still doesn't tell me when and why I need to create Gtk or Gdk windows? What is the picture here?
Now you ask, what specific problem am I trying to solve? Of course I'm trying to draw text using cairo + pango on top of gtk + gdk, right after moving the mouse. The problem is that although the actual drawing seems to be working fast, I cannot get this to happen exactly as the mouse moves. In my motion_notify_event I just call gtk_widget_queue_draw(GtkWidget) , but there is an obvious lag behind the actual mouse movement on the screen, even if I draw a single character, it does not align with the mouse pointer during the move phase and only catches it after the mouse has stopped.
I tried to speed up the update by calling gdk_window_process_updates(GDK_WINDOW(window), false); , the compiler eats it, but I got a runtime statement: Gdk-CRITICAL **: gdk_window_process_updates: assertion 'GDK_IS_WINDOW (window)' failed . I can not find information about this macro and how to use it.
turn on
#include <gtk/gtk.h> #define TXT "1234567890" int X = 0, Y = 0; static void do_drawing(cairo_t *); GtkWidget *window; PangoLayout *layout = 0; static gboolean on_draw_event(GtkWidget *widget, cairo_t *cr, gpointer user_data) { do_drawing(cr); return FALSE; } static void do_drawing(cairo_t *cr) { if (layout == 0) { layout = pango_cairo_create_layout (cr); pango_layout_set_text (layout, TXT, -1); } for (int y = 0; y < 2; y++) { cairo_set_source_rgb (cr, 1, 0, 1); cairo_move_to (cr, 0+X, 0 + y * 20 + Y); pango_cairo_show_layout (cr, layout); } gtk_widget_queue_draw(window); } static gint onmouse(GtkWidget *widget, GdkEventMotion *event) { X = event->x; Y = event->y; gtk_widget_queue_draw(widget); gdk_window_process_updates(GDK_WINDOW(widget), false); } int main(int argc, char *argv[]) { GtkWidget *darea; gtk_init(&argc, &argv); window = gtk_window_new(GTK_WINDOW_TOPLEVEL); darea = gtk_drawing_area_new(); gtk_container_add(GTK_CONTAINER(window), darea); gtk_widget_set_events (window, GDK_EXPOSURE_MASK | GDK_LEAVE_NOTIFY_MASK | GDK_POINTER_MOTION_MASK); g_signal_connect(G_OBJECT(darea), "draw", G_CALLBACK(on_draw_event), NULL); g_signal_connect(window, "destroy", G_CALLBACK(gtk_main_quit), NULL); g_signal_connect(window, "motion_notify_event", G_CALLBACK(onmouse), NULL); gtk_window_set_position(GTK_WINDOW(window), GTK_WIN_POS_CENTER); gtk_window_set_default_size(GTK_WINDOW(window), 5000, 5000); gtk_window_set_title(GTK_WINDOW(window), "Lines"); gtk_widget_show_all(window); gtk_main(); return 0; }