Trying to just hide the widget will cause some severely bizarre display problems, so just set the heading to be empty instead for now. We should probably look at another way of handling this case. https://bugzilla.gnome.org/show_bug.cgi?id=657606
548 lines
15 KiB
C
548 lines
15 KiB
C
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*-
|
|
*
|
|
* Copyright (C) 2010 Red Hat, Inc
|
|
* Copyright (C) 2008 William Jon McCann <jmccann@redhat.com>
|
|
*
|
|
* 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, write to the Free Software
|
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|
*
|
|
*/
|
|
|
|
#include "cc-screen-panel.h"
|
|
|
|
G_DEFINE_DYNAMIC_TYPE (CcScreenPanel, cc_screen_panel, CC_TYPE_PANEL)
|
|
|
|
#define SCREEN_PANEL_PRIVATE(o) \
|
|
(G_TYPE_INSTANCE_GET_PRIVATE ((o), CC_TYPE_SCREEN_PANEL, CcScreenPanelPrivate))
|
|
|
|
#define WID(s) GTK_WIDGET (gtk_builder_get_object (self->priv->builder, s))
|
|
|
|
struct _CcScreenPanelPrivate
|
|
{
|
|
GSettings *lock_settings;
|
|
GSettings *gsd_settings;
|
|
GSettings *session_settings;
|
|
GSettings *lockdown_settings;
|
|
GCancellable *cancellable;
|
|
GtkBuilder *builder;
|
|
GDBusProxy *proxy;
|
|
gboolean setting_brightness;
|
|
};
|
|
|
|
|
|
static void
|
|
cc_screen_panel_get_property (GObject *object,
|
|
guint property_id,
|
|
GValue *value,
|
|
GParamSpec *pspec)
|
|
{
|
|
switch (property_id)
|
|
{
|
|
default:
|
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
|
|
}
|
|
}
|
|
|
|
static void
|
|
cc_screen_panel_set_property (GObject *object,
|
|
guint property_id,
|
|
const GValue *value,
|
|
GParamSpec *pspec)
|
|
{
|
|
switch (property_id)
|
|
{
|
|
default:
|
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
|
|
}
|
|
}
|
|
|
|
static void
|
|
cc_screen_panel_dispose (GObject *object)
|
|
{
|
|
CcScreenPanelPrivate *priv = CC_SCREEN_PANEL (object)->priv;
|
|
|
|
if (priv->lock_settings)
|
|
{
|
|
g_object_unref (priv->lock_settings);
|
|
priv->lock_settings = NULL;
|
|
}
|
|
if (priv->gsd_settings)
|
|
{
|
|
g_object_unref (priv->gsd_settings);
|
|
priv->gsd_settings = NULL;
|
|
}
|
|
if (priv->session_settings)
|
|
{
|
|
g_object_unref (priv->session_settings);
|
|
priv->session_settings = NULL;
|
|
}
|
|
if (priv->lockdown_settings)
|
|
{
|
|
g_object_unref (priv->lockdown_settings);
|
|
priv->lockdown_settings = NULL;
|
|
}
|
|
if (priv->cancellable != NULL)
|
|
{
|
|
g_object_unref (priv->cancellable);
|
|
priv->cancellable = NULL;
|
|
}
|
|
if (priv->builder != NULL)
|
|
{
|
|
g_object_unref (priv->builder);
|
|
priv->builder = NULL;
|
|
}
|
|
if (priv->proxy != NULL)
|
|
{
|
|
g_object_unref (priv->proxy);
|
|
priv->proxy = NULL;
|
|
}
|
|
|
|
G_OBJECT_CLASS (cc_screen_panel_parent_class)->dispose (object);
|
|
}
|
|
|
|
static void
|
|
cc_screen_panel_finalize (GObject *object)
|
|
{
|
|
CcScreenPanelPrivate *priv = CC_SCREEN_PANEL (object)->priv;
|
|
g_cancellable_cancel (priv->cancellable);
|
|
G_OBJECT_CLASS (cc_screen_panel_parent_class)->finalize (object);
|
|
}
|
|
|
|
static void
|
|
on_lock_settings_changed (GSettings *settings,
|
|
const char *key,
|
|
CcScreenPanel *panel)
|
|
{
|
|
if (g_str_equal (key, "lock-delay") == FALSE)
|
|
return;
|
|
}
|
|
|
|
static void
|
|
update_lock_screen_sensitivity (CcScreenPanel *self)
|
|
{
|
|
GtkWidget *widget;
|
|
gboolean locked;
|
|
|
|
widget = WID ("screen_lock_main_box");
|
|
locked = g_settings_get_boolean (self->priv->lockdown_settings, "disable-lock-screen");
|
|
gtk_widget_set_sensitive (widget, !locked);
|
|
}
|
|
|
|
static void
|
|
on_lockdown_settings_changed (GSettings *settings,
|
|
const char *key,
|
|
CcScreenPanel *panel)
|
|
{
|
|
if (g_str_equal (key, "disable-lock-screen") == FALSE)
|
|
return;
|
|
|
|
update_lock_screen_sensitivity (panel);
|
|
}
|
|
|
|
static void
|
|
cc_screen_panel_class_init (CcScreenPanelClass *klass)
|
|
{
|
|
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
|
|
|
g_type_class_add_private (klass, sizeof (CcScreenPanelPrivate));
|
|
|
|
object_class->get_property = cc_screen_panel_get_property;
|
|
object_class->set_property = cc_screen_panel_set_property;
|
|
object_class->dispose = cc_screen_panel_dispose;
|
|
object_class->finalize = cc_screen_panel_finalize;
|
|
}
|
|
|
|
static void
|
|
cc_screen_panel_class_finalize (CcScreenPanelClass *klass)
|
|
{
|
|
}
|
|
|
|
static void
|
|
on_signal (GDBusProxy *proxy,
|
|
gchar *sender_name,
|
|
gchar *signal_name,
|
|
GVariant *parameters,
|
|
gpointer user_data)
|
|
{
|
|
CcScreenPanel *self = CC_SCREEN_PANEL (user_data);
|
|
|
|
if (g_strcmp0 (signal_name, "BrightnessChanged") == 0)
|
|
{
|
|
guint brightness;
|
|
GtkRange *range;
|
|
|
|
/* changed, but ignoring */
|
|
if (self->priv->setting_brightness)
|
|
return;
|
|
|
|
/* update the bar */
|
|
g_variant_get (parameters,
|
|
"(u)",
|
|
&brightness);
|
|
range = GTK_RANGE (WID ("screen_brightness_hscale"));
|
|
gtk_range_set_value (range, brightness);
|
|
}
|
|
}
|
|
|
|
static void
|
|
set_brightness_cb (GObject *source_object, GAsyncResult *res, gpointer user_data)
|
|
{
|
|
GError *error = NULL;
|
|
GVariant *result;
|
|
|
|
CcScreenPanelPrivate *priv = CC_SCREEN_PANEL (user_data)->priv;
|
|
|
|
/* not setting, so pay attention to changed signals */
|
|
priv->setting_brightness = FALSE;
|
|
result = g_dbus_proxy_call_finish (G_DBUS_PROXY (source_object), res, &error);
|
|
if (result == NULL)
|
|
{
|
|
g_printerr ("Error setting brightness: %s\n", error->message);
|
|
g_error_free (error);
|
|
return;
|
|
}
|
|
}
|
|
|
|
static void
|
|
brightness_slider_value_changed_cb (GtkRange *range, gpointer user_data)
|
|
{
|
|
guint percentage;
|
|
CcScreenPanelPrivate *priv = CC_SCREEN_PANEL (user_data)->priv;
|
|
|
|
/* do not loop */
|
|
if (priv->setting_brightness)
|
|
return;
|
|
|
|
priv->setting_brightness = TRUE;
|
|
|
|
/* push this to g-p-m */
|
|
percentage = (guint) gtk_range_get_value (range);
|
|
g_dbus_proxy_call (priv->proxy,
|
|
"SetPercentage",
|
|
g_variant_new ("(u)",
|
|
percentage),
|
|
G_DBUS_CALL_FLAGS_NONE,
|
|
-1,
|
|
priv->cancellable,
|
|
set_brightness_cb,
|
|
user_data);
|
|
}
|
|
|
|
static void
|
|
get_brightness_cb (GObject *source_object, GAsyncResult *res, gpointer user_data)
|
|
{
|
|
GError *error = NULL;
|
|
GVariant *result;
|
|
guint brightness;
|
|
GtkRange *range;
|
|
CcScreenPanel *self = CC_SCREEN_PANEL (user_data);
|
|
|
|
result = g_dbus_proxy_call_finish (G_DBUS_PROXY (source_object), res, &error);
|
|
if (result == NULL)
|
|
{
|
|
gtk_widget_hide (WID ("screen_brightness_hscale"));
|
|
gtk_widget_hide (WID ("screen_auto_reduce_checkbutton"));
|
|
/* FIXME: This needs a proper fix:
|
|
* https://bugzilla.gnome.org/show_bug.cgi?id=657606 */
|
|
gtk_label_set_text (GTK_LABEL (WID ("brightness-section-heading")), "");
|
|
g_warning ("Error getting brightness: %s", error->message);
|
|
g_error_free (error);
|
|
return;
|
|
}
|
|
|
|
/* set the slider */
|
|
g_variant_get (result,
|
|
"(u)",
|
|
&brightness);
|
|
range = GTK_RANGE (WID ("screen_brightness_hscale"));
|
|
gtk_range_set_range (range, 0, 100);
|
|
gtk_range_set_increments (range, 1, 10);
|
|
gtk_range_set_value (range, brightness);
|
|
g_signal_connect (range,
|
|
"value-changed",
|
|
G_CALLBACK (brightness_slider_value_changed_cb),
|
|
user_data);
|
|
g_variant_unref (result);
|
|
}
|
|
|
|
static void
|
|
got_power_proxy_cb (GObject *source_object, GAsyncResult *res, gpointer user_data)
|
|
{
|
|
GError *error = NULL;
|
|
CcScreenPanelPrivate *priv = CC_SCREEN_PANEL (user_data)->priv;
|
|
|
|
priv->proxy = g_dbus_proxy_new_for_bus_finish (res, &error);
|
|
if (priv->proxy == NULL)
|
|
{
|
|
g_printerr ("Error creating proxy: %s\n", error->message);
|
|
g_error_free (error);
|
|
return;
|
|
}
|
|
|
|
/* we want to change the bar if the user presses brightness buttons */
|
|
g_signal_connect (priv->proxy,
|
|
"g-signal",
|
|
G_CALLBACK (on_signal),
|
|
user_data);
|
|
|
|
/* get the initial state */
|
|
g_dbus_proxy_call (priv->proxy,
|
|
"GetPercentage",
|
|
NULL,
|
|
G_DBUS_CALL_FLAGS_NONE,
|
|
200, /* we don't want to randomly move the bar */
|
|
priv->cancellable,
|
|
get_brightness_cb,
|
|
user_data);
|
|
}
|
|
|
|
static void
|
|
set_idle_delay_from_dpms (CcScreenPanel *self,
|
|
int value)
|
|
{
|
|
guint off_delay;
|
|
|
|
off_delay = 1;
|
|
|
|
if (value > 0)
|
|
off_delay = (guint) value;
|
|
|
|
g_settings_set (self->priv->session_settings, "idle-delay", "u", off_delay);
|
|
}
|
|
|
|
static void
|
|
dpms_combo_changed_cb (GtkWidget *widget, CcScreenPanel *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 battery and ac keys */
|
|
g_settings_set_int (self->priv->gsd_settings, "sleep-display-ac", value);
|
|
g_settings_set_int (self->priv->gsd_settings, "sleep-display-battery", value);
|
|
|
|
set_idle_delay_from_dpms (self, value);
|
|
}
|
|
|
|
static void
|
|
lock_combo_changed_cb (GtkWidget *widget, CcScreenPanel *self)
|
|
{
|
|
GtkTreeIter iter;
|
|
GtkTreeModel *model;
|
|
guint delay;
|
|
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, &delay,
|
|
-1);
|
|
g_settings_set (self->priv->lock_settings, "lock-delay", "u", delay);
|
|
}
|
|
|
|
static void
|
|
set_dpms_value_for_combo (GtkComboBox *combo_box, CcScreenPanel *self)
|
|
{
|
|
GtkTreeIter iter;
|
|
GtkTreeModel *model;
|
|
gint value;
|
|
gint value_tmp, value_prev;
|
|
gboolean ret;
|
|
guint i;
|
|
|
|
/* get entry */
|
|
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;
|
|
|
|
/* try to make the UI match the AC setting */
|
|
value = g_settings_get_int (self->priv->gsd_settings, "sleep-display-ac");
|
|
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));
|
|
|
|
/* If we didn't find the setting in the list */
|
|
gtk_combo_box_set_active (combo_box, i - 1);
|
|
}
|
|
|
|
static void
|
|
set_lock_value_for_combo (GtkComboBox *combo_box, CcScreenPanel *self)
|
|
{
|
|
GtkTreeIter iter;
|
|
GtkTreeModel *model;
|
|
guint value;
|
|
gint value_tmp, value_prev;
|
|
gboolean ret;
|
|
guint i;
|
|
|
|
/* get entry */
|
|
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;
|
|
|
|
/* try to make the UI match the lock setting */
|
|
g_settings_get (self->priv->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));
|
|
|
|
/* If we didn't find the setting in the list */
|
|
gtk_combo_box_set_active (combo_box, i - 1);
|
|
}
|
|
|
|
static void
|
|
cc_screen_panel_init (CcScreenPanel *self)
|
|
{
|
|
GError *error;
|
|
GtkWidget *widget;
|
|
|
|
self->priv = SCREEN_PANEL_PRIVATE (self);
|
|
|
|
self->priv->builder = gtk_builder_new ();
|
|
|
|
error = NULL;
|
|
gtk_builder_add_from_file (self->priv->builder,
|
|
GNOMECC_UI_DIR "/screen.ui",
|
|
&error);
|
|
|
|
if (error != NULL)
|
|
{
|
|
g_warning ("Could not load interface file: %s", error->message);
|
|
g_error_free (error);
|
|
return;
|
|
}
|
|
|
|
self->priv->cancellable = g_cancellable_new ();
|
|
|
|
/* get initial brightness version */
|
|
g_dbus_proxy_new_for_bus (G_BUS_TYPE_SESSION,
|
|
G_DBUS_PROXY_FLAGS_NONE,
|
|
NULL,
|
|
"org.gnome.SettingsDaemon",
|
|
"/org/gnome/SettingsDaemon/Power",
|
|
"org.gnome.SettingsDaemon.Power.Screen",
|
|
self->priv->cancellable,
|
|
got_power_proxy_cb,
|
|
self);
|
|
|
|
self->priv->lock_settings = g_settings_new ("org.gnome.desktop.screensaver");
|
|
g_signal_connect (self->priv->lock_settings,
|
|
"changed",
|
|
G_CALLBACK (on_lock_settings_changed),
|
|
self);
|
|
self->priv->gsd_settings = g_settings_new ("org.gnome.settings-daemon.plugins.power");
|
|
self->priv->session_settings = g_settings_new ("org.gnome.desktop.session");
|
|
self->priv->lockdown_settings = g_settings_new ("org.gnome.desktop.lockdown");
|
|
g_signal_connect (self->priv->lockdown_settings,
|
|
"changed",
|
|
G_CALLBACK (on_lockdown_settings_changed),
|
|
self);
|
|
|
|
/* bind the auto dim checkbox */
|
|
widget = WID ("screen_auto_reduce_checkbutton");
|
|
g_settings_bind (self->priv->gsd_settings,
|
|
"idle-dim-battery",
|
|
widget, "active",
|
|
G_SETTINGS_BIND_DEFAULT);
|
|
|
|
/* display off time */
|
|
widget = WID ("screen_brightness_combobox");
|
|
set_dpms_value_for_combo (GTK_COMBO_BOX (widget), self);
|
|
g_signal_connect (widget, "changed",
|
|
G_CALLBACK (dpms_combo_changed_cb),
|
|
self);
|
|
|
|
/* bind the screen lock checkbox */
|
|
widget = WID ("screen_lock_on_switch");
|
|
g_settings_bind (self->priv->lock_settings,
|
|
"lock-enabled",
|
|
widget, "active",
|
|
G_SETTINGS_BIND_DEFAULT);
|
|
|
|
/* lock time */
|
|
widget = WID ("screen_lock_combobox");
|
|
set_lock_value_for_combo (GTK_COMBO_BOX (widget), self);
|
|
g_signal_connect (widget, "changed",
|
|
G_CALLBACK (lock_combo_changed_cb),
|
|
self);
|
|
|
|
widget = WID ("screen_lock_hbox");
|
|
g_settings_bind (self->priv->lock_settings,
|
|
"lock-enabled",
|
|
widget, "sensitive",
|
|
G_SETTINGS_BIND_GET);
|
|
|
|
update_lock_screen_sensitivity (self);
|
|
|
|
widget = WID ("screen_vbox");
|
|
gtk_widget_reparent (widget, (GtkWidget *) self);
|
|
}
|
|
|
|
void
|
|
cc_screen_panel_register (GIOModule *module)
|
|
{
|
|
cc_screen_panel_register_type (G_TYPE_MODULE (module));
|
|
g_io_extension_point_implement (CC_SHELL_PANEL_EXTENSION_POINT,
|
|
CC_TYPE_SCREEN_PANEL,
|
|
"screen", 0);
|
|
}
|
|
|