2023-10-14
This application catches mouse signals and logs them in a GtkTextView:
Type ESCAPE to close the window.
#include <gtk/gtk.h> // // Variables // static GtkWidget* textview = NULL; static GtkTextBuffer* buffer = NULL; // // Logs output to textview and adds line break. // static void log_line(const char* text) { GtkTextIter iter; gtk_text_buffer_get_end_iter(buffer, &iter); gtk_text_buffer_insert(buffer, &iter, g_strdup_printf("%s\n", text), -1); // // autoscroll // gtk_text_buffer_get_end_iter(buffer, &iter); GtkTextMark* mark = gtk_text_buffer_create_mark(buffer, "mark", &iter, TRUE); gtk_text_view_scroll_to_mark(GTK_TEXT_VIEW(textview), mark, 0.0, TRUE, 0, 0); } // /// Is called when the mouse cursor enters the label. // static void mouse_enter(GtkWidget* label, gdouble x, gdouble y, gpointer user_data) { const char* text = g_strdup_printf("Enter - x: %f y: %f", x, y); gtk_label_set_text(GTK_LABEL(label), text); log_line(text); } // /// Is called when the mouse cursor leaves the label. // static void mouse_leave(GtkWidget* label, gpointer user_data) { const char* text = g_strdup_printf("Leave"); gtk_label_set_text(GTK_LABEL(label), text); log_line(text); } // // Is called when the mouse cursor moves above the label. // static void mouse_motion(GtkWidget* label, gdouble x, gdouble y, gpointer user_data) { const char* text = g_strdup_printf("Motion - x: %f y: %f", x, y); gtk_label_set_text(GTK_LABEL(label), text); log_line(text); } // // Is called when a key is pressed while the main application window has focus. // static gboolean key_pressed(GtkWidget* window, guint keyval, guint keycode, GdkModifierType state, gpointer user_data) { const char* text = g_strdup_printf("key_pressed - keyval: %d keycode: %d", keyval, keycode); g_print(g_strdup_printf("%s\n", text)); if (keyval == GDK_KEY_Escape) { g_print(g_strdup_printf("Good bye world.\n")); gtk_window_destroy(GTK_WINDOW(window)); } return TRUE; } // // Is called when the main application window is activated. // static void activate(GtkApplication* app) { // // Initialize window and signals // GtkWindow* window = GTK_WINDOW(gtk_application_window_new(app)); { gtk_window_set_default_size(window, 600, 480); GtkEventController* event_controller = gtk_event_controller_key_new(); g_signal_connect_object(event_controller, "key-pressed", G_CALLBACK(key_pressed), window, G_CONNECT_SWAPPED); gtk_widget_add_controller(GTK_WIDGET(window), event_controller); } // // Initialize label and signals // GtkWidget* label = gtk_label_new("Hello world!"); { gtk_widget_set_size_request(label, 600, 240); GtkEventController* motion_controller = gtk_event_controller_motion_new(); g_signal_connect_object(motion_controller, "enter", G_CALLBACK(mouse_enter), label, G_CONNECT_SWAPPED); g_signal_connect_object(motion_controller, "leave", G_CALLBACK(mouse_leave), label, G_CONNECT_SWAPPED); g_signal_connect_object(motion_controller, "motion", G_CALLBACK(mouse_motion), label, G_CONNECT_SWAPPED); gtk_widget_add_controller(GTK_WIDGET(label), motion_controller); } // // Initialize scrolled window for textview // GtkWidget* scrolledwindow = gtk_scrolled_window_new(); { gtk_scrolled_window_set_max_content_height(GTK_SCROLLED_WINDOW(scrolledwindow), 240); gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolledwindow), GTK_POLICY_ALWAYS, GTK_POLICY_ALWAYS); // // Initialize textview and buffer // textview = gtk_text_view_new(); gtk_widget_set_size_request(scrolledwindow, 600,240); buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(textview)); gtk_scrolled_window_set_child(GTK_SCROLLED_WINDOW(scrolledwindow), textview); } // // Initialize grid // { GtkWidget* grid = gtk_grid_new(); gtk_grid_attach(GTK_GRID(grid), label, 0, 0, 1, 1); gtk_grid_attach(GTK_GRID(grid), scrolledwindow, 0, 1, 1, 1); gtk_window_set_child(window, grid); } gtk_window_present(window); } // // Main function. // int main(int argc, char* argv[]) { g_autoptr(GtkApplication) app = gtk_application_new(NULL, 0); g_signal_connect(app, "activate", G_CALLBACK(activate), NULL); return g_application_run(G_APPLICATION(app), argc, argv); }
Compile with:
cc $(pkg-config --cflags gtk4) main.c $(pkg-config --libs gtk4)
Execute program with:
./a.out
GtkTextIter iter; gtk_text_buffer_get_end_iter(buffer, &iter);
works but after GtkTextIter* iter = NULL; gtk_text_buffer_get_end_iter(buffer, iter);
iter is still NULL.gtk_text_view_scroll_to_iter()
works odd while gtk_text_view_scroll_to_mark()
works okay (as is documented).