From d106191e6ae2aa98ea60a268fb877dc037af9b02 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Mon, 20 Aug 2012 00:06:50 -0400 Subject: [PATCH] Port to GnomeIdleMonitor https://bugzilla.gnome.org/show_bug.cgi?id=682224 --- configure.ac | 2 +- js/ui/messageTray.js | 32 ++- js/ui/pointerWatcher.js | 18 +- js/ui/unlockDialog.js | 5 +- src/Makefile.am | 2 - src/shell-idle-monitor.c | 429 --------------------------------------- src/shell-idle-monitor.h | 74 ------- 7 files changed, 36 insertions(+), 526 deletions(-) delete mode 100644 src/shell-idle-monitor.c delete mode 100644 src/shell-idle-monitor.h diff --git a/configure.ac b/configure.ac index 7b10ae9a4..d01be3905 100644 --- a/configure.ac +++ b/configure.ac @@ -74,7 +74,7 @@ TELEPATHY_LOGGER_MIN_VERSION=0.2.4 POLKIT_MIN_VERSION=0.100 STARTUP_NOTIFICATION_MIN_VERSION=0.11 GCR_MIN_VERSION=3.3.90 -GNOME_DESKTOP_REQUIRED_VERSION=3.5.1 +GNOME_DESKTOP_REQUIRED_VERSION=3.6.0 GNOME_MENUS_REQUIRED_VERSION=3.5.3 # Collect more than 20 libraries for a prize! diff --git a/js/ui/messageTray.js b/js/ui/messageTray.js index 9fb7e790a..791ea9e73 100644 --- a/js/ui/messageTray.js +++ b/js/ui/messageTray.js @@ -4,6 +4,7 @@ const Clutter = imports.gi.Clutter; const GLib = imports.gi.GLib; const Gio = imports.gi.Gio; const Gtk = imports.gi.Gtk; +const GnomeDesktop = imports.gi.GnomeDesktop; const Atk = imports.gi.Atk; const Lang = imports.lang; const Mainloop = imports.mainloop; @@ -1452,10 +1453,10 @@ const MessageTray = new Lang.Class({ this._closeButton.connect('clicked', Lang.bind(this, this._onCloseClicked)); this._notificationWidget.add_actor(this._closeButton); - this._idleMonitorWatchId = 0; + this._idleMonitorBecameActiveId = 0; this._userActiveWhileNotificationShown = false; - this.idleMonitor = Shell.IdleMonitor.get(); + this.idleMonitor = new GnomeDesktop.IdleMonitor(); this._grabHelper = new GrabHelper.GrabHelper(this.actor); this._grabHelper.addActor(this._summaryBoxPointer.actor); @@ -2167,20 +2168,26 @@ const MessageTray = new Lang.Class({ }); }, - _onIdleMonitorWatch: function(monitor, id, userBecameIdle) { - this.idleMonitor.remove_watch(this._idleMonitorWatchId); - this._idleMonitorWatchId = 0; - if (!userBecameIdle) - this._updateNotificationTimeout(2000); + _onIdleMonitorBecameActive: function() { + this.idleMonitor.disconnect(this._idleMonitorBecameActiveId); + this._idleMonitorBecameActiveId = 0; + this._userActiveWhileNotificationShown = true; + this._updateNotificationTimeout(2000); this._updateState(); }, _showNotification: function() { this._notification = this._notificationQueue.shift(); - this._userActiveWhileNotificationShown = this.idleMonitor.get_idletime() <= IDLE_TIME; - this._idleMonitorWatchId = this.idleMonitor.add_watch(IDLE_TIME, - Lang.bind(this, this._onIdleMonitorWatch)); + + let userIdle = this.idleMonitor.get_idletime() > IDLE_TIME; + if (userIdle) { + this._userActiveWhileNotificationShown = false; + this._idleMonitorBecameActiveId = this.idleMonitor.connect('became-active', Lang.bind(this, this._onIdleMonitorBecameActive)); + } else { + this._userActiveWhileNotificationShown = true; + } + this._notificationClickedId = this._notification.connect('done-displaying', Lang.bind(this, this._escapeTray)); this._notification.connect('unfocused', Lang.bind(this, function() { @@ -2293,6 +2300,11 @@ const MessageTray = new Lang.Class({ _hideNotification: function() { this._grabHelper.ungrab({ actor: this._notification.actor }); + if (this._idleMonitorBecameActiveId) { + this.idleMonitor.disconnect(this._idleMonitorBecameActiveId); + this._idleMonitorBecameActiveId = 0; + } + if (this._notificationExpandedId) { this._notification.disconnect(this._notificationExpandedId); this._notificationExpandedId = 0; diff --git a/js/ui/pointerWatcher.js b/js/ui/pointerWatcher.js index 9c5d1fa44..9f7f2909c 100644 --- a/js/ui/pointerWatcher.js +++ b/js/ui/pointerWatcher.js @@ -2,6 +2,7 @@ const Lang = imports.lang; const Mainloop = imports.mainloop; +const GnomeDesktop = imports.gi.GnomeDesktop; const Shell = imports.gi.Shell; // We stop polling if the user is idle for more than this amount of time @@ -40,9 +41,9 @@ const PointerWatcher = new Lang.Class({ Name: 'PointerWatcher', _init: function() { - let idleMonitor = Shell.IdleMonitor.get(); - idleMonitor.add_watch(IDLE_TIME, - Lang.bind(this, this._onIdleMonitorWatch)); + let idleMonitor = new GnomeDesktop.IdleMonitor(); + idleMonitor.connect('became-active', Lang.bind(this, this._onIdleMonitorBecameActive)); + idleMonitor.add_watch(IDLE_TIME, Lang.bind(this, this._onIdleMonitorBecameIdle)); this._idle = idleMonitor.get_idletime() > IDLE_TIME; this._watches = []; this.pointerX = null; @@ -78,11 +79,14 @@ const PointerWatcher = new Lang.Class({ } }, - _onIdleMonitorWatch: function(monitor, id, userBecameIdle) { - this._idle = userBecameIdle; - if (!userBecameIdle) - this._updatePointer(); + _onIdleMonitorBecameActive: function(monitor) { + this._idle = false; + this._updatePointer(); + this._updateTimeout(); + }, + _onIdleMonitorBecameIdle: function(monitor) { + this._idle = true; this._updateTimeout(); }, diff --git a/js/ui/unlockDialog.js b/js/ui/unlockDialog.js index 7b3018265..c86f13c11 100644 --- a/js/ui/unlockDialog.js +++ b/js/ui/unlockDialog.js @@ -5,6 +5,7 @@ const Clutter = imports.gi.Clutter; const Gdm = imports.gi.Gdm; const Gio = imports.gi.Gio; const GLib = imports.gi.GLib; +const GnomeDesktop = imports.gi.GnomeDesktop; const Gtk = imports.gi.Gtk; const Lang = imports.lang; const Signals = imports.signals; @@ -195,9 +196,7 @@ const UnlockDialog = new Lang.Class({ return false; })); - this._idleMonitor = Shell.IdleMonitor.get(); - // this dialog is only created after user activity (curtain drag or - // escape key press), so the timeout will fire after IDLE_TIMEOUT seconds of inactivity + this._idleMonitor = new GnomeDesktop.IdleMonitor(); this._idleWatchId = this._idleMonitor.add_watch(IDLE_TIMEOUT * 1000, Lang.bind(this, this._escape)); }, diff --git a/src/Makefile.am b/src/Makefile.am index a390691c5..bcae2572b 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -113,7 +113,6 @@ shell_public_headers_h = \ shell-generic-container.h \ shell-gtk-embed.h \ shell-global.h \ - shell-idle-monitor.h \ shell-invert-lightness-effect.h \ shell-mobile-providers.h \ shell-mount-operation.h \ @@ -158,7 +157,6 @@ libgnome_shell_la_SOURCES = \ shell-generic-container.c \ shell-gtk-embed.c \ shell-global.c \ - shell-idle-monitor.c \ shell-invert-lightness-effect.c \ shell-keyring-prompt.h \ shell-keyring-prompt.c \ diff --git a/src/shell-idle-monitor.c b/src/shell-idle-monitor.c deleted file mode 100644 index 5bdb6ba2c..000000000 --- a/src/shell-idle-monitor.c +++ /dev/null @@ -1,429 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- - * - * Adapted from gnome-session/gnome-session/gs-idle-monitor.c - * - * Copyright (C) 2012 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, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - * - * Authors: William Jon McCann - * - */ - -#include "config.h" - -#include -#include - -#include -#include - -#include -#include -#include - -#include "shell-idle-monitor.h" - -#define SHELL_IDLE_MONITOR_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), SHELL_TYPE_IDLE_MONITOR, ShellIdleMonitorPrivate)) - -struct ShellIdleMonitorPrivate -{ - Display *display; - - GHashTable *watches; - int sync_event_base; - XSyncCounter counter; -}; - -typedef struct -{ - Display *display; - guint id; - XSyncValue interval; - ShellIdleMonitorWatchFunc callback; - gpointer user_data; - GDestroyNotify notify; - XSyncAlarm xalarm_positive; - XSyncAlarm xalarm_negative; -} ShellIdleMonitorWatch; - -static guint32 watch_serial = 1; - -G_DEFINE_TYPE (ShellIdleMonitor, shell_idle_monitor, G_TYPE_OBJECT) - -static gint64 -_xsyncvalue_to_int64 (XSyncValue value) -{ - return ((guint64) XSyncValueHigh32 (value)) << 32 - | (guint64) XSyncValueLow32 (value); -} - -static XSyncValue -_int64_to_xsyncvalue (gint64 value) -{ - XSyncValue ret; - - XSyncIntsToValue (&ret, value, ((guint64)value) >> 32); - - return ret; -} - -static void -shell_idle_monitor_dispose (GObject *object) -{ - ShellIdleMonitor *monitor; - - monitor = SHELL_IDLE_MONITOR (object); - - if (monitor->priv->watches != NULL) { - g_hash_table_destroy (monitor->priv->watches); - monitor->priv->watches = NULL; - } - - G_OBJECT_CLASS (shell_idle_monitor_parent_class)->dispose (object); -} - -static gboolean -_find_alarm (gpointer key, - ShellIdleMonitorWatch *watch, - XSyncAlarm *alarm) -{ - /* g_debug ("Searching for %d in %d,%d", (int)*alarm, (int)watch->xalarm_positive, (int)watch->xalarm_negative); */ - if (watch->xalarm_positive == *alarm - || watch->xalarm_negative == *alarm) { - return TRUE; - } - return FALSE; -} - -static ShellIdleMonitorWatch * -find_watch_for_alarm (ShellIdleMonitor *monitor, - XSyncAlarm alarm) -{ - ShellIdleMonitorWatch *watch; - - watch = g_hash_table_find (monitor->priv->watches, - (GHRFunc)_find_alarm, - &alarm); - return watch; -} - -static void -handle_alarm_notify_event (ShellIdleMonitor *monitor, - XSyncAlarmNotifyEvent *alarm_event) -{ - ShellIdleMonitorWatch *watch; - gboolean condition; - - if (alarm_event->state == XSyncAlarmDestroyed) { - return; - } - - watch = find_watch_for_alarm (monitor, alarm_event->alarm); - - if (watch == NULL) { - /* g_debug ("Unable to find watch for alarm %d", (int)alarm_event->alarm); */ - return; - } - - /* g_debug ("Watch %d fired, idle time = %" G_GINT64_FORMAT, - watch->id, - _xsyncvalue_to_int64 (alarm_event->counter_value)); */ - - if (alarm_event->alarm == watch->xalarm_positive) { - condition = TRUE; - } else { - condition = FALSE; - } - - if (watch->callback != NULL) { - watch->callback (monitor, - watch->id, - condition, - watch->user_data); - } -} - -static GdkFilterReturn -xevent_filter (GdkXEvent *xevent, - GdkEvent *event, - ShellIdleMonitor *monitor) -{ - XEvent *ev; - XSyncAlarmNotifyEvent *alarm_event; - - ev = xevent; - if (ev->xany.type != monitor->priv->sync_event_base + XSyncAlarmNotify) { - return GDK_FILTER_CONTINUE; - } - - alarm_event = xevent; - - handle_alarm_notify_event (monitor, alarm_event); - - return GDK_FILTER_CONTINUE; -} - -static gboolean -init_xsync (ShellIdleMonitor *monitor) -{ - int sync_error_base; - int res; - int major; - int minor; - int i; - int ncounters; - XSyncSystemCounter *counters; - - res = XSyncQueryExtension (monitor->priv->display, - &monitor->priv->sync_event_base, - &sync_error_base); - if (! res) { - g_warning ("ShellIdleMonitor: Sync extension not present"); - return FALSE; - } - - res = XSyncInitialize (monitor->priv->display, &major, &minor); - if (! res) { - g_warning ("ShellIdleMonitor: Unable to initialize Sync extension"); - return FALSE; - } - - counters = XSyncListSystemCounters (monitor->priv->display, &ncounters); - for (i = 0; i < ncounters; i++) { - if (counters[i].name != NULL - && strcmp (counters[i].name, "IDLETIME") == 0) { - monitor->priv->counter = counters[i].counter; - break; - } - } - XSyncFreeSystemCounterList (counters); - - if (monitor->priv->counter == None) { - g_warning ("ShellIdleMonitor: IDLETIME counter not found"); - return FALSE; - } - - gdk_window_add_filter (NULL, (GdkFilterFunc)xevent_filter, monitor); - - return TRUE; -} - -static GObject * -shell_idle_monitor_constructor (GType type, - guint n_construct_properties, - GObjectConstructParam *construct_properties) -{ - ShellIdleMonitor *monitor; - - monitor = SHELL_IDLE_MONITOR (G_OBJECT_CLASS (shell_idle_monitor_parent_class)->constructor (type, - n_construct_properties, - construct_properties)); - - monitor->priv->display = GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()); - - if (! init_xsync (monitor)) { - g_object_unref (monitor); - return NULL; - } - - return G_OBJECT (monitor); -} - -static void -shell_idle_monitor_class_init (ShellIdleMonitorClass *klass) -{ - GObjectClass *object_class = G_OBJECT_CLASS (klass); - - object_class->dispose = shell_idle_monitor_dispose; - object_class->constructor = shell_idle_monitor_constructor; - - g_type_class_add_private (klass, sizeof (ShellIdleMonitorPrivate)); -} - -static guint32 -get_next_watch_serial (void) -{ - guint32 serial; - - serial = watch_serial++; - - if ((gint32)watch_serial < 0) { - watch_serial = 1; - } - - /* FIXME: make sure it isn't in the hash */ - - return serial; -} - -static ShellIdleMonitorWatch * -idle_monitor_watch_new (guint interval) -{ - ShellIdleMonitorWatch *watch; - - watch = g_slice_new0 (ShellIdleMonitorWatch); - watch->interval = _int64_to_xsyncvalue ((gint64)interval); - watch->id = get_next_watch_serial (); - watch->xalarm_positive = None; - watch->xalarm_negative = None; - - return watch; -} - -static void -idle_monitor_watch_free (ShellIdleMonitorWatch *watch) -{ - if (watch == NULL) { - return; - } - - if (watch->notify != NULL) { - watch->notify (watch->user_data); - } - - if (watch->xalarm_positive != None) { - XSyncDestroyAlarm (watch->display, watch->xalarm_positive); - } - if (watch->xalarm_negative != None) { - XSyncDestroyAlarm (watch->display, watch->xalarm_negative); - } - g_slice_free (ShellIdleMonitorWatch, watch); -} - -static void -shell_idle_monitor_init (ShellIdleMonitor *monitor) -{ - monitor->priv = SHELL_IDLE_MONITOR_GET_PRIVATE (monitor); - - monitor->priv->watches = g_hash_table_new_full (NULL, - NULL, - NULL, - (GDestroyNotify)idle_monitor_watch_free); - - monitor->priv->counter = None; -} - -/** - * shell_idle_monitor_get: - * - * Returns: (transfer none): the global #ShellIdleMonitor. - */ -ShellIdleMonitor * -shell_idle_monitor_get (void) -{ - static ShellIdleMonitor *idle_monitor; - - if (G_UNLIKELY (idle_monitor == NULL)) - idle_monitor = g_object_new (SHELL_TYPE_IDLE_MONITOR, - NULL); - - return idle_monitor; -} - -static gboolean -_xsync_alarm_set (ShellIdleMonitor *monitor, - ShellIdleMonitorWatch *watch) -{ - XSyncAlarmAttributes attr; - XSyncValue delta; - guint flags; - - flags = XSyncCACounter - | XSyncCAValueType - | XSyncCATestType - | XSyncCAValue - | XSyncCADelta - | XSyncCAEvents; - - XSyncIntToValue (&delta, 0); - attr.trigger.counter = monitor->priv->counter; - attr.trigger.value_type = XSyncAbsolute; - attr.trigger.wait_value = watch->interval; - attr.delta = delta; - attr.events = TRUE; - - attr.trigger.test_type = XSyncPositiveTransition; - if (watch->xalarm_positive != None) { - /* g_debug ("ShellIdleMonitor: updating alarm for positive transition wait=%" G_GINT64_FORMAT, - _xsyncvalue_to_int64 (attr.trigger.wait_value)); */ - XSyncChangeAlarm (monitor->priv->display, watch->xalarm_positive, flags, &attr); - } else { - /* g_debug ("ShellIdleMonitor: creating new alarm for positive transition wait=%" G_GINT64_FORMAT, - _xsyncvalue_to_int64 (attr.trigger.wait_value)); */ - watch->xalarm_positive = XSyncCreateAlarm (monitor->priv->display, flags, &attr); - } - - attr.trigger.wait_value = _int64_to_xsyncvalue (_xsyncvalue_to_int64 (watch->interval) - 1); - attr.trigger.test_type = XSyncNegativeTransition; - if (watch->xalarm_negative != None) { - /* g_debug ("ShellIdleMonitor: updating alarm for negative transition wait=%" G_GINT64_FORMAT, - _xsyncvalue_to_int64 (attr.trigger.wait_value)); */ - XSyncChangeAlarm (monitor->priv->display, watch->xalarm_negative, flags, &attr); - } else { - /* g_debug ("ShellIdleMonitor: creating new alarm for negative transition wait=%" G_GINT64_FORMAT, - _xsyncvalue_to_int64 (attr.trigger.wait_value)); */ - watch->xalarm_negative = XSyncCreateAlarm (monitor->priv->display, flags, &attr); - } - - return TRUE; -} - -guint -shell_idle_monitor_add_watch (ShellIdleMonitor *monitor, - guint interval, - ShellIdleMonitorWatchFunc callback, - gpointer user_data, - GDestroyNotify notify) -{ - ShellIdleMonitorWatch *watch; - - g_return_val_if_fail (SHELL_IS_IDLE_MONITOR (monitor), 0); - g_return_val_if_fail (callback != NULL, 0); - - watch = idle_monitor_watch_new (interval); - watch->display = monitor->priv->display; - watch->callback = callback; - watch->user_data = user_data; - watch->notify = notify; - - _xsync_alarm_set (monitor, watch); - - g_hash_table_insert (monitor->priv->watches, - GUINT_TO_POINTER (watch->id), - watch); - return watch->id; -} - -void -shell_idle_monitor_remove_watch (ShellIdleMonitor *monitor, - guint id) -{ - g_return_if_fail (SHELL_IS_IDLE_MONITOR (monitor)); - - g_hash_table_remove (monitor->priv->watches, - GUINT_TO_POINTER (id)); -} - -gint64 -shell_idle_monitor_get_idletime (ShellIdleMonitor *monitor) -{ - XSyncValue value; - - if (!XSyncQueryCounter (monitor->priv->display, monitor->priv->counter, &value)) - return FALSE; - - return _xsyncvalue_to_int64 (value); -} diff --git a/src/shell-idle-monitor.h b/src/shell-idle-monitor.h deleted file mode 100644 index 6a620827f..000000000 --- a/src/shell-idle-monitor.h +++ /dev/null @@ -1,74 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- - * - * Adapted from gnome-session/gnome-session/gs-idle-monitor.h - * - * Copyright (C) 2012 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, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - * - * Authors: William Jon McCann - * - */ - -#ifndef __SHELL_IDLE_MONITOR_H -#define __SHELL_IDLE_MONITOR_H - -#include - -G_BEGIN_DECLS - -#define SHELL_TYPE_IDLE_MONITOR (shell_idle_monitor_get_type ()) -#define SHELL_IDLE_MONITOR(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), SHELL_TYPE_IDLE_MONITOR, ShellIdleMonitor)) -#define SHELL_IDLE_MONITOR_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), SHELL_TYPE_IDLE_MONITOR, ShellIdleMonitorClass)) -#define SHELL_IS_IDLE_MONITOR(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), SHELL_TYPE_IDLE_MONITOR)) -#define SHELL_IS_IDLE_MONITOR_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), SHELL_TYPE_IDLE_MONITOR)) -#define SHELL_IDLE_MONITOR_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), SHELL_TYPE_IDLE_MONITOR, ShellIdleMonitorClass)) - -typedef struct ShellIdleMonitorPrivate ShellIdleMonitorPrivate; - -typedef struct -{ - GObject parent; - ShellIdleMonitorPrivate *priv; -} ShellIdleMonitor; - -typedef struct -{ - GObjectClass parent_class; -} ShellIdleMonitorClass; - -typedef void (*ShellIdleMonitorWatchFunc) (ShellIdleMonitor *monitor, - guint id, - gboolean condition, - gpointer user_data); - -GType shell_idle_monitor_get_type (void); - -ShellIdleMonitor * shell_idle_monitor_get (void); - -guint shell_idle_monitor_add_watch (ShellIdleMonitor *monitor, - guint interval, - ShellIdleMonitorWatchFunc callback, - gpointer user_data, - GDestroyNotify notify); - -void shell_idle_monitor_remove_watch (ShellIdleMonitor *monitor, - guint id); - -gint64 shell_idle_monitor_get_idletime (ShellIdleMonitor *monitor); - -G_END_DECLS - -#endif /* __SHELL_IDLE_MONITOR_H */