add sys tray
This commit is contained in:
parent
f978bb2faa
commit
712a2d1e70
104
Cargo.lock
generated
104
Cargo.lock
generated
@ -41,6 +41,15 @@ dependencies = [
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ansi_term"
|
||||
version = "0.12.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d52a9bb7ec0cf484c551830a7ce27bd20d67eac647e1befb56b0be4ee39a55d2"
|
||||
dependencies = [
|
||||
"winapi 0.3.9",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "apt-sources-lists"
|
||||
version = "0.1.0"
|
||||
@ -232,6 +241,21 @@ dependencies = [
|
||||
"windows-targets 0.52.6",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "clap"
|
||||
version = "2.34.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a0610544180c38b88101fecf2dd634b174a62eef6946f84dfc6a7127512b381c"
|
||||
dependencies = [
|
||||
"ansi_term",
|
||||
"atty",
|
||||
"bitflags 1.3.2",
|
||||
"strsim",
|
||||
"textwrap",
|
||||
"unicode-width",
|
||||
"vec_map",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cloudabi"
|
||||
version = "0.0.3"
|
||||
@ -368,6 +392,37 @@ dependencies = [
|
||||
"syn 2.0.70",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "dbus"
|
||||
version = "0.9.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1bb21987b9fb1613058ba3843121dd18b163b254d8a6e797e144cbac14d96d1b"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"libdbus-sys",
|
||||
"winapi 0.3.9",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "dbus-codegen"
|
||||
version = "0.9.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a49da9fdfbe872d4841d56605dc42efa5e6ca3291299b87f44e1cde91a28617c"
|
||||
dependencies = [
|
||||
"clap",
|
||||
"dbus",
|
||||
"xml-rs",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "dbus-tree"
|
||||
version = "0.9.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f456e698ae8e54575e19ddb1f9b7bce2298568524f215496b248eb9498b4f508"
|
||||
dependencies = [
|
||||
"dbus",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "deb822-lossless"
|
||||
version = "0.1.23"
|
||||
@ -1230,6 +1285,18 @@ dependencies = [
|
||||
"winapi-build",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ksni"
|
||||
version = "0.2.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4934310bdd016e55725482b8d35ac0c16fd058c1b955d8959aa2d953b918c85b"
|
||||
dependencies = [
|
||||
"dbus",
|
||||
"dbus-codegen",
|
||||
"dbus-tree",
|
||||
"thiserror",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "lazy_static"
|
||||
version = "1.5.0"
|
||||
@ -1281,6 +1348,15 @@ version = "0.2.155"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "97b3888a4aecf77e811145cadf6eef5901f4782c53886191b2f693f24761847c"
|
||||
|
||||
[[package]]
|
||||
name = "libdbus-sys"
|
||||
version = "0.2.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "06085512b750d640299b79be4bad3d2fa90a9c00b1fd9e1b46364f66f0485c72"
|
||||
dependencies = [
|
||||
"pkg-config",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "libflatpak"
|
||||
version = "0.5.0"
|
||||
@ -1671,6 +1747,7 @@ dependencies = [
|
||||
"duct",
|
||||
"futures 0.3.30",
|
||||
"gtk4",
|
||||
"ksni",
|
||||
"legacy-apt-list-tools-rs",
|
||||
"libadwaita",
|
||||
"libflatpak",
|
||||
@ -2191,6 +2268,12 @@ version = "0.2.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7a8348af2d9fc3258c8733b8d9d8db2e56f54b2363a4b5b81585c7875ed65e65"
|
||||
|
||||
[[package]]
|
||||
name = "strsim"
|
||||
version = "0.8.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a"
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "1.0.109"
|
||||
@ -2322,6 +2405,15 @@ version = "1.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f18aa187839b2bdb1ad2fa35ead8c4c2976b64e4363c386d45ac0f7ee85c9233"
|
||||
|
||||
[[package]]
|
||||
name = "textwrap"
|
||||
version = "0.11.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d326610f408c7a4eb6f51c37c330e496b08506c9457c9d34287ecc38809fb060"
|
||||
dependencies = [
|
||||
"unicode-width",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "thiserror"
|
||||
version = "1.0.61"
|
||||
@ -2651,6 +2743,12 @@ version = "0.2.15"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426"
|
||||
|
||||
[[package]]
|
||||
name = "vec_map"
|
||||
version = "0.8.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f1bddf1187be692e79c5ffeab891132dfb0f236ed36a43c7ed39f1165ee20191"
|
||||
|
||||
[[package]]
|
||||
name = "version-compare"
|
||||
version = "0.2.0"
|
||||
@ -3002,6 +3100,12 @@ dependencies = [
|
||||
"winapi-build",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "xml-rs"
|
||||
version = "0.8.22"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "af4e2e2f7cba5a093896c1e150fbfe177d1883e7448200efb81d40b9d339ef26"
|
||||
|
||||
[[package]]
|
||||
name = "yaml-rust"
|
||||
version = "0.4.5"
|
||||
|
@ -44,4 +44,5 @@ duct = "0.13.7"
|
||||
reqwest = { version = "0.11", features = ["blocking"] }
|
||||
strfmt = "0.2.4"
|
||||
configparser = "3.1.0"
|
||||
ksni = "0.2.2"
|
||||
|
||||
|
@ -154,5 +154,9 @@
|
||||
"flatpak_ref_install_flatref_path_prefrencesgroup_title": "The File Path to The Flatpak Reference File You Want to Install",
|
||||
"flatpak_ref_install_dialog_heading": "Flatpak Reference File Installer",
|
||||
"flatpak_ref_install_dialog_add_label": "Install",
|
||||
"flatpak_ref_install_dialog_cancel_label": "Cancel"
|
||||
"flatpak_ref_install_dialog_cancel_label": "Cancel",
|
||||
"pikman_indicator_apt_count_item_label": "APT Updates: {NUM}",
|
||||
"pikman_indicator_flatpak_count_item_label": "Flatpak Updates: {NUM}",
|
||||
"pikman_indicator_open_item_label": "Open",
|
||||
"pikman_indicator_exit_item_label": "Exit"
|
||||
}
|
@ -5,14 +5,84 @@ use crate::config::{APP_GITHUB, APP_ICON, APP_ID, VERSION};
|
||||
use crate::flatpak_update_page;
|
||||
use adw::prelude::*;
|
||||
use adw::*;
|
||||
use async_channel::Sender;
|
||||
use futures::task::SpawnExt;
|
||||
use gtk::glib::{clone, MainContext};
|
||||
use gtk::{License, WindowControls};
|
||||
use std::borrow::Borrow;
|
||||
use std::cell::RefCell;
|
||||
use std::ops::Index;
|
||||
use std::process::Command;
|
||||
use std::rc::Rc;
|
||||
use std::sync::atomic::AtomicBool;
|
||||
use std::thread;
|
||||
use std::sync::Arc;
|
||||
use ksni;
|
||||
|
||||
#[derive(Debug)]
|
||||
struct PikmanTray {
|
||||
icon_name: Option<String>,
|
||||
apt_item_label: Option<String>,
|
||||
flatpak_item_label: Option<String>,
|
||||
action_sender: &'static async_channel::Sender<String>,
|
||||
}
|
||||
|
||||
impl ksni::Tray for PikmanTray {
|
||||
fn icon_name(&self) -> String {
|
||||
match &self.icon_name {
|
||||
Some(t) => t.into(),
|
||||
None => "help-about".into()
|
||||
}
|
||||
}
|
||||
fn title(&self) -> String {
|
||||
t!("application_name").to_string()
|
||||
}
|
||||
// NOTE: On some system trays, `id` is a required property to avoid unexpected behaviors
|
||||
fn id(&self) -> String {
|
||||
env!("CARGO_PKG_NAME").into()
|
||||
}
|
||||
fn menu(&self) -> Vec<ksni::MenuItem<Self>> {
|
||||
use ksni::menu::*;
|
||||
vec![
|
||||
StandardItem {
|
||||
label: match &self.apt_item_label {
|
||||
Some(t) => t,
|
||||
None => "?"
|
||||
}.into(),
|
||||
icon_name: "application-vnd.debian.binary-package".into(),
|
||||
enabled: false,
|
||||
..Default::default()
|
||||
}
|
||||
.into(),
|
||||
StandardItem {
|
||||
label: match &self.flatpak_item_label {
|
||||
Some(t) => t,
|
||||
None => "?"
|
||||
}.into(),
|
||||
icon_name: "application-vnd.flatpak".into(),
|
||||
enabled: false,
|
||||
..Default::default()
|
||||
}
|
||||
.into(),
|
||||
MenuItem::Separator,
|
||||
StandardItem {
|
||||
label: t!("pikman_indicator_open_item_label").into(),
|
||||
icon_name: "view-paged-symbolic".into(),
|
||||
activate: Box::new(|_| {
|
||||
self.action_sender.send_blocking(String::from("open")).unwrap()
|
||||
}),
|
||||
..Default::default()
|
||||
}
|
||||
.into(),
|
||||
StandardItem {
|
||||
label: t!("pikman_indicator_exit_item_label").into(),
|
||||
icon_name: "application-exit-symbolic".into(),
|
||||
activate: Box::new(|_| std::process::exit(0)),
|
||||
..Default::default()
|
||||
}
|
||||
.into(),
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
pub fn build_ui(app: &Application) {
|
||||
// setup glib
|
||||
@ -24,6 +94,23 @@ pub fn build_ui(app: &Application) {
|
||||
let (internet_loop_sender, internet_loop_receiver) = async_channel::unbounded();
|
||||
let internet_loop_sender = internet_loop_sender.clone();
|
||||
|
||||
// Systray
|
||||
|
||||
let update_sys_tray = gio::SimpleAction::new("sys_tray", Some(glib::VariantTy::ARRAY));
|
||||
|
||||
let (tray_service_sender, tray_service_receiver) = async_channel::unbounded();
|
||||
let tray_service_sender = tray_service_sender.clone();
|
||||
|
||||
let tray_service = ksni::TrayService::new(PikmanTray {
|
||||
action_sender: Box::leak(Box::new(tray_service_sender)),
|
||||
icon_name: None,
|
||||
apt_item_label: None,
|
||||
flatpak_item_label: None,
|
||||
});
|
||||
let tray_handle = tray_service.handle();
|
||||
|
||||
tray_service.spawn();
|
||||
|
||||
thread::spawn(move || loop {
|
||||
match Command::new("ping").arg("google.com").arg("-c 1").output() {
|
||||
Ok(t) if t.status.success() => internet_loop_sender
|
||||
@ -318,6 +405,44 @@ pub fn build_ui(app: &Application) {
|
||||
let flatpak_manage_page_toggle_button = add_content_button(&window_adw_stack, false, "flatpak_manage_page".to_string(), t!("flatpak_manage_page_title").to_string(), &null_toggle_button);
|
||||
window_adw_view_switcher_sidebar_box.append(&flatpak_manage_page_toggle_button);
|
||||
|
||||
update_sys_tray.connect_activate(clone!(
|
||||
#[strong]
|
||||
tray_handle,
|
||||
move |_,param| {
|
||||
let array: &[i32] = param.unwrap().fixed_array().unwrap();
|
||||
let vec = array.to_vec();
|
||||
let apt_update_count = vec[0];
|
||||
let flatpak_update_count = vec[1];
|
||||
let tray_icon = if apt_update_count + flatpak_update_count > 1 {
|
||||
Some("update-high".into())
|
||||
} else {
|
||||
Some("update-none".into())
|
||||
};
|
||||
tray_handle.update(|tray: &mut PikmanTray| {
|
||||
tray.icon_name = tray_icon;
|
||||
tray.apt_item_label = Some(strfmt::strfmt(
|
||||
&t!("pikman_indicator_apt_count_item_label").to_string(),
|
||||
&std::collections::HashMap::from([
|
||||
(
|
||||
"NUM".to_string(),
|
||||
apt_update_count.to_string(),
|
||||
),
|
||||
]),
|
||||
)
|
||||
.unwrap());
|
||||
tray.flatpak_item_label = Some(strfmt::strfmt(
|
||||
&t!("pikman_indicator_flatpak_count_item_label").to_string(),
|
||||
&std::collections::HashMap::from([
|
||||
(
|
||||
"NUM".to_string(),
|
||||
flatpak_update_count.to_string(),
|
||||
),
|
||||
]),
|
||||
)
|
||||
.unwrap());
|
||||
});
|
||||
}));
|
||||
|
||||
app.connect_command_line(clone!(
|
||||
#[strong]
|
||||
apt_manage_page_toggle_button,
|
||||
|
Loading…
Reference in New Issue
Block a user