feat: don't include hidden workspaces

This commit is contained in:
Ashley Wulber 2022-06-20 15:48:27 -04:00
parent 8a3fd21b26
commit 031ec45cd7
No known key found for this signature in database
GPG key ID: 5216D4F46A90A820
13 changed files with 98 additions and 55 deletions

View file

@ -5,7 +5,7 @@ use crate::dock_popover::DockPopover;
use crate::utils::BoxedWindowList; use crate::utils::BoxedWindowList;
use crate::utils::Event; use crate::utils::Event;
use cascade::cascade; use cascade::cascade;
use cosmic_panel_config::config::{PanelAnchor}; use cosmic_panel_config::config::PanelAnchor;
use gtk4::glib; use gtk4::glib;
use gtk4::prelude::*; use gtk4::prelude::*;
use gtk4::subclass::prelude::*; use gtk4::subclass::prelude::*;

View file

@ -1,6 +1,6 @@
// SPDX-License-Identifier: MPL-2.0-only // SPDX-License-Identifier: MPL-2.0-only
use cosmic_panel_config::config::{PanelAnchor, CosmicPanelConfig}; use cosmic_panel_config::config::{CosmicPanelConfig, PanelAnchor};
use glib::SignalHandlerId; use glib::SignalHandlerId;
use gtk4::subclass::prelude::*; use gtk4::subclass::prelude::*;
use gtk4::{gio, glib}; use gtk4::{gio, glib};

View file

@ -10,7 +10,7 @@ pub mod graphics;
pub mod mode_box; pub mod mode_box;
use self::{dbus::PowerDaemonProxy, graphics::Graphics, mode_box::ModeSelection}; use self::{dbus::PowerDaemonProxy, graphics::Graphics, mode_box::ModeSelection};
use cosmic_panel_config::config::{CosmicPanelConfig}; use cosmic_panel_config::config::CosmicPanelConfig;
use gtk4::{ use gtk4::{
gdk::Display, gdk::Display,
gio::ApplicationFlags, gio::ApplicationFlags,

View file

@ -6,7 +6,7 @@ extern crate relm4_macros;
pub mod session_manager; pub mod session_manager;
pub mod ui; pub mod ui;
use cosmic_panel_config::config::{CosmicPanelConfig}; use cosmic_panel_config::config::CosmicPanelConfig;
use gtk4::{gio::ApplicationFlags, glib, prelude::*, Align, Button, Label, Orientation, Separator}; use gtk4::{gio::ApplicationFlags, glib, prelude::*, Align, Button, Label, Orientation, Separator};
use once_cell::sync::Lazy; use once_cell::sync::Lazy;
use std::process::Command; use std::process::Command;

View file

@ -8,10 +8,10 @@ use gtk4::{
CssProvider, StyleContext, CssProvider, StyleContext,
}; };
use once_cell::sync::OnceCell; use once_cell::sync::OnceCell;
use wayland::State;
use std::sync::{Arc, Mutex}; use std::sync::{Arc, Mutex};
use tokio::sync::mpsc; use tokio::sync::mpsc;
use utils::{Activate, WorkspaceEvent}; use utils::{Activate, WorkspaceEvent};
use wayland::State;
use window::CosmicWorkspacesWindow; use window::CosmicWorkspacesWindow;
mod localize; mod localize;

View file

@ -1,11 +1,19 @@
use crate::{utils::{Activate, WorkspaceEvent}, wayland::generated::client::zext_workspace_manager_v1::ZextWorkspaceManagerV1, wayland_source::WaylandSource}; use crate::{
use std::{env, os::unix::net::UnixStream, path::PathBuf, sync::Arc, mem, time::Duration}; utils::{Activate, WorkspaceEvent},
wayland::generated::client::zext_workspace_manager_v1::ZextWorkspaceManagerV1,
wayland_source::WaylandSource,
};
use gtk4::glib; use gtk4::glib;
use std::{env, mem, os::unix::net::UnixStream, path::PathBuf, sync::Arc, time::Duration};
use tokio::sync::mpsc; use tokio::sync::mpsc;
use wayland_backend::client::ObjectData; use wayland_backend::client::ObjectData;
use wayland_client::{ use wayland_client::{
protocol::{wl_output::{WlOutput, self}, wl_registry}, event_created_child,
ConnectError, Proxy, event_created_child, protocol::{
wl_output::{self, WlOutput},
wl_registry,
},
ConnectError, Proxy,
}; };
use wayland_client::{Connection, Dispatch, QueueHandle}; use wayland_client::{Connection, Dispatch, QueueHandle};
@ -60,9 +68,10 @@ pub fn spawn_workspaces(tx: glib::Sender<State>) -> mpsc::Sender<WorkspaceEvent>
let event_queue = conn.new_event_queue::<State>(); let event_queue = conn.new_event_queue::<State>();
let qhandle = event_queue.handle(); let qhandle = event_queue.handle();
WaylandSource::new(event_queue).expect("Failed to create wayland source") WaylandSource::new(event_queue)
.insert(loop_handle) .expect("Failed to create wayland source")
.unwrap(); .insert(loop_handle)
.unwrap();
let display = conn.display(); let display = conn.display();
display.get_registry(&qhandle, ()).unwrap(); display.get_registry(&qhandle, ()).unwrap();
@ -79,36 +88,42 @@ pub fn spawn_workspaces(tx: glib::Sender<State>) -> mpsc::Sender<WorkspaceEvent>
while let Ok(request) = workspaces_rx.try_recv() { while let Ok(request) = workspaces_rx.try_recv() {
match request { match request {
WorkspaceEvent::Activate(id) => { WorkspaceEvent::Activate(id) => {
if let Some(w) = state.workspace_groups.iter().find_map(|g| { if let Some(w) = state
g.workspaces .workspace_groups
.iter() .iter()
.find(|w| w.name == id) .find_map(|g| g.workspaces.iter().find(|w| w.name == id))
}) { {
w.workspace_handle.activate(); w.workspace_handle.activate();
changed = true; changed = true;
} }
} }
WorkspaceEvent::Scroll(v) => { WorkspaceEvent::Scroll(v) => {
dbg!(v); dbg!(v);
if let Some((w_g, w_i)) = state.workspace_groups.iter().enumerate().find_map(|(g_i, g)| { if let Some((w_g, w_i)) = state
g.workspaces .workspace_groups
.iter() .iter()
.position(|w| w.state == 0) .enumerate()
.map(|w_i| (g, w_i)) .find_map(|(g_i, g)| {
}) { g.workspaces
let max_w = w_g.workspaces.len().wrapping_sub(1); .iter()
let d_i = if v > 0.0 { .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 { if w_i == max_w {
0 0
} else { } else {
w_i.wrapping_add(1) w_i.wrapping_add(1)
} }
} else { } else {
if w_i == 0 { if w_i == 0 {
max_w max_w
} else { } else {
w_i.wrapping_sub(1) w_i.wrapping_sub(1)
} }; }
};
if let Some(w) = w_g.workspaces.get(d_i) { if let Some(w) = w_g.workspaces.get(d_i) {
w.workspace_handle.activate(); w.workspace_handle.activate();
changed = true; changed = true;
@ -116,12 +131,13 @@ pub fn spawn_workspaces(tx: glib::Sender<State>) -> mpsc::Sender<WorkspaceEvent>
} }
} }
} }
} }
if changed { if changed {
state.workspace_manager.as_ref().unwrap().commit(); state.workspace_manager.as_ref().unwrap().commit();
} }
event_loop.dispatch(Duration::from_millis(16), &mut state).unwrap(); event_loop
.dispatch(Duration::from_millis(16), &mut state)
.unwrap();
std::thread::sleep(Duration::from_millis(16)); std::thread::sleep(Duration::from_millis(16));
} }
}); });
@ -143,8 +159,11 @@ pub struct State {
impl State { impl State {
// XXX // XXX
pub fn workspace_list(&self) -> impl Iterator<Item=(String, u32)> + '_ { pub fn workspace_list(&self) -> impl Iterator<Item = (String, u32)> + '_ {
self.workspace_groups.iter().map(|g| g.workspaces.iter().map(|w| (w.name.clone(), w.state))).flatten() self.workspace_groups
.iter()
.map(|g| g.workspaces.iter().map(|w| (w.name.clone(), w.state)))
.flatten()
} }
} }
@ -354,5 +373,6 @@ impl Dispatch<WlOutput, ()> for State {
_: &(), _: &(),
_: &Connection, _: &Connection,
_: &QueueHandle<Self>, _: &QueueHandle<Self>,
) {} ) {
}
} }

View file

@ -33,7 +33,11 @@ impl<D> WaylandSource<D> {
let fd = Generic::new(guard.connection_fd(), Interest::READ, Mode::Level); let fd = Generic::new(guard.connection_fd(), Interest::READ, Mode::Level);
drop(guard); drop(guard);
Ok(WaylandSource { queue, fd, read_guard: None }) Ok(WaylandSource {
queue,
fd,
read_guard: None,
})
} }
/// Access the underlying event queue /// Access the underlying event queue
@ -212,4 +216,4 @@ impl<D> WaylandSource<D> {
} }
}) })
} }
} }

View file

@ -1,6 +1,6 @@
// SPDX-License-Identifier: MPL-2.0-only // SPDX-License-Identifier: MPL-2.0-only
use crate::{fl, utils::Activate, workspace_list::WorkspaceList, wayland::State}; use crate::{fl, utils::Activate, wayland::State, workspace_list::WorkspaceList};
use cascade::cascade; use cascade::cascade;
use cosmic_panel_config::config::CosmicPanelConfig; use cosmic_panel_config::config::CosmicPanelConfig;
use gtk4::{ use gtk4::{
@ -9,7 +9,6 @@ use gtk4::{
prelude::*, prelude::*,
subclass::prelude::*, subclass::prelude::*,
}; };
use tokio::sync::mpsc;
mod imp; mod imp;

View file

@ -1,6 +1,6 @@
mod imp; mod imp;
use crate::{workspace_object::WorkspaceObject, Activate, TX, utils::WorkspaceEvent}; use crate::{utils::WorkspaceEvent, workspace_object::WorkspaceObject, Activate, TX};
use glib::Object; use glib::Object;
use gtk4::{glib, prelude::*, subclass::prelude::*, ToggleButton}; use gtk4::{glib, prelude::*, subclass::prelude::*, ToggleButton};
@ -44,7 +44,11 @@ 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(WorkspaceEvent::Activate(id_clone)).await.unwrap(); TX.get()
.unwrap()
.send(WorkspaceEvent::Activate(id_clone))
.await
.unwrap();
}); });
} }
}); });

View file

@ -1,19 +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::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 crate::TX;
use cascade::cascade; use cascade::cascade;
use cosmic_panel_config::config::{CosmicPanelConfig}; use cosmic_panel_config::config::CosmicPanelConfig;
use gtk4::builders::EventControllerScrollBuilder;
use gtk4::EventControllerScrollFlags; use gtk4::EventControllerScrollFlags;
use gtk4::Inhibit; 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;
@ -55,14 +55,18 @@ impl WorkspaceList {
self.append(&list_view); self.append(&list_view);
let flags = EventControllerScrollFlags::BOTH_AXES; let flags = EventControllerScrollFlags::BOTH_AXES;
let scroll_controller = EventControllerScrollBuilder::new()
.flags(flags.union(EventControllerScrollFlags::DISCRETE))
.build();
scroll_controller.connect_scroll( |_, dx, dy| { let scroll_controller = EventControllerScrollBuilder::new()
.flags(flags.union(EventControllerScrollFlags::DISCRETE))
.build();
scroll_controller.connect_scroll(|_, dx, dy| {
glib::MainContext::default().spawn_local(async move { glib::MainContext::default().spawn_local(async move {
TX.get().unwrap().send(WorkspaceEvent::Scroll(dx + dy)).await.unwrap(); TX.get()
.unwrap()
.send(WorkspaceEvent::Scroll(dx + dy))
.await
.unwrap();
}); });
Inhibit::default() Inhibit::default()
}); });
@ -76,11 +80,20 @@ impl WorkspaceList {
let model = imp.model.get().unwrap(); let model = imp.model.get().unwrap();
let model_len = model.n_items(); let model_len = model.n_items();
let new_results: Vec<glib::Object> = workspaces.workspace_list() let new_results: Vec<glib::Object> = workspaces
.workspace_list()
.into_iter() .into_iter()
.map(|w| WorkspaceObject::from_id_active(w.0, w.1).upcast()) .filter_map(|w| {
// don't include hidden workspaces
if w.1 != 2 {
Some(WorkspaceObject::from_id_active(w.0, w.1).upcast())
} else {
None
}
})
.collect(); .collect();
model.splice(0, model_len, &new_results[..]); } model.splice(0, model_len, &new_results[..]);
}
fn setup_model(&self) { fn setup_model(&self) {
let imp = imp::WorkspaceList::from_instance(self); let imp = imp::WorkspaceList::from_instance(self);

View file

@ -1,6 +1,6 @@
// SPDX-License-Identifier: MPL-2.0-only // SPDX-License-Identifier: MPL-2.0-only
use std::cell::{RefCell, Cell}; use std::cell::{Cell, RefCell};
use glib::{ParamFlags, ParamSpec, Value}; use glib::{ParamFlags, ParamSpec, Value};
use gtk4::gdk::glib::ParamSpecBoolean; use gtk4::gdk::glib::ParamSpecBoolean;

View file

@ -18,7 +18,10 @@ impl WorkspaceObject {
} }
pub fn id(&self) -> String { pub fn id(&self) -> String {
imp::WorkspaceObject::from_instance(&self).id.borrow().clone() imp::WorkspaceObject::from_instance(&self)
.id
.borrow()
.clone()
} }
pub fn active(&self) -> u32 { pub fn active(&self) -> u32 {

View file

@ -2,7 +2,7 @@
use crate::fl; use crate::fl;
use cascade::cascade; use cascade::cascade;
use cosmic_panel_config::config::{CosmicPanelConfig}; use cosmic_panel_config::config::CosmicPanelConfig;
use gtk4::{ use gtk4::{
gio::{self, DesktopAppInfo, Icon}, gio::{self, DesktopAppInfo, Icon},
glib::{self, Object}, glib::{self, Object},