aboutsummaryrefslogtreecommitdiffstats
path: root/libempathy-gtk/empathy-theme-adium.c
diff options
context:
space:
mode:
authorGustavo Noronha Silva <gustavo.noronha@collabora.co.uk>2009-10-09 22:52:24 +0800
committerGustavo Noronha Silva <gustavo.noronha@collabora.co.uk>2009-10-10 01:03:01 +0800
commit52192715c5ea4dddd6bd42b8874fbb28412606ee (patch)
tree9e6f2891c1a2c80c16a7bf387ecdc57a5554ccea /libempathy-gtk/empathy-theme-adium.c
parentec9d9d8779bd3e8a18fdd210bc0d317dc120f91e (diff)
downloadgsoc2013-empathy-52192715c5ea4dddd6bd42b8874fbb28412606ee.tar
gsoc2013-empathy-52192715c5ea4dddd6bd42b8874fbb28412606ee.tar.gz
gsoc2013-empathy-52192715c5ea4dddd6bd42b8874fbb28412606ee.tar.bz2
gsoc2013-empathy-52192715c5ea4dddd6bd42b8874fbb28412606ee.tar.lz
gsoc2013-empathy-52192715c5ea4dddd6bd42b8874fbb28412606ee.tar.xz
gsoc2013-empathy-52192715c5ea4dddd6bd42b8874fbb28412606ee.tar.zst
gsoc2013-empathy-52192715c5ea4dddd6bd42b8874fbb28412606ee.zip
Refactor context menu code to use new HitTestResult API
This is a big cleanup of the context menu code. The current API in WebKit is still not perfect, but we are now able to avoid lots of hacks and work-arounds.
Diffstat (limited to 'libempathy-gtk/empathy-theme-adium.c')
-rw-r--r--libempathy-gtk/empathy-theme-adium.c246
1 files changed, 121 insertions, 125 deletions
diff --git a/libempathy-gtk/empathy-theme-adium.c b/libempathy-gtk/empathy-theme-adium.c
index a860754c9..0f2288e2a 100644
--- a/libempathy-gtk/empathy-theme-adium.c
+++ b/libempathy-gtk/empathy-theme-adium.c
@@ -54,7 +54,6 @@ typedef struct {
gboolean last_is_backlog;
gboolean page_loaded;
GList *message_queue;
- gchar *hovered_uri;
guint notify_enable_webkit_developer_tools_id;
GtkWidget *inspector_window;
} EmpathyThemeAdiumPriv;
@@ -153,140 +152,36 @@ theme_adium_navigation_policy_decision_requested_cb (WebKitWebView *
}
static void
-theme_adium_hovering_over_link_cb (EmpathyThemeAdium *theme,
- gchar *title,
- gchar *uri,
- gpointer user_data)
-{
- EmpathyThemeAdiumPriv *priv = GET_PRIV (theme);
-
- if (tp_strdiff (uri, priv->hovered_uri)) {
- g_free (priv->hovered_uri);
- priv->hovered_uri = g_strdup (uri);
- }
-}
-
-static void
theme_adium_copy_address_cb (GtkMenuItem *menuitem,
gpointer user_data)
{
- EmpathyThemeAdium *theme = EMPATHY_THEME_ADIUM (user_data);
- EmpathyThemeAdiumPriv *priv = GET_PRIV (theme);
+ WebKitHitTestResult *hit_test_result = WEBKIT_HIT_TEST_RESULT (user_data);
+ gchar *uri;
GtkClipboard *clipboard;
+ g_object_get (G_OBJECT (hit_test_result), "link-uri", &uri, NULL);
+
clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
- gtk_clipboard_set_text (clipboard, priv->hovered_uri, -1);
+ gtk_clipboard_set_text (clipboard, uri, -1);
clipboard = gtk_clipboard_get (GDK_SELECTION_PRIMARY);
- gtk_clipboard_set_text (clipboard, priv->hovered_uri, -1);
+ gtk_clipboard_set_text (clipboard, uri, -1);
+
+ g_free (uri);
}
static void
theme_adium_open_address_cb (GtkMenuItem *menuitem,
gpointer user_data)
{
- EmpathyThemeAdium *theme = EMPATHY_THEME_ADIUM (user_data);
- EmpathyThemeAdiumPriv *priv = GET_PRIV (theme);
-
- empathy_url_show (GTK_WIDGET (menuitem), priv->hovered_uri);
-}
-
-static void
-theme_adium_populate_popup_cb (WebKitWebView *view,
- GtkMenu *menu,
- gpointer user_data)
-{
- EmpathyThemeAdium *theme = EMPATHY_THEME_ADIUM (view);
- EmpathyThemeAdiumPriv *priv = GET_PRIV (theme);
- GtkWidget *item;
- GList *items;
- GtkWidget *icon;
- gchar *stock_id;
- gboolean is_link = FALSE;
- gboolean developer_tools_enabled;
-
- /* FIXME: WebKitGTK+'s context menu API clearly needs an
- * overhaul. There is currently no way to know what is being
- * clicked, to decide what features to provide. You either
- * take what it gives you as a menu, or use hacks to figure
- * out what to display. */
- items = gtk_container_get_children (GTK_CONTAINER (menu));
- item = GTK_WIDGET (g_list_nth_data (items, 0));
- g_list_free (items);
-
- if (GTK_IS_IMAGE_MENU_ITEM (item)) {
- icon = gtk_image_menu_item_get_image (GTK_IMAGE_MENU_ITEM (item));
- gtk_image_get_stock (GTK_IMAGE (icon), &stock_id, NULL);
-
- if ((!strcmp (stock_id, GTK_STOCK_OPEN)) && priv->hovered_uri)
- is_link = TRUE;
- }
+ WebKitHitTestResult *hit_test_result = WEBKIT_HIT_TEST_RESULT (user_data);
+ gchar *uri;
- /* Remove default menu items */
- g_object_get (G_OBJECT (webkit_web_view_get_settings (view)),
- "enable-developer-extras", &developer_tools_enabled, NULL);
- if (!developer_tools_enabled)
- gtk_container_foreach (GTK_CONTAINER (menu),
- (GtkCallback) gtk_widget_destroy, NULL);
+ g_object_get (G_OBJECT (hit_test_result), "link-uri", &uri, NULL);
- /* Select all item */
- item = gtk_image_menu_item_new_from_stock (GTK_STOCK_SELECT_ALL, NULL);
- gtk_menu_shell_prepend (GTK_MENU_SHELL (menu), item);
- gtk_widget_show (item);
+ empathy_url_show (GTK_WIDGET (menuitem), uri);
- g_signal_connect_swapped (item, "activate",
- G_CALLBACK (webkit_web_view_select_all),
- view);
-
- /* Copy menu item */
- if (webkit_web_view_can_copy_clipboard (view)) {
- item = gtk_image_menu_item_new_from_stock (GTK_STOCK_COPY, NULL);
- gtk_menu_shell_prepend (GTK_MENU_SHELL (menu), item);
- gtk_widget_show (item);
-
- g_signal_connect_swapped (item, "activate",
- G_CALLBACK (webkit_web_view_copy_clipboard),
- view);
- }
-
- /* Clear menu item */
- item = gtk_separator_menu_item_new ();
- gtk_menu_shell_prepend (GTK_MENU_SHELL (menu), item);
- gtk_widget_show (item);
-
- item = gtk_image_menu_item_new_from_stock (GTK_STOCK_CLEAR, NULL);
- gtk_menu_shell_prepend (GTK_MENU_SHELL (menu), item);
- gtk_widget_show (item);
-
- g_signal_connect_swapped (item, "activate",
- G_CALLBACK (empathy_chat_view_clear),
- view);
-
- /* We will only add the following menu items if we are
- * right-clicking a link */
- if (!is_link)
- return;
-
- /* Separator */
- item = gtk_separator_menu_item_new ();
- gtk_menu_shell_prepend (GTK_MENU_SHELL (menu), item);
- gtk_widget_show (item);
-
- /* Copy Link Address menu item */
- item = gtk_menu_item_new_with_mnemonic (_("_Copy Link Address"));
- g_signal_connect (item, "activate",
- G_CALLBACK (theme_adium_copy_address_cb),
- view);
- gtk_menu_shell_prepend (GTK_MENU_SHELL (menu), item);
- gtk_widget_show (item);
-
- /* Open Link menu item */
- item = gtk_menu_item_new_with_mnemonic (_("_Open Link"));
- g_signal_connect (item, "activate",
- G_CALLBACK (theme_adium_open_address_cb),
- view);
- gtk_menu_shell_prepend (GTK_MENU_SHELL (menu), item);
- gtk_widget_show (item);
+ g_free (uri);
}
static gchar *
@@ -832,6 +727,111 @@ theme_adium_copy_clipboard (EmpathyChatView *view)
}
static void
+theme_adium_context_menu_selection_done_cb (GtkMenuShell *menu, gpointer user_data)
+{
+ WebKitHitTestResult *hit_test_result = WEBKIT_HIT_TEST_RESULT (user_data);
+
+ g_object_unref (hit_test_result);
+}
+
+static void
+theme_adium_context_menu_for_event (EmpathyThemeAdium *theme, GdkEventButton *event)
+{
+ WebKitWebView *view = WEBKIT_WEB_VIEW (theme);
+ WebKitHitTestResult *hit_test_result;
+ WebKitHitTestResultContext context;
+ GtkWidget *menu;
+ GtkWidget *item;
+
+ hit_test_result = webkit_web_view_get_hit_test_result (view, event);
+ g_object_get (G_OBJECT (hit_test_result), "context", &context, NULL);
+
+ /* The menu */
+ menu = gtk_menu_new ();
+
+ /* Select all item */
+ item = gtk_image_menu_item_new_from_stock (GTK_STOCK_SELECT_ALL, NULL);
+ gtk_menu_shell_prepend (GTK_MENU_SHELL (menu), item);
+
+ g_signal_connect_swapped (item, "activate",
+ G_CALLBACK (webkit_web_view_select_all),
+ view);
+
+ /* Copy menu item */
+ if (webkit_web_view_can_copy_clipboard (view)) {
+ item = gtk_image_menu_item_new_from_stock (GTK_STOCK_COPY, NULL);
+ gtk_menu_shell_prepend (GTK_MENU_SHELL (menu), item);
+
+ g_signal_connect_swapped (item, "activate",
+ G_CALLBACK (webkit_web_view_copy_clipboard),
+ view);
+ }
+
+ /* Clear menu item */
+ item = gtk_separator_menu_item_new ();
+ gtk_menu_shell_prepend (GTK_MENU_SHELL (menu), item);
+
+ item = gtk_image_menu_item_new_from_stock (GTK_STOCK_CLEAR, NULL);
+ gtk_menu_shell_prepend (GTK_MENU_SHELL (menu), item);
+
+ g_signal_connect_swapped (item, "activate",
+ G_CALLBACK (empathy_chat_view_clear),
+ view);
+
+ /* We will only add the following menu items if we are
+ * right-clicking a link */
+ if (context & WEBKIT_HIT_TEST_RESULT_CONTEXT_LINK) {
+ /* Separator */
+ item = gtk_separator_menu_item_new ();
+ gtk_menu_shell_prepend (GTK_MENU_SHELL (menu), item);
+
+ /* Copy Link Address menu item */
+ item = gtk_menu_item_new_with_mnemonic (_("_Copy Link Address"));
+ g_signal_connect (item, "activate",
+ G_CALLBACK (theme_adium_copy_address_cb),
+ hit_test_result);
+ gtk_menu_shell_prepend (GTK_MENU_SHELL (menu), item);
+
+ /* Open Link menu item */
+ item = gtk_menu_item_new_with_mnemonic (_("_Open Link"));
+ g_signal_connect (item, "activate",
+ G_CALLBACK (theme_adium_open_address_cb),
+ hit_test_result);
+ gtk_menu_shell_prepend (GTK_MENU_SHELL (menu), item);
+ }
+
+ g_signal_connect (GTK_MENU_SHELL (menu), "selection-done",
+ G_CALLBACK (theme_adium_context_menu_selection_done_cb),
+ hit_test_result);
+
+ /* Display the menu */
+ gtk_widget_show_all (menu);
+ gtk_menu_popup (GTK_MENU (menu), NULL, NULL, NULL, NULL,
+ event->button, event->time);
+}
+
+static gboolean
+theme_adium_button_press_event (GtkWidget *widget, GdkEventButton *event)
+{
+ if (event->button == 3) {
+ gboolean developer_tools_enabled;
+
+ g_object_get (G_OBJECT (webkit_web_view_get_settings (WEBKIT_WEB_VIEW (widget))),
+ "enable-developer-extras", &developer_tools_enabled, NULL);
+
+ /* We currently have no way to add an inspector menu
+ * item ourselves, so we disable our customized menu
+ * if the developer extras are enabled. */
+ if (!developer_tools_enabled) {
+ theme_adium_context_menu_for_event (EMPATHY_THEME_ADIUM (widget), event);
+ return TRUE;
+ }
+ }
+
+ return GTK_WIDGET_CLASS (empathy_theme_adium_parent_class)->button_press_event (widget, event);
+}
+
+static void
theme_adium_iface_init (EmpathyChatViewIface *iface)
{
iface->append_message = theme_adium_append_message;
@@ -875,7 +875,6 @@ theme_adium_finalize (GObject *object)
EmpathyThemeAdiumPriv *priv = GET_PRIV (object);
empathy_adium_data_unref (priv->data);
- g_free (priv->hovered_uri);
empathy_conf_notify_remove (empathy_conf_get (),
priv->notify_enable_webkit_developer_tools_id);
@@ -1058,6 +1057,7 @@ static void
empathy_theme_adium_class_init (EmpathyThemeAdiumClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
+ GtkWidgetClass* widget_class = GTK_WIDGET_CLASS (klass);
object_class->finalize = theme_adium_finalize;
object_class->dispose = theme_adium_dispose;
@@ -1065,6 +1065,8 @@ empathy_theme_adium_class_init (EmpathyThemeAdiumClass *klass)
object_class->get_property = theme_adium_get_property;
object_class->set_property = theme_adium_set_property;
+ widget_class->button_press_event = theme_adium_button_press_event;
+
g_object_class_install_property (object_class,
PROP_ADIUM_DATA,
g_param_spec_boxed ("adium-data",
@@ -1094,12 +1096,6 @@ empathy_theme_adium_init (EmpathyThemeAdium *theme)
g_signal_connect (theme, "navigation-policy-decision-requested",
G_CALLBACK (theme_adium_navigation_policy_decision_requested_cb),
NULL);
- g_signal_connect (theme, "populate-popup",
- G_CALLBACK (theme_adium_populate_popup_cb),
- NULL);
- g_signal_connect (theme, "hovering-over-link",
- G_CALLBACK (theme_adium_hovering_over_link_cb),
- NULL);
priv->notify_enable_webkit_developer_tools_id =
empathy_conf_notify_add (empathy_conf_get (),