/* -*- Mode: C; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ /* * Copyright © 2000, 2001, 2002, 2003, 2004 Marco Pesenti Gritti * Copyright © 2003, 2004, 2005 Christian Persch * Copyright © 2010, 2012 Igalia S.L. * * This file is part of Epiphany. * * 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. * * 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 General Public License * along with Epiphany. If not, see . */ #include "config.h" #include "ephy-lockdown.h" #include "ephy-action-helper.h" #include "ephy-debug.h" #include "ephy-embed-container.h" #include "ephy-embed-shell.h" #include "ephy-embed-utils.h" #include "ephy-location-controller.h" #include "ephy-prefs.h" #include "ephy-settings.h" #include "ephy-shell.h" #include "ephy-window.h" #include #define LOCKDOWN_FLAG 1 << 8 struct _EphyLockdown { GObject parent_instance; }; G_DEFINE_TYPE (EphyLockdown, ephy_lockdown, G_TYPE_OBJECT) static void arbitrary_url_cb (GSettings *settings, const char *key, EphyWindow *window) { EphyEmbed *embed; const char *address; /* Restore the real web page address when disabling entry */ if (g_settings_get_boolean (settings, key)) { embed = ephy_embed_container_get_active_child (EPHY_EMBED_CONTAINER (window)); /* embed is NULL on startup */ if (embed == NULL) return; address = ephy_web_view_get_display_address (ephy_embed_get_web_view (embed)); ephy_window_set_location (window, address); ephy_web_view_set_typed_address (ephy_embed_get_web_view (embed), NULL); } } static void fullscreen_cb (GSettings *settings, const char *key, EphyWindow *window) { if (g_settings_get_boolean (settings, key)) gtk_window_fullscreen (GTK_WINDOW (window)); else gtk_window_unfullscreen (GTK_WINDOW (window)); } typedef struct { const char *key; const char *action; const char *prop; } BindAction; static const BindAction app_actions[] = { { EPHY_PREFS_LOCKDOWN_FULLSCREEN, "new-window", "enabled" }, { EPHY_PREFS_LOCKDOWN_FULLSCREEN, "new-incognito", "enabled" }, }; static const BindAction app_mode_app_actions[] = { { EPHY_PREFS_LOCKDOWN_HISTORY, "history", "enabled" } }; static const BindAction window_actions[] = { { EPHY_PREFS_LOCKDOWN_ARBITRARY_URL, "location", "enabled"}, { EPHY_PREFS_LOCKDOWN_BOOKMARK_EDITING, "bookmark-page", "enabled" }, { EPHY_PREFS_LOCKDOWN_FULLSCREEN, "fullscreen", "enabled" }, { EPHY_PREFS_LOCKDOWN_PRINTING, "print", "enabled" }, { EPHY_PREFS_LOCKDOWN_SAVE_TO_DISK, "save-as", "enabled" } }; static const BindAction popup_actions[] = { { EPHY_PREFS_LOCKDOWN_SAVE_TO_DISK, "download-link-as", "enabled" }, { EPHY_PREFS_LOCKDOWN_SAVE_TO_DISK, "save-image-as", "enabled" }, { EPHY_PREFS_LOCKDOWN_BOOKMARK_EDITING, "context-bookmark-page", "enabled" }, { EPHY_PREFS_LOCKDOWN_FULLSCREEN, "open-link-in-new-window", "enabled" } }; static const BindAction tab_actions[] = { { EPHY_PREFS_LOCKDOWN_FULLSCREEN, "detach", "enabled" } }; static const BindAction toolbar_actions[] = { { EPHY_PREFS_LOCKDOWN_HISTORY, "navigation-back", "enabled" }, { EPHY_PREFS_LOCKDOWN_HISTORY, "navigation-forward", "enabled" } }; static gboolean sensitive_get_mapping (GValue *value, GVariant *variant, gpointer data) { GAction *action; gboolean active, before, after; action = G_ACTION (data); active = g_variant_get_boolean (variant); before = g_action_get_enabled (action); ephy_action_change_sensitivity_flags (G_SIMPLE_ACTION (action), LOCKDOWN_FLAG, active); after = g_action_get_enabled (action); /* Set (GAction::enabled) to the value in GSettings _only if_ * the LOCKDOWN_FLAG had some real effect in the GAction */ g_value_set_boolean (value, (before != after) ? after : before); return TRUE; } static void bind_settings_and_actions (GSettings *settings, GActionGroup *action_group, const BindAction *actions, int actions_n) { int i; for (i = 0; i < actions_n; i++) { GAction *action; action = g_action_map_lookup_action (G_ACTION_MAP (action_group), actions[i].action); g_assert (action); /* We need a custom get_mapping for 'enabled' * properties, see usage of * ephy_action_change_sensitivity_flags in * ephy-window.c. */ g_settings_bind_with_mapping (settings, actions[i].key, action, actions[i].prop, G_SETTINGS_BIND_GET, sensitive_get_mapping, NULL, action, NULL); } } static void bind_location_controller (GSettings *settings, EphyLocationController *controller) { g_settings_bind (settings, EPHY_PREFS_LOCKDOWN_ARBITRARY_URL, controller, "editable", G_SETTINGS_BIND_GET | G_SETTINGS_BIND_INVERT_BOOLEAN); } static void window_added_cb (GtkApplication *application, GtkWindow *window, EphyLockdown *lockdown) { GActionGroup *action_group; EphyEmbedShellMode mode; GAction *action; GSettings *settings; EphyLocationController *location_controller; if (!EPHY_IS_WINDOW (window)) return; g_signal_connect (EPHY_SETTINGS_LOCKDOWN, "changed::" EPHY_PREFS_LOCKDOWN_FULLSCREEN, G_CALLBACK (fullscreen_cb), window); g_signal_connect (EPHY_SETTINGS_LOCKDOWN, "changed::" EPHY_PREFS_LOCKDOWN_ARBITRARY_URL, G_CALLBACK (arbitrary_url_cb), window); /* Trigger an initial state on these elements. */ fullscreen_cb (EPHY_SETTINGS_LOCKDOWN, EPHY_PREFS_LOCKDOWN_FULLSCREEN, EPHY_WINDOW (window)); arbitrary_url_cb (EPHY_SETTINGS_LOCKDOWN, EPHY_PREFS_LOCKDOWN_ARBITRARY_URL, EPHY_WINDOW (window)); mode = ephy_embed_shell_get_mode (EPHY_EMBED_SHELL (application)); action_group = G_ACTION_GROUP (G_APPLICATION (application)); if (mode != EPHY_EMBED_SHELL_MODE_APPLICATION) { /* These actions do not exist in application mode. */ bind_settings_and_actions (EPHY_SETTINGS_LOCKDOWN, action_group, app_actions, G_N_ELEMENTS (app_actions)); } bind_settings_and_actions (EPHY_SETTINGS_LOCKDOWN, action_group, app_mode_app_actions, G_N_ELEMENTS (app_mode_app_actions)); action_group = gtk_widget_get_action_group (GTK_WIDGET (window), "win"); bind_settings_and_actions (EPHY_SETTINGS_LOCKDOWN, action_group, window_actions, G_N_ELEMENTS (window_actions)); action_group = gtk_widget_get_action_group (GTK_WIDGET (window), "tab"); bind_settings_and_actions (EPHY_SETTINGS_LOCKDOWN, action_group, tab_actions, G_N_ELEMENTS (tab_actions)); action_group = gtk_widget_get_action_group (GTK_WIDGET (window), "toolbar"); bind_settings_and_actions (EPHY_SETTINGS_LOCKDOWN, action_group, toolbar_actions, G_N_ELEMENTS (toolbar_actions)); action_group = gtk_widget_get_action_group (GTK_WIDGET (window), "popup"); bind_settings_and_actions (EPHY_SETTINGS_LOCKDOWN, action_group, popup_actions, G_N_ELEMENTS (popup_actions)); action = g_action_map_lookup_action (G_ACTION_MAP (action_group), "set-image-as-background"); settings = ephy_settings_get ("org.gnome.desktop.background"); g_settings_bind_writable (settings, "picture-filename", action, "enabled", FALSE); 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); } } static void ephy_lockdown_init (EphyLockdown *lockdown) { EphyShell *shell; LOG ("EphyLockdown initialising"); shell = ephy_shell_get_default (); g_signal_connect (shell, "window-added", G_CALLBACK (window_added_cb), lockdown); } static void ephy_lockdown_class_init (EphyLockdownClass *klass) { }