feat: scrolling
This commit is contained in:
parent
6657cd514b
commit
3b4f15b935
7 changed files with 73 additions and 15 deletions
2
Cargo.lock
generated
2
Cargo.lock
generated
|
|
@ -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",
|
||||||
|
|
|
||||||
|
|
@ -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();
|
||||||
|
|
|
||||||
|
|
@ -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);
|
||||||
|
|
|
||||||
|
|
@ -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();
|
||||||
|
|
|
||||||
|
|
@ -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();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
|
|
|
||||||
|
|
@ -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();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue