Tue, 11 Apr 2023 00:17:15 -0500
Use gtk_widget_set_visible for everything
gtk_widget_show and gtk_widget_hide are deprecated in GTK 4.10. However,
gtk_widget_set_visible has been around forever so we just need to move to that.
I didn't test all of these and there are probably some that can still be
removed, but most of those are in code that is going to get refreshed in the
future so I didn't bother for now.
Testing Done:
I tested the join chat, add chat, and add buddy dialogs, as well as the contact added notification.
Reviewed at https://reviews.imfreedom.org/r/2430/
/* GNOME stroke implementation Copyright (c) 2000, 2001 Dan Nicolaescu See the file COPYING for distribution information. */ #include "config.h" #ifdef HAVE_UNISTD_H #include <unistd.h> #endif #include <stdlib.h> #include <stdio.h> #include <glib.h> #include <gtk/gtk.h> #include <gdk/gdk.h> #include "gstroke.h" #include "gstroke-internal.h" static gboolean gstroke_draw_cb(GtkWidget *widget, cairo_t *cr, gpointer user_data); /*FIXME: Maybe these should be put in a structure, and not static...*/ static int mouse_button = 2; static gboolean draw_strokes = FALSE; #define GSTROKE_TIMEOUT_DURATION 10 #define GSTROKE_SIGNALS "gstroke_signals" struct gstroke_func_and_data { void (*func)(GtkWidget *, void *); gpointer data; }; /*FIXME: maybe it's better to just make 2 static variables, not a structure */ struct mouse_position { struct s_point last_point; gboolean invalid; }; static struct mouse_position last_mouse_position; static guint timer_id; static void gstroke_execute (GtkWidget *widget, const gchar *name); static void record_stroke_segment(GtkWidget *widget) { gint x, y; struct gstroke_metrics *metrics; GdkSeat *seat; GdkDevice *dev; g_return_if_fail(widget != NULL); seat = gdk_display_get_default_seat(gtk_widget_get_display(widget)); dev = gdk_seat_get_pointer(seat); gdk_window_get_device_position(gtk_widget_get_window(widget), dev, &x, &y, NULL); last_mouse_position.invalid = FALSE; if (last_mouse_position.last_point.x != x || last_mouse_position.last_point.y != y) { last_mouse_position.last_point.x = x; last_mouse_position.last_point.y = y; metrics = g_object_get_data(G_OBJECT(widget), GSTROKE_METRICS); _gstroke_record (x, y, metrics); } if (gstroke_draw_strokes()) { gtk_widget_queue_draw(widget); } } static gint gstroke_timeout (gpointer data) { GtkWidget *widget; g_return_val_if_fail(data != NULL, FALSE); widget = GTK_WIDGET (data); record_stroke_segment (widget); return TRUE; } static void gstroke_cancel(GtkWidget *widget, GdkEvent *event) { last_mouse_position.invalid = TRUE; g_clear_handle_id(&timer_id, g_source_remove); if (event != NULL) { gdk_seat_ungrab(gdk_event_get_seat(event)); } if (gstroke_draw_strokes()) { gtk_widget_queue_draw(widget); } } static gint process_event(GtkWidget *widget, GdkEvent *event, gpointer data) { static GtkWidget *original_widget = NULL; static GdkCursor *cursor = NULL; switch (event->type) { case GDK_BUTTON_PRESS: if (event->button.button != gstroke_get_mouse_button()) { /* Similar to the bug below catch when any other button is * clicked after the middle button is clicked (but possibly * not released) */ gstroke_cancel(widget, event); original_widget = NULL; break; } original_widget = widget; /* remember the widget where the stroke started */ record_stroke_segment (widget); if (cursor == NULL) { GdkDisplay *display = gtk_widget_get_display(widget); cursor = gdk_cursor_new_for_display(display, GDK_PENCIL); } gdk_seat_grab(gdk_event_get_seat(event), gtk_widget_get_window(widget), GDK_SEAT_CAPABILITY_ALL_POINTING, FALSE, cursor, event, NULL, NULL); timer_id = g_timeout_add (GSTROKE_TIMEOUT_DURATION, gstroke_timeout, widget); return TRUE; case GDK_BUTTON_RELEASE: if ((event->button.button != gstroke_get_mouse_button()) || (original_widget == NULL)) { /* Nice bug when you hold down one button and press another. */ /* We'll just cancel the gesture instead. */ gstroke_cancel(widget, event); original_widget = NULL; break; } last_mouse_position.invalid = TRUE; original_widget = NULL; g_clear_handle_id(&timer_id, g_source_remove); gdk_seat_ungrab(gdk_event_get_seat(event)); { GtkWidget *history = data; char result[GSTROKE_MAX_SEQUENCE]; struct gstroke_metrics *metrics; metrics = (struct gstroke_metrics *)g_object_get_data(G_OBJECT (widget), GSTROKE_METRICS); if (gstroke_draw_strokes()) { gtk_widget_queue_draw(widget); } _gstroke_canonical(result, metrics); gstroke_execute(history, result); } return FALSE; default: break; } return FALSE; } void gstroke_set_draw_strokes(gboolean draw) { draw_strokes = draw; } gboolean gstroke_draw_strokes(void) { return draw_strokes; } void gstroke_set_mouse_button(gint button) { mouse_button = button; } guint gstroke_get_mouse_button(void) { return mouse_button; } void gstroke_enable (GtkWidget *widget) { GtkWidget *event = gtk_widget_get_parent(widget); struct gstroke_metrics *metrics = NULL; if (GTK_IS_EVENT_BOX(event)) { metrics = (struct gstroke_metrics *)g_object_get_data(G_OBJECT(event), GSTROKE_METRICS); } if (metrics == NULL) { GtkWidget *parent; metrics = g_new0(struct gstroke_metrics, 1); metrics->pointList = NULL; metrics->min_x = 10000; metrics->min_y = 10000; metrics->max_x = 0; metrics->max_y = 0; metrics->point_count = 0; event = gtk_event_box_new(); gtk_event_box_set_above_child(GTK_EVENT_BOX(event), TRUE); gtk_widget_set_events(event, GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | GDK_BUTTON2_MOTION_MASK); gtk_widget_set_app_paintable(event, TRUE); gtk_widget_set_visible(event, TRUE); parent = gtk_widget_get_parent(widget); g_object_ref(widget); gtk_container_remove(GTK_CONTAINER(parent), widget); gtk_container_add(GTK_CONTAINER(event), widget); g_object_unref(widget); gtk_container_add(GTK_CONTAINER(parent), event); g_object_set_data(G_OBJECT(event), GSTROKE_METRICS, metrics); g_signal_connect(G_OBJECT(event), "event", G_CALLBACK(process_event), widget); g_signal_connect_after(G_OBJECT(event), "draw", G_CALLBACK(gstroke_draw_cb), NULL); } else { _gstroke_init(metrics); } last_mouse_position.invalid = TRUE; } void gstroke_disable(GtkWidget *widget) { GtkWidget *event = gtk_widget_get_parent(widget); g_return_if_fail(GTK_IS_EVENT_BOX(event)); g_signal_handlers_disconnect_by_func(G_OBJECT(event), G_CALLBACK(process_event), widget); g_signal_handlers_disconnect_by_func(G_OBJECT(event), G_CALLBACK(gstroke_draw_cb), NULL); } void gstroke_signal_connect(GtkWidget *widget, const gchar *name, void (*func)(GtkWidget *widget, void *data), gpointer data) { struct gstroke_func_and_data *func_and_data; GHashTable *hash_table = (GHashTable *)g_object_get_data(G_OBJECT(widget), GSTROKE_SIGNALS); if (!hash_table) { hash_table = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, g_free); g_object_set_data(G_OBJECT(widget), GSTROKE_SIGNALS, hash_table); } func_and_data = g_new0(struct gstroke_func_and_data, 1); func_and_data->func = func; func_and_data->data = data; g_hash_table_insert(hash_table, g_strdup(name), func_and_data); } static void gstroke_execute (GtkWidget *widget, const gchar *name) { GHashTable *hash_table = (GHashTable*)g_object_get_data(G_OBJECT(widget), GSTROKE_SIGNALS); #if 0 purple_debug_misc("gestures", "gstroke %s", name); #endif if (hash_table) { struct gstroke_func_and_data *fd = (struct gstroke_func_and_data*)g_hash_table_lookup (hash_table, name); if (fd) (*fd->func)(widget, fd->data); } } void gstroke_cleanup (GtkWidget *widget) { struct gstroke_metrics *metrics; GHashTable *hash_table = (GHashTable *)g_object_steal_data(G_OBJECT(widget), GSTROKE_SIGNALS); g_clear_pointer(&hash_table, g_hash_table_destroy); metrics = (struct gstroke_metrics *)g_object_steal_data(G_OBJECT(widget), GSTROKE_METRICS); g_free(metrics); } static gboolean gstroke_draw_cb(GtkWidget *widget, cairo_t *cr, G_GNUC_UNUSED gpointer user_data) { struct gstroke_metrics *metrics = (struct gstroke_metrics *)g_object_get_data(G_OBJECT(widget), GSTROKE_METRICS); GSList *iter = NULL; p_point point; if (last_mouse_position.invalid) { return FALSE; } if (!metrics) { return FALSE; } iter = metrics->pointList; if (!iter) { return FALSE; } cairo_save(cr); cairo_set_line_width(cr, 2.0); cairo_set_dash(cr, NULL, 0, 0.0); cairo_set_line_cap(cr, CAIRO_LINE_CAP_BUTT); cairo_set_line_join(cr, CAIRO_LINE_JOIN_MITER); point = (p_point)iter->data; iter = iter->next; cairo_move_to(cr, point->x, point->y); while (iter) { point = (p_point)iter->data; iter = iter->next; cairo_line_to(cr, point->x, point->y); } cairo_stroke(cr); cairo_restore(cr); return FALSE; }