@@ -28,6 +28,7 @@ use cosmic::{
2828 iced_winit:: platform_specific:: wayland:: commands:: layer_surface:: {
2929 destroy_layer_surface, get_layer_surface,
3030 } ,
31+ scroll:: DiscreteScrollState ,
3132} ;
3233use cosmic_comp_config:: CosmicCompConfig ;
3334use cosmic_config:: { CosmicConfigEntry , cosmic_config_derive:: CosmicConfigEntry } ;
@@ -85,11 +86,6 @@ impl CosmicFlags for Args {
8586 }
8687}
8788
88- enum ScrollDirection {
89- Next ,
90- Prev ,
91- }
92-
9389#[ derive( Clone , Debug ) ]
9490enum Msg {
9591 WaylandEvent ( WaylandEvent ) ,
@@ -197,7 +193,7 @@ struct App {
197193 conf : Conf ,
198194 core : cosmic:: app:: Core ,
199195 drop_target : Option < DropTarget > ,
200- scroll : Option < ( f32 , Instant ) > ,
196+ scroll : DiscreteScrollState ,
201197 dbus_interface : Option < dbus:: Interface > ,
202198}
203199
@@ -620,81 +616,20 @@ impl Application for App {
620616 }
621617 }
622618 Msg :: OnScroll ( output, delta) => {
623- // Accumulate delta with a timer
624- // TODO: Should x scroll be handled too?
625- // Best time/pixel count?
626-
627- let previous_scroll = if let Some ( ( scroll, last_scroll_time) ) = self . scroll {
628- if last_scroll_time. elapsed ( ) > Duration :: from_millis ( 100 ) {
629- 0.
630- } else {
631- scroll
632- }
633- } else {
634- 0.
635- } ;
636-
637- let direction = match delta {
638- ScrollDelta :: Pixels { x : _, mut y } => {
639- y = -y;
640-
641- let scroll = previous_scroll + y;
642- if scroll <= -SCROLL_PIXELS {
643- self . scroll = None ;
644- ScrollDirection :: Prev
645- } else if scroll >= SCROLL_PIXELS {
646- self . scroll = None ;
647- ScrollDirection :: Next
648- } else {
649- // If scroll has y element, accumulate scroll
650- self . scroll = if y != 0. {
651- Some ( ( scroll, Instant :: now ( ) ) )
652- } else {
653- None
654- } ;
655- return Task :: none ( ) ;
656- }
619+ let discrete_delta = self . scroll . update ( delta) ;
620+ if discrete_delta. y != 0 {
621+ // TODO assumes only one active workspace per output
622+ let workspaces = self . workspaces . for_output ( & output) . collect :: < Vec < _ > > ( ) ;
623+ if let Some ( workspace_idx) = workspaces. iter ( ) . position ( |i| i. is_active ( ) ) {
624+ // Add delta_num, to index wrapping around
625+ let new_workspace_idx = ( workspace_idx as isize - discrete_delta. y )
626+ . rem_euclid ( workspaces. len ( ) as isize )
627+ as usize ;
628+ let workspace = workspaces[ new_workspace_idx] ;
629+ self . send_wayland_cmd ( backend:: Cmd :: ActivateWorkspace (
630+ workspace. handle ( ) . clone ( ) ,
631+ ) ) ;
657632 }
658- ScrollDelta :: Lines { x : _, mut y } => {
659- y = -y;
660-
661- let scroll = previous_scroll + y;
662- if scroll <= -1. {
663- self . scroll = None ;
664- ScrollDirection :: Prev
665- } else if scroll >= 1. {
666- self . scroll = None ;
667- ScrollDirection :: Next
668- } else {
669- self . scroll = if y != 0. {
670- Some ( ( scroll, Instant :: now ( ) ) )
671- } else {
672- None
673- } ;
674- return Task :: none ( ) ;
675- }
676- }
677- } ;
678-
679- // TODO assumes only one active workspace per output
680- let workspaces = self . workspaces . for_output ( & output) . collect :: < Vec < _ > > ( ) ;
681- if let Some ( workspace_idx) = workspaces. iter ( ) . position ( |i| i. is_active ( ) ) {
682- let new_workspace_idx = match direction {
683- // Next workspace on output, wrapping to start
684- ScrollDirection :: Next => ( workspace_idx + 1 ) % workspaces. len ( ) ,
685- // Previous workspace on output, wrapping to end
686- ScrollDirection :: Prev => {
687- if workspace_idx == 0 {
688- workspaces. len ( ) - 1
689- } else {
690- workspace_idx - 1
691- }
692- }
693- } ;
694- let workspace = workspaces[ new_workspace_idx] ;
695- self . send_wayland_cmd ( backend:: Cmd :: ActivateWorkspace (
696- workspace. handle ( ) . clone ( ) ,
697- ) ) ;
698633 }
699634 }
700635 Msg :: DndWorkspaceDrag => { }
0 commit comments