feat: scrolling

This commit is contained in:
Ashley Wulber 2022-06-20 14:42:12 -04:00
parent 6657cd514b
commit 3b4f15b935
No known key found for this signature in database
GPG key ID: 5216D4F46A90A820
7 changed files with 73 additions and 15 deletions

2
Cargo.lock generated
View file

@ -428,7 +428,7 @@ dependencies = [
[[package]] [[package]]
name = "cosmic-panel-config" name = "cosmic-panel-config"
version = "0.1.0" version = "0.1.0"
source = "git+https://github.com/pop-os/cosmic-panel#231dc1ec0656840458d9f0d3468d9c7ea5c2a98c" source = "git+https://github.com/pop-os/cosmic-panel/#231dc1ec0656840458d9f0d3468d9c7ea5c2a98c"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"gtk4", "gtk4",

View file

@ -11,7 +11,7 @@ use once_cell::sync::OnceCell;
use wayland::State; use wayland::State;
use std::sync::{Arc, Mutex}; use std::sync::{Arc, Mutex};
use tokio::sync::mpsc; use tokio::sync::mpsc;
use utils::{Activate}; use utils::{Activate, WorkspaceEvent};
use window::CosmicWorkspacesWindow; use window::CosmicWorkspacesWindow;
mod localize; mod localize;
@ -24,7 +24,7 @@ mod workspace_list;
mod workspace_object; mod workspace_object;
const ID: &str = "com.system76.CosmicAppletWorkspaces"; const ID: &str = "com.system76.CosmicAppletWorkspaces";
static TX: OnceCell<mpsc::Sender<Activate>> = OnceCell::new(); static TX: OnceCell<mpsc::Sender<WorkspaceEvent>> = OnceCell::new();
pub fn localize() { pub fn localize() {
let localizer = crate::localize::localizer(); let localizer = crate::localize::localizer();

View file

@ -7,6 +7,12 @@ use std::future::Future;
pub type Activate = String; pub type Activate = String;
#[derive(Debug, Clone)]
pub enum WorkspaceEvent {
Activate(String),
Scroll(f64),
}
pub fn data_path() -> PathBuf { pub fn data_path() -> PathBuf {
let mut path = glib::user_data_dir(); let mut path = glib::user_data_dir();
path.push(crate::ID); path.push(crate::ID);

View file

@ -1,4 +1,4 @@
use crate::{utils::{Activate}, wayland::generated::client::zext_workspace_manager_v1::ZextWorkspaceManagerV1, wayland_source::WaylandSource}; use crate::{utils::{Activate, WorkspaceEvent}, wayland::generated::client::zext_workspace_manager_v1::ZextWorkspaceManagerV1, wayland_source::WaylandSource};
use std::{env, os::unix::net::UnixStream, path::PathBuf, sync::Arc, mem, time::Duration}; use std::{env, os::unix::net::UnixStream, path::PathBuf, sync::Arc, mem, time::Duration};
use gtk4::glib; use gtk4::glib;
use tokio::sync::mpsc; use tokio::sync::mpsc;
@ -38,7 +38,7 @@ use self::generated::client::{
zext_workspace_handle_v1::{self, ZextWorkspaceHandleV1}, zext_workspace_handle_v1::{self, ZextWorkspaceHandleV1},
}; };
pub fn spawn_workspaces(tx: glib::Sender<State>) -> mpsc::Sender<Activate> { pub fn spawn_workspaces(tx: glib::Sender<State>) -> mpsc::Sender<WorkspaceEvent> {
let (workspaces_tx, mut workspaces_rx) = mpsc::channel(100); let (workspaces_tx, mut workspaces_rx) = mpsc::channel(100);
if let Ok(Ok(conn)) = std::env::var("HOST_WAYLAND_DISPLAY") if let Ok(Ok(conn)) = std::env::var("HOST_WAYLAND_DISPLAY")
.map_err(anyhow::Error::msg) .map_err(anyhow::Error::msg)
@ -75,14 +75,46 @@ pub fn spawn_workspaces(tx: glib::Sender<State>) -> mpsc::Sender<Activate> {
while state.running { while state.running {
let mut changed = false; let mut changed = false;
while let Ok(request) = workspaces_rx.try_recv() { while let Ok(request) = workspaces_rx.try_recv() {
if let Some(w) = state.workspace_groups.iter().find_map(|g| { match request {
g.workspaces WorkspaceEvent::Activate(id) => {
.iter() if let Some(w) = state.workspace_groups.iter().find_map(|g| {
.find(|w| w.name == request) g.workspaces
}) { .iter()
w.workspace_handle.activate(); .find(|w| w.name == id)
}) {
w.workspace_handle.activate();
changed = true;
}
}
WorkspaceEvent::Scroll(v) => {
dbg!(v);
if let Some((w_g, w_i)) = state.workspace_groups.iter().enumerate().find_map(|(g_i, g)| {
g.workspaces
.iter()
.position(|w| w.state == 0)
.map(|w_i| (g, w_i))
}) {
let max_w = w_g.workspaces.len().wrapping_sub(1);
let d_i = if v > 0.0 {
if w_i == max_w {
0
} else {
w_i.wrapping_add(1)
}
} else {
if w_i == 0 {
max_w
} else {
w_i.wrapping_sub(1)
} };
if let Some(w) = w_g.workspaces.get(d_i) {
w.workspace_handle.activate();
changed = true;
}
}
}
} }
changed = true;
} }
if changed { if changed {
state.workspace_manager.as_ref().unwrap().commit(); state.workspace_manager.as_ref().unwrap().commit();

View file

@ -1,6 +1,6 @@
mod imp; mod imp;
use crate::{workspace_object::WorkspaceObject, Activate, TX}; use crate::{workspace_object::WorkspaceObject, Activate, TX, utils::WorkspaceEvent};
use glib::Object; use glib::Object;
use gtk4::{glib, prelude::*, subclass::prelude::*, ToggleButton}; use gtk4::{glib, prelude::*, subclass::prelude::*, ToggleButton};
@ -44,7 +44,7 @@ impl WorkspaceButton {
let id_clone = id.clone(); let id_clone = id.clone();
if !is_active { if !is_active {
glib::MainContext::default().spawn_local(async move { glib::MainContext::default().spawn_local(async move {
TX.get().unwrap().send(id_clone).await.unwrap(); TX.get().unwrap().send(WorkspaceEvent::Activate(id_clone)).await.unwrap();
}); });
} }
}); });

View file

@ -2,7 +2,7 @@
use cosmic_panel_config::config::CosmicPanelConfig; use cosmic_panel_config::config::CosmicPanelConfig;
use gtk4::subclass::prelude::*; use gtk4::subclass::prelude::*;
use gtk4::{gio, glib}; use gtk4::{gio, glib, EventControllerScroll};
use gtk4::{Box, ListView}; use gtk4::{Box, ListView};
use once_cell::sync::OnceCell; use once_cell::sync::OnceCell;
use tokio::sync::mpsc; use tokio::sync::mpsc;

View file

@ -1,14 +1,19 @@
// SPDX-License-Identifier: MPL-2.0-only // SPDX-License-Identifier: MPL-2.0-only
use crate::TX;
use crate::utils::Activate; use crate::utils::Activate;
use crate::utils::WorkspaceEvent;
use crate::wayland::State; use crate::wayland::State;
use crate::workspace_button::WorkspaceButton; use crate::workspace_button::WorkspaceButton;
use crate::workspace_object::WorkspaceObject; use crate::workspace_object::WorkspaceObject;
use cascade::cascade; use cascade::cascade;
use cosmic_panel_config::config::{CosmicPanelConfig}; use cosmic_panel_config::config::{CosmicPanelConfig};
use gtk4::EventControllerScrollFlags;
use gtk4::Inhibit;
use gtk4::ListView; use gtk4::ListView;
use gtk4::Orientation; use gtk4::Orientation;
use gtk4::SignalListItemFactory; use gtk4::SignalListItemFactory;
use gtk4::builders::EventControllerScrollBuilder;
use gtk4::{gio, glib, prelude::*, subclass::prelude::*}; use gtk4::{gio, glib, prelude::*, subclass::prelude::*};
use tokio::sync::mpsc::Sender; use tokio::sync::mpsc::Sender;
@ -48,6 +53,21 @@ impl WorkspaceList {
..add_css_class("transparent"); ..add_css_class("transparent");
}; };
self.append(&list_view); self.append(&list_view);
let flags = EventControllerScrollFlags::BOTH_AXES;
let scroll_controller = EventControllerScrollBuilder::new()
.flags(flags.union(EventControllerScrollFlags::DISCRETE))
.build();
scroll_controller.connect_scroll( |_, dx, dy| {
glib::MainContext::default().spawn_local(async move {
TX.get().unwrap().send(WorkspaceEvent::Scroll(dx + dy)).await.unwrap();
});
Inhibit::default()
});
list_view.add_controller(&scroll_controller);
imp.list_view.set(list_view).unwrap(); imp.list_view.set(list_view).unwrap();
} }