mirror of
https://github.com/Zedfrigg/ironbar.git
synced 2025-08-17 14:51:04 +02:00
Merge pull request #855 from Rodrigodd/feat/module-bindmode
feat: rename sway_mode to bindmode and add Hyprland support
This commit is contained in:
commit
a9508e6541
13 changed files with 209 additions and 82 deletions
3
.github/workflows/build.yml
vendored
3
.github/workflows/build.yml
vendored
|
@ -100,6 +100,9 @@ jobs:
|
||||||
- config+toml
|
- config+toml
|
||||||
- config+corn
|
- config+corn
|
||||||
- config+ron
|
- config+ron
|
||||||
|
- bindmode+all
|
||||||
|
- bindmode+sway
|
||||||
|
- bindmode+hyprland
|
||||||
- cairo
|
- cairo
|
||||||
- clipboard
|
- clipboard
|
||||||
- clock
|
- clock
|
||||||
|
|
|
@ -19,6 +19,7 @@ default = [
|
||||||
"focused",
|
"focused",
|
||||||
"http",
|
"http",
|
||||||
"ipc",
|
"ipc",
|
||||||
|
"bindmode+all",
|
||||||
"keyboard+all",
|
"keyboard+all",
|
||||||
"launcher",
|
"launcher",
|
||||||
"label",
|
"label",
|
||||||
|
@ -38,6 +39,11 @@ ipc = ["dep:serde_json", "dep:clap"]
|
||||||
|
|
||||||
http = ["dep:reqwest"]
|
http = ["dep:reqwest"]
|
||||||
|
|
||||||
|
bindmode = []
|
||||||
|
"bindmode+all" = ["bindmode+sway", "bindmode+hyprland"]
|
||||||
|
"bindmode+sway" = ["bindmode", "sway"]
|
||||||
|
"bindmode+hyprland" = ["bindmode", "hyprland"]
|
||||||
|
|
||||||
"config+all" = [
|
"config+all" = [
|
||||||
"config+json",
|
"config+json",
|
||||||
"config+yaml",
|
"config+yaml",
|
||||||
|
|
|
@ -29,6 +29,7 @@ A full list of feature flags can be found [here](Compiling#features).
|
||||||
|
|
||||||
| Module | Status | Notes |
|
| Module | Status | Notes |
|
||||||
|-----------------|--------|------------------------------------------------------------------------------------------------------------------------------------------|
|
|-----------------|--------|------------------------------------------------------------------------------------------------------------------------------------------|
|
||||||
|
| Bindmode | ❌ | |
|
||||||
| Cairo | ✅ | |
|
| Cairo | ✅ | |
|
||||||
| Clipboard | ✅ | |
|
| Clipboard | ✅ | |
|
||||||
| Clock | ✅ | |
|
| Clock | ✅ | |
|
||||||
|
@ -41,7 +42,6 @@ A full list of feature flags can be found [here](Compiling#features).
|
||||||
| Network Manager | ❌ | |
|
| Network Manager | ❌ | |
|
||||||
| Notifications | ✅ | |
|
| Notifications | ✅ | |
|
||||||
| Script | ✅ | |
|
| Script | ✅ | |
|
||||||
| Sway Mode | ❌ | |
|
|
||||||
| SysInfo | ✅ | |
|
| SysInfo | ✅ | |
|
||||||
| Tray | ❌ | GTK4 removes widgets required to move the tray. No `libdbusmenu-gtk4` either. will need to manually re-create menus with custom widgets. |
|
| Tray | ❌ | GTK4 removes widgets required to move the tray. No `libdbusmenu-gtk4` either. will need to manually re-create menus with custom widgets. |
|
||||||
| UPower | ❌ | |
|
| UPower | ❌ | |
|
||||||
|
|
|
@ -25,6 +25,7 @@
|
||||||
|
|
||||||
# Modules
|
# Modules
|
||||||
|
|
||||||
|
- [Bindmode](bindmode)
|
||||||
- [Cairo](cairo)
|
- [Cairo](cairo)
|
||||||
- [Clipboard](clipboard)
|
- [Clipboard](clipboard)
|
||||||
- [Clock](clock)
|
- [Clock](clock)
|
||||||
|
@ -37,7 +38,6 @@
|
||||||
- [Network Manager](network-manager)
|
- [Network Manager](network-manager)
|
||||||
- [Notifications](notifications)
|
- [Notifications](notifications)
|
||||||
- [Script](script)
|
- [Script](script)
|
||||||
- [Sway-mode](sway-mode)
|
|
||||||
- [Sys_Info](sys-info)
|
- [Sys_Info](sys-info)
|
||||||
- [Tray](tray)
|
- [Tray](tray)
|
||||||
- [Upower](upower)
|
- [Upower](upower)
|
||||||
|
|
|
@ -1,12 +1,12 @@
|
||||||
Displays the current sway mode in a label. If the current sway mode is
|
> [!IMPORTANT]
|
||||||
"default", nothing is displayed.
|
> This module is currently only available on Sway and Hyprland.
|
||||||
|
|
||||||
> [!NOTE]
|
Displays Sway's current binding mode or [Hyprland's current submap](https://wiki.hyprland.org/Configuring/Binds/#submaps)
|
||||||
> This module only works under the [Sway](https://swaywm.org/) compositor.
|
in a label. Nothing is displayed if no binding mode is active.
|
||||||
|
|
||||||
## Configuration
|
## Configuration
|
||||||
|
|
||||||
> Type: `sway-mode`
|
> Type: `bindmode`
|
||||||
|
|
||||||
| Name | Type | Default | Description |
|
| Name | Type | Default | Description |
|
||||||
| --------------------- | ------------------------------------------- | ------- | ----------------------------------------------------------------------------------------------------------------------------------------------------- |
|
| --------------------- | ------------------------------------------- | ------- | ----------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||||
|
@ -22,7 +22,7 @@ Displays the current sway mode in a label. If the current sway mode is
|
||||||
{
|
{
|
||||||
"end": [
|
"end": [
|
||||||
{
|
{
|
||||||
"type": "sway-mode",
|
"type": "bindmode",
|
||||||
"truncate": "start"
|
"truncate": "start"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
@ -36,7 +36,7 @@ Displays the current sway mode in a label. If the current sway mode is
|
||||||
|
|
||||||
```toml
|
```toml
|
||||||
[[end]]
|
[[end]]
|
||||||
type = "sway-mode"
|
type = "bindmode"
|
||||||
truncate = "start"
|
truncate = "start"
|
||||||
```
|
```
|
||||||
|
|
||||||
|
@ -47,7 +47,7 @@ truncate = "start"
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
end:
|
end:
|
||||||
- type: "sway-mode"
|
- type: "bindmode"
|
||||||
truncate: "start"
|
truncate: "start"
|
||||||
```
|
```
|
||||||
|
|
||||||
|
@ -60,7 +60,7 @@ end:
|
||||||
{
|
{
|
||||||
end = [
|
end = [
|
||||||
{
|
{
|
||||||
type = "sway-mode"
|
type = "bindmode"
|
||||||
truncate = "start"
|
truncate = "start"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
@ -72,7 +72,7 @@ end:
|
||||||
## Styling
|
## Styling
|
||||||
|
|
||||||
| Selector | Description |
|
| Selector | Description |
|
||||||
| ------------ | ---------------------- |
|
| ----------- | ---------------------- |
|
||||||
| `.sway_mode` | Sway mode label widget |
|
| `.bindmode` | Bind mode label widget |
|
||||||
|
|
||||||
For more information on styling, please see the [styling guide](styling-guide).
|
For more information on styling, please see the [styling guide](styling-guide).
|
|
@ -10,11 +10,22 @@ use hyprland::shared::{HyprDataVec, WorkspaceType};
|
||||||
use tokio::sync::broadcast::{Receiver, Sender, channel};
|
use tokio::sync::broadcast::{Receiver, Sender, channel};
|
||||||
use tracing::{debug, error, info};
|
use tracing::{debug, error, info};
|
||||||
|
|
||||||
|
#[cfg(feature = "bindmode+hyprland")]
|
||||||
|
use super::{BindModeClient, BindModeUpdate};
|
||||||
|
#[cfg(feature = "keyboard+hyprland")]
|
||||||
|
use super::{KeyboardLayoutClient, KeyboardLayoutUpdate};
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
struct TxRx<T> {
|
struct TxRx<T> {
|
||||||
tx: Sender<T>,
|
tx: Sender<T>,
|
||||||
_rx: Receiver<T>,
|
_rx: Receiver<T>,
|
||||||
}
|
}
|
||||||
|
impl<T: Clone> TxRx<T> {
|
||||||
|
fn new() -> Self {
|
||||||
|
let (tx, rx) = channel(16);
|
||||||
|
Self { tx, _rx: rx }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct Client {
|
pub struct Client {
|
||||||
|
@ -23,27 +34,20 @@ pub struct Client {
|
||||||
|
|
||||||
#[cfg(feature = "keyboard+hyprland")]
|
#[cfg(feature = "keyboard+hyprland")]
|
||||||
keyboard_layout: TxRx<KeyboardLayoutUpdate>,
|
keyboard_layout: TxRx<KeyboardLayoutUpdate>,
|
||||||
|
|
||||||
|
#[cfg(feature = "bindmode+hyprland")]
|
||||||
|
bindmode: TxRx<BindModeUpdate>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Client {
|
impl Client {
|
||||||
pub(crate) fn new() -> Self {
|
pub(crate) fn new() -> Self {
|
||||||
#[cfg(feature = "workspaces+hyprland")]
|
|
||||||
let (workspace_tx, workspace_rx) = channel(16);
|
|
||||||
|
|
||||||
#[cfg(feature = "keyboard+hyprland")]
|
|
||||||
let (keyboard_layout_tx, keyboard_layout_rx) = channel(16);
|
|
||||||
|
|
||||||
let instance = Self {
|
let instance = Self {
|
||||||
#[cfg(feature = "workspaces+hyprland")]
|
#[cfg(feature = "workspaces+hyprland")]
|
||||||
workspace: TxRx {
|
workspace: TxRx::new(),
|
||||||
tx: workspace_tx,
|
|
||||||
_rx: workspace_rx,
|
|
||||||
},
|
|
||||||
#[cfg(feature = "keyboard+hyprland")]
|
#[cfg(feature = "keyboard+hyprland")]
|
||||||
keyboard_layout: TxRx {
|
keyboard_layout: TxRx::new(),
|
||||||
tx: keyboard_layout_tx,
|
#[cfg(feature = "bindmode+hyprland")]
|
||||||
_rx: keyboard_layout_rx,
|
bindmode: TxRx::new(),
|
||||||
},
|
|
||||||
};
|
};
|
||||||
|
|
||||||
instance.listen_events();
|
instance.listen_events();
|
||||||
|
@ -54,11 +58,14 @@ impl Client {
|
||||||
info!("Starting Hyprland event listener");
|
info!("Starting Hyprland event listener");
|
||||||
|
|
||||||
#[cfg(feature = "workspaces+hyprland")]
|
#[cfg(feature = "workspaces+hyprland")]
|
||||||
let tx = self.workspace.tx.clone();
|
let workspace_tx = self.workspace.tx.clone();
|
||||||
|
|
||||||
#[cfg(feature = "keyboard+hyprland")]
|
#[cfg(feature = "keyboard+hyprland")]
|
||||||
let keyboard_layout_tx = self.keyboard_layout.tx.clone();
|
let keyboard_layout_tx = self.keyboard_layout.tx.clone();
|
||||||
|
|
||||||
|
#[cfg(feature = "bindmode+hyprland")]
|
||||||
|
let bindmode_tx = self.bindmode.tx.clone();
|
||||||
|
|
||||||
spawn_blocking(move || {
|
spawn_blocking(move || {
|
||||||
let mut event_listener = EventListener::new();
|
let mut event_listener = EventListener::new();
|
||||||
|
|
||||||
|
@ -67,10 +74,13 @@ impl Client {
|
||||||
|
|
||||||
// cache the active workspace since Hyprland doesn't give us the prev active
|
// cache the active workspace since Hyprland doesn't give us the prev active
|
||||||
#[cfg(feature = "workspaces+hyprland")]
|
#[cfg(feature = "workspaces+hyprland")]
|
||||||
Self::listen_workspace_events(tx, &mut event_listener, &lock);
|
Self::listen_workspace_events(workspace_tx, &mut event_listener, &lock);
|
||||||
|
|
||||||
#[cfg(feature = "keyboard+hyprland")]
|
#[cfg(feature = "keyboard+hyprland")]
|
||||||
Self::listen_keyboard_events(keyboard_layout_tx, &mut event_listener, lock);
|
Self::listen_keyboard_events(keyboard_layout_tx, &mut event_listener, &lock);
|
||||||
|
|
||||||
|
#[cfg(feature = "bindmode+hyprland")]
|
||||||
|
Self::listen_bindmode_events(bindmode_tx, &mut event_listener, &lock);
|
||||||
|
|
||||||
event_listener
|
event_listener
|
||||||
.start_listener()
|
.start_listener()
|
||||||
|
@ -257,7 +267,7 @@ impl Client {
|
||||||
fn listen_keyboard_events(
|
fn listen_keyboard_events(
|
||||||
keyboard_layout_tx: Sender<KeyboardLayoutUpdate>,
|
keyboard_layout_tx: Sender<KeyboardLayoutUpdate>,
|
||||||
event_listener: &mut EventListener,
|
event_listener: &mut EventListener,
|
||||||
lock: std::sync::Arc<std::sync::Mutex<()>>,
|
lock: &std::sync::Arc<std::sync::Mutex<()>>,
|
||||||
) {
|
) {
|
||||||
let tx = keyboard_layout_tx.clone();
|
let tx = keyboard_layout_tx.clone();
|
||||||
let lock = lock.clone();
|
let lock = lock.clone();
|
||||||
|
@ -307,6 +317,29 @@ impl Client {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "bindmode+hyprland")]
|
||||||
|
fn listen_bindmode_events(
|
||||||
|
bindmode_tx: Sender<BindModeUpdate>,
|
||||||
|
event_listener: &mut EventListener,
|
||||||
|
lock: &std::sync::Arc<std::sync::Mutex<()>>,
|
||||||
|
) {
|
||||||
|
let tx = bindmode_tx.clone();
|
||||||
|
let lock = lock.clone();
|
||||||
|
|
||||||
|
event_listener.add_sub_map_change_handler(move |bind_mode| {
|
||||||
|
let _lock = lock!(lock);
|
||||||
|
debug!("Received bind mode: {bind_mode:?}");
|
||||||
|
|
||||||
|
send!(
|
||||||
|
tx,
|
||||||
|
BindModeUpdate {
|
||||||
|
name: bind_mode,
|
||||||
|
pango_markup: false,
|
||||||
|
}
|
||||||
|
);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
/// Sends a `WorkspaceUpdate::Focus` event
|
/// Sends a `WorkspaceUpdate::Focus` event
|
||||||
/// and updates the active workspace cache.
|
/// and updates the active workspace cache.
|
||||||
#[cfg(feature = "workspaces+hyprland")]
|
#[cfg(feature = "workspaces+hyprland")]
|
||||||
|
@ -392,9 +425,6 @@ impl super::WorkspaceClient for Client {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "keyboard+hyprland")]
|
|
||||||
use super::{KeyboardLayoutClient, KeyboardLayoutUpdate};
|
|
||||||
|
|
||||||
#[cfg(feature = "keyboard+hyprland")]
|
#[cfg(feature = "keyboard+hyprland")]
|
||||||
impl KeyboardLayoutClient for Client {
|
impl KeyboardLayoutClient for Client {
|
||||||
fn set_next_active(&self) {
|
fn set_next_active(&self) {
|
||||||
|
@ -436,6 +466,13 @@ impl KeyboardLayoutClient for Client {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "bindmode+hyprland")]
|
||||||
|
impl BindModeClient for Client {
|
||||||
|
fn subscribe(&self) -> Result<Receiver<BindModeUpdate>> {
|
||||||
|
Ok(self.bindmode.tx.subscribe())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn get_workspace_name(name: WorkspaceType) -> String {
|
fn get_workspace_name(name: WorkspaceType) -> String {
|
||||||
match name {
|
match name {
|
||||||
WorkspaceType::Regular(name) => name,
|
WorkspaceType::Regular(name) => name,
|
||||||
|
|
|
@ -66,6 +66,28 @@ impl Compositor {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "bindmode")]
|
||||||
|
pub fn create_bindmode_client(
|
||||||
|
clients: &mut super::Clients,
|
||||||
|
) -> ClientResult<dyn BindModeClient + Send + Sync> {
|
||||||
|
let current = Self::get_current();
|
||||||
|
debug!("Getting keyboard_layout client for: {current}");
|
||||||
|
match current {
|
||||||
|
#[cfg(feature = "bindmode+sway")]
|
||||||
|
Self::Sway => Ok(clients.sway()?),
|
||||||
|
#[cfg(feature = "bindmode+hyprland")]
|
||||||
|
Self::Hyprland => Ok(clients.hyprland()),
|
||||||
|
#[cfg(feature = "niri")]
|
||||||
|
Self::Niri => Err(Report::msg("Unsupported compositor")
|
||||||
|
.note("Currently bindmode is only supported by Sway and Hyprland")),
|
||||||
|
Self::Unsupported => Err(Report::msg("Unsupported compositor")
|
||||||
|
.note("Currently bindmode is only supported by Sway and Hyprland")),
|
||||||
|
#[allow(unreachable_patterns)]
|
||||||
|
_ => Err(Report::msg("Unsupported compositor")
|
||||||
|
.note("Bindmode feature is disabled for this compositor")),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(feature = "keyboard")]
|
#[cfg(feature = "keyboard")]
|
||||||
pub fn create_keyboard_layout_client(
|
pub fn create_keyboard_layout_client(
|
||||||
clients: &mut super::Clients,
|
clients: &mut super::Clients,
|
||||||
|
@ -74,9 +96,7 @@ impl Compositor {
|
||||||
debug!("Getting keyboard_layout client for: {current}");
|
debug!("Getting keyboard_layout client for: {current}");
|
||||||
match current {
|
match current {
|
||||||
#[cfg(feature = "keyboard+sway")]
|
#[cfg(feature = "keyboard+sway")]
|
||||||
Self::Sway => clients
|
Self::Sway => Ok(clients.sway()?),
|
||||||
.sway()
|
|
||||||
.map(|client| client as Arc<dyn KeyboardLayoutClient + Send + Sync>),
|
|
||||||
#[cfg(feature = "keyboard+hyprland")]
|
#[cfg(feature = "keyboard+hyprland")]
|
||||||
Self::Hyprland => Ok(clients.hyprland()),
|
Self::Hyprland => Ok(clients.hyprland()),
|
||||||
#[cfg(feature = "niri")]
|
#[cfg(feature = "niri")]
|
||||||
|
@ -102,9 +122,7 @@ impl Compositor {
|
||||||
debug!("Getting workspace client for: {current}");
|
debug!("Getting workspace client for: {current}");
|
||||||
match current {
|
match current {
|
||||||
#[cfg(feature = "workspaces+sway")]
|
#[cfg(feature = "workspaces+sway")]
|
||||||
Self::Sway => clients
|
Self::Sway => Ok(clients.sway()?),
|
||||||
.sway()
|
|
||||||
.map(|client| client as Arc<dyn WorkspaceClient + Send + Sync>),
|
|
||||||
#[cfg(feature = "workspaces+hyprland")]
|
#[cfg(feature = "workspaces+hyprland")]
|
||||||
Self::Hyprland => Ok(clients.hyprland()),
|
Self::Hyprland => Ok(clients.hyprland()),
|
||||||
#[cfg(feature = "workspaces+niri")]
|
#[cfg(feature = "workspaces+niri")]
|
||||||
|
@ -195,6 +213,14 @@ pub enum WorkspaceUpdate {
|
||||||
Unknown,
|
Unknown,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Debug)]
|
||||||
|
pub struct BindModeUpdate {
|
||||||
|
/// The binding mode that became active.
|
||||||
|
pub name: String,
|
||||||
|
/// Whether the mode should be parsed as pango markup.
|
||||||
|
pub pango_markup: bool,
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(feature = "workspaces")]
|
#[cfg(feature = "workspaces")]
|
||||||
pub trait WorkspaceClient: Debug + Send + Sync {
|
pub trait WorkspaceClient: Debug + Send + Sync {
|
||||||
/// Requests the workspace with this id is focused.
|
/// Requests the workspace with this id is focused.
|
||||||
|
@ -218,3 +244,12 @@ pub trait KeyboardLayoutClient: Debug + Send + Sync {
|
||||||
|
|
||||||
#[cfg(feature = "keyboard")]
|
#[cfg(feature = "keyboard")]
|
||||||
register_fallible_client!(dyn KeyboardLayoutClient, keyboard_layout);
|
register_fallible_client!(dyn KeyboardLayoutClient, keyboard_layout);
|
||||||
|
|
||||||
|
#[cfg(feature = "bindmode")]
|
||||||
|
pub trait BindModeClient: Debug + Send + Sync {
|
||||||
|
/// Add a callback for bindmode updates.
|
||||||
|
fn subscribe(&self) -> Result<broadcast::Receiver<BindModeUpdate>>;
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "bindmode")]
|
||||||
|
register_fallible_client!(dyn BindModeClient, bindmode);
|
||||||
|
|
|
@ -231,3 +231,36 @@ impl TryFrom<InputEvent> for KeyboardLayoutUpdate {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "bindmode+sway")]
|
||||||
|
use super::{BindModeClient, BindModeUpdate};
|
||||||
|
|
||||||
|
#[cfg(feature = "bindmode+sway")]
|
||||||
|
impl BindModeClient for Client {
|
||||||
|
fn subscribe(&self) -> Result<Receiver<BindModeUpdate>, Report> {
|
||||||
|
let (tx, rx) = channel(16);
|
||||||
|
await_sync(async {
|
||||||
|
self.add_listener::<swayipc_async::ModeEvent>(move |mode| {
|
||||||
|
tracing::trace!("mode: {:?}", mode);
|
||||||
|
|
||||||
|
// when no bindind is active the bindmode is named "default", but we must display
|
||||||
|
// nothing in this case.
|
||||||
|
let name = if mode.change == "default" {
|
||||||
|
String::new()
|
||||||
|
} else {
|
||||||
|
mode.change.clone()
|
||||||
|
};
|
||||||
|
|
||||||
|
send!(
|
||||||
|
tx,
|
||||||
|
BindModeUpdate {
|
||||||
|
name,
|
||||||
|
pango_markup: mode.pango_markup,
|
||||||
|
}
|
||||||
|
);
|
||||||
|
})
|
||||||
|
.await
|
||||||
|
})?;
|
||||||
|
Ok(rx)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -7,7 +7,12 @@ use std::sync::Arc;
|
||||||
|
|
||||||
#[cfg(feature = "clipboard")]
|
#[cfg(feature = "clipboard")]
|
||||||
pub mod clipboard;
|
pub mod clipboard;
|
||||||
#[cfg(any(feature = "keyboard", feature = "workspaces", feature = "hyprland"))]
|
#[cfg(any(
|
||||||
|
feature = "bindmode",
|
||||||
|
feature = "hyprland",
|
||||||
|
feature = "keyboard",
|
||||||
|
feature = "workspaces",
|
||||||
|
))]
|
||||||
pub mod compositor;
|
pub mod compositor;
|
||||||
#[cfg(feature = "keyboard")]
|
#[cfg(feature = "keyboard")]
|
||||||
pub mod libinput;
|
pub mod libinput;
|
||||||
|
@ -42,6 +47,8 @@ pub struct Clients {
|
||||||
sway: Option<Arc<sway::Client>>,
|
sway: Option<Arc<sway::Client>>,
|
||||||
#[cfg(feature = "hyprland")]
|
#[cfg(feature = "hyprland")]
|
||||||
hyprland: Option<Arc<compositor::hyprland::Client>>,
|
hyprland: Option<Arc<compositor::hyprland::Client>>,
|
||||||
|
#[cfg(feature = "bindmode")]
|
||||||
|
bindmode: Option<Arc<dyn compositor::BindModeClient>>,
|
||||||
#[cfg(feature = "clipboard")]
|
#[cfg(feature = "clipboard")]
|
||||||
clipboard: Option<Arc<clipboard::Client>>,
|
clipboard: Option<Arc<clipboard::Client>>,
|
||||||
#[cfg(feature = "keyboard")]
|
#[cfg(feature = "keyboard")]
|
||||||
|
@ -114,6 +121,19 @@ impl Clients {
|
||||||
Ok(client)
|
Ok(client)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "bindmode")]
|
||||||
|
pub fn bindmode(&mut self) -> ClientResult<dyn compositor::BindModeClient> {
|
||||||
|
let client = if let Some(client) = &self.bindmode {
|
||||||
|
client.clone()
|
||||||
|
} else {
|
||||||
|
let client = compositor::Compositor::create_bindmode_client(self)?;
|
||||||
|
self.bindmode.replace(client.clone());
|
||||||
|
client
|
||||||
|
};
|
||||||
|
|
||||||
|
Ok(client)
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(feature = "sway")]
|
#[cfg(feature = "sway")]
|
||||||
pub fn sway(&mut self) -> ClientResult<sway::Client> {
|
pub fn sway(&mut self) -> ClientResult<sway::Client> {
|
||||||
let client = if let Some(client) = &self.sway {
|
let client = if let Some(client) = &self.sway {
|
||||||
|
|
|
@ -3,6 +3,8 @@ mod r#impl;
|
||||||
mod layout;
|
mod layout;
|
||||||
mod truncate;
|
mod truncate;
|
||||||
|
|
||||||
|
#[cfg(any(feature = "bindmode"))]
|
||||||
|
use crate::modules::bindmode::Bindmode;
|
||||||
#[cfg(feature = "cairo")]
|
#[cfg(feature = "cairo")]
|
||||||
use crate::modules::cairo::CairoModule;
|
use crate::modules::cairo::CairoModule;
|
||||||
#[cfg(feature = "clipboard")]
|
#[cfg(feature = "clipboard")]
|
||||||
|
@ -27,8 +29,6 @@ use crate::modules::networkmanager::NetworkManagerModule;
|
||||||
use crate::modules::notifications::NotificationsModule;
|
use crate::modules::notifications::NotificationsModule;
|
||||||
#[cfg(feature = "script")]
|
#[cfg(feature = "script")]
|
||||||
use crate::modules::script::ScriptModule;
|
use crate::modules::script::ScriptModule;
|
||||||
#[cfg(feature = "sway")]
|
|
||||||
use crate::modules::sway::mode::SwayModeModule;
|
|
||||||
#[cfg(feature = "sys_info")]
|
#[cfg(feature = "sys_info")]
|
||||||
use crate::modules::sysinfo::SysInfoModule;
|
use crate::modules::sysinfo::SysInfoModule;
|
||||||
#[cfg(feature = "tray")]
|
#[cfg(feature = "tray")]
|
||||||
|
@ -57,6 +57,8 @@ pub use self::truncate::{EllipsizeMode, TruncateMode};
|
||||||
#[serde(tag = "type", rename_all = "snake_case")]
|
#[serde(tag = "type", rename_all = "snake_case")]
|
||||||
#[cfg_attr(feature = "schema", derive(JsonSchema))]
|
#[cfg_attr(feature = "schema", derive(JsonSchema))]
|
||||||
pub enum ModuleConfig {
|
pub enum ModuleConfig {
|
||||||
|
#[cfg(feature = "bindmode")]
|
||||||
|
Bindmode(Box<Bindmode>),
|
||||||
#[cfg(feature = "cairo")]
|
#[cfg(feature = "cairo")]
|
||||||
Cairo(Box<CairoModule>),
|
Cairo(Box<CairoModule>),
|
||||||
#[cfg(feature = "clipboard")]
|
#[cfg(feature = "clipboard")]
|
||||||
|
@ -83,8 +85,6 @@ pub enum ModuleConfig {
|
||||||
Script(Box<ScriptModule>),
|
Script(Box<ScriptModule>),
|
||||||
#[cfg(feature = "sys_info")]
|
#[cfg(feature = "sys_info")]
|
||||||
SysInfo(Box<SysInfoModule>),
|
SysInfo(Box<SysInfoModule>),
|
||||||
#[cfg(feature = "sway")]
|
|
||||||
SwayMode(Box<SwayModeModule>),
|
|
||||||
#[cfg(feature = "tray")]
|
#[cfg(feature = "tray")]
|
||||||
Tray(Box<TrayModule>),
|
Tray(Box<TrayModule>),
|
||||||
#[cfg(feature = "upower")]
|
#[cfg(feature = "upower")]
|
||||||
|
@ -109,6 +109,8 @@ impl ModuleConfig {
|
||||||
}
|
}
|
||||||
|
|
||||||
match self {
|
match self {
|
||||||
|
#[cfg(feature = "bindmode")]
|
||||||
|
Self::Bindmode(module) => create!(module),
|
||||||
#[cfg(feature = "cairo")]
|
#[cfg(feature = "cairo")]
|
||||||
Self::Cairo(module) => create!(module),
|
Self::Cairo(module) => create!(module),
|
||||||
#[cfg(feature = "clipboard")]
|
#[cfg(feature = "clipboard")]
|
||||||
|
@ -135,8 +137,6 @@ impl ModuleConfig {
|
||||||
Self::Script(module) => create!(module),
|
Self::Script(module) => create!(module),
|
||||||
#[cfg(feature = "sys_info")]
|
#[cfg(feature = "sys_info")]
|
||||||
Self::SysInfo(module) => create!(module),
|
Self::SysInfo(module) => create!(module),
|
||||||
#[cfg(feature = "sway")]
|
|
||||||
Self::SwayMode(module) => create!(module),
|
|
||||||
#[cfg(feature = "tray")]
|
#[cfg(feature = "tray")]
|
||||||
Self::Tray(module) => create!(module),
|
Self::Tray(module) => create!(module),
|
||||||
#[cfg(feature = "upower")]
|
#[cfg(feature = "upower")]
|
||||||
|
|
|
@ -1,18 +1,18 @@
|
||||||
|
use crate::clients::compositor::BindModeUpdate;
|
||||||
use crate::config::{CommonConfig, LayoutConfig, TruncateMode};
|
use crate::config::{CommonConfig, LayoutConfig, TruncateMode};
|
||||||
use crate::gtk_helpers::IronbarLabelExt;
|
use crate::gtk_helpers::IronbarLabelExt;
|
||||||
use crate::modules::{Module, ModuleInfo, ModuleParts, ModuleUpdateEvent, WidgetContext};
|
use crate::modules::{Module, ModuleInfo, ModuleParts, WidgetContext};
|
||||||
use crate::{await_sync, glib_recv, module_impl, try_send};
|
use crate::{glib_recv, module_impl, module_update, send_async, spawn};
|
||||||
use color_eyre::{Report, Result};
|
use color_eyre::Result;
|
||||||
use gtk::Label;
|
use gtk::Label;
|
||||||
use gtk::prelude::*;
|
use gtk::prelude::*;
|
||||||
use serde::Deserialize;
|
use serde::Deserialize;
|
||||||
use swayipc_async::ModeEvent;
|
|
||||||
use tokio::sync::mpsc;
|
use tokio::sync::mpsc;
|
||||||
use tracing::{info, trace};
|
use tracing::{info, trace};
|
||||||
|
|
||||||
#[derive(Debug, Deserialize, Clone)]
|
#[derive(Debug, Deserialize, Clone)]
|
||||||
#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
|
#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
|
||||||
pub struct SwayModeModule {
|
pub struct Bindmode {
|
||||||
// -- Common --
|
// -- Common --
|
||||||
/// See [truncate options](module-level-options#truncate-mode).
|
/// See [truncate options](module-level-options#truncate-mode).
|
||||||
///
|
///
|
||||||
|
@ -28,11 +28,11 @@ pub struct SwayModeModule {
|
||||||
pub common: Option<CommonConfig>,
|
pub common: Option<CommonConfig>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Module<Label> for SwayModeModule {
|
impl Module<Label> for Bindmode {
|
||||||
type SendMessage = ModeEvent;
|
type SendMessage = BindModeUpdate;
|
||||||
type ReceiveMessage = ();
|
type ReceiveMessage = ();
|
||||||
|
|
||||||
module_impl!("sway_mode");
|
module_impl!("bindmode");
|
||||||
|
|
||||||
fn spawn_controller(
|
fn spawn_controller(
|
||||||
&self,
|
&self,
|
||||||
|
@ -40,20 +40,18 @@ impl Module<Label> for SwayModeModule {
|
||||||
context: &WidgetContext<Self::SendMessage, Self::ReceiveMessage>,
|
context: &WidgetContext<Self::SendMessage, Self::ReceiveMessage>,
|
||||||
_rx: mpsc::Receiver<Self::ReceiveMessage>,
|
_rx: mpsc::Receiver<Self::ReceiveMessage>,
|
||||||
) -> Result<()> {
|
) -> Result<()> {
|
||||||
info!("Sway Mode module started");
|
info!("Bindmode module started");
|
||||||
|
|
||||||
|
let client = context.try_client::<dyn crate::clients::compositor::BindModeClient>()?;
|
||||||
|
|
||||||
let tx = context.tx.clone();
|
let tx = context.tx.clone();
|
||||||
|
|
||||||
await_sync(async move {
|
let mut rx = client.subscribe()?;
|
||||||
let client = context.ironbar.clients.borrow_mut().sway()?;
|
spawn(async move {
|
||||||
client
|
while let Ok(ev) = rx.recv().await {
|
||||||
.add_listener::<swayipc_async::ModeEvent>(move |mode| {
|
module_update!(tx, ev);
|
||||||
trace!("mode: {:?}", mode);
|
}
|
||||||
try_send!(tx, ModuleUpdateEvent::Update(mode.clone()));
|
});
|
||||||
})
|
|
||||||
.await?;
|
|
||||||
|
|
||||||
Ok::<(), Report>(())
|
|
||||||
})?;
|
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
@ -69,24 +67,20 @@ impl Module<Label> for SwayModeModule {
|
||||||
.justify(self.layout.justify.into())
|
.justify(self.layout.justify.into())
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
{
|
|
||||||
let label = label.clone();
|
|
||||||
|
|
||||||
if let Some(truncate) = self.truncate {
|
if let Some(truncate) = self.truncate {
|
||||||
label.truncate(truncate);
|
label.truncate(truncate);
|
||||||
}
|
}
|
||||||
|
|
||||||
let on_mode = move |mode: ModeEvent| {
|
{
|
||||||
|
let label = label.clone();
|
||||||
|
|
||||||
|
let on_mode = move |mode: BindModeUpdate| {
|
||||||
trace!("mode: {:?}", mode);
|
trace!("mode: {:?}", mode);
|
||||||
label.set_use_markup(mode.pango_markup);
|
label.set_use_markup(mode.pango_markup);
|
||||||
if mode.change == "default" {
|
label.set_label_escaped(&mode.name);
|
||||||
label.set_label_escaped("");
|
|
||||||
} else {
|
|
||||||
label.set_label_escaped(&mode.change);
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
glib_recv!(context.subscribe(), mode => on_mode(mode));
|
glib_recv!(context.subscribe(), on_mode);
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(ModuleParts {
|
Ok(ModuleParts {
|
|
@ -17,6 +17,8 @@ use crate::gtk_helpers::{IronbarGtkExt, WidgetGeometry};
|
||||||
use crate::popup::Popup;
|
use crate::popup::Popup;
|
||||||
use crate::{Ironbar, glib_recv_mpsc, send};
|
use crate::{Ironbar, glib_recv_mpsc, send};
|
||||||
|
|
||||||
|
#[cfg(feature = "bindmode")]
|
||||||
|
pub mod bindmode;
|
||||||
#[cfg(feature = "cairo")]
|
#[cfg(feature = "cairo")]
|
||||||
pub mod cairo;
|
pub mod cairo;
|
||||||
#[cfg(feature = "clipboard")]
|
#[cfg(feature = "clipboard")]
|
||||||
|
@ -50,8 +52,6 @@ pub mod notifications;
|
||||||
|
|
||||||
#[cfg(feature = "script")]
|
#[cfg(feature = "script")]
|
||||||
pub mod script;
|
pub mod script;
|
||||||
#[cfg(feature = "sway")]
|
|
||||||
pub mod sway;
|
|
||||||
#[cfg(feature = "sys_info")]
|
#[cfg(feature = "sys_info")]
|
||||||
pub mod sysinfo;
|
pub mod sysinfo;
|
||||||
#[cfg(feature = "tray")]
|
#[cfg(feature = "tray")]
|
||||||
|
|
|
@ -1 +0,0 @@
|
||||||
pub mod mode;
|
|
Loading…
Add table
Add a link
Reference in a new issue