termusic icon indicating copy to clipboard operation
termusic copied to clipboard

Allow termusic to apply tui theme colors externally (pywal support)

Open uwidev opened this issue 1 year ago • 1 comments

Describe what you want

Allow termusic to apply (update) tui theme colors externally.

The specific thing I want to do is to integrate pywal into the tui themes, so that colors can sync with a different wallpaper. Pywal is only able to change the background color, and is unable to change anything else (border, foreground, highlight, etc).

Do you have already an idea for the implementation?

  • Reapply the current theme when a client receives SIGUSR1.
  • Automatically apply current theme on modifications to the currently watched file theme.yml.
  • Perhaps do some similar shenanigans with the termusic-server.

Of course, users would have to write their own scripts, something like...

wal -i "new-img.png"
cp ~/.cache/wal/colors-termusic.yml ~/.config/termusic/themes/pywal.yml
killall -SIGUSR1 -e termusic # exactly termusic, not termusic-server

Update: I also learned that termusic does not load the current them on start. I'm assuming it uses the tui.yml file instead... which while isn't impossible to hook into and modify, is quite inconvenient considering the functionality already exists to just load a theme, and it still doesn't update the terminal during operation.

uwidev avatar Jun 21 '24 04:06 uwidev

Interesting idea. I will put it to todo list.

tramhao avatar Aug 23 '24 16:08 tramhao

The specific thing I want to do is to integrate pywal into the tui themes, so that colors can sync with a different wallpaper. Pywal is only able to change the background color, and is unable to change anything else (border, foreground, highlight, etc).

Just to reiterate the current state, the options for termusic themeing are:

  • directly modify tui.toml's theme
  • add a theme into the themes folder (which should exist where the configs are) and load it again on update

Perhaps do some similar shenanigans with the termusic-server.

What would you want out of termusic-server that has to do with themes?

I also learned that termusic does not load the current them on start. I'm assuming it uses the tui.yml file instead...

Yes, termusic(tui) only reads a theme once on select in the config editor, then saves the values to the tui.toml, where it is read and applied from every start.


From what i can tell, pywal seems to be discontinued without reference to it having moved to somewhere else or being renamed, is this still a active project?

hasezoey avatar Jan 26 '25 13:01 hasezoey

It's been a while since I've touched turmusic, but when I was using it, I couldn't get it to use built-in terminal colors. It seemed like the theme it applies overwrites that.

Pywal is archived, but it has many forks and successors. Generally, pywal's system works by generating a palette of colors from an image and outputting some template that caters to another application's theme file, which said application would then dynamically update its colors. The current iteration of pywal I use is wallust.

I think the most simplest change that would fix this is to allow termusic to update based on terminal colors when a "theme" is selected. The other option I proposed was to watch the current theme file for any modifications, and if so, update tui with the new theme.

So this feature is more so about dynamically updating colors (instead of only at the start or on theme selection) rather than specific pywal support.

I also have no idea where I was going on with termusic-server.

uwidev avatar Jan 26 '25 14:01 uwidev

I just tried it in a hacky way:

Patch used to make it work
diff --git a/lib/src/config/v2/tui/theme/mod.rs b/lib/src/config/v2/tui/theme/mod.rs
index a2e305ba..b6ffca9c 100644
--- a/lib/src/config/v2/tui/theme/mod.rs
+++ b/lib/src/config/v2/tui/theme/mod.rs
@@ -30,24 +30,24 @@ impl ThemeWrap {
     pub fn get_color_from_theme(&self, color: ColorTermusic) -> Color {
         match color {
             ColorTermusic::Reset => Color::Reset,
-            ColorTermusic::Foreground => self.theme.primary.foreground.into(),
-            ColorTermusic::Background => self.theme.primary.background.into(),
-            ColorTermusic::Black => self.theme.normal.black.into(),
-            ColorTermusic::Red => self.theme.normal.red.into(),
-            ColorTermusic::Green => self.theme.normal.green.into(),
-            ColorTermusic::Yellow => self.theme.normal.yellow.into(),
-            ColorTermusic::Blue => self.theme.normal.blue.into(),
-            ColorTermusic::Magenta => self.theme.normal.magenta.into(),
-            ColorTermusic::Cyan => self.theme.normal.cyan.into(),
-            ColorTermusic::White => self.theme.normal.white.into(),
-            ColorTermusic::LightBlack => self.theme.bright.black.into(),
-            ColorTermusic::LightRed => self.theme.bright.red.into(),
-            ColorTermusic::LightGreen => self.theme.bright.green.into(),
-            ColorTermusic::LightYellow => self.theme.bright.yellow.into(),
-            ColorTermusic::LightBlue => self.theme.bright.blue.into(),
-            ColorTermusic::LightMagenta => self.theme.bright.magenta.into(),
-            ColorTermusic::LightCyan => self.theme.bright.cyan.into(),
-            ColorTermusic::LightWhite => self.theme.bright.white.into(),
+            ColorTermusic::Foreground => Color::Reset,
+            ColorTermusic::Background => Color::Reset,
+            ColorTermusic::Black => Color::Black,
+            ColorTermusic::Red => Color::Red,
+            ColorTermusic::Green => Color::Green,
+            ColorTermusic::Yellow => Color::Yellow,
+            ColorTermusic::Blue => Color::Blue,
+            ColorTermusic::Magenta => Color::Magenta,
+            ColorTermusic::Cyan => Color::Cyan,
+            ColorTermusic::White => Color::White,
+            ColorTermusic::LightBlack => Color::DarkGray,
+            ColorTermusic::LightRed => Color::LightRed,
+            ColorTermusic::LightGreen => Color::LightGreen,
+            ColorTermusic::LightYellow => Color::LightYellow,
+            ColorTermusic::LightBlue => Color::LightBlue,
+            ColorTermusic::LightMagenta => Color::LightMagenta,
+            ColorTermusic::LightCyan => Color::LightCyan,
+            ColorTermusic::LightWhite => Color::White,
         }
     }

and as for the ColorTermusic used, it is basically lib::config::v2::tui::theme::styles::Styles::default

Konsole Breath theme (ie default terminal theme): Konsole Breath Theme

wallust vscode theme: wallust vscode theme

wallust theme for my profile picture (just as a random test): Profile theme

For context, the Termusic Default theme without the patch: termusic default theme

Note: All assigned colors and styles likely should be looked over again and made consistent or something.


Does this look somewhat acceptable? In any case, with the way themes are currently implemented in termusic, it would require:

  • all theme fields to be Option, which could be mis-matched if some exist and some dont, or
  • a complete optional theme(ie make [theme] optional) or
  • a config option to use the native theme (while keeping the other theme values; ie add a [theme.use_native] field).

A final alternative would be to just have any wal implementation just generate a theme for termusic.

What approach would you want @tramhao ? I think the least invasive would be to make [theme] optional or add a [theme.use_native] field.

hasezoey avatar Jan 27 '25 11:01 hasezoey

I saw a youtuber evaluating termusic and said that pywal support is important for her. I guess it is what we'll do then. Haven't look into it but it shouldn't be too hard. I think we should read the output from pywal into current used theme. The whole reload code is already there. Theme.use_native you mean if we set this, it'll not use pywal themes?

tramhao avatar Mar 31 '25 08:03 tramhao

Theme.use_native you mean if we set this, it'll not use pywal themes?

Well if the terminal is configured to have the pywal output (or any other) as the theme, then theme.use_native would use those colors. Though i would also not have anything against direct pywal support. Or said differently, it will bypass our currently existing color system and directly output ASCII color codes and let the terminal decide which colors they should actually be.

hasezoey avatar Mar 31 '25 09:03 hasezoey

I got your ideas. use_native would read these colors from terminal and there will be no more further handling from termusic. It sounds clean.

tramhao avatar Mar 31 '25 09:03 tramhao

use_native would read these colors from terminal and there will be no more further handling from termusic.

Just to clarify, termusic would not read those colors from the terminal (is that even possible?) but just output standard ASCII color codes (which the terminal defines the actual color used) instead of RGB ones.

hasezoey avatar Mar 31 '25 09:03 hasezoey

I just uploaded a branch named pywal. The result is ok. As I'm not sure of the new v2 theme style, I don't know if it is the right place for bool: use_native. Would you please check this? @hasezoey

tramhao avatar Apr 01 '25 15:04 tramhao

As I'm not sure of the new v2 theme style, I don't know if it is the right place for bool: use_native.

From what i can tell, at state 348306223dfa27f9df57cc4e5717193cec95c4da, the bool is on the top-level instead of on themes, i think the confusion came as it is currently placed in ThemeWrap, which has serde(flatten), to actually put it under config option theme, you will have to put it in ThemeColors.

Additionally, i think use_native should be disabled when selecting another theme in the theme selector (otherwise some stuff changes, like the border for selectable themes, but nothing else until disabled again).

Now that i see a more proper implementation, i also think a bool is not the best option, but it is a start. How about we just do a shadow theme like i did for Termusic Default instead? Though this would mean it would overwrite the existing theme and we either need to add a new possible color (currently only hex colors #000 are supported), or just ignore those when on native theme. Which approach would be better?

hasezoey avatar Apr 02 '25 10:04 hasezoey

As i did not see any new development in this issue or on branch pywal, i took a shot at creating what i had now proposed in my last comment in #475. TL;DR: That PR adds a new "Fake" / "No File" Theme (like Termusic Default) and fully integrates with the theme preview without having to do much extra. Also adds a new possible tui.toml theme value native, where before only hex values were supported.

What do you all think, does this solve the issue?

PS: as for the dynamic part, as soon as the terminal itself (for example alacritty) reloads its theme, termusic has the theme also reloaded (due to not outputting specific rgb values).

hasezoey avatar Apr 18 '25 10:04 hasezoey