Make Notifications a GObject

So it can emit signals.
This commit is contained in:
Ian Douglas Scott 2021-09-07 18:33:11 -07:00
parent 7430b965e1
commit 069e1a24f9
2 changed files with 43 additions and 22 deletions

View file

@ -6,7 +6,7 @@ use gtk4::{
subclass::prelude::*, subclass::prelude::*,
}; };
use once_cell::unsync::OnceCell; use once_cell::unsync::OnceCell;
use std::{cell::Cell, sync::Arc}; use std::cell::Cell;
use crate::notifications::Notifications; use crate::notifications::Notifications;
use crate::status_notifier_watcher; use crate::status_notifier_watcher;
@ -14,7 +14,7 @@ use crate::window::PanelWindow;
#[derive(Default)] #[derive(Default)]
pub struct PanelAppInner { pub struct PanelAppInner {
notifications: OnceCell<Arc<Notifications>>, notifications: OnceCell<Notifications>,
activated: Cell<bool>, activated: Cell<bool>,
} }

View file

@ -2,14 +2,9 @@ use gtk4::{
gio, gio,
glib::{self, clone}, glib::{self, clone},
prelude::*, prelude::*,
subclass::prelude::*,
}; };
use std::{ use std::{borrow::Cow, cell::Cell, collections::HashMap, fmt, num::NonZeroU32};
borrow::Cow,
collections::HashMap,
fmt,
num::NonZeroU32,
sync::{Arc, Mutex},
};
static NOTIFICATIONS_XML: &str = " static NOTIFICATIONS_XML: &str = "
<node name='/org/freedesktop/Notifications'> <node name='/org/freedesktop/Notifications'>
@ -54,10 +49,33 @@ static NOTIFICATIONS_XML: &str = "
</node> </node>
"; ";
pub struct Notifications { pub struct NotificationsInner {
next_id: Mutex<NonZeroU32>, next_id: Cell<NonZeroU32>,
} }
#[glib::object_subclass]
impl ObjectSubclass for NotificationsInner {
const NAME: &'static str = "S76Notifications";
type ParentType = glib::Object;
type Type = Notifications;
fn new() -> Self {
Self {
next_id: Cell::new(NonZeroU32::new(1).unwrap()),
}
}
}
impl ObjectImpl for NotificationsInner {}
glib::wrapper! {
pub struct Notifications(ObjectSubclass<NotificationsInner>);
}
// XXX hack: https://github.com/gtk-rs/gtk-rs-core/issues/263
unsafe impl Send for Notifications {}
unsafe impl Sync for Notifications {}
struct Hints(HashMap<String, glib::Variant>); struct Hints(HashMap<String, glib::Variant>);
#[allow(dead_code)] #[allow(dead_code)]
@ -146,10 +164,8 @@ impl glib::FromVariant for Hints {
} }
impl Notifications { impl Notifications {
pub fn new() -> Arc<Self> { pub fn new() -> Self {
let notifications = Arc::new(Notifications { let notifications = glib::Object::new::<Self>(&[]).unwrap();
next_id: Mutex::new(NonZeroU32::new(1).unwrap()),
});
gio::bus_own_name( gio::bus_own_name(
gio::BusType::Session, gio::BusType::Session,
@ -163,11 +179,16 @@ impl Notifications {
notifications notifications
} }
fn inner(&self) -> &NotificationsInner {
NotificationsInner::from_instance(self)
}
fn next_id(&self) -> NonZeroU32 { fn next_id(&self) -> NonZeroU32 {
let mut next_id = self.next_id.lock().unwrap(); let next_id = &self.inner().next_id;
let id = *next_id; let id = next_id.get();
*next_id = NonZeroU32::new(u32::from(*next_id).wrapping_add(1)) next_id.set(
.unwrap_or(NonZeroU32::new(1).unwrap()); NonZeroU32::new(u32::from(id).wrapping_add(1)).unwrap_or(NonZeroU32::new(1).unwrap()),
);
id id
} }
@ -205,9 +226,9 @@ impl Notifications {
fn close_notification(&self, _id: u32) {} fn close_notification(&self, _id: u32) {}
fn bus_acquired(self: &Arc<Self>, _connection: gio::DBusConnection, _name: &str) {} fn bus_acquired(&self, _connection: gio::DBusConnection, _name: &str) {}
fn name_acquired(self: &Arc<Self>, connection: gio::DBusConnection, _name: &str) { fn name_acquired(&self, connection: gio::DBusConnection, _name: &str) {
let introspection_data = gio::DBusNodeInfo::for_xml(NOTIFICATIONS_XML).unwrap(); let introspection_data = gio::DBusNodeInfo::for_xml(NOTIFICATIONS_XML).unwrap();
let interface_info = introspection_data let interface_info = introspection_data
.lookup_interface("org.freedesktop.Notifications") .lookup_interface("org.freedesktop.Notifications")
@ -267,5 +288,5 @@ impl Notifications {
} }
} }
fn name_lost(self: &Arc<Self>, _connection: Option<gio::DBusConnection>, _name: &str) {} fn name_lost(&self, _connection: Option<gio::DBusConnection>, _name: &str) {}
} }