--- a/talkatu/talkatuview.c Sat Jul 13 09:07:50 2019 -0500
+++ b/talkatu/talkatuview.c Sat Jul 13 09:08:29 2019 -0500
@@ -59,11 +59,6 @@
GtkTextMark *context_mark;
-} TalkatuViewOpenLinkData;
@@ -86,36 +81,136 @@
*****************************************************************************/
-talkatu_view_insert_anchor_cb(GtkTextBuffer *buffer,
- GtkTextChildAnchor *anchor,
+talkatu_view_open_url_cb(GtkMenuItem *item, gpointer data) { + TalkatuView *view = g_object_get_data(G_OBJECT(item), "view"); + gchar *url = g_object_get_data(G_OBJECT(item), "url"); + g_signal_emit(view, signals[SIG_OPEN_URL], 0, url); +talkatu_view_copy_url_cb(GtkMenuItem *item, gpointer data) { + GtkClipboard *clipboard = gtk_widget_get_clipboard( + GDK_SELECTION_CLIPBOARD + gtk_clipboard_set_text(clipboard, (gchar *)data, -1); +talkatu_view_anchor_tag_event_cb(GtkTextTag *tag, - GtkTextView *view = GTK_TEXT_VIEW(user_data);
+ GdkEventType event_type = gdk_event_get_event_type(event); - /* first check if talkatu-url is added */
- data = g_object_get_data(G_OBJECT(anchor), "talkatu-url");
- GtkWidget *link = NULL;
- gpointer label = g_object_get_data(G_OBJECT(anchor), "talkatu-url-label");
+ if(event_type == GDK_BUTTON_PRESS) { + GdkEventButton *event_button = (GdkEventButton *)event; + /* the user is right clicking on a link so stop the default handler */ + if(event_button->button == GDK_BUTTON_SECONDARY) { + } else if(event_type == GDK_BUTTON_RELEASE) { + GdkEventButton *event_button = (GdkEventButton *)event; + TalkatuView *view = TALKATU_VIEW(object); + GSList *tags = NULL, *tag = NULL;
- link = gtk_link_button_new_with_label((gchar *)data, (gchar *)label);
- link = gtk_link_button_new((gchar *)data);
+ /* walk through the tags here and look for the tag that has the url */ + tags = gtk_text_iter_get_tags(iter); + for(tag = tags; tag != NULL; tag = tag->next) { + if(tag->data == NULL) { + url = g_object_get_data(G_OBJECT(tag->data), "talkatu-anchor-url"); + /* if we didn't find a url, bail */ - gtk_text_view_add_child_at_anchor(view, link, anchor);
+ if(event_button->button == GDK_BUTTON_PRIMARY) { + GtkTextBuffer *buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(view)); + /* old behavior from pidgin2, if the users has something selected + * we don't open links. Other clients don't do this.. but it seems + * to be a work around for someone pressing a button over text, + * then moving the cursor to the link and then releasing. Without + * the selection check that'll cause that to open the link if the + * button is released in the middle of the link. + if(gtk_text_buffer_get_has_selection(buffer)) { + g_signal_emit(view, signals[SIG_OPEN_URL], 0, url); + } else if(event_button->button == GDK_BUTTON_SECONDARY) { + GtkWidget *menu = gtk_menu_new(); + GtkWidget *item = NULL;
+ item = gtk_menu_item_new_with_label("Open Link"); + /* to make it easier to deal with the life cycle, we just add data + * to the menu item itself with destroy notifies. + g_object_set_data_full( + g_object_set_data_full( + G_CALLBACK(talkatu_view_open_url_cb), + gtk_menu_shell_append(GTK_MENU_SHELL(menu), item); + item = gtk_menu_item_new_with_label("Copy Link"); + G_CALLBACK(talkatu_view_copy_url_cb), + gtk_menu_shell_append(GTK_MENU_SHELL(menu), item); + gtk_widget_show_all(menu); + G_GNUC_BEGIN_IGNORE_DEPRECATIONS + gtk_menu_popup(GTK_MENU(menu), NULL, NULL, NULL, NULL, 0, event_button->time); + G_GNUC_END_IGNORE_DEPRECATIONS talkatu_view_buffer_set_cb(GObject *view, GParamSpec *pspec, gpointer data) {
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; if(TALKATU_IS_BUFFER(buffer)) {
@@ -125,14 +220,18 @@
gtk_text_buffer_get_start_iter(buffer, &start);
priv->context_mark = gtk_text_buffer_create_mark(buffer, NULL, &start, TRUE);
- gspell_text_view_basic_setup(priv->gspell_view);
+ /* 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); + G_CALLBACK(talkatu_view_anchor_tag_event_cb), - g_signal_connect_after(
- gtk_text_view_get_buffer(GTK_TEXT_VIEW(view)),
- G_CALLBACK(talkatu_view_insert_anchor_cb),
+ gspell_text_view_basic_setup(priv->gspell_view); /******************************************************************************
@@ -191,30 +290,6 @@
-talkatu_view_open_url_cb(GtkMenuItem *item, gpointer data) {
- TalkatuViewOpenLinkData *open_link_data = (TalkatuViewOpenLinkData *)data;
- g_slice_free(TalkatuViewOpenLinkData, data);
-talkatu_view_copy_url_cb(GtkMenuItem *item, gpointer data) {
- GtkClipboard *clipboard = gtk_widget_get_clipboard(
- GDK_SELECTION_CLIPBOARD
- gtk_clipboard_set_text(clipboard, (gchar *)data, -1);
talkatu_view_populate_popup_cb(GtkTextView *view, GtkWidget *popup) {
TalkatuViewPrivate *priv = NULL;
GtkTextBuffer *buffer = NULL;