[gnome-screensaver] Add an API to show a message on the locked screen
- From: William Jon McCann <mccann src gnome org>
- To: svn-commits-list gnome org
- Cc:
- Subject: [gnome-screensaver] Add an API to show a message on the locked screen
- Date: Mon, 2 Nov 2009 22:16:16 +0000 (UTC)
commit 370ae655619c8e0fbd8a092d7dc8dc6ad4ab1445
Author: William Jon McCann <jmccann redhat com>
Date: Mon Nov 2 17:15:45 2009 -0500
Add an API to show a message on the locked screen
Fixes https://bugzilla.gnome.org/show_bug.cgi?id=599258
src/gs-listener-dbus.c | 68 ++++++++++++++++++++++++++++++
src/gs-listener-dbus.h | 4 ++
src/gs-manager.c | 17 ++++++++
src/gs-manager.h | 4 ++
src/gs-marshal.list | 1 +
src/gs-monitor.c | 16 +++++++
src/gs-window-x11.c | 107 ++++++++++++++++++++++++++++++++++++++++++++++++
src/gs-window.h | 4 ++
8 files changed, 221 insertions(+), 0 deletions(-)
---
diff --git a/src/gs-listener-dbus.c b/src/gs-listener-dbus.c
index 85a0328..e7690a5 100644
--- a/src/gs-listener-dbus.c
+++ b/src/gs-listener-dbus.c
@@ -108,6 +108,7 @@ enum {
SIMULATE_USER_ACTIVITY,
ACTIVE_CHANGED,
THROTTLE_CHANGED,
+ SHOW_MESSAGE,
LAST_SIGNAL
};
@@ -1223,6 +1224,52 @@ listener_get_active_time (GSListener *listener,
}
static DBusHandlerResult
+listener_show_message (GSListener *listener,
+ DBusConnection *connection,
+ DBusMessage *message)
+{
+ DBusMessageIter iter;
+ DBusMessage *reply;
+ DBusError error;
+
+ reply = dbus_message_new_method_return (message);
+
+ dbus_message_iter_init_append (reply, &iter);
+
+ if (reply == NULL) {
+ g_error ("No memory");
+ }
+
+ if (listener->priv->active) {
+ char *summary;
+ char *body;
+ char *icon;
+
+ /* if we're not active we ignore the request */
+
+ dbus_error_init (&error);
+ if (! dbus_message_get_args (message, &error,
+ DBUS_TYPE_STRING, &summary,
+ DBUS_TYPE_STRING, &body,
+ DBUS_TYPE_STRING, &icon,
+ DBUS_TYPE_INVALID)) {
+ raise_syntax (connection, message, "ShowMessage");
+ return DBUS_HANDLER_RESULT_HANDLED;
+ }
+
+ g_signal_emit (listener, signals [SHOW_MESSAGE], 0, summary, body, icon);
+ }
+
+ if (! dbus_connection_send (connection, reply, NULL)) {
+ g_error ("No memory");
+ }
+
+ dbus_message_unref (reply);
+
+ return DBUS_HANDLER_RESULT_HANDLED;
+}
+
+static DBusHandlerResult
do_introspect (DBusConnection *connection,
DBusMessage *message,
dbus_bool_t local_interface)
@@ -1278,6 +1325,11 @@ do_introspect (DBusConnection *connection,
" <method name=\"SetActive\">\n"
" <arg name=\"value\" direction=\"in\" type=\"b\"/>\n"
" </method>\n"
+ " <method name=\"ShowMessage\">\n"
+ " <arg name=\"summary\" direction=\"in\" type=\"s\"/>\n"
+ " <arg name=\"body\" direction=\"in\" type=\"s\"/>\n"
+ " <arg name=\"icon\" direction=\"in\" type=\"s\"/>\n"
+ " </method>\n"
" <signal name=\"ActiveChanged\">\n"
" <arg name=\"new_value\" type=\"b\"/>\n"
" </signal>\n"
@@ -1362,6 +1414,9 @@ listener_dbus_handle_session_message (DBusConnection *connection,
if (dbus_message_is_method_call (message, GS_LISTENER_SERVICE, "GetActiveTime")) {
return listener_get_active_time (listener, connection, message);
}
+ if (dbus_message_is_method_call (message, GS_LISTENER_SERVICE, "ShowMessage")) {
+ return listener_show_message (listener, connection, message);
+ }
if (dbus_message_is_method_call (message, GS_LISTENER_SERVICE, "SimulateUserActivity")) {
g_signal_emit (listener, signals [SIMULATE_USER_ACTIVITY], 0);
return DBUS_HANDLER_RESULT_HANDLED;
@@ -1796,6 +1851,19 @@ gs_listener_class_init (GSListenerClass *klass)
G_TYPE_NONE,
1,
G_TYPE_BOOLEAN);
+ signals [SHOW_MESSAGE] =
+ g_signal_new ("show-message",
+ G_TYPE_FROM_CLASS (object_class),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (GSListenerClass, show_message),
+ NULL,
+ NULL,
+ gs_marshal_VOID__STRING_STRING_STRING,
+ G_TYPE_NONE,
+ 3,
+ G_TYPE_STRING,
+ G_TYPE_STRING,
+ G_TYPE_STRING);
g_object_class_install_property (object_class,
PROP_ACTIVE,
diff --git a/src/gs-listener-dbus.h b/src/gs-listener-dbus.h
index a788e40..c57f367 100644
--- a/src/gs-listener-dbus.h
+++ b/src/gs-listener-dbus.h
@@ -52,6 +52,10 @@ typedef struct
gboolean active);
void (* throttle_changed) (GSListener *listener,
gboolean throttled);
+ void (* show_message) (GSListener *listener,
+ const char *summary,
+ const char *body,
+ const char *icon);
} GSListenerClass;
diff --git a/src/gs-manager.c b/src/gs-manager.c
index bb0ddf6..1609f83 100644
--- a/src/gs-manager.c
+++ b/src/gs-manager.c
@@ -1174,6 +1174,23 @@ find_window_at_pointer (GSManager *manager)
return window;
}
+void
+gs_manager_show_message (GSManager *manager,
+ const char *summary,
+ const char *body,
+ const char *icon)
+{
+ GSWindow *window;
+
+ g_return_if_fail (GS_IS_MANAGER (manager));
+
+ /* Find the GSWindow that contains the pointer */
+ window = find_window_at_pointer (manager);
+ gs_window_show_message (window, summary, body, icon);
+
+ gs_manager_request_unlock (manager);
+}
+
static gboolean
manager_maybe_grab_window (GSManager *manager,
GSWindow *window)
diff --git a/src/gs-manager.h b/src/gs-manager.h
index b0493ab..3a3e349 100644
--- a/src/gs-manager.h
+++ b/src/gs-manager.h
@@ -95,6 +95,10 @@ void gs_manager_set_themes (GSManager *manager,
GSList *themes);
void gs_manager_set_mode (GSManager *manager,
GSSaverMode mode);
+void gs_manager_show_message (GSManager *manager,
+ const char *summary,
+ const char *body,
+ const char *icon);
gboolean gs_manager_request_unlock (GSManager *manager);
void gs_manager_cancel_unlock_request (GSManager *manager);
diff --git a/src/gs-marshal.list b/src/gs-marshal.list
index 228ba92..9a4d620 100644
--- a/src/gs-marshal.list
+++ b/src/gs-marshal.list
@@ -1,3 +1,4 @@
BOOLEAN:VOID
BOOLEAN:INT
BOOLEAN:BOOLEAN
+VOID:STRING,STRING,STRING
diff --git a/src/gs-monitor.c b/src/gs-monitor.c
index 0fd4402..640ee74 100644
--- a/src/gs-monitor.c
+++ b/src/gs-monitor.c
@@ -220,6 +220,19 @@ listener_cycle_cb (GSListener *listener,
gs_manager_cycle (monitor->priv->manager);
}
+static void
+listener_show_message_cb (GSListener *listener,
+ const char *summary,
+ const char *body,
+ const char *icon,
+ GSMonitor *monitor)
+{
+ gs_manager_show_message (monitor->priv->manager,
+ summary,
+ body,
+ icon);
+}
+
static gboolean
listener_active_changed_cb (GSListener *listener,
gboolean active,
@@ -334,6 +347,7 @@ disconnect_listener_signals (GSMonitor *monitor)
g_signal_handlers_disconnect_by_func (monitor->priv->listener, listener_active_changed_cb, monitor);
g_signal_handlers_disconnect_by_func (monitor->priv->listener, listener_throttle_changed_cb, monitor);
g_signal_handlers_disconnect_by_func (monitor->priv->listener, listener_simulate_user_activity_cb, monitor);
+ g_signal_handlers_disconnect_by_func (monitor->priv->listener, listener_show_message_cb, monitor);
}
static void
@@ -351,6 +365,8 @@ connect_listener_signals (GSMonitor *monitor)
G_CALLBACK (listener_throttle_changed_cb), monitor);
g_signal_connect (monitor->priv->listener, "simulate-user-activity",
G_CALLBACK (listener_simulate_user_activity_cb), monitor);
+ g_signal_connect (monitor->priv->listener, "show-message",
+ G_CALLBACK (listener_show_message_cb), monitor);
}
static void
diff --git a/src/gs-window-x11.c b/src/gs-window-x11.c
index 2a74e10..5e0ebe5 100644
--- a/src/gs-window-x11.c
+++ b/src/gs-window-x11.c
@@ -52,6 +52,7 @@ enum {
};
#define MAX_QUEUED_EVENTS 16
+#define INFO_BAR_SECONDS 30
#define GS_WINDOW_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GS_TYPE_WINDOW, GSWindowPrivate))
@@ -77,6 +78,8 @@ struct GSWindowPrivate
GtkWidget *lock_box;
GtkWidget *lock_socket;
GtkWidget *keyboard_socket;
+ GtkWidget *info_bar;
+ GtkWidget *info_content;
GdkPixmap *background_pixmap;
@@ -87,6 +90,7 @@ struct GSWindowPrivate
guint dialog_response_signal_id;
guint watchdog_timer_id;
+ guint info_bar_timer_id;
gint lock_pid;
gint lock_watch_id;
@@ -896,6 +900,96 @@ gs_window_real_show (GtkWidget *widget)
gdk_window_add_filter (NULL, (GdkFilterFunc)xevent_filter, window);
}
+static void
+set_info_text_and_icon (GSWindow *window,
+ const char *icon_stock_id,
+ const char *primary_text,
+ const char *secondary_text)
+{
+ GtkWidget *content_area;
+ GtkWidget *hbox_content;
+ GtkWidget *image;
+ GtkWidget *vbox;
+ gchar *primary_markup;
+ gchar *secondary_markup;
+ GtkWidget *primary_label;
+ GtkWidget *secondary_label;
+
+ hbox_content = gtk_hbox_new (FALSE, 8);
+ gtk_widget_show (hbox_content);
+
+ image = gtk_image_new_from_stock (icon_stock_id, GTK_ICON_SIZE_DIALOG);
+ gtk_widget_show (image);
+ gtk_box_pack_start (GTK_BOX (hbox_content), image, FALSE, FALSE, 0);
+ gtk_misc_set_alignment (GTK_MISC (image), 0.5, 0);
+
+ vbox = gtk_vbox_new (FALSE, 6);
+ gtk_widget_show (vbox);
+ gtk_box_pack_start (GTK_BOX (hbox_content), vbox, FALSE, FALSE, 0);
+
+ primary_markup = g_strdup_printf ("<b>%s</b>", primary_text);
+ primary_label = gtk_label_new (primary_markup);
+ g_free (primary_markup);
+ gtk_widget_show (primary_label);
+ gtk_box_pack_start (GTK_BOX (vbox), primary_label, TRUE, TRUE, 0);
+ gtk_label_set_use_markup (GTK_LABEL (primary_label), TRUE);
+ gtk_label_set_line_wrap (GTK_LABEL (primary_label), TRUE);
+ gtk_misc_set_alignment (GTK_MISC (primary_label), 0, 0.5);
+
+ if (secondary_text != NULL) {
+ secondary_markup = g_strdup_printf ("<small>%s</small>",
+ secondary_text);
+ secondary_label = gtk_label_new (secondary_markup);
+ g_free (secondary_markup);
+ gtk_widget_show (secondary_label);
+ gtk_box_pack_start (GTK_BOX (vbox), secondary_label, TRUE, TRUE, 0);
+ gtk_label_set_use_markup (GTK_LABEL (secondary_label), TRUE);
+ gtk_label_set_line_wrap (GTK_LABEL (secondary_label), TRUE);
+ gtk_misc_set_alignment (GTK_MISC (secondary_label), 0, 0.5);
+ }
+
+ /* remove old content */
+ content_area = gtk_info_bar_get_content_area (GTK_INFO_BAR (window->priv->info_bar));
+ if (window->priv->info_content != NULL) {
+ gtk_container_remove (GTK_CONTAINER (content_area), window->priv->info_content);
+ }
+ gtk_box_pack_start (GTK_BOX (content_area),
+ hbox_content,
+ TRUE, FALSE, 0);
+ window->priv->info_content = hbox_content;
+}
+
+static gboolean
+info_bar_timeout (GSWindow *window)
+{
+ window->priv->info_bar_timer_id = 0;
+ gtk_widget_hide (window->priv->info_bar);
+ return FALSE;
+}
+
+void
+gs_window_show_message (GSWindow *window,
+ const char *summary,
+ const char *body,
+ const char *icon)
+{
+ g_return_if_fail (GS_IS_WINDOW (window));
+
+ set_info_text_and_icon (window,
+ icon,
+ summary,
+ body);
+ gtk_widget_show (window->priv->info_bar);
+
+ if (window->priv->info_bar_timer_id > 0) {
+ g_source_remove (window->priv->info_bar_timer_id);
+ }
+
+ window->priv->info_bar_timer_id = g_timeout_add_seconds (INFO_BAR_SECONDS,
+ (GSourceFunc)info_bar_timeout,
+ window);
+}
+
void
gs_window_show (GSWindow *window)
{
@@ -2218,6 +2312,14 @@ gs_window_class_init (GSWindowClass *klass)
}
static void
+create_info_bar (GSWindow *window)
+{
+ window->priv->info_bar = gtk_info_bar_new ();
+ gtk_widget_set_no_show_all (window->priv->info_bar, TRUE);
+ gtk_box_pack_end (GTK_BOX (window->priv->vbox), window->priv->info_bar, FALSE, FALSE, 0);
+}
+
+static void
gs_window_init (GSWindow *window)
{
window->priv = GS_WINDOW_GET_PRIVATE (window);
@@ -2258,6 +2360,7 @@ gs_window_init (GSWindow *window)
window->priv->drawing_area = gtk_drawing_area_new ();
gtk_widget_show (window->priv->drawing_area);
gtk_box_pack_start (GTK_BOX (window->priv->vbox), window->priv->drawing_area, TRUE, TRUE, 0);
+ create_info_bar (window);
force_no_pixmap_background (window->priv->drawing_area);
}
@@ -2290,6 +2393,10 @@ gs_window_finalize (GObject *object)
g_free (window->priv->logout_command);
g_free (window->priv->keyboard_command);
+ if (window->priv->info_bar_timer_id > 0) {
+ g_source_remove (window->priv->info_bar_timer_id);
+ }
+
remove_watchdog_timer (window);
remove_popup_dialog_idle (window);
diff --git a/src/gs-window.h b/src/gs-window.h
index 6440a6d..fc2287e 100644
--- a/src/gs-window.h
+++ b/src/gs-window.h
@@ -83,6 +83,10 @@ void gs_window_set_logout_command (GSWindow *window,
const char *command);
void gs_window_set_status_message (GSWindow *window,
const char *status_message);
+void gs_window_show_message (GSWindow *window,
+ const char *summary,
+ const char *body,
+ const char *icon);
void gs_window_request_unlock (GSWindow *window);
void gs_window_cancel_unlock_request (GSWindow *window);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]