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.
This commit is contained in:
Ian Douglas Scott 2025-01-24 15:35:45 -08:00 committed by Ian Douglas Scott
parent a977667ac5
commit 3d7d3823c4
2 changed files with 29 additions and 1 deletions

View file

@ -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<PathBuf>),
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::<Vec<_>>();
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 => {}
}

View file

@ -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> {