Skip to content

✨ feat(compositor/hyprland): runtime config injection#41

Open
retrozinndev wants to merge 33 commits intoryofrom
feat/comp-config-injection
Open

✨ feat(compositor/hyprland): runtime config injection#41
retrozinndev wants to merge 33 commits intoryofrom
feat/comp-config-injection

Conversation

@retrozinndev
Copy link
Owner

@retrozinndev retrozinndev commented Jan 15, 2026

This makes colorshell inject it's own Hyprland config into the running instance without modifying the user's config files, it also fixes the Nix issue with colorshell's Hyprland config(#34).
Other than Hyprland, it also packs other config files like hyprlock into the gresource, then unpacks it into memory for later use on XDG_RUNTIME_DIR/colorshell/config.

Why isn't this merged yet?

I was waiting for a Hyprland bug(hyprwm/Hyprland#12984 (comment)) to be fixed. Now that it got fixed in hyprwm/Hyprland#13080, we just have to wait for it to get merged in the next Hyprland version.

Extra new features

  • colorshell now implements it's own grim+slurp abstraction; together with that, you can now take an active/focused client screenshot with ALT + PrintScrn or colorshell screenshot active.

Breaking Changes

Bindings like SUPER + K(terminal) and SUPER + E(file manager) have been removed from the shell configuration, as it's more of a personal choice; the user should configure it beforehand(or just use the default Hyprland configuration).

The input method editor(IME) is now fcitx5, which is less buggy1, faster and more integrated than the previous one, ibus.

(internal) The socket path has moved from XDG_RUNTIME_DIR/colorshell.sock to XDG_RUNTIME_DIR/colorshell/.sock for organization purposes.

Non-breaking changes

colorshell is now independent of the hyprshot program and now implements its own grim and slurp abstraction, using the Compositor API2.

Footnotes

  1. ibus had some annoying text entry issues; it would entirely clear the focused text entry if the window was opened with the entry focused + also other text entry-related issues.

  2. The Compositor API is an interface that makes it easier to implement support for different Wayland compositors, it's currently being worked on, and also, a small part of it is already being used internally.

@retrozinndev retrozinndev changed the title ✨ feat(compositor/hyprland): runtime config injection ✨ feat(compositor/hyprland): runtime config injection Jan 17, 2026
@retrozinndev retrozinndev added enhancement New feature or request compositor Something about colorshell's wayland compositor abstraction common Something that is being developed in a regular basis, with continuous work, but nothing critical. labels Feb 7, 2026
@HerXayah
Copy link

HerXayah commented Feb 8, 2026

I have been looking into the config injection part for a bit now (an hour).
I've been wondering.
How I understand gresources is bundling files within the final compiled thing.
Meaning whatever is in the configs that were bundled, is in the app.
How do you get around to having the thing even load the user configs, when what you load kinda has to be in the final compilation apart from recompiling the whole thing for every change, since it reads from the conf included first.

@retrozinndev
Copy link
Owner Author

I have been looking into the config injection part for a bit now (an hour). I've been wondering. How I understand gresources is bundling files within the final compiled thing. Meaning whatever is in the configs that were bundled, is in the app. How do you get around to having the thing even load the user configs, when what you load kinda has to be in the final compilation apart from recompiling the whole thing for every change, since it reads from the conf included first.

Here's how it works:
colorshell first reads the config files from its gresource at initialization, then it writes all the hyprland config files to XDG_RUNTIME_DIR(which is a tmpfs directory/it's stored in memory instead of disk), and finally, loads them on hyprland with hyprctl keyword source; which is the equivalent of sourcing another config file from hyprland.conf .

@HerXayah
Copy link

HerXayah commented Feb 8, 2026

I have been looking into the config injection part for a bit now (an hour). I've been wondering. How I understand gresources is bundling files within the final compiled thing. Meaning whatever is in the configs that were bundled, is in the app. How do you get around to having the thing even load the user configs, when what you load kinda has to be in the final compilation apart from recompiling the whole thing for every change, since it reads from the conf included first.

Here's how it works: colorshell first reads the config files from its gresource at initialization, then it writes all the hyprland config files to XDG_RUNTIME_DIR(which is a tmpfs directory/it's stored in memory instead of disk), and finally, loads them on hyprland with hyprctl keyword source; which is the equivalent of sourcing another config file from hyprland.conf .

sigh I feared that kinda 😭

Thanks for the response though ^-^

What I mean is, that how I use your colorshell personally is this:
https://github.com/HerXayah/mielladots/blob/main/install.sh

I never touch your .config files at all, instead supplying my own via stow symlinking it.
At least in my head, this would kinda bork stuff, unless I'm just mis-thinking in my head how the whole thing works.

@retrozinndev
Copy link
Owner Author

Also, forgot to mention, it also checks if the .last-updated file exists in XDG_RUNTIME_DIR/colorshell/config/hyprland/.last-updated, then, if it exists, it checks if there's a difference between the gresource's .last-updated and the written one under XDG_RUNTIME_DIR(i don't think we need a precise date checking thing, since it's just some config files), if there is a difference, colorshell overrides the "old" config files with the ones in the gresource.

This XDG_RUNTIME_DIR is completely temporary, since it's stored in RAM as a tmpfs, so we need to write the config files in every first-run after the user is logged in; if the user restarts colorshell in the same session, colorshell won't write the configs in memory again, just so it doesn't waste your RAMs lifetime without actually needing it.

@retrozinndev
Copy link
Owner Author

retrozinndev commented Feb 8, 2026

sigh I feared that kinda 😭

Thanks for the response though ^-^

I'm sorry if I overcomplicated it... haha

You're welcome 😁

What I mean is, that how I use your colorshell personally is this:
https://github.com/HerXayah/mielladots/blob/main/install.sh

I never touch your .config files at all, instead supplying my own via stow symlinking it.
At least in my head, this would kinda bork stuff, unless I'm just mis-thinking in my head how the whole thing works.

Ahh, I see. I don't think it'll break your system that much, it'll take some tinkering tho.
I removed some configs that seemed personal from the shell, like the terminal and file manager binds(as I mentioned in the main PR comment) + (this is the only actual breaking thing) window management binds.

I removed them because Hyprland's default config already provides all of it, and I'm trying to make colorshell the more customizable/less restricting it can be(also less intrusive, allowing the creation of a package to be able to install it), so hence the changes...

I recommend merging some of the ~/.config/hypr/shell/ files with your ~/.config/hypr/user/ ones(or, if you don't use this directory, merge it with your personal configs), then moving the user configs to the common ~/.config/hypr/ dir(just for a better looking structure, since ~/.config/hypr/shell is now-unused)
Just remove from the merged config bindings like SUPER + L, SUPER + N, and other colorshell-specific ones, those are configured in colorshell's own Hyprland config.

I'll try doing a migration thing in the update script, so you won't have to do all that manually.

@HerXayah
Copy link

HerXayah commented Feb 8, 2026

Also, forgot to mention, it also checks if the .last-updated file exists in XDG_RUNTIME_DIR/colorshell/config/hyprland/.last-updated, then, if it exists, it checks if there's a difference between the gresource's .last-updated and the written one under XDG_RUNTIME_DIR(i don't think we need a precise date checking thing, since it's just some config files), if there is a difference, colorshell overrides the "old" config files with the ones in the gresource.

This XDG_RUNTIME_DIR is completely temporary, since it's stored in RAM as a tmpfs, so we need to write the config files in every first-run after the user is logged in; if the user restarts colorshell in the same session, colorshell won't write the configs in memory again, just so it doesn't waste your RAMs lifetime without actually needing it.

sigh I feared that kinda 😭
Thanks for the response though ^-^

I'm sorry if I overcomplicated it... haha You're welcome 😁

What I mean is, that how I use your colorshell personally is this:
https://github.com/HerXayah/mielladots/blob/main/install.sh
I never touch your .config files at all, instead supplying my own via stow symlinking it.
At least in my head, this would kinda bork stuff, unless I'm just mis-thinking in my head how the whole thing works.

Ahh, I see. I don't think it'll break your system that much, it'll take some tinkering tho. I removed some configs that seemed personal from the shell, like the terminal and file manager binds(as I mentioned in the main PR comment) + (this is the only actual breaking thing) window management binds.

I removed them because Hyprland's default config already provides all of it, and I'm trying to make colorshell the more customizable/less restricting it can be, so rence the changes...

I recommend merging some of the ~/.config/shell/ files with your ~/.config/user/ ones, them moving the user configs to the common ~/.config/hypr/ dir(just for a better looking structure, since ~/.config/hypr/shell is now-unused) Just remove from the merged config bindings like SUPER + L, SUPER + N, and other colorshell-specific ones, those are configured in colorshell's own Hyprland config.

I'll try doing a migration thing in the update script, so you won't have to do all that manually.

I am chaos! MUHAHAH!
haha... I hacked that together in 2 hours today out of boredom and after failing at AGS.

Okay, so you moved the internal ones into it.
Would keybind management be inside the shell itself going forward or via the config file?
Since you load them once, that would mean changing keybinds must be somewhere inside the app, as you read the actual files etc.

@retrozinndev
Copy link
Owner Author

retrozinndev commented Feb 8, 2026

I am chaos! MUHAHAH!
haha... I hacked that together in 2 hours today out of boredom and after failing at AGS.

That's crazy lmao, a lot of stuff for 2 hours 😆
But I really recommend learning how to use AGS and the Astal libraries, you'll surely learn a lot of valuable stuff!

Okay, so you moved the internal ones into it.

Yep.

Would keybind management be inside the shell itself going forward or via the config file?

It's now stored in one of the config files that are sourced/imported at runtime.

Since you load them once, that would mean changing keybinds must be somewhere inside the app, as you read the actual files etc.

Nahh, you can configure hyprland just how you would normally in a clean install, that's why I'm doing this, makes things a lot cleaner.

You should just add an exec-once = ~/.local/bin/colorshell and boom, colorshell works out of the box

@HerXayah
Copy link

HerXayah commented Feb 8, 2026

I am chaos! MUHAHAH!
haha... I hacked that together in 2 hours today out of boredom and after failing at AGS.

That's crazy lmao, a lot of stuff for 2 hours 😆 But I really recommend learning how to use AGS and the Astal libraries, you'll surely learn a lot of valuable stuff!

Okay, so you moved the internal ones into it.

Yep.

Would keybind management be inside the shell itself going forward or via the config file?

It's now stored in one of the config files that are sourced/imported at runtime.

Since you load them once, that would mean changing keybinds must be somewhere inside the app, as you read the actual files etc.

Nahh, you can configure hyprland just how you would normally in a clean install, that's why I'm doing this, makes things a lot cleaner.

Nah. Nah nah nah!
The Documentation is very horrible in my opinion on Astral Libs.
Have fun getting Cava to work. It wont.... URK. PAIN!
The file is in the UI folder in my repo in the Bar.tsx xD
its painful

Also check. Okay, good, then ill wait patiently and excitedly

@retrozinndev
Copy link
Owner Author

Nah. Nah nah nah!
The Documentation is very horrible in my opinion on Astral Libs.

I don't think so... The usage of the libraries are pretty straightforward, a lot of them have built-in documentation for each functions and classes.

Have fun getting Cava to work. It wont.... URK. PAIN!

I tried adding a cava display into the media widget... I couldn't lmao

The thing is that I don't know much about Cairo(GTK's renderer), I should learn it a little bit more so I can actually try to do this properly.

The file is in the UI folder in my repo in the Bar.tsx xD
its painful

Also check. Okay, good, then ill wait patiently and excitedly

Oh you did the implementation?! That's crazy work!! I'll surely take a look at it as soon as I can

@retrozinndev
Copy link
Owner Author

You can't seem to have uploaded the fork tho, did you change the name of the repo to something custom? Or is it private?

@HerXayah
Copy link

HerXayah commented Feb 8, 2026

You can't seem to have uploaded the fork tho, did you change the name of the repo to something custom? Or is it private?

https://github.com/HerXayah/mielladots/blob/main/UI%2Fwidget%2FBar.tsx

This i mean.
I tried it myself for 5 hours, i can get values and read them. It just doesnt display shit.
Had it then shot through an AI (urk fuck ai) because i was at my wits end and just gave up

@retrozinndev
Copy link
Owner Author

retrozinndev commented Feb 8, 2026

This i mean.

Thanks! I just took a look at it. You seem to have tinkered a lot with it already 😆

I tried it myself for 5 hours, i can get values and read them. It just doesnt display shit.

From what I could see, the style/css is not being updated, since you're not binding it to anything, so it'll get stuck to the first value it gets. Try binding it to the current bar's value and then transforming it to the stylesheet.

Just a quick guess tho, not entirely sure.

Had it then shot through an AI (urk fuck ai) because i was at my wits end and just gave up

I feel that...

@retrozinndev retrozinndev force-pushed the feat/comp-config-injection branch from a8f23f9 to 12547cb Compare February 9, 2026 12:58
…fig, unbind colorshell binds

colorshell now unbinds shell-exclusive key combinations before adding them, so it avoids duplicate actions if the user had set to something else previously
…rocess to the shell, add process util functions
colorshell now beeps when the compositor sends a `bell` signal!
it now waits for a previous reading operation to end before starting a new one, avoiding the error message
we wait a little bit to re-launch hyprsunset after killing the existing instance
… not found

Hyprland and hyprpaper default configuration files will be installed if they're not found at their dirs. Also, colorshell now asks if the user want's to add an autostart/exec-once line to their Hyprland config file
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

common Something that is being developed in a regular basis, with continuous work, but nothing critical. compositor Something about colorshell's wayland compositor abstraction enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants