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