diff options
Diffstat (limited to '')
-rw-r--r-- | panels/lock/cc-lock-panel.c | 336 | ||||
-rw-r--r-- | panels/lock/cc-lock-panel.h | 30 | ||||
-rw-r--r-- | panels/lock/cc-lock-panel.ui | 250 | ||||
-rw-r--r-- | panels/lock/gnome-lock-panel.desktop.in.in | 19 | ||||
-rw-r--r-- | panels/lock/lock.gresource.xml | 6 | ||||
-rw-r--r-- | panels/lock/meson.build | 40 |
6 files changed, 681 insertions, 0 deletions
diff --git a/panels/lock/cc-lock-panel.c b/panels/lock/cc-lock-panel.c new file mode 100644 index 0000000..86800e8 --- /dev/null +++ b/panels/lock/cc-lock-panel.c @@ -0,0 +1,336 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- + * + * Copyright (C) 2018 Red Hat, Inc + * Copyright (C) 2020 Collabora Ltd. + * + * This program 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 2 of the License, or + * (at your option) any later version. + * + * This program 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 this program; if not, see <http://www.gnu.org/licenses/>. + * + * Author: Matthias Clasen <mclasen@redhat.com> + */ + +#include "list-box-helper.h" +#include "cc-lock-panel.h" +#include "cc-lock-resources.h" +#include "cc-util.h" + +#include <gio/gdesktopappinfo.h> +#include <glib/gi18n.h> + +struct _CcLockPanel +{ + CcPanel parent_instance; + + GSettings *lock_settings; + GSettings *notification_settings; + GSettings *privacy_settings; + GSettings *session_settings; + + GCancellable *cancellable; + + GtkSwitch *automatic_screen_lock_switch; + GtkComboBox *blank_screen_combo; + GtkComboBox *lock_after_combo; + GtkListBox *lock_list_box; + GtkSwitch *show_notifications_switch; + GtkSwitch *usb_protection_switch; + GDBusProxy *usb_proxy; + GtkListBoxRow *usb_protection_row; +}; + +CC_PANEL_REGISTER (CcLockPanel, cc_lock_panel) + +static void +on_lock_combo_changed_cb (GtkWidget *widget, + CcLockPanel *self) +{ + GtkTreeIter iter; + GtkTreeModel *model; + guint delay; + gboolean ret; + + ret = gtk_combo_box_get_active_iter (GTK_COMBO_BOX (widget), &iter); + if (!ret) + return; + + model = gtk_combo_box_get_model (GTK_COMBO_BOX (widget)); + gtk_tree_model_get (model, &iter, + 1, &delay, + -1); + g_settings_set (self->lock_settings, "lock-delay", "u", delay); +} + +static void +set_lock_value_for_combo (GtkComboBox *combo_box, + CcLockPanel *self) +{ + GtkTreeIter iter; + GtkTreeModel *model; + guint value; + gint value_tmp, value_prev; + gboolean ret; + guint i; + + model = gtk_combo_box_get_model (combo_box); + ret = gtk_tree_model_get_iter_first (model, &iter); + if (!ret) + return; + + value_prev = 0; + i = 0; + + g_settings_get (self->lock_settings, "lock-delay", "u", &value); + do + { + gtk_tree_model_get (model, + &iter, + 1, &value_tmp, + -1); + if (value == value_tmp || + (value_tmp > value_prev && value < value_tmp)) + { + gtk_combo_box_set_active_iter (combo_box, &iter); + return; + } + value_prev = value_tmp; + i++; + } + while (gtk_tree_model_iter_next (model, &iter)); + + gtk_combo_box_set_active (combo_box, i - 1); +} + +static void +set_blank_screen_delay_value (CcLockPanel *self, + gint value) +{ + g_autoptr(GtkTreeIter) insert = NULL; + g_autofree gchar *text = NULL; + GtkTreeIter iter; + GtkTreeIter new; + GtkTreeModel *model; + gint value_tmp; + gint value_last = 0; + gboolean ret; + + /* get entry */ + model = gtk_combo_box_get_model (self->blank_screen_combo); + ret = gtk_tree_model_get_iter_first (model, &iter); + if (!ret) + return; + + /* try to make the UI match the setting */ + do + { + gtk_tree_model_get (model, + &iter, + 1, &value_tmp, + -1); + if (value_tmp == value) + { + gtk_combo_box_set_active_iter (self->blank_screen_combo, &iter); + return; + } + + /* Insert before if the next value is larger or the value is lower + * again (i.e. "Never" is zero and last). */ + if (!insert && (value_tmp > value || value_last > value_tmp)) + insert = gtk_tree_iter_copy (&iter); + + value_last = value_tmp; + } while (gtk_tree_model_iter_next (model, &iter)); + + /* The value is not listed, so add it at the best point (or the end). */ + gtk_list_store_insert_before (GTK_LIST_STORE (model), &new, insert); + + text = cc_util_time_to_string_text (value * 1000); + gtk_list_store_set (GTK_LIST_STORE (model), &new, + 0, text, + 1, value, + -1); + gtk_combo_box_set_active_iter (self->blank_screen_combo, &new); +} + +static void +on_blank_screen_delay_changed_cb (GtkWidget *widget, + CcLockPanel *self) +{ + GtkTreeIter iter; + GtkTreeModel *model; + gint value; + gboolean ret; + + /* no selection */ + ret = gtk_combo_box_get_active_iter (GTK_COMBO_BOX (widget), &iter); + if (!ret) + return; + + /* get entry */ + model = gtk_combo_box_get_model (GTK_COMBO_BOX(widget)); + gtk_tree_model_get (model, &iter, + 1, &value, + -1); + + /* set both keys */ + g_settings_set_uint (self->session_settings, "idle-delay", value); +} + +static void +on_usb_protection_properties_changed_cb (GDBusProxy *usb_proxy, + GVariant *changed_properties, + GStrv invalidated_properties, + CcLockPanel *self) +{ + gboolean available = FALSE; + + if (self->usb_proxy) + { + g_autoptr(GVariant) variant = NULL; + + variant = g_dbus_proxy_get_cached_property (self->usb_proxy, "Available"); + if (variant != NULL) + available = g_variant_get_boolean (variant); + } + + /* Show the USB protection row only if the required daemon is up and running */ + gtk_widget_set_visible (GTK_WIDGET (self->usb_protection_row), available); +} + +static void +on_usb_protection_param_ready (GObject *source_object, + GAsyncResult *res, + gpointer user_data) +{ + g_autoptr(GError) error = NULL; + CcLockPanel *self; + GDBusProxy *proxy; + + self = user_data; + proxy = g_dbus_proxy_new_for_bus_finish (res, &error); + if (error) + { + if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) + { + g_warning ("Failed to connect to SettingsDaemon.UsbProtection: %s", + error->message); + } + + gtk_widget_hide (GTK_WIDGET (self->usb_protection_row)); + return; + } + self->usb_proxy = proxy; + + g_signal_connect_object (self->usb_proxy, + "g-properties-changed", + G_CALLBACK (on_usb_protection_properties_changed_cb), + self, + 0); + on_usb_protection_properties_changed_cb (self->usb_proxy, NULL, NULL, self); +} + +static void +cc_lock_panel_finalize (GObject *object) +{ + CcLockPanel *self = CC_LOCK_PANEL (object); + + g_cancellable_cancel (self->cancellable); + g_clear_object (&self->cancellable); + g_clear_object (&self->lock_settings); + g_clear_object (&self->notification_settings); + g_clear_object (&self->session_settings); + g_clear_object (&self->usb_proxy); + + G_OBJECT_CLASS (cc_lock_panel_parent_class)->finalize (object); +} + +static void +cc_lock_panel_class_init (CcLockPanelClass *klass) +{ + GObjectClass *oclass = G_OBJECT_CLASS (klass); + GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass); + + oclass->finalize = cc_lock_panel_finalize; + + gtk_widget_class_set_template_from_resource (widget_class, "/org/gnome/control-center/lock/cc-lock-panel.ui"); + + gtk_widget_class_bind_template_child (widget_class, CcLockPanel, automatic_screen_lock_switch); + gtk_widget_class_bind_template_child (widget_class, CcLockPanel, blank_screen_combo); + gtk_widget_class_bind_template_child (widget_class, CcLockPanel, lock_after_combo); + gtk_widget_class_bind_template_child (widget_class, CcLockPanel, lock_list_box); + gtk_widget_class_bind_template_child (widget_class, CcLockPanel, show_notifications_switch); + gtk_widget_class_bind_template_child (widget_class, CcLockPanel, usb_protection_switch); + gtk_widget_class_bind_template_child (widget_class, CcLockPanel, usb_protection_row); + + gtk_widget_class_bind_template_callback (widget_class, on_blank_screen_delay_changed_cb); + gtk_widget_class_bind_template_callback (widget_class, on_lock_combo_changed_cb); +} + +static void +cc_lock_panel_init (CcLockPanel *self) +{ + guint value; + + g_resources_register (cc_lock_get_resource ()); + + gtk_widget_init_template (GTK_WIDGET (self)); + + gtk_list_box_set_header_func (self->lock_list_box, + cc_list_box_update_header_func, + NULL, NULL); + + self->cancellable = g_cancellable_new (); + + self->lock_settings = g_settings_new ("org.gnome.desktop.screensaver"); + self->privacy_settings = g_settings_new ("org.gnome.desktop.privacy"); + self->notification_settings = g_settings_new ("org.gnome.desktop.notifications"); + self->session_settings = g_settings_new ("org.gnome.desktop.session"); + + g_settings_bind (self->lock_settings, + "lock-enabled", + self->automatic_screen_lock_switch, + "active", + G_SETTINGS_BIND_DEFAULT); + + g_settings_bind (self->lock_settings, + "lock-enabled", + self->lock_after_combo, + "sensitive", + G_SETTINGS_BIND_GET); + + set_lock_value_for_combo (self->lock_after_combo, self); + + g_settings_bind (self->notification_settings, + "show-in-lock-screen", + self->show_notifications_switch, + "active", + G_SETTINGS_BIND_DEFAULT); + + value = g_settings_get_uint (self->session_settings, "idle-delay"); + set_blank_screen_delay_value (self, value); + + g_settings_bind (self->privacy_settings, + "usb-protection", + self->usb_protection_switch, + "active", + G_SETTINGS_BIND_DEFAULT); + + g_dbus_proxy_new_for_bus (G_BUS_TYPE_SESSION, + G_DBUS_PROXY_FLAGS_NONE, + NULL, + "org.gnome.SettingsDaemon.UsbProtection", + "/org/gnome/SettingsDaemon/UsbProtection", + "org.gnome.SettingsDaemon.UsbProtection", + self->cancellable, + on_usb_protection_param_ready, + self); +} diff --git a/panels/lock/cc-lock-panel.h b/panels/lock/cc-lock-panel.h new file mode 100644 index 0000000..c8db1b9 --- /dev/null +++ b/panels/lock/cc-lock-panel.h @@ -0,0 +1,30 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- + * + * Copyright (C) 2018 Red Hat, Inc + * + * This program 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 2 of the License, or + * (at your option) any later version. + * + * This program 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 this program; if not, see <http://www.gnu.org/licenses/>. + * + * Author: Matthias Clasen <mclasen@redhat.com> + */ + +#pragma once + +#include <shell/cc-panel.h> + +G_BEGIN_DECLS + +#define CC_TYPE_LOCK_PANEL (cc_lock_panel_get_type ()) +G_DECLARE_FINAL_TYPE (CcLockPanel, cc_lock_panel, CC, LOCK_PANEL, CcPanel) + +G_END_DECLS diff --git a/panels/lock/cc-lock-panel.ui b/panels/lock/cc-lock-panel.ui new file mode 100644 index 0000000..f32dde1 --- /dev/null +++ b/panels/lock/cc-lock-panel.ui @@ -0,0 +1,250 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- Generated with glade 3.18.1 --> +<interface> + <template class="CcLockPanel" parent="CcPanel"> + <property name="visible">True</property> + <child> + <object class="GtkScrolledWindow"> + <property name="visible">1</property> + <property name="hscrollbar-policy">never</property> + <child> + <object class="HdyClamp"> + <property name="visible">True</property> + <property name="margin_top">32</property> + <property name="margin_bottom">32</property> + <property name="margin_start">12</property> + <property name="margin_end">12</property> + + <child> + <object class="GtkBox"> + <property name="visible">1</property> + <property name="orientation">vertical</property> + <property name="hexpand">1</property> + <child> + <object class="GtkLabel" id="lock_description_label"> + <property name="visible">1</property> + <property name="margin-bottom">12</property> + <property name="label" translatable="yes">Automatically locking the screen prevents others from accessing the computer while you're away.</property> + <property name="wrap">1</property> + <property name="max-width-chars">50</property> + <property name="xalign">0</property> + </object> + </child> + + <child> + <object class="GtkListBox" id="lock_list_box"> + <property name="visible">1</property> + <property name="can-focus">1</property> + <property name="selection-mode">none</property> + + <!-- Blank Screen Delay row --> + <child> + <object class="HdyActionRow"> + <property name="visible">true</property> + <property name="title" translatable="yes">Blank Screen Delay</property> + <property name="subtitle" translatable="yes">Period of inactivity after which the screen will go blank.</property> + <property name="activatable-widget">blank_screen_combo</property> + <property name="sensitive" bind-source="blank_screen_combo" bind-property="sensitive"/> + <property name="use-underline">true</property> + <child> + <object class="GtkComboBoxText" id="blank_screen_combo"> + <property name="visible">1</property> + <property name="valign">center</property> + <property name="entry_text_column">0</property> + <property name="model">blank_screen_model</property> + <signal name="changed" handler="on_blank_screen_delay_changed_cb" object="CcLockPanel" swapped="no" /> + </object> + </child> + </object> + </child> + + <!-- Automatic Screen Lock row --> + <child> + <object class="HdyActionRow"> + <property name="visible">true</property> + <property name="title" translatable="yes">Automatic Screen _Lock</property> + <property name="activatable-widget">automatic_screen_lock_switch</property> + <property name="use-underline">true</property> + <child> + <object class="GtkSwitch" id="automatic_screen_lock_switch"> + <property name="visible">1</property> + <property name="halign">end</property> + <property name="valign">center</property> + </object> + </child> + </object> + </child> + + <!-- Automatic Screen Lock Delay row --> + <child> + <object class="HdyActionRow"> + <property name="visible">true</property> + <property name="title" translatable="yes">Automatic _Screen Lock Delay</property> + <property name="subtitle" translatable="yes">Period after the screen blanks when the screen is automatically locked.</property> + <property name="activatable-widget">lock_after_combo</property> + <property name="sensitive" bind-source="lock_after_combo" bind-property="sensitive"/> + <property name="use-underline">true</property> + <child> + <object class="GtkComboBoxText" id="lock_after_combo"> + <property name="visible">1</property> + <property name="valign">center</property> + <property name="entry_text_column">0</property> + <property name="model">lock_after_model</property> + <signal name="changed" handler="on_lock_combo_changed_cb" object="CcLockPanel" swapped="no" /> + </object> + </child> + </object> + </child> + + <!-- Show Notifications row --> + <child> + <object class="HdyActionRow"> + <property name="visible">true</property> + <property name="title" translatable="yes">Show _Notifications on Lock Screen</property> + <property name="activatable-widget">show_notifications_switch</property> + <property name="use-underline">true</property> + <child> + <object class="GtkSwitch" id="show_notifications_switch"> + <property name="visible">1</property> + <property name="halign">end</property> + <property name="valign">center</property> + </object> + </child> + </object> + </child> + + <!-- USB protection row --> + <child> + <object class="HdyActionRow" id="usb_protection_row"> + <property name="visible">false</property> + <property name="title" translatable="yes">Forbid new _USB devices</property> + <property name="subtitle" translatable="yes">Prevent new USB devices from interacting with the system when the screen is locked.</property> + <property name="activatable-widget">usb_protection_switch</property> + <property name="use-underline">true</property> + <child> + <object class="GtkSwitch" id="usb_protection_switch"> + <property name="visible">true</property> + <property name="halign">end</property> + <property name="valign">center</property> + </object> + </child> + </object> + </child> + + <style> + <class name="view"/> + <class name="frame"/> + </style> + </object> + </child> + </object> + </child> + + </object> + </child> + </object> + </child> + </template> + + <object class="GtkSizeGroup"> + <property name="mode">horizontal</property> + <widgets> + <widget name="blank_screen_combo" /> + <widget name="lock_after_combo" /> + </widgets> + </object> + + <object class="GtkListStore" id="lock_after_model"> + <columns> + <!-- column-name name --> + <column type="gchararray"/> + <!-- column-name value --> + <column type="gint"/> + </columns> + <data> + <row> + <col id="0" translatable="yes" context="lock_screen" comments="Translators: Option for "Lock screen after blank for" in "Screen Lock" dialog.">Screen Turns Off</col> + <col id="1">0</col> + </row> + <row> + <col id="0" translatable="yes" context="lock_screen" comments="Translators: Option for "Lock screen after blank for" in "Screen Lock" dialog.">30 seconds</col> + <col id="1">30</col> + </row> + <row> + <col id="0" translatable="yes" context="lock_screen" comments="Translators: Option for "Lock screen after blank for" in "Screen Lock" dialog.">1 minute</col> + <col id="1">60</col> + </row> + <row> + <col id="0" translatable="yes" context="lock_screen" comments="Translators: Option for "Lock screen after blank for" in "Screen Lock" dialog.">2 minutes</col> + <col id="1">120</col> + </row> + <row> + <col id="0" translatable="yes" context="lock_screen" comments="Translators: Option for "Lock screen after blank for" in "Screen Lock" dialog.">3 minutes</col> + <col id="1">180</col> + </row> + <row> + <col id="0" translatable="yes" context="lock_screen" comments="Translators: Option for "Lock screen after blank for" in "Screen Lock" dialog.">5 minutes</col> + <col id="1">300</col> + </row> + <row> + <col id="0" translatable="yes" context="lock_screen" comments="Translators: Option for "Lock screen after blank for" in "Screen Lock" dialog.">30 minutes</col> + <col id="1">1800</col> + </row> + <row> + <col id="0" translatable="yes" context="lock_screen" comments="Translators: Option for "Lock screen after blank for" in "Screen Lock" dialog.">1 hour</col> + <col id="1">3600</col> + </row> + </data> + </object> + + <object class="GtkListStore" id="blank_screen_model"> + <columns> + <!-- column-name name --> + <column type="gchararray"/> + <!-- column-name value --> + <column type="gint"/> + </columns> + <data> + <row> + <col id="0" translatable="yes" context="blank_screen" comments="Translators: Option for "Blank screen" in "Power" panel.">1 minute</col> + <col id="1">60</col> + </row> + <row> + <col id="0" translatable="yes" context="blank_screen" comments="Translators: Option for "Blank screen" in "Power" panel.">2 minutes</col> + <col id="1">120</col> + </row> + <row> + <col id="0" translatable="yes" context="blank_screen" comments="Translators: Option for "Blank screen" in "Power" panel.">3 minutes</col> + <col id="1">180</col> + </row> + <row> + <col id="0" translatable="yes" context="blank_screen" comments="Translators: Option for "Blank screen" in "Power" panel.">4 minutes</col> + <col id="1">240</col> + </row> + <row> + <col id="0" translatable="yes" context="blank_screen" comments="Translators: Option for "Blank screen" in "Power" panel.">5 minutes</col> + <col id="1">300</col> + </row> + <row> + <col id="0" translatable="yes" context="blank_screen" comments="Translators: Option for "Blank screen" in "Power" panel.">8 minutes</col> + <col id="1">480</col> + </row> + <row> + <col id="0" translatable="yes" context="blank_screen" comments="Translators: Option for "Blank screen" in "Power" panel.">10 minutes</col> + <col id="1">600</col> + </row> + <row> + <col id="0" translatable="yes" context="blank_screen" comments="Translators: Option for "Blank screen" in "Power" panel.">12 minutes</col> + <col id="1">720</col> + </row> + <row> + <col id="0" translatable="yes" context="blank_screen" comments="Translators: Option for "Blank screen" in "Power" panel.">15 minutes</col> + <col id="1">900</col> + </row> + <row> + <col id="0" translatable="yes" context="blank_screen" comments="Translators: Option for "Blank screen" in "Power" panel.">Never</col> + <col id="1">0</col> + </row> + </data> + </object> +</interface> diff --git a/panels/lock/gnome-lock-panel.desktop.in.in b/panels/lock/gnome-lock-panel.desktop.in.in new file mode 100644 index 0000000..5b4f8b4 --- /dev/null +++ b/panels/lock/gnome-lock-panel.desktop.in.in @@ -0,0 +1,19 @@ +[Desktop Entry] +Name=Screen Lock +Comment=Lock your screen +Exec=gnome-control-center lock +# FIXME +# Translators: Do NOT translate or transliterate this text (this is an icon file name)! +Icon=system-lock-screen-symbolic +Terminal=false +Type=Application +NoDisplay=true +StartupNotify=true +Categories=GNOME;GTK;Settings;DesktopSettings;X-GNOME-Settings-Panel;X-GNOME-PrivacySettings; +OnlyShowIn=GNOME;Unity; +X-GNOME-Bugzilla-Bugzilla=GNOME +X-GNOME-Bugzilla-Product=gnome-control-center +X-GNOME-Bugzilla-Component=privacy +X-GNOME-Bugzilla-Version=@VERSION@ +# Translators: Search terms to find the Privacy panel. Do NOT translate or localize the semicolons! The list MUST also end with a semicolon! +Keywords=screen;lock;diagnostics;crash;private;recent;temporary;tmp;index;name;network;identity;privacy; diff --git a/panels/lock/lock.gresource.xml b/panels/lock/lock.gresource.xml new file mode 100644 index 0000000..8b25a21 --- /dev/null +++ b/panels/lock/lock.gresource.xml @@ -0,0 +1,6 @@ +<?xml version="1.0" encoding="UTF-8"?> +<gresources> + <gresource prefix="/org/gnome/control-center/lock"> + <file preprocess="xml-stripblanks">cc-lock-panel.ui</file> + </gresource> +</gresources> diff --git a/panels/lock/meson.build b/panels/lock/meson.build new file mode 100644 index 0000000..0661af4 --- /dev/null +++ b/panels/lock/meson.build @@ -0,0 +1,40 @@ +panels_list += cappletname +desktop = 'gnome-@0@-panel.desktop'.format(cappletname) + +desktop_in = configure_file( + input: desktop + '.in.in', + output: desktop + '.in', + configuration: desktop_conf +) + +i18n.merge_file( + desktop, + type: 'desktop', + input: desktop_in, + output: desktop, + po_dir: po_dir, + install: true, + install_dir: control_center_desktopdir +) + +sources = files('cc-lock-panel.c') + +resource_data = files('cc-lock-panel.ui') + +sources += gnome.compile_resources( + 'cc-' + cappletname + '-resources', + cappletname + '.gresource.xml', + c_name: 'cc_' + cappletname, + dependencies: resource_data, + export: true +) + +cflags += '-DGNOMELOCALEDIR="@0@"'.format(control_center_localedir) + +panels_libs += static_library( + cappletname, + sources: sources, + include_directories: [top_inc, common_inc], + dependencies: common_deps, + c_args: cflags +) |