qulogic/talkatu

6db3b87f0e8a
Parents ffe4a049963e
Children 23dc31dfa7e8
Change cursors when hovering over a link
--- a/talkatu/talkatuview.c Sat Jul 13 10:02:45 2019 -0500
+++ b/talkatu/talkatuview.c Sat Jul 13 11:34:58 2019 -0500
@@ -57,6 +57,13 @@
* is updated via cursor-moved and button-press callbacks.
*/
GtkTextMark *context_mark;
+
+ /* we chance the cursor that's display while hovering over a link. To
+ * avoid lots of lookups, we also store the tag for links/anchors.
+ */
+ GdkCursor *cursor_text;
+ GdkCursor *cursor_hand;
+ GtkTextTag *tag_anchor;
} TalkatuViewPrivate;
enum {
@@ -221,7 +228,6 @@
TalkatuViewPrivate *priv = talkatu_view_get_instance_private(TALKATU_VIEW(view));
GtkTextBuffer *buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(view));
GtkTextTagTable *table = gtk_text_buffer_get_tag_table(buffer);
- GtkTextTag *anchor = NULL;
GtkTextIter start;
if(TALKATU_IS_BUFFER(buffer)) {
@@ -232,10 +238,11 @@
priv->context_mark = gtk_text_buffer_create_mark(buffer, NULL, &start, TRUE);
/* check for the anchor tag, if we have it, add a signal handler to it */
- anchor = gtk_text_tag_table_lookup(table, TALKATU_TAG_ANCHOR);
- if(anchor != NULL) {
+ g_clear_pointer(&priv->tag_anchor, g_object_unref);
+ priv->tag_anchor = gtk_text_tag_table_lookup(table, TALKATU_TAG_ANCHOR);
+ if(priv->tag_anchor != NULL) {
g_signal_connect(
- anchor,
+ priv->tag_anchor,
"event",
G_CALLBACK(talkatu_view_anchor_tag_event_cb),
NULL
@@ -379,10 +386,49 @@
return GTK_WIDGET_CLASS(talkatu_view_parent_class)->query_tooltip(widget, x, y, keyboard, tooltip);
}
+static gboolean
+talkatu_view_motion_notify_event(GtkWidget *widget, GdkEventMotion *event) {
+ TalkatuViewPrivate *priv = talkatu_view_get_instance_private(TALKATU_VIEW(widget));
+ GtkTextIter iter;
+ GdkCursor *cursor = NULL;
+ gint x, y;
+
+ gtk_text_view_window_to_buffer_coords(
+ GTK_TEXT_VIEW(widget),
+ GTK_TEXT_WINDOW_TEXT,
+ event->x, event->y,
+ &x, &y
+ );
+
+ gtk_text_view_get_iter_at_location(GTK_TEXT_VIEW(widget), &iter, x, y);
+
+ if(gtk_text_iter_has_tag(&iter, priv->tag_anchor)) {
+ cursor = priv->cursor_hand;
+ }
+
+ if(cursor != gdk_window_get_cursor(event->window)) {
+ gdk_window_set_cursor(event->window, cursor);
+
+ return TRUE;
+ }
+
+ return GTK_WIDGET_CLASS(talkatu_view_parent_class)->motion_notify_event(widget, event);
+}
+
/******************************************************************************
* GObject Stuff
*****************************************************************************/
static void
+talkatu_view_finalize(GObject *obj) {
+ TalkatuViewPrivate *priv = talkatu_view_get_instance_private(TALKATU_VIEW(obj));
+
+ g_object_unref(G_OBJECT(priv->cursor_text));
+ g_object_unref(G_OBJECT(priv->cursor_hand));
+
+ G_OBJECT_CLASS(talkatu_view_parent_class)->finalize(obj);
+}
+
+static void
talkatu_view_get_property(GObject *obj, guint prop_id, GValue *value, GParamSpec *pspec) {
TalkatuView *view = TALKATU_VIEW(obj);
@@ -414,6 +460,9 @@
talkatu_view_init(TalkatuView *view) {
TalkatuViewPrivate *priv = talkatu_view_get_instance_private(view);
+ priv->cursor_text = gdk_cursor_new_from_name(gdk_display_get_default(), "text");
+ priv->cursor_hand = gdk_cursor_new_from_name(gdk_display_get_default(), "pointer");
+
/* tell the widest class that we support tooltips. This is used to show
* link targets, and probably other stuff at some point.
*/
@@ -457,7 +506,9 @@
obj_class->get_property = talkatu_view_get_property;
obj_class->set_property = talkatu_view_set_property;
+ obj_class->finalize = talkatu_view_finalize;
+ widget_class->motion_notify_event = talkatu_view_motion_notify_event;
widget_class->popup_menu = talkatu_view_popup_menu;
widget_class->query_tooltip = talkatu_view_query_tooltip;