Skip to content

Commit

Permalink
feat: show popup on active notifications applet output
Browse files Browse the repository at this point in the history
  • Loading branch information
wash2 committed Dec 18, 2023
1 parent 78f8a3f commit 64ea722
Show file tree
Hide file tree
Showing 6 changed files with 449 additions and 20 deletions.
3 changes: 3 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions cosmic-applet-notifications/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -36,4 +36,7 @@ i18n-embed = { version = "0.13.4", features = [
i18n-embed-fl = "0.6.4"
rust-embed = "6.3.0"
rust-embed-utils = "7.5.0"
cctk.workspace = true
cosmic-protocols.workspace = true
url = "2.4.0"
futures = "0.3.21"
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,4 @@ Icon=com.system76.CosmicAppletNotifications
NoDisplay=true
X-CosmicApplet=true
X-NotificationsApplet=true
X-HostWaylandDisplay=true
75 changes: 55 additions & 20 deletions cosmic-applet-notifications/src/main.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
mod localize;
mod subscriptions;
use cosmic::applet::token::subscription::{
activation_token_subscription, TokenRequest, TokenUpdate,
};
mod wayland_handler;
mod wayland_subscription;
use cosmic::applet::{menu_button, menu_control_padding, padded_control};
use cosmic::cctk::sctk::reexports::calloop;
use cosmic::cosmic_config::{config_subscription, Config, CosmicConfigEntry};
Expand All @@ -28,6 +27,7 @@ use std::collections::HashMap;
use std::path::PathBuf;
use tokio::sync::mpsc::Sender;
use tracing::info;
use wayland_subscription::{WaylandRequest, WaylandUpdate};

#[tokio::main(flavor = "current_thread")]
pub async fn main() -> cosmic::iced::Result {
Expand All @@ -42,18 +42,25 @@ pub async fn main() -> cosmic::iced::Result {

static DO_NOT_DISTURB: Lazy<id::Toggler> = Lazy::new(id::Toggler::unique);

#[derive(Debug, Clone, Copy)]
pub enum Popup {
NewNotifications,
UserActivated,
}

#[derive(Default)]
struct Notifications {
core: cosmic::app::Core,
config: NotificationsConfig,
config_helper: Option<Config>,
icon_name: String,
popup: Option<window::Id>,
popup: Option<(window::Id, Popup)>,
// notifications: Vec<Notification>,
timeline: Timeline,
dbus_sender: Option<Sender<subscriptions::dbus::Input>>,
cards: Vec<(id::Cards, Vec<Notification>, bool, String, String, String)>,
token_tx: Option<calloop::channel::Sender<TokenRequest>>,
wayland_tx: Option<calloop::channel::Sender<WaylandRequest>>,
on_active_output: bool,
}

impl Notifications {
Expand Down Expand Up @@ -93,8 +100,8 @@ enum Message {
Dismissed(u32),
ClearAll(String),
CardsToggled(String, bool),
Token(TokenUpdate),
OpenSettings,
WaylandUpdate(wayland_subscription::WaylandUpdate),
}

impl cosmic::Application for Notifications {
Expand Down Expand Up @@ -131,6 +138,7 @@ impl cosmic::Application for Notifications {
core,
config_helper: helper,
config,
on_active_output: false,
..Default::default()
};
_self.update_icon();
Expand Down Expand Up @@ -170,7 +178,7 @@ impl cosmic::Application for Notifications {
.map(|(_, now)| Message::Frame(now)),
subscriptions::dbus::proxy().map(Message::DbusEvent),
subscriptions::notifications::notifications().map(Message::NotificationEvent),
activation_token_subscription(0).map(Message::Token),
wayland_subscription::wayland_subscription(0).map(Message::WaylandUpdate),
])
}

Expand All @@ -183,11 +191,11 @@ impl cosmic::Application for Notifications {
self.timeline.now(now);
}
Message::TogglePopup => {
if let Some(p) = self.popup.take() {
if let Some((p, _popup_type)) = self.popup.take() {
return destroy_popup(p);
} else {
let new_id = window::Id::unique();
self.popup.replace(new_id);
self.popup.replace((new_id, Popup::UserActivated));

let mut popup_settings = self.core.applet.get_popup_settings(
window::Id::MAIN,
Expand Down Expand Up @@ -238,6 +246,25 @@ impl cosmic::Application for Notifications {
fl!("clear-all"),
));
}
// create new notification popup if none exists
if self.popup.is_none() {
let new_id = window::Id::unique();
self.popup.replace((new_id, Popup::NewNotifications));

let mut popup_settings = self.core.applet.get_popup_settings(
window::Id::MAIN,
new_id,
None,
None,
None,
);
popup_settings.positioner.size_limits = Limits::NONE
.min_width(1.0)
.max_width(444.0)
.min_height(100.0)
.max_height(900.0);
return get_popup(popup_settings);
}
}
Message::Config(config) => {
self.config = config;
Expand Down Expand Up @@ -307,27 +334,27 @@ impl cosmic::Application for Notifications {
self.update_cards(id);
}
Message::CloseRequested(id) => {
if Some(id) == self.popup {
if Some(id) == self.popup.as_ref().map(|(id, _)| *id) {
self.popup = None;
}
}
Message::OpenSettings => {
let exec = "cosmic-settings notifications".to_string();
if let Some(tx) = self.token_tx.as_ref() {
let _ = tx.send(TokenRequest {
if let Some(tx) = self.wayland_tx.as_ref() {
let _ = tx.send(WaylandRequest::TokenRequest {
app_id: Self::APP_ID.to_string(),
exec,
});
}
}
Message::Token(u) => match u {
TokenUpdate::Init(tx) => {
self.token_tx = Some(tx);
Message::WaylandUpdate(u) => match u {
WaylandUpdate::Init(tx) => {
self.wayland_tx = Some(tx);
}
TokenUpdate::Finished => {
self.token_tx = None;
WaylandUpdate::Finished => {
self.wayland_tx = None;
}
TokenUpdate::ActivationToken { token, .. } => {
WaylandUpdate::ActivationToken { token, .. } => {
let mut cmd = std::process::Command::new("cosmic-settings");
cmd.arg("notifications");
if let Some(token) = token {
Expand All @@ -336,6 +363,9 @@ impl cosmic::Application for Notifications {
}
cosmic::process::spawn(cmd);
}
WaylandUpdate::ActiveOutput(active) => {
self.on_active_output = active;
}
},
};
self.update_icon();
Expand Down Expand Up @@ -506,13 +536,18 @@ impl cosmic::Application for Notifications {
notifs.push(card_list.into());
}

row!(scrollable(
let ret = row!(scrollable(
Column::with_children(notifs)
.spacing(8)
.height(Length::Shrink),
)
.height(Length::Shrink))
.padding(menu_control_padding())
.padding(menu_control_padding());

if matches!(self.popup, Some((_, Popup::NewNotifications))) {
return self.core.applet.popup_container(ret).into();
}
ret
};

let main_content = column![
Expand Down
Loading

0 comments on commit 64ea722

Please sign in to comment.