...
 
Commits (123)
build/
subprojects/libdazzle/
subprojects/libhandy/
......@@ -11,7 +11,7 @@ flatpak:
FLATPAK_MODULE: 'epiphany'
# Make sure to keep this in sync with the Flatpak manifest, all arguments
# are passed except the config-args because we build it ourselves
MESON_ARGS: '-Dunit_tests=true'
MESON_ARGS: '-Dunit_tests=enabled'
APP_ID: 'org.gnome.Epiphany'
review:
......@@ -20,4 +20,4 @@ review:
extends: '.review'
stop_review:
extends: '.stop_review'
\ No newline at end of file
extends: '.stop_review'
[submodule "subprojects/libhandy"]
path = subprojects/libhandy
url = https://source.puri.sm/Librem5/libhandy.git
[submodule "subprojects/libdazzle"]
path = subprojects/libdazzle
url = https://gitlab.gnome.org/GNOME/libdazzle.git
3.32.1.2 - March 21, 2019
=========================
- Recreate Safe Browsing database when it might be corrupted (#57)
- Update libdazzle subproject to improve compatibility with new meson versions (#699)
3.32.1.1 - March 20, 2019
=========================
- Really bring back libdazzle subproject, for 3.32 branch only (#699)
3.32.1 - March 20, 2019
=======================
- Switch to WebKit's two-finger back/forward swipe gesture (Alexander Mikhaylenko)
- Fix search highlight disappearing when repeating search (#166)
- Fix pages without title always appearing first in address bar dropdown (#579)
- Bring back libdazzle subproject for 3.32 branch only (#699)
- Fix new web apps being saved in wrong place under certain circumstances (!224)
- Fix web process settings being saved in the wrong place (!224)
3.32.0 - March 11, 2019
=======================
Major changes since 3.30:
- Redesigned address bar dropdown with new dazzling
- Redesigned open tabs menu, now displays tab favicons and allows closing tabs
- Greatly improved adaptive mode support for small displays
- Three-finger swipe touchpad gesture now available for back/forward navigation
- Automation mode, for running WebDriver tests (useful for website developers)
Changes since 3.31.92:
- Fix preferences dialog crash
- Fix password manager crash on 32-bit systems
- Bump to libhandy 0.0.9 (Adrien Plazas)
3.31.92 - March 4, 2019
=======================
- Add animation when download completes (#629)
- New tab popover should close tabs on middle-click (#643)
- Fix context menu in history dialog (#651)
- Add separators to tab bar context menu (#652)
- Fix crash in mouse gesture controller (#679)
- Disable safe browsing test by default (#684)
- Improve reliability of password form detection
- Fix encoding dialog (Arnaud B.)
- Restore unsafe process model and process count settings for 3.32 branch only
- Change -Dunit_tests meson option to feature rather than bool type
- Require system libdazzle and recent GTK 3.24
- Build libhandy as static lib (Jeremy Bicha)
- Bundle newer libhandy to fix i18n (Adrien Plazas)
- Fix licence in appstream metadata to GPLv3+
3.31.91 - February 18, 2019
===========================
- Fix test failure when not installed (#675)
- libhandy and libdazzle now use git submodules (#676)
- Improve tab bar style in incognito mode (Alexander Mikhaylenko)
3.31.90 - February 4, 2019
==========================
......
......@@ -33,9 +33,9 @@
</kudos>
<project_group>GNOME</project_group>
<compulsory_for_desktop>GNOME</compulsory_for_desktop>
<project_license>GPL-2.0+</project_license>
<project_license>GPL-3.0+</project_license>
<developer_name>The GNOME Project</developer_name>
<url type="bugtracker">https://bugzilla.gnome.org/enter_bug.cgi?product=epiphany</url>
<url type="bugtracker">https://gitlab.gnome.org/GNOME/epiphany/issues</url>
<url type="donation">http://www.gnome.org/friends/</url>
<url type="help">https://help.gnome.org/users/epiphany/stable/</url>
<url type="translate">https://wiki.gnome.org/TranslationProject</url>
......
......@@ -55,6 +55,17 @@
<summary>Whether to delay loading of tabs that are not immediately visible on session restore</summary>
<description>When this option is set to true, tabs will not start loading until the user switches to them, upon session restore.</description>
</key>
<key name="process-model" enum="org.gnome.Epiphany.EphyPrefsProcessModel">
<default>'one-secondary-process-per-web-view'</default>
<summary>Process model</summary>
<description>This option allows to set the process model used. Use “shared-secondary-process” to use a single web process shared by all the tabs and “one-secondary-process-per-web-view” to use a different web process for each tab.</description>
</key>
<key type="u" name="max-processes">
<default>0</default>
<summary>Maximum number of web processes created at the same time when using “one-secondary-process-per-web-view” model</summary>
<description>This option sets a limit to the number of web processes that will be used at the same time for the “one-secondary-process-per-web-view” model. The default value is “0” and means no limit.</description>
</key>
<key type="as" name="adblock-filters">
<default>['https://easylist.to/easylist/easylist.txt', 'https://easylist.to/easylist/easyprivacy.txt']</default>
<summary>List of adblock filters</summary>
......@@ -177,7 +188,7 @@
<key type="b" name="do-not-track">
<default>true</default>
<summary>Do Not Track</summary>
<description>Enables DNT headers and tracking query parameter removal. Note that when changing this setting from the preferences dialog, the adblock-filters setting will additionally be updated to add/remove EasyPrivacy filters.</description>
<description>Enables tracking query parameter removal. Note that when changing this setting from the preferences dialog, the adblock-filters setting will additionally be updated to add/remove EasyPrivacy filters.</description>
</key>
<key type="b" name="enable-adblock">
<default>true</default>
......
......@@ -447,7 +447,7 @@ ephy_about_handler_handle_incognito (EphyAboutHandler *handler,
"</head>\n"
"<body class=\"incognito-body\">\n"
" <div id=\"mainblock\">\n"
" <div style=\"background: transparent url(ephy-resource:///org/gnome/epiphany/incognito.png) no-repeat 10px center;\">\n" \
" <div style=\"background: transparent url(ephy-resource:///org/gnome/epiphany/private-mode.svg) no-repeat 10px center;\">\n" \
" <h1>%s</h1>\n"
" <p>%s</p>\n"
" <p><strong>%s</strong> %s</p>\n"
......
......@@ -58,17 +58,28 @@ ephy_embed_event_init (EphyEmbedEvent *embed_event)
}
EphyEmbedEvent *
ephy_embed_event_new (GdkEventButton *event, WebKitHitTestResult *hit_test_result)
ephy_embed_event_new (GdkEvent *event,
WebKitHitTestResult *hit_test_result)
{
EphyEmbedEvent *embed_event;
embed_event = g_object_new (EPHY_TYPE_EMBED_EVENT, NULL);
embed_event->hit_test_result = g_object_ref (hit_test_result);
embed_event->button = event->button;
embed_event->modifier = event->state;
embed_event->x = event->x;
embed_event->y = event->y;
switch (event->type) {
case GDK_BUTTON_PRESS:
embed_event->button = ((GdkEventButton *)event)->button;
embed_event->modifier = ((GdkEventButton *)event)->state;
embed_event->x = ((GdkEventButton *)event)->x;
embed_event->y = ((GdkEventButton *)event)->y;
break;
case GDK_KEY_PRESS:
embed_event->modifier = ((GdkEventKey *)event)->state;
break;
default:
break;
}
return embed_event;
}
......
......@@ -30,7 +30,7 @@ G_BEGIN_DECLS
G_DECLARE_FINAL_TYPE (EphyEmbedEvent, ephy_embed_event, EPHY, EMBED_EVENT, GObject)
EphyEmbedEvent * ephy_embed_event_new (GdkEventButton *event,
EphyEmbedEvent * ephy_embed_event_new (GdkEvent *event,
WebKitHitTestResult *hit_test_result);
guint ephy_embed_event_get_context (EphyEmbedEvent *event);
guint ephy_embed_event_get_button (EphyEmbedEvent *event);
......
......@@ -492,6 +492,7 @@ ephy_embed_prefs_init (gpointer user_data)
"enable-dns-prefetching", TRUE,
"enable-mediasource", TRUE,
"javascript-can-open-windows-automatically", TRUE,
"enable-back-forward-navigation-gestures", TRUE,
NULL);
for (i = 0; i < G_N_ELEMENTS (webkit_pref_entries); i++) {
......
......@@ -499,12 +499,12 @@ web_extension_password_manager_save_real (EphyEmbedShell *shell,
return;
/* The username field is required if username is present. */
if (username != NULL && username_field == NULL)
g_clear_pointer (&username_field, g_free);
if (username && !username_field)
g_clear_pointer (&username, g_free);
/* The username is required if username field is present. */
if (username == NULL && username_field != NULL)
g_clear_pointer (&username, g_free);
if (!username && username_field)
g_clear_pointer (&username_field, g_free);
/* This also sanity checks that a page isn't saving websites for
* other origins. Remember the request comes from the untrusted web
......@@ -966,10 +966,10 @@ initialize_web_extensions (WebKitWebContext *web_context,
private_profile = priv->mode == EPHY_EMBED_SHELL_MODE_PRIVATE || priv->mode == EPHY_EMBED_SHELL_MODE_INCOGNITO || priv->mode == EPHY_EMBED_SHELL_MODE_AUTOMATION;
browser_mode = priv->mode == EPHY_EMBED_SHELL_MODE_BROWSER;
user_data = g_variant_new ("(smsssbb)",
user_data = g_variant_new ("(smsmssbb)",
priv->guid,
address,
ephy_profile_dir (),
ephy_profile_dir_is_default () ? NULL : ephy_profile_dir (),
ephy_filters_manager_get_adblock_filters_dir (priv->filters_manager),
private_profile,
browser_mode);
......@@ -1067,6 +1067,33 @@ ephy_embed_shell_setup_web_extensions_server (EphyEmbedShell *shell)
g_object_unref (observer);
}
static void
ephy_embed_shell_setup_process_model (EphyEmbedShell *shell)
{
EphyEmbedShellPrivate *priv = ephy_embed_shell_get_instance_private (shell);
EphyPrefsProcessModel process_model;
guint max_processes;
if (ephy_embed_shell_get_mode (shell) == EPHY_EMBED_SHELL_MODE_APPLICATION)
process_model = EPHY_PREFS_PROCESS_MODEL_SHARED_SECONDARY_PROCESS;
else
process_model = g_settings_get_enum (EPHY_SETTINGS_MAIN, EPHY_PREFS_PROCESS_MODEL);
switch (process_model) {
case EPHY_PREFS_PROCESS_MODEL_SHARED_SECONDARY_PROCESS:
max_processes = 1;
break;
case EPHY_PREFS_PROCESS_MODEL_ONE_SECONDARY_PROCESS_PER_WEB_VIEW:
max_processes = g_settings_get_uint (EPHY_SETTINGS_MAIN, EPHY_PREFS_MAX_PROCESSES);
break;
default:
g_assert_not_reached ();
}
webkit_web_context_set_process_model (priv->web_context, WEBKIT_PROCESS_MODEL_MULTIPLE_SECONDARY_PROCESSES);
webkit_web_context_set_web_process_count_limit (priv->web_context, max_processes);
}
static void
ephy_embed_shell_create_web_context (EphyEmbedShell *shell)
{
......@@ -1209,8 +1236,7 @@ ephy_embed_shell_startup (GApplication *application)
G_CALLBACK (web_extension_password_manager_request_save_received_cb),
shell);
webkit_web_context_set_process_model (priv->web_context, WEBKIT_PROCESS_MODEL_MULTIPLE_SECONDARY_PROCESSES);
ephy_embed_shell_setup_process_model (shell);
g_signal_connect_object (priv->web_context, "initialize-web-extensions",
G_CALLBACK (initialize_web_extensions),
shell, 0);
......
......@@ -567,8 +567,6 @@ ephy_find_toolbar_open (EphyFindToolbar *toolbar,
toolbar->typing_ahead = typing_ahead;
toolbar->links_only = links_only;
clear_status (toolbar);
gtk_editable_select_region (GTK_EDITABLE (toolbar->entry), 0, -1);
hdy_search_bar_set_search_mode (HDY_SEARCH_BAR (toolbar), TRUE);
......
......@@ -2819,13 +2819,13 @@ ephy_web_view_init (EphyWebView *web_view)
web_view->history_service = ephy_embed_shell_get_global_history_service (ephy_embed_shell_get_default ());
web_view->history_service_cancellable = g_cancellable_new ();
g_signal_connect (EPHY_SETTINGS_READER, "changed::" EPHY_PREFS_READER_FONT_STYLE,
G_CALLBACK (reader_setting_changed_cb),
web_view);
g_signal_connect_object (EPHY_SETTINGS_READER, "changed::" EPHY_PREFS_READER_FONT_STYLE,
G_CALLBACK (reader_setting_changed_cb),
web_view, 0);
g_signal_connect (EPHY_SETTINGS_READER, "changed::" EPHY_PREFS_READER_COLOR_SCHEME,
G_CALLBACK (reader_setting_changed_cb),
web_view);
g_signal_connect_object (EPHY_SETTINGS_READER, "changed::" EPHY_PREFS_READER_COLOR_SCHEME,
G_CALLBACK (reader_setting_changed_cb),
web_view, 0);
g_signal_connect (web_view, "decide-policy",
G_CALLBACK (decide_policy_cb),
......@@ -3585,14 +3585,15 @@ ephy_web_view_print (EphyWebView *view)
G_CALLBACK (print_operation_failed_cb),
view);
webkit_print_operation_set_page_setup (operation, ephy_embed_shell_get_page_setup (shell));
settings = gtk_print_settings_new ();
settings = ephy_embed_shell_get_print_settings (shell);
gtk_print_settings_set (settings,
GTK_PRINT_SETTINGS_OUTPUT_BASENAME,
webkit_web_view_get_title (WEBKIT_WEB_VIEW (view)));
webkit_print_operation_set_print_settings (operation, settings);
webkit_print_operation_run_dialog (operation, NULL);
if (webkit_print_operation_run_dialog (operation, NULL) == WEBKIT_PRINT_OPERATION_RESPONSE_PRINT)
ephy_embed_shell_set_print_settings (shell, webkit_print_operation_get_print_settings (operation));
g_object_unref (operation);
g_object_unref (settings);
}
static void
......
......@@ -42,7 +42,7 @@ webkit_web_extension_initialize_with_user_data (WebKitWebExtension *webkit_exten
gboolean browser_mode;
GError *error = NULL;
g_variant_get (user_data, "(&sm&s&s&sbb)", &guid, &server_address, &dot_dir, &adblock_data_dir, &private_profile, &browser_mode);
g_variant_get (user_data, "(&sm&sm&s&sbb)", &guid, &server_address, &dot_dir, &adblock_data_dir, &private_profile, &browser_mode);
if (!server_address) {
g_warning ("UI process did not start D-Bus server, giving up.");
......
......@@ -145,21 +145,14 @@ web_page_send_request (WebKitWebPage *web_page,
const char *request_uri;
const char *redirected_response_uri;
const char *page_uri;
char *modified_uri = NULL;
g_autofree char *modified_uri = NULL;
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 (g_settings_get_boolean (EPHY_SETTINGS_WEB_EXTENSION_WEB, EPHY_PREFS_WEB_DO_NOT_TRACK)) {
SoupMessageHeaders *headers = webkit_uri_request_get_http_headers (request);
if (headers) {
/* Do Not Track header. '1' means 'opt-out'. See:
* http://tools.ietf.org/id/draft-mayer-do-not-track-00.txt */
soup_message_headers_append (headers, "DNT", "1");
}
if (g_settings_get_boolean (EPHY_SETTINGS_WEB_EXTENSION_WEB, EPHY_PREFS_WEB_DO_NOT_TRACK))
modified_uri = ephy_remove_tracking_from_uri (request_uri);
}
if (should_use_adblocker (request_uri, page_uri, redirected_response_uri)) {
char *result;
......@@ -168,13 +161,12 @@ web_page_send_request (WebKitWebPage *web_page,
result = ephy_uri_tester_rewrite_uri (extension->uri_tester,
modified_uri ? modified_uri : request_uri,
page_uri);
g_free (modified_uri);
if (!result) {
LOG ("Refused to load %s", request_uri);
return TRUE;
}
g_free (modified_uri);
modified_uri = result;
} else if (!modified_uri) {
return FALSE;
......@@ -185,8 +177,6 @@ web_page_send_request (WebKitWebPage *web_page,
webkit_uri_request_set_uri (request, modified_uri);
}
g_free (modified_uri);
return FALSE;
}
......@@ -256,7 +246,6 @@ web_page_form_controls_associated (WebKitWebPage *web_page,
JSCValue *js_ephy;
JSCValue *js_serializer;
JSCValue *js_result;
gboolean remember_passwords;
guint i;
frame = webkit_web_page_get_main_frame (web_page);
......@@ -275,14 +264,11 @@ web_page_form_controls_associated (WebKitWebPage *web_page,
G_CALLBACK (sensitive_form_message_serializer), NULL, NULL,
G_TYPE_STRING, 2,
G_TYPE_UINT64, G_TYPE_BOOLEAN);
remember_passwords = !extension->is_private_profile &&
g_settings_get_boolean (EPHY_SETTINGS_WEB_EXTENSION_WEB, EPHY_PREFS_WEB_REMEMBER_PASSWORDS);
js_result = jsc_value_object_invoke_method (js_ephy,
"formControlsAssociated",
G_TYPE_UINT64, webkit_web_page_get_id (web_page),
G_TYPE_PTR_ARRAY, form_controls,
JSC_TYPE_VALUE, js_serializer,
G_TYPE_BOOLEAN, remember_passwords,
G_TYPE_NONE);
g_object_unref (js_result);
g_ptr_array_unref (form_controls);
......@@ -660,19 +646,26 @@ js_is_edited (JSCValue *js_element)
return webkit_dom_element_html_input_element_is_user_edited (WEBKIT_DOM_ELEMENT (node));
}
static gboolean
js_should_remember_passwords (EphyWebExtension *extension)
{
g_assert (EPHY_IS_WEB_EXTENSION (extension));
return !extension->is_private_profile && g_settings_get_boolean (EPHY_SETTINGS_WEB_EXTENSION_WEB, EPHY_PREFS_WEB_REMEMBER_PASSWORDS);
}
static void
js_exception_handler (JSCContext *context,
JSCException *exception)
{
JSCValue *js_console;
JSCValue *js_result;
g_autoptr(JSCValue) js_console = NULL;
g_autoptr(JSCValue) js_result = NULL;
g_autofree char *report = NULL;
js_console = jsc_context_get_value (context, "console");
js_result = jsc_value_object_invoke_method (js_console, "error", JSC_TYPE_EXCEPTION, exception, G_TYPE_NONE);
g_object_unref (js_result);
g_object_unref (js_console);
g_warning ("JavaScriptException: %s", jsc_exception_get_message (exception));
report = jsc_exception_report (exception);
g_warning ("%s", report);
jsc_context_throw_exception (context, exception);
}
......@@ -751,12 +744,10 @@ window_object_cleared_cb (WebKitScriptWorld *world,
js_ephy);
if (!extension->is_private_profile) {
guint64 page_id = webkit_web_page_get_id (page);
g_assert (page_id < G_MAXINT32);
g_autoptr(JSCValue) js_password_manager_ctor = jsc_value_object_get_property (js_ephy, "PasswordManager");
g_autoptr(JSCValue) js_password_manager = jsc_value_constructor_call (js_password_manager_ctor,
G_TYPE_INT, page_id, G_TYPE_NONE);
G_TYPE_UINT64, webkit_web_page_get_id (page),
G_TYPE_NONE);
jsc_value_object_set_property (js_ephy, "passwordManager", js_password_manager);
js_function = jsc_value_new_function (js_context,
......@@ -784,6 +775,14 @@ window_object_cleared_cb (WebKitScriptWorld *world,
jsc_value_object_set_property (js_ephy, "isEdited", js_function);
g_object_unref (js_function);
js_function = jsc_value_new_function (js_context,
"shouldRememberPasswords",
G_CALLBACK (js_should_remember_passwords),
g_object_ref (extension), g_object_unref,
G_TYPE_BOOLEAN, 0);
jsc_value_object_set_property (js_ephy, "shouldRememberPasswords", js_function);
g_object_unref (js_function);
g_object_unref (js_ephy);
g_object_unref (js_context);
}
......
var Ephy = {};
Ephy.formControlsAssociated = function(pageID, forms, serializer, rememberPasswords)
Ephy.formControlsAssociated = function(pageID, forms, serializer)
{
Ephy.formManagers = [];
......@@ -9,8 +9,7 @@ Ephy.formControlsAssociated = function(pageID, forms, serializer, rememberPasswo
continue;
let formManager = new Ephy.FormManager(pageID, forms[i]);
formManager.handleSensitiveElement(serializer);
if (rememberPasswords)
formManager.preFillForms();
formManager.preFillForms();
Ephy.formManagers.push(formManager);
}
}
......@@ -425,6 +424,9 @@ Ephy.FormManager = class FormManager
preFillForms()
{
if (!Ephy.shouldRememberPasswords())
return;
this._formAuth = this._findFormAuthElements(true);
if (!this._formAuth || !this._formAuth.passwordNode) {
Ephy.log('No pre-fillable/hookable form found');
......@@ -460,13 +462,16 @@ Ephy.FormManager = class FormManager
preFill()
{
if (!Ephy.shouldRememberPasswords())
return;
const self = this;
Ephy.passwordManager.query(
this._formAuth.url.origin,
this._formAuth.targetURL.origin,
this._formAuth.usernameNode && this._formAuth.usernameNode.value ? this._formAuth.usernameNode.value : null,
this._formAuth.usernameNode ? this._formAuth.usernameNode.name : null,
this._formAuth.passwordNode.name ? this._formAuth.passwordNode.name : null).then(function (authInfo) {
this._formAuth.usernameNode ? (this._formAuth.usernameNode.name ? this._formAuth.usernameNode.name : this._formAuth.usernameNode.id) : null,
this._formAuth.passwordNode.name ? this._formAuth.passwordNode.name : this._formAuth.passwordNode.id).then(function (authInfo) {
if (!authInfo) {
Ephy.log('No result');
return;
......@@ -491,6 +496,9 @@ Ephy.FormManager = class FormManager
handleFormSubmission()
{
if (!Ephy.shouldRememberPasswords())
return;
if (!this._formAuth)
return;
......@@ -500,17 +508,17 @@ Ephy.FormManager = class FormManager
return;
}
if (!this._formAuth.passwordNode.value || !this._formAuth.passwordNode.name)
if (!this._formAuth.passwordNode.value || (!this._formAuth.passwordNode.name && !this._formAuth.passwordNode.id))
return;
let password = this._formAuth.passwordNode.value;
let passwordField = this._formAuth.passwordNode.name;
let passwordField = this._formAuth.passwordNode.name ? this._formAuth.passwordNode.name : this._formAuth.passwordNode.id;
let username = null;
let usernameField = null;
if (this._formAuth.usernameNode && this._formAuth.usernameNode.value && this._formAuth.usernameNode.name) {
if (this._formAuth.usernameNode && this._formAuth.usernameNode.value && (this._formAuth.usernameNode.name || this._formAuth.usernameNode.id)) {
username = this._formAuth.usernameNode.value;
usernameField = this._formAuth.usernameNode.name;
usernameField = this._formAuth.usernameNode.name ? this._formAuth.usernameNode.name : this._formAuth.usernameNode.id;
}
this._formAuth.url = new URL(String(window.location));
......
......@@ -71,6 +71,12 @@ typedef enum
EPHY_PREFS_WEB_HARDWARE_ACCELERATION_POLICY_NEVER
} EphyPrefsWebHardwareAccelerationPolicy;
typedef enum
{
EPHY_PREFS_PROCESS_MODEL_SHARED_SECONDARY_PROCESS,
EPHY_PREFS_PROCESS_MODEL_ONE_SECONDARY_PROCESS_PER_WEB_VIEW
} EphyPrefsProcessModel;
#define EPHY_PREFS_UI_SCHEMA "org.gnome.Epiphany.ui"
#define EPHY_PREFS_UI_EXPAND_TABS_BAR "expand-tabs-bar"
#define EPHY_PREFS_UI_TABS_BAR_POSITION "tabs-bar-position"
......@@ -165,6 +171,8 @@ static const char * const ephy_prefs_web_schema[] = {
#define EPHY_PREFS_INTERNAL_VIEW_SOURCE "internal-view-source"
#define EPHY_PREFS_RESTORE_SESSION_POLICY "restore-session-policy"
#define EPHY_PREFS_RESTORE_SESSION_DELAYING_LOADS "restore-session-delaying-loads"
#define EPHY_PREFS_PROCESS_MODEL "process-model"
#define EPHY_PREFS_MAX_PROCESSES "max-processes"
#define EPHY_PREFS_ADBLOCK_FILTERS "adblock-filters"
#define EPHY_PREFS_SEARCH_ENGINES "search-engines"
#define EPHY_PREFS_DEFAULT_SEARCH_ENGINE "default-search-engine"
......
......@@ -73,12 +73,13 @@ ephy_profile_utils_get_migration_version (void)
}
gboolean
ephy_profile_utils_set_migration_version (int version)
ephy_profile_utils_set_migration_version_for_profile_dir (int version,
const char *profile_directory)
{
char *migrated_file, *contents;
gboolean result = FALSE;
migrated_file = g_build_filename (ephy_profile_dir (),
migrated_file = g_build_filename (profile_directory,
PROFILE_MIGRATION_FILE,
NULL);
contents = g_strdup_printf ("%d", version);
......@@ -86,7 +87,7 @@ ephy_profile_utils_set_migration_version (int version)
if (result == FALSE)
LOG ("Couldn't store migration version %d in %s (%s, %s)",
version, migrated_file, ephy_profile_dir (), PROFILE_MIGRATION_FILE);
version, migrated_file, profile_directory, PROFILE_MIGRATION_FILE);
g_free (contents);
g_free (migrated_file);
......@@ -94,6 +95,12 @@ ephy_profile_utils_set_migration_version (int version)
return result;
}
gboolean
ephy_profile_utils_set_migration_version (int version)
{
return ephy_profile_utils_set_migration_version_for_profile_dir (version, ephy_profile_dir ());
}
#define EPHY_PROFILE_MIGRATOR "ephy-profile-migrator"
gboolean
......
......@@ -24,7 +24,7 @@
G_BEGIN_DECLS
#define EPHY_PROFILE_MIGRATION_VERSION 30
#define EPHY_PROFILE_MIGRATION_VERSION 32
#define EPHY_INSECURE_PASSWORDS_MIGRATION_VERSION 11
#define EPHY_FIREFOX_SYNC_PASSWORDS_MIGRATION_VERSION 19
#define EPHY_TARGET_ORIGIN_MIGRATION_VERSION 21
......@@ -40,6 +40,7 @@ int ephy_profile_utils_get_migration_version (void);
int ephy_profile_utils_get_migration_version_for_profile_dir (const char *profile_directory);
gboolean ephy_profile_utils_set_migration_version (int version);
gboolean ephy_profile_utils_set_migration_version_for_profile_dir (int version, const char *profile_directory);
gboolean ephy_profile_utils_do_migration (const char *profile_directory, int test_to_run, gboolean debug);
......
......@@ -127,7 +127,8 @@ ephy_suggestion_init (EphySuggestion *self)
}
EphySuggestion *
ephy_suggestion_new (const char *title,
ephy_suggestion_new (const char *title_markup,
const char *unescaped_title,
const char *uri)
{
EphySuggestion *suggestion;
......@@ -138,8 +139,8 @@ ephy_suggestion_new (const char *title,
"icon-name", "web-browser-symbolic",
"id", uri,
"subtitle", escaped_uri,
"title", title,
"unescaped-title", title,
"title", title_markup,
"unescaped-title", unescaped_title,
NULL);
g_free (decoded_uri);
......@@ -149,7 +150,8 @@ ephy_suggestion_new (const char *title,
}
EphySuggestion *
ephy_suggestion_new_without_subtitle (const char *title,
ephy_suggestion_new_without_subtitle (const char *title_markup,
const char *unescaped_title,
const char *uri)
{
EphySuggestion *suggestion;
......@@ -157,8 +159,8 @@ ephy_suggestion_new_without_subtitle (const char *title,
suggestion = g_object_new (EPHY_TYPE_SUGGESTION,
"icon-name", "web-browser-symbolic",
"id", uri,
"title", title,
"unescaped-title", title,
"title", title_markup,
"unescaped-title", unescaped_title,
NULL);
return suggestion;
......
......@@ -27,9 +27,11 @@ G_BEGIN_DECLS
G_DECLARE_FINAL_TYPE (EphySuggestion, ephy_suggestion, EPHY, SUGGESTION, DzlSuggestion)
EphySuggestion *ephy_suggestion_new (const char *title,
EphySuggestion *ephy_suggestion_new (const char *title_markup,
const char *unescaped_title,
const char *uri);
EphySuggestion *ephy_suggestion_new_without_subtitle (const char *title,
EphySuggestion *ephy_suggestion_new_without_subtitle (const char *title_markup,
const char *unescaped_title,
const char *uri);
const char *ephy_suggestion_get_unescaped_title (EphySuggestion *self);
const char *ephy_suggestion_get_uri (EphySuggestion *self);
......
......@@ -23,6 +23,7 @@
#include "ephy-debug.h"
#include "ephy-file-helpers.h"
#include "ephy-profile-utils.h"
#include "ephy-settings.h"
#include <errno.h>
......@@ -156,6 +157,19 @@ get_app_id_from_profile_directory (const char *profile_dir)
return program_name ? get_app_id_from_program_name (program_name) : NULL;
}
static char *
ephy_web_application_get_directory_under (const char *id,
const char *path)
{
g_autofree char *app_dir = NULL;
app_dir = get_app_profile_directory_name (id);
if (!app_dir)
return NULL;
return g_build_filename (path, app_dir, NULL);
}
/**
* ephy_web_application_get_profile_directory:
* @id: the application identifier
......@@ -167,18 +181,19 @@ get_app_id_from_profile_directory (const char *profile_dir)
char *
ephy_web_application_get_profile_directory (const char *id)
{
char *dot_dir, *app_dir, *profile_dir;
app_dir = get_app_profile_directory_name (id);
if (!app_dir)
return NULL;
return ephy_web_application_get_directory_under (id, g_get_user_data_dir ());
}
dot_dir = !ephy_profile_dir_is_default () ? ephy_default_profile_dir () : NULL;
profile_dir = g_build_filename (dot_dir ? dot_dir : g_get_user_data_dir (), app_dir, NULL);
g_free (app_dir);
g_free (dot_dir);
static char *
ephy_web_application_get_cache_directory (const char *id)
{
return ephy_web_application_get_directory_under (id, g_get_user_cache_dir ());
}
return profile_dir;
static char *
ephy_web_application_get_config_directory (const char *id)
{
return ephy_web_application_get_directory_under (id, g_get_user_config_dir ());
}
/**
......@@ -193,51 +208,68 @@ ephy_web_application_get_profile_directory (const char *id)
gboolean
ephy_web_application_delete (const char *id)
{
char *profile_dir;
char *desktop_file = NULL, *desktop_path = NULL;
GFile *launcher = NULL;
gboolean return_value = FALSE;
g_autofree char *profile_dir = NULL;
g_autofree char *cache_dir = NULL;
g_autofree char *config_dir = NULL;
g_autofree char *desktop_file = NULL;
g_autofree char *desktop_path = NULL;
g_autoptr(GFile) launcher = NULL;
g_autoptr(GError) error = NULL;
g_assert (id);
profile_dir = ephy_web_application_get_profile_directory (id);
if (!profile_dir)
goto out;
return FALSE;
/* If there's no profile dir for this app, it means it does not
* exist. */
if (!g_file_test (profile_dir, G_FILE_TEST_IS_DIR)) {
g_warning ("No application with id '%s' is installed.\n", id);
goto out;
return FALSE;
}
if (!ephy_file_delete_dir_recursively (profile_dir, NULL))
goto out;
if (!ephy_file_delete_dir_recursively (profile_dir, &error)) {
g_warning ("Failed to recursively delete %s: %s", profile_dir, error->message);
return FALSE;
}
LOG ("Deleted application profile.\n");
cache_dir = ephy_web_application_get_cache_directory (id);
if (g_file_test (cache_dir, G_FILE_TEST_IS_DIR)) {
if (!ephy_file_delete_dir_recursively (cache_dir, &error)) {
g_warning ("Failed to recursively delete %s: %s", cache_dir, error->message);
return FALSE;
}
LOG ("Deleted application cache directory.\n");
}
config_dir = ephy_web_application_get_config_directory (id);
if (g_file_test (config_dir, G_FILE_TEST_IS_DIR)) {
if (!ephy_file_delete_dir_recursively (config_dir, &error)) {
g_warning ("Failed to recursively delete %s: %s", config_dir, error->message);
return FALSE;
}
LOG ("Deleted application config directory.\n");
}
desktop_file = get_app_desktop_filename (id);
if (!desktop_file)
goto out;
if (!desktop_file) {
g_warning ("Failed to compute desktop filename for app %s", id);
return FALSE;
}
desktop_path = g_build_filename (g_get_user_data_dir (), "applications", desktop_file, NULL);
if (g_file_test (desktop_path, G_FILE_TEST_IS_SYMLINK)) {
launcher = g_file_new_for_path (desktop_path);
if (!g_file_delete (launcher, NULL, NULL))
goto out;
if (!g_file_delete (launcher, NULL, &error)) {
g_warning ("Failed to delete %s: %s", desktop_path, error->message);
return FALSE;
}
LOG ("Deleted application launcher.\n");
}
return_value = TRUE;
out:
g_free (profile_dir);
if (launcher)
g_object_unref (launcher);
g_free (desktop_file);
g_free (desktop_path);
return return_value;
return TRUE;
}
static char *
......@@ -359,6 +391,9 @@ ephy_web_application_create (const char *id,
goto out;
}
/* Skip migration for new web apps. */
ephy_profile_utils_set_migration_version_for_profile_dir (EPHY_PROFILE_MIGRATION_VERSION, profile_dir);
/* Create an .app file. */
g_autofree char *app_file = g_build_filename (profile_dir, ".app", NULL);
int fd = g_open (app_file, O_WRONLY|O_CREAT|O_TRUNC, 0644);
......@@ -563,22 +598,20 @@ ephy_web_application_get_application_list_internal (gboolean only_legacy)
GFileEnumerator *children = NULL;
GFileInfo *info;
GList *applications = NULL;
GFile *dot_dir;
char *default_dot_dir;
g_autofree char *profile_base = NULL;
default_dot_dir = !ephy_profile_dir_is_default () ? ephy_default_profile_dir () : NULL;
if (only_legacy) {
profile_base = g_build_filename (g_get_user_config_dir (), "epiphany", NULL);
dot_dir = g_file_new_for_path (profile_base);
} else {
profile_base = g_strdup (g_get_user_data_dir ());
dot_dir = g_file_new_for_path (default_dot_dir ? default_dot_dir : g_get_user_data_dir ());
}
children = g_file_enumerate_children (dot_dir,
g_autofree char *parent_directory_path = NULL;
g_autoptr(GFile) parent_directory = NULL;
if (only_legacy)
parent_directory_path = g_build_filename (g_get_user_config_dir (), "epiphany", NULL);
else
parent_directory_path = g_strdup (g_get_user_data_dir ());
parent_directory = g_file_new_for_path (parent_directory_path);
children = g_file_enumerate_children (parent_directory,
"standard::name",
0, NULL, NULL);
g_object_unref (dot_dir);
if (!children)
return NULL;
info = g_file_enumerator_next_file (children, NULL, NULL);
while (info) {
......@@ -590,7 +623,7 @@ ephy_web_application_get_application_list_internal (gboolean only_legacy)
EphyWebApplication *app;
char *profile_dir;
profile_dir = g_build_filename (profile_base, name, NULL);
profile_dir = g_build_filename (parent_directory_path, name, NULL);
app = ephy_web_application_for_profile_directory (profile_dir);
if (app) {
if (!only_legacy) {
......@@ -612,7 +645,6 @@ ephy_web_application_get_application_list_internal (gboolean only_legacy)
}
g_object_unref (children);
g_free (default_dot_dir);
return g_list_reverse (applications);
}
......
......@@ -292,6 +292,8 @@ out:
g_list_free_full (threat_lists, (GDestroyNotify)ephy_gsb_threat_list_free);
ephy_gsb_storage_set_metadata (self->storage, "next_list_updates_time", self->next_list_updates_time);
g_object_unref (self);
}
static void
......@@ -313,7 +315,7 @@ ephy_gsb_service_update (EphyGSBService *self)
g_assert (ephy_gsb_storage_is_operable (self->storage));
g_atomic_int_set (&self->is_updating, TRUE);
task = g_task_new (self, NULL,
task = g_task_new (g_object_ref (self), NULL,
(GAsyncReadyCallback)ephy_gsb_service_update_finished_cb,
NULL);
g_task_run_in_thread (task, (GTaskThreadFunc)ephy_gsb_service_update_thread);
......
......@@ -378,6 +378,17 @@ ephy_gsb_storage_open_db (EphyGSBStorage *self)
return TRUE;
}
static void
ephy_gsb_storage_clear_db (EphyGSBStorage *self)
{
g_assert (EPHY_IS_GSB_STORAGE (self));
g_assert (EPHY_IS_SQLITE_CONNECTION (self->db));
ephy_sqlite_connection_close (self->db);
ephy_sqlite_connection_delete_database (self->db);
g_clear_object (&self->db);
}
static gboolean
ephy_gsb_storage_init_db (EphyGSBStorage *self)
{
......@@ -394,15 +405,21 @@ ephy_gsb_storage_init_db (EphyGSBStorage *self)
ephy_gsb_storage_init_hash_prefix_table (self) &&
ephy_gsb_storage_init_hash_full_table (self);
if (!success) {
ephy_sqlite_connection_close (self->db);
ephy_sqlite_connection_delete_database (self->db);
g_clear_object (&self->db);
}
if (!success)
ephy_gsb_storage_clear_db (self);
return success;
}
static gboolean
ephy_gsb_storage_recreate_db (EphyGSBStorage *self)
{
g_assert (EPHY_IS_GSB_STORAGE (self));
ephy_gsb_storage_clear_db (self);
return ephy_gsb_storage_init_db (self);
}
static inline gboolean
ephy_gsb_storage_check_schema_version (EphyGSBStorage *self)
{
......@@ -481,10 +498,7 @@ ephy_gsb_storage_constructed (GObject *object)
success = ephy_gsb_storage_open_db (self);
if (success && !ephy_gsb_storage_check_schema_version (self)) {
LOG ("GSB database schema incompatibility, recreating database...");
ephy_sqlite_connection_close (self->db);
ephy_sqlite_connection_delete_database (self->db);
g_clear_object (&self->db);
success = ephy_gsb_storage_init_db (self);
success = ephy_gsb_storage_recreate_db (self);
}
}
......@@ -585,6 +599,7 @@ ephy_gsb_storage_get_metadata (EphyGSBStorage *self,
g_warning ("Failed to execute select metadata statement: %s", error->message);
g_error_free (error);
g_object_unref (statement);
ephy_gsb_storage_recreate_db (self);
return default_value;
}
......@@ -645,6 +660,7 @@ ephy_gsb_storage_set_metadata (EphyGSBStorage *self,
if (error) {
g_warning ("Failed to execute update metadata statement: %s", error->message);
g_error_free (error);
ephy_gsb_storage_recreate_db (self);
}
}
......@@ -693,6 +709,7 @@ ephy_gsb_storage_get_threat_lists (EphyGSBStorage *self)
if (error) {
g_warning ("Failed to execute select threat lists statement: %s", error->message);
g_error_free (error);
ephy_gsb_storage_recreate_db (self);
}
g_object_unref (statement);
......@@ -753,6 +770,7 @@ ephy_gsb_storage_compute_checksum (EphyGSBStorage *self,
if (error) {
g_warning ("Failed to execute select hash prefix statement: %s", error->message);
g_error_free (error);
ephy_gsb_storage_recreate_db (self);
goto out;
}
......@@ -821,6 +839,7 @@ ephy_gsb_storage_update_client_state (EphyGSBStorage *self,
if (error) {
g_warning ("Failed to execute update threat statement: %s", error->message);
g_error_free (error);
ephy_gsb_storage_recreate_db (self);
}
g_object_unref (statement);
......@@ -863,6 +882,7 @@ ephy_gsb_storage_clear_hash_prefixes (EphyGSBStorage *self,
if (error) {
g_warning ("Failed to execute clear hash prefix statement: %s", error->message);
g_error_free (error);
ephy_gsb_storage_recreate_db (self);
}
g_object_unref (statement);
......@@ -915,6 +935,7 @@ ephy_gsb_storage_get_hash_prefixes_to_delete (EphyGSBStorage *self,
if (error) {
g_warning ("Failed to execute select prefix value statement: %s", error->message);
g_error_free (error);
ephy_gsb_storage_recreate_db (self);
}
g_object_unref (statement);
......@@ -997,6 +1018,7 @@ ephy_gsb_storage_delete_hash_prefixes_batch (EphyGSBStorage *self,
if (error) {
g_warning ("Failed to execute delete hash prefix statement: %s", error->message);
g_error_free (error);
ephy_gsb_storage_recreate_db (self);
}
out:
......@@ -1178,6 +1200,7 @@ ephy_gsb_storage_insert_hash_prefixes_batch (EphyGSBStorage *self,
if (error) {
g_warning ("Failed to execute insert hash prefix statement: %s", error->message);
g_error_free (error);
ephy_gsb_storage_recreate_db (self);
}
out:
......@@ -1355,6 +1378,7 @@ ephy_gsb_storage_lookup_hash_prefixes (EphyGSBStorage *self,
g_error_free (error);
g_list_free_full (retval, (GDestroyNotify)ephy_gsb_hash_prefix_lookup_free);
retval = NULL;
ephy_gsb_storage_recreate_db (self);
}
g_object_unref (statement);
......@@ -1439,6 +1463,7 @@ ephy_gsb_storage_lookup_full_hashes (EphyGSBStorage *self,
g_error_free (error);
g_list_free_full (retval, (GDestroyNotify)ephy_gsb_hash_full_lookup_free);
retval = NULL;
ephy_gsb_storage_recreate_db (self);
}
g_object_unref (statement);
......@@ -1496,6 +1521,7 @@ ephy_gsb_storage_insert_full_hash (EphyGSBStorage *self,
ephy_sqlite_statement_step (statement, &error);
if (error) {
g_warning ("Failed to execute insert full hash statement: %s", error->message);
ephy_gsb_storage_recreate_db (self);
goto out;
}
......@@ -1523,8 +1549,10 @@ ephy_gsb_storage_insert_full_hash (EphyGSBStorage *self,
goto out;
ephy_sqlite_statement_step (statement, &error);
if (error)
if (error) {
g_warning ("Failed to execute insert full hash statement: %s", error->message);
ephy_gsb_storage_recreate_db (self);
}
out:
if (statement)
......@@ -1573,6 +1601,7 @@ ephy_gsb_storage_delete_old_full_hashes (EphyGSBStorage *self)
if (error) {
g_warning ("Failed to execute delete full hash statement: %s", error->message);
g_error_free (error);
ephy_gsb_storage_recreate_db (self);
}
g_object_unref (statement);
......@@ -1631,6 +1660,7 @@ ephy_gsb_storage_update_hash_prefix_expiration (EphyGSBStorage *self,
if (error) {
g_warning ("Failed to execute update hash prefix statement: %s", error->message);
g_error_free (error);
ephy_gsb_storage_recreate_db (self);
}
g_object_unref (statement);
......
......@@ -303,9 +303,7 @@ 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 (entry->url_entry), GTK_INPUT_HINT_NO_EMOJI);
#endif
}
static void
......
project('epiphany', 'c',
license: 'GPL3+',
version: '3.31.90',
version: '3.32.1.2',
meson_version: '>= 0.42.0',
default_options: ['c_std=gnu11']
)
......@@ -76,13 +76,10 @@ else
)
endif
# Dependencies policy: except for WebKitGTK+, all dependency versions must be
# available in Ubuntu 18.04. Please check before bumping the required version
# of any dependency.
glib_requirement = '>= 2.56.0'
gtk_requirement = '>= 3.22.13'
gtk_requirement = '>= 3.24.0'
nettle_requirement = '>= 3.4'
webkitgtk_requirement = '>= 2.21.92'
webkitgtk_requirement = '>= 2.24.1'
cairo_dep = dependency('cairo', version: '>= 1.2')
gcr_dep = dependency('gcr-3', version: '>= 3.5.5')
......@@ -98,8 +95,8 @@ hogweed_dep = dependency('hogweed', version: nettle_requirement)
icu_uc_dep = dependency('icu-uc', version: '>= 4.6')
iso_codes_dep = dependency('iso-codes', version: '>= 0.35')
json_glib_dep = dependency('json-glib-1.0', version: '>= 1.2.4')
libdazzle_dep = dependency('libdazzle-1.0', version: '>= 3.29.4', required: false)
libhandy_dep = dependency('libhandy-0.0', version: '>= 0.0.7', required: false)
libdazzle_dep = dependency('libdazzle-1.0', version: '>= 3.31.90', required: false)
libhandy_dep = dependency('libhandy-0.0', version: '>= 0.0.9', required: false)
libnotify_dep = dependency('libnotify', version: '>= 0.5.1')
libsecret_dep = dependency('libsecret-1', version: '>= 0.14')
libsoup_dep = dependency('libsoup-2.4', version: '>= 2.48.0')
......@@ -109,8 +106,7 @@ sqlite3_dep = dependency('sqlite3', version: '>= 3.0')
webkit2gtk_dep = dependency('webkit2gtk-4.0', version: webkitgtk_requirement)
webkit2gtk_web_extension_dep = dependency('webkit2gtk-web-extension-4.0', version: webkitgtk_requirement)
# Ubuntu 18.04 has libdazzle 3.28, the max we can require from the system, but
# we need 3.30, so bundle it if the system copy is too old.
# Debian Buster wants to ship Ephy 3.32 but libdazzle 3.30, which is too old.
if not libdazzle_dep.found()
libdazzle_dep = subproject('libdazzle', default_options: ['package_subdir=epiphany',
'enable_tools=false',
......@@ -125,6 +121,7 @@ if not libhandy_dep.found()
'glade_catalog=disabled',
'introspection=disabled',
'package_subdir=epiphany',
'static=true',
'tests=false',
'vapi=false']).get_variable('libhandy_dep')
endif
......
......@@ -4,6 +4,12 @@ option('developer_mode',
description: 'Enable developer mode'
)
option('network_tests',
type: 'feature',
value: 'disabled',
description: 'Enable tests that require network access, if unit_tests are enabled'
)
option('tech_preview',
type: 'boolean',
value: false,
......@@ -11,7 +17,7 @@ option('tech_preview',
)
option('unit_tests',
type: 'boolean',
value: true,
type: 'feature',
value: 'enabled',
description: 'Enable unit tests'
)
# List of source files that should *not* be translated.
# Please keep this file sorted alphabetically.
subprojects/libdazzle
subprojects/libhandy
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.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
......@@ -7,8 +7,8 @@ msgid ""
msgstr ""
"Project-Id-Version: epiphany gnome-3-20\n"
"Report-Msgid-Bugs-To: https://gitlab.gnome.org/GNOME/epiphany/issues\n"
"POT-Creation-Date: 2019-02-05 03:26+0000\n"
"PO-Revision-Date: 2019-02-05 12:18+0100\n"
"POT-Creation-Date: 2019-02-20 21:58+0000\n"
"PO-Revision-Date: 2019-02-26 21:31+0100\n"
"Last-Translator: Fabio Tomat <f.t.public@gmail.com>\n"
"Language-Team: Friulian <f.t.public@gmail.com>\n"
"Language: fur\n"
......@@ -16,7 +16,7 @@ msgstr ""
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
"X-Generator: Poedit 2.2\n"
"X-Generator: Poedit 2.2.1\n"
#: data/org.gnome.Epiphany.appdata.xml.in:6
msgid "GNOME Web"
......@@ -284,7 +284,7 @@ msgid ""
"is set."
msgstr ""
"Un valôr di doprâ par sorescrivi il caratar dal scritori sans-serif cuant "
"che use-gnome-fonts al è impuestât."
"che use-gnome-fonts al è stabilît."
#: data/org.gnome.epiphany.gschema.xml:115
msgid "Custom serif font"
......@@ -296,7 +296,7 @@ msgid ""
"set."
msgstr ""
"Un valôr di doprâ par sorescrivi il caratar dal scritori serif cuant che use-"
"gnome-fonts al è impuestât."
"gnome-fonts al è stabilît."
#: data/org.gnome.epiphany.gschema.xml:120
msgid "Custom monospace font"
......@@ -308,7 +308,7 @@ msgid ""
"is set."
msgstr ""
"Un valôr di doprâ par sorescrivi il caratar dal scritori a spazis fis cuant "
"che use-gnome-fonts al è impuestât."
"che use-gnome-fonts al è stabilît."
#: data/org.gnome.epiphany.gschema.xml:125
msgid "Use a custom CSS"
......@@ -418,14 +418,14 @@ msgstr "Do Not Track"
#: data/org.gnome.epiphany.gschema.xml:180
msgid ""
"Enables DNT headers and tracking query parameter removal. Note that when "
"changing this setting from the preferences dialog, the adblock-filters "
"setting will additionally be updated to add/remove EasyPrivacy filters."
"Enables tracking query parameter removal. Note that when changing this "
"setting from the preferences dialog, the adblock-filters setting will "
"additionally be updated to add/remove EasyPrivacy filters."
msgstr ""
"Abilite lis intestazions DNT e la rimozion dai parametris di interogazion di "
"segnadure. Viôt che cuant che si cambie cheste impostazion dal dialic des "
"preferencis, la impostazion dai filtris di adblock e sarà ancje inzornade "
"par zontâ/gjavâ i filtris EasyPrivacy."
"Al abilite la rimozion dai parametris di interogazion di segnadure. Viôt che "
"cuant che si cambie cheste impostazion dal dialic des preferencis, la "
"impostazion dai filtris di adblock e sarà ancje inzornade par zontâ/gjavâ i "
"filtris EasyPrivacy."
#: data/org.gnome.epiphany.gschema.xml:184
msgid "Enable adblock"
......@@ -2794,7 +2794,7 @@ msgstr "Ingrandî"
#: src/resources/gtk/page-menu-popover.ui:80
msgid "Print…"
msgstr "Stampe..."
msgstr "Stampe"
#: src/resources/gtk/page-menu-popover.ui:95
msgid "Find…"
......
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.
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.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
......@@ -44,6 +44,8 @@ struct _EphyActionBarEnd {
G_DEFINE_TYPE (EphyActionBarEnd, ephy_action_bar_end, GTK_TYPE_BOX)
static void begin_complete_theatrics (EphyActionBarEnd *self);
static void
remove_downloads_button_attention_style (EphyActionBarEnd *self)
{
......@@ -123,11 +125,71 @@ download_added_cb (EphyDownloadsManager *manager,
}
}
static gboolean
begin_complete_theatrics_from_main (gpointer user_data)
{
EphyActionBarEnd *self = user_data;
GtkAllocation rect;
gtk_widget_get_allocation (GTK_WIDGET (self->downloads_button), &rect);
if (rect.x != -1 && rect.y != -1)
begin_complete_theatrics (self);
return G_SOURCE_REMOVE;
}
static void
begin_complete_theatrics (EphyActionBarEnd *self)
{
g_autoptr(GIcon) icon = NULL;
DzlBoxTheatric *theatric;
GtkAllocation rect;
gtk_widget_get_allocation (GTK_WIDGET (self->downloads_button), &rect);
if (rect.x == -1 && rect.y == -1) {
/* Delay this until our widget has been mapped/realized/displayed */
g_idle_add_full (G_PRIORITY_LOW,
begin_complete_theatrics_from_main,
g_object_ref (self), g_object_unref);