summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorAlexander Mikhaylenko <alexm@gnome.org>2022-03-23 15:14:48 +0400
committerAlexander Mikhaylenko <alexm@gnome.org>2022-03-23 15:31:29 +0400
commit56f0e359e90b7a625a78a72393defff8c2197fef (patch)
tree65b064f452dc957944ce05f774875d6cc4c0d954 /lib
parent1e4c397c3e2fe003bf1afbc229408ff21a4a3373 (diff)
downloadepiphany-56f0e359e90b7a625a78a72393defff8c2197fef.tar.gz
location-entry: Reorder functions
Match the GTK4 order to reduce the diff. Part-of: <https://gitlab.gnome.org/GNOME/epiphany/-/merge_requests/1099>
Diffstat (limited to 'lib')
-rw-r--r--lib/widgets/ephy-location-entry.c1218
1 files changed, 608 insertions, 610 deletions
diff --git a/lib/widgets/ephy-location-entry.c b/lib/widgets/ephy-location-entry.c
index e6b7b1689..a177c2462 100644
--- a/lib/widgets/ephy-location-entry.c
+++ b/lib/widgets/ephy-location-entry.c
@@ -107,304 +107,119 @@ enum signalsEnum {
static gint signals[LAST_SIGNAL] = { 0 };
static void ephy_location_entry_title_widget_interface_init (EphyTitleWidgetInterface *iface);
-static void schedule_dns_prefetch (EphyLocationEntry *entry,
- const gchar *url);
G_DEFINE_TYPE_WITH_CODE (EphyLocationEntry, ephy_location_entry, GTK_TYPE_BIN,
G_IMPLEMENT_INTERFACE (EPHY_TYPE_TITLE_WIDGET,
ephy_location_entry_title_widget_interface_init))
-static gboolean
-entry_button_release (GtkWidget *widget,
- GdkEvent *event,
- gpointer user_data)
-{
- EphyLocationEntry *entry = EPHY_LOCATION_ENTRY (user_data);
- if (((GdkEventButton *)event)->button != GDK_BUTTON_PRIMARY)
- return GDK_EVENT_PROPAGATE;
-
- gtk_editable_select_region (GTK_EDITABLE (entry->url_entry), 0, -1);
-
- g_signal_handlers_block_by_func (widget, G_CALLBACK (entry_button_release), entry);
- entry->button_release_is_blocked = TRUE;
-
- return GDK_EVENT_STOP;
-}
+typedef struct {
+ GUri *uri;
+ EphyLocationEntry *entry;
+} PrefetchHelper;
static void
-update_entry_style (EphyLocationEntry *self)
-{
- PangoAttrList *attrs;
- PangoAttribute *color_normal;
- PangoAttribute *color_dimmed;
- PangoAttribute *scaled;
- g_autoptr (GUri) uri = NULL;
- const char *text = gtk_entry_get_text (GTK_ENTRY (self->url_entry));
- const char *host;
- const char *base_domain;
- char *sub_string;
-
- attrs = pango_attr_list_new ();
-
- if (self->adaptive_mode == EPHY_ADAPTIVE_MODE_NARROW) {
- scaled = pango_attr_scale_new (PANGO_SCALE_SMALL);
- pango_attr_list_insert (attrs, scaled);
- }
-
- if (gtk_widget_has_focus (self->url_entry))
- goto out;
-
- uri = g_uri_parse (text, G_URI_FLAGS_NONE, NULL);
- if (!uri)
- goto out;
-
- host = g_uri_get_host (uri);
- if (!host || strlen (host) == 0)
- goto out;
-
- base_domain = soup_tld_get_base_domain (host, NULL);
- if (!base_domain)
- goto out;
-
- sub_string = strstr (text, base_domain);
- if (!sub_string)
- goto out;
-
- /* Complete text is dimmed */
- color_dimmed = pango_attr_foreground_alpha_new (32768);
- pango_attr_list_insert (attrs, color_dimmed);
-
- /* Base domain with normal style */
- color_normal = pango_attr_foreground_alpha_new (65535);
- color_normal->start_index = sub_string - text;
- color_normal->end_index = color_normal->start_index + strlen (base_domain);
- pango_attr_list_insert (attrs, color_normal);
-
-out:
- gtk_entry_set_attributes (GTK_ENTRY (self->url_entry), attrs);
- pango_attr_list_unref (attrs);
-}
-
-static gboolean
-entry_focus_in_event (GtkWidget *widget,
- GdkEvent *event,
- gpointer user_data)
+free_prefetch_helper (PrefetchHelper *helper)
{
- EphyLocationEntry *self = EPHY_LOCATION_ENTRY (user_data);
-
- update_entry_style (self);
- return GDK_EVENT_PROPAGATE;
+ g_uri_unref (helper->uri);
+ g_object_unref (helper->entry);
+ g_free (helper);
}
static gboolean
-entry_focus_out_event (GtkWidget *widget,
- GdkEvent *event,
- gpointer user_data)
-{
- EphyLocationEntry *entry = EPHY_LOCATION_ENTRY (user_data);
-
- update_entry_style (entry);
-
- if (((GdkEventButton *)event)->button != GDK_BUTTON_PRIMARY)
- return GDK_EVENT_PROPAGATE;
-
- /* Unselect. */
- gtk_editable_select_region (GTK_EDITABLE (entry->url_entry), 0, 0);
-
- if (entry->button_release_is_blocked) {
- g_signal_handlers_unblock_by_func (widget, G_CALLBACK (entry_button_release), entry);
- entry->button_release_is_blocked = FALSE;
- }
-
- return GDK_EVENT_PROPAGATE;
-}
-
-static void
-editable_changed_cb (GtkEditable *editable,
- EphyLocationEntry *entry);
-
-static void
-ephy_location_entry_activate (EphyLocationEntry *entry)
+do_dns_prefetch (PrefetchHelper *helper)
{
- g_signal_emit_by_name (entry->url_entry, "activate");
-}
+ EphyEmbedShell *shell = ephy_embed_shell_get_default ();
-static const char *
-ephy_location_entry_title_widget_get_address (EphyTitleWidget *widget)
-{
- EphyLocationEntry *entry = EPHY_LOCATION_ENTRY (widget);
+ if (helper->uri)
+ webkit_web_context_prefetch_dns (ephy_embed_shell_get_web_context (shell), g_uri_get_host (helper->uri));
- g_assert (entry);
+ helper->entry->dns_prefetch_handle_id = 0;
- return gtk_entry_get_text (GTK_ENTRY (entry->url_entry));
+ return G_SOURCE_REMOVE;
}
+/*
+ * Note: As we do not have access to WebKitNetworkProxyMode, and because
+ * Epiphany does not ever change it, we are just checking system default proxy.
+ */
static void
-ephy_location_entry_title_widget_set_address (EphyTitleWidget *widget,
- const char *address)
+proxy_resolver_ready_cb (GObject *object,
+ GAsyncResult *result,
+ gpointer user_data)
{
- EphyLocationEntry *entry = EPHY_LOCATION_ENTRY (widget);
- GtkClipboard *clipboard;
- const char *text;
- g_autofree char *effective_text = NULL;
- g_autofree char *selection = NULL;
- int start, end;
- const char *final_text;
-
- g_assert (widget);
-
- /* Setting a new text will clear the clipboard. This makes it impossible
- * to copy&paste from the location entry of one tab into another tab, see
- * bug #155824. So we save the selection iff the clipboard was owned by
- * the location entry.
- */
- if (gtk_widget_get_realized (GTK_WIDGET (entry))) {
- clipboard = gtk_widget_get_clipboard (GTK_WIDGET (entry->url_entry),
- GDK_SELECTION_PRIMARY);
- g_assert (clipboard != NULL);
-
- if (gtk_clipboard_get_owner (clipboard) == G_OBJECT (entry->url_entry) &&
- gtk_editable_get_selection_bounds (GTK_EDITABLE (entry->url_entry),
- &start, &end)) {
- selection = gtk_editable_get_chars (GTK_EDITABLE (entry->url_entry),
- start, end);
- }
- }
+ PrefetchHelper *helper = user_data;
+ GProxyResolver *resolver = G_PROXY_RESOLVER (object);
+ g_autoptr (GError) error = NULL;
+ g_auto (GStrv) proxies = NULL;
- if (address != NULL) {
- if (g_str_has_prefix (address, EPHY_ABOUT_SCHEME))
- effective_text = g_strdup_printf ("about:%s",
- address + strlen (EPHY_ABOUT_SCHEME) + 1);
- text = address;
- } else {
- text = "";
+ proxies = g_proxy_resolver_lookup_finish (resolver, result, &error);
+ if (error != NULL) {
+ free_prefetch_helper (helper);
+ return;
}
- final_text = effective_text ? effective_text : text;
-
- entry->block_update = TRUE;
- g_signal_handlers_block_by_func (entry->url_entry, G_CALLBACK (editable_changed_cb), entry);
- gtk_entry_set_text (GTK_ENTRY (entry->url_entry), final_text);
- update_entry_style (entry);
- g_signal_handlers_unblock_by_func (entry->url_entry, G_CALLBACK (editable_changed_cb), entry);
-
- dzl_suggestion_entry_hide_suggestions (DZL_SUGGESTION_ENTRY (entry->url_entry));
- entry->block_update = FALSE;
-
- /* Now restore the selection.
- * Note that it's not owned by the entry anymore!
- */
- if (selection != NULL) {
- gtk_clipboard_set_text (gtk_clipboard_get (GDK_SELECTION_PRIMARY),
- selection, strlen (selection));
+ if (proxies != NULL && (g_strv_length (proxies) > 1 || g_strcmp0 (proxies[0], "direct://") != 0)) {
+ free_prefetch_helper (helper);
+ return;
}
-}
-static EphySecurityLevel
-ephy_location_entry_title_widget_get_security_level (EphyTitleWidget *widget)
-{
- EphyLocationEntry *entry = EPHY_LOCATION_ENTRY (widget);
-
- g_assert (entry);
-
- return entry->security_level;
+ g_clear_handle_id (&helper->entry->dns_prefetch_handle_id, g_source_remove);
+ helper->entry->dns_prefetch_handle_id =
+ g_timeout_add_full (G_PRIORITY_DEFAULT,
+ 250,
+ (GSourceFunc)do_dns_prefetch,
+ helper,
+ (GDestroyNotify)free_prefetch_helper);
+ g_source_set_name_by_id (helper->entry->dns_prefetch_handle_id, "[epiphany] do_dns_prefetch");
}
static void
-ephy_location_entry_title_widget_set_security_level (EphyTitleWidget *widget,
- EphySecurityLevel security_level)
-
+schedule_dns_prefetch (EphyLocationEntry *entry,
+ const gchar *url)
{
- EphyLocationEntry *entry = EPHY_LOCATION_ENTRY (widget);
- const char *icon_name;
-
- g_assert (entry);
-
- if (!entry->reader_mode_active) {
- icon_name = ephy_security_level_to_icon_name (security_level);
- gtk_entry_set_icon_from_icon_name (GTK_ENTRY (entry->url_entry),
- GTK_ENTRY_ICON_PRIMARY,
- icon_name);
- } else {
- gtk_entry_set_icon_from_icon_name (GTK_ENTRY (entry->url_entry),
- GTK_ENTRY_ICON_PRIMARY,
- NULL);
- }
-
- entry->security_level = security_level;
-}
+ GProxyResolver *resolver = g_proxy_resolver_get_default ();
+ PrefetchHelper *helper;
+ g_autoptr (GUri) uri = NULL;
-static void
-ephy_location_entry_set_property (GObject *object,
- guint prop_id,
- const GValue *value,
- GParamSpec *pspec)
-{
- EphyLocationEntry *entry = EPHY_LOCATION_ENTRY (object);
+ if (resolver == NULL)
+ return;
- switch (prop_id) {
- case PROP_ADDRESS:
- ephy_title_widget_set_address (EPHY_TITLE_WIDGET (entry),
- g_value_get_string (value));
- break;
- case PROP_SECURITY_LEVEL:
- ephy_title_widget_set_security_level (EPHY_TITLE_WIDGET (entry),
- g_value_get_enum (value));
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
- }
-}
+ uri = g_uri_parse (url, G_URI_FLAGS_NONE, NULL);
+ if (!uri || !g_uri_get_host (uri))
+ return;
-static void
-ephy_location_entry_get_property (GObject *object,
- guint prop_id,
- GValue *value,
- GParamSpec *pspec)
-{
- EphyLocationEntry *entry = EPHY_LOCATION_ENTRY (object);
+ helper = g_new0 (PrefetchHelper, 1);
+ helper->entry = g_object_ref (entry);
+ helper->uri = g_steal_pointer (&uri);
- switch (prop_id) {
- case PROP_ADDRESS:
- g_value_set_string (value, ephy_title_widget_get_address (EPHY_TITLE_WIDGET (entry)));
- break;
- case PROP_SECURITY_LEVEL:
- g_value_set_enum (value, ephy_title_widget_get_security_level (EPHY_TITLE_WIDGET (entry)));
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
- }
+ g_proxy_resolver_lookup_async (resolver, url, NULL, proxy_resolver_ready_cb, helper);
}
static void
-ephy_location_entry_constructed (GObject *object)
-{
- EphyLocationEntry *entry = EPHY_LOCATION_ENTRY (object);
-
- G_OBJECT_CLASS (ephy_location_entry_parent_class)->constructed (object);
-
- gtk_entry_set_input_hints (GTK_ENTRY (entry->url_entry), GTK_INPUT_HINT_NO_EMOJI);
-}
+editable_changed_cb (GtkEditable *editable,
+ EphyLocationEntry *entry);
static void
-ephy_location_entry_finalize (GObject *object)
+suggestion_selected (DzlSuggestionEntry *entry,
+ DzlSuggestion *suggestion,
+ gpointer user_data)
{
- EphyLocationEntry *entry = EPHY_LOCATION_ENTRY (object);
-
- g_free (entry->saved_text);
- g_clear_pointer (&entry->jump_tab, g_free);
+ EphyLocationEntry *lentry = EPHY_LOCATION_ENTRY (user_data);
+ const gchar *uri = dzl_suggestion_get_id (suggestion);
- G_OBJECT_CLASS (ephy_location_entry_parent_class)->finalize (object);
-}
+ g_signal_handlers_block_by_func (entry, G_CALLBACK (editable_changed_cb), user_data);
+ g_clear_pointer (&lentry->jump_tab, g_free);
-static void
-ephy_location_entry_get_preferred_height (GtkWidget *widget,
- gint *minimum_height,
- gint *natural_height)
-{
- EphyLocationEntry *entry = EPHY_LOCATION_ENTRY (widget);
+ if (g_str_has_prefix (uri, "ephy-tab://")) {
+ lentry->jump_tab = g_strdup (uri);
+ gtk_entry_set_text (GTK_ENTRY (entry), dzl_suggestion_get_subtitle (suggestion));
+ } else {
+ gtk_entry_set_text (GTK_ENTRY (entry), uri);
+ }
+ gtk_editable_set_position (GTK_EDITABLE (entry), -1);
+ g_signal_handlers_unblock_by_func (entry, G_CALLBACK (editable_changed_cb), user_data);
- gtk_widget_get_preferred_height (entry->url_entry, minimum_height, natural_height);
+ schedule_dns_prefetch (lentry, uri);
}
static void
@@ -453,139 +268,41 @@ ephy_location_entry_cut_clipboard (GtkEntry *entry)
}
static void
-ephy_location_entry_title_widget_interface_init (EphyTitleWidgetInterface *iface)
+entry_redo_activate_cb (GtkMenuItem *item,
+ EphyLocationEntry *entry)
{
- iface->get_address = ephy_location_entry_title_widget_get_address;
- iface->set_address = ephy_location_entry_title_widget_set_address;
- iface->get_security_level = ephy_location_entry_title_widget_get_security_level;
- iface->set_security_level = ephy_location_entry_title_widget_set_security_level;
+ ephy_location_entry_undo_reset (entry);
}
static void
-ephy_location_entry_dispose (GObject *object)
+entry_undo_activate_cb (GtkMenuItem *item,
+ EphyLocationEntry *entry)
{
- EphyLocationEntry *entry = EPHY_LOCATION_ENTRY (object);
-
- g_clear_handle_id (&entry->progress_timeout, g_source_remove);
-
- g_clear_object (&entry->css_provider);
-
- G_OBJECT_CLASS (ephy_location_entry_parent_class)->dispose (object);
+ ephy_location_entry_reset (entry);
}
-
-static void
-ephy_location_entry_class_init (EphyLocationEntryClass *klass)
+static gboolean
+entry_button_release (GtkWidget *widget,
+ GdkEvent *event,
+ gpointer user_data)
{
- GObjectClass *object_class = G_OBJECT_CLASS (klass);
- GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
-
- object_class->get_property = ephy_location_entry_get_property;
- object_class->set_property = ephy_location_entry_set_property;
- object_class->constructed = ephy_location_entry_constructed;
- object_class->finalize = ephy_location_entry_finalize;
- object_class->dispose = ephy_location_entry_dispose;
-
- widget_class->get_preferred_height = ephy_location_entry_get_preferred_height;
-
- g_object_class_override_property (object_class, PROP_ADDRESS, "address");
- g_object_class_override_property (object_class, PROP_SECURITY_LEVEL, "security-level");
-
- /**
- * EphyLocationEntry::activate:
- * @flags: the #GdkModifierType from the activation event
- *
- * Emitted when the entry is activated.
- *
- */
- signals[ACTIVATE] = g_signal_new ("activate", G_OBJECT_CLASS_TYPE (klass),
- G_SIGNAL_RUN_FIRST | G_SIGNAL_RUN_LAST,
- 0, NULL, NULL, NULL,
- G_TYPE_NONE,
- 1,
- GDK_TYPE_MODIFIER_TYPE);
+ EphyLocationEntry *entry = EPHY_LOCATION_ENTRY (user_data);
- /**
- * EphyLocationEntry::user-changed:
- * @entry: the object on which the signal is emitted
- *
- * Emitted when the user changes the contents of the internal #GtkEntry
- *
- */
- signals[USER_CHANGED] = g_signal_new ("user_changed", G_OBJECT_CLASS_TYPE (klass),
- G_SIGNAL_RUN_FIRST | G_SIGNAL_RUN_LAST,
- 0, NULL, NULL, NULL,
- G_TYPE_NONE,
- 0,
- G_TYPE_NONE);
+ if (((GdkEventButton *)event)->button != GDK_BUTTON_PRIMARY)
+ return GDK_EVENT_PROPAGATE;
- /**
- * EphyLocationEntry::reader-mode-changed:
- * @entry: the object on which the signal is emitted
- * @active: whether reader mode is active
- *
- * Emitted when the user clicks the reader mode icon inside the
- * #EphyLocationEntry.
- *
- */
- signals[READER_MODE_CHANGED] = g_signal_new ("reader-mode-changed", G_OBJECT_CLASS_TYPE (klass),
- G_SIGNAL_RUN_FIRST | G_SIGNAL_RUN_LAST,
- 0, NULL, NULL, NULL,
- G_TYPE_NONE,
- 1,
- G_TYPE_BOOLEAN);
+ gtk_editable_select_region (GTK_EDITABLE (entry->url_entry), 0, -1);
- /**
- * EphyLocationEntry::get-location:
- * @entry: the object on which the signal is emitted
- * Returns: the current page address as a string
- *
- * For drag and drop purposes, the location bar will request you the
- * real address of where it is pointing to. The signal handler for this
- * function should return the address of the currently loaded site.
- *
- */
- signals[GET_LOCATION] = g_signal_new ("get-location", G_OBJECT_CLASS_TYPE (klass),
- G_SIGNAL_RUN_FIRST | G_SIGNAL_RUN_LAST,
- 0, ephy_signal_accumulator_string,
- NULL, NULL,
- G_TYPE_STRING,
- 0,
- G_TYPE_NONE);
+ g_signal_handlers_block_by_func (widget, G_CALLBACK (entry_button_release), entry);
+ entry->button_release_is_blocked = TRUE;
- /**
- * EphyLocationEntry::get-title:
- * @entry: the object on which the signal is emitted
- * Returns: the current page title as a string
- *
- * For drag and drop purposes, the location bar will request you the
- * title of where it is pointing to. The signal handler for this
- * function should return the title of the currently loaded site.
- *
- */
- signals[GET_TITLE] = g_signal_new ("get-title", G_OBJECT_CLASS_TYPE (klass),
- G_SIGNAL_RUN_FIRST | G_SIGNAL_RUN_LAST,
- 0, ephy_signal_accumulator_string,
- NULL, NULL,
- G_TYPE_STRING,
- 0,
- G_TYPE_NONE);
+ return GDK_EVENT_STOP;
}
static void
-editable_changed_cb (GtkEditable *editable,
- EphyLocationEntry *entry)
+ephy_location_entry_activate (EphyLocationEntry *entry)
{
- if (entry->block_update == TRUE)
- return;
- else {
- entry->user_changed = TRUE;
- entry->can_redo = FALSE;
- }
-
- g_clear_pointer (&entry->jump_tab, g_free);
-
- g_signal_emit (entry, signals[USER_CHANGED], 0);
+ g_signal_emit_by_name (entry->url_entry, "activate");
}
static gboolean
@@ -656,140 +373,121 @@ entry_key_press_cb (GtkEntry *entry,
}
static void
-entry_clear_activate_cb (GtkMenuItem *item,
- EphyLocationEntry *entry)
+handle_forward_tab_key (GtkWidget *widget,
+ gpointer user_data)
{
- entry->block_update = TRUE;
- g_signal_handlers_block_by_func (entry->url_entry, G_CALLBACK (editable_changed_cb), entry);
- gtk_entry_set_text (GTK_ENTRY (entry->url_entry), "");
- g_signal_handlers_unblock_by_func (entry->url_entry, G_CALLBACK (editable_changed_cb), entry);
- entry->block_update = FALSE;
- entry->user_changed = TRUE;
-}
+ EphyLocationEntry *entry = EPHY_LOCATION_ENTRY (user_data);
+ GtkWidget *popover;
-static void
-paste_received (GtkClipboard *clipboard,
- const gchar *text,
- EphyLocationEntry *entry)
-{
- if (text) {
- g_signal_handlers_block_by_func (entry->url_entry, G_CALLBACK (editable_changed_cb), entry);
- gtk_entry_set_text (GTK_ENTRY (entry->url_entry), text);
- ephy_location_entry_activate (entry);
- g_signal_handlers_unblock_by_func (entry->url_entry, G_CALLBACK (editable_changed_cb), entry);
+ popover = dzl_suggestion_entry_get_popover (DZL_SUGGESTION_ENTRY (entry->url_entry));
+ if (gtk_widget_is_visible (popover)) {
+ g_signal_emit_by_name (entry->url_entry, "move-suggestion", 1, G_TYPE_INT, 1, G_TYPE_NONE);
+ } else {
+ gtk_widget_child_focus (gtk_widget_get_toplevel (GTK_WIDGET (entry)), GTK_DIR_TAB_FORWARD);
}
}
static void
-entry_paste_and_go_activate_cb (GtkMenuItem *item,
- EphyLocationEntry *entry)
+handle_backward_tab_key (GtkWidget *widget,
+ gpointer user_data)
{
- GtkClipboard *clipboard;
+ EphyLocationEntry *entry = EPHY_LOCATION_ENTRY (user_data);
+ GtkWidget *popover;
- clipboard = gtk_clipboard_get_default (gdk_display_get_default ());
- gtk_clipboard_request_text (clipboard,
- (GtkClipboardTextReceivedFunc)paste_received,
- entry);
+ popover = dzl_suggestion_entry_get_popover (DZL_SUGGESTION_ENTRY (entry->url_entry));
+ if (gtk_widget_is_visible (popover)) {
+ g_signal_emit_by_name (entry->url_entry, "move-suggestion", -1, G_TYPE_INT, 1, G_TYPE_NONE);
+ } else {
+ gtk_widget_child_focus (gtk_widget_get_toplevel (GTK_WIDGET (entry)), GTK_DIR_TAB_BACKWARD);
+ }
}
static void
-entry_redo_activate_cb (GtkMenuItem *item,
- EphyLocationEntry *entry)
+update_entry_style (EphyLocationEntry *self)
{
- ephy_location_entry_undo_reset (entry);
-}
+ PangoAttrList *attrs;
+ PangoAttribute *color_normal;
+ PangoAttribute *color_dimmed;
+ PangoAttribute *scaled;
+ g_autoptr (GUri) uri = NULL;
+ const char *text = gtk_entry_get_text (GTK_ENTRY (self->url_entry));
+ const char *host;
+ const char *base_domain;
+ char *sub_string;
-static void
-entry_undo_activate_cb (GtkMenuItem *item,
- EphyLocationEntry *entry)
-{
- ephy_location_entry_reset (entry);
-}
+ attrs = pango_attr_list_new ();
-/* The build should fail here each time when upgrading to a new major version
- * of GTK+, so that we don't forget to update this domain.
- */
-#if GTK_MAJOR_VERSION == 3
-#define GTK_GETTEXT_DOMAIN "gtk30"
-#endif
+ if (self->adaptive_mode == EPHY_ADAPTIVE_MODE_NARROW) {
+ scaled = pango_attr_scale_new (PANGO_SCALE_SMALL);
+ pango_attr_list_insert (attrs, scaled);
+ }
-static void
-entry_populate_popup_cb (GtkEntry *entry,
- GtkMenu *menu,
- EphyLocationEntry *lentry)
-{
- GtkWidget *clear_menuitem;
- GtkWidget *undo_menuitem;
- GtkWidget *redo_menuitem;
- GtkWidget *paste_and_go_menuitem;
- GtkWidget *separator;
- GtkWidget *paste_menuitem = NULL;
- GList *children, *item;
- int pos = 0, sep = 0;
- gboolean is_editable;
+ if (gtk_widget_has_focus (self->url_entry))
+ goto out;
- /* Translators: the mnemonic shouldn't conflict with any of the
- * standard items in the GtkEntry context menu (Cut, Copy, Paste, Delete,
- * Select All, Input Methods and Insert Unicode control character.)
- */
- clear_menuitem = gtk_menu_item_new_with_mnemonic (_("Cl_ear"));
- g_signal_connect (clear_menuitem, "activate",
- G_CALLBACK (entry_clear_activate_cb), lentry);
- is_editable = gtk_editable_get_editable (GTK_EDITABLE (entry));
- gtk_widget_set_sensitive (clear_menuitem, is_editable);
- gtk_widget_show (clear_menuitem);
+ uri = g_uri_parse (text, G_URI_FLAGS_NONE, NULL);
+ if (!uri)
+ goto out;
- /* search for the 2nd separator (the one after Select All) in the context
- * menu, and insert this menu item before it.
- * It's a bit of a hack, but there seems to be no better way to do it :/
- */
- children = gtk_container_get_children (GTK_CONTAINER (menu));
- for (item = children; item != NULL && sep < 2; item = item->next, pos++) {
- if (GTK_IS_SEPARATOR_MENU_ITEM (item->data))
- sep++;
- }
- g_list_free (children);
+ host = g_uri_get_host (uri);
+ if (!host || strlen (host) == 0)
+ goto out;
- gtk_menu_shell_insert (GTK_MENU_SHELL (menu), clear_menuitem, pos - 1);
+ base_domain = soup_tld_get_base_domain (host, NULL);
+ if (!base_domain)
+ goto out;
- paste_and_go_menuitem = gtk_menu_item_new_with_mnemonic (_("Paste and _Go"));
+ sub_string = strstr (text, base_domain);
+ if (!sub_string)
+ goto out;
- /* Search for the Paste menu item and insert right after it. */
- children = gtk_container_get_children (GTK_CONTAINER (menu));
- for (item = children, pos = 0; item != NULL; item = item->next, pos++) {
- if (g_strcmp0 (gtk_menu_item_get_label (item->data), g_dgettext (GTK_GETTEXT_DOMAIN, "_Paste")) == 0) {
- paste_menuitem = item->data;
- break;
- }
- }
- g_assert (paste_menuitem != NULL);
- g_list_free (children);
+ /* Complete text is dimmed */
+ color_dimmed = pango_attr_foreground_alpha_new (32768);
+ pango_attr_list_insert (attrs, color_dimmed);
- g_signal_connect (paste_and_go_menuitem, "activate",
- G_CALLBACK (entry_paste_and_go_activate_cb), lentry);
- lentry->paste_binding = g_object_bind_property (paste_menuitem, "sensitive",
- paste_and_go_menuitem, "sensitive",
- G_BINDING_SYNC_CREATE);
- gtk_widget_show (paste_and_go_menuitem);
- gtk_menu_shell_insert (GTK_MENU_SHELL (menu), paste_and_go_menuitem, pos + 1);
+ /* Base domain with normal style */
+ color_normal = pango_attr_foreground_alpha_new (65535);
+ color_normal->start_index = sub_string - text;
+ color_normal->end_index = color_normal->start_index + strlen (base_domain);
+ pango_attr_list_insert (attrs, color_normal);
- undo_menuitem = gtk_menu_item_new_with_mnemonic (_("_Undo"));
- gtk_widget_set_sensitive (undo_menuitem, lentry->user_changed);
- g_signal_connect (undo_menuitem, "activate",
- G_CALLBACK (entry_undo_activate_cb), lentry);
- gtk_widget_show (undo_menuitem);
- gtk_menu_shell_insert (GTK_MENU_SHELL (menu), undo_menuitem, 0);
+out:
+ gtk_entry_set_attributes (GTK_ENTRY (self->url_entry), attrs);
+ pango_attr_list_unref (attrs);
+}
- redo_menuitem = gtk_menu_item_new_with_mnemonic (_("_Redo"));
- gtk_widget_set_sensitive (redo_menuitem, lentry->can_redo);
- g_signal_connect (redo_menuitem, "activate",
- G_CALLBACK (entry_redo_activate_cb), lentry);
- gtk_widget_show (redo_menuitem);
- gtk_menu_shell_insert (GTK_MENU_SHELL (menu), redo_menuitem, 1);
+static gboolean
+entry_focus_in_event (GtkWidget *widget,
+ GdkEvent *event,
+ gpointer user_data)
+{
+ EphyLocationEntry *self = EPHY_LOCATION_ENTRY (user_data);
- separator = gtk_separator_menu_item_new ();
- gtk_widget_show (separator);
- gtk_menu_shell_insert (GTK_MENU_SHELL (menu), separator, 2);
+ update_entry_style (self);
+ return GDK_EVENT_PROPAGATE;
+}
+
+static gboolean
+entry_focus_out_event (GtkWidget *widget,
+ GdkEvent *event,
+ gpointer user_data)
+{
+ EphyLocationEntry *entry = EPHY_LOCATION_ENTRY (user_data);
+
+ update_entry_style (entry);
+
+ if (((GdkEventButton *)event)->button != GDK_BUTTON_PRIMARY)
+ return GDK_EVENT_PROPAGATE;
+
+ /* Unselect. */
+ gtk_editable_select_region (GTK_EDITABLE (entry->url_entry), 0, 0);
+
+ if (entry->button_release_is_blocked) {
+ g_signal_handlers_unblock_by_func (widget, G_CALLBACK (entry_button_release), entry);
+ entry->button_release_is_blocked = FALSE;
+ }
+
+ return GDK_EVENT_PROPAGATE;
}
static gboolean
@@ -896,6 +594,47 @@ event_button_press_event_cb (GtkWidget *widget,
}
static void
+enter_notify_cb (GtkWidget *widget,
+ GdkEvent *event,
+ gpointer user_data)
+{
+ gtk_widget_set_state_flags (widget, GTK_STATE_FLAG_PRELIGHT, FALSE);
+}
+
+static void
+leave_notify_cb (GtkWidget *widget,
+ GdkEvent *event,
+ gpointer user_data)
+{
+ gtk_widget_unset_state_flags (widget, GTK_STATE_FLAG_PRELIGHT);
+}
+
+static void
+editable_changed_cb (GtkEditable *editable,
+ EphyLocationEntry *entry)
+{
+ if (entry->block_update == TRUE)
+ return;
+ else {
+ entry->user_changed = TRUE;
+ entry->can_redo = FALSE;
+ }
+
+ g_clear_pointer (&entry->jump_tab, g_free);
+
+ g_signal_emit (entry, signals[USER_CHANGED], 0);
+}
+
+static void
+reader_mode_clicked_cb (EphyLocationEntry *self)
+{
+ self->reader_mode_active = !self->reader_mode_active;
+
+ g_signal_emit (G_OBJECT (self), signals[READER_MODE_CHANGED], 0,
+ self->reader_mode_active);
+}
+
+static void
ephy_location_entry_suggestion_activated (DzlSuggestionEntry *entry,
DzlSuggestion *arg1,
gpointer user_data)
@@ -918,72 +657,153 @@ ephy_location_entry_suggestion_activated (DzlSuggestionEntry *entry,
}
static void
-suggestion_selected (DzlSuggestionEntry *entry,
- DzlSuggestion *suggestion,
- gpointer user_data)
+activate_cb (EphyLocationEntry *self)
{
- EphyLocationEntry *lentry = EPHY_LOCATION_ENTRY (user_data);
- const gchar *uri = dzl_suggestion_get_id (suggestion);
-
- g_signal_handlers_block_by_func (entry, G_CALLBACK (editable_changed_cb), user_data);
- g_clear_pointer (&lentry->jump_tab, g_free);
+ GdkModifierType modifiers;
- if (g_str_has_prefix (uri, "ephy-tab://")) {
- lentry->jump_tab = g_strdup (uri);
- gtk_entry_set_text (GTK_ENTRY (entry), dzl_suggestion_get_subtitle (suggestion));
- } else {
- gtk_entry_set_text (GTK_ENTRY (entry), uri);
- }
- gtk_editable_set_position (GTK_EDITABLE (entry), -1);
- g_signal_handlers_unblock_by_func (entry, G_CALLBACK (editable_changed_cb), user_data);
+ ephy_gui_get_current_event (NULL, &modifiers, NULL, NULL);
- schedule_dns_prefetch (lentry, uri);
+ g_signal_emit (G_OBJECT (self), signals[ACTIVATE], 0, modifiers);
}
static void
-enter_notify_cb (GtkWidget *widget,
- GdkEvent *event,
- gpointer user_data)
+update_reader_icon (EphyLocationEntry *entry)
{
- gtk_widget_set_state_flags (widget, GTK_STATE_FLAG_PRELIGHT, FALSE);
+ GtkIconTheme *theme;
+ const gchar *name;
+
+ theme = gtk_icon_theme_get_default ();
+
+ if (gtk_icon_theme_has_icon (theme, "view-reader-symbolic"))
+ name = "view-reader-symbolic";
+ else
+ name = "ephy-reader-mode-symbolic";
+
+ gtk_image_set_from_icon_name (GTK_IMAGE (entry->reader_mode_icon),
+ name, GTK_ICON_SIZE_MENU);
}
static void
-leave_notify_cb (GtkWidget *widget,
- GdkEvent *event,
- gpointer user_data)
+paste_received (GtkClipboard *clipboard,
+ const gchar *text,
+ EphyLocationEntry *entry)
{
- gtk_widget_unset_state_flags (widget, GTK_STATE_FLAG_PRELIGHT);
+ if (text) {
+ g_signal_handlers_block_by_func (entry->url_entry, G_CALLBACK (editable_changed_cb), entry);
+ gtk_entry_set_text (GTK_ENTRY (entry->url_entry), text);
+ ephy_location_entry_activate (entry);
+ g_signal_handlers_unblock_by_func (entry->url_entry, G_CALLBACK (editable_changed_cb), entry);
+ }
}
static void
-handle_forward_tab_key (GtkWidget *widget,
- gpointer user_data)
+entry_paste_and_go_activate_cb (GtkMenuItem *item,
+ EphyLocationEntry *entry)
{
- EphyLocationEntry *entry = EPHY_LOCATION_ENTRY (user_data);
- GtkWidget *popover;
+ GtkClipboard *clipboard;
- popover = dzl_suggestion_entry_get_popover (DZL_SUGGESTION_ENTRY (entry->url_entry));
- if (gtk_widget_is_visible (popover)) {
- g_signal_emit_by_name (entry->url_entry, "move-suggestion", 1, G_TYPE_INT, 1, G_TYPE_NONE);
- } else {
- gtk_widget_child_focus (gtk_widget_get_toplevel (GTK_WIDGET (entry)), GTK_DIR_TAB_FORWARD);
- }
+ clipboard = gtk_clipboard_get_default (gdk_display_get_default ());
+ gtk_clipboard_request_text (clipboard,
+ (GtkClipboardTextReceivedFunc)paste_received,
+ entry);
}
static void
-handle_backward_tab_key (GtkWidget *widget,
- gpointer user_data)
+entry_clear_activate_cb (GtkMenuItem *item,
+ EphyLocationEntry *entry)
{
- EphyLocationEntry *entry = EPHY_LOCATION_ENTRY (user_data);
- GtkWidget *popover;
+ entry->block_update = TRUE;
+ g_signal_handlers_block_by_func (entry->url_entry, G_CALLBACK (editable_changed_cb), entry);
+ gtk_entry_set_text (GTK_ENTRY (entry->url_entry), "");
+ g_signal_handlers_unblock_by_func (entry->url_entry, G_CALLBACK (editable_changed_cb), entry);
+ entry->block_update = FALSE;
+ entry->user_changed = TRUE;
+}
- popover = dzl_suggestion_entry_get_popover (DZL_SUGGESTION_ENTRY (entry->url_entry));
- if (gtk_widget_is_visible (popover)) {
- g_signal_emit_by_name (entry->url_entry, "move-suggestion", -1, G_TYPE_INT, 1, G_TYPE_NONE);
- } else {
- gtk_widget_child_focus (gtk_widget_get_toplevel (GTK_WIDGET (entry)), GTK_DIR_TAB_BACKWARD);
+/* The build should fail here each time when upgrading to a new major version
+ * of GTK+, so that we don't forget to update this domain.
+ */
+#if GTK_MAJOR_VERSION == 3
+#define GTK_GETTEXT_DOMAIN "gtk30"
+#endif
+
+static void
+entry_populate_popup_cb (GtkEntry *entry,
+ GtkMenu *menu,
+ EphyLocationEntry *lentry)
+{
+ GtkWidget *clear_menuitem;
+ GtkWidget *undo_menuitem;
+ GtkWidget *redo_menuitem;
+ GtkWidget *paste_and_go_menuitem;
+ GtkWidget *separator;
+ GtkWidget *paste_menuitem = NULL;
+ GList *children, *item;
+ int pos = 0, sep = 0;
+ gboolean is_editable;
+
+ /* Translators: the mnemonic shouldn't conflict with any of the
+ * standard items in the GtkEntry context menu (Cut, Copy, Paste, Delete,
+ * Select All, Input Methods and Insert Unicode control character.)
+ */
+ clear_menuitem = gtk_menu_item_new_with_mnemonic (_("Cl_ear"));
+ g_signal_connect (clear_menuitem, "activate",
+ G_CALLBACK (entry_clear_activate_cb), lentry);
+ is_editable = gtk_editable_get_editable (GTK_EDITABLE (entry));
+ gtk_widget_set_sensitive (clear_menuitem, is_editable);
+ gtk_widget_show (clear_menuitem);
+
+ /* search for the 2nd separator (the one after Select All) in the context
+ * menu, and insert this menu item before it.
+ * It's a bit of a hack, but there seems to be no better way to do it :/
+ */
+ children = gtk_container_get_children (GTK_CONTAINER (menu));
+ for (item = children; item != NULL && sep < 2; item = item->next, pos++) {
+ if (GTK_IS_SEPARATOR_MENU_ITEM (item->data))
+ sep++;
+ }
+ g_list_free (children);
+
+ gtk_menu_shell_insert (GTK_MENU_SHELL (menu), clear_menuitem, pos - 1);
+
+ paste_and_go_menuitem = gtk_menu_item_new_with_mnemonic (_("Paste and _Go"));
+
+ /* Search for the Paste menu item and insert right after it. */
+ children = gtk_container_get_children (GTK_CONTAINER (menu));
+ for (item = children, pos = 0; item != NULL; item = item->next, pos++) {
+ if (g_strcmp0 (gtk_menu_item_get_label (item->data), g_dgettext (GTK_GETTEXT_DOMAIN, "_Paste")) == 0) {
+ paste_menuitem = item->data;
+ break;
+ }
}
+ g_assert (paste_menuitem != NULL);
+ g_list_free (children);
+
+ g_signal_connect (paste_and_go_menuitem, "activate",
+ G_CALLBACK (entry_paste_and_go_activate_cb), lentry);
+ lentry->paste_binding = g_object_bind_property (paste_menuitem, "sensitive",
+ paste_and_go_menuitem, "sensitive",
+ G_BINDING_SYNC_CREATE);
+ gtk_widget_show (paste_and_go_menuitem);
+ gtk_menu_shell_insert (GTK_MENU_SHELL (menu), paste_and_go_menuitem, pos + 1);
+
+ undo_menuitem = gtk_menu_item_new_with_mnemonic (_("_Undo"));
+ gtk_widget_set_sensitive (undo_menuitem, lentry->user_changed);
+ g_signal_connect (undo_menuitem, "activate",
+ G_CALLBACK (entry_undo_activate_cb), lentry);
+ gtk_widget_show (undo_menuitem);
+ gtk_menu_shell_insert (GTK_MENU_SHELL (menu), undo_menuitem, 0);
+
+ redo_menuitem = gtk_menu_item_new_with_mnemonic (_("_Redo"));
+ gtk_widget_set_sensitive (redo_menuitem, lentry->can_redo);
+ g_signal_connect (redo_menuitem, "activate",
+ G_CALLBACK (entry_redo_activate_cb), lentry);
+ gtk_widget_show (redo_menuitem);
+ gtk_menu_shell_insert (GTK_MENU_SHELL (menu), redo_menuitem, 1);
+
+ separator = gtk_separator_menu_item_new ();
+ gtk_widget_show (separator);
+ gtk_menu_shell_insert (GTK_MENU_SHELL (menu), separator, 2);
}
static void
@@ -1020,39 +840,186 @@ position_func (DzlSuggestionEntry *self,
}
static void
-update_reader_icon (EphyLocationEntry *entry)
+ephy_location_entry_get_preferred_height (GtkWidget *widget,
+ gint *minimum_height,
+ gint *natural_height)
{
- GtkIconTheme *theme;
- const gchar *name;
+ EphyLocationEntry *entry = EPHY_LOCATION_ENTRY (widget);
- theme = gtk_icon_theme_get_default ();
+ gtk_widget_get_preferred_height (entry->url_entry, minimum_height, natural_height);
+}
- if (gtk_icon_theme_has_icon (theme, "view-reader-symbolic"))
- name = "view-reader-symbolic";
- else
- name = "ephy-reader-mode-symbolic";
+static void
+ephy_location_entry_set_property (GObject *object,
+ guint prop_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ EphyLocationEntry *entry = EPHY_LOCATION_ENTRY (object);
- gtk_image_set_from_icon_name (GTK_IMAGE (entry->reader_mode_icon),
- name, GTK_ICON_SIZE_MENU);
+ switch (prop_id) {
+ case PROP_ADDRESS:
+ ephy_title_widget_set_address (EPHY_TITLE_WIDGET (entry),
+ g_value_get_string (value));
+ break;
+ case PROP_SECURITY_LEVEL:
+ ephy_title_widget_set_security_level (EPHY_TITLE_WIDGET (entry),
+ g_value_get_enum (value));
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ }
}
static void
-reader_mode_clicked_cb (EphyLocationEntry *self)
+ephy_location_entry_get_property (GObject *object,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec)
{
- self->reader_mode_active = !self->reader_mode_active;
+ EphyLocationEntry *entry = EPHY_LOCATION_ENTRY (object);
- g_signal_emit (G_OBJECT (self), signals[READER_MODE_CHANGED], 0,
- self->reader_mode_active);
+ switch (prop_id) {
+ case PROP_ADDRESS:
+ g_value_set_string (value, ephy_title_widget_get_address (EPHY_TITLE_WIDGET (entry)));
+ break;
+ case PROP_SECURITY_LEVEL:
+ g_value_set_enum (value, ephy_title_widget_get_security_level (EPHY_TITLE_WIDGET (entry)));
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ }
}
static void
-activate_cb (EphyLocationEntry *self)
+ephy_location_entry_constructed (GObject *object)
{
- GdkModifierType modifiers;
+ EphyLocationEntry *entry = EPHY_LOCATION_ENTRY (object);
- ephy_gui_get_current_event (NULL, &modifiers, NULL, NULL);
+ G_OBJECT_CLASS (ephy_location_entry_parent_class)->constructed (object);
- g_signal_emit (G_OBJECT (self), signals[ACTIVATE], 0, modifiers);
+ gtk_entry_set_input_hints (GTK_ENTRY (entry->url_entry), GTK_INPUT_HINT_NO_EMOJI);
+}
+
+static void
+ephy_location_entry_dispose (GObject *object)
+{
+ EphyLocationEntry *entry = EPHY_LOCATION_ENTRY (object);
+
+ g_clear_handle_id (&entry->progress_timeout, g_source_remove);
+
+ g_clear_object (&entry->css_provider);
+
+ G_OBJECT_CLASS (ephy_location_entry_parent_class)->dispose (object);
+}
+
+static void
+ephy_location_entry_finalize (GObject *object)
+{
+ EphyLocationEntry *entry = EPHY_LOCATION_ENTRY (object);
+
+ g_free (entry->saved_text);
+ g_clear_pointer (&entry->jump_tab, g_free);
+
+ G_OBJECT_CLASS (ephy_location_entry_parent_class)->finalize (object);
+}
+
+static void
+ephy_location_entry_class_init (EphyLocationEntryClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+ GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
+
+ object_class->get_property = ephy_location_entry_get_property;
+ object_class->set_property = ephy_location_entry_set_property;
+ object_class->constructed = ephy_location_entry_constructed;
+ object_class->finalize = ephy_location_entry_finalize;
+ object_class->dispose = ephy_location_entry_dispose;
+
+ widget_class->get_preferred_height = ephy_location_entry_get_preferred_height;
+
+ g_object_class_override_property (object_class, PROP_ADDRESS, "address");
+ g_object_class_override_property (object_class, PROP_SECURITY_LEVEL, "security-level");
+
+ /**
+ * EphyLocationEntry::activate:
+ * @flags: the #GdkModifierType from the activation event
+ *
+ * Emitted when the entry is activated.
+ *
+ */
+ signals[ACTIVATE] = g_signal_new ("activate", G_OBJECT_CLASS_TYPE (klass),
+ G_SIGNAL_RUN_FIRST | G_SIGNAL_RUN_LAST,
+ 0, NULL, NULL, NULL,
+ G_TYPE_NONE,
+ 1,
+ GDK_TYPE_MODIFIER_TYPE);
+
+ /**
+ * EphyLocationEntry::user-changed:
+ * @entry: the object on which the signal is emitted
+ *
+ * Emitted when the user changes the contents of the internal #GtkEntry
+ *
+ */
+ signals[USER_CHANGED] = g_signal_new ("user_changed", G_OBJECT_CLASS_TYPE (klass),
+ G_SIGNAL_RUN_FIRST | G_SIGNAL_RUN_LAST,
+ 0, NULL, NULL, NULL,
+ G_TYPE_NONE,
+ 0,
+ G_TYPE_NONE);
+
+ /**
+ * EphyLocationEntry::reader-mode-changed:
+ * @entry: the object on which the signal is emitted
+ * @active: whether reader mode is active
+ *
+ * Emitted when the user clicks the reader mode icon inside the
+ * #EphyLocationEntry.
+ *
+ */
+ signals[READER_MODE_CHANGED] = g_signal_new ("reader-mode-changed", G_OBJECT_CLASS_TYPE (klass),
+ G_SIGNAL_RUN_FIRST | G_SIGNAL_RUN_LAST,
+ 0, NULL, NULL, NULL,
+ G_TYPE_NONE,
+ 1,
+ G_TYPE_BOOLEAN);
+
+ /**
+ * EphyLocationEntry::get-location:
+ * @entry: the object on which the signal is emitted
+ * Returns: the current page address as a string
+ *
+ * For drag and drop purposes, the location bar will request you the
+ * real address of where it is pointing to. The signal handler for this
+ * function should return the address of the currently loaded site.
+ *
+ */
+ signals[GET_LOCATION] = g_signal_new ("get-location", G_OBJECT_CLASS_TYPE (klass),
+ G_SIGNAL_RUN_FIRST | G_SIGNAL_RUN_LAST,
+ 0, ephy_signal_accumulator_string,
+ NULL, NULL,
+ G_TYPE_STRING,
+ 0,
+ G_TYPE_NONE);
+
+ /**
+ * EphyLocationEntry::get-title:
+ * @entry: the object on which the signal is emitted
+ * Returns: the current page title as a string
+ *
+ * For drag and drop purposes, the location bar will request you the
+ * title of where it is pointing to. The signal handler for this
+ * function should return the title of the currently loaded site.
+ *
+ */
+ signals[GET_TITLE] = g_signal_new ("get-title", G_OBJECT_CLASS_TYPE (klass),
+ G_SIGNAL_RUN_FIRST | G_SIGNAL_RUN_LAST,
+ 0, ephy_signal_accumulator_string,
+ NULL, NULL,
+ G_TYPE_STRING,
+ 0,
+ G_TYPE_NONE);
}
static void
@@ -1198,93 +1165,124 @@ ephy_location_entry_init (EphyLocationEntry *le)
ephy_location_entry_construct_contents (le);
}
-GtkWidget *
-ephy_location_entry_new (void)
+static const char *
+ephy_location_entry_title_widget_get_address (EphyTitleWidget *widget)
{
- return GTK_WIDGET (g_object_new (EPHY_TYPE_LOCATION_ENTRY, NULL));
-}
+ EphyLocationEntry *entry = EPHY_LOCATION_ENTRY (widget);
-typedef struct {
- GUri *uri;
- EphyLocationEntry *entry;
-} PrefetchHelper;
+ g_assert (entry);
+
+ return gtk_entry_get_text (GTK_ENTRY (entry->url_entry));
+}
static void
-free_prefetch_helper (PrefetchHelper *helper)
+ephy_location_entry_title_widget_set_address (EphyTitleWidget *widget,
+ const char *address)
{
- g_uri_unref (helper->uri);
- g_object_unref (helper->entry);
- g_free (helper);
+ EphyLocationEntry *entry = EPHY_LOCATION_ENTRY (widget);
+ GtkClipboard *clipboard;
+ const char *text;
+ g_autofree char *effective_text = NULL;
+ g_autofree char *selection = NULL;
+ int start, end;
+ const char *final_text;
+
+ g_assert (widget);
+
+ /* Setting a new text will clear the clipboard. This makes it impossible
+ * to copy&paste from the location entry of one tab into another tab, see
+ * bug #155824. So we save the selection iff the clipboard was owned by
+ * the location entry.
+ */
+ if (gtk_widget_get_realized (GTK_WIDGET (entry))) {
+ clipboard = gtk_widget_get_clipboard (GTK_WIDGET (entry->url_entry),
+ GDK_SELECTION_PRIMARY);
+ g_assert (clipboard != NULL);
+
+ if (gtk_clipboard_get_owner (clipboard) == G_OBJECT (entry->url_entry) &&
+ gtk_editable_get_selection_bounds (GTK_EDITABLE (entry->url_entry),
+ &start, &end)) {
+ selection = gtk_editable_get_chars (GTK_EDITABLE (entry->url_entry),
+ start, end);
+ }
+ }
+
+ if (address != NULL) {
+ if (g_str_has_prefix (address, EPHY_ABOUT_SCHEME))
+ effective_text = g_strdup_printf ("about:%s",
+ address + strlen (EPHY_ABOUT_SCHEME) + 1);
+ text = address;
+ } else {
+ text = "";
+ }
+
+ final_text = effective_text ? effective_text : text;
+
+ entry->block_update = TRUE;
+ g_signal_handlers_block_by_func (entry->url_entry, G_CALLBACK (editable_changed_cb), entry);
+ gtk_entry_set_text (GTK_ENTRY (entry->url_entry), final_text);
+ update_entry_style (entry);
+ g_signal_handlers_unblock_by_func (entry->url_entry, G_CALLBACK (editable_changed_cb), entry);
+
+ dzl_suggestion_entry_hide_suggestions (DZL_SUGGESTION_ENTRY (entry->url_entry));
+ entry->block_update = FALSE;
+
+ /* Now restore the selection.
+ * Note that it's not owned by the entry anymore!
+ */
+ if (selection != NULL) {
+ gtk_clipboard_set_text (gtk_clipboard_get (GDK_SELECTION_PRIMARY),
+ selection, strlen (selection));
+ }
}
-static gboolean
-do_dns_prefetch (PrefetchHelper *helper)
+static EphySecurityLevel
+ephy_location_entry_title_widget_get_security_level (EphyTitleWidget *widget)
{
- EphyEmbedShell *shell = ephy_embed_shell_get_default ();
-
- if (helper->uri)
- webkit_web_context_prefetch_dns (ephy_embed_shell_get_web_context (shell), g_uri_get_host (helper->uri));
+ EphyLocationEntry *entry = EPHY_LOCATION_ENTRY (widget);
- helper->entry->dns_prefetch_handle_id = 0;
+ g_assert (entry);
- return G_SOURCE_REMOVE;
+ return entry->security_level;
}
-/*
- * Note: As we do not have access to WebKitNetworkProxyMode, and because
- * Epiphany does not ever change it, we are just checking system default proxy.
- */
static void
-proxy_resolver_ready_cb (GObject *object,
- GAsyncResult *result,
- gpointer user_data)
+ephy_location_entry_title_widget_set_security_level (EphyTitleWidget *widget,
+ EphySecurityLevel security_level)
+
{
- PrefetchHelper *helper = user_data;
- GProxyResolver *resolver = G_PROXY_RESOLVER (object);
- g_autoptr (GError) error = NULL;
- g_auto (GStrv) proxies = NULL;
+ EphyLocationEntry *entry = EPHY_LOCATION_ENTRY (widget);
+ const char *icon_name;
- proxies = g_proxy_resolver_lookup_finish (resolver, result, &error);
- if (error != NULL) {
- free_prefetch_helper (helper);
- return;
- }
+ g_assert (entry);
- if (proxies != NULL && (g_strv_length (proxies) > 1 || g_strcmp0 (proxies[0], "direct://") != 0)) {
- free_prefetch_helper (helper);
- return;
+ if (!entry->reader_mode_active) {
+ icon_name = ephy_security_level_to_icon_name (security_level);
+ gtk_entry_set_icon_from_icon_name (GTK_ENTRY (entry->url_entry),
+ GTK_ENTRY_ICON_PRIMARY,
+ icon_name);
+ } else {
+ gtk_entry_set_icon_from_icon_name (GTK_ENTRY (entry->url_entry),
+ GTK_ENTRY_ICON_PRIMARY,
+ NULL);
}
- g_clear_handle_id (&helper->entry->dns_prefetch_handle_id, g_source_remove);
- helper->entry->dns_prefetch_handle_id =
- g_timeout_add_full (G_PRIORITY_DEFAULT,
- 250,
- (GSourceFunc)do_dns_prefetch,
- helper,
- (GDestroyNotify)free_prefetch_helper);
- g_source_set_name_by_id (helper->entry->dns_prefetch_handle_id, "[epiphany] do_dns_prefetch");
+ entry->security_level = security_level;
}
static void
-schedule_dns_prefetch (EphyLocationEntry *entry,
- const gchar *url)
+ephy_location_entry_title_widget_interface_init (EphyTitleWidgetInterface *iface)
{
- GProxyResolver *resolver = g_proxy_resolver_get_default ();
- PrefetchHelper *helper;
- g_autoptr (GUri) uri = NULL;
-
- if (resolver == NULL)
- return;
-
- uri = g_uri_parse (url, G_URI_FLAGS_NONE, NULL);
- if (!uri || !g_uri_get_host (uri))
- return;
-
- helper = g_new0 (PrefetchHelper, 1);
- helper->entry = g_object_ref (entry);
- helper->uri = g_steal_pointer (&uri);
+ iface->get_address = ephy_location_entry_title_widget_get_address;
+ iface->set_address = ephy_location_entry_title_widget_set_address;
+ iface->get_security_level = ephy_location_entry_title_widget_get_security_level;
+ iface->set_security_level = ephy_location_entry_title_widget_set_security_level;
+}
- g_proxy_resolver_lookup_async (resolver, url, NULL, proxy_resolver_ready_cb, helper);
+GtkWidget *
+ephy_location_entry_new (void)
+{
+ return GTK_WIDGET (g_object_new (EPHY_TYPE_LOCATION_ENTRY, NULL));
}
/**