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",
|
"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]]
|
[[package]]
|
||||||
name = "apt-sources-lists"
|
name = "apt-sources-lists"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
@ -232,6 +241,21 @@ dependencies = [
|
|||||||
"windows-targets 0.52.6",
|
"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]]
|
[[package]]
|
||||||
name = "cloudabi"
|
name = "cloudabi"
|
||||||
version = "0.0.3"
|
version = "0.0.3"
|
||||||
@ -368,6 +392,37 @@ dependencies = [
|
|||||||
"syn 2.0.70",
|
"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]]
|
[[package]]
|
||||||
name = "deb822-lossless"
|
name = "deb822-lossless"
|
||||||
version = "0.1.23"
|
version = "0.1.23"
|
||||||
@ -1230,6 +1285,18 @@ dependencies = [
|
|||||||
"winapi-build",
|
"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]]
|
[[package]]
|
||||||
name = "lazy_static"
|
name = "lazy_static"
|
||||||
version = "1.5.0"
|
version = "1.5.0"
|
||||||
@ -1281,6 +1348,15 @@ version = "0.2.155"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "97b3888a4aecf77e811145cadf6eef5901f4782c53886191b2f693f24761847c"
|
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]]
|
[[package]]
|
||||||
name = "libflatpak"
|
name = "libflatpak"
|
||||||
version = "0.5.0"
|
version = "0.5.0"
|
||||||
@ -1671,6 +1747,7 @@ dependencies = [
|
|||||||
"duct",
|
"duct",
|
||||||
"futures 0.3.30",
|
"futures 0.3.30",
|
||||||
"gtk4",
|
"gtk4",
|
||||||
|
"ksni",
|
||||||
"legacy-apt-list-tools-rs",
|
"legacy-apt-list-tools-rs",
|
||||||
"libadwaita",
|
"libadwaita",
|
||||||
"libflatpak",
|
"libflatpak",
|
||||||
@ -2191,6 +2268,12 @@ version = "0.2.4"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "7a8348af2d9fc3258c8733b8d9d8db2e56f54b2363a4b5b81585c7875ed65e65"
|
checksum = "7a8348af2d9fc3258c8733b8d9d8db2e56f54b2363a4b5b81585c7875ed65e65"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "strsim"
|
||||||
|
version = "0.8.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "syn"
|
name = "syn"
|
||||||
version = "1.0.109"
|
version = "1.0.109"
|
||||||
@ -2322,6 +2405,15 @@ version = "1.1.1"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "f18aa187839b2bdb1ad2fa35ead8c4c2976b64e4363c386d45ac0f7ee85c9233"
|
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]]
|
[[package]]
|
||||||
name = "thiserror"
|
name = "thiserror"
|
||||||
version = "1.0.61"
|
version = "1.0.61"
|
||||||
@ -2651,6 +2743,12 @@ version = "0.2.15"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426"
|
checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "vec_map"
|
||||||
|
version = "0.8.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "f1bddf1187be692e79c5ffeab891132dfb0f236ed36a43c7ed39f1165ee20191"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "version-compare"
|
name = "version-compare"
|
||||||
version = "0.2.0"
|
version = "0.2.0"
|
||||||
@ -3002,6 +3100,12 @@ dependencies = [
|
|||||||
"winapi-build",
|
"winapi-build",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "xml-rs"
|
||||||
|
version = "0.8.22"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "af4e2e2f7cba5a093896c1e150fbfe177d1883e7448200efb81d40b9d339ef26"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "yaml-rust"
|
name = "yaml-rust"
|
||||||
version = "0.4.5"
|
version = "0.4.5"
|
||||||
|
@ -44,4 +44,5 @@ duct = "0.13.7"
|
|||||||
reqwest = { version = "0.11", features = ["blocking"] }
|
reqwest = { version = "0.11", features = ["blocking"] }
|
||||||
strfmt = "0.2.4"
|
strfmt = "0.2.4"
|
||||||
configparser = "3.1.0"
|
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_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_heading": "Flatpak Reference File Installer",
|
||||||
"flatpak_ref_install_dialog_add_label": "Install",
|
"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 crate::flatpak_update_page;
|
||||||
use adw::prelude::*;
|
use adw::prelude::*;
|
||||||
use adw::*;
|
use adw::*;
|
||||||
|
use async_channel::Sender;
|
||||||
|
use futures::task::SpawnExt;
|
||||||
use gtk::glib::{clone, MainContext};
|
use gtk::glib::{clone, MainContext};
|
||||||
use gtk::{License, WindowControls};
|
use gtk::{License, WindowControls};
|
||||||
use std::borrow::Borrow;
|
|
||||||
use std::cell::RefCell;
|
use std::cell::RefCell;
|
||||||
use std::ops::Index;
|
use std::ops::Index;
|
||||||
use std::process::Command;
|
use std::process::Command;
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
|
use std::sync::atomic::AtomicBool;
|
||||||
use std::thread;
|
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) {
|
pub fn build_ui(app: &Application) {
|
||||||
// setup glib
|
// 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_receiver) = async_channel::unbounded();
|
||||||
let internet_loop_sender = internet_loop_sender.clone();
|
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 {
|
thread::spawn(move || loop {
|
||||||
match Command::new("ping").arg("google.com").arg("-c 1").output() {
|
match Command::new("ping").arg("google.com").arg("-c 1").output() {
|
||||||
Ok(t) if t.status.success() => internet_loop_sender
|
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);
|
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);
|
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!(
|
app.connect_command_line(clone!(
|
||||||
#[strong]
|
#[strong]
|
||||||
apt_manage_page_toggle_button,
|
apt_manage_page_toggle_button,
|
||||||
|
Loading…
Reference in New Issue
Block a user