How to Customize Jellium-Desktop’s Appearance: Web UI and Native Window Theming

Jellium-desktop’s appearance is controlled by a generated CSS theme for the jellyfin-web overlay and a Rust theme module that synchronizes the native window title-bar with the web UI’s <meta name="theme-color"> tag, configurable through built-in stylesheets, custom CSS files, and the titlebarThemeColor config option.

Jellium-desktop combines an embedded web interface with platform-native window decorations. You can customize jellium-desktop’s appearance by modifying both the web overlay and the native host window. In the andrewrabert/jellium-desktop repository, theming is split between the CEF-based UI layer and the OS-level window chrome.

How the Jellium-Desktop Theme System Works

The application manages appearance through two distinct but connected layers.

Web UI Layer

The web UI layer controls colors, fonts, and layout inside the overlay. In src/jfn_cef/src/resource.rs, a generated theme.css is served at app://resources/theme.css. This stylesheet defines CSS variables such as --bg-color and --primary-color that the jellyfin-web interface consumes, and the CEF resource handler injects it into the browser context.

Native Window Layer

The native window layer handles platform-specific decorations including the title-bar and background color. The Rust theme module in src/color/src/theme.rs tracks the <meta name="theme-color"> tag emitted by the web UI and forwards that color to the operating system. On Windows, the tint applies through DWM. On macOS, it dispatches to an Objective-C helper. On Wayland, it renders a solid-color placeholder while the overlay loads.

Customizing the Web UI Appearance

You have three primary ways to customize the visual style of the embedded web interface.

Edit the Built-In theme.css

The default stylesheet is produced by the theme_css() function and served through src/jfn_cef/src/resource.rs. Modifying this function or the generated file changes the default values of CSS variables like --bg-color and --primary-color across the overlay UI.

Add a Custom Stylesheet

Drop a file named custom.css next to the Jellium binary, then reference it inside src/web/overlay.html with a standard <link> tag. Rules in this file override the default theme because the browser loads them after theme.css.

<link rel="stylesheet" href="theme.css">
<link rel="stylesheet" href="custom.css">

Change the Meta Theme Color at Runtime

The JavaScript shim in src/web/native-shim.js observes the <meta name="theme-color"> tag. When a user selects a different theme, the shim calls window.jmpNative.themeColor('#RRGGBB'). That call crosses to the Rust side via the ThemeColor IPC and updates the native title-bar. You can also force a color manually from the browser console:

// Force a light theme from the console
document.querySelector('meta[name="theme-color"]').setAttribute('content', '#ffffff');

Customizing the Native Window Appearance

The color shown in the window chrome is driven by the theme singleton in src/color/src/theme.rs. It stores two callbacks:

  • on_set_theme_color(u32) — applied only when the titlebarThemeColor config option is enabled.
  • on_set_bg_hex(*const c_char) — always called to keep the mpv background synchronized with the web UI.

Toggle Title-Bar Theming via Config

The configuration option titlebarThemeColor lives in src/config/src/lib.rs. When set to true, the title-bar follows the web UI’s theme color. When false, the title-bar remains a static color (default #101010).


# src/config/jellium.toml

titlebarThemeColor = true

The underlying Rust accessor looks like this:

pub fn titlebar_theme_color() -> bool { … }

Platform-Specific Native Implementations

Each platform handles the forwarded color differently.

Windows: src/windows/src/lib.rs calls win_set_theme_color(rgb), which loads dwmapi.dll to tint the DWM title-bar.

macOS: src/macos/src/lib.rs forwards the value to macos_set_theme_color, which dispatches to the main thread and invokes the Objective-C helper apply_theme_color_to_window.

Wayland: src/wayland/src/make_platform.rs implements set_theme_color(&self, rgb) and renders a solid-color placeholder while the overlay finishes loading.

Practical Code Examples

Override the Theme Color from Rust

If you are writing a plugin or patching the binary, you can force a specific title-bar color by calling the native callback directly:

use jfn_color::theme::jfn_theme_color_on_color;

// Force a dark title-bar
unsafe { jfn_theme_color_on_color(0x202020) };

Add the following line to src/web/overlay.html after the default theme link:

<link rel="stylesheet" href="custom.css">

Place your override rules in custom.css beside the Jellium executable.

Toggle Native Sync in Config

Enable automatic window decoration theming by setting the config value:

titlebarThemeColor = true

Set it to false to lock the native title-bar to the static default.

Summary

Frequently Asked Questions

How do I change the default theme color in jellium-desktop without editing Rust code?

Place a custom.css file next to the Jellium binary and load it via a <link> tag in src/web/overlay.html. You can also change the <meta name="theme-color"> content from JavaScript, which triggers the native shim to update the window decoration if titlebarThemeColor is enabled.

What file controls the native title-bar color on Windows?

On Windows, src/windows/src/lib.rs defines win_set_theme_color(rgb), which calls into dwmapi.dll to apply the tint to the DWM title-bar. The function receives its value from the theme singleton in src/color/src/theme.rs.

Can I prevent the native title-bar from following the web UI theme?

Yes. Set titlebarThemeColor = false in your configuration file. According to src/config/src/lib.rs, this disables the on_set_theme_color callback and keeps the title-bar at its static default of #101010.

Does the mpv background stay in sync with the theme automatically?

Yes. The on_set_bg_hex(*const c_char) callback in src/color/src/theme.rs is always invoked regardless of the titlebarThemeColor setting, ensuring the mpv background remains visually consistent with the web UI.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →