diff options
Diffstat (limited to 'src/interface-gtk/gtk-info-popup.c')
-rw-r--r-- | src/interface-gtk/gtk-info-popup.c | 57 |
1 files changed, 46 insertions, 11 deletions
diff --git a/src/interface-gtk/gtk-info-popup.c b/src/interface-gtk/gtk-info-popup.c index 4e25224..aaa0a65 100644 --- a/src/interface-gtk/gtk-info-popup.c +++ b/src/interface-gtk/gtk-info-popup.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2012-2024 Robin Haberkorn + * Copyright (C) 2012-2025 Robin Haberkorn * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -47,12 +47,15 @@ struct _TecoGtkInfoPopup { GtkAdjustment *hadjustment, *vadjustment; GtkWidget *flow_box; + GdkCursor *cursor; /*< pointer/hand cursor */ GStringChunk *chunk; teco_stailq_head_t list; guint idle_id; gboolean frozen; }; +static guint teco_gtk_info_popup_clicked_signal; + static gboolean teco_gtk_info_popup_scroll_event(GtkWidget *widget, GdkEventScroll *event); static void teco_gtk_info_popup_show(GtkWidget *widget); static void teco_gtk_info_popup_vadjustment_changed(GtkAdjustment *vadjustment, GtkWidget *scrollbar); @@ -72,6 +75,9 @@ teco_gtk_info_popup_finalize(GObject *obj_self) while ((entry = teco_stailq_remove_head(&self->list))) g_free(entry); + if (self->cursor) + g_object_unref(self->cursor); + /* chain up to parent class */ G_OBJECT_CLASS(teco_gtk_info_popup_parent_class)->finalize(obj_self); } @@ -82,6 +88,31 @@ teco_gtk_info_popup_class_init(TecoGtkInfoPopupClass *klass) GTK_WIDGET_CLASS(klass)->scroll_event = teco_gtk_info_popup_scroll_event; GTK_WIDGET_CLASS(klass)->show = teco_gtk_info_popup_show; G_OBJECT_CLASS(klass)->finalize = teco_gtk_info_popup_finalize; + + teco_gtk_info_popup_clicked_signal = + g_signal_new("clicked", G_TYPE_FROM_CLASS(klass), + G_SIGNAL_RUN_LAST | G_SIGNAL_NO_RECURSE | G_SIGNAL_NO_HOOKS, + 0, NULL, NULL, NULL, + G_TYPE_NONE, 2, G_TYPE_STRING, G_TYPE_ULONG); +} + +static void +teco_gtk_info_popup_activated_cb(GtkFlowBox *box, GtkFlowBoxChild *child, gpointer user_data) +{ + TecoGtkInfoPopup *popup = TECO_GTK_INFO_POPUP(user_data); + + /* + * Find the TecoGtkLabel in the flow box child. + */ + GtkWidget *hbox = gtk_bin_get_child(GTK_BIN(child)); + g_autoptr(GList) child_list = gtk_container_get_children(GTK_CONTAINER(hbox)); + GList *entry; + for (entry = child_list; entry != NULL && !TECO_IS_GTK_LABEL(entry->data); entry = g_list_next(entry)); + g_assert(entry != NULL); + const teco_string_t *str = teco_gtk_label_get_text(TECO_GTK_LABEL(entry->data)); + + g_signal_emit(popup, teco_gtk_info_popup_clicked_signal, 0, + str->data, (gulong)str->len); } static void @@ -106,6 +137,8 @@ teco_gtk_info_popup_init(TecoGtkInfoPopup *self) G_CALLBACK(teco_gtk_info_popup_vadjustment_changed), scrollbar); self->flow_box = gtk_flow_box_new(); + g_signal_connect(self->flow_box, "child-activated", + G_CALLBACK(teco_gtk_info_popup_activated_cb), self); /* take as little height as necessary */ gtk_orientable_set_orientation(GTK_ORIENTABLE(self->flow_box), GTK_ORIENTATION_HORIZONTAL); @@ -311,12 +344,6 @@ teco_gtk_info_popup_idle_add(TecoGtkInfoPopup *self, teco_popup_entry_type_t typ gtk_widget_set_halign(label, GTK_ALIGN_START); gtk_widget_set_valign(label, GTK_ALIGN_CENTER); - /* - * FIXME: This makes little sense once we've got mouse support. - * But for the time being, it's a useful setting. - */ - gtk_label_set_selectable(GTK_LABEL(label), TRUE); - switch (type) { case TECO_POPUP_PLAIN: gtk_label_set_ellipsize(GTK_LABEL(label), PANGO_ELLIPSIZE_START); @@ -331,6 +358,16 @@ teco_gtk_info_popup_idle_add(TecoGtkInfoPopup *self, teco_popup_entry_type_t typ gtk_widget_show_all(hbox); gtk_container_add(GTK_CONTAINER(self->flow_box), hbox); + + GtkWidget *flow_box_child = gtk_widget_get_parent(hbox); + g_assert(GTK_IS_FLOW_BOX_CHILD(flow_box_child)); + GdkWindow *window = gtk_widget_get_window(flow_box_child); + g_assert(window != NULL); + + if (G_UNLIKELY(!self->cursor)) + /* we only initialize it now after guaranteed widget realization */ + self->cursor = gdk_cursor_new_from_name(gdk_window_get_display(window), "pointer"); + gdk_window_set_cursor(window, self->cursor); } static gboolean @@ -417,12 +454,10 @@ teco_gtk_info_popup_scroll_page(TecoGtkInfoPopup *self) * Adjust this so only complete entries are shown. * Effectively, this rounds down to the line height. */ - GList *child_list = gtk_container_get_children(GTK_CONTAINER(self->flow_box)); - if (child_list) { + g_autoptr(GList) child_list = gtk_container_get_children(GTK_CONTAINER(self->flow_box)); + if (child_list) new_value -= (gint)new_value % gtk_widget_get_allocated_height(GTK_WIDGET(child_list->data)); - g_list_free(child_list); - } /* clip to the maximum possible value */ new_value = MIN(new_value, gtk_adjustment_get_upper(adj)); |