[drwright] Add Lock button to break window
- From: Christian Persch <chpe src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [drwright] Add Lock button to break window
- Date: Sun, 11 Dec 2011 12:55:18 +0000 (UTC)
commit 6ddc60f3493b7a77668431ea70b2db430ff3ed0e
Author: Christian Persch <chpe gnome org>
Date: Sat Apr 16 23:55:22 2011 +0200
Add Lock button to break window
Based on a patch by Matthias Clasen.
Bug #128381.
src/drw-break-window.c | 96 ++++++++++++++++++++++++++++++++++++++++++-----
src/drw-break-window.h | 2 +-
src/drw-utils.c | 13 ++++++
src/drw-utils.h | 3 +-
src/drwright.c | 97 +++++++++++++++++++++++++++++++++++++++++++++++-
src/drwright.h | 2 +
6 files changed, 198 insertions(+), 15 deletions(-)
---
diff --git a/src/drw-break-window.c b/src/drw-break-window.c
index 57d7a39..b2f5b07 100644
--- a/src/drw-break-window.c
+++ b/src/drw-break-window.c
@@ -22,6 +22,7 @@
#include <config.h>
#include <string.h>
+#include <unistd.h>
#include <math.h>
#include <glib/gi18n.h>
#include <gio/gio.h>
@@ -52,6 +53,8 @@ struct _DrwBreakWindowPrivate {
guint postpone_delay;
gint elapsed_idle_time;
+ gboolean enable_lock;
+
GSettings *settings;
};
@@ -67,11 +70,18 @@ struct _DrwBreakWindowPrivate {
enum {
DONE,
POSTPONE,
+ LOCK,
LAST_SIGNAL
};
+enum {
+ PROP_0,
+ PROP_ENABLE_LOCK
+};
+
static void drw_break_window_class_init (DrwBreakWindowClass *klass);
static void drw_break_window_init (DrwBreakWindow *window);
+static void drw_break_window_constructed (GObject *object);
static void drw_break_window_finalize (GObject *object);
static void drw_break_window_dispose (GObject *object);
static gboolean postpone_sensitize_cb (DrwBreakWindow *window);
@@ -84,10 +94,30 @@ G_DEFINE_TYPE (DrwBreakWindow, drw_break_window, GTK_TYPE_WINDOW)
static guint signals[LAST_SIGNAL];
static void
+drw_break_window_set_property (GObject *object,
+ guint property_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ DrwBreakWindow *window = DRW_BREAK_WINDOW (object);
+ DrwBreakWindowPrivate *priv = window->priv;
+
+ switch (property_id) {
+ case PROP_ENABLE_LOCK:
+ priv->enable_lock = g_value_get_boolean (value);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+ }
+}
+
+static void
drw_break_window_class_init (DrwBreakWindowClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
+ object_class->set_property = drw_break_window_set_property;
+ object_class->constructed = drw_break_window_constructed;
object_class->finalize = drw_break_window_finalize;
object_class->dispose = drw_break_window_dispose;
@@ -100,6 +130,16 @@ drw_break_window_class_init (DrwBreakWindowClass *klass)
g_cclosure_marshal_VOID__VOID,
G_TYPE_NONE, 0);
+ signals[LOCK] =
+ g_signal_new ("lock",
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_LAST,
+ 0,
+ NULL, NULL,
+ g_cclosure_marshal_VOID__VOID,
+ G_TYPE_NONE, 0);
+
+ signals[DONE] =
signals[DONE] =
g_signal_new ("done",
G_TYPE_FROM_CLASS (klass),
@@ -109,13 +149,35 @@ drw_break_window_class_init (DrwBreakWindowClass *klass)
g_cclosure_marshal_VOID__VOID,
G_TYPE_NONE, 0);
+ g_object_class_install_property
+ (object_class,
+ PROP_ENABLE_LOCK,
+ g_param_spec_boolean ("enable-lock", NULL, NULL,
+ FALSE,
+ G_PARAM_WRITABLE |
+ G_PARAM_CONSTRUCT_ONLY |
+ G_PARAM_STATIC_STRINGS));
+
g_type_class_add_private (klass, sizeof (DrwBreakWindowPrivate));
}
static void
+lock_clicked_cb (GtkWidget *button, DrwBreakWindow *window)
+{
+ g_signal_emit (window, signals[LOCK], 0, NULL);
+}
+
+static void
drw_break_window_init (DrwBreakWindow *window)
{
- DrwBreakWindowPrivate *priv;
+ window->priv = DRW_BREAK_WINDOW_GET_PRIVATE (window);
+}
+
+static void
+drw_break_window_constructed (GObject *object)
+{
+ DrwBreakWindow *window = DRW_BREAK_WINDOW (object);
+ DrwBreakWindowPrivate *priv = window->priv;
GtkWidget *vbox;
GtkWidget *hbox;
GtkWidget *align;
@@ -124,6 +186,7 @@ drw_break_window_init (DrwBreakWindow *window)
GtkWidget *outer_vbox;
GtkWidget *button_box;
gboolean allow_postpone;
+ GtkWidget *lock_button;
gint root_monitor = 0;
GdkScreen *screen = NULL;
@@ -131,8 +194,6 @@ drw_break_window_init (DrwBreakWindow *window)
gint right_padding;
gint bottom_padding;
- priv = DRW_BREAK_WINDOW_GET_PRIVATE (window);
- window->priv = priv;
priv->settings = g_settings_new (DRW_SETTINGS_SCHEMA_ID);
@@ -180,12 +241,17 @@ drw_break_window_init (DrwBreakWindow *window)
gtk_box_pack_start (GTK_BOX (outer_vbox), align, TRUE, TRUE, 0);
- if (allow_postpone) {
- button_box = gtk_hbox_new (FALSE, 0);
- gtk_widget_show (button_box);
+ if (allow_postpone || priv->enable_lock) {
+ button_box = gtk_hbutton_box_new ();
+ gtk_button_box_set_layout (GTK_BUTTON_BOX (button_box), GTK_BUTTONBOX_END);
+ gtk_container_set_border_width (GTK_CONTAINER (button_box), 12);
+ gtk_box_set_spacing (GTK_BOX (button_box), 12);
- gtk_container_set_border_width (GTK_CONTAINER (button_box), 12);
+ gtk_box_pack_start (GTK_BOX (outer_vbox), button_box, FALSE, FALSE, 0);
+ gtk_widget_show (button_box);
+ }
+ if (allow_postpone) {
priv->postpone_button = gtk_button_new_with_mnemonic (_("_Postpone Break"));
gtk_button_set_focus_on_click (GTK_BUTTON (priv->postpone_button), FALSE);
gtk_widget_show (priv->postpone_button);
@@ -209,10 +275,18 @@ drw_break_window_init (DrwBreakWindow *window)
gtk_entry_set_has_frame (GTK_ENTRY (priv->postpone_entry), FALSE);
gtk_box_pack_end (GTK_BOX (button_box), priv->postpone_entry, FALSE, TRUE, 4);
-
- gtk_box_pack_end (GTK_BOX (outer_vbox), button_box, FALSE, TRUE, 0);
}
+ if (priv->enable_lock) {
+ lock_button = gtk_button_new_with_mnemonic (_("_Lock Screen"));
+ gtk_widget_show (lock_button);
+ gtk_box_pack_start (GTK_BOX (button_box), lock_button, FALSE, FALSE, 0);
+ g_signal_connect (lock_button,
+ "clicked",
+ G_CALLBACK (lock_clicked_cb),
+ window);
+ }
+
vbox = gtk_vbox_new (FALSE, 0);
gtk_widget_show (vbox);
@@ -237,7 +311,6 @@ drw_break_window_init (DrwBreakWindow *window)
gtk_box_pack_start (GTK_BOX (hbox), priv->break_label, FALSE, FALSE, 12);
-
priv->clock_label = gtk_label_new (NULL);
gtk_misc_set_alignment (GTK_MISC (priv->clock_label), 0.5, 0.5);
gtk_widget_show (priv->clock_label);
@@ -310,7 +383,7 @@ drw_break_window_dispose (GObject *object)
}
GtkWidget *
-drw_break_window_new (void)
+drw_break_window_new (gboolean enable_lock)
{
GObject *object;
@@ -319,6 +392,7 @@ drw_break_window_new (void)
"skip-taskbar-hint", TRUE,
"skip-pager-hint", TRUE,
"focus-on-map", TRUE,
+ "enable-lock", enable_lock,
NULL);
return GTK_WIDGET (object);
diff --git a/src/drw-break-window.h b/src/drw-break-window.h
index b6b038b..78901d4 100644
--- a/src/drw-break-window.h
+++ b/src/drw-break-window.h
@@ -48,7 +48,7 @@ struct _DrwBreakWindowClass {
};
GType drw_break_window_get_type (void) G_GNUC_CONST;
-GtkWidget * drw_break_window_new (void);
+GtkWidget * drw_break_window_new (gboolean can_lock);
void drw_break_window_set_elapsed_idle_time (DrwBreakWindow *window,
gint seconds);
diff --git a/src/drw-utils.c b/src/drw-utils.c
index 9242fa2..2e59959 100644
--- a/src/drw-utils.c
+++ b/src/drw-utils.c
@@ -19,6 +19,8 @@
*/
#include <config.h>
+#include <unistd.h>
+#include <gio/gio.h>
#include <gdk/gdk.h>
#include <gdk-pixbuf/gdk-pixbuf.h>
#include <gtk/gtk.h>
@@ -222,3 +224,14 @@ drw_setup_background (GtkWidget *window)
}
}
+static gboolean
+drw_is_program_in_path (const char *program)
+{
+ char *tmp = g_find_program_in_path (program);
+ if (tmp != NULL) {
+ g_free (tmp);
+ return TRUE;
+ } else {
+ return FALSE;
+ }
+}
diff --git a/src/drw-utils.h b/src/drw-utils.h
index 9ef75bb..ea2693b 100644
--- a/src/drw-utils.h
+++ b/src/drw-utils.h
@@ -23,7 +23,6 @@
#include <gtk/gtk.h>
-void drw_setup_background (GtkWidget *window);
-
+void drw_setup_background (GtkWidget *window);
#endif /* __DRW_UTILS_H__ */
diff --git a/src/drwright.c b/src/drwright.c
index c768c31..4eb1d98 100644
--- a/src/drwright.c
+++ b/src/drwright.c
@@ -53,6 +53,8 @@ typedef enum {
struct _DrWright {
GSettings *settings;
+ GDBusProxy *screensaver_proxy;
+
/* Widgets. */
GtkWidget *break_window;
GList *secondary_break_windows;
@@ -84,12 +86,55 @@ static void break_window_done_cb (GtkWidget *window,
DrWright *dr);
static void break_window_postpone_cb (GtkWidget *window,
DrWright *dr);
+static void break_window_lock_cb (GtkWidget *window,
+ DrWright *dr);
static void break_window_destroy_cb (GtkWidget *window,
DrWright *dr);
static GList * create_secondary_break_windows (void);
extern gboolean debug;
+#define GNOME_SCREENSAVER_BUS_NAME "org.gnome.ScreenSaver"
+#define GNOME_SCREENSAVER_OBJECT_PATH "/org/gnome/ScreenSaver"
+#define GNOME_SCREENSAVER_INTERFACE "org.gnome.ScreenSaver"
+
+/* FIXMEchpe: make this async! */
+static GDBusProxy *
+get_screensaver_proxy (DrWright *dr)
+{
+ GDBusConnection *connection;
+ GVariant *result;
+ GError *error = NULL;
+
+ if (dr->screensaver_proxy != NULL)
+ return dr->screensaver_proxy;
+
+ connection = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, NULL);
+ if (connection == NULL)
+ return NULL;
+
+ dr->screensaver_proxy =
+ g_dbus_proxy_new_sync (connection,
+ G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES |
+ G_DBUS_PROXY_FLAGS_DO_NOT_CONNECT_SIGNALS |
+ G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START,
+ NULL,
+ GNOME_SCREENSAVER_BUS_NAME,
+ GNOME_SCREENSAVER_OBJECT_PATH,
+ GNOME_SCREENSAVER_INTERFACE,
+ NULL,
+ NULL);
+ g_object_unref (connection);
+
+ return dr->screensaver_proxy;
+}
+
+gboolean
+drwright_can_lock_screen (DrWright *dr)
+{
+ return get_screensaver_proxy (dr) != NULL;
+}
+
static void
notification_action_cb (NotifyNotification *notification,
const char *action,
@@ -304,7 +349,7 @@ maybe_change_state (DrWright *dr)
drw_timer_start (dr->timer);
- dr->break_window = drw_break_window_new ();
+ dr->break_window = drw_break_window_new (drwright_can_lock_screen (dr));
drw_break_window_set_elapsed_idle_time (DRW_BREAK_WINDOW (dr->break_window),
elapsed_idle_time);
@@ -324,6 +369,11 @@ maybe_change_state (DrWright *dr)
dr);
g_signal_connect (dr->break_window,
+ "lock",
+ G_CALLBACK (break_window_lock_cb),
+ dr);
+
+ g_signal_connect (dr->break_window,
"destroy",
G_CALLBACK (break_window_destroy_cb),
dr);
@@ -427,6 +477,51 @@ break_window_postpone_cb (GtkWidget *window,
}
static void
+screensaver_locked_cb (GDBusProxy *proxy,
+ GAsyncResult *result,
+ DrWright *dr)
+{
+ GVariant *variant;
+
+ variant = g_dbus_proxy_call_finish (proxy, result, NULL);
+ if (variant == NULL)
+ return;
+
+ g_variant_unref (variant);
+
+ /* We keep the break window. If the user unlocks before the break is up,
+ * it'll still prevent typing; otherwise the timeout will have killed
+ * it in the meantime.
+ *
+ * FIXME: make sure we don't go to 'break' again while the screen is
+ * locked.
+ */
+}
+
+static void
+break_window_lock_cb (GtkWidget *window,
+ DrWright *dr)
+{
+ GDBusProxy *proxy;
+
+ proxy = get_screensaver_proxy (dr);
+ if (proxy == NULL)
+ return;
+
+ /* ungrab the keyboard so the screensaver can start */
+ gdk_keyboard_ungrab (GDK_CURRENT_TIME);
+
+ g_dbus_proxy_call (proxy,
+ "Lock",
+ g_variant_new ("()"),
+ G_DBUS_CALL_FLAGS_NONE,
+ -1,
+ NULL,
+ (GAsyncReadyCallback) screensaver_locked_cb,
+ dr);
+}
+
+static void
break_window_destroy_cb (GtkWidget *window,
DrWright *dr)
{
diff --git a/src/drwright.h b/src/drwright.h
index 9ce13c3..5481224 100644
--- a/src/drwright.h
+++ b/src/drwright.h
@@ -27,4 +27,6 @@ typedef struct _DrWright DrWright;
DrWright *drwright_new (void);
+gboolean drwright_can_lock_screen (DrWright *dr);
+
#endif /* __DR_WRIGHT_H__ */
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]