Skip to content
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
Binary file modified assets/AshellCustomIcon-Regular.otf
Binary file not shown.
2 changes: 1 addition & 1 deletion assets/ashell_custom_icon_project.gs2

Large diffs are not rendered by default.

3 changes: 3 additions & 0 deletions assets/key_backlight_off.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
7 changes: 7 additions & 0 deletions assets/key_backlight_on.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 4 additions & 0 deletions docs/src/reference/config-reference.md
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,9 @@ weather_format = "{temp}°C"
# Enable/disable hover tooltips on status indicators (audio, bluetooth, wifi, battery)
enable_tooltips = true

# Show a slider for the built-in keyboard backlight, under the brightness slider
keyboard_backlight_slider = false

# Custom buttons in the settings panel
[[settings.custom_buttons]]
icon = "\u{f023}"
Expand All @@ -185,6 +188,7 @@ on_click = "vpn-toggle"
| Brightness | systemd-logind (usually present) |
| Network | `networkmanager` or `iwd` |
| Power (battery) | `upower` |
| Keyboard backlight | `upower` (built-in keyboard only) |

## Media Player Module

Expand Down
2 changes: 1 addition & 1 deletion i18n/de-DE/ashell.ftl
Original file line number Diff line number Diff line change
Expand Up @@ -154,4 +154,4 @@ system-info-temperature = Temperatur
system-info-disk-usage = Festplattennutzung { $mount }
system-info-ip-address = IP-Adresse
system-info-download-speed = Download
system-info-upload-speed = Upload
system-info-upload-speed = Upload
12 changes: 9 additions & 3 deletions src/components/icons.rs
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,8 @@ pub enum StaticIcon {
KeyboardBatteryLow,
KeyboardBatteryAlert,
KeyboardBatteryCharging,
KeyboardBacklightOn,
KeyboardBacklightOff,
MouseBatteryFull,
MouseBatteryMedium,
MouseBatteryLow,
Expand Down Expand Up @@ -239,6 +241,8 @@ impl StaticIcon {
StaticIcon::HeadphoneBatteryLow => "\u{c000c}",
StaticIcon::HeadphoneBatteryAlert => "\u{c000d}",
StaticIcon::HeadphoneBatteryCharging => "\u{c000e}",
StaticIcon::KeyboardBacklightOn => "\u{c000f}",
StaticIcon::KeyboardBacklightOff => "\u{c0010}",
StaticIcon::GamepadBatteryFull => "\u{f074d}",
StaticIcon::GamepadBatteryMedium => "\u{f074f}",
StaticIcon::GamepadBatteryLow => "\u{f074e}",
Expand All @@ -251,7 +255,7 @@ impl StaticIcon {
}
}

fn is_custom_battery_icon(&self) -> bool {
fn is_custom_icon(&self) -> bool {
matches!(
self,
StaticIcon::KeyboardBatteryFull
Expand All @@ -269,19 +273,21 @@ impl StaticIcon {
| StaticIcon::HeadphoneBatteryLow
| StaticIcon::HeadphoneBatteryAlert
| StaticIcon::HeadphoneBatteryCharging
| StaticIcon::KeyboardBacklightOn
| StaticIcon::KeyboardBacklightOff
)
}

fn get_font(&self) -> &'static str {
if self.is_custom_battery_icon() {
if self.is_custom_icon() {
"Ashell Custom Icon"
} else {
"Symbols Nerd Font"
}
}

fn get_font_mono(&self) -> &'static str {
if self.is_custom_battery_icon() {
if self.is_custom_icon() {
"Ashell Custom Icon"
} else {
"Symbols Nerd Font Mono"
Expand Down
2 changes: 2 additions & 0 deletions src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -644,6 +644,7 @@ pub struct SettingsModuleConfig {
pub indicators: Vec<SettingsIndicator>,
#[serde(rename = "CustomButton")]
pub custom_buttons: Vec<SettingsCustomButton>,
pub keyboard_backlight_slider: bool,
}

impl Default for SettingsModuleConfig {
Expand Down Expand Up @@ -686,6 +687,7 @@ impl Default for SettingsModuleConfig {
SettingsIndicator::Battery,
],
custom_buttons: Default::default(),
keyboard_backlight_slider: Default::default(),
}
}
}
Expand Down
7 changes: 7 additions & 0 deletions src/modules/settings/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -214,6 +214,7 @@ impl Settings {
config.peripheral_indicators,
config.peripheral_battery_format,
config.peripheral_expanded_by_default,
config.keyboard_backlight_slider,
)),
audio: AudioSettings::new(AudioSettingsConfig::new(
config.audio_sinks_more_cmd,
Expand Down Expand Up @@ -514,6 +515,7 @@ impl Settings {
config.peripheral_indicators,
config.peripheral_battery_format,
config.peripheral_expanded_by_default,
config.keyboard_backlight_slider,
)));
self.audio
.update(audio::Message::ConfigReloaded(AudioSettingsConfig::new(
Expand Down Expand Up @@ -752,6 +754,11 @@ impl Settings {
.push(audio_sinks_group)
.push(audio_sources_group)
.push(self.brightness.slider().map(|e| e.map(Message::Brightness)))
.push(
self.power
.kbd_backlight_slider()
.map(|e| e.map(Message::Power)),
)
.push(quick_settings)
.spacing(space.md)
.into()
Expand Down
80 changes: 78 additions & 2 deletions src/modules/settings/power.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use crate::{
components::{
ButtonKind, IconPosition, divider, format_indicator,
icons::{StaticIcon, icon},
quick_setting_button, styled_button,
quick_setting_button, slider_control, styled_button,
},
config::{PeripheralIndicators, SettingsFormat},
services::{
Expand All @@ -13,11 +13,12 @@ use crate::{
},
t,
theme::use_theme,
utils::{self, IndicatorState, format_duration},
utils::{self, IndicatorState, format_duration, remote_value},
};
use iced::{
Alignment, Element, Length, Subscription, Task, Theme,
alignment::Vertical,
mouse::ScrollDelta,
widget::{Column, Row, column, container, row, text},
};

Expand Down Expand Up @@ -51,11 +52,13 @@ pub enum Message {
TogglePeripheralMenu,
TogglePowerProfile,
ToggleChargeLimit,
ToggleKbdBacklight,
Suspend,
Hibernate,
Reboot,
Shutdown,
Logout,
KbdBacklightChanged(remote_value::Message<u32>),
ConfigReloaded(PowerSettingsConfig),
}

Expand All @@ -77,6 +80,7 @@ pub struct PowerSettingsConfig {
pub peripheral_indicators: PeripheralIndicators,
pub peripheral_battery_format: SettingsFormat,
pub peripheral_expanded_by_default: bool,
pub keyboard_backlight_slider: bool,
}

impl PowerSettingsConfig {
Expand All @@ -92,6 +96,7 @@ impl PowerSettingsConfig {
peripheral_indicators: PeripheralIndicators,
peripheral_battery_format: SettingsFormat,
peripheral_expanded_by_default: bool,
keyboard_backlight_slider: bool,
) -> Self {
Self {
suspend_cmd,
Expand All @@ -104,6 +109,7 @@ impl PowerSettingsConfig {
peripheral_indicators,
peripheral_battery_format,
peripheral_expanded_by_default,
keyboard_backlight_slider,
}
}
}
Expand Down Expand Up @@ -137,6 +143,23 @@ impl PowerSettings {
ServiceEvent::Error(_) => Action::None,
},
Message::TogglePeripheralMenu => Action::TogglePeripheralMenu,
Message::ToggleKbdBacklight => {
if let Some(service) = self.service.as_mut()
&& let Some(backlight) = service.kbd_backlight.as_mut()
{
let new_value = if backlight.current.value() == 0 {
backlight.retained.unwrap_or(backlight.max)
} else {
backlight.retained = Some(backlight.current.value());
0
};
self.update(Message::KbdBacklightChanged(
remote_value::Message::RequestAndTimeout(new_value),
))
} else {
Action::None
}
}
Message::TogglePowerProfile => match self.service.as_mut() {
Some(service) => Action::Command(
service
Expand Down Expand Up @@ -175,6 +198,24 @@ impl PowerSettings {
utils::launcher::logout(&self.config.logout_cmd);
Action::None
}
Message::KbdBacklightChanged(message) => {
if let Some(service) = self.service.as_mut() {
// Send
if let Some(value) = message.value() {
let _ = service.command(UPowerCommand::SetKbdBacklight(value));
}
// Drive UI updates
if let Some(kbd_backlight) = service.kbd_backlight.as_mut() {
return Action::Command(
kbd_backlight
.current
.update(message)
.map(Message::KbdBacklightChanged),
);
}
};
Action::None
}
Message::ConfigReloaded(config) => {
self.config = config;
Action::None
Expand Down Expand Up @@ -529,6 +570,41 @@ impl PowerSettings {
})
}

pub fn kbd_backlight_slider<'a>(&'a self) -> Option<Element<'a, Message>> {
if !self.config.keyboard_backlight_slider {
return None;
}
let backlight = self.service.as_ref()?.kbd_backlight.as_ref()?;
let current = backlight.current.value();
Some(
slider_control(
if current != 0 {
StaticIcon::KeyboardBacklightOn
} else {
StaticIcon::KeyboardBacklightOff
},
0..=backlight.max,
current,
Message::KbdBacklightChanged,
move |delta| {
let y = match delta {
ScrollDelta::Lines { y, .. } => y,
ScrollDelta::Pixels { y, .. } => y,
};
let step = (5 * backlight.max / 100).max(1);
let new = if y > 0.0 {
(current + step).min(backlight.max)
} else {
current.saturating_sub(step)
};
Message::KbdBacklightChanged(remote_value::Message::RequestAndTimeout(new))
},
)
.on_icon_press(Message::ToggleKbdBacklight)
.into(),
)
}

pub fn subscription(&self) -> Subscription<Message> {
UPowerService::subscribe().map(Message::Event)
}
Expand Down
16 changes: 16 additions & 0 deletions src/services/upower/dbus.rs
Original file line number Diff line number Diff line change
Expand Up @@ -469,3 +469,19 @@ pub trait PowerProfiles {
#[zbus(property)]
fn set_active_profile(&self, profile: &str) -> zbus::Result<()>;
}

#[proxy(
default_service = "org.freedesktop.UPower",
default_path = "/org/freedesktop/UPower/KbdBacklight",
interface = "org.freedesktop.UPower.KbdBacklight"
)]
pub trait KbdBacklight {
fn get_max_brightness(&self) -> zbus::Result<i32>;

fn get_brightness(&self) -> zbus::Result<i32>;

fn set_brightness(&self, value: i32) -> zbus::Result<()>;

#[zbus(signal)]
fn brightness_changed(&self, value: i32) -> zbus::Result<()>;
}
Loading