Add caps lock indicator and keyboard layout support
CI / build-ubuntu (, default) (push) Has been cancelled
CI / build-ubuntu (--features networking, networking) (push) Has been cancelled
CI / build-ubuntu (--no-default-features, no-default-features) (push) Has been cancelled
CI / build-debian (push) Has been cancelled
CI / build-fedora (push) Has been cancelled
CI / build-arch (push) Has been cancelled
CI / build-opensuse (push) Has been cancelled
CI / build-ubuntu (, default) (push) Has been cancelled
CI / build-ubuntu (--features networking, networking) (push) Has been cancelled
CI / build-ubuntu (--no-default-features, no-default-features) (push) Has been cancelled
CI / build-debian (push) Has been cancelled
CI / build-fedora (push) Has been cancelled
CI / build-arch (push) Has been cancelled
CI / build-opensuse (push) Has been cancelled
- Add caps lock ring color change when caps lock is enabled (matching swaylock-effects) - Add configurable caps lock colors: ring, text, key highlight, backspace highlight - Add show_caps_lock_text config option (enabled by default) - Add keyboard layout display with show_keyboard_layout option (disabled by default) - Change keyboard_layout from u32 to String for proper display - Add rust-cache to CI and dbus-1-dev dependency
This commit is contained in:
@@ -24,6 +24,7 @@ jobs:
|
|||||||
args: "--no-default-features"
|
args: "--no-default-features"
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
|
- uses: Swatinem/rust-cache@v2
|
||||||
- name: Install system dependencies
|
- name: Install system dependencies
|
||||||
run: |
|
run: |
|
||||||
sudo apt-get update
|
sudo apt-get update
|
||||||
@@ -31,7 +32,7 @@ jobs:
|
|||||||
llvm clang libclang-dev \
|
llvm clang libclang-dev \
|
||||||
pkg-config \
|
pkg-config \
|
||||||
libglib2.0-dev libcairo2-dev libpango1.0-dev libatk1.0-dev \
|
libglib2.0-dev libcairo2-dev libpango1.0-dev libatk1.0-dev \
|
||||||
libpam0g-dev \
|
libpam0g-dev libdbus-1-dev \
|
||||||
libwayland-dev libxkbcommon-dev
|
libwayland-dev libxkbcommon-dev
|
||||||
- name: Build (${{ matrix.features }})
|
- name: Build (${{ matrix.features }})
|
||||||
run: cargo build --verbose ${{ matrix.args }}
|
run: cargo build --verbose ${{ matrix.args }}
|
||||||
@@ -43,6 +44,7 @@ jobs:
|
|||||||
container: debian:stable-slim
|
container: debian:stable-slim
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
|
- uses: Swatinem/rust-cache@v2
|
||||||
- name: Install system dependencies
|
- name: Install system dependencies
|
||||||
run: |
|
run: |
|
||||||
apt-get update
|
apt-get update
|
||||||
@@ -50,7 +52,7 @@ jobs:
|
|||||||
llvm clang libclang-dev \
|
llvm clang libclang-dev \
|
||||||
pkg-config \
|
pkg-config \
|
||||||
libglib2.0-dev libcairo2-dev libpango1.0-dev libatk1.0-dev \
|
libglib2.0-dev libcairo2-dev libpango1.0-dev libatk1.0-dev \
|
||||||
libpam0g-dev \
|
libpam0g-dev libdbus-1-dev \
|
||||||
libwayland-dev libxkbcommon-dev \
|
libwayland-dev libxkbcommon-dev \
|
||||||
cargo rustc
|
cargo rustc
|
||||||
- name: Build
|
- name: Build
|
||||||
@@ -61,13 +63,14 @@ jobs:
|
|||||||
container: fedora:latest
|
container: fedora:latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
|
- uses: Swatinem/rust-cache@v2
|
||||||
- name: Install system dependencies
|
- name: Install system dependencies
|
||||||
run: |
|
run: |
|
||||||
dnf install -y \
|
dnf install -y \
|
||||||
llvm clang libclang-devel \
|
llvm clang libclang-devel \
|
||||||
pkg-config \
|
pkg-config \
|
||||||
glib2-devel cairo-devel pango-devel atk-devel \
|
glib2-devel cairo-devel pango-devel atk-devel \
|
||||||
pam-devel \
|
pam-devel dbus-devel \
|
||||||
wayland-devel libxkbcommon-devel \
|
wayland-devel libxkbcommon-devel \
|
||||||
cargo rust
|
cargo rust
|
||||||
- name: Build
|
- name: Build
|
||||||
@@ -78,12 +81,13 @@ jobs:
|
|||||||
container: archlinux:latest
|
container: archlinux:latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
|
- uses: Swatinem/rust-cache@v2
|
||||||
- name: Install system dependencies
|
- name: Install system dependencies
|
||||||
run: |
|
run: |
|
||||||
pacman -Sy --noconfirm \
|
pacman -Sy --noconfirm \
|
||||||
llvm clang pkgconf \
|
llvm clang pkgconf \
|
||||||
glib2 cairo pango atk \
|
glib2 cairo pango atk \
|
||||||
pam \
|
pam dbus \
|
||||||
wayland libxkbcommon \
|
wayland libxkbcommon \
|
||||||
rust cargo
|
rust cargo
|
||||||
- name: Build
|
- name: Build
|
||||||
@@ -94,13 +98,14 @@ jobs:
|
|||||||
container: opensuse/tumbleweed:latest
|
container: opensuse/tumbleweed:latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
|
- uses: Swatinem/rust-cache@v2
|
||||||
- name: Install system dependencies
|
- name: Install system dependencies
|
||||||
run: |
|
run: |
|
||||||
zypper install -y \
|
zypper install -y \
|
||||||
llvm clang \
|
llvm clang \
|
||||||
pkg-config \
|
pkg-config \
|
||||||
glib2-devel cairo-devel pango-devel atk-devel \
|
glib2-devel cairo-devel pango-devel atk-devel \
|
||||||
pam-devel \
|
pam-devel dbus-1-devel \
|
||||||
wayland-devel libxkbcommon-devel \
|
wayland-devel libxkbcommon-devel \
|
||||||
rust cargo
|
rust cargo
|
||||||
- name: Build
|
- name: Build
|
||||||
|
|||||||
@@ -42,6 +42,21 @@ pub struct Config {
|
|||||||
#[arg(long, default_value = "4EAC41", value_parser = util::parse_hex_color)]
|
#[arg(long, default_value = "4EAC41", value_parser = util::parse_hex_color)]
|
||||||
pub key_hl_color: (f64, f64, f64, f64),
|
pub key_hl_color: (f64, f64, f64, f64),
|
||||||
|
|
||||||
|
#[arg(long, default_value = "4EAC41", value_parser = util::parse_hex_color)]
|
||||||
|
pub caps_lock_key_hl_color: (f64, f64, f64, f64),
|
||||||
|
|
||||||
|
#[arg(long, default_value = "DB3300", value_parser = util::parse_hex_color)]
|
||||||
|
pub caps_lock_bs_hl_color: (f64, f64, f64, f64),
|
||||||
|
|
||||||
|
#[arg(long, default_value = "E5A445", value_parser = util::parse_hex_color)]
|
||||||
|
pub caps_lock_color: (f64, f64, f64, f64),
|
||||||
|
|
||||||
|
#[arg(long, default_value = "E5A445", value_parser = util::parse_hex_color)]
|
||||||
|
pub caps_lock_text_color: (f64, f64, f64, f64),
|
||||||
|
|
||||||
|
#[arg(long, action = clap::ArgAction::Set, num_args = 0..=1, default_value = "true", default_missing_value = "true")]
|
||||||
|
pub show_caps_lock_text: bool,
|
||||||
|
|
||||||
#[arg(long, default_value = "00000000", value_parser = util::parse_hex_color)]
|
#[arg(long, default_value = "00000000", value_parser = util::parse_hex_color)]
|
||||||
pub line_color: (f64, f64, f64, f64),
|
pub line_color: (f64, f64, f64, f64),
|
||||||
|
|
||||||
@@ -189,6 +204,7 @@ impl Config {
|
|||||||
merge_bool(&mut config.show_network, "show_network");
|
merge_bool(&mut config.show_network, "show_network");
|
||||||
merge_bool(&mut config.show_bluetooth, "show_bluetooth");
|
merge_bool(&mut config.show_bluetooth, "show_bluetooth");
|
||||||
merge_bool(&mut config.show_album_art, "show_album_art");
|
merge_bool(&mut config.show_album_art, "show_album_art");
|
||||||
|
merge_bool(&mut config.show_keyboard_layout, "show_keyboard_layout");
|
||||||
|
|
||||||
if !is_cli("image") {
|
if !is_cli("image") {
|
||||||
if let Some(toml::Value::String(s)) = table.get("image") {
|
if let Some(toml::Value::String(s)) = table.get("image") {
|
||||||
|
|||||||
@@ -109,7 +109,6 @@ impl LockedSurface {
|
|||||||
|
|
||||||
// Update caps lock state in renderer
|
// Update caps lock state in renderer
|
||||||
self.renderer.caps_lock = self.input_handler.caps_lock();
|
self.renderer.caps_lock = self.input_handler.caps_lock();
|
||||||
log::debug!("Caps lock state: {}", self.input_handler.caps_lock());
|
|
||||||
|
|
||||||
// Set background if available and not already applied
|
// Set background if available and not already applied
|
||||||
if !self.background_applied {
|
if !self.background_applied {
|
||||||
|
|||||||
+1
-1
@@ -724,7 +724,7 @@ fn main() -> Result<(), Box<dyn Error>> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
let mut status = state.system_manager.get_status();
|
let mut status = state.system_manager.get_status();
|
||||||
status.keyboard_layout = Some(state.current_layout);
|
status.keyboard_layout = Some(state.current_layout.to_string());
|
||||||
|
|
||||||
if let Ok(mut lm) = state.lock_manager.lock() {
|
if let Ok(mut lm) = state.lock_manager.lock() {
|
||||||
lm.set_system_status(status);
|
lm.set_system_status(status);
|
||||||
|
|||||||
+23
-8
@@ -238,7 +238,7 @@ impl Renderer {
|
|||||||
self.draw_password_display();
|
self.draw_password_display();
|
||||||
}
|
}
|
||||||
|
|
||||||
if self.caps_lock {
|
if self.caps_lock && self.config.show_caps_lock_text {
|
||||||
self.draw_caps_lock_indicator();
|
self.draw_caps_lock_indicator();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -351,8 +351,13 @@ impl Renderer {
|
|||||||
self.context.stroke().unwrap();
|
self.context.stroke().unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Use caps lock color when caps lock is on and indicator is enabled, otherwise ring color
|
||||||
|
let (r, g, b, a) = if self.caps_lock {
|
||||||
|
self.config.caps_lock_color
|
||||||
|
} else {
|
||||||
|
self.config.ring_color
|
||||||
|
};
|
||||||
self.context.new_path();
|
self.context.new_path();
|
||||||
let (r, g, b, a) = self.config.ring_color;
|
|
||||||
self.context.set_source_rgba(r, g, b, a * self.fade_alpha);
|
self.context.set_source_rgba(r, g, b, a * self.fade_alpha);
|
||||||
self.context.set_line_width(thickness);
|
self.context.set_line_width(thickness);
|
||||||
self.context
|
self.context
|
||||||
@@ -388,12 +393,16 @@ impl Renderer {
|
|||||||
let center_y = self.height as f64 / 2.0;
|
let center_y = self.height as f64 / 2.0;
|
||||||
let radius = self.config.indicator_radius as f64;
|
let radius = self.config.indicator_radius as f64;
|
||||||
self.context.new_path();
|
self.context.new_path();
|
||||||
self.context.set_font_size(12.0);
|
// Use configurable caps lock text color
|
||||||
self.context.set_source_rgba(1.0, 0.5, 0.0, self.fade_alpha);
|
let (r, g, b, a) = self.config.caps_lock_text_color;
|
||||||
let text = "CAPS LOCK";
|
self.context.set_source_rgba(r, g, b, a * self.fade_alpha);
|
||||||
|
// Increase font size for bigger letters
|
||||||
|
self.context.set_font_size(24.0);
|
||||||
|
let text = "Caps Lock";
|
||||||
let te = self.context.text_extents(text).unwrap();
|
let te = self.context.text_extents(text).unwrap();
|
||||||
|
// Position above the ring
|
||||||
self.context
|
self.context
|
||||||
.move_to(center_x - te.width() / 2.0, center_y + radius / 1.1 + 20.0);
|
.move_to(center_x - te.width() / 2.0, center_y - radius - 10.0);
|
||||||
self.context.show_text(text).unwrap();
|
self.context.show_text(text).unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -443,7 +452,11 @@ impl Renderer {
|
|||||||
};
|
};
|
||||||
|
|
||||||
if intensity > 0.0 {
|
if intensity > 0.0 {
|
||||||
let (r, g, b, a) = self.config.key_hl_color;
|
let (r, g, b, a) = if self.caps_lock {
|
||||||
|
self.config.caps_lock_key_hl_color
|
||||||
|
} else {
|
||||||
|
self.config.key_hl_color
|
||||||
|
};
|
||||||
self.context
|
self.context
|
||||||
.set_source_rgba(r, g, b, a * intensity * self.fade_alpha);
|
.set_source_rgba(r, g, b, a * intensity * self.fade_alpha);
|
||||||
self.context.set_line_width(thickness + 1.5);
|
self.context.set_line_width(thickness + 1.5);
|
||||||
@@ -708,7 +721,8 @@ impl Renderer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn draw_keyboard_layout(&self) {
|
fn draw_keyboard_layout(&self) {
|
||||||
if let Some(layout) = self.system_status.keyboard_layout {
|
if self.config.show_keyboard_layout {
|
||||||
|
if let Some(ref layout) = self.system_status.keyboard_layout {
|
||||||
let margin = 20.0;
|
let margin = 20.0;
|
||||||
let x = margin;
|
let x = margin;
|
||||||
let y = margin + 80.0;
|
let y = margin + 80.0;
|
||||||
@@ -721,6 +735,7 @@ impl Renderer {
|
|||||||
self.context.show_text(&text).unwrap();
|
self.context.show_text(&text).unwrap();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn draw_icon_at(&self, x: f64, y: f64, surface: &ImageSurface) {
|
fn draw_icon_at(&self, x: f64, y: f64, surface: &ImageSurface) {
|
||||||
self.context.save().unwrap();
|
self.context.save().unwrap();
|
||||||
|
|||||||
+1
-1
@@ -17,7 +17,7 @@ pub struct SystemStatus {
|
|||||||
pub wifi_strength: Option<u8>,
|
pub wifi_strength: Option<u8>,
|
||||||
pub bluetooth_connected: bool,
|
pub bluetooth_connected: bool,
|
||||||
pub bluetooth_devices: Vec<String>,
|
pub bluetooth_devices: Vec<String>,
|
||||||
pub keyboard_layout: Option<u32>,
|
pub keyboard_layout: Option<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy)]
|
#[derive(Debug, Clone, Copy)]
|
||||||
|
|||||||
Reference in New Issue
Block a user