Skip to content

feat(theme): add sway bar color integration#2154

Open
him-cyber wants to merge 1 commit intogreshake:masterfrom
him-cyber:sway-theme-override
Open

feat(theme): add sway bar color integration#2154
him-cyber wants to merge 1 commit intogreshake:masterfrom
him-cyber:sway-theme-override

Conversation

@him-cyber
Copy link
Copy Markdown

@him-cyber him-cyber commented Apr 3, 2025

Summary

This PR introduces optional integration with the user's Sway configuration to automatically apply bar colors (background and foreground) from the ~/.config/sway/config file. Fix for the open issue #2145

Motivation

As a Wayland-native window manager, Sway allows defining custom bar colors. This enhancement bridges the theme configuration in i3status-rust with Sway’s color settings, improving visual consistency and user experience for Sway users.

Implementation

  • Introduced a sway_integration section in config.toml
  • Parsed Sway bar colors (background, statusline) from the local Sway config
  • Applied parsed colors to the theme's idle_bg and idle_fg fields
  • Added necessary Rust glue code with minimal footprint

Config Usage

To enable this, add to your config.toml:

[sway_integration]
use_sway_bar_colors = true

@bim9262
Copy link
Copy Markdown
Collaborator

bim9262 commented Mar 8, 2026

Instead of trying to read the config from disk, I'd recommend using swayipc_async to get the values.

Here's a toy program that reads the background and statusline colors:

use swayipc_async::Connection;

#[tokio::main]
async fn main() {
    let mut connection = Connection::new().await.unwrap();
    if let Some(bar_id) = connection.get_bar_ids().await.unwrap().first() {
        let bar_config = connection.get_bar_config(bar_id).await.unwrap();
        println!(
            "Bar config for {}: background {:?} statusline {:?}",
            bar_id, bar_config.colors.background, bar_config.colors.statusline
        );
    }
}

Here's another extension of this that finds the bar id for the current i3status-rust that's running:

use std::{os::unix::process::parent_id, path::Path};
use swayipc_async::Connection;
use tokio::io::AsyncReadExt as _;

pub async fn read_file(path: impl AsRef<Path>) -> std::io::Result<String> {
    let mut file = tokio::fs::File::open(path).await?;
    let mut content = String::new();
    file.read_to_string(&mut content).await?;
    Ok(content.trim_end().to_string())
}

#[tokio::main]
async fn main() {
    let mut connection = Connection::new().await.unwrap();
    eprintln!("Parent process ID: {}", parent_id());
    let ppid_stat = read_file(
        Path::new("/proc")
            .join(parent_id().to_string())
            .join("stat"),
    )
    .await
    .unwrap();
    let grandppid = ppid_stat.split(' ').nth(3).unwrap();
    eprintln!("Grandparent process ID: {}", grandppid);
    let grandppid_cmdline = read_file(Path::new("/proc").join(grandppid).join("cmdline"))
        .await
        .unwrap();
    let grandppid_cmdline_parts: Vec<_> = grandppid_cmdline.split('\0').collect();
    if let Some(bar_id) = grandppid_cmdline_parts
        .iter()
        .position(|&s| s == "-b" || s == "--bar_id")
        .and_then(|pos| grandppid_cmdline_parts.get(pos + 1))
    {
        let bar_config = connection.get_bar_config(&bar_id).await.unwrap();
        eprintln!(
            "Bar config for {}: background {:?} statusline {:?}",
            bar_id, bar_config.colors.background, bar_config.colors.statusline
        );
    }

    println!("{{\"version\": 1, \"click_events\": true}}\n[");
    loop {
        println!("[],")
    }
}

This will be able to get the arguments that are used to start bar:

(excerpt from pstree -ap)

  |           |-swaybar,2147460 -b bar-1
  |           |   |-sh,2147520 -c /tmp/sway_test/target/debug/sway_test 2> /tmp/l
  |           |   |   `-sway_test,2147521

and the sway config:

set $background #ffdddd
bar {
  position top
  strip_workspace_numbers yes
  height $bar_height
  status_padding 0

  # When the status_command prints a new line to stdout, swaybar updates.
  status_command /tmp/sway_test/target/debug/sway_test 2> /tmp/l

  colors {
          background $background
          statusline #222222
          separator #666666

  #                          border  backgr. text
          focused_workspace #0088CC #0088CC #ffffff
          active_workspace #333333 #333333 #ffffff
          inactive_workspace #333333 #333333 #888888
          urgent_workspace #2f343a #900000 #ffffff
  }
}

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.

2 participants