Commit 28a84367 authored by Carlos Garcia Campos's avatar Carlos Garcia Campos Committed by Carlos Garcia Campos

Add automation mode

parent d8767ea1
Pipeline #49039 passed with stage
in 8 minutes and 21 seconds
......@@ -37,6 +37,9 @@ Start a private instance (temporary profile directory, not private browsing mode
\fB\-\-incognito\-mode\fR
Start a private instance in incognito mode
.TP
\fB\-\-automation\-mode\fR
Start the browser in automation mode, for WebDriver control
.TP
\fB\-\-profile\fR=\fIFILE\fR
Profile directory to use in the private instance
.TP
......
......@@ -165,3 +165,22 @@ ephy_embed_container_get_is_popup (EphyEmbedContainer *container)
iface = EPHY_EMBED_CONTAINER_GET_IFACE (container);
return iface->get_is_popup (container);
}
/**
* ephy_embed_container_get_n_children:
* @container: a #EphyEmbedContainer
*
* Returns the number of #EphyEmbed:s in the container.
*
* Returns: the number of children
*/
guint
ephy_embed_container_get_n_children (EphyEmbedContainer *container)
{
EphyEmbedContainerInterface *iface;
g_assert (EPHY_IS_EMBED_CONTAINER (container));
iface = EPHY_EMBED_CONTAINER_GET_IFACE (container);
return iface->get_n_children (container);
}
......@@ -52,6 +52,8 @@ struct _EphyEmbedContainerInterface
GList * (* get_children) (EphyEmbedContainer *container);
gboolean (* get_is_popup) (EphyEmbedContainer *container);
guint (* get_n_children) (EphyEmbedContainer *container);
};
gint ephy_embed_container_add_child (EphyEmbedContainer *container,
......@@ -65,5 +67,6 @@ void ephy_embed_container_remove_child (EphyEmbedContainer *con
EphyEmbed * ephy_embed_container_get_active_child (EphyEmbedContainer *container);
GList * ephy_embed_container_get_children (EphyEmbedContainer *container);
gboolean ephy_embed_container_get_is_popup (EphyEmbedContainer *container);
guint ephy_embed_container_get_n_children (EphyEmbedContainer *container);
G_END_DECLS
......@@ -756,6 +756,7 @@ ephy_embed_shell_get_global_history_service (EphyEmbedShell *shell)
EphySQLiteConnectionMode mode;
if (priv->mode == EPHY_EMBED_SHELL_MODE_INCOGNITO ||
priv->mode == EPHY_EMBED_SHELL_MODE_AUTOMATION ||
priv->mode == EPHY_EMBED_SHELL_MODE_SEARCH_PROVIDER)
mode = EPHY_SQLITE_CONNECTION_MODE_READ_ONLY;
else
......@@ -958,7 +959,7 @@ initialize_web_extensions (WebKitWebContext *web_context,
address = priv->dbus_server ? g_dbus_server_get_client_address (priv->dbus_server) : NULL;
private_profile = priv->mode == EPHY_EMBED_SHELL_MODE_PRIVATE || priv->mode == EPHY_EMBED_SHELL_MODE_INCOGNITO;
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)",
priv->guid,
......@@ -1101,6 +1102,12 @@ ephy_embed_shell_create_web_context (EphyEmbedShell *shell)
return;
}
if (priv->mode == EPHY_EMBED_SHELL_MODE_AUTOMATION) {
priv->web_context = webkit_web_context_new_ephemeral ();
webkit_web_context_set_automation_allowed (priv->web_context, TRUE);
return;
}
data_dir = g_build_filename (priv->mode == EPHY_EMBED_SHELL_MODE_PRIVATE ?
ephy_dot_dir () : g_get_user_data_dir (),
g_get_prgname (), NULL);
......@@ -1258,17 +1265,21 @@ ephy_embed_shell_startup (GApplication *application)
priv->password_manager = ephy_password_manager_new ();
/* Favicon Database */
if (priv->mode == EPHY_EMBED_SHELL_MODE_PRIVATE)
favicon_db_path = g_build_filename (ephy_dot_dir (), "icondatabase", NULL);
else
favicon_db_path = g_build_filename (g_get_user_cache_dir (), "epiphany", "icondatabase", NULL);
webkit_web_context_set_favicon_database_directory (priv->web_context, favicon_db_path);
g_free (favicon_db_path);
/* Do not ignore TLS errors. */
webkit_web_context_set_tls_errors_policy (priv->web_context, WEBKIT_TLS_ERRORS_POLICY_FAIL);
/* Do not cache favicons in automation mode. Don't change the TLS policy either, since that's
* handled by session capabilities in automation mode.
*/
if (priv->mode != EPHY_EMBED_SHELL_MODE_AUTOMATION) {
/* Favicon Database */
if (priv->mode == EPHY_EMBED_SHELL_MODE_PRIVATE)
favicon_db_path = g_build_filename (ephy_dot_dir (), "icondatabase", NULL);
else
favicon_db_path = g_build_filename (g_get_user_cache_dir (), "epiphany", "icondatabase", NULL);
webkit_web_context_set_favicon_database_directory (priv->web_context, favicon_db_path);
g_free (favicon_db_path);
/* Do not ignore TLS errors. */
webkit_web_context_set_tls_errors_policy (priv->web_context, WEBKIT_TLS_ERRORS_POLICY_FAIL);
}
/* about: URIs handler */
priv->about_handler = ephy_about_handler_new ();
......@@ -1299,7 +1310,7 @@ ephy_embed_shell_startup (GApplication *application)
/* Store cookies in moz-compatible SQLite format */
cookie_manager = webkit_web_context_get_cookie_manager (priv->web_context);
if (priv->mode != EPHY_EMBED_SHELL_MODE_INCOGNITO) {
if (!webkit_web_context_is_ephemeral (priv->web_context)) {
filename = g_build_filename (ephy_dot_dir (), "cookies.sqlite", NULL);
webkit_cookie_manager_set_persistent_storage (cookie_manager, filename,
WEBKIT_COOKIE_PERSISTENT_STORAGE_SQLITE);
......
......@@ -46,7 +46,8 @@ typedef enum
EPHY_EMBED_SHELL_MODE_INCOGNITO,
EPHY_EMBED_SHELL_MODE_APPLICATION,
EPHY_EMBED_SHELL_MODE_TEST,
EPHY_EMBED_SHELL_MODE_SEARCH_PROVIDER
EPHY_EMBED_SHELL_MODE_SEARCH_PROVIDER,
EPHY_EMBED_SHELL_MODE_AUTOMATION
} EphyEmbedShellMode;
struct _EphyEmbedShellClass
......
......@@ -808,6 +808,20 @@ ephy_embed_constructed (GObject *object)
g_signal_connect (inspector, "closed",
G_CALLBACK (ephy_embed_close_inspector_cb),
embed);
if (webkit_web_view_is_controlled_by_automation (embed->web_view)) {
GtkWidget *info_bar;
GtkWidget *label;
info_bar = gtk_info_bar_new ();
gtk_info_bar_set_message_type (GTK_INFO_BAR (info_bar), GTK_MESSAGE_INFO);
label = gtk_label_new (_("Web is being controlled by automation"));
  • This string could use a translator comment explaining that it’s the browser that is controlled by robots, not the Web as a whole (as much as it’s actually true in reality 😃).

    @mcatanzaro

    Edited by Piotr Drąg
  • Added!

Please register or sign in to reply
gtk_box_pack_start (GTK_BOX (gtk_info_bar_get_content_area (GTK_INFO_BAR (info_bar))), label, FALSE, FALSE, 0);
gtk_widget_show (label);
ephy_embed_add_top_widget (embed, info_bar, EPHY_EMBED_TOP_WIDGET_POLICY_RETAIN_ON_TRANSITION);
gtk_widget_show (info_bar);
}
}
static void
......
......@@ -2900,6 +2900,7 @@ ephy_web_view_new (void)
"web-context", ephy_embed_shell_get_web_context (shell),
"user-content-manager", ephy_embed_shell_get_user_content_manager (shell),
"settings", ephy_embed_prefs_get_settings (),
"is-controlled-by-automation", ephy_embed_shell_get_mode (shell) == EPHY_EMBED_SHELL_MODE_AUTOMATION,
NULL);
}
......@@ -3687,7 +3688,8 @@ ephy_web_view_load_homepage (EphyWebView *view)
shell = ephy_embed_shell_get_default ();
mode = ephy_embed_shell_get_mode (shell);
if (mode == EPHY_EMBED_SHELL_MODE_INCOGNITO) {
if (mode == EPHY_EMBED_SHELL_MODE_INCOGNITO ||
mode == EPHY_EMBED_SHELL_MODE_AUTOMATION) {
ephy_web_view_load_new_tab_page (view);
return;
}
......@@ -3718,6 +3720,8 @@ ephy_web_view_load_new_tab_page (EphyWebView *view)
ephy_web_view_set_visit_type (view, EPHY_PAGE_VISIT_HOMEPAGE);
if (mode == EPHY_EMBED_SHELL_MODE_INCOGNITO)
ephy_web_view_load_url (view, "about:incognito");
else if (mode == EPHY_EMBED_SHELL_MODE_AUTOMATION)
ephy_web_view_load_url (view, "about:blank");
else
ephy_web_view_load_url (view, "about:overview");
}
......
......@@ -49,6 +49,11 @@ conf.set10('TECH_PREVIEW', tech_preview)
conf.set_quoted('VERSION', meson.project_version())
version_array = meson.project_version().split('.')
conf.set('EPHY_MAJOR_VERSION', version_array[0].to_int())
conf.set('EPHY_MINOR_VERSION', version_array[1].to_int())
conf.set('EPHY_MICRO_VERSION', version_array[2].to_int())
configure_file(
output: 'config.h',
configuration: conf
......
......@@ -252,7 +252,8 @@ window_added_cb (GtkApplication *application,
g_settings_bind_writable (settings, "picture-filename",
action, "enabled", FALSE);
if (mode != EPHY_EMBED_SHELL_MODE_APPLICATION) {
if (mode != EPHY_EMBED_SHELL_MODE_APPLICATION &&
mode != EPHY_EMBED_SHELL_MODE_AUTOMATION) {
location_controller = ephy_window_get_location_controller (EPHY_WINDOW (window));
bind_location_controller (EPHY_SETTINGS_LOCKDOWN, location_controller);
}
......
......@@ -57,6 +57,7 @@ static char *application_to_delete = NULL;
static gboolean private_instance = FALSE;
static gboolean incognito_mode = FALSE;
static gboolean application_mode = FALSE;
static gboolean automation_mode = FALSE;
static char *desktop_file_basename = NULL;
static char *profile_directory = NULL;
......@@ -128,6 +129,8 @@ static const GOptionEntry option_entries[] =
{ "application-mode", 'a', G_OPTION_FLAG_FILENAME | G_OPTION_FLAG_OPTIONAL_ARG,
G_OPTION_ARG_CALLBACK, application_mode_cb,
N_("Start the browser in application mode"), NULL },
{ "automation-mode", 0, 0, G_OPTION_ARG_NONE, &automation_mode,
N_("Start an instance in automation mode"), NULL },
{ "profile", 0, 0, G_OPTION_ARG_STRING, &profile_directory,
N_("Profile directory to use in the private instance"), N_("DIR") },
{ G_OPTION_REMAINING, '\0', 0, G_OPTION_ARG_FILENAME_ARRAY, &arguments,
......@@ -306,6 +309,11 @@ main (int argc,
exit (1);
}
if (automation_mode && (private_instance || incognito_mode || application_mode || profile_directory)) {
g_print ("Cannot use --automation-mode and --private-instance, --incognito-mode, --application-mode, or --profile at the same time\n");
exit (1);
}
if (application_mode && profile_directory && !g_file_test (profile_directory, G_FILE_TEST_IS_DIR)) {
g_print ("--profile must be an existing directory when --application-mode is requested\n");
exit (1);
......@@ -336,7 +344,7 @@ main (int argc,
/* Start our services */
flags = !application_mode ? EPHY_FILE_HELPERS_ENSURE_EXISTS : 0;
if (incognito_mode || private_instance || application_mode)
if (incognito_mode || private_instance || application_mode || automation_mode)
flags |= EPHY_FILE_HELPERS_PRIVATE_PROFILE;
if (incognito_mode)
flags |= EPHY_FILE_HELPERS_STEAL_DATA;
......@@ -349,8 +357,8 @@ main (int argc,
/* Run the migration in all cases, except when running a private
instance without a given profile directory or running in
incognito mode. */
if (!(private_instance && profile_directory == NULL) && incognito_mode == FALSE) {
incognito or automation mode. */
if (!(private_instance && profile_directory == NULL) && !incognito_mode && !automation_mode) {
/* If the migration fails we don't really want to continue. */
if (!ephy_profile_utils_do_migration ((const char *)profile_directory, -1, FALSE)) {
g_print ("Failed to run the migrator process, Web will now abort.\n");
......@@ -358,6 +366,10 @@ main (int argc,
}
}
/* Ignore arguments in automation mode */
if (automation_mode)
g_clear_pointer (&arguments, g_strfreev);
arbitrary_url = g_settings_get_boolean (EPHY_SETTINGS_LOCKDOWN,
EPHY_PREFS_LOCKDOWN_ARBITRARY_URL);
......@@ -397,6 +409,8 @@ main (int argc,
startup_flags |= EPHY_STARTUP_NEW_TAB;
} else if (incognito_mode) {
mode = EPHY_EMBED_SHELL_MODE_INCOGNITO;
} else if (automation_mode) {
mode = EPHY_EMBED_SHELL_MODE_AUTOMATION;
} else if (application_mode) {
mode = EPHY_EMBED_SHELL_MODE_APPLICATION;
......
......@@ -372,7 +372,8 @@ ephy_shell_startup (GApplication *application)
app_entries, G_N_ELEMENTS (app_entries),
application);
if (mode != EPHY_EMBED_SHELL_MODE_INCOGNITO) {
if (mode != EPHY_EMBED_SHELL_MODE_INCOGNITO &&
mode != EPHY_EMBED_SHELL_MODE_AUTOMATION) {
g_action_map_add_action_entries (G_ACTION_MAP (application),
non_incognito_extra_app_entries, G_N_ELEMENTS (non_incognito_extra_app_entries),
application);
......@@ -409,6 +410,41 @@ ephy_shell_startup (GApplication *application)
set_accel_for_action (shell, "app.quit", "<Primary>q");
}
static GtkWidget *
create_web_view_for_automation_cb (WebKitAutomationSession *session,
EphyShell *shell)
{
EphyEmbed *embed;
EphyWindow *window;
EphyWebView *web_view;
guint n_embeds;
window = EPHY_WINDOW (gtk_application_get_active_window (GTK_APPLICATION (shell)));
embed = ephy_embed_container_get_active_child (EPHY_EMBED_CONTAINER (window));
n_embeds = ephy_embed_container_get_n_children (EPHY_EMBED_CONTAINER (window));
web_view = ephy_embed_get_web_view (embed);
if (n_embeds == 1 && ephy_web_view_get_visit_type (web_view) == EPHY_PAGE_VISIT_HOMEPAGE)
return GTK_WIDGET (web_view);
embed = ephy_shell_new_tab (shell, window, NULL, EPHY_NEW_TAB_JUMP);
return GTK_WIDGET (ephy_embed_get_web_view (embed));
}
static void
automation_started_cb (WebKitWebContext *web_context,
WebKitAutomationSession *session,
EphyShell *shell)
{
WebKitApplicationInfo *info = webkit_application_info_new ();
webkit_application_info_set_name (info, "Epiphany");
webkit_application_info_set_version (info, EPHY_MAJOR_VERSION, EPHY_MINOR_VERSION, EPHY_MICRO_VERSION);
webkit_automation_session_set_application_info (session, info);
webkit_application_info_unref (info);
g_signal_connect (session, "create-web-view", G_CALLBACK (create_web_view_for_automation_cb), shell);
}
static void
session_load_cb (GObject *object,
GAsyncResult *result,
......@@ -425,6 +461,12 @@ static void
ephy_shell_activate (GApplication *application)
{
EphyShell *shell = EPHY_SHELL (application);
EphyEmbedShell *embed_shell = EPHY_EMBED_SHELL (shell);
if (ephy_embed_shell_get_mode (embed_shell) == EPHY_EMBED_SHELL_MODE_AUTOMATION) {
WebKitWebContext *web_context = ephy_embed_shell_get_web_context (embed_shell);
g_signal_connect (web_context, "automation-started", G_CALLBACK (automation_started_cb), shell);
}
if (shell->remote_startup_context == NULL) {
EphySession *session = ephy_shell_get_session (shell);
......@@ -819,7 +861,7 @@ ephy_shell_get_session (EphyShell *shell)
g_assert (EPHY_IS_SHELL (shell));
mode = ephy_embed_shell_get_mode (EPHY_EMBED_SHELL (shell));
if (mode == EPHY_EMBED_SHELL_MODE_APPLICATION || mode == EPHY_EMBED_SHELL_MODE_INCOGNITO)
if (mode == EPHY_EMBED_SHELL_MODE_APPLICATION || mode == EPHY_EMBED_SHELL_MODE_INCOGNITO || mode == EPHY_EMBED_SHELL_MODE_AUTOMATION)
return NULL;
if (shell->session == NULL)
......
......@@ -312,6 +312,14 @@ impl_get_is_popup (EphyEmbedContainer *container)
return EPHY_WINDOW (container)->is_popup;
}
static guint
impl_get_n_children (EphyEmbedContainer *container)
{
EphyWindow *window = EPHY_WINDOW (container);
return gtk_notebook_get_n_pages (window->notebook);
}
static void
ephy_window_embed_container_iface_init (EphyEmbedContainerInterface *iface)
{
......@@ -321,6 +329,7 @@ ephy_window_embed_container_iface_init (EphyEmbedContainerInterface *iface)
iface->get_active_child = impl_get_active_child;
iface->get_children = impl_get_children;
iface->get_is_popup = impl_get_is_popup;
iface->get_n_children = impl_get_n_children;
}
static EphyEmbed *
......@@ -1159,6 +1168,7 @@ sync_tab_bookmarked_status (EphyWebView *view,
{
EphyBookmarksManager *manager = ephy_shell_get_bookmarks_manager (ephy_shell_get_default ());
EphyEmbedShell *shell = ephy_embed_shell_get_default ();
EphyEmbedShellMode mode;
EphyLocationEntryBookmarkIconState state;
GtkWidget *widget;
EphyBookmark *bookmark;
......@@ -1170,10 +1180,12 @@ sync_tab_bookmarked_status (EphyWebView *view,
return;
address = ephy_web_view_get_address (view);
mode = ephy_embed_shell_get_mode (shell);
if (!address ||
ephy_embed_utils_is_no_show_address (address) ||
ephy_embed_shell_get_mode (shell) == EPHY_EMBED_SHELL_MODE_INCOGNITO) {
mode == EPHY_EMBED_SHELL_MODE_INCOGNITO ||
mode == EPHY_EMBED_SHELL_MODE_AUTOMATION) {
state = EPHY_LOCATION_ENTRY_BOOKMARK_ICON_HIDDEN;
} else {
bookmark = ephy_bookmarks_manager_get_bookmark_by_url (manager, address);
......@@ -2771,6 +2783,11 @@ notebook_page_close_request_cb (EphyNotebook *notebook,
return;
}
if (ephy_embed_shell_get_mode (ephy_embed_shell_get_default ()) == EPHY_EMBED_SHELL_MODE_AUTOMATION) {
/* Never prompt the user before closing in automation mode */
ephy_window_close_tab (window, embed);
}
/* Last window, check ongoing downloads before closing the tab */
if (ephy_shell_get_n_windows (ephy_shell_get_default ()) == 1) {
EphyDownloadsManager *manager = ephy_embed_shell_get_downloads_manager (EPHY_EMBED_SHELL (ephy_shell_get_default ()));
......@@ -3377,6 +3394,8 @@ ephy_window_constructed (GObject *object)
mode = ephy_embed_shell_get_mode (ephy_embed_shell_get_default ());
if (mode == EPHY_EMBED_SHELL_MODE_INCOGNITO)
gtk_style_context_add_class (gtk_widget_get_style_context (GTK_WIDGET (window)), "incognito-mode");
else if (mode == EPHY_EMBED_SHELL_MODE_AUTOMATION)
gtk_style_context_add_class (gtk_widget_get_style_context (GTK_WIDGET (window)), "automation-mode");
/* Setup the toolbar. */
window->header_bar = setup_header_bar (window);
......@@ -3448,6 +3467,8 @@ ephy_window_constructed (GObject *object)
action = g_action_map_lookup_action (G_ACTION_MAP (action_group), "context-bookmark-page");
ephy_action_change_sensitivity_flags (G_SIMPLE_ACTION (action),
SENS_FLAG_CHROME, TRUE);
} else if (mode == EPHY_EMBED_SHELL_MODE_AUTOMATION) {
g_object_set (window->location_controller, "editable", FALSE, NULL);
}
window->mouse_gesture_controller = ephy_mouse_gesture_controller_new (window);
......
......@@ -41,6 +41,48 @@
.incognito-mode headerbar entry:backdrop { box-shadow: none; }
.automation-mode headerbar { background: #ff9600 linear-gradient(to top, #bd6f00, #f59000 2px, #ff9600 3px); box-shadow: inset 0 1px #ffb142; border-color: #995a00; color: rgba(46, 52, 54, 0.2); }
.automation-mode headerbar > * { color: #2e3436; }
.automation-mode headerbar > *:backdrop { color: #929595; }
.automation-mode headerbar:backdrop { box-shadow: inset 0 1px #ffb142; color: rgba(146, 149, 149, 0.1); }
.automation-mode headerbar button { color: #2e3436; outline-color: rgba(46, 52, 54, 0.3); border-color: #995a00; border-bottom-color: #663c00; background-image: linear-gradient(to bottom, #ff9600, #eb8a00 95%, #db8100 1px); text-shadow: 0 1px rgba(255, 255, 255, 0.769231); -gtk-icon-shadow: 0 1px rgba(255, 255, 255, 0.769231); box-shadow: inset 0 1px rgba(255, 255, 255, 0.2); }
.automation-mode headerbar button.flat, .automation-mode headerbar button.titlebutton { border-color: transparent; background-color: transparent; background-image: none; box-shadow: inset 0 1px rgba(255, 255, 255, 0); text-shadow: none; -gtk-icon-shadow: none; }
.automation-mode headerbar button.titlebutton { text-shadow: 0 1px rgba(255, 255, 255, 0.769231); -gtk-icon-shadow: 0 1px rgba(255, 255, 255, 0.769231); }
.automation-mode headerbar button:hover { color: #2e3436; outline-color: rgba(46, 52, 54, 0.3); border-color: #995a00; border-bottom-color: #663c00; text-shadow: 0 1px rgba(255, 255, 255, 0.769231); -gtk-icon-shadow: 0 1px rgba(255, 255, 255, 0.769231); box-shadow: inset 0 1px rgba(255, 255, 255, 0.4); background-image: linear-gradient(to bottom, #ffa31f, #ff9600 95%, #db8100 1px); }
.automation-mode headerbar button:active, .automation-mode headerbar button:checked { color: #2e3436; outline-color: rgba(46, 52, 54, 0.3); border-color: #995a00; background-image: image(#e08400); box-shadow: inset 0 1px rgba(255, 255, 255, 0); text-shadow: none; -gtk-icon-shadow: none; }
.automation-mode headerbar button:disabled { border-color: #995a00; background-image: image(#ffa626); text-shadow: none; -gtk-icon-shadow: none; box-shadow: inset 0 1px rgba(255, 255, 255, 0); }
.automation-mode headerbar button:disabled label, .automation-mode headerbar button:disabled { color: #929595; }
.automation-mode headerbar button:backdrop { border-color: #ff9600; background-image: image(#ff9600); text-shadow: none; -gtk-icon-shadow: none; box-shadow: inset 0 1px rgba(255, 255, 255, 0); border-color: #995a00; }
.automation-mode headerbar button:backdrop label, .automation-mode headerbar button:backdrop { color: #929595; }
.automation-mode headerbar button:backdrop:active { border-color: #fc9500; background-image: image(#fc9500); box-shadow: inset 0 1px rgba(255, 255, 255, 0); border-color: #995a00; }
.automation-mode headerbar button:backdrop:active label, .automation-mode headerbar button:backdrop:active { color: #929595; }
.automation-mode headerbar button:backdrop:disabled { border-color: #ffa626; background-image: image(#ffa626); text-shadow: none; -gtk-icon-shadow: none; box-shadow: inset 0 1px rgba(255, 255, 255, 0); border-color: #995a00; }
.automation-mode headerbar button:backdrop:disabled label, .automation-mode headerbar button:backdrop:disabled { color: #b67e2c; }
.automation-mode headerbar button.flat:backdrop, .automation-mode headerbar button.titlebutton:backdrop { border-color: transparent; background-color: transparent; background-image: none; box-shadow: inset 0 1px rgba(255, 255, 255, 0); text-shadow: none; -gtk-icon-shadow: none; }
.automation-mode headerbar entry { border-color: #995a00; }
.automation-mode headerbar entry:focus { border-color: #3584e4; box-shadow: inset 0 0 0 1px #3584e4; }
.automation-mode headerbar entry:backdrop { box-shadow: none; }
.bookmark-tag-widget { background-color: #cfcfcd; }
.bookmark-tag-widget image, .bookmark-tag-widget label { color: #2e3436; }
......
......@@ -6,7 +6,7 @@
.incognito-mode {
headerbar {
@include headerbar_fill($incognito_color, $edge_color, -gtk-icontheme($incognito_icon) 160px 0 / 64px 64px no-repeat);
@include headerbar_fill($incognito_color, $incognito_edge_color, -gtk-icontheme($incognito_icon) 160px 0 / 64px 64px no-repeat);
border-color: _border_color($incognito_color);
......@@ -20,7 +20,7 @@
&:backdrop {
background-image: -gtk-icontheme($incognito_icon), image($incognito_color);
box-shadow: inset 0 1px $edge_color;
box-shadow: inset 0 1px $incognito_edge_color;
color: transparentize($backdrop_fg_color, 0.9); // color of the overlayed icon in backdrop
}
......@@ -68,6 +68,68 @@
}
}
.automation-mode {
headerbar {
@include headerbar_fill($automation_color, $automation_edge_color);
border-color: _border_color($automation_color);
color: transparentize($fg_color, 0.8); // this is the color of the overlayed icon
> * {
color: $fg_color;
&:backdrop { color: $backdrop_fg_color }
}
&:backdrop {
box-shadow: inset 0 1px $automation_edge_color;
color: transparentize($backdrop_fg_color, 0.9); // color of the overlayed icon in backdrop
}
button { // changing the headerbar background color requires changing widget borders accordingly
@include button(normal, $automation_color);
&.flat, &.titlebutton { @include button(undecorated); }
&.titlebutton { @include _button_text_shadow($fg_color, $automation_color); }
&:hover { @include button(hover, $automation_color); }
&:active, &:checked { @include button(active, $automation_color); }
&:disabled { @include button(insensitive, $automation_color); }
&:backdrop {
@include button(backdrop, $automation_color);
border-color: _border_color($automation_color);
&:active {
@include button(backdrop-active, $automation_color);
border-color: _border_color($automation_color);
}
&:disabled {
@include button(backdrop-insensitive, $automation_color);
border-color: _border_color($automation_color);
}
}
&.flat:backdrop, &.titlebutton:backdrop { @include button(undecorated); }
}
entry {
border-color: _border_color($automation_color);
&:focus {
border-color: entry_focus_border($selected_bg_color);
box-shadow: entry_focus_shadow($selected_bg_color);
}
&:backdrop { box-shadow: none; }
}
}
}
$close_button_fg_color: lighten($fg_color, 10%);
.bookmark-tag-widget {
......
......@@ -3,8 +3,11 @@
//$incognito_color: #c5cfd8;
$incognito_color: #cbd2d9;
$incognito_icon: 'user-not-tracked-symbolic';
$edge_color: lighten($incognito_color, 13%);
$incognito_edge_color: lighten($incognito_color, 13%);
// automation mode
$automation_color: #ff9600;
$automation_edge_color: lighten($automation_color, 13%);
// utility function/macros and imports from the base GTK+ theme.
......
......@@ -8,6 +8,8 @@
.incognito-mode headerbar { background-image: -gtk-icontheme("user-not-tracked-symbolic"); background-repeat: no-repeat; background-position: 157px 0; background-size: 64px 64px; color: rgba(0, 0, 0, 0.35); }
.automation-mode headerbar { background-color: #ff9600; color: rgba(0, 0, 0, 0.35); }
.entry_icon { color: mix(@theme_fg_color, @theme_base_color, 0.2); }
.entry_icon:hover { color: @theme_fg_color; }
......
......@@ -35,6 +35,14 @@
}
}
// automation mode
.automation-mode {
headerbar {
background-color: $automation_color;
color: rgba(0, 0, 0, 0.35);
}
}
// entry icons colors
.entry_icon {
color: #{"mix(" + themecolor(theme_fg_color) + ", " + themecolor(theme_base_color) + ", 0.2)"};
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment