diff --git a/callbacks.c b/callbacks.c index 801eef6..a13e50d 100644 --- a/callbacks.c +++ b/callbacks.c @@ -590,3 +590,16 @@ cb_page_widget_image_selected(ZathuraPage* page, GdkPixbuf* pixbuf, void* data) g_free(selection); } + +void +cb_page_widget_link(ZathuraPage* page, void* data) +{ + g_return_if_fail(page != NULL); + + bool enter = (bool) data; + + GdkWindow* window = gtk_widget_get_parent_window(GTK_WIDGET(page)); + GdkCursor* cursor = gdk_cursor_new(enter == true ? GDK_HAND1 : GDK_LEFT_PTR); + gdk_window_set_cursor(window, cursor); + g_object_unref(cursor); +} diff --git a/callbacks.h b/callbacks.h index 48cbf90..524e4ce 100644 --- a/callbacks.h +++ b/callbacks.h @@ -200,4 +200,8 @@ void cb_page_widget_text_selected(ZathuraPage* page, const char* text, void cb_page_widget_image_selected(ZathuraPage* page, GdkPixbuf* pixbuf, void* data); +void +cb_page_widget_link(ZathuraPage* page, void* data); + + #endif // CALLBACKS_H diff --git a/page-widget.c b/page-widget.c index 98b983a..d67b050 100644 --- a/page-widget.c +++ b/page-widget.c @@ -51,6 +51,7 @@ typedef struct zathura_page_widget_private_s { int x; /**< X coordinate */ int y; /**< Y coordinate */ } selection_basepoint; + bool over_link; } mouse; } zathura_page_widget_private_t; @@ -94,6 +95,8 @@ enum properties_e { enum { TEXT_SELECTED, IMAGE_SELECTED, + ENTER_LINK, + LEAVE_LINK, LAST_SIGNAL }; @@ -162,6 +165,26 @@ zathura_page_widget_class_init(ZathuraPageClass* class) G_TYPE_NONE, 1, G_TYPE_OBJECT); + + signals[ENTER_LINK] = g_signal_new("enter-link", + ZATHURA_TYPE_PAGE, + G_SIGNAL_RUN_LAST, + 0, + NULL, + NULL, + g_cclosure_marshal_generic, + G_TYPE_NONE, + 0); + + signals[LEAVE_LINK] = g_signal_new("leave-link", + ZATHURA_TYPE_PAGE, + G_SIGNAL_RUN_LAST, + 0, + NULL, + NULL, + g_cclosure_marshal_generic, + G_TYPE_NONE, + 0); } static void @@ -737,7 +760,34 @@ cb_zathura_page_widget_motion_notify(GtkWidget* widget, GdkEventMotion* event) { g_return_val_if_fail(widget != NULL, false); g_return_val_if_fail(event != NULL, false); + if ((event->state & GDK_BUTTON1_MASK) == 0) { + zathura_page_widget_private_t* priv = ZATHURA_PAGE_GET_PRIVATE(widget); + if (priv->links.retrieved == false) { + priv->links.list = zathura_page_links_get(priv->page, NULL); + priv->links.retrieved = true; + priv->links.n = (priv->links.list == NULL) ? 0 : girara_list_size(priv->links.list); + } + + if (priv->links.list != NULL && priv->links.n > 0) { + bool over_link = false; + GIRARA_LIST_FOREACH(priv->links.list, zathura_link_t*, iter, link) + zathura_rectangle_t rect = recalc_rectangle(priv->page, zathura_link_get_position(link)); + if (rect.x1 <= event->x && rect.x2 >= event->x && rect.y1 <= event->y && rect.y2 >= event->y) { + over_link = true; + } + GIRARA_LIST_FOREACH_END(priv->links.list, zathura_link_t*, iter, link); + + if (priv->mouse.over_link != over_link) { + if (over_link == true) { + g_signal_emit(ZATHURA_PAGE(widget), signals[ENTER_LINK], 0); + } else { + g_signal_emit(ZATHURA_PAGE(widget), signals[LEAVE_LINK], 0); + } + priv->mouse.over_link = over_link; + } + } + return false; } diff --git a/zathura.c b/zathura.c index d75a551..f5ccfb3 100644 --- a/zathura.c +++ b/zathura.c @@ -783,6 +783,10 @@ document_open(zathura_t* zathura, const char* path, const char* password, G_CALLBACK(cb_page_widget_text_selected), zathura); g_signal_connect(G_OBJECT(page_widget), "image-selected", G_CALLBACK(cb_page_widget_image_selected), zathura); + g_signal_connect(G_OBJECT(page_widget), "enter-link", + G_CALLBACK(cb_page_widget_link), (gpointer) true); + g_signal_connect(G_OBJECT(page_widget), "leave-link", + G_CALLBACK(cb_page_widget_link), (gpointer) false); } /* view mode */