...
 
Commits (49)
3.24.5 - September 29, 2017
===========================
- Fix search engine dialog, which has been borked since 3.24.3 (#787458)
- Don't disable navigation actions when history is cleared (#788329)
- Fix bookmarks import crash when there's no Firefox profile
- Disable emoji chooser in address bar if built with GTK+ >= 3.20.20
- Make json-glib optional (it's only needed for experimental sync support)
3.24.4 - September 3, 2017
==========================
- Fix crash in bookmarks popover (#780549)
- Fix crash when clicking on security icon after deleting address (#785338)
- Disable Alt+Home shortcut for web apps (#785996)
- Adblocker must not block main resource during redirects (#787011)
- Updated translations
3.24.3 - July 17, 2017
======================
- Fix floating status bar blocking clicks (#668493)
- Add [Shift+]Ctrl+Tab shortcuts for switching tabs (#762631)
- Fix crash when download fails (#778653)
- Restore address bar search for bookmarks tags (#781746)
- Fix notifications permissions being forgotten for web apps (#782386)
- Fix tags with no bookmarks appearing in bookmarks popover
- Fix crash if search engine settings get desynced
- Updated translations
3.24.2 - May 8, 2017
====================
- Decode last component of URIs to determine file names for saving (#780086)
- Disable Ctrl+T in application mode (#781440)
- Do not use a popover for the tab selection menu, to allow scrolling it
- Add hidden setting for disabling quirks mode
- Updated translations
3.24.1 - April 10, 2017
=======================
......
......@@ -28,9 +28,9 @@ AX_REQUIRE_DEFINED([PKG_CHECK_MODULES])
AX_REQUIRE_DEFINED([YELP_HELP_INIT])
dnl Must be a valid git tag
m4_define([epiphany_changelog_start],[3.21.4])
m4_define([epiphany_changelog_start],[3.24.0])
AC_INIT([GNOME Web Browser],[3.24.1],[http://bugzilla.gnome.org/enter_bug.cgi?product=epiphany],[epiphany])
AC_INIT([GNOME Web Browser],[3.24.5],[http://bugzilla.gnome.org/enter_bug.cgi?product=epiphany],[epiphany])
AX_IS_RELEASE([git-directory])
AC_PREREQ([2.69])
......@@ -95,7 +95,7 @@ LIBGD_INIT([_view-common notification static])
LT_LIB_M
GLIB_REQUIRED=2.46.0
GTK_REQUIRED=3.22.0
GTK_REQUIRED=3.22.13
WEBKITGTK_REQUIRED=2.15.90
PKG_CHECK_MODULES([CAIRO], [cairo >= 1.2])
......@@ -108,7 +108,6 @@ PKG_CHECK_MODULES([GNOME_DESKTOP], [gnome-desktop-3.0 >= 2.91.2])
PKG_CHECK_MODULES([GTK], [gtk+-3.0 >= $GTK_REQUIRED])
PKG_CHECK_MODULES([GTK_UNIX_PRINT], [gtk+-unix-print-3.0 >= $GTK_REQUIRED])
PKG_CHECK_MODULES([ICU_UC], [icu-uc >= 4.6])
PKG_CHECK_MODULES([JSON_GLIB], [json-glib-1.0 >= 1.2.0])
PKG_CHECK_MODULES([LIBNOTIFY], [libnotify >= 0.5.1])
PKG_CHECK_MODULES([LIBSECRET], [libsecret-1 >= 0.14])
PKG_CHECK_MODULES([LIBSOUP], [libsoup-2.4 >= 2.48.0])
......@@ -140,7 +139,8 @@ AC_ARG_ENABLE([firefox-sync],
[enable_firefox_sync=no]
)
AS_IF([test "x$enable_firefox_sync" = "xyes"],
[PKG_CHECK_MODULES([HOGWEED], [hogweed >= 3.2])
[PKG_CHECK_MODULES([JSON_GLIB], [json-glib-1.0 >= 1.2.0])
PKG_CHECK_MODULES([HOGWEED], [hogweed >= 3.2])
PKG_CHECK_MODULES([NETTLE], [nettle >= 3.2])
AC_DEFINE([ENABLE_SYNC], [1], [Define if Firefox Sync support is enabled])]
)
......
......@@ -226,6 +226,9 @@
<summary>Remember passwords</summary>
<description>Whether to store and prefill passwords in websites.</description>
</key>
<key type="b" name="enable-site-specific-quirks">
<default>true</default>
</key>
</schema>
<schema id="org.gnome.Epiphany.state">
<key type="s" name="download-dir">
......
......@@ -159,12 +159,6 @@ download_estimated_progress_changed_cb (EphyDownloadsManager *manager)
g_signal_emit (manager, signals[ESTIMATED_PROGRESS_CHANGED], 0);
}
static void
download_created_destination_cb (EphyDownloadsManager *manager)
{
ephy_downloads_manager_acquire_session_inhibitor (manager);
}
void
ephy_downloads_manager_add_download (EphyDownloadsManager *manager,
EphyDownload *download)
......@@ -177,6 +171,8 @@ ephy_downloads_manager_add_download (EphyDownloadsManager *manager,
if (g_list_find (manager->downloads, download))
return;
ephy_downloads_manager_acquire_session_inhibitor (manager);
manager->downloads = g_list_prepend (manager->downloads, g_object_ref (download));
g_signal_connect (download, "completed",
G_CALLBACK (download_completed_cb),
......@@ -189,9 +185,6 @@ ephy_downloads_manager_add_download (EphyDownloadsManager *manager,
g_signal_connect_swapped (wk_download, "notify::estimated-progress",
G_CALLBACK (download_estimated_progress_changed_cb),
manager);
g_signal_connect_swapped (wk_download, "created-destination",
G_CALLBACK (download_created_destination_cb),
manager);
g_signal_emit (manager, signals[DOWNLOAD_ADDED], 0, download);
g_signal_emit (manager, signals[ESTIMATED_PROGRESS_CHANGED], 0);
}
......
......@@ -561,7 +561,6 @@ ephy_embed_prefs_init (gpointer user_data)
webkit_settings = webkit_settings_new_with_settings ("enable-developer-extras", TRUE,
"enable-fullscreen", TRUE,
"enable-javascript", TRUE,
"enable-site-specific-quirks", TRUE,
"enable-dns-prefetching", TRUE,
"javascript-can-open-windows-automatically", TRUE,
NULL);
......@@ -621,6 +620,10 @@ ephy_embed_prefs_init (gpointer user_data)
EPHY_PREFS_WEB_ENABLE_SMOOTH_SCROLLING,
webkit_settings, "enable-smooth-scrolling",
G_SETTINGS_BIND_GET);
g_settings_bind (EPHY_SETTINGS_WEB,
EPHY_PREFS_WEB_ENABLE_SITE_SPECIFIC_QUIRKS,
webkit_settings, "enable-site-specific-quirks",
G_SETTINGS_BIND_GET);
return webkit_settings;
}
......
......@@ -1392,11 +1392,7 @@ ephy_embed_shell_launch_handler (EphyEmbedShell *shell,
/* Do not allow recursive calls into the browser, they can lead to
* infinite loops and they should never happen anyway. */
/* FIXME: Should use g_application_get_application_id() here instead of
* hardcoding epiphany.desktop. But first, we have to rename the desktop file.
*/
if (!app || g_strcmp0 (g_app_info_get_id (app), "epiphany.desktop") == 0)
if (!app || g_strcmp0 (g_app_info_get_id (app), "org.gnome.Epiphany.desktop") == 0)
return ret;
list = g_list_append (list, file);
......
......@@ -270,15 +270,13 @@ ephy_embed_utils_autosearch_address (const char *search_key)
{
char *query_param;
const char *address_search;
char *default_name;
char *effective_address;
EphyEmbedShell *shell;
EphySearchEngineManager *search_engine_manager;
shell = ephy_embed_shell_get_default ();
search_engine_manager = ephy_embed_shell_get_search_engine_manager (shell);
default_name = ephy_search_engine_manager_get_default_engine (search_engine_manager);
address_search = ephy_search_engine_manager_get_address (search_engine_manager, default_name);
address_search = ephy_search_engine_manager_get_default_search_address (search_engine_manager);
query_param = soup_form_encode ("q", search_key, NULL);
#pragma GCC diagnostic push
......@@ -288,7 +286,6 @@ ephy_embed_utils_autosearch_address (const char *search_key)
effective_address = g_strdup_printf (address_search, query_param + 2);
#pragma GCC diagnostic pop
g_free (query_param);
g_free (default_name);
return effective_address;
}
......
......@@ -463,13 +463,9 @@ ephy_web_view_key_press_event (GtkWidget *widget, GdkEventKey *event)
static gboolean
ephy_web_view_button_press_event (GtkWidget *widget, GdkEventButton *event)
{
/* This are the special cases WebkitWebView doesn't handle but we have an
/* These are the special cases WebkitWebView doesn't handle but we have an
* interest in handling. */
/* We always show the browser context menu on control-rightclick. */
if (event->button == 3 && event->state == GDK_CONTROL_MASK)
return FALSE;
/* Handle typical back/forward mouse buttons. */
if (event->button == 8) {
webkit_web_view_go_back (WEBKIT_WEB_VIEW (widget));
......@@ -1487,11 +1483,6 @@ permission_request_cb (WebKitWebView *web_view,
if (WEBKIT_IS_GEOLOCATION_PERMISSION_REQUEST (decision)) {
permission_type = EPHY_PERMISSION_TYPE_ACCESS_LOCATION;
} else if (WEBKIT_IS_NOTIFICATION_PERMISSION_REQUEST (decision)) {
/* Application mode implies being OK with notifications. */
if (ephy_embed_shell_get_mode (shell) == EPHY_EMBED_SHELL_MODE_APPLICATION) {
webkit_permission_request_allow (decision);
return TRUE;
}
permission_type = EPHY_PERMISSION_TYPE_SHOW_NOTIFICATIONS;
} else if (WEBKIT_IS_USER_MEDIA_PERMISSION_REQUEST (decision)) {
if (webkit_user_media_permission_is_for_video_device (WEBKIT_USER_MEDIA_PERMISSION_REQUEST (decision)))
......@@ -1511,21 +1502,31 @@ permission_request_cb (WebKitWebView *web_view,
permission = ephy_permissions_manager_get_permission (permissions_manager,
permission_type,
origin);
g_free (origin);
switch (permission) {
case EPHY_PERMISSION_PERMIT:
webkit_permission_request_allow (decision);
return TRUE;
goto out;
case EPHY_PERMISSION_DENY:
webkit_permission_request_deny (decision);
return TRUE;
goto out;
case EPHY_PERMISSION_UNDECIDED:
default:
break;
/* Application mode implies being OK with notifications. */
if (permission_type == EPHY_PERMISSION_TYPE_SHOW_NOTIFICATIONS &&
ephy_embed_shell_get_mode (shell) == EPHY_EMBED_SHELL_MODE_APPLICATION) {
ephy_permissions_manager_set_permission (permissions_manager,
permission_type,
origin,
EPHY_PERMISSION_PERMIT);
webkit_permission_request_allow (decision);
} else {
show_permission_request_info_bar (web_view, decision, permission_type);
}
}
show_permission_request_info_bar (web_view, decision, permission_type);
out:
g_free (origin);
return TRUE;
}
......
......@@ -148,12 +148,20 @@ should_use_https_everywhere (const char *request_uri,
static gboolean
should_use_adblocker (const char *request_uri,
const char *page_uri)
const char *page_uri,
const char *redirected_request_uri)
{
/* Always load the main resource. */
if (!g_settings_get_boolean (EPHY_SETTINGS_WEB, EPHY_PREFS_WEB_ENABLE_ADBLOCK))
return FALSE;
/* Always load the main resource... */
if (g_strcmp0 (request_uri, page_uri) == 0)
return FALSE;
/* ...even during a redirect, when page_uri is stale. */
if (g_strcmp0 (page_uri, redirected_request_uri) == 0)
return FALSE;
/* Always load data requests, as uri_tester won't do any good here. */
if (g_str_has_prefix (request_uri, SOUP_URI_SCHEME_DATA))
return FALSE;
......@@ -189,9 +197,9 @@ web_page_send_request (WebKitWebPage *web_page,
request_uri = webkit_uri_request_get_uri (request);
page_uri = webkit_web_page_get_uri (web_page);
redirected_response_uri = redirected_response ? webkit_uri_response_get_uri (redirected_response) : NULL;
if (!should_use_adblocker (request_uri, page_uri) ||
!g_settings_get_boolean (EPHY_SETTINGS_WEB, EPHY_PREFS_WEB_ENABLE_ADBLOCK))
if (!should_use_adblocker (request_uri, page_uri, redirected_response_uri))
flags &= ~EPHY_URI_TEST_ADBLOCK;
if (g_settings_get_boolean (EPHY_SETTINGS_WEB, EPHY_PREFS_WEB_DO_NOT_TRACK)) {
......@@ -204,7 +212,6 @@ web_page_send_request (WebKitWebPage *web_page,
modified_uri = ephy_remove_tracking_from_uri (request_uri);
}
redirected_response_uri = redirected_response ? webkit_uri_response_get_uri (redirected_response) : NULL;
if (!should_use_https_everywhere (request_uri, redirected_response_uri))
flags &= ~EPHY_URI_TEST_HTTPS_EVERYWHERE;
......
......@@ -354,7 +354,7 @@ ephy_permissions_manager_get_matching_origins (EphyPermissionsManager *manager,
{
GKeyFile *file;
char *filename;
char **groups;
char **groups = NULL;
gsize groups_length;
GList *origins = NULL;
GError *error = NULL;
......@@ -380,7 +380,7 @@ ephy_permissions_manager_get_matching_origins (EphyPermissionsManager *manager,
if (!g_error_matches (error, G_FILE_ERROR, G_FILE_ERROR_NOENT))
g_warning ("Error processing %s: %s", filename, error->message);
g_error_free (error);
return NULL;
goto out;
}
groups = g_key_file_get_groups (file, &groups_length);
......@@ -388,10 +388,6 @@ ephy_permissions_manager_get_matching_origins (EphyPermissionsManager *manager,
origins = g_list_concat (origins,
origins_for_keyfile_group (file, filename, groups[i], type, permit));
g_key_file_unref (file);
g_strfreev (groups);
g_free (filename);
/* Cache the results. */
if (origins != NULL) {
g_hash_table_insert (permit ? manager->permission_type_permitted_origins
......@@ -400,6 +396,11 @@ ephy_permissions_manager_get_matching_origins (EphyPermissionsManager *manager,
origins);
}
out:
g_key_file_unref (file);
g_strfreev (groups);
g_free (filename);
return origins;
}
......
......@@ -78,26 +78,27 @@ static const char * const ephy_prefs_state_schema[] = {
EPHY_PREFS_STATE_IS_MAXIMIZED
};
#define EPHY_PREFS_WEB_SCHEMA "org.gnome.Epiphany.web"
#define EPHY_PREFS_WEB_FONT_MIN_SIZE "min-font-size"
#define EPHY_PREFS_WEB_LANGUAGE "language"
#define EPHY_PREFS_WEB_USE_GNOME_FONTS "use-gnome-fonts"
#define EPHY_PREFS_WEB_SANS_SERIF_FONT "sans-serif-font"
#define EPHY_PREFS_WEB_SERIF_FONT "serif-font"
#define EPHY_PREFS_WEB_MONOSPACE_FONT "monospace-font"
#define EPHY_PREFS_WEB_ENABLE_USER_CSS "enable-user-css"
#define EPHY_PREFS_WEB_ENABLE_POPUPS "enable-popups"
#define EPHY_PREFS_WEB_ENABLE_PLUGINS "enable-plugins"
#define EPHY_PREFS_WEB_ENABLE_SPELL_CHECKING "enable-spell-checking"
#define EPHY_PREFS_WEB_ENABLE_WEBGL "enable-webgl"
#define EPHY_PREFS_WEB_ENABLE_WEBAUDIO "enable-webaudio"
#define EPHY_PREFS_WEB_ENABLE_SMOOTH_SCROLLING "enable-smooth-scrolling"
#define EPHY_PREFS_WEB_USER_AGENT "user-agent"
#define EPHY_PREFS_WEB_COOKIES_POLICY "cookies-policy"
#define EPHY_PREFS_WEB_DEFAULT_ENCODING "default-encoding"
#define EPHY_PREFS_WEB_DO_NOT_TRACK "do-not-track"
#define EPHY_PREFS_WEB_ENABLE_ADBLOCK "enable-adblock"
#define EPHY_PREFS_WEB_REMEMBER_PASSWORDS "remember-passwords"
#define EPHY_PREFS_WEB_SCHEMA "org.gnome.Epiphany.web"
#define EPHY_PREFS_WEB_FONT_MIN_SIZE "min-font-size"
#define EPHY_PREFS_WEB_LANGUAGE "language"
#define EPHY_PREFS_WEB_USE_GNOME_FONTS "use-gnome-fonts"
#define EPHY_PREFS_WEB_SANS_SERIF_FONT "sans-serif-font"
#define EPHY_PREFS_WEB_SERIF_FONT "serif-font"
#define EPHY_PREFS_WEB_MONOSPACE_FONT "monospace-font"
#define EPHY_PREFS_WEB_ENABLE_USER_CSS "enable-user-css"
#define EPHY_PREFS_WEB_ENABLE_POPUPS "enable-popups"
#define EPHY_PREFS_WEB_ENABLE_PLUGINS "enable-plugins"
#define EPHY_PREFS_WEB_ENABLE_SPELL_CHECKING "enable-spell-checking"
#define EPHY_PREFS_WEB_ENABLE_WEBGL "enable-webgl"
#define EPHY_PREFS_WEB_ENABLE_WEBAUDIO "enable-webaudio"
#define EPHY_PREFS_WEB_ENABLE_SMOOTH_SCROLLING "enable-smooth-scrolling"
#define EPHY_PREFS_WEB_USER_AGENT "user-agent"
#define EPHY_PREFS_WEB_COOKIES_POLICY "cookies-policy"
#define EPHY_PREFS_WEB_DEFAULT_ENCODING "default-encoding"
#define EPHY_PREFS_WEB_DO_NOT_TRACK "do-not-track"
#define EPHY_PREFS_WEB_ENABLE_ADBLOCK "enable-adblock"
#define EPHY_PREFS_WEB_REMEMBER_PASSWORDS "remember-passwords"
#define EPHY_PREFS_WEB_ENABLE_SITE_SPECIFIC_QUIRKS "enable-site-specific-quirks"
static const char * const ephy_prefs_web_schema[] = {
EPHY_PREFS_WEB_FONT_MIN_SIZE,
......@@ -119,6 +120,7 @@ static const char * const ephy_prefs_web_schema[] = {
EPHY_PREFS_WEB_DO_NOT_TRACK,
EPHY_PREFS_WEB_ENABLE_ADBLOCK,
EPHY_PREFS_WEB_REMEMBER_PASSWORDS,
EPHY_PREFS_WEB_ENABLE_SITE_SPECIFIC_QUIRKS
};
#define EPHY_PREFS_SCHEMA "org.gnome.Epiphany"
......
......@@ -27,6 +27,8 @@
#include "ephy-settings.h"
#include "ephy-prefs.h"
#define FALLBACK_ADDRESS "https://duckduckgo.com/?q=%s&t=epiphany"
enum {
SEARCH_ENGINES_CHANGED,
LAST_SIGNAL
......@@ -148,6 +150,19 @@ ephy_search_engine_manager_get_address (EphySearchEngineManager *manager,
return NULL;
}
const char *
ephy_search_engine_manager_get_default_search_address (EphySearchEngineManager *manager)
{
char *name;
const char *address;
name = ephy_search_engine_manager_get_default_engine (manager);
address = ephy_search_engine_manager_get_address (manager, name);
g_free (name);
return address ? address : FALLBACK_ADDRESS;
}
const char *
ephy_search_engine_manager_get_bang (EphySearchEngineManager *manager,
const char *name)
......
......@@ -39,6 +39,8 @@ G_DECLARE_FINAL_TYPE (EphySearchEngineManager, ephy_search_engine_manager, EPHY,
EphySearchEngineManager *ephy_search_engine_manager_new (void);
const char *ephy_search_engine_manager_get_address (EphySearchEngineManager *manager,
const char *name);
const char *ephy_search_engine_manager_get_default_search_address
(EphySearchEngineManager *manager);
const char *ephy_search_engine_manager_get_bang (EphySearchEngineManager *manager,
const char *name);
char *ephy_search_engine_manager_get_default_engine (EphySearchEngineManager *manager);
......
......@@ -270,6 +270,16 @@ ephy_location_entry_get_property (GObject *object,
}
}
static void
ephy_location_entry_constructed (GObject *object)
{
G_OBJECT_CLASS (ephy_location_entry_parent_class)->constructed (object);
#if GTK_CHECK_VERSION(3, 22, 20)
gtk_entry_set_input_hints (GTK_ENTRY (object), GTK_INPUT_HINT_NO_EMOJI);
#endif
}
static void
ephy_location_entry_finalize (GObject *object)
{
......@@ -368,6 +378,7 @@ ephy_location_entry_class_init (EphyLocationEntryClass *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;
widget_class->size_allocate = ephy_location_entry_size_allocate;
......@@ -662,6 +673,7 @@ entry_populate_popup_cb (GtkEntry *entry,
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);
......@@ -676,6 +688,7 @@ entry_populate_popup_cb (GtkEntry *entry,
}
}
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);
......
/* -*- Mode: C; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/*
* Copyright (C) 2011 Red Hat Inc.
/* Nautilus - Floating status bar.
*
* This file is part of Epiphany.
* Copyright (C) 2011 Red Hat Inc.
*
* Epiphany is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* Epiphany is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Epiphany. If not, see <http://www.gnu.org/licenses/>.
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, see <http://www.gnu.org/licenses/>.
*
* Authors: Cosimo Cecchi <cosimoc@redhat.com>
*
* Authors: Cosimo Cecchi <cosimoc@redhat.com>
*/
#include <config.h>
......@@ -26,6 +25,8 @@
#include "nautilus-floating-bar.h"
#define HOVER_HIDE_TIMEOUT_INTERVAL 100
struct _NautilusFloatingBarDetails {
gchar *primary_label;
gchar *details_label;
......@@ -73,6 +74,7 @@ nautilus_floating_bar_finalize (GObject *obj)
{
NautilusFloatingBar *self = NAUTILUS_FLOATING_BAR (obj);
nautilus_floating_bar_remove_hover_timeout (self);
g_free (self->priv->primary_label);
g_free (self->priv->details_label);
......@@ -146,41 +148,29 @@ update_labels (NautilusFloatingBar *self)
gtk_widget_set_visible (self->priv->details_label_widget, details_visible);
}
static void
nautilus_floating_bar_show (GtkWidget *widget)
void
nautilus_floating_bar_remove_hover_timeout (NautilusFloatingBar *self)
{
NautilusFloatingBar *self = NAUTILUS_FLOATING_BAR (widget);
/* Epiphany: never show the bar on top of the web view. */
if (gtk_widget_get_valign (widget) == GTK_ALIGN_START)
return;
GTK_WIDGET_CLASS (nautilus_floating_bar_parent_class)->show (widget);
if (self->priv->show_spinner) {
gtk_spinner_start (GTK_SPINNER (self->priv->spinner));
if (self->priv->hover_timeout_id != 0) {
g_source_remove (self->priv->hover_timeout_id);
self->priv->hover_timeout_id = 0;
}
}
static void
nautilus_floating_bar_hide (GtkWidget *widget)
{
NautilusFloatingBar *self = NAUTILUS_FLOATING_BAR (widget);
GTK_WIDGET_CLASS (nautilus_floating_bar_parent_class)->hide (widget);
gtk_spinner_stop (GTK_SPINNER (self->priv->spinner));
}
typedef struct {
GtkWidget *overlay;
GtkWidget *floating_bar;
GdkDevice *device;
gint y_down_limit;
gint y_upper_limit;
gboolean first_time;
} CheckPointerData;
static void
check_pointer_data_free (gpointer data)
{
g_slice_free (CheckPointerData, data);
}
static gboolean
check_pointer_timeout (gpointer user_data)
{
......@@ -191,26 +181,16 @@ check_pointer_timeout (gpointer user_data)
NULL, &pointer_y, NULL);
if (pointer_y == -1 || pointer_y < data->y_down_limit || pointer_y > data->y_upper_limit) {
if (!data->first_time) {
gtk_widget_set_valign (data->floating_bar, GTK_ALIGN_END);
nautilus_floating_bar_show (data->floating_bar);
}
gtk_widget_show (data->floating_bar);
NAUTILUS_FLOATING_BAR (data->floating_bar)->priv->hover_timeout_id = 0;
return G_SOURCE_REMOVE;
} else {
gtk_widget_hide (data->floating_bar);
}
if (data->first_time) {
/* Hide floating bar at top position of widget */
nautilus_floating_bar_hide (data->floating_bar);
gtk_widget_set_valign (data->floating_bar, GTK_ALIGN_START);
gtk_widget_queue_resize (data->floating_bar);
}
data->first_time = FALSE;
return G_SOURCE_CONTINUE;
}
static gboolean
overlay_enter_notify_cb (GtkWidget *parent,
GdkEventCrossing *event,
......@@ -218,14 +198,12 @@ overlay_enter_notify_cb (GtkWidget *parent,
{
GtkWidget *widget = user_data;
CheckPointerData *data;
GtkAllocation alloc_parent;
gint y_pos;
NautilusFloatingBar *self = NAUTILUS_FLOATING_BAR (widget);
if (self->priv->hover_timeout_id != 0) {
g_source_remove (self->priv->hover_timeout_id);
self->priv->hover_timeout_id = 0;
}
if (event->window != gtk_widget_get_window (widget)) {
......@@ -236,20 +214,19 @@ overlay_enter_notify_cb (GtkWidget *parent,
return GDK_EVENT_PROPAGATE;
}
gtk_widget_get_allocation (parent, &alloc_parent);
gdk_window_get_position (gtk_widget_get_window (widget), NULL, &y_pos);
data = g_new (CheckPointerData, 1);
data = g_slice_new (CheckPointerData);
data->overlay = parent;
data->floating_bar = widget;
data->device = gdk_event_get_device ((GdkEvent *)event);
data->y_down_limit = y_pos;
data->y_upper_limit = alloc_parent.height;
data->first_time = TRUE;
data->y_upper_limit = y_pos + gtk_widget_get_allocated_height (widget);
self->priv->hover_timeout_id = g_timeout_add_full (G_PRIORITY_DEFAULT, 250,
self->priv->hover_timeout_id = g_timeout_add_full (G_PRIORITY_DEFAULT, HOVER_HIDE_TIMEOUT_INTERVAL,
check_pointer_timeout, data,
g_free);
check_pointer_data_free);
g_source_set_name_by_id (self->priv->hover_timeout_id, "[nautilus-floating-bar] overlay_enter_notify_cb");
return GDK_EVENT_STOP;
......@@ -274,28 +251,95 @@ nautilus_floating_bar_parent_set (GtkWidget *widget,
}
}
static gboolean
nautilus_floating_bar_draw (GtkWidget *widget,
cairo_t *cr)
static void
get_padding_and_border (GtkWidget *widget,
GtkBorder *border)
{
GtkStyleContext *context;
GtkStateFlags state;
GtkBorder tmp;
context = gtk_widget_get_style_context (widget);
state = gtk_widget_get_state_flags (widget);
gtk_style_context_get_padding (context, state, border);
gtk_style_context_get_border (context, state, &tmp);
border->top += tmp.top;
border->right += tmp.right;
border->bottom += tmp.bottom;
border->left += tmp.left;
}
static void
nautilus_floating_bar_get_preferred_width (GtkWidget *widget,
gint *minimum_size,
gint *natural_size)
{
GtkBorder border;
get_padding_and_border (widget, &border);
GTK_WIDGET_CLASS (nautilus_floating_bar_parent_class)->get_preferred_width (widget,
minimum_size,
natural_size);
*minimum_size += border.left + border.right;
*natural_size += border.left + border.right;
}
static void
nautilus_floating_bar_get_preferred_width_for_height (GtkWidget *widget,
gint height,
gint *minimum_size,
gint *natural_size)
{
GtkBorder border;
get_padding_and_border (widget, &border);
gtk_style_context_save (context);
gtk_style_context_set_state (context, gtk_widget_get_state_flags (widget));
GTK_WIDGET_CLASS (nautilus_floating_bar_parent_class)->get_preferred_width_for_height (widget,
height,
minimum_size,
natural_size);
gtk_render_background (context, cr, 0, 0,
gtk_widget_get_allocated_width (widget),
gtk_widget_get_allocated_height (widget));
*minimum_size += border.left + border.right;
*natural_size += border.left + border.right;
}
static void
nautilus_floating_bar_get_preferred_height (GtkWidget *widget,
gint *minimum_size,
gint *natural_size)
{
GtkBorder border;
get_padding_and_border (widget, &border);
GTK_WIDGET_CLASS (nautilus_floating_bar_parent_class)->get_preferred_height (widget,
minimum_size,
natural_size);
*minimum_size += border.top + border.bottom;
*natural_size += border.top + border.bottom;
}
static void
nautilus_floating_bar_get_preferred_height_for_width (GtkWidget *widget,
gint width,
gint *minimum_size,
gint *natural_size)
{
GtkBorder border;
gtk_render_frame (context, cr, 0, 0,
gtk_widget_get_allocated_width (widget),
gtk_widget_get_allocated_height (widget));
get_padding_and_border (widget, &border);
gtk_style_context_restore (context);
GTK_WIDGET_CLASS (nautilus_floating_bar_parent_class)->get_preferred_height_for_width (widget,
width,
minimum_size,
natural_size);
return GTK_WIDGET_CLASS (nautilus_floating_bar_parent_class)->draw (widget, cr);;
*minimum_size += border.top + border.bottom;
*natural_size += border.top + border.bottom;
}
static void
......@@ -311,6 +355,7 @@ nautilus_floating_bar_constructed (GObject *obj)
w = gtk_spinner_new ();
gtk_box_pack_start (GTK_BOX (box), w, FALSE, FALSE, 0);
gtk_widget_set_visible (w, self->priv->show_spinner);
gtk_spinner_start (GTK_SPINNER (w));
self->priv->spinner = w;
gtk_widget_set_size_request (w, 16, 16);
......@@ -363,9 +408,10 @@ nautilus_floating_bar_class_init (NautilusFloatingBarClass *klass)
oclass->get_property = nautilus_floating_bar_get_property;
oclass->finalize = nautilus_floating_bar_finalize;
wclass->draw = nautilus_floating_bar_draw;
wclass->show = nautilus_floating_bar_show;
wclass->hide = nautilus_floating_bar_hide;
wclass->get_preferred_width = nautilus_floating_bar_get_preferred_width;
wclass->get_preferred_width_for_height = nautilus_floating_bar_get_preferred_width_for_height;
wclass->get_preferred_height = nautilus_floating_bar_get_preferred_height;
wclass->get_preferred_height_for_width = nautilus_floating_bar_get_preferred_height_for_width;
wclass->parent_set = nautilus_floating_bar_parent_set;
properties[PROP_PRIMARY_LABEL] =
......@@ -391,7 +437,8 @@ nautilus_floating_bar_class_init (NautilusFloatingBarClass *klass)
g_signal_new ("action",
G_TYPE_FROM_CLASS (klass),
G_SIGNAL_RUN_LAST,
0, NULL, NULL, NULL,
0, NULL, NULL,
g_cclosure_marshal_VOID__INT,
G_TYPE_NONE, 1,
G_TYPE_INT);
......@@ -468,13 +515,14 @@ nautilus_floating_bar_add_action (NautilusFloatingBar *self,
const gchar *icon_name,
gint action_id)
{
GtkWidget *w, *button;
w = gtk_image_new_from_icon_name (icon_name, GTK_ICON_SIZE_MENU);
gtk_widget_show (w);
GtkWidget *button;
GtkStyleContext *context;
button = gtk_button_new ();
gtk_button_set_image (GTK_BUTTON (button), w);
button = gtk_button_new_from_icon_name (icon_name, GTK_ICON_SIZE_MENU);
context = gtk_widget_get_style_context (button);
gtk_style_context_add_class (context, "circular");
gtk_style_context_add_class (context, "flat");
gtk_widget_set_valign (button, GTK_ALIGN_CENTER);
gtk_box_pack_end (GTK_BOX (self), button, FALSE, FALSE, 0);
gtk_widget_show (button);
......
/* -*- Mode: C; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/*
* Copyright (C) 2011 Red Hat Inc.
/* Nautilus - Floating status bar.
*
* Copyright (C) 2011 Red Hat Inc.
*
* This file is part of Epiphany.
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* Epiphany is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* Epiphany is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, see <http://www.gnu.org/licenses/>.
*
* You should have received a copy of the GNU General Public License
* along with Epiphany. If not, see <http://www.gnu.org/licenses/>.
* Authors: Cosimo Cecchi <cosimoc@redhat.com>
*
* Authors: Cosimo Cecchi <cosimoc@redhat.com>
*/
#pragma once
#ifndef __NAUTILUS_FLOATING_BAR_H__
#define __NAUTILUS_FLOATING_BAR_H__
#include <gtk/gtk.h>
......@@ -72,3 +73,7 @@ void nautilus_floating_bar_add_action (NautilusFloatingBar *self,
const gchar *icon_name,
gint action_id);
void nautilus_floating_bar_cleanup_actions (NautilusFloatingBar *self);
void nautilus_floating_bar_remove_hover_timeout (NautilusFloatingBar *self);
#endif /* __NAUTILUS_FLOATING_BAR_H__ */
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
......@@ -238,3 +238,11 @@ ephy_bookmark_row_get_bookmark (EphyBookmarkRow *self)
return self->bookmark;
}
const char *
ephy_bookmark_row_get_bookmark_url (EphyBookmarkRow *self)
{
g_return_val_if_fail (EPHY_IS_BOOKMARK_ROW (self), NULL);
return ephy_bookmark_get_url (self->bookmark);
}
......@@ -30,8 +30,10 @@ G_BEGIN_DECLS
G_DECLARE_FINAL_TYPE (EphyBookmarkRow, ephy_bookmark_row, EPHY, BOOKMARK_ROW, GtkListBoxRow)
GtkWidget *ephy_bookmark_row_new (EphyBookmark *bookmark);
GtkWidget *ephy_bookmark_row_new (EphyBookmark *bookmark);
EphyBookmark *ephy_bookmark_row_get_bookmark (EphyBookmarkRow *self);
EphyBookmark *ephy_bookmark_row_get_bookmark (EphyBookmarkRow *self);
const char *ephy_bookmark_row_get_bookmark_url (EphyBookmarkRow *self);
G_END_DECLS
......@@ -48,6 +48,7 @@ struct _EphyBookmark {
gboolean uploaded;
};
#ifdef ENABLE_SYNC
static JsonSerializableIface *serializable_iface = NULL;
static void json_serializable_iface_init (gpointer g_iface);
......@@ -55,6 +56,9 @@ static void json_serializable_iface_init (gpointer g_iface);
G_DEFINE_TYPE_WITH_CODE (EphyBookmark, ephy_bookmark, G_TYPE_OBJECT,
G_IMPLEMENT_INTERFACE (JSON_TYPE_SERIALIZABLE,
json_serializable_iface_init))
#else
G_DEFINE_TYPE (EphyBookmark, ephy_bookmark, G_TYPE_OBJECT)
#endif
enum {
PROP_0,
......@@ -230,6 +234,7 @@ ephy_bookmark_init (EphyBookmark *self)
#endif
}
#ifdef ENABLE_SYNC
static JsonNode *
ephy_bookmark_json_serializable_serialize_property (JsonSerializable *serializable,
const char *name,
......@@ -303,6 +308,7 @@ json_serializable_iface_init (gpointer g_iface)
iface->serialize_property = ephy_bookmark_json_serializable_serialize_property;
iface->deserialize_property = ephy_bookmark_json_serializable_deserialize_property;
}
#endif
EphyBookmark *
ephy_bookmark_new (const char *url, const char *title, GSequence *tags)
......
......@@ -21,7 +21,10 @@
#pragma once
#include <glib-object.h>
#ifdef ENABLE_SYNC
#include <json-glib/json-glib.h>
#endif
G_BEGIN_DECLS
......
......@@ -59,6 +59,28 @@ enum {
static GParamSpec *obj_properties[LAST_PROP];
static GtkWidget *create_bookmark_row (gpointer item, gpointer user_data);
static GtkWidget *create_tag_row (const char *tag);
static void
remove_bookmark_row_from_container (GtkContainer *container,
const char *url)
{
GList *children;
g_assert (GTK_IS_CONTAINER (container));
children = gtk_container_get_children (container);
for (GList *l = children; l && l->data; l = l->next) {
const char *type = g_object_get_data (l->data, "type");
if (g_strcmp0 (type, EPHY_LIST_BOX_ROW_TYPE_BOOKMARK) == 0 &&
g_strcmp0 (ephy_bookmark_row_get_bookmark_url (l->data), url) == 0) {
gtk_container_remove (container, l->data);
break;
}
}
g_list_free (children);
}
static void
ephy_bookmarks_popover_bookmark_tag_added_cb (EphyBookmarksPopover *self,
......@@ -66,23 +88,17 @@ ephy_bookmarks_popover_bookmark_tag_added_cb (EphyBookmarksPopover *self,
const char *tag,
EphyBookmarksManager *manager)
{
GtkWidget *tag_row;
g_assert (EPHY_IS_BOOKMARK (bookmark));
g_assert (EPHY_IS_BOOKMARKS_POPOVER (self));
/* If the bookmark no longer has 0 tags, we remove it from the tags list box */
if (g_sequence_get_length (ephy_bookmark_get_tags (bookmark)) == 1) {
GList *children;
GList *l;
const char *visible_stack_child;
children = gtk_container_get_children (GTK_CONTAINER (self->tags_list_box));
for (l = children; l != NULL; l = l->next) {
const char *url;
url = g_object_get_data (G_OBJECT (l->data), "url");
if (g_strcmp0 (ephy_bookmark_get_url (bookmark), url) == 0)
gtk_container_remove (GTK_CONTAINER (self->tags_list_box), GTK_WIDGET (l->data));
}
remove_bookmark_row_from_container (GTK_CONTAINER (self->tags_list_box),
ephy_bookmark_get_url (bookmark));
/* If we are on the tag detail list box, then the user has toggled the state
* of the tag widget multiple times. The first time the bookmark was removed
......@@ -94,6 +110,13 @@ ephy_bookmarks_popover_bookmark_tag_added_cb (EphyBookmarksPopover *self,
gtk_container_add (GTK_CONTAINER (self->tag_detail_list_box), row);
}
}
/* The first time a tag is asigned to a bookmark, a tag row is created and
* added to the tags list */
if (g_sequence_get_length (ephy_bookmarks_manager_get_bookmarks_with_tag (manager, tag)) == 1) {
tag_row = create_tag_row (tag);
gtk_container_add (GTK_CONTAINER (self->tags_list_box), tag_row);
}
}
static void
......@@ -107,6 +130,7 @@ ephy_bookmarks_popover_bookmark_tag_removed_cb (EphyBookmarksPopover *self,
GList *l;
const char *visible_stack_child;
gboolean exists;
gpointer title;
g_assert (EPHY_IS_BOOKMARK (bookmark));
g_assert (EPHY_IS_BOOKMARKS_POPOVER (self));
......@@ -117,14 +141,18 @@ ephy_bookmarks_popover_bookmark_tag_removed_cb (EphyBookmarksPopover *self,
exists = FALSE;
children = gtk_container_get_children (GTK_CONTAINER (self->tags_list_box));
for (l = children; l != NULL; l = l->next) {
const char *url;
const char *type = g_object_get_data (l->data, "type");
if (g_strcmp0 (type, EPHY_LIST_BOX_ROW_TYPE_BOOKMARK) == 0) {
const char *url = ephy_bookmark_row_get_bookmark_url (l->data);
url = g_object_get_data (G_OBJECT(l->data), "url");
if (g_strcmp0 (ephy_bookmark_get_url (bookmark), url) == 0) {
exists = TRUE;
break;
if (g_strcmp0 (ephy_bookmark_get_url (bookmark), url) == 0) {
exists = TRUE;
break;
}
}
}
g_list_free (children);
if (!exists) {
row = create_bookmark_row (bookmark, self);
......@@ -137,14 +165,8 @@ ephy_bookmarks_popover_bookmark_tag_removed_cb (EphyBookmarksPopover *self,
visible_stack_child = gtk_stack_get_visible_child_name (GTK_STACK (self->toplevel_stack));
if (g_strcmp0 (visible_stack_child, "tag_detail") == 0 &&
g_strcmp0 (self->tag_detail_tag, tag) == 0) {
children = gtk_container_get_children (GTK_CONTAINER (self->tag_detail_list_box));
for (l = children; l != NULL; l = l->next) {
const char *url;
url = g_object_get_data (G_OBJECT (l->data), "url");
if (g_strcmp0 (ephy_bookmark_get_url (bookmark), url) == 0)
gtk_container_remove (GTK_CONTAINER (self->tag_detail_list_box), GTK_WIDGET (l->data));
}
remove_bookmark_row_from_container (GTK_CONTAINER (self->tag_detail_list_box),
ephy_bookmark_get_url (bookmark));
/* If we removed the tag's last bookmark, switch back to the tags list. */
if (g_sequence_is_empty (ephy_bookmarks_manager_get_bookmarks_with_tag (self->manager, tag))) {
......@@ -156,6 +178,17 @@ ephy_bookmarks_popover_bookmark_tag_removed_cb (EphyBookmarksPopover *self,
g_action_activate (action, NULL);
}
}
/* If the tag no longer contains bookmarks, remove it from the tags list */
if (g_sequence_is_empty (ephy_bookmarks_manager_get_bookmarks_with_tag (self->manager, tag))) {
children = gtk_container_get_children (GTK_CONTAINER (self->tags_list_box));
for (l = children; l != NULL; l = l->next) {
title = g_object_get_data (G_OBJECT (l->data), "title");
if (g_strcmp0 (title, tag) == 0)
gtk_container_remove (GTK_CONTAINER (self->tags_list_box), GTK_WIDGET (l->data));
}
g_list_free (children);
}
}
static GtkWidget *
......@@ -172,9 +205,6 @@ create_bookmark_row (gpointer item,
g_object_set_data_full (G_OBJECT (row), "title",
g_strdup (ephy_bookmark_get_title (bookmark)),
(GDestroyNotify)g_free);
g_object_set_data_full (G_OBJECT (row), "url",
g_strdup (ephy_bookmark_get_url (bookmark)),
(GDestroyNotify)g_free);
return row;
}
......@@ -241,50 +271,14 @@ ephy_bookmarks_popover_bookmark_removed_cb (EphyBookmarksPopover *self,
EphyBookmark *bookmark,
EphyBookmarksManager *manager)
{
GtkWidget *row = NULL;
GList *children;
GList *l;
gboolean found = FALSE;
g_assert (EPHY_IS_BOOKMARKS_POPOVER (self));
g_assert (EPHY_IS_BOOKMARK (bookmark));
g_assert (EPHY_IS_BOOKMARKS_MANAGER (manager));
children = gtk_container_get_children (GTK_CONTAINER (self->tags_list_box));
for (l = children; l != NULL; l = l->next) {
const char *type;
const char *url;
row = GTK_WIDGET (l->data);
type = g_object_get_data (G_OBJECT (row), "type");
url = g_object_get_data (G_OBJECT (row), "url");
if (g_strcmp0 (type, EPHY_LIST_BOX_ROW_TYPE_BOOKMARK) == 0
&& g_strcmp0 (ephy_bookmark_get_url (bookmark), url) == 0) {
found = TRUE;
break;
}
}
if (found) {
gtk_container_remove (GTK_CONTAINER (self->tags_list_box), row);
found = FALSE;
}
children = gtk_container_get_children (GTK_CONTAINER (self->tag_detail_list_box));
for (l = children; l != NULL; l = l->next) {
const char *type;
const char *url;
row = GTK_WIDGET (l->data);
type = g_object_get_data (G_OBJECT (row), "type");
url = g_object_get_data (G_OBJECT (row), "url");
if (g_strcmp0 (type, EPHY_LIST_BOX_ROW_TYPE_BOOKMARK) == 0
&& g_strcmp0 (ephy_bookmark_get_url (bookmark), url) == 0) {
found = TRUE;
break;
}
}
if (found)
gtk_container_remove (GTK_CONTAINER (self->tag_detail_list_box), row);
remove_bookmark_row_from_container (GTK_CONTAINER (self->tags_list_box),
ephy_bookmark_get_url (bookmark));
remove_bookmark_row_from_container (GTK_CONTAINER (self->tag_detail_list_box),
ephy_bookmark_get_url (bookmark));
if (g_list_model_get_n_items (G_LIST_MODEL (self->manager)) == 0) {
gtk_stack_set_visible_child_name (GTK_STACK (self->toplevel_stack), "empty-state");
......@@ -376,17 +370,17 @@ ephy_bookmarks_popover_actions_tag_detail_back (GSimpleAction *action,
gpointer user_data)
{
EphyBookmarksPopover *self = user_data;
GList *l;
GList *children;
g_assert (EPHY_IS_BOOKMARKS_POPOVER (self));
gtk_stack_set_visible_child_name (GTK_STACK (self->toplevel_stack),
"default");
for (l = gtk_container_get_children (GTK_CONTAINER (self->tag_detail_list_box));
l != NULL;
l = l->next)
children = gtk_container_get_children (GTK_CONTAINER (self->tag_detail_list_box));
for (GList *l = children; l != NULL; l = l->next)
gtk_container_remove (GTK_CONTAINER (self->tag_detail_list_box), l->data);
g_list_free (children);
}
static void
......@@ -435,16 +429,13 @@ ephy_bookmarks_popover_list_box_row_activated_cb (EphyBookmarksPopover *self,
type = g_object_get_data (G_OBJECT (row), "type");
if (g_strcmp0 (type, EPHY_LIST_BOX_ROW_TYPE_BOOKMARK) == 0) {
EphyBookmark *bookmark;
GActionGroup *action_group;
GAction *action;
const char *url;
action_group = gtk_widget_get_action_group (GTK_WIDGET (self->window), "win");
action = g_action_map_lookup_action (G_ACTION_MAP (action_group), "open-bookmark");
bookmark = ephy_bookmark_row_get_bookmark (EPHY_BOOKMARK_ROW (row));
url = ephy_bookmark_get_url (bookmark);
url = ephy_bookmark_row_get_bookmark_url (EPHY_BOOKMARK_ROW (row));
g_action_activate (action, g_variant_new_string (url));
} else {
......@@ -552,8 +543,10 @@ ephy_bookmarks_popover_init (EphyBookmarksPopover *self)
const char *tag = g_sequence_get (iter);
GtkWidget *tag_row;
tag_row = create_tag_row (tag);
gtk_container_add (GTK_CONTAINER (self->tags_list_box), tag_row);
if (!g_sequence_is_empty (ephy_bookmarks_manager_get_bookmarks_with_tag (self->manager, tag))) {
tag_row = create_tag_row (tag);
gtk_container_add (GTK_CONTAINER (self->tags_list_box), tag_row);
}
}
bookmarks = ephy_bookmarks_manager_get_bookmarks_with_tag (self->manager, NULL);
......
......@@ -291,10 +291,30 @@ replace_rows_in_model (EphyCompletionModel *model, GSList *new_rows)
static gboolean
should_add_bookmark_to_model (EphyCompletionModel *model,
const char *search_string,
const char *title,
const char *location)
EphyBookmark *bookmark)
{
gboolean ret = TRUE;
GSequence *tags;
GSequenceIter *tag_iter;
const char *url;
const char *title;
char *tag_string = NULL;
char **tag_array;
int i;
title = ephy_bookmark_get_title (bookmark);
url = ephy_bookmark_get_url (bookmark);
tags = ephy_bookmark_get_tags (bookmark);
tag_array = g_malloc0 ((g_sequence_get_length (tags) + 1) * sizeof (char *));
for (i = 0, tag_iter = g_sequence_get_begin_iter (tags);
!g_sequence_iter_is_end (tag_iter);
i++, tag_iter = g_sequence_iter_next (tag_iter)) {
tag_array[i] = g_sequence_get (tag_iter);
}
tag_string = g_strjoinv (" ", tag_array);
if (model->search_terms) {
GSList *iter;
......@@ -302,14 +322,19 @@ should_add_bookmark_to_model (EphyCompletionModel *model,
for (iter = model->search_terms; iter != NULL; iter = iter->next) {
current = (GRegex *)iter->data;
if ((!g_regex_match (current, title ? title : "", G_REGEX_MATCH_NOTEMPTY, NULL)) &&
(!g_regex_match (current, location ? location : "", G_REGEX_MATCH_NOTEMPTY, NULL))) {
(!g_regex_match (current, url ? url : "", G_REGEX_MATCH_NOTEMPTY, NULL)) &&
(!g_regex_match (current, tag_string ? tag_string : "", G_REGEX_MATCH_NOTEMPTY, NULL))) {
ret = FALSE;
break;
}
}
}
g_free (tag_array);
g_free (tag_string);
return ret;
}
......@@ -426,12 +451,11 @@ query_completed_cb (EphyHistoryService *service,
bookmark = g_sequence_get (iter);
url = ephy_bookmark_get_url (bookmark);
title = ephy_bookmark_get_title (bookmark);
if (should_add_bookmark_to_model (model, user_data->search_string,
title, url))
if (should_add_bookmark_to_model (model, user_data->search_string, bookmark)) {
url = ephy_bookmark_get_url (bookmark);
title = ephy_bookmark_get_title (bookmark);
list = add_to_potential_rows (list, title, url, NULL, 0, TRUE, FALSE);
}
}
/* History */
......
......@@ -206,25 +206,6 @@ typedef enum {
WEBKIT_HISTORY_FORWARD
} WebKitHistoryType;
static void
ephy_history_cleared_cb (EphyHistoryService *history,
gpointer user_data)
{
GActionGroup *action_group;
GAction *action;
guint i;
gchar **actions;
action_group = gtk_widget_get_action_group (GTK_WIDGET (user_data), "toolbar");
actions = g_action_group_list_actions (action_group);
for (i = 0; actions[i] != NULL; i++) {
action = g_action_map_lookup_action (G_ACTION_MAP (action_group), actions[i]);
ephy_action_change_sensitivity_flags (G_SIMPLE_ACTION (action), SENS_FLAG, TRUE);
}
g_strfreev (actions);
}
static gboolean
item_enter_notify_event_cb (GtkWidget *widget,
GdkEvent *event,
......@@ -628,7 +609,6 @@ ephy_header_bar_constructed (GObject *object)
GtkWidget *page_menu_popover;
EphyDownloadsManager *downloads_manager;
GtkBuilder *builder;
EphyHistoryService *history_service;
EphyEmbedShell *embed_shell;
G_OBJECT_CLASS (ephy_header_bar_parent_class)->constructed (object);
......@@ -826,12 +806,6 @@ ephy_header_bar_constructed (GObject *object)
gtk_header_bar_pack_end (GTK_HEADER_BAR (header_bar), header_bar->downloads_revealer);
gtk_widget_show (header_bar->downloads_revealer);
history_service = ephy_embed_shell_get_global_history_service (ephy_embed_shell_get_default ());
g_signal_connect (history_service,
"cleared", G_CALLBACK (ephy_history_cleared_cb),
header_bar->window);
}
static void
......
......@@ -32,6 +32,7 @@
#include "ephy-location-entry.h"
#include "ephy-shell.h"
#include "ephy-title-widget.h"
#include "ephy-uri-helpers.h"
#include "ephy-widgets-type-builtins.h"
#include <gdk/gdkkeysyms.h>
......@@ -227,11 +228,12 @@ get_location_cb (EphyLocationEntry *entry,
EphyLocationController *controller)
{
EphyEmbed *embed;
const char *address;
embed = ephy_embed_container_get_active_child
(EPHY_EMBED_CONTAINER (controller->window));
embed = ephy_embed_container_get_active_child (EPHY_EMBED_CONTAINER (controller->window));
address = ephy_web_view_get_address (ephy_embed_get_web_view (embed));
return g_strdup (ephy_web_view_get_address (ephy_embed_get_web_view (embed)));
return ephy_embed_utils_is_no_show_address (address) ? NULL : ephy_uri_decode (address);
}
static char *
......@@ -406,8 +408,8 @@ ephy_location_controller_constructed (GObject *object)
add_completion_actions (controller, EPHY_LOCATION_ENTRY (controller->title_widget));
g_signal_connect (controller->search_engine_manager, "changed",
G_CALLBACK (search_engines_changed_cb), controller);
g_signal_connect_object (controller->search_engine_manager, "changed",
G_CALLBACK (search_engines_changed_cb), controller, 0);
g_object_bind_property (controller, "editable",
controller->title_widget, "editable",
......
......@@ -465,7 +465,6 @@ ephy_notebook_constructed (GObject *object)
EphyNotebook *notebook = EPHY_NOTEBOOK (object);
GtkWidget *hbox;
GtkWidget *button;
GtkWidget *popover;
G_OBJECT_CLASS (ephy_notebook_parent_class)->constructed (object);
......@@ -489,9 +488,9 @@ ephy_notebook_constructed (GObject *object)
gtk_widget_show (button);
notebook->tab_menu = g_menu_new ();
popover = gtk_popover_new (button);
gtk_popover_bind_model (GTK_POPOVER (popover), G_MENU_MODEL (notebook->tab_menu), "win");
gtk_menu_button_set_popover (GTK_MENU_BUTTON (button), popover);
/* Remove this when popover menus become scrollable. */
gtk_menu_button_set_use_popover (GTK_MENU_BUTTON (button), FALSE);
gtk_menu_button_set_menu_model (GTK_MENU_BUTTON (button), G_MENU_MODEL (notebook->tab_menu));
}
static void
......@@ -574,7 +573,7 @@ ephy_notebook_rebuild_tab_menu (EphyNotebook *notebook)
text = get_nth_tab_label_text (GTK_NOTEBOOK (notebook), i);
ellipsized_text = ellipsize_tab_label (text);
item = g_menu_item_new (ellipsized_text, NULL);
g_menu_item_set_action_and_target (item, "show-tab", "u", (guint)i, NULL);
g_menu_item_set_action_and_target (item, "win.show-tab", "u", (guint)i, NULL);
g_menu_append_item (notebook->tab_menu, item);
g_free (ellipsized_text);
g_object_unref (item);
......