Skip to content

Commit 6a7d55f

Browse files
committed
Add preference option to enable/disable tray icon
1 parent fa8b6b1 commit 6a7d55f

File tree

3 files changed

+90
-11
lines changed

3 files changed

+90
-11
lines changed

data/io.github.nozwock.Packet.gschema.xml.in

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,5 +41,8 @@
4141
<key name="enable-nautilus-plugin" type="b">
4242
<default>false</default>
4343
</key>
44+
<key name="enable-tray-icon" type="b">
45+
<default>false</default>
46+
</key>
4447
</schema>
4548
</schemalist>

data/resources/ui/window.blp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -463,6 +463,14 @@ Adw.PreferencesDialog preferences_dialog {
463463
}
464464
}
465465

466+
Adw.PreferencesGroup tray_icon_group {
467+
visible: false; // Set true for target_os linux since ksni is linux only
468+
Adw.SwitchRow tray_icon_switch {
469+
title: _("Tray Icon");
470+
subtitle: _("Show tray icon in the system tray");
471+
}
472+
}
473+
466474
Adw.PreferencesGroup {
467475
Adw.ExpanderRow static_port_expander {
468476
title: _("Static Network Port");

src/window.rs

Lines changed: 79 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ mod imp {
5454

5555
use super::*;
5656

57-
#[derive(Debug, gtk::CompositeTemplate, better_default::Default)]
57+
#[derive(gtk::CompositeTemplate, better_default::Default)]
5858
#[template(resource = "/io/github/nozwock/Packet/ui/window.ui")]
5959
pub struct PacketApplicationWindow {
6060
#[default(gio::Settings::new(APP_ID))]
@@ -114,6 +114,10 @@ mod imp {
114114
#[template_child]
115115
pub nautilus_plugin_switch: TemplateChild<adw::SwitchRow>,
116116
pub nautilus_plugin_switch_handler_id: RefCell<Option<glib::SignalHandlerId>>,
117+
#[template_child]
118+
pub tray_icon_group: TemplateChild<adw::PreferencesGroup>,
119+
#[template_child]
120+
pub tray_icon_switch: TemplateChild<adw::SwitchRow>,
117121

118122
#[template_child]
119123
pub main_box: TemplateChild<gtk::Box>,
@@ -178,6 +182,9 @@ mod imp {
178182
pub is_recipients_dialog_opened: Cell<bool>,
179183

180184
pub nautilus_plugin: NautilusPlugin,
185+
186+
#[cfg(target_os = "linux")]
187+
pub tray_icon_handle: RefCell<Option<ksni::Handle<crate::tray::Tray>>>,
181188
}
182189

183190
#[glib::object_subclass]
@@ -462,6 +469,9 @@ impl PacketApplicationWindow {
462469
"active",
463470
)
464471
.build();
472+
imp.settings
473+
.bind("enable-tray-icon", &imp.tray_icon_switch.get(), "active")
474+
.build();
465475

466476
// TODO: The value of many preference options are only validated in the
467477
// UI, not outside of it.
@@ -571,6 +581,31 @@ impl PacketApplicationWindow {
571581
imp.nautilus_plugin_switch_handler_id
572582
.replace(Some(_signal_handle));
573583

584+
#[cfg(target_os = "linux")]
585+
imp.tray_icon_switch.connect_active_notify(clone!(
586+
#[weak]
587+
imp,
588+
move |switch| {
589+
glib::spawn_future_local(clone!(
590+
#[weak]
591+
imp,
592+
#[weak]
593+
switch,
594+
async move {
595+
switch.set_sensitive(false);
596+
597+
if switch.is_active() {
598+
_ = imp.obj().enable_tray_icon().await;
599+
} else {
600+
imp.obj().disable_tray_icon().await;
601+
}
602+
603+
switch.set_sensitive(true);
604+
}
605+
));
606+
}
607+
));
608+
574609
let _signal_handle = imp.run_in_background_switch.connect_active_notify(clone!(
575610
#[weak]
576611
imp,
@@ -1058,23 +1093,54 @@ impl PacketApplicationWindow {
10581093
///
10591094
/// https://github.com/tauri-apps/tray-icon/pull/201
10601095
fn setup_tray_icon(&self) {
1096+
let imp = self.imp();
1097+
1098+
imp.tray_icon_group.set_visible(true);
1099+
1100+
let is_enable_tray_icon = imp.settings.boolean("enable-tray-icon");
1101+
tracing::debug!(?is_enable_tray_icon);
1102+
if is_enable_tray_icon {
1103+
self.enable_tray_icon();
1104+
}
1105+
}
1106+
1107+
#[cfg(target_os = "linux")]
1108+
async fn disable_tray_icon(&self) {
1109+
let imp = self.imp();
1110+
1111+
if let Some(ref mut handle) = *imp.tray_icon_handle.borrow_mut() {
1112+
tracing::debug!("Disabling tray icon");
1113+
handle.shutdown().await;
1114+
}
1115+
imp.tray_icon_handle.take();
1116+
}
1117+
1118+
#[cfg(target_os = "linux")]
1119+
fn enable_tray_icon(&self) -> glib::JoinHandle<()> {
10611120
use crate::tray;
10621121
use ksni::*;
10631122

10641123
let imp = self.imp();
10651124

1125+
tracing::debug!("Enabling tray icon");
10661126
let (tx, mut rx) = tokio::sync::mpsc::channel::<tray::TrayMessage>(1);
1067-
tokio_runtime().spawn(async move {
1068-
let tray = crate::tray::Tray { tx: tx };
1069-
_ = if ashpd::is_sandboxed().await {
1070-
tray.spawn_without_dbus_name().await
1071-
} else {
1072-
tray.spawn().await
1127+
let handle = glib::spawn_future_local(clone!(
1128+
#[weak]
1129+
imp,
1130+
async move {
1131+
let tray = crate::tray::Tray { tx: tx };
1132+
let handle = if ashpd::is_sandboxed().await {
1133+
tray.spawn_without_dbus_name().await
1134+
} else {
1135+
tray.spawn().await
1136+
}
1137+
.inspect_err(
1138+
|err| tracing::warn!(%err, "Failed to setup KStatusNotifierItem tray icon"),
1139+
)
1140+
.ok();
1141+
*imp.tray_icon_handle.borrow_mut() = handle;
10731142
}
1074-
.inspect_err(
1075-
|err| tracing::warn!(%err, "Failed to setup KStatusNotifierItem tray icon"),
1076-
);
1077-
});
1143+
));
10781144

10791145
glib::spawn_future_local(clone!(
10801146
#[weak]
@@ -1095,6 +1161,8 @@ impl PacketApplicationWindow {
10951161
}
10961162
}
10971163
));
1164+
1165+
handle
10981166
}
10991167

11001168
fn setup_ui(&self) {

0 commit comments

Comments
 (0)