eww
eww copied to clipboard
WIP: feat: naive system tray widget
This is still a work in progress, properties needs to be added at least to configure the icon size, gtk menu and menuitem scss classes for the system tray.
While this is functional this needs to be tested against various applications.
Description
Add a system tray widget
Usage
For now there is just a (system-tray)
widget with no prop binding.
Showcase
see #111
Checklist
Please make sure you can check all the boxes that apply to this PR.
- [ ] All widgets I've added are correctly documented.
- [ ] I added my changes to CHANGELOG.md, if appropriate.
- [ ] The documentation in the
docs/content/main
directory has been adjusted to reflect my changes. - [x] I used
cargo fmt
to automatically format all code before committing
I've had a first look through the code right now, and this looks very promising!
Not a fan of the amount of .unwrap
/ .expect
calls currently, but I assume that's gonna be relatively easy to sort out and do cleanly.
Having global state for this is generally fine - as i'm assuming that's pretty much unavoidable.
I think the functions etc in system_tray could definitely use some more comments and a bit more structure -- currently, spawn_local_handler does a lot more than just spawn some handler ^^
I haven't looked into the all the exact details yet, but the approach taken here definitely looks good! Good job already!
Actually there is one big problem here. Every time a menu gets updated it closes and reopen.
For instance when using nm-applet --indicator
if an update occurs (a new wifi network is seen on the interface) while I open the applet, the menu closes and I need to reopen it to see the update.
I have talked with the gtk-rs folks and it seems the solution is to implement a custom MenuModel.
This seems doable but it involves a lot more boiler plate, and unsafe ffi function usage(an example for gio::ListModel
https://github.com/gtk-rs/gtk-rs-core/blob/master/gio/src/subclass/list_model.rs.
So I will probably break everything again soon.
Now I am wondering if it would be better to expose the custom MenuModel from my crate or keep the gtk stuff in eww.
I'll keep you updated :)
I'd think if you wanted to put some GTK stuff into your crate, it might be worth it to actually make a second crate (gtk-stray
or sth), to keep the core system tray handling separate from specific frontend stuff -- that'd allow other projects to also make use of your stray implementation without necessarily needing to use the gtk frontend.
Generally tho, if this does become complex enough, I could see putting the gtk-stuff into a separate crate rather than into eww be worthwhile ππ»
Hey @elkowar I've tried to implement a custom MenuModel without success. I don't think I will be able to do it without help.
That said the current, naive implementation work as is :
Let me know what you want to do.
Awesome work! I'm looking forward for this to be merged to master. I think I might be able to help. Is there any place to converse about this? any EWW room or such?
May I ask what the current state is of this PR?
For what it's worth, I'm trying this out on NixOS on River (Wayland) and I get the following error about icon info lookup:
thread 'main' panicked at 'Failed to lookup icon info', crates/eww/src/widgets/system_tray.rs:76:88
stack backtrace:
0: 0x5580aa0ff2dc - <std::sys_common::backtrace::_print::DisplayBacktrace as core::fmt::Display>::fmt::h90d86d5e49dcdb23
1: 0x5580aa138c8e - core::fmt::write::hf402a79d5884ad76
2: 0x5580aa104fd1 - std::io::Write::write_fmt::h1839547170afd413
3: 0x5580aa1120a5 - std::panicking::default_hook::{{closure}}::h1d6d5b9a19e531e9
4: 0x5580aa111d2a - std::panicking::default_hook::h78a6ac0c850df841
5: 0x5580aa11258c - std::panicking::rust_panic_with_hook::ha3460b9892f156c0
6: 0x5580aa100007 - std::panicking::begin_panic_handler::{{closure}}::h89605b23b2447736
7: 0x5580aa0ff6b4 - std::sys_common::backtrace::__rust_end_short_backtrace::h20c2a9b05a320fe6
8: 0x5580aa112252 - rust_begin_unwind
9: 0x5580a98dd4b3 - core::panicking::panic_fmt::hab911959b97bc6d9
10: 0x5580aa13ed81 - core::panicking::panic_display::he8b09729440fceed
11: 0x5580aa13ed2b - core::panicking::panic_str::h4e2544976daaf571
12: 0x5580a98dd676 - core::option::expect_failed::h7c61aacccb08ad84
13: 0x5580a9a37f85 - eww::widgets::system_tray::NotifierItem::get_icon::h44c3fc2ad0506b71
14: 0x5580a99b1190 - <core::future::from_generator::GenFuture<T> as core::future::future::Future>::poll::h4f6e11f34a6f16ef
15: 0x5580aa0e328c - glib::main_context::<impl glib::auto::main_context::MainContext>::with_thread_default::hccad9d8f02533033
16: 0x5580aa0decaa - glib::main_context_futures::TaskSource::dispatch::h575e8baf5d618d63
17: 0x7f5001e8ddfb - g_main_context_dispatch
18: 0x7f5001e8e0a8 - g_main_context_iterate.constprop.0
19: 0x7f5001e8e393 - g_main_loop_run
20: 0x7f50025fa375 - gtk_main
21: 0x5580a9aba579 - eww::server::initialize_server::h172ed4c880e186da
22: 0x5580a9a39302 - eww::main::h4d89aa5698bad2de
23: 0x5580a99fa923 - std::sys_common::backtrace::__rust_begin_short_backtrace::hfcca3777e9002403
24: 0x5580a99ce469 - std::rt::lang_start::{{closure}}::hb1e9e012b522d946
25: 0x5580aa104951 - std::rt::lang_start_internal::he9577dbc8903283e
26: 0x5580a9a3c512 - main
27: 0x7f5001b89237 - __libc_start_call_main
28: 0x7f5001b892f5 - __libc_start_main_impl
29: 0x5580a98dd6a1 - _start
30: 0x0 - <unknown>
Some more info:
Doesn't matter which icon theme I use. I've tried setting a few different ones with dconf Editor (there are no schemas installed in "gsettings", but dconf Editor does the trick) as well as by editing the settings.ini for GTK 3 and 4, including setting it back to the default.
I suppose it shouldn't panic if it can't find an icon anyway, but the tray works fine in Sway with Waybar so that's a bit strange. Waybar ~~causes River to panic and exit for me though, even if I just have a clock enabled~~ never mind, finally found the culprit: a negative bottom margin. Waybar shows the tray just fine in River now. But Eww is so much more fun... :stuck_out_tongue:
Some more info:
Doesn't matter which icon theme I use. I've tried setting a few different ones with dconf Editor (there are no schemas installed in "gsettings", but dconf Editor does the trick) as well as by editing the settings.ini for GTK 3 and 4, including setting it back to the default.
I suppose it shouldn't panic if it can't find an icon anyway, but the tray works fine in Sway with Waybar so that's a bit strange. Waybar ~causes River to panic and exit for me though, even if I just have a clock enabled~ never mind, finally found the culprit: a negative bottom margin. Waybar shows the tray just fine in River now. But Eww is so much more fun... stuck_out_tongue
Well looking at that line, it would seem to be a gtk issue
Yeah, indeed. Maybe I'm missing some dependency, I don't know. I'm still running this branch, can try it in Sway when I get a chance and see if it works there. Wish I knew more Rust and could be more helpful.
EWW is awesome either way though, crazy addictive. For now, I'm just changing the settings so that apps don't close to tray. :slightly_smiling_face:
Exactly the same stack trace in Sway as well.
What's needed for this to be merged? No system tray is the only thing keeping me from using eww as my main bar.
What's needed for this to be merged? No system tray is the only thing keeping me from using eww as my main bar.
This NEEDS to be merged, I know eww has slowed down in development, but for those of us who want the power of eww, this is kind of a deal breaker, what is a bar without a system tray. (a GNOME panel)
I tried this PR and it seems to be a prototype with lots of problems. Currently, I am trying hard to implement a system tray based on the same idea. However, Linux's system tray specifications are really complicated.
Hey @sunziping2016 I am currently working on something else but maybe we can join our effort ?
This is indeed a prototype but it's not far form being usable. Actually I am using it as a daily driver. If you want to help improving the current behavior maybe we can work together on https://github.com/oknozor/stray/ ?
The main issue, imo is not the dbus system tray implementation, but the gtk integration, which require building a custom MenuModel
and involve messing with some ffi bindings with the C api.
If anyone has experience with gtk-rs help would be more than welcome.
@oknozor I did some investigation, and found some systray implementations leverage libdbusmenu. It seems there is no existing Rust binding for libdbusmenu
.
For those why are trying libdbusmenu
, see gtk-rs/gir for instruction to generate bindings. I am currently working on it, and nearly finish it. xembed-sni-proxy can be used to bridge between XEmbed apps and StatusNotifierItem apps.
I believe I can implement a native systray soon.
Awesome. I have been waiting for this feature for forever. If there's anything I can do (I do have Rust experience, just not gtk-rs
) -- then let me know.
Any updates on this?
Any updates on this?
Bit inappropriate in open-source, especially when people are devoting their free time to unpaid work. Also irrelevant to the technical discussion of the PR itself. https://teejeetech.medium.com/etiquette-in-open-source-projects-f302b6e19c38
Asking for ETAsβββAvoid asking for ETAs for issues and feature requests. Itβs more rude than you may realize. People working on open-source projects are not your employees. They have no obligation to implement every feature you request, to fix every issue you report, or to provide technical support that you are not even paying for. I do not enjoy spending my time working on features that are of no interest to me, or investigating issues that I never face. If I fix such an issue, itβs usually because Iβm curious as to whatβs causing it, or because that issue is affecting a lot of people and can be fixed quickly. The same goes for feature requests. I may add a feature for the sake of completeness, because itβs interesting, or maybe because itβs easy to implement. If itβs time consuming then it will remain undone till I find the time, or till someone else comes along, implements the feature, and submits a pull request.
If you want to contribute, I imagine submitting your own PR would be far more welcome.
Any updates on this?
Bit inappropriate in open-source, especially when people are devoting their free time to unpaid work. Also irrelevant to the technical discussion of the PR itself. https://teejeetech.medium.com/etiquette-in-open-source-projects-f302b6e19c38
Asking for ETAsβββAvoid asking for ETAs for issues and feature requests. Itβs more rude than you may realize. People working on open-source projects are not your employees. They have no obligation to implement every feature you request, to fix every issue you report, or to provide technical support that you are not even paying for. I do not enjoy spending my time working on features that are of no interest to me, or investigating issues that I never face. If I fix such an issue, itβs usually because Iβm curious as to whatβs causing it, or because that issue is affecting a lot of people and can be fixed quickly. The same goes for feature requests. I may add a feature for the sake of completeness, because itβs interesting, or maybe because itβs easy to implement. If itβs time consuming then it will remain undone till I find the time, or till someone else comes along, implements the feature, and submits a pull request.
If you want to contribute, I imagine submitting your own PR would be far more welcome.
I am very sorry, I didn't realize that. I was just very excited to see this PR. Again, sorry, I didn't want to be rude.
Also the pr author has started his own bar project, so i doubt he will complete this pr soon
@oknozor I used your fork to try the systray integration, then added this on my yuck
file:
(defwidget systray []
(system-tray))
But the window is empty, and it prints in the log thread 'tokio-runtime-worker' panicked at 'Error occurred in notifier watcher task: name already taken on the bus', ~/.cargo/registry/src/github.com-1ecc6299db9ec823/stray-0.1.1/src/lib.rs:38:18
.
I'm using Awesome WM so I tried to remove its systray management but the problem is still there.
I also tried to rebase this PR, but when I try to compile with stray v0.1.0 or v0.1.2 the compilation raises those errors:
error[E0432]: unresolved imports `stray::tokio_stream`, `stray::SystemTray`
--> crates/eww/src/widgets/system_tray.rs:14:5
|
14 | tokio_stream::StreamExt,
| ^^^^^^^^^^^^ could not find `tokio_stream` in `stray`
15 | SystemTray,
| ^^^^^^^^^^ no `SystemTray` in the root
warning: unused import: `glib::signal::SignalHandlerId`
--> crates/eww/src/widgets/widget_definitions.rs:14:5
|
14 | use glib::signal::SignalHandlerId;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: `#[warn(unused_imports)]` on by default
error[E0308]: mismatched types
--> crates/eww/src/widgets/system_tray.rs:109:53
|
109 | state.insert(id, NotifierItem { item, menu });
| ^^^^ expected struct `StatusNotifierItem`, found struct `Box`
|
= note: expected struct `StatusNotifierItem`
found struct `std::boxed::Box<StatusNotifierItem>`
help: consider unboxing the value
|
109 | state.insert(id, NotifierItem { item: *item, menu });
| +++++++
warning: unused import: `std::hash::Hasher`
--> crates/eww/src/widgets/widget_definitions.rs:18:5
|
18 | use std::hash::Hasher;
| ^^^^^^^^
I don't have time to update this PR know but it should work using my eww fork if yo carefully killing other apps using the dbus system stray.
I don't know about awesome specifics but it works on i3 and sway.
Maybe you want to use dfleet to find the app using the system tray.
Thanks for suggesting d-feet. When I start eww, org.freedesktop.StatusNotifierHost-[eww PID]-MyNotifierHost
and org.kde.StatusNotifierWatch
appear in the session bus tab, with "activatable: no, cmd: eww daemon".
It disappears when I kill eww so it should be the only one to use org.freedesktop.StatusNotifierHost, even when Awesome has its systray activated it's not listed.
@Anarky this snippet β taken from the gtk-tray
example on the stray
repo (except the unbox in line 111) β works for me:
diff --git a/crates/eww/src/widgets/system_tray.rs b/crates/eww/src/widgets/system_tray.rs
index bc2e088..c297e58 100644
--- a/crates/eww/src/widgets/system_tray.rs
+++ b/crates/eww/src/widgets/system_tray.rs
@@ -11,8 +11,7 @@ use stray::{
tray::StatusNotifierItem,
NotifierItemCommand, NotifierItemMessage,
},
- tokio_stream::StreamExt,
- SystemTray,
+ StatusNotifierWatcher,
};
use tokio::{runtime::Runtime, sync::mpsc};
@@ -85,11 +84,14 @@ pub fn start_communication_thread(sender: mpsc::Sender<NotifierItemMessage>, cmd
let runtime = Runtime::new().expect("Failed to create tokio RT");
runtime.block_on(async {
- let mut tray = SystemTray::new(cmd_rx).await;
+ let tray = StatusNotifierWatcher::new(cmd_rx).await.unwrap();
+ let mut host = tray.create_notifier_host("MyHost").await.unwrap();
- while let Some(message) = tray.next().await {
+ while let Ok(message) = host.recv().await {
sender.send(message).await.expect("failed to send message to UI");
}
+
+ host.destroy().await.unwrap();
})
});
}
@@ -106,7 +108,7 @@ pub fn spawn_local_handler(
match item {
NotifierItemMessage::Update { address: id, item, menu } => {
- state.insert(id, NotifierItem { item, menu });
+ state.insert(id, NotifierItem { item: *item, menu });
}
NotifierItemMessage::Remove { address } => {
state.remove(&address);
diff --git a/crates/eww/src/widgets/widget_definitions.rs b/crates/eww/src/widgets/widget_definitions.rs
index 02f142d..26cca19 100644
--- a/crates/eww/src/widgets/widget_definitions.rs
+++ b/crates/eww/src/widgets/widget_definitions.rs
@@ -11,11 +11,9 @@ use eww_shared_util::Spanned;
use gdk::{ModifierType, NotifyType};
use glib::translate::FromGlib;
-use glib::signal::SignalHandlerId;
use gtk::{self, glib, prelude::*, DestDefaults, TargetEntry, TargetList};
use itertools::Itertools;
use once_cell::sync::Lazy;
-use std::hash::Hasher;
use crate::widgets::system_tray::{spawn_local_handler, start_communication_thread};
use std::{
Edit: now without the two unused import
warnings
@VuiMuich thanks for your help! I attached a zip containing a patch that applies for the current revision (678e4db) with stray 0.1.2, and a PKGBUILD for arch.
Unfortunately it still doesn't work for me, even when using startx
I have this error:
thread 'tokio-runtime-worker' panicked at 'Unexpected StatusNotifierError : DbusError(NameTaken)', ~/.cargo/registry/src/github.com-1ecc6299db9ec823/stray-0.1.2/src/notifier_watcher/mod.rs:37:22
thread '<unnamed>' panicked at 'called `Result::unwrap()` on an `Err` value: DbusError(NameTaken)', crates/eww/src/widgets/system_tray.rs:88:70
It does not run very stable for me neither. I tried to put stray
in a window to toggle it on and off, but that causes some panics as well. Had no time yet, to debug that.i
But I basically get the same error:
~ >>> eww open-many tags left right --debug
2022-12-22T09:01:53.115Z WARN eww > Failed to connect to daemon: Failed to connect to daemon
2022-12-22T09:01:53.115Z INFO eww > Initializing eww server. (/run/user/1000/eww-server_9df4f14eefddaddf)
Run `eww logs` to see any errors while editing your configuration.
2022-12-22T09:01:53.115Z INFO eww::server > Loading paths: config-dir: /home/vuimuich/.config/leftwm/themes/serika/eww, ipc-socket: /run/user/1000/eww-server_9df4f14eefddaddf, log-file: /home/vuimuich/.cache/eww_9df4f14eefddaddf.log
~ >>> eww logs
βββββββββββββββββββββββββ
βInitializing eww daemonβ
βββββββββββββββββββββββββ
2022-12-22T09:01:53.192Z INFO eww::app > Opening window tags
2022-12-22T09:01:53.193Z INFO eww::ipc_server > IPC server initialized
2022-12-22T09:01:53.214Z INFO eww::app > Opening window left
2022-12-22T09:01:53.227Z INFO eww::app > Opening window right
2022-12-22T09:02:05.211Z INFO eww::app > Opening window tray
2022-12-22T09:02:07.480Z INFO eww::app > Closing gtk window tray
2022-12-22T09:02:09.898Z INFO eww::app > Opening window tray
thread 'thread 'tokio-runtime-worker<unnamed>' panicked at '' panicked at 'Unexpected StatusNotifierError : DbusError(NameTaken)called `Result::unwrap()` on an `Err` value: DbusError(NameTaken)', ', /home/vuimuich/.cargo/registry/src/github.com-1ecc6299db9ec823/stray-0.1.2/src/notifier_watcher/mod.rscrates/eww/src/widgets/system_tray.rs::3788::2270
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
2022-12-22T09:02:12.213Z INFO eww::app > Closing gtk window tray
2022-12-22T09:02:14.447Z INFO eww::app > Opening window tray
thread '<unnamed>' panicked at 'called `Result::unwrap()` on an `Err` value: DbusError(NameTaken)', crates/eww/src/widgets/system_tray.rs:88:70
2022-12-22T09:02:17.884Z INFO eww::app > Closing gtk window tray
^Cβ
For what it's worth, I'm trying this out on NixOS on River (Wayland) and I get the following error about icon info lookup:
thread 'main' panicked at 'Failed to lookup icon info', crates/eww/src/widgets/system_tray.rs
@dnordstrom I had the same issue and did a bit of digging and I don't think it's an issue with this project. It seems to be https://github.com/NixOS/nixpkgs/issues/163107/. The fix at the bottom of this comment -- https://github.com/NixOS/nixpkgs/issues/163107#issuecomment-1100569484 -- worked for me.
This is a feature I want, but the PR has kinda stalled, so I've been fixing some things over at https://github.com/ralismark/eww. I'm happy to try and get this into a mergeable state, but I haven't properly looked at all of the current changes, plus I'll be a bit busy for the next few weeks, so it might take some time.
@elkowar @oknozor what are your thoughts? Should I e.g. create a new pr?
@ralismark besides the fix for nixos, does your fork's systray work properly? I would be very interested in testing it
I tried to use @ralismark's fork but after some groking only 1 of 6 icons appeared.
I hope that this features will get more attention, in the meantime I use Stalonetray with a eww button widget to toggle it.