Use libcosmic DiscreteScrollState helper
This commit is contained in:
parent
cf2bb0205c
commit
a607da7f44
2 changed files with 102 additions and 121 deletions
101
src/main.rs
101
src/main.rs
|
|
@ -28,6 +28,7 @@ use cosmic::{
|
|||
iced_winit::platform_specific::wayland::commands::layer_surface::{
|
||||
destroy_layer_surface, get_layer_surface,
|
||||
},
|
||||
scroll::DiscreteScrollState,
|
||||
};
|
||||
use cosmic_comp_config::CosmicCompConfig;
|
||||
use cosmic_config::{CosmicConfigEntry, cosmic_config_derive::CosmicConfigEntry};
|
||||
|
|
@ -38,7 +39,7 @@ use std::{
|
|||
mem,
|
||||
path::PathBuf,
|
||||
str,
|
||||
time::{Duration, Instant},
|
||||
time::Duration,
|
||||
};
|
||||
|
||||
mod dbus;
|
||||
|
|
@ -53,8 +54,7 @@ mod utils;
|
|||
mod widgets;
|
||||
use dnd::{DragSurface, DragToplevel, DragWorkspace, DropTarget};
|
||||
|
||||
// Number of scroll pixels before changing workspace
|
||||
const SCROLL_PIXELS: f32 = 24.0;
|
||||
const SCROLL_RATE_LIMIT: Duration = Duration::from_millis(200);
|
||||
|
||||
#[derive(Clone, Debug, Default, PartialEq, CosmicConfigEntry)]
|
||||
struct CosmicWorkspacesConfig {
|
||||
|
|
@ -86,11 +86,6 @@ impl CosmicFlags for Args {
|
|||
}
|
||||
}
|
||||
|
||||
enum ScrollDirection {
|
||||
Next,
|
||||
Prev,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
enum Msg {
|
||||
WaylandEvent(WaylandEvent),
|
||||
|
|
@ -200,7 +195,7 @@ struct App {
|
|||
conf: Conf,
|
||||
core: cosmic::app::Core,
|
||||
drop_target: Option<DropTarget>,
|
||||
scroll: Option<(f32, Instant)>,
|
||||
scroll: DiscreteScrollState,
|
||||
dbus_interface: Option<dbus::Interface>,
|
||||
panel_configs: HashMap<String, Option<CosmicPanelConfig>>,
|
||||
}
|
||||
|
|
@ -415,6 +410,7 @@ impl Application for App {
|
|||
(
|
||||
Self {
|
||||
core,
|
||||
scroll: DiscreteScrollState::default().rate_limit(Some(SCROLL_RATE_LIMIT)),
|
||||
..Default::default()
|
||||
},
|
||||
Task::none(),
|
||||
|
|
@ -672,81 +668,20 @@ impl Application for App {
|
|||
}
|
||||
}
|
||||
Msg::OnScroll(output, delta) => {
|
||||
// Accumulate delta with a timer
|
||||
// TODO: Should x scroll be handled too?
|
||||
// Best time/pixel count?
|
||||
|
||||
let previous_scroll = if let Some((scroll, last_scroll_time)) = self.scroll {
|
||||
if last_scroll_time.elapsed() > Duration::from_millis(100) {
|
||||
0.
|
||||
} else {
|
||||
scroll
|
||||
let discrete_delta = self.scroll.update(delta);
|
||||
if discrete_delta.y != 0 {
|
||||
// TODO assumes only one active workspace per output
|
||||
let workspaces = self.workspaces.for_output(&output).collect::<Vec<_>>();
|
||||
if let Some(workspace_idx) = workspaces.iter().position(|i| i.is_active()) {
|
||||
// Add delta_num, to index wrapping around
|
||||
let new_workspace_idx = (workspace_idx as isize - discrete_delta.y)
|
||||
.rem_euclid(workspaces.len() as isize)
|
||||
as usize;
|
||||
let workspace = workspaces[new_workspace_idx];
|
||||
self.send_wayland_cmd(backend::Cmd::ActivateWorkspace(
|
||||
workspace.handle().clone(),
|
||||
));
|
||||
}
|
||||
} else {
|
||||
0.
|
||||
};
|
||||
|
||||
let direction = match delta {
|
||||
ScrollDelta::Pixels { x: _, mut y } => {
|
||||
y = -y;
|
||||
|
||||
let scroll = previous_scroll + y;
|
||||
if scroll <= -SCROLL_PIXELS {
|
||||
self.scroll = None;
|
||||
ScrollDirection::Prev
|
||||
} else if scroll >= SCROLL_PIXELS {
|
||||
self.scroll = None;
|
||||
ScrollDirection::Next
|
||||
} else {
|
||||
// If scroll has y element, accumulate scroll
|
||||
self.scroll = if y != 0. {
|
||||
Some((scroll, Instant::now()))
|
||||
} else {
|
||||
None
|
||||
};
|
||||
return Task::none();
|
||||
}
|
||||
}
|
||||
ScrollDelta::Lines { x: _, mut y } => {
|
||||
y = -y;
|
||||
|
||||
let scroll = previous_scroll + y;
|
||||
if scroll <= -1. {
|
||||
self.scroll = None;
|
||||
ScrollDirection::Prev
|
||||
} else if scroll >= 1. {
|
||||
self.scroll = None;
|
||||
ScrollDirection::Next
|
||||
} else {
|
||||
self.scroll = if y != 0. {
|
||||
Some((scroll, Instant::now()))
|
||||
} else {
|
||||
None
|
||||
};
|
||||
return Task::none();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// TODO assumes only one active workspace per output
|
||||
let workspaces = self.workspaces.for_output(&output).collect::<Vec<_>>();
|
||||
if let Some(workspace_idx) = workspaces.iter().position(|i| i.is_active()) {
|
||||
let new_workspace_idx = match direction {
|
||||
// Next workspace on output, wrapping to start
|
||||
ScrollDirection::Next => (workspace_idx + 1) % workspaces.len(),
|
||||
// Previous workspace on output, wrapping to end
|
||||
ScrollDirection::Prev => {
|
||||
if workspace_idx == 0 {
|
||||
workspaces.len() - 1
|
||||
} else {
|
||||
workspace_idx - 1
|
||||
}
|
||||
}
|
||||
};
|
||||
let workspace = workspaces[new_workspace_idx];
|
||||
self.send_wayland_cmd(backend::Cmd::ActivateWorkspace(
|
||||
workspace.handle().clone(),
|
||||
));
|
||||
}
|
||||
}
|
||||
Msg::DndWorkspaceDrag => {}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue