diff --git a/docs/modules/Workspaces.md b/docs/modules/Workspaces.md index 9dfe7df..1ebcecc 100644 --- a/docs/modules/Workspaces.md +++ b/docs/modules/Workspaces.md @@ -8,14 +8,14 @@ Shows all current workspaces. Clicking a workspace changes focus to it. > Type: `workspaces` -| Name | Type | Default | Description | -|----------------|---------------------------------------|----------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| `name_map` | `Map` | `{}` | A map of actual workspace names to their display labels/images. Workspaces use their actual name if not present in the map. See [here](images) for information on images. | -| `favorites` | `Map` or `string[]` | `[]` | Workspaces to always show. This can be for all monitors, or a map to set per monitor. | -| `hidden` | `string[]` | `[]` | A list of workspace names to never show | -| `icon_size` | `integer` | `32` | Size to render icon at (image icons only). | -| `all_monitors` | `boolean` | `false` | Whether to display workspaces from all monitors. When `false`, only shows workspaces on the current monitor. | -| `sort` | `'added'` or `'alphanumeric'` | `alphanumeric` | The method used for sorting workspaces. `added` always appends to the end, `alphanumeric` sorts by number/name. | +| Name | Type | Default | Description | +|----------------|---------------------------------------|---------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| `name_map` | `Map` | `{}` | A map of actual workspace names to their display labels/images. Workspaces use their actual name if not present in the map. See [here](images) for information on images. | +| `favorites` | `Map` or `string[]` | `[]` | Workspaces to always show. This can be for all monitors, or a map to set per monitor. | +| `hidden` | `string[]` | `[]` | A list of workspace names to never show | +| `icon_size` | `integer` | `32` | Size to render icon at (image icons only). | +| `all_monitors` | `boolean` | `false` | Whether to display workspaces from all monitors. When `false`, only shows workspaces on the current monitor. | +| `sort` | `'added'` or `'label'` or `'name'` | `label` | The method used for sorting workspaces. `added` always appends to the end, `label` sorts by displayed value, and `name` sorts by workspace name. |
JSON diff --git a/src/clients/compositor/hyprland.rs b/src/clients/compositor/hyprland.rs index f7bb09f..063e7b7 100644 --- a/src/clients/compositor/hyprland.rs +++ b/src/clients/compositor/hyprland.rs @@ -119,7 +119,7 @@ impl Client { { Self::send_focus_change(&mut prev_workspace, workspace, &tx); } else { - error!("Unable to locate workspace"); + error!("unable to locate workspace: {workspace_name}"); } }); } @@ -154,6 +154,7 @@ impl Client { event_listener.add_workspace_rename_handler(move |data| { let _lock = lock!(lock); + debug!("Received workspace rename: {data:?}"); send!( tx, diff --git a/src/clients/compositor/mod.rs b/src/clients/compositor/mod.rs index 5243fcc..5c92e4e 100644 --- a/src/clients/compositor/mod.rs +++ b/src/clients/compositor/mod.rs @@ -86,29 +86,25 @@ pub struct Workspace { pub visibility: Visibility, } -/// Indicates workspace visibility. Visible workspaces have a boolean flag to indicate if they are also focused. -/// Yes, this is the same signature as Option, but it's impl is a lot more suited for our case. +/// Indicates workspace visibility. +/// Visible workspaces have a boolean flag to indicate if they are also focused. #[derive(Debug, Copy, Clone)] pub enum Visibility { - Visible(bool), + Visible { focused: bool }, Hidden, } impl Visibility { pub fn visible() -> Self { - Self::Visible(false) + Self::Visible { focused: false } } pub fn focused() -> Self { - Self::Visible(true) - } - - pub fn is_visible(self) -> bool { - matches!(self, Self::Visible(_)) + Self::Visible { focused: true } } pub fn is_focused(self) -> bool { - if let Self::Visible(focused) = self { + if let Self::Visible { focused } = self { focused } else { false diff --git a/src/gtk_helpers.rs b/src/gtk_helpers.rs index 5ce9357..de5d8af 100644 --- a/src/gtk_helpers.rs +++ b/src/gtk_helpers.rs @@ -20,7 +20,7 @@ pub struct WidgetGeometry { pub trait IronbarGtkExt { /// Adds a new CSS class to the widget. fn add_class(&self, class: &str); - /// Removes a CSS class to the widget. + /// Removes a CSS class from the widget fn remove_class(&self, class: &str); /// Gets the geometry for the widget fn geometry(&self, orientation: Orientation) -> WidgetGeometry; diff --git a/src/modules/workspaces.rs b/src/modules/workspaces.rs deleted file mode 100644 index 039d969..0000000 --- a/src/modules/workspaces.rs +++ /dev/null @@ -1,451 +0,0 @@ -use crate::clients::compositor::{Visibility, Workspace, WorkspaceClient, WorkspaceUpdate}; -use crate::config::CommonConfig; -use crate::gtk_helpers::IronbarGtkExt; -use crate::image::new_icon_button; -use crate::modules::{Module, ModuleInfo, ModuleParts, ModuleUpdateEvent, WidgetContext}; -use crate::{glib_recv, module_impl, send_async, spawn, try_send, Ironbar}; -use color_eyre::{Report, Result}; -use gtk::prelude::*; -use gtk::{Button, IconTheme}; -use serde::Deserialize; -use std::cmp::Ordering; -use std::collections::{HashMap, HashSet}; -use tokio::sync::mpsc::{Receiver, Sender}; -use tracing::{debug, trace, warn}; - -#[derive(Debug, Deserialize, Clone, Copy, Eq, PartialEq)] -#[serde(rename_all = "snake_case")] -#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))] -pub enum SortOrder { - /// Shows workspaces in the order they're added - Added, - /// Shows workspaces in numeric order. - /// Named workspaces are added to the end in alphabetical order. - Alphanumeric, -} - -impl Default for SortOrder { - fn default() -> Self { - Self::Alphanumeric - } -} - -#[derive(Debug, Deserialize, Clone)] -#[serde(untagged)] -#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))] -pub enum Favorites { - ByMonitor(HashMap>), - Global(Vec), -} - -impl Default for Favorites { - fn default() -> Self { - Self::Global(vec![]) - } -} - -#[derive(Debug, Deserialize, Clone)] -#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))] -pub struct WorkspacesModule { - /// Map of actual workspace names to custom names. - /// - /// Custom names can be [images](images). - /// - /// If a workspace is not present in the map, - /// it will fall back to using its actual name. - name_map: Option>, - - /// Workspaces which should always be shown. - /// This can either be an array of workspace names, - /// or a map of monitor names to arrays of workspace names. - /// - /// **Default**: `{}` - /// - /// # Example - /// - /// ```corn - /// // array format - /// { - /// type = "workspaces" - /// favorites = ["1", "2", "3"] - /// } - /// - /// // map format - /// { - /// type = "workspaces" - /// favorites.DP-1 = ["1", "2", "3"] - /// favorites.DP-2 = ["4", "5", "6"] - /// } - /// ``` - #[serde(default)] - favorites: Favorites, - - /// A list of workspace names to never show. - /// - /// This may be useful for scratchpad/special workspaces, for example. - /// - /// **Default**: `[]` - #[serde(default)] - hidden: Vec, - - /// Whether to display workspaces from all monitors. - /// When false, only shows workspaces on the current monitor. - /// - /// **Default**: `false` - #[serde(default = "crate::config::default_false")] - all_monitors: bool, - - /// The method used for sorting workspaces. - /// `added` always appends to the end, `alphanumeric` sorts by number/name. - /// - /// **Valid options**: `added`, `alphanumeric` - ///
- /// **Default**: `alphanumeric` - #[serde(default)] - sort: SortOrder, - - /// The size to render icons at (image icons only). - /// - /// **Default**: `32` - #[serde(default = "default_icon_size")] - icon_size: i32, - - /// See [common options](module-level-options#common-options). - #[serde(flatten)] - pub common: Option, -} - -const fn default_icon_size() -> i32 { - 32 -} - -/// Creates a button from a workspace -fn create_button( - name: &str, - visibility: Visibility, - name_map: &HashMap, - icon_theme: &IconTheme, - icon_size: i32, - tx: &Sender, -) -> Button { - let label = name_map.get(name).map_or(name, String::as_str); - - let button = new_icon_button(label, icon_theme, icon_size); - button.set_widget_name(name); - - button.add_class("item"); - - if visibility.is_visible() { - button.add_class("visible"); - } - - if visibility.is_focused() { - button.add_class("focused"); - } - - if !visibility.is_visible() { - button.add_class("inactive"); - } - - { - let tx = tx.clone(); - let name = name.to_string(); - button.connect_clicked(move |button| { - if !button.style_context().has_class("focused") { - try_send!(tx, name.clone()); - } - }); - } - - button -} - -fn reorder_workspaces(container: >k::Box) { - let mut buttons = container - .children() - .into_iter() - .map(|child| { - let label = child - .downcast_ref::