393 lines
14 KiB
Diff
393 lines
14 KiB
Diff
|
From e91c0b36899a05dfb9c95e60ccd0e28313b68e75 Mon Sep 17 00:00:00 2001
|
||
|
From: =?UTF-8?q?Guido=20G=C3=BCnther?= <agx@sigxcpu.org>
|
||
|
Date: Sun, 6 Dec 2020 18:46:37 +0100
|
||
|
Subject: [PATCH 1/2] notification: Fix phosh_notification_expires docstring
|
||
|
|
||
|
---
|
||
|
src/notifications/notification.c | 4 ++--
|
||
|
1 file changed, 2 insertions(+), 2 deletions(-)
|
||
|
|
||
|
diff --git a/src/notifications/notification.c b/src/notifications/notification.c
|
||
|
index 19ce8be8..8e5239f7 100644
|
||
|
--- a/src/notifications/notification.c
|
||
|
+++ b/src/notifications/notification.c
|
||
|
@@ -934,8 +934,8 @@ expired (gpointer data)
|
||
|
*
|
||
|
* Set @self to expire after @timeout (from this call)
|
||
|
*
|
||
|
- * Note doesn't close the notification, for that call
|
||
|
- * phosh_notification_close() is response to #PhoshNotification::expired
|
||
|
+ * Note: doesn't close the notification, for that call
|
||
|
+ * phosh_notification_close() in response to #PhoshNotification::expired
|
||
|
*/
|
||
|
void
|
||
|
phosh_notification_expires (PhoshNotification *self,
|
||
|
--
|
||
|
2.26.2
|
||
|
|
||
|
|
||
|
From 8abbd9ae7efa99553a40f24da02d5e2d9c1de9f1 Mon Sep 17 00:00:00 2001
|
||
|
From: =?UTF-8?q?Guido=20G=C3=BCnther?= <agx@sigxcpu.org>
|
||
|
Date: Sun, 6 Dec 2020 16:41:31 +0100
|
||
|
Subject: [PATCH 2/2] notification-content: Add close button on hover
|
||
|
MIME-Version: 1.0
|
||
|
Content-Type: text/plain; charset=UTF-8
|
||
|
Content-Transfer-Encoding: 8bit
|
||
|
|
||
|
This adds a close button when hovering with the mouse. Modeled like
|
||
|
176354a2e0b27b2508213a22bc0029eeda4dde93.
|
||
|
|
||
|
Signed-off-by: Guido Günther <guido.gunther@puri.sm>
|
||
|
---
|
||
|
src/notifications/notification-content.c | 91 ++++++++++++
|
||
|
src/style.css | 7 +
|
||
|
src/ui/notification-content.ui | 180 ++++++++++++++---------
|
||
|
3 files changed, 212 insertions(+), 66 deletions(-)
|
||
|
|
||
|
diff --git a/src/notifications/notification-content.c b/src/notifications/notification-content.c
|
||
|
index 3ea3dd2a..6cfa8ccc 100644
|
||
|
--- a/src/notifications/notification-content.c
|
||
|
+++ b/src/notifications/notification-content.c
|
||
|
@@ -35,12 +35,92 @@ struct _PhoshNotificationContent {
|
||
|
GtkWidget *lbl_body;
|
||
|
GtkWidget *img_image;
|
||
|
GtkWidget *box_actions;
|
||
|
+ GtkWidget *revealer;
|
||
|
+ GtkWidget *ev_box;
|
||
|
+
|
||
|
+ gboolean hovering;
|
||
|
};
|
||
|
typedef struct _PhoshNotificationContent PhoshNotificationContent;
|
||
|
|
||
|
|
||
|
G_DEFINE_TYPE (PhoshNotificationContent, phosh_notification_content, GTK_TYPE_LIST_BOX_ROW)
|
||
|
|
||
|
+static void
|
||
|
+closed_cb (PhoshNotificationContent *self)
|
||
|
+{
|
||
|
+ phosh_notification_close (self->notification, PHOSH_NOTIFICATION_REASON_CLOSED);
|
||
|
+}
|
||
|
+
|
||
|
+static void
|
||
|
+set_hovering (PhoshNotificationContent *self,
|
||
|
+ gboolean hovering)
|
||
|
+{
|
||
|
+ if (hovering == self->hovering)
|
||
|
+ return;
|
||
|
+
|
||
|
+ self->hovering = hovering;
|
||
|
+
|
||
|
+ /* Revealer won't animate if not mapped, show it preemptively */
|
||
|
+ if (hovering)
|
||
|
+ gtk_widget_show (self->revealer);
|
||
|
+
|
||
|
+ gtk_revealer_set_reveal_child (GTK_REVEALER (self->revealer), hovering);
|
||
|
+}
|
||
|
+
|
||
|
+
|
||
|
+static gboolean
|
||
|
+on_enter_notify_event (PhoshNotificationContent *self,
|
||
|
+ GdkEventCrossing *event,
|
||
|
+ GtkEventBox *box)
|
||
|
+{
|
||
|
+ if (event->window != gtk_widget_get_window (self->ev_box) ||
|
||
|
+ event->detail == GDK_NOTIFY_INFERIOR)
|
||
|
+ return GDK_EVENT_PROPAGATE;
|
||
|
+
|
||
|
+ /* enter-notify never happens on touch, so we don't need to check it */
|
||
|
+ set_hovering (self, TRUE);
|
||
|
+
|
||
|
+ return GDK_EVENT_PROPAGATE;
|
||
|
+}
|
||
|
+
|
||
|
+
|
||
|
+static gboolean
|
||
|
+on_leave_notify_event (PhoshNotificationContent *self,
|
||
|
+ GdkEventCrossing *event,
|
||
|
+ GtkEventBox *box)
|
||
|
+{
|
||
|
+ if (event->window != gtk_widget_get_window (self->ev_box) ||
|
||
|
+ event->detail == GDK_NOTIFY_INFERIOR)
|
||
|
+ return GDK_EVENT_PROPAGATE;
|
||
|
+
|
||
|
+ set_hovering (self, FALSE);
|
||
|
+
|
||
|
+ return GDK_EVENT_PROPAGATE;
|
||
|
+}
|
||
|
+
|
||
|
+
|
||
|
+static gboolean
|
||
|
+on_motion_notify_event (PhoshNotificationContent *self,
|
||
|
+ GdkEventMotion *event,
|
||
|
+ GtkEventBox *box)
|
||
|
+{
|
||
|
+ GdkDevice *source_device = gdk_event_get_source_device ((GdkEvent *) event);
|
||
|
+ GdkInputSource input_source = gdk_device_get_source (source_device);
|
||
|
+
|
||
|
+ if (input_source != GDK_SOURCE_TOUCHSCREEN)
|
||
|
+ set_hovering (self, TRUE);
|
||
|
+
|
||
|
+ return GDK_EVENT_PROPAGATE;
|
||
|
+}
|
||
|
+
|
||
|
+
|
||
|
+static void
|
||
|
+phosh_notification_content_unmap (GtkWidget *widget)
|
||
|
+{
|
||
|
+ set_hovering (PHOSH_NOTIFICATION_CONTENT (widget), FALSE);
|
||
|
+
|
||
|
+ GTK_WIDGET_CLASS (phosh_notification_content_parent_class)->unmap (widget);
|
||
|
+}
|
||
|
|
||
|
static gboolean
|
||
|
set_image (GBinding *binding,
|
||
|
@@ -248,6 +328,8 @@ phosh_notification_content_class_init (PhoshNotificationContentClass *klass)
|
||
|
object_class->set_property = phosh_notification_content_set_property;
|
||
|
object_class->get_property = phosh_notification_content_get_property;
|
||
|
|
||
|
+ widget_class->unmap = phosh_notification_content_unmap;
|
||
|
+
|
||
|
/**
|
||
|
* PhoshNotificationContent:notification:
|
||
|
* @self: the #PhoshNotificationContent
|
||
|
@@ -271,6 +353,12 @@ phosh_notification_content_class_init (PhoshNotificationContentClass *klass)
|
||
|
gtk_widget_class_bind_template_child (widget_class, PhoshNotificationContent, lbl_body);
|
||
|
gtk_widget_class_bind_template_child (widget_class, PhoshNotificationContent, img_image);
|
||
|
gtk_widget_class_bind_template_child (widget_class, PhoshNotificationContent, box_actions);
|
||
|
+ gtk_widget_class_bind_template_child (widget_class, PhoshNotificationContent, revealer);
|
||
|
+ gtk_widget_class_bind_template_child (widget_class, PhoshNotificationContent, ev_box);
|
||
|
+ gtk_widget_class_bind_template_callback (widget_class, closed_cb);
|
||
|
+ gtk_widget_class_bind_template_callback (widget_class, on_enter_notify_event);
|
||
|
+ gtk_widget_class_bind_template_callback (widget_class, on_leave_notify_event);
|
||
|
+ gtk_widget_class_bind_template_callback (widget_class, on_motion_notify_event);
|
||
|
|
||
|
gtk_widget_class_set_css_name (widget_class, "phosh-notification-content");
|
||
|
}
|
||
|
@@ -312,6 +400,9 @@ phosh_notification_content_init (PhoshNotificationContent *self)
|
||
|
G_ACTION_GROUP (map));
|
||
|
|
||
|
gtk_widget_init_template (GTK_WIDGET (self));
|
||
|
+
|
||
|
+ gtk_widget_add_events (GTK_WIDGET (self->ev_box),
|
||
|
+ GDK_ENTER_NOTIFY | GDK_LEAVE_NOTIFY | GDK_MOTION_NOTIFY);
|
||
|
}
|
||
|
|
||
|
|
||
|
diff --git a/src/style.css b/src/style.css
|
||
|
index c279e946..4b0d6021 100644
|
||
|
--- a/src/style.css
|
||
|
+++ b/src/style.css
|
||
|
@@ -273,6 +273,13 @@ phosh-notification-content {
|
||
|
background: transparent;
|
||
|
}
|
||
|
|
||
|
+phosh-notification-content .close-button {
|
||
|
+ border-radius: 50%;
|
||
|
+ min-width: 24px;
|
||
|
+ min-height: 24px;
|
||
|
+ padding: 0;
|
||
|
+}
|
||
|
+
|
||
|
phosh-notification-content .message-area {
|
||
|
padding: 12px;
|
||
|
}
|
||
|
diff --git a/src/ui/notification-content.ui b/src/ui/notification-content.ui
|
||
|
index 0abe6249..db1b86e5 100644
|
||
|
--- a/src/ui/notification-content.ui
|
||
|
+++ b/src/ui/notification-content.ui
|
||
|
@@ -4,77 +4,125 @@
|
||
|
<template class="PhoshNotificationContent" parent="GtkListBoxRow">
|
||
|
<property name="visible">True</property>
|
||
|
<child>
|
||
|
- <object class="GtkBox">
|
||
|
- <property name="visible">True</property>
|
||
|
- <property name="valign">start</property>
|
||
|
- <property name="orientation">vertical</property>
|
||
|
- <child>
|
||
|
- <object class="GtkBox">
|
||
|
+
|
||
|
+ <object class="GtkEventBox" id="ev_box">
|
||
|
+ <property name="visible">True</property>
|
||
|
+ <property name="valign">fill</property>
|
||
|
+ <property name="above-child">True</property>
|
||
|
+ <signal name="enter-notify-event" handler="on_enter_notify_event" swapped="true"/>
|
||
|
+ <signal name="leave-notify-event" handler="on_leave_notify_event" swapped="true"/>
|
||
|
+ <signal name="motion-notify-event" handler="on_motion_notify_event" swapped="true"/>
|
||
|
+ <child>
|
||
|
+ <object class="GtkOverlay">
|
||
|
<property name="visible">True</property>
|
||
|
- <property name="spacing">12</property>
|
||
|
+ <property name="can_focus">False</property>
|
||
|
<child>
|
||
|
- <object class="GtkImage" id="img_image">
|
||
|
- <property name="visible">True</property>
|
||
|
- <property name="halign">start</property>
|
||
|
- <property name="valign">start</property>
|
||
|
- <property name="pixel_size">32</property>
|
||
|
- <property name="icon_name">dialog-information</property>
|
||
|
- <style>
|
||
|
- <class name="notification-image"/>
|
||
|
- </style>
|
||
|
- </object>
|
||
|
- </child>
|
||
|
- <child>
|
||
|
- <object class="GtkBox">
|
||
|
- <property name="visible">True</property>
|
||
|
- <property name="valign">center</property>
|
||
|
- <property name="orientation">vertical</property>
|
||
|
- <property name="spacing">2</property>
|
||
|
- <child>
|
||
|
- <object class="GtkLabel" id="lbl_summary">
|
||
|
+ <object class="GtkBox">
|
||
|
+ <property name="visible">True</property>
|
||
|
+ <property name="valign">start</property>
|
||
|
+ <property name="orientation">vertical</property>
|
||
|
+ <child>
|
||
|
+ <object class="GtkBox">
|
||
|
<property name="visible">True</property>
|
||
|
- <property name="label">Title</property>
|
||
|
- <property name="justify">center</property>
|
||
|
- <property name="ellipsize">end</property>
|
||
|
- <property name="single_line_mode">True</property>
|
||
|
- <property name="xalign">0</property>
|
||
|
- <attributes>
|
||
|
- <attribute name="weight" value="bold"/>
|
||
|
- </attributes>
|
||
|
- </object>
|
||
|
- </child>
|
||
|
- <child>
|
||
|
- <object class="GtkLabel" id="lbl_body">
|
||
|
+ <property name="spacing">12</property>
|
||
|
+ <child>
|
||
|
+ <object class="GtkImage" id="img_image">
|
||
|
+ <property name="visible">True</property>
|
||
|
+ <property name="halign">start</property>
|
||
|
+ <property name="valign">start</property>
|
||
|
+ <property name="pixel_size">32</property>
|
||
|
+ <property name="icon_name">dialog-information</property>
|
||
|
+ <style>
|
||
|
+ <class name="notification-image"/>
|
||
|
+ </style>
|
||
|
+ </object>
|
||
|
+ </child>
|
||
|
+ <child>
|
||
|
+ <object class="GtkBox">
|
||
|
+ <property name="visible">True</property>
|
||
|
+ <property name="valign">center</property>
|
||
|
+ <property name="orientation">vertical</property>
|
||
|
+ <property name="spacing">2</property>
|
||
|
+ <child>
|
||
|
+ <object class="GtkLabel" id="lbl_summary">
|
||
|
+ <property name="visible">True</property>
|
||
|
+ <property name="label">Title</property>
|
||
|
+ <property name="justify">center</property>
|
||
|
+ <property name="ellipsize">end</property>
|
||
|
+ <property name="single_line_mode">True</property>
|
||
|
+ <property name="xalign">0</property>
|
||
|
+ <attributes>
|
||
|
+ <attribute name="weight" value="bold"/>
|
||
|
+ </attributes>
|
||
|
+ </object>
|
||
|
+ </child>
|
||
|
+ <child>
|
||
|
+ <object class="GtkLabel" id="lbl_body">
|
||
|
+ <property name="visible">True</property>
|
||
|
+ <property name="valign">center</property>
|
||
|
+ <property name="label">Message</property>
|
||
|
+ <property name="use-markup">True</property>
|
||
|
+ <property name="justify">left</property>
|
||
|
+ <property name="wrap">True</property>
|
||
|
+ <property name="wrap-mode">word-char</property>
|
||
|
+ <property name="ellipsize">end</property>
|
||
|
+ <property name="lines">3</property>
|
||
|
+ <property name="xalign">0</property>
|
||
|
+ </object>
|
||
|
+ </child>
|
||
|
+ </object>
|
||
|
+ </child>
|
||
|
+ <style>
|
||
|
+ <class name="message-area"/>
|
||
|
+ </style>
|
||
|
+ </object>
|
||
|
+ </child>
|
||
|
+ <child>
|
||
|
+ <object class="GtkBox" id="box_actions">
|
||
|
<property name="visible">True</property>
|
||
|
- <property name="valign">center</property>
|
||
|
- <property name="label">Message</property>
|
||
|
- <property name="use-markup">True</property>
|
||
|
- <property name="justify">left</property>
|
||
|
- <property name="wrap">True</property>
|
||
|
- <property name="wrap-mode">word-char</property>
|
||
|
- <property name="ellipsize">end</property>
|
||
|
- <property name="lines">3</property>
|
||
|
- <property name="xalign">0</property>
|
||
|
- </object>
|
||
|
- </child>
|
||
|
- </object>
|
||
|
+ <property name="orientation">vertical</property>
|
||
|
+ <property name="valign">end</property>
|
||
|
+ <style>
|
||
|
+ <class name="linked"/>
|
||
|
+ <class name="actions-area"/>
|
||
|
+ </style>
|
||
|
+ </object>
|
||
|
+ </child>
|
||
|
+ </object>
|
||
|
</child>
|
||
|
- <style>
|
||
|
- <class name="message-area"/>
|
||
|
- </style>
|
||
|
- </object>
|
||
|
- </child>
|
||
|
- <child>
|
||
|
- <object class="GtkBox" id="box_actions">
|
||
|
- <property name="visible">True</property>
|
||
|
- <property name="orientation">vertical</property>
|
||
|
- <property name="valign">end</property>
|
||
|
- <style>
|
||
|
- <class name="linked"/>
|
||
|
- <class name="actions-area"/>
|
||
|
- </style>
|
||
|
- </object>
|
||
|
- </child>
|
||
|
+ <child type="overlay">
|
||
|
+ <object class="GtkRevealer" id="revealer">
|
||
|
+ <property name="transition-type">crossfade</property>
|
||
|
+ <property name="visible" bind-source="revealer" bind-property="child-revealed" bind-flags="sync-create"/>
|
||
|
+ <property name="halign">end</property>
|
||
|
+ <property name="valign">start</property>
|
||
|
+ <property name="margin">12</property>
|
||
|
+ <child>
|
||
|
+ <object class="GtkButton" id="btn_close">
|
||
|
+ <property name="visible">True</property>
|
||
|
+ <property name="can_focus">False</property>
|
||
|
+ <property name="receives_default">False</property>
|
||
|
+ <signal name="clicked" handler="closed_cb" swapped="true"/>
|
||
|
+ <child>
|
||
|
+ <object class="GtkImage" id="img_close_icon">
|
||
|
+ <property name="visible">True</property>
|
||
|
+ <property name="can_focus">False</property>
|
||
|
+ <property name="icon_name">window-close-symbolic</property>
|
||
|
+ </object>
|
||
|
+ </child>
|
||
|
+ <style>
|
||
|
+ <class name="close-button"/>
|
||
|
+ <class name="osd"/>
|
||
|
+ </style>
|
||
|
+ </object>
|
||
|
+ </child>
|
||
|
+ </object>
|
||
|
+ <packing>
|
||
|
+ <property name="pass_through">True</property>
|
||
|
+ </packing>
|
||
|
+ </child>
|
||
|
+ </object>
|
||
|
+ </child>
|
||
|
</object>
|
||
|
</child>
|
||
|
</template>
|
||
|
--
|
||
|
2.26.2
|
||
|
|