Skip to content

add peripheral battery levels for mice and keyboards #159

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 4 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ This will build ashell from source, but you can also use `pkgs.ashell` from nixp
- OS Updates indicator
- Hyprland Active Window
- Hyprland Workspaces
- System Information (CPU, RAM, Temperature)
- System Information (CPU, RAM, Temperature, Peripheral battery levels)
- Hyprland Keyboard Layout
- Hyprland Keyboard Submap
- Tray
Expand Down Expand Up @@ -219,6 +219,7 @@ enable_workspace_filling = false
# - IpAddress
# - DownloadSpeed
# - UploadSpeed
# - Peripherals
# optional, the following is the default configuration
# If for example you want to dispay the usage of the root and home partition
# you can use the following configuration
Expand Down
28 changes: 25 additions & 3 deletions src/app.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,10 @@ use crate::{
},
outputs::{HasOutput, Outputs},
position_button::ButtonUIRef,
services::{Service, ServiceEvent, brightness::BrightnessCommand, tray::TrayEvent},
services::{
ReadOnlyService, Service, ServiceEvent, brightness::BrightnessCommand, tray::TrayEvent,
upower::UPowerService,
},
style::{ashell_theme, backdrop_color, darken_color},
utils,
};
Expand Down Expand Up @@ -59,6 +62,7 @@ pub struct App {
pub privacy: Privacy,
pub settings: Settings,
pub media_player: MediaPlayer,
pub upower: Option<UPowerService>,
}

#[derive(Debug, Clone)]
Expand All @@ -80,6 +84,7 @@ pub enum Message {
Privacy(modules::privacy::PrivacyMessage),
Settings(modules::settings::Message),
MediaPlayer(modules::media_player::Message),
UPowerEvent(ServiceEvent<UPowerService>),
OutputEvent((OutputEvent, WlOutput)),
}

Expand All @@ -105,6 +110,7 @@ impl App {
privacy: Privacy::default(),
settings: Settings::default(),
media_player: MediaPlayer::default(),
upower: None,
config,
},
task,
Expand Down Expand Up @@ -249,6 +255,20 @@ impl App {
self.settings
.update(message, &self.config.settings, &mut self.outputs)
}
Message::MediaPlayer(msg) => self.media_player.update(msg),
Message::UPowerEvent(event) => match event {
ServiceEvent::Init(service) => {
self.upower = Some(service);
Task::none()
}
ServiceEvent::Update(data) => {
if let Some(upower) = self.upower.as_mut() {
upower.update(data);
}
Task::none()
}
ServiceEvent::Error(_) => Task::none(),
},
Message::OutputEvent((event, wl_output)) => match event {
iced::event::wayland::OutputEvent::Created(info) => {
info!("Output created: {:?}", info);
Expand All @@ -275,7 +295,6 @@ impl App {
}
_ => Task::none(),
},
Message::MediaPlayer(msg) => self.media_player.update(msg),
}
}

Expand Down Expand Up @@ -441,7 +460,9 @@ impl App {
),
Some((MenuType::SystemInfo, button_ui_ref)) => menu_wrapper(
id,
self.system_info.menu_view().map(Message::SystemInfo),
self.system_info
.menu_view(&self.upower)
.map(Message::SystemInfo),
MenuSize::Large,
*button_ui_ref,
self.config.position,
Expand All @@ -460,6 +481,7 @@ impl App {
Subscription::batch(self.modules_subscriptions(&self.config.modules.left)),
Subscription::batch(self.modules_subscriptions(&self.config.modules.center)),
Subscription::batch(self.modules_subscriptions(&self.config.modules.right)),
UPowerService::subscribe().map(Message::UPowerEvent),
config::subscription(),
listen_with(|evt, _, _| match evt {
iced::Event::PlatformSpecific(iced::event::PlatformSpecific::Wayland(
Expand Down
4 changes: 4 additions & 0 deletions src/components/icons.rs
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,8 @@ pub enum Icons {
UploadSpeed,
Copy,
RightChevron,
Mouse,
Keyboard,
}

impl From<Icons> for &'static str {
Expand Down Expand Up @@ -147,6 +149,8 @@ impl From<Icons> for &'static str {
Icons::UploadSpeed => "󰛶",
Icons::Copy => "󰆏",
Icons::RightChevron => "󰅂",
Icons::Mouse => "󰍽",
Icons::Keyboard => "",
}
}
}
Expand Down
2 changes: 2 additions & 0 deletions src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,7 @@ pub enum SystemIndicator {
IpAddress,
DownloadSpeed,
UploadSpeed,
Peripherals,
}

#[derive(Deserialize, Clone, Debug)]
Expand All @@ -141,6 +142,7 @@ fn default_system_indicators() -> Vec<SystemIndicator> {
SystemIndicator::Cpu,
SystemIndicator::Memory,
SystemIndicator::Temperature,
SystemIndicator::Peripherals,
]
}

Expand Down
2 changes: 1 addition & 1 deletion src/modules/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -241,7 +241,7 @@ impl App {
self.config.appearance.special_workspace_colors.as_deref(),
)),
ModuleName::WindowTitle => self.window_title.view(()),
ModuleName::SystemInfo => self.system_info.view(&self.config.system),
ModuleName::SystemInfo => self.system_info.view((&self.config.system, &self.upower)),
ModuleName::KeyboardLayout => self.keyboard_layout.view(&self.config.keyboard_layout),
ModuleName::KeyboardSubmap => self.keyboard_submap.view(()),
ModuleName::Tray => self.tray.view((id, opacity)),
Expand Down
4 changes: 2 additions & 2 deletions src/modules/settings/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -453,7 +453,7 @@ impl Settings {
let battery_data = self
.upower
.as_ref()
.and_then(|upower| upower.battery)
.and_then(|upower| upower.system_battery)
.map(|battery| battery.settings_indicator());
let right_buttons = Row::new()
.push_maybe(config.lock_cmd.as_ref().map(|_| {
Expand Down Expand Up @@ -641,7 +641,7 @@ impl Module for Settings {
.push_maybe(
self.upower
.as_ref()
.and_then(|upower| upower.battery)
.and_then(|upower| upower.system_battery)
.map(|battery| battery.indicator()),
)
.spacing(8)
Expand Down
58 changes: 54 additions & 4 deletions src/modules/system_info.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ use crate::{
components::icons::{Icons, icon},
config::{SystemIndicator, SystemModuleConfig},
menu::MenuType,
services::upower::{PeripheralDeviceKind, UPowerService},
};
use iced::{
Alignment, Element, Length, Subscription, Task, Theme,
Expand Down Expand Up @@ -220,7 +221,7 @@ impl SystemInfo {
}
}

pub fn menu_view(&self) -> Element<Message> {
pub fn menu_view(&self, upower: &Option<UPowerService>) -> Element<Message> {
column!(
column!(text("System Info").size(20), horizontal_rule(1)).spacing(4),
Column::new()
Expand Down Expand Up @@ -289,6 +290,28 @@ impl SystemInfo {
),
])
}))
.push_maybe(
upower
.as_ref()
.and_then(|upower| {
(!upower.peripheral.is_empty()).then_some(&upower.peripheral)
})
.map(|peripherals| {
let devices = peripherals.iter().map(|peripheral| {
let icon = match peripheral.kind {
PeripheralDeviceKind::Keyboard => Icons::Keyboard,
PeripheralDeviceKind::Mouse => Icons::Mouse,
};
Self::info_element(
icon,
peripheral.name.clone(),
format!("{}%", peripheral.data.capacity),
)
});

Column::with_children(devices)
}),
)
.spacing(4)
.padding([0, 8])
)
Expand All @@ -298,12 +321,12 @@ impl SystemInfo {
}

impl Module for SystemInfo {
type ViewData<'a> = &'a SystemModuleConfig;
type ViewData<'a> = (&'a SystemModuleConfig, &'a Option<UPowerService>);
type SubscriptionData<'a> = ();

fn view(
&self,
config: Self::ViewData<'_>,
(config, upower): Self::ViewData<'_>,
) -> Option<(Element<app::Message>, Option<OnModulePress>)> {
let indicators = config.indicators.iter().filter_map(|i| match i {
SystemIndicator::Cpu => Some(Self::indicator_info_element(
Expand Down Expand Up @@ -397,6 +420,29 @@ impl Module for SystemInfo {
None,
)
}),
SystemIndicator::Peripherals => upower
.as_ref()
.and_then(|upower| (!upower.peripheral.is_empty()).then_some(&upower.peripheral))
.map(|peripheral| {
let devices = peripheral.iter().map(|peripheral| {
let icon = match peripheral.kind {
PeripheralDeviceKind::Keyboard => Icons::Keyboard,
PeripheralDeviceKind::Mouse => Icons::Mouse,
};
Self::indicator_info_element(
icon,
peripheral.data.capacity,
"%",
None,
None,
)
});

Row::with_children(devices)
.align_y(Alignment::Center)
.spacing(4)
.into()
}),
});

Some((
Expand All @@ -409,6 +455,10 @@ impl Module for SystemInfo {
}

fn subscription(&self, _: Self::SubscriptionData<'_>) -> Option<Subscription<app::Message>> {
Some(every(Duration::from_secs(5)).map(|_| app::Message::SystemInfo(Message::Update)))
Some(
every(Duration::from_secs(5))
.map(|_| Message::Update)
.map(app::Message::SystemInfo),
)
}
}
Loading