[nautilus] operations: show a notification when operation finishes



commit 2d5a7e6dfd5ab3e94ef298b1a38618b5ec7ee1a6
Author: Carlos Soriano <csoriano gnome org>
Date:   Tue Jul 14 19:46:21 2015 +0200

    operations: show a notification when operation finishes
    
    When the operations popover is not visible, we have to give
    feedback to the user about if an operation finished.
    For that, show a in-app notification in case the operation popover
    is closed and a operation finishes. Also, to link the notification
    with the operation button, make the button pulse for a second.
    
    The code interaction between nautilus-file-operations and nautilus-progress-info
    start to get crowed. At some point, the best we can do is delegate all the
    progress UI part to nautilus-progress-info, providing all the needed information
    like the CommonJob, TransferInfo and SourceInfo; so we avoid the current
    odd interaction between them. This is a future work.

 libnautilus-private/nautilus-file-operations.c |   21 +++
 libnautilus-private/nautilus-progress-info.c   |   25 ++++
 libnautilus-private/nautilus-progress-info.h   |    4 +
 src/nautilus-toolbar.c                         |   50 +++++++-
 src/nautilus-window.c                          |  171 ++++++++++++++++++------
 src/nautilus-window.h                          |    4 +
 src/nautilus-window.ui                         |   69 ++++++++++
 7 files changed, 300 insertions(+), 44 deletions(-)
---
diff --git a/libnautilus-private/nautilus-file-operations.c b/libnautilus-private/nautilus-file-operations.c
index 38bdf39..4b5b853 100644
--- a/libnautilus-private/nautilus-file-operations.c
+++ b/libnautilus-private/nautilus-file-operations.c
@@ -4910,6 +4910,9 @@ nautilus_file_operations_copy_file (GFile *source_file,
        job->done_callback_data = done_callback_data;
        job->files = g_list_append (NULL, g_object_ref (source_file));
        job->destination = g_object_ref (target_dir);
+        /* Need to indicate the destination for the operation notification open
+         * button. */
+        nautilus_progress_info_set_destination (((CommonJob *)job)->progress, target_dir);
        job->target_name = g_strdup (new_name);
        job->debuting_files = g_hash_table_new_full (g_file_hash, (GEqualFunc)g_file_equal, g_object_unref, 
NULL);
 
@@ -4947,6 +4950,9 @@ nautilus_file_operations_copy (GList *files,
        job->done_callback_data = done_callback_data;
        job->files = g_list_copy_deep (files, (GCopyFunc) g_object_ref, NULL);
        job->destination = g_object_ref (target_dir);
+        /* Need to indicate the destination for the operation notification open
+         * button. */
+        nautilus_progress_info_set_destination (((CommonJob *)job)->progress, target_dir);
        if (relative_item_points != NULL &&
            relative_item_points->len > 0) {
                job->icon_positions =
@@ -5485,6 +5491,9 @@ nautilus_file_operations_move (GList *files,
        job->done_callback_data = done_callback_data;
        job->files = g_list_copy_deep (files, (GCopyFunc) g_object_ref, NULL);
        job->destination = g_object_ref (target_dir);
+        /* Need to indicate the destination for the operation notification open
+         * button. */
+        nautilus_progress_info_set_destination (((CommonJob *)job)->progress, target_dir);
        if (relative_item_points != NULL &&
            relative_item_points->len > 0) {
                job->icon_positions =
@@ -5811,6 +5820,9 @@ nautilus_file_operations_link (GList *files,
        job->done_callback_data = done_callback_data;
        job->files = g_list_copy_deep (files, (GCopyFunc) g_object_ref, NULL);
        job->destination = g_object_ref (target_dir);
+        /* Need to indicate the destination for the operation notification open
+         * button. */
+        nautilus_progress_info_set_destination (((CommonJob *)job)->progress, target_dir);
        if (relative_item_points != NULL &&
            relative_item_points->len > 0) {
                job->icon_positions =
@@ -5846,12 +5858,19 @@ nautilus_file_operations_duplicate (GList *files,
                                    gpointer done_callback_data)
 {
        CopyMoveJob *job;
+        GFile *parent;
 
        job = op_job_new (CopyMoveJob, parent_window);
        job->done_callback = done_callback;
        job->done_callback_data = done_callback_data;
        job->files = g_list_copy_deep (files, (GCopyFunc) g_object_ref, NULL);
        job->destination = NULL;
+        /* Duplicate files doesn't have a destination, since is the same as source.
+         * For that set as destination the source parent folder */
+        parent = g_file_get_parent (files->data);
+        /* Need to indicate the destination for the operation notification open
+         * button. */
+        nautilus_progress_info_set_destination (((CommonJob *)job)->progress, parent);
        if (relative_item_points != NULL &&
            relative_item_points->len > 0) {
                job->icon_positions =
@@ -5877,6 +5896,8 @@ nautilus_file_operations_duplicate (GList *files,
                           NULL, /* destroy notify */
                           0,
                           job->common.cancellable);
+
+        g_object_unref (parent);
 }
 
 static gboolean
diff --git a/libnautilus-private/nautilus-progress-info.c b/libnautilus-private/nautilus-progress-info.c
index ddec248..2498899 100644
--- a/libnautilus-private/nautilus-progress-info.c
+++ b/libnautilus-private/nautilus-progress-info.c
@@ -68,6 +68,8 @@ struct _NautilusProgressInfo
        gboolean cancel_at_idle;
        gboolean changed_at_idle;
        gboolean progress_at_idle;
+
+        GFile *destination;
 };
 
 struct _NautilusProgressInfoClass
@@ -92,6 +94,7 @@ nautilus_progress_info_finalize (GObject *object)
        g_object_unref (info->cancellable);
         g_cancellable_cancel (info->details_in_thread_cancellable);
         g_clear_object (&info->details_in_thread_cancellable);
+        g_clear_object (&info->destination);
        
        if (G_OBJECT_CLASS (nautilus_progress_info_parent_class)->finalize) {
                (*G_OBJECT_CLASS (nautilus_progress_info_parent_class)->finalize) (object);
@@ -687,3 +690,25 @@ nautilus_progress_info_get_elapsed_time (NautilusProgressInfo *info)
 
         return elapsed_time;
 }
+
+void
+nautilus_progress_info_set_destination (NautilusProgressInfo *info,
+                                        GFile                *file)
+{
+        G_LOCK (progress_info);
+        g_clear_object (&info->destination);
+        info->destination = g_object_ref (file);
+        G_UNLOCK (progress_info);
+}
+
+GFile *
+nautilus_progress_info_get_destination (NautilusProgressInfo *info)
+{
+        GFile *destination;
+
+        G_LOCK (progress_info);
+        destination = g_object_ref (info->destination);
+        G_UNLOCK (progress_info);
+
+        return destination;
+}
diff --git a/libnautilus-private/nautilus-progress-info.h b/libnautilus-private/nautilus-progress-info.h
index 44b812c..cf0daeb 100644
--- a/libnautilus-private/nautilus-progress-info.h
+++ b/libnautilus-private/nautilus-progress-info.h
@@ -86,6 +86,10 @@ void          nautilus_progress_info_set_elapsed_time (NautilusProgressInfo *inf
                                                        gdouble               time);
 gdouble       nautilus_progress_info_get_elapsed_time (NautilusProgressInfo *info);
 
+void nautilus_progress_info_set_destination (NautilusProgressInfo *info,
+                                             GFile                *file);
+GFile *nautilus_progress_info_get_destination (NautilusProgressInfo *info);
+
 
 
 #endif /* NAUTILUS_PROGRESS_INFO_H */
diff --git a/src/nautilus-toolbar.c b/src/nautilus-toolbar.c
index 0b85ed0..b4934fe 100644
--- a/src/nautilus-toolbar.c
+++ b/src/nautilus-toolbar.c
@@ -61,6 +61,7 @@ struct _NautilusToolbarPrivate {
        guint popup_timeout_id;
         guint start_operations_timeout_id;
         guint remove_finished_operations_timeout_id;
+        guint operations_button_attention_timeout_id;
 
        GtkWidget *operations_button;
        GtkWidget *view_button;
@@ -492,6 +493,19 @@ schedule_remove_finished_operations (NautilusToolbar *self)
         }
 }
 
+static gboolean
+remove_operations_button_attention_style (NautilusToolbar *self)
+{
+        GtkStyleContext *style_context;
+
+        style_context = gtk_widget_get_style_context (self->priv->operations_button);
+        gtk_style_context_remove_class (style_context,
+                                        "suggested-action");
+        self->priv->operations_button_attention_timeout_id = 0;
+
+        return G_SOURCE_REMOVE;
+}
+
 static void
 on_progress_info_cancelled (NautilusToolbar *self)
 {
@@ -510,14 +524,40 @@ on_progress_info_progress_changed (NautilusToolbar *self)
 }
 
 static void
-on_progress_info_finished (NautilusToolbar *self)
+on_progress_info_finished (NautilusToolbar      *self,
+                           NautilusProgressInfo *info)
 {
+        GtkStyleContext *style_context;
+        gchar *main_label;
+        GFile *folder_to_open;
+
         /* Update the pie chart progress */
         gtk_widget_queue_draw (self->priv->operations_icon);
 
         if (!gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (self->priv->operations_button))) {
                 schedule_remove_finished_operations (self);
         }
+
+        folder_to_open = nautilus_progress_info_get_destination (info);
+        /* If destination is null, don't show a notification. This happens when the
+         * operation is a trash operation, which we already show a diferent kind of
+         * notification */
+        if (!gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (self->priv->operations_button)) &&
+            folder_to_open != NULL) {
+                style_context = gtk_widget_get_style_context (self->priv->operations_button);
+                gtk_style_context_add_class (style_context,
+                                             "suggested-action");
+                self->priv->operations_button_attention_timeout_id = g_timeout_add_seconds (1,
+                                                                                            (GSourceFunc) 
remove_operations_button_attention_style,
+                                                                                            self);
+                main_label = nautilus_progress_info_get_status (info);
+                nautilus_window_show_operation_notification (self->priv->window,
+                                                             main_label,
+                                                             folder_to_open);
+                g_free (main_label);
+        }
+
+        g_clear_object (&folder_to_open);
 }
 
 static void
@@ -594,9 +634,6 @@ on_progress_info_started_timeout (NautilusToolbar *self)
                 return G_SOURCE_CONTINUE;
         } else {
                 self->priv->start_operations_timeout_id = 0;
-                if (!gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (self->priv->operations_button))) {
-                        schedule_remove_finished_operations (self);
-                }
                 return G_SOURCE_REMOVE;
         }
 }
@@ -827,6 +864,11 @@ nautilus_toolbar_dispose (GObject *obj)
         unschedule_remove_finished_operations (self);
         unschedule_operations_start (self);
 
+        if (self->priv->operations_button_attention_timeout_id != 0) {
+                g_source_remove (self->priv->operations_button_attention_timeout_id);
+                self->priv->operations_button_attention_timeout_id = 0;
+        }
+
         g_signal_handlers_disconnect_by_data (self->priv->progress_manager, self);
         g_clear_object (&self->priv->progress_manager);
 
diff --git a/src/nautilus-window.c b/src/nautilus-window.c
index d315316..748e91c 100644
--- a/src/nautilus-window.c
+++ b/src/nautilus-window.c
@@ -120,6 +120,12 @@ struct _NautilusWindowPrivate {
         GtkWidget *notification_delete_close;
         GtkWidget *notification_delete_undo;
        guint notification_delete_timeout_id;
+        GtkWidget *notification_operation;
+        GtkWidget *notification_operation_label;
+        GtkWidget *notification_operation_close;
+        GtkWidget *notification_operation_open;
+       guint notification_operation_timeout_id;
+        GFile *folder_to_open;
 
         /* Toolbar */
         GtkWidget *toolbar;
@@ -1488,30 +1494,39 @@ nautilus_window_ensure_location_entry (NautilusWindow *window)
 }
 
 static void
-nautilus_window_on_notification_delete_undo_clicked (GtkWidget  *notification,
-                                                     gpointer    user_data)
+remove_notifications (NautilusWindow *window)
 {
-       NautilusWindow *window;
-
-       window = NAUTILUS_WINDOW (user_data);
+        GtkRevealerTransitionType transition_type;
 
-       if (window->priv->notification_delete_timeout_id != 0) {
-               g_source_remove (window->priv->notification_delete_timeout_id);
-               window->priv->notification_delete_timeout_id = 0;
+        /* Hide it inmediatily so we can animate the new notification. */
+        transition_type = gtk_revealer_get_transition_type (GTK_REVEALER 
(window->priv->notification_delete));
+        gtk_revealer_set_transition_type (GTK_REVEALER (window->priv->notification_delete),
+                                          GTK_REVEALER_TRANSITION_TYPE_NONE);
+        gtk_revealer_set_reveal_child (GTK_REVEALER (window->priv->notification_delete),
+                                       FALSE);
+        gtk_revealer_set_transition_type (GTK_REVEALER (window->priv->notification_delete),
+                                          transition_type);
+        if (window->priv->notification_delete_timeout_id != 0) {
+                g_source_remove (window->priv->notification_delete_timeout_id);
+                window->priv->notification_delete_timeout_id = 0;
        }
 
-       gtk_revealer_set_reveal_child (GTK_REVEALER (window->priv->notification_delete), FALSE);
-       nautilus_file_undo_manager_undo (GTK_WINDOW (window));
+        transition_type = gtk_revealer_get_transition_type (GTK_REVEALER 
(window->priv->notification_operation));
+        gtk_revealer_set_transition_type (GTK_REVEALER (window->priv->notification_operation),
+                                          GTK_REVEALER_TRANSITION_TYPE_NONE);
+        gtk_revealer_set_reveal_child (GTK_REVEALER (window->priv->notification_operation),
+                                       FALSE);
+        gtk_revealer_set_transition_type (GTK_REVEALER (window->priv->notification_operation),
+                                          transition_type);
+        if (window->priv->notification_operation_timeout_id != 0) {
+                g_source_remove (window->priv->notification_operation_timeout_id);
+                window->priv->notification_operation_timeout_id = 0;
+       }
 }
 
 static void
-nautilus_window_on_notification_delete_close_clicked (GtkWidget  *notification,
-                                                      gpointer    user_data)
+hide_notification_delete (NautilusWindow *window)
 {
-       NautilusWindow *window;
-
-       window = NAUTILUS_WINDOW (user_data);
-
        if (window->priv->notification_delete_timeout_id != 0) {
                g_source_remove (window->priv->notification_delete_timeout_id);
                window->priv->notification_delete_timeout_id = 0;
@@ -1520,19 +1535,26 @@ nautilus_window_on_notification_delete_close_clicked (GtkWidget  *notification,
        gtk_revealer_set_reveal_child (GTK_REVEALER (window->priv->notification_delete), FALSE);
 }
 
-static gboolean
-nautilus_window_on_notification_delete_timeout (gpointer user_data)
+static void
+nautilus_window_on_notification_delete_undo_clicked (GtkWidget      *notification,
+                                                     NautilusWindow *window)
 {
-       NautilusWindow *window;
+        hide_notification_delete (window);
 
-       window = NAUTILUS_WINDOW (user_data);
+       nautilus_file_undo_manager_undo (GTK_WINDOW (window));
+}
 
-       if (window->priv->notification_delete_timeout_id != 0) {
-               g_source_remove (window->priv->notification_delete_timeout_id);
-               window->priv->notification_delete_timeout_id = 0;
-       }
+static void
+nautilus_window_on_notification_delete_close_clicked (GtkWidget      *notification,
+                                                      NautilusWindow *window)
+{
+        hide_notification_delete (window);
+}
 
-       gtk_revealer_set_reveal_child (GTK_REVEALER (window->priv->notification_delete), FALSE);
+static gboolean
+nautilus_window_on_notification_delete_timeout (NautilusWindow *window)
+{
+        hide_notification_delete (window);
 
        return FALSE;
 }
@@ -1566,20 +1588,9 @@ nautilus_window_on_undo_changed (NautilusFileUndoManager *manager,
 {
        NautilusFileUndoInfo *undo_info;
        NautilusFileUndoManagerState state;
-       int transition_durantion;
        gchar *label;
        GList *files;
 
-       /* Hide it inmediatily so we can animate the new notification. */
-       transition_durantion = gtk_revealer_get_transition_duration (GTK_REVEALER 
(window->priv->notification_delete));
-       gtk_revealer_set_transition_duration (GTK_REVEALER (window->priv->notification_delete), 0);
-       gtk_revealer_set_reveal_child (GTK_REVEALER (window->priv->notification_delete), FALSE);
-       gtk_revealer_set_transition_duration (GTK_REVEALER (window->priv->notification_delete), 
transition_durantion);
-       if (window->priv->notification_delete_timeout_id != 0) {
-               g_source_remove (window->priv->notification_delete_timeout_id);
-               window->priv->notification_delete_timeout_id = 0;
-       }
-
        undo_info = nautilus_file_undo_manager_get_action ();
        state = nautilus_file_undo_manager_get_state ();
 
@@ -1597,7 +1608,7 @@ nautilus_window_on_undo_changed (NautilusFileUndoManager *manager,
                        gtk_label_set_markup (GTK_LABEL (window->priv->notification_delete_label), label);
                        gtk_revealer_set_reveal_child (GTK_REVEALER (window->priv->notification_delete), 
TRUE);
                        window->priv->notification_delete_timeout_id = g_timeout_add_seconds 
(NOTIFICATION_TIMEOUT,
-                                                                                             
nautilus_window_on_notification_delete_timeout,
+                                                                                             (GSourceFunc) 
nautilus_window_on_notification_delete_timeout,
                                                                                              window);
                        g_free (label);
                }
@@ -1606,6 +1617,74 @@ nautilus_window_on_undo_changed (NautilusFileUndoManager *manager,
 }
 
 static void
+hide_notification_operation (NautilusWindow *window)
+{
+       if (window->priv->notification_operation_timeout_id != 0) {
+               g_source_remove (window->priv->notification_operation_timeout_id);
+               window->priv->notification_operation_timeout_id = 0;
+       }
+
+       gtk_revealer_set_reveal_child (GTK_REVEALER (window->priv->notification_operation), FALSE);
+        g_clear_object (&window->priv->folder_to_open);
+}
+
+static void
+on_notification_operation_open_clicked (GtkWidget      *notification,
+                                        NautilusWindow *window)
+{
+        nautilus_window_slot_open_location (window->priv->active_slot,
+                                            window->priv->folder_to_open,
+                                            0);
+        hide_notification_operation (window);
+}
+
+static void
+on_notification_operation_close_clicked (GtkWidget      *notification,
+                                         NautilusWindow *window)
+{
+        hide_notification_operation (window);
+}
+
+static gboolean
+on_notification_operation_timeout (NautilusWindow *window)
+{
+        hide_notification_operation (window);
+
+       return FALSE;
+}
+
+void
+nautilus_window_show_operation_notification (NautilusWindow *window,
+                                             gchar          *main_label,
+                                             GFile          *folder_to_open)
+{
+        gchar *button_label;
+        gchar *folder_name;
+        NautilusFile *folder;
+
+       if (gtk_window_has_toplevel_focus (GTK_WINDOW (window)) &&
+            !NAUTILUS_IS_DESKTOP_WINDOW (window)) {
+                remove_notifications (window);
+                window->priv->folder_to_open = g_object_ref (folder_to_open);
+                folder = nautilus_file_get (folder_to_open);
+                folder_name = nautilus_file_get_display_name (folder);
+                button_label = g_strdup_printf (_("Open %s"), folder_name);
+               gtk_label_set_text (GTK_LABEL (window->priv->notification_operation_label),
+                                    main_label);
+                gtk_button_set_label (GTK_BUTTON (window->priv->notification_operation_open),
+                                      button_label);
+               gtk_revealer_set_reveal_child (GTK_REVEALER (window->priv->notification_operation), TRUE);
+               window->priv->notification_operation_timeout_id = g_timeout_add_seconds (NOTIFICATION_TIMEOUT,
+                                                                                         (GSourceFunc) 
on_notification_operation_timeout,
+                                                                                         window);
+              g_object_unref (folder);
+              g_free (folder_name);
+              g_free (button_label);
+       }
+
+}
+
+static void
 path_bar_location_changed_callback (GtkWidget      *widget,
                                    GFile          *location,
                                    NautilusWindow *window)
@@ -2104,9 +2183,14 @@ nautilus_window_finalize (GObject *object)
                window->priv->sidebar_width_handler_id = 0;
        }
 
-       if (window->priv->notification_delete_timeout_id != 0) {
-               g_source_remove (window->priv->notification_delete_timeout_id);
-               window->priv->notification_delete_timeout_id = 0;
+        if (window->priv->notification_delete_timeout_id != 0) {
+                g_source_remove (window->priv->notification_delete_timeout_id);
+                window->priv->notification_delete_timeout_id = 0;
+       }
+
+        if (window->priv->notification_operation_timeout_id != 0) {
+                g_source_remove (window->priv->notification_operation_timeout_id);
+                window->priv->notification_operation_timeout_id = 0;
        }
 
        g_signal_handlers_disconnect_by_func (nautilus_file_undo_manager_get (),
@@ -2508,6 +2592,10 @@ nautilus_window_class_init (NautilusWindowClass *class)
        gtk_widget_class_bind_template_child_private (wclass, NautilusWindow, notification_delete_label);
        gtk_widget_class_bind_template_child_private (wclass, NautilusWindow, notification_delete_undo);
        gtk_widget_class_bind_template_child_private (wclass, NautilusWindow, notification_delete_close);
+       gtk_widget_class_bind_template_child_private (wclass, NautilusWindow, notification_operation);
+       gtk_widget_class_bind_template_child_private (wclass, NautilusWindow, notification_operation_label);
+       gtk_widget_class_bind_template_child_private (wclass, NautilusWindow, notification_operation_open);
+       gtk_widget_class_bind_template_child_private (wclass, NautilusWindow, notification_operation_close);
 
        properties[PROP_DISABLE_CHROME] =
                g_param_spec_boolean ("disable-chrome",
@@ -2558,6 +2646,9 @@ nautilus_window_class_init (NautilusWindowClass *class)
                                  G_CALLBACK(use_extra_mouse_buttons_changed),
                                  NULL);
 
+        gtk_widget_class_bind_template_callback (wclass, on_notification_operation_open_clicked);
+        gtk_widget_class_bind_template_callback (wclass, on_notification_operation_close_clicked);
+
        g_object_class_install_properties (oclass, NUM_PROPERTIES, properties);
 }
 
diff --git a/src/nautilus-window.h b/src/nautilus-window.h
index 1612145..4b16bf7 100644
--- a/src/nautilus-window.h
+++ b/src/nautilus-window.h
@@ -146,4 +146,8 @@ void nautilus_window_sync_allow_stop       (NautilusWindow *window,
                                            NautilusWindowSlot *slot);
 void nautilus_window_sync_title            (NautilusWindow *window,
                                            NautilusWindowSlot *slot);
+
+void nautilus_window_show_operation_notification (NautilusWindow *window,
+                                                  gchar          *main_label,
+                                                  GFile          *folder_to_open);
 #endif
diff --git a/src/nautilus-window.ui b/src/nautilus-window.ui
index 5205ced..2a8c439 100644
--- a/src/nautilus-window.ui
+++ b/src/nautilus-window.ui
@@ -123,6 +123,75 @@
                     </child>
                   </object>
                 </child>
+                <child type="overlay">
+                  <object class="GtkRevealer" id="notification_operation">
+                    <property name="visible">True</property>
+                    <property name="can_focus">False</property>
+                    <property name="halign">center</property>
+                    <property name="valign">start</property>
+                    <property name="transition_duration">100</property>
+                    <child>
+                      <object class="GtkFrame">
+                        <property name="visible">True</property>
+                        <property name="can_focus">False</property>
+                        <child>
+                          <object class="GtkBox">
+                            <property name="visible">True</property>
+                            <property name="can_focus">False</property>
+                            <property name="margin_start">12</property>
+                            <property name="margin_end">4</property>
+                            <child>
+                              <object class="GtkLabel" id="notification_operation_label">
+                                <property name="visible">True</property>
+                                <property name="can_focus">False</property>
+                                <property name="max_width_chars">50</property>
+                                <property name="ellipsize">middle</property>
+                                <property name="margin_end">30</property>
+                              </object>
+                            </child>
+                            <child>
+                              <object class="GtkButton" id="notification_operation_open">
+                                <property name="visible">True</property>
+                                <property name="can_focus">True</property>
+                                <property name="receives_default">True</property>
+                                <property name="no_show_all">True</property>
+                                <property name="margin_end">6</property>
+                                <signal name="clicked" handler="on_notification_operation_open_clicked" 
object="NautilusWindow" swapped="no"/>
+                                <style>
+                                  <class name="text-button"/>
+                                </style>
+                              </object>
+                            </child>
+                            <child>
+                              <object class="GtkButton" id="notification_operation_close">
+                                <property name="visible">True</property>
+                                <property name="can_focus">True</property>
+                                <property name="receives_default">True</property>
+                                <property name="relief">none</property>
+                                <property name="focus_on_click">False</property>
+                                <signal name="clicked" handler="on_notification_operation_close_clicked" 
object="NautilusWindow" swapped="no"/>
+                                <child>
+                                  <object class="GtkImage">
+                                    <property name="visible">True</property>
+                                    <property name="can_focus">False</property>
+                                    <property name="icon_name">window-close-symbolic</property>
+                                    <property name="icon_size">2</property>
+                                  </object>
+                                </child>
+                                <style>
+                                  <class name="image-button"/>
+                                </style>
+                              </object>
+                            </child>
+                          </object>
+                        </child>
+                        <style>
+                          <class name="app-notification"/>
+                        </style>
+                      </object>
+                    </child>
+                  </object>
+                </child>
               </object>
             </child>
           </object>


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]