Skip to content

feat: Add keyboard back-light quick setting with slider - #883

Open
3bnz wants to merge 8 commits into
MalpenZibo:mainfrom
3bnz:kbd-backlight
Open

feat: Add keyboard back-light quick setting with slider#883
3bnz wants to merge 8 commits into
MalpenZibo:mainfrom
3bnz:kbd-backlight

Conversation

@3bnz

@3bnz 3bnz commented Jul 21, 2026

Copy link
Copy Markdown
output.mp4
  • Adds a quick setting toggle with a slider in the menu for controlling built-in keyboard backlight.
  • Supports a single keyboard - which should be fine since this does not concern bluetooth and usb peripherals.
  • When toggling back-light off and on again the previous brightness value is retained
  • Backlight symbol is not included i
    n nerd-fonts so I drew the missing icons and added them to AshellCustomIcon-Regular.otf

*I used fontforge to edit the font. You can see that after the edit - the size has decreased. Not sure why, but I did test that mouse and keyboard status bar icons still look as expected.

@romanstingler

romanstingler commented Aug 3, 2026

Copy link
Copy Markdown
Collaborator

I like the feature, even if for some reason my HP is still not supported (not the issue of this here).
I will be honest, I don't like the UI.

In my opinion, we can use the same sliders as for the other components.
Or we can discuss wide sliders (like i.e. Android)

image

https://github.com/user-attachments/assets/abbe39c5-1fae-4333-aa6b-6810743300c5
demo at https://github.com/romanstingler/ashell/tree/feature/kbd ()no real kbd brightness, due to the lack of drivers supporting it for my system)

But a button that opens the slider is nothing I would like to have.

@MalpenZibo

Copy link
Copy Markdown
Owner

Hi, thanks for the support!

From my point of view, we should place a config setting to enable this option (by default, I prefer to hide this functionality. Then we should probably change the UX. A quick settings with a simple slider seems too much. Maybe we should simply place the slider under the screen brightness.

@romanstingler

Copy link
Copy Markdown
Collaborator

yes I agree, just add it under the brightness slider.

@3bnz

3bnz commented Aug 15, 2026

Copy link
Copy Markdown
Author

@MalpenZibo thanks for the feedback!

Quick Setting

The main reason for placing the slider inside a quick-setting was to copy gnome and macOS quick settings.
Personally I don't have a strong opinion here - so the PR has been simplified to a simple inline slider.
The toggle action is still kept in the leading button:

2026-08-15_14-01-53

Config Flag

As for the configuration flag - the slider would be already hidden for any system without built-in keyboard backlight - this includes USB keboards since they normally handle backlight using keyboard shortcuts.
I added the flag if it's prefferred but feel free to revert the last commit if you change your mind ;)

@3bnz

3bnz commented Aug 15, 2026

Copy link
Copy Markdown
Author

@romanstingler
Cool demo! While out of scope for this feature - I also preffer thick sliders.
We could explore writing a custom widget for the whole shell - the default iced sliders are a bit crude/simple indeed.
This could allow us to handle scrollwheel as well as animate "jumps" in a single place.

@romanstingler romanstingler left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I had a look,
first I added the icons to the font just replace these files with yours in assets/

ashell_custom_icon_project.zip

  • keyboard_backlight_slider is undocumented in the docs

  • scroll step logic is duplicated verbatim from brightness.rs, same 5% calculation and clamp (NO NEED TO de-duplicate now, there will be a cleanup session later over more code)

The biggest thing is that each slider tick spawns a fresh tokio task that builds a new proxy and calls set_brightness. Those tasks run concurrently and their completion order depends on the scheduler. If task N-1 lands after task N, the backlight settles one step off from where you dropped the slider, and UPower reports that value back so the UI shows the wrong-but-real state with no correction. The brightness service solves this with a commander channel and a throttle that coalesces writes and keeps them ordered.

Comment on lines +945 to +948
UPowerCommand::SetKbdBacklight(brightness) => {
let _ = self.commander.send(brightness);
iced::Task::none()
}

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is the only new code in the function.
rest is just indentation change and splitting into separate match arms due to fact that Task::none() can now be returned.

@3bnz

3bnz commented Aug 25, 2026

Copy link
Copy Markdown
Author

Icons

Thanks for the icons @romanstingler! My svgs where way too small though - not even visible.
I scaled them up and them again - now in https://www.glyphrstudio.com/ project.

2026-08-25_18-53-57

I hope this is the propper way.

Commmander

so the UI shows the wrong-but-real state with no correction

I think this is only partially true - we have the Remote<Value> wrapper, which will show the source of truth after a timeout.

That being said - while it "works on my machine" due to backlight changes being near instantaneous - it would indeed be more robust to have a proper throttled rx/tx queue.

The commander has been added to the upower service (slider only). :)

@3bnz
3bnz requested a review from romanstingler August 25, 2026 16:03
Add a Keyboard Backlight section to the settings module page covering
`keyboard_backlight_slider`, the UPower requirement, the icon toggle and
the 5% scroll step, plus the option in the full config example and the
developer config reference.
Comment thread src/services/upower/mod.rs Outdated
.collect();

let (tx, rx) = tokio::sync::mpsc::unbounded_channel();
Self::start_commander(conn.clone(), rx);

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe we should start the commander only if we can actually send a command to the device and the feature is enabled in the config

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Patched.

Comment thread src/services/upower/mod.rs Outdated
pub power_profile: PowerProfile,
pub kbd_backlight: Option<KbdBacklight>,
conn: zbus::Connection,
commander: UnboundedSender<u32>,

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's strange to see an Option that is only present if the device supports the feature and a commander that is always present to send a command to change the KdbBacklight. Probably we should place both stuff in the same Option

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My bad - also patched.

By the way I have gone on a small side-quest - looking at implementing a custom widget,
which would also remove the need for commanders.
More info: #931 (comment)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants