From 3d7d3823c4c9d6fec2e3736fcf8bc9d1266fd9e6 Mon Sep 17 00:00:00 2001 From: Ian Douglas Scott Date: Fri, 24 Jan 2025 15:35:45 -0800 Subject: [PATCH] Change workspace based on scroll events Works, I'm not sure how many pixels to interpret as a change to the workspace, and perhaps it should accumulate multiple deltas with a timer. Assuming some lower level of the stack isn't doing that already. I only see `ScrollDelta::Pixels` events, not `Lines`, though maybe that's relevant with a different type of input device. The behavior would also be clearer with animation, though it doesn't seem to bad (https://github.com/pop-os/cosmic-workspaces-epoch/issues/32). Fixes https://github.com/pop-os/cosmic-workspaces-epoch/issues/34. --- src/main.rs | 25 +++++++++++++++++++++++++ src/view/mod.rs | 5 ++++- 2 files changed, 29 insertions(+), 1 deletion(-) diff --git a/src/main.rs b/src/main.rs index 7543da9..4eaef5c 100644 --- a/src/main.rs +++ b/src/main.rs @@ -16,6 +16,7 @@ use cosmic::{ self, event::wayland::{Event as WaylandEvent, LayerEvent, OutputEvent}, keyboard::key::{Key, Named}, + mouse::ScrollDelta, Size, Subscription, Task, }, iced_core::window::Id as SurfaceId, @@ -98,6 +99,7 @@ enum Msg { Config(CosmicWorkspacesConfig), BgConfig(cosmic_bg_config::state::State), UpdateToplevelIcon(String, Option), + OnScroll(wl_output::WlOutput, ScrollDelta), Ignore, } @@ -537,6 +539,29 @@ impl Application for App { } } } + Msg::OnScroll(output, delta) => { + // TODO assumes only one active workspace per output + let mut workspaces = self.workspaces_for_output(&output).collect::>(); + if let Some(workspace_idx) = workspaces.iter().position(|i| i.is_active) { + if let ScrollDelta::Pixels { x: _, y } = delta { + // XXX accumulate delta, with timer? + let workspace = if y <= -4. { + // Next workspace on output + workspaces[workspace_idx + 1..].iter().next() + } else if y >= 4. { + // Previous workspace on output + workspaces[..workspace_idx].iter().last() + } else { + None + }; + if let Some(workspace) = workspace { + self.send_wayland_cmd(backend::Cmd::ActivateWorkspace( + dbg!(workspace).handle.clone(), + )); + } + } + } + } Msg::Ignore => {} } diff --git a/src/view/mod.rs b/src/view/mod.rs index 05823de..b69aa20 100644 --- a/src/view/mod.rs +++ b/src/view/mod.rs @@ -103,7 +103,10 @@ pub(crate) fn layer_surface<'a>( .width(iced::Length::Fill), ), }; - container.into() + let output = surface.output.clone(); + widget::mouse_area(container) + .on_scroll(move |delta| Msg::OnScroll(output.clone(), delta)) + .into() } fn close_button(on_press: Msg) -> cosmic::Element<'static, Msg> {