pidgin/pidgin

f95b932717bb
Parents 7c639ab519a1
Children 530549d9d6aa
Implement PidginNotifiable on PidginNotificationList

Also pulled display-item out to it's own ui file.

There isn't much to do regarding styling right now as it looks like we're going to have to create our own indicator/notification widget as adwaita doesn't expose theirs and gtk doesn't have anything either. And there's no way to invert background/foreground via css, so that's that.

Testing Done:
Used the demo protocol plugin to trigger a bunch of notifications.

Reviewed at https://reviews.imfreedom.org/r/3155/
--- a/pidgin/pidginnotificationlist.c Tue May 07 22:57:09 2024 -0500
+++ b/pidgin/pidginnotificationlist.c Tue May 07 23:01:07 2024 -0500
@@ -26,10 +26,20 @@
#include "pidgin/pidginnotificationlist.h"
+#include "pidgin/pidginnotifiable.h"
#include "pidgin/pidginnotificationaddcontact.h"
#include "pidgin/pidginnotificationauthorizationrequest.h"
#include "pidgin/pidginnotificationconnectionerror.h"
+enum {
+ PROP_0,
+ N_PROPERTIES,
+ /* Overrides */
+ PROP_NEEDS_ATTENTION = N_PROPERTIES,
+ PROP_NOTIFICATION_COUNT,
+};
+/* There's no global properties because we only have overrides right now. */
+
struct _PidginNotificationList {
GtkBox parent;
@@ -37,9 +47,6 @@
GtkSingleSelection *selection_model;
};
-G_DEFINE_FINAL_TYPE(PidginNotificationList, pidgin_notification_list,
- GTK_TYPE_BOX)
-
/******************************************************************************
* Helpers
*****************************************************************************/
@@ -102,6 +109,24 @@
return row;
}
+static guint
+pidgin_notification_list_get_count(PidginNotificationList *list) {
+ g_return_val_if_fail(PIDGIN_IS_NOTIFICATION_LIST(list), 0);
+
+ return g_list_model_get_n_items(G_LIST_MODEL(list->selection_model));
+}
+
+static gboolean
+pidgin_notification_list_get_needs_attention(PidginNotificationList *list) {
+ guint count = 0;
+
+ g_return_val_if_fail(PIDGIN_IS_NOTIFICATION_LIST(list), FALSE);
+
+ count = g_list_model_get_n_items(G_LIST_MODEL(list->selection_model));
+
+ return (count > 0);
+}
+
/******************************************************************************
* Callbacks
*****************************************************************************/
@@ -113,12 +138,18 @@
gpointer data)
{
PidginNotificationList *list = data;
+ GObject *obj = G_OBJECT(list);
if(g_list_model_get_n_items(model) != 0) {
gtk_stack_set_visible_child_name(list->stack, "view");
} else {
gtk_stack_set_visible_child_name(list->stack, "placeholder");
}
+
+ g_object_freeze_notify(obj);
+ g_object_notify(obj, "needs-attention");
+ g_object_notify(obj, "notification-count");
+ g_object_thaw_notify(obj);
}
static void
@@ -158,8 +189,41 @@
}
/******************************************************************************
+ * PidginNotifiable Implementation
+ *****************************************************************************/
+static void
+pidgin_notification_list_notifiable_init(G_GNUC_UNUSED PidginNotifiableInterface *iface) {
+}
+
+/******************************************************************************
* GObject Implementation
*****************************************************************************/
+G_DEFINE_FINAL_TYPE_WITH_CODE(
+ PidginNotificationList,
+ pidgin_notification_list,
+ GTK_TYPE_BOX,
+ G_IMPLEMENT_INTERFACE(PIDGIN_TYPE_NOTIFIABLE, pidgin_notification_list_notifiable_init))
+
+static void
+pidgin_notification_list_get_property(GObject *obj, guint param_id,
+ GValue *value, GParamSpec *pspec)
+{
+ PidginNotificationList *list = PIDGIN_NOTIFICATION_LIST(obj);
+
+ switch(param_id) {
+ case PROP_NEEDS_ATTENTION:
+ g_value_set_boolean(value,
+ pidgin_notification_list_get_needs_attention(list));
+ break;
+ case PROP_NOTIFICATION_COUNT:
+ g_value_set_uint(value, pidgin_notification_list_get_count(list));
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID(obj, param_id, pspec);
+ break;
+ }
+}
+
static void
pidgin_notification_list_init(PidginNotificationList *list) {
GListModel *model = NULL;
@@ -176,8 +240,16 @@
static void
pidgin_notification_list_class_init(PidginNotificationListClass *klass) {
+ GObjectClass *obj_class = G_OBJECT_CLASS(klass);
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS(klass);
+ obj_class->get_property = pidgin_notification_list_get_property;
+
+ g_object_class_override_property(obj_class, PROP_NEEDS_ATTENTION,
+ "needs-attention");
+ g_object_class_override_property(obj_class, PROP_NOTIFICATION_COUNT,
+ "notification-count");
+
gtk_widget_class_set_template_from_resource(
widget_class,
"/im/pidgin/Pidgin3/notificationlist.ui"
--- a/pidgin/resources/Display/window.ui Tue May 07 22:57:09 2024 -0500
+++ b/pidgin/resources/Display/window.ui Tue May 07 23:01:07 2024 -0500
@@ -52,6 +52,12 @@
</child>
</object>
</property>
+ <binding name="needs-attention">
+ <lookup name="needs-attention">notification_list</lookup>
+ </binding>
+ <binding name="badge-number">
+ <lookup name="notification-count">notification_list</lookup>
+ </binding>
</object>
</child>
<child>
@@ -159,58 +165,7 @@
</property>
<property name="factory">
<object class="GtkBuilderListItemFactory">
- <property name="bytes">
-<![CDATA[
-<?xml version="1.0" encoding="UTF-8"?>
-<interface>
- <template class="GtkListItem">
- <property name="child">
- <object class="GtkTreeExpander" id="expander">
- <binding name="list-row">
- <lookup name="item">GtkListItem</lookup>
- </binding>
- <property name="child">
- <object class="GtkBox">
- <property name="orientation">horizontal</property>
- <property name="spacing">6</property>
- <child>
- <object class="GtkLabel">
- <property name="xalign">0</property>
- <property name="hexpand">0</property>
- <binding name="label">
- <lookup name="title" type="PidginDisplayItem">
- <lookup name="item">expander</lookup>
- </lookup>
- </binding>
- </object>
- </child>
- <child>
- <object class="GtkLabel">
- <style>
- <class name="accent"/>
- <class name="circular"/>
- </style>
- <property name="halign">end</property>
- <binding name="visible">
- <lookup name="needs-attention" type="PidginDisplayItem">
- <lookup name="item">expander</lookup>
- </lookup>
- </binding>
- <binding name="label">
- <lookup name="badge-number" type="PidginDisplayItem">
- <lookup name="item">expander</lookup>
- </lookup>
- </binding>
- </object>
- </child>
- </object>
- </property>
- </object>
- </property>
- </template>
-</interface>
-]]>
- </property>
+ <property name="resource">/im/pidgin/Pidgin3/display-item.ui</property>
</object>
</property>
</object>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/pidgin/resources/display-item.ui Tue May 07 23:01:07 2024 -0500
@@ -0,0 +1,48 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<interface>
+ <template class="GtkListItem">
+ <property name="child">
+ <object class="GtkTreeExpander" id="expander">
+ <binding name="list-row">
+ <lookup name="item">GtkListItem</lookup>
+ </binding>
+ <property name="child">
+ <object class="GtkBox">
+ <property name="orientation">horizontal</property>
+ <property name="spacing">6</property>
+ <child>
+ <object class="GtkLabel">
+ <property name="xalign">0</property>
+ <property name="hexpand">0</property>
+ <binding name="label">
+ <lookup name="title" type="PidginDisplayItem">
+ <lookup name="item">expander</lookup>
+ </lookup>
+ </binding>
+ </object>
+ </child>
+ <child>
+ <object class="GtkLabel">
+ <style>
+ <class name="accent"/>
+ <class name="circular"/>
+ </style>
+ <property name="halign">end</property>
+ <binding name="visible">
+ <lookup name="needs-attention" type="PidginDisplayItem">
+ <lookup name="item">expander</lookup>
+ </lookup>
+ </binding>
+ <binding name="label">
+ <lookup name="badge-number" type="PidginDisplayItem">
+ <lookup name="item">expander</lookup>
+ </lookup>
+ </binding>
+ </object>
+ </child>
+ </object>
+ </property>
+ </object>
+ </property>
+ </template>
+</interface>
--- a/pidgin/resources/pidgin.gresource.xml Tue May 07 22:57:09 2024 -0500
+++ b/pidgin/resources/pidgin.gresource.xml Tue May 07 23:01:07 2024 -0500
@@ -36,6 +36,7 @@
<file compressed="true" preprocess="xml-stripblanks">contactlist.ui</file>
<file compressed="true" preprocess="xml-stripblanks">contactlistitem.ui</file>
<file compressed="true" preprocess="xml-stripblanks">conversationmemberlistitem.ui</file>
+ <file compressed="true" preprocess="xml-stripblanks">display-item.ui</file>
<file compressed="true" preprocess="xml-stripblanks">infopane.ui</file>
<file compressed="true" preprocess="xml-stripblanks">notificationlist.ui</file>
<file compressed="true" preprocess="xml-stripblanks">presenceicon.ui</file>