[libadwaita/wip/exalm/toast-timeout] toast: Allow changing timeout




commit 859992b23da87f156830b122d0c377c4e2d2b518
Author: Alexander Mikhaylenko <alexm gnome org>
Date:   Tue Nov 16 15:36:08 2021 +0500

    toast: Allow changing timeout
    
    Fixes https://gitlab.gnome.org/GNOME/libadwaita/-/issues/326

 src/adw-toast-widget.c | 10 +++---
 src/adw-toast.c        | 85 +++++++++++++++++++++++++++++++++++++++++++++++---
 src/adw-toast.h        |  6 ++++
 tests/test-toast.c     | 26 +++++++++++++++
 4 files changed, 117 insertions(+), 10 deletions(-)
---
diff --git a/src/adw-toast-widget.c b/src/adw-toast-widget.c
index 4fdc78b6..b04f0d59 100644
--- a/src/adw-toast-widget.c
+++ b/src/adw-toast-widget.c
@@ -10,8 +10,6 @@
 
 #include "adw-macros-private.h"
 
-#define TOAST_DURATION 5000
-
 struct _AdwToastWidget {
   GtkWidget parent_instance;
 
@@ -51,11 +49,11 @@ timeout_cb (AdwToastWidget *self)
 static void
 start_timeout (AdwToastWidget *self)
 {
-  if (!self->hide_timeout_id)
+  guint timeout = adw_toast_get_timeout (self->toast);
+
+  if (!self->hide_timeout_id && timeout)
     self->hide_timeout_id =
-      g_timeout_add (TOAST_DURATION,
-                     G_SOURCE_FUNC (timeout_cb),
-                     self);
+      g_timeout_add (timeout * 1000, G_SOURCE_FUNC (timeout_cb), self);
 }
 
 static void
diff --git a/src/adw-toast.c b/src/adw-toast.c
index 8ab7dfa5..82927be2 100644
--- a/src/adw-toast.c
+++ b/src/adw-toast.c
@@ -34,10 +34,11 @@
  * adw_toast_overlay_add_toast (overlay, adw_toast_new (_("Simple Toast"));
  * ```
  *
- * Toasts always have a close button and a timeout. In both cases, they emit the
+ * Toasts always have a close button. They emit the
  * [signal@Adw.Toast::dismissed] signal when disappearing.
  *
- * [property@Adw.Toast:priority] determines how the toast behaves if another
+ * [property@Adw.Toast:timeout] determines how long the toast stays on screen,
+ * while  [property@Adw.Toast:priority] determines how it behaves if another
  * toast is already being displayed.
  *
  * ## Actions
@@ -135,6 +136,7 @@ struct _AdwToast {
   char *action_name;
   GVariant *action_target;
   AdwToastPriority priority;
+  guint timeout;
 
   gboolean added;
 };
@@ -146,6 +148,7 @@ enum {
   PROP_ACTION_NAME,
   PROP_ACTION_TARGET,
   PROP_PRIORITY,
+  PROP_TIMEOUT,
   LAST_PROP,
 };
 
@@ -203,6 +206,9 @@ adw_toast_get_property (GObject    *object,
   case PROP_PRIORITY:
     g_value_set_enum (value, adw_toast_get_priority (self));
     break;
+  case PROP_TIMEOUT:
+    g_value_set_uint (value, adw_toast_get_timeout (self));
+    break;
   default:
     G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
   }
@@ -232,6 +238,9 @@ adw_toast_set_property (GObject      *object,
   case PROP_PRIORITY:
     adw_toast_set_priority (self, g_value_get_enum (value));
     break;
+  case PROP_TIMEOUT:
+    adw_toast_set_timeout (self, g_value_get_uint (value));
+    break;
   default:
     G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
   }
@@ -340,6 +349,26 @@ adw_toast_class_init (AdwToastClass *klass)
                        ADW_TOAST_PRIORITY_NORMAL,
                        G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY);
 
+  /**
+   * AdwToast:timeout: (attributes org.gtk.Property.get=adw_toast_get_timeout 
org.gtk.Property.set=adw_toast_set_timeout)
+   *
+   * The timeout of the toast, in seconds.
+   *
+   * If timeout is 0, the toast is displayed indefinitely until manually
+   * dismissed.
+   *
+   * Toasts cannot disappear while being hovered, pressed (on touchscreen), or
+   * have keyboard focus inside them.
+   *
+   * Since: 1.0
+   */
+  props[PROP_TIMEOUT] =
+    g_param_spec_uint ("timeout",
+                       "Timeout",
+                       "The timeout of the toast, in seconds",
+                       0, G_MAXUINT, 5,
+                       G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY);
+
   g_object_class_install_properties (object_class, LAST_PROP, props);
 
   /**
@@ -363,6 +392,7 @@ adw_toast_init (AdwToast *self)
 {
   self->title = g_strdup ("");
   self->priority = ADW_TOAST_PRIORITY_NORMAL;
+  self->timeout = 5;
 
   g_signal_connect (self, "dismissed", G_CALLBACK (dismissed_cb), self);
 }
@@ -641,7 +671,7 @@ adw_toast_set_detailed_action_name (AdwToast   *self,
  * adw_toast_get_priority: (attributes org.gtk.Method.get_property=priority)
  * @self: a `AdwToast`
  *
- * Gets the toast priority.
+ * Gets priority for @self.
  *
  * Returns: the priority
  *
@@ -660,7 +690,7 @@ adw_toast_get_priority (AdwToast *self)
  * @self: a `AdwToast`
  * @priority: the priority
  *
- * Sets the toast priority.
+ * Sets priority for @self.
  *
  * Priority controls how the toast behaves when another toast is already
  * being displayed.
@@ -688,6 +718,53 @@ adw_toast_set_priority (AdwToast         *self,
   g_object_notify_by_pspec (G_OBJECT (self), props[PROP_PRIORITY]);
 }
 
+/**
+ * adw_toast_get_timeout: (attributes org.gtk.Method.get_property=timeout)
+ * @self: a `AdwToast`
+ *
+ * Gets timeout for @self.
+ *
+ * Returns: the timeout
+ *
+ * Since: 1.0
+ */
+guint
+adw_toast_get_timeout (AdwToast *self)
+{
+  g_return_val_if_fail (ADW_IS_TOAST (self), 0);
+
+  return self->timeout;
+}
+
+/**
+ * adw_toast_set_timeout: (attributes org.gtk.Method.set_property=timeout)
+ * @self: a `AdwToast`
+ * @timeout: the timeout
+ *
+ * Sets timeout for @self.
+ *
+ * If @timeout is 0, the toast is displayed indefinitely until manually
+ * dismissed.
+ *
+ * Toasts cannot disappear while being hovered, pressed (on touchscreen), or
+ * have keyboard focus inside them.
+ *
+ * Since: 1.0
+ */
+void
+adw_toast_set_timeout (AdwToast *self,
+                       guint     timeout)
+{
+  g_return_if_fail (ADW_IS_TOAST (self));
+
+  if (self->timeout == timeout)
+    return;
+
+  self->timeout = timeout;
+
+  g_object_notify_by_pspec (G_OBJECT (self), props[PROP_TIMEOUT]);
+}
+
 /**
  * adw_toast_dismiss:
  * @self: a `AdwToast`
diff --git a/src/adw-toast.h b/src/adw-toast.h
index 4111a088..a6adfe39 100644
--- a/src/adw-toast.h
+++ b/src/adw-toast.h
@@ -67,6 +67,12 @@ ADW_AVAILABLE_IN_ALL
 void             adw_toast_set_priority (AdwToast         *self,
                                          AdwToastPriority  priority);
 
+ADW_AVAILABLE_IN_ALL
+guint adw_toast_get_timeout (AdwToast *self);
+ADW_AVAILABLE_IN_ALL
+void  adw_toast_set_timeout (AdwToast *self,
+                             guint     timeout);
+
 ADW_AVAILABLE_IN_ALL
 void adw_toast_dismiss (AdwToast *self);
 
diff --git a/tests/test-toast.c b/tests/test-toast.c
index 0ce6364b..ad293e88 100644
--- a/tests/test-toast.c
+++ b/tests/test-toast.c
@@ -170,6 +170,31 @@ test_adw_toast_priority (void)
   g_assert_finalize_object (toast);
 }
 
+static void
+test_adw_toast_timeout (void)
+{
+  AdwToast *toast = adw_toast_new ("Title");
+  guint timeout;
+
+  g_assert_nonnull (toast);
+
+  notified = 0;
+  g_signal_connect (toast, "notify::timeout", G_CALLBACK (notify_cb), NULL);
+
+  g_object_get (toast, "timeout", &timeout, NULL);
+  g_assert_cmpint (timeout, ==, 5);
+
+  adw_toast_set_timeout (toast, 10);
+  g_assert_cmpint (adw_toast_get_timeout (toast), ==, 10);
+  g_assert_cmpint (notified, ==, 1);
+
+  g_object_set (toast, "timeout", 5, NULL);
+  g_assert_cmpint (adw_toast_get_timeout (toast), ==, 5);
+  g_assert_cmpint (notified, ==, 2);
+
+  g_assert_finalize_object (toast);
+}
+
 static void
 test_adw_toast_dismiss (void)
 {
@@ -199,6 +224,7 @@ main (int   argc,
   g_test_add_func ("/Adwaita/Toast/action_target", test_adw_toast_action_target);
   g_test_add_func ("/Adwaita/Toast/detailed_action_name", test_adw_toast_detailed_action_name);
   g_test_add_func ("/Adwaita/Toast/priority", test_adw_toast_priority);
+  g_test_add_func ("/Adwaita/Toast/timeout", test_adw_toast_timeout);
   g_test_add_func ("/Adwaita/Toast/dismiss", test_adw_toast_dismiss);
 
   return g_test_run ();


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