From 03136e7c700e545c566eb281c50e6ea343646bc6 Mon Sep 17 00:00:00 2001 From: Jake Stanger Date: Sat, 28 Dec 2024 14:00:37 +0000 Subject: [PATCH] feat(workspaces): new sorting options Renames existing `alphanumeric` sorting method to `label` and adds a new method called `name` which uses the real workspace name, akin to behaviour before #799. BREAKING CHANGE: The workspace `sort` config option valid values have changed. Where `alphanumeric` is explicitly set, this will need changing to one of `label` or `name`. --- docs/modules/Workspaces.md | 16 +++++----- src/modules/workspaces/mod.rs | 55 +++++++++++++++++++++++++---------- 2 files changed, 47 insertions(+), 24 deletions(-) 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/modules/workspaces/mod.rs b/src/modules/workspaces/mod.rs index fd00a45..39548e1 100644 --- a/src/modules/workspaces/mod.rs +++ b/src/modules/workspaces/mod.rs @@ -18,21 +18,29 @@ use std::collections::HashMap; use tokio::sync::mpsc; use tracing::{debug, trace, warn}; -#[derive(Debug, Deserialize, Clone, Copy, Eq, PartialEq)] +#[derive(Debug, Deserialize, Default, 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 - } + /// Shows workspaces in the order of their displayed labels, + /// accounting for any mappings supplied in `name_map`. + /// In most cases, this is likely their number. + /// + /// Workspaces are sorted numerically first, + /// and named workspaces are added to the end in alphabetical order. + #[default] + Label, + + /// Shows workspaces in the order of their real names, + /// as supplied by the compositor. + /// In most cases, this is likely their number. + /// + /// Workspaces are sorted numerically first, + /// and named workspaces are added to the end in alphabetical order. + Name, } #[derive(Debug, Deserialize, Clone)] @@ -101,11 +109,14 @@ pub struct WorkspacesModule { all_monitors: bool, /// The method used for sorting workspaces. - /// `added` always appends to the end, `alphanumeric` sorts by number/name. /// - /// **Valid options**: `added`, `alphanumeric` + /// - `added` always appends to the end. + /// - `label` sorts by displayed value. + /// - `name` sorts by workspace name. + /// + /// **Valid options**: `added`, `label`, `name`. ///
- /// **Default**: `alphanumeric` + /// **Default**: `label` #[serde(default)] sort: SortOrder, @@ -136,11 +147,23 @@ pub struct WorkspaceItemContext { /// using their widget names. /// /// Named workspaces are always sorted before numbered ones. -fn reorder_workspaces(container: >k::Box) { +fn reorder_workspaces(container: >k::Box, sort_order: SortOrder) { let mut buttons = container .children() .into_iter() - .map(|child| (child.widget_name().to_string(), child)) + .map(|child| { + let label = if sort_order == SortOrder::Label { + child + .downcast_ref::() + .and_then(|button| button.label()) + .unwrap_or_else(|| child.widget_name()) + } else { + child.widget_name() + } + .to_string(); + + (label, child) + }) .collect::>(); buttons.sort_by(|(label_a, _), (label_b, _a)| { @@ -285,8 +308,8 @@ impl Module for WorkspacesModule { macro_rules! reorder { () => { - if self.sort == SortOrder::Alphanumeric { - reorder_workspaces(&container); + if self.sort != SortOrder::Added { + reorder_workspaces(&container, self.sort); } }; }