wip: use desktop file stem for app id

This commit is contained in:
Ashley Wulber 2022-07-19 23:39:19 -04:00
parent 223c7855cf
commit adc02df64f
No known key found for this signature in database
GPG key ID: 5216D4F46A90A820
12 changed files with 209 additions and 146 deletions

4
Cargo.lock generated
View file

@ -2141,7 +2141,7 @@ checksum = "a3f87b73ce11b1619a3c6332f45341e0047173771e8b8b73f87bfeefb7b56244"
[[package]]
name = "relm4"
version = "0.5.0-beta.1"
source = "git+https://github.com/Relm4/Relm4.git?branch=next#746d244004e23764294b23519f6f8be1002c1ceb"
source = "git+https://github.com/relm4/relm4?branch=next#746d244004e23764294b23519f6f8be1002c1ceb"
dependencies = [
"async-broadcast",
"async-oneshot",
@ -2158,7 +2158,7 @@ dependencies = [
[[package]]
name = "relm4-macros"
version = "0.5.0-beta.1"
source = "git+https://github.com/Relm4/Relm4.git?branch=next#746d244004e23764294b23519f6f8be1002c1ceb"
source = "git+https://github.com/relm4/relm4?branch=next#746d244004e23764294b23519f6f8be1002c1ceb"
dependencies = [
"proc-macro2",
"quote",

View file

@ -6,11 +6,11 @@ use crate::dock_list::DockList;
use crate::dock_list::DockListType;
use crate::utils::AppListEvent;
use cascade::cascade;
use cosmic_panel_config::{PanelAnchor, CosmicPanelConfig};
use gtk4::Separator;
use cosmic_panel_config::{CosmicPanelConfig, PanelAnchor};
use gtk4::prelude::*;
use gtk4::subclass::prelude::*;
use gtk4::Orientation;
use gtk4::Separator;
use gtk4::{gio, glib};
use tokio::sync::mpsc::Sender;
@ -69,13 +69,12 @@ impl AppsContainer {
// Setup
self_.setup_callbacks();
self_.set_position(config.anchor);
Self::setup_callbacks(&self_);
self_
}
pub fn model(&self, type_: DockListType) -> &gio::ListStore {
// Get state
let imp = imp::AppsContainer::from_instance(self);

View file

@ -1,9 +1,9 @@
use std::fmt::Debug;
use std::fs::File;
use crate::ID;
use anyhow::anyhow;
use serde::Deserialize;
use std::fmt::Debug;
use std::fs::File;
use xdg::BaseDirectories;
use crate::ID;
#[derive(Debug, Clone, Deserialize)]
pub enum TopLevelFilter {
@ -19,13 +19,18 @@ pub struct AppListConfig {
impl AppListConfig {
/// load config with the provided name
pub fn load() -> anyhow::Result<AppListConfig> {
let file= match BaseDirectories::new().ok().and_then(|dirs| dirs.find_config_file(format!("{ID}/config.ron"))).and_then(|p| File::open(p).ok()) {
let file = match BaseDirectories::new()
.ok()
.and_then(|dirs| dirs.find_config_file(format!("{ID}/config.ron")))
.and_then(|p| File::open(p).ok())
{
Some(path) => path,
_ => {
anyhow::bail!("Failed to load config");
}
};
ron::de::from_reader::<_, AppListConfig>(file).map_err(|err| anyhow!("Failed to parse config file: {}", err))
ron::de::from_reader::<_, AppListConfig>(file)
.map_err(|err| anyhow!("Failed to parse config file: {}", err))
}
}
}

View file

@ -2,8 +2,8 @@
use crate::dock_object::DockObject;
use crate::dock_popover::DockPopover;
use crate::utils::BoxedWindowList;
use crate::utils::AppListEvent;
use crate::utils::BoxedWindowList;
use cascade::cascade;
use cosmic_panel_config::PanelAnchor;
use gtk4::glib;

View file

@ -1,6 +1,6 @@
// SPDX-License-Identifier: MPL-2.0-only
use cosmic_panel_config::{PanelAnchor, CosmicPanelConfig};
use cosmic_panel_config::{CosmicPanelConfig, PanelAnchor};
use glib::SignalHandlerId;
use gtk4::subclass::prelude::*;
use gtk4::{gio, glib};
@ -25,7 +25,7 @@ pub struct DockList {
pub popover_menu_index: Rc<Cell<Option<u32>>>,
pub position: Rc<Cell<PanelAnchor>>,
pub tx: OnceCell<mpsc::Sender<AppListEvent>>,
pub config: OnceCell<CosmicPanelConfig>
pub config: OnceCell<CosmicPanelConfig>,
}
#[glib::object_subclass]

View file

@ -1,12 +1,13 @@
// SPDX-License-Identifier: MPL-2.0-only
use crate::{TX, WAYLAND_TX};
use crate::dock_item::DockItem;
use crate::dock_object::DockObject;
use crate::utils::data_path;
use crate::utils::{BoxedWindowList, AppListEvent};
use crate::utils::{AppListEvent, BoxedWindowList};
use crate::wayland::{Toplevel, ToplevelEvent};
use crate::{TX, WAYLAND_TX};
use cascade::cascade;
use cosmic_panel_config::{CosmicPanelConfig, PanelAnchor};
use gio::DesktopAppInfo;
use gio::Icon;
use glib::Object;
@ -27,7 +28,6 @@ use gtk4::SignalListItemFactory;
use gtk4::{DragSource, GestureClick};
use std::fs::File;
use std::path::Path;
use cosmic_panel_config::{CosmicPanelConfig, PanelAnchor};
use tokio::sync::mpsc::Sender;
mod imp;

View file

@ -95,7 +95,10 @@ impl DockObject {
if let Some(path) = path.to_str() {
if let Some(app_info) = gio::DesktopAppInfo::new(path) {
if app_info.should_show()
&& Some(&first.app_id) == app_info.id().map(|s| s.to_string()).as_ref()
&& Some(&first.app_id)
== app_info.filename().and_then(|p| p
.file_stem()
.and_then(|s| s.to_str().map(|s| s.to_string()))).as_ref()
{
return Some(app_info);
}
@ -109,7 +112,7 @@ impl DockObject {
} else {
None
};
// dbg!(&appinfo);
Object::new(&[("appinfo", &appinfo), ("active", &results)])
.expect("Failed to create `DockObject`.")
}

View file

@ -9,11 +9,11 @@ use gtk4::{prelude::*, Label};
use gtk4::{Box, Button, Image, ListBox, Orientation};
use tokio::sync::mpsc::Sender;
use crate::dock_object::DockObject;
use crate::utils::AppListEvent;
use crate::utils::BoxedWindowList;
use crate::wayland::ToplevelEvent;
use crate::{TX, WAYLAND_TX};
use crate::dock_object::DockObject;
use crate::utils::BoxedWindowList;
use crate::utils::AppListEvent;
mod imp;

View file

@ -8,15 +8,16 @@ use gio::{ApplicationFlags, DesktopAppInfo};
use gtk4::gdk::Display;
use gtk4::{glib, prelude::*, CssProvider, StyleContext};
use once_cell::sync::OnceCell;
use wayland::{ToplevelEvent, Toplevel};
use std::collections::BTreeMap;
use std::sync::{Arc, Mutex};
use std::time::Duration;
use tokio::sync::mpsc;
use utils::{block_on, BoxedWindowList, AppListEvent, DEST, PATH};
use utils::{block_on, AppListEvent, BoxedWindowList, DEST, PATH};
use wayland::{Toplevel, ToplevelEvent};
mod apps_container;
mod apps_window;
mod config;
mod dock_item;
mod dock_list;
mod dock_object;
@ -25,7 +26,6 @@ mod localize;
mod utils;
mod wayland;
mod wayland_source;
mod config;
const ID: &str = "com.system76.CosmicAppList";
static TX: OnceCell<glib::Sender<AppListEvent>> = OnceCell::new();
@ -152,7 +152,9 @@ fn main() {
if let Some((i, _s)) = stack_active
.iter()
.enumerate()
.find(|(_i, s)| Some(&s.0[0].app_id) == cur_app_info.id().map(|s| s.to_string()).as_ref())
.find(|(_i, s)| Some(&s.0[0].app_id) == cur_app_info.filename().and_then(|p| p
.file_stem()
.and_then(|s| s.to_str().map(|s| s.to_string()))).as_ref())
{
// println!(
// "found active saved app {} at {}",
@ -163,7 +165,9 @@ fn main() {
saved_app_model.items_changed(saved_i, 0, 0);
} else if cached_results
.iter()
.any(|s| Some(&s.app_id) == cur_app_info.id().map(|s| s.to_string()).as_ref())
.any(|s| Some(&s.app_id) == cur_app_info.filename().and_then(|p| p
.file_stem()
.and_then(|s| s.to_str().map(|s| s.to_string()))).as_ref())
{
dock_obj.set_property(
"active",
@ -238,7 +242,9 @@ fn main() {
if let Some((i, _s)) = stack_active
.iter()
.enumerate()
.find(|(_i, s)| Some(&s.0[0].app_id) == cur_app_info.id().map(|s| s.to_string()).as_ref())
.find(|(_i, s)| Some(&s.0[0].app_id) == cur_app_info.filename().and_then(|p| p
.file_stem()
.and_then(|s| s.to_str().map(|s| s.to_string()))).as_ref())
{
// println!("found active saved app {} at {}", s.0[0].name, i);
let active = stack_active.remove(i);
@ -246,7 +252,9 @@ fn main() {
saved_app_model.items_changed(saved_i, 0, 0);
} else if cached_results
.iter()
.any(|s| Some(&s.app_id) == cur_app_info.id().map(|s| s.to_string()).as_ref())
.any(|s| Some(&s.app_id) == cur_app_info.filename().and_then(|p| p
.file_stem()
.and_then(|s| s.to_str().map(|s| s.to_string()))).as_ref())
{
dock_obj.set_property(
"active",

View file

@ -1,10 +1,22 @@
use crate::{
wayland_source::WaylandSource, config::TopLevelFilter, TX, utils::AppListEvent,
};
use crate::config::AppListConfig;
use crate::{config::TopLevelFilter, utils::AppListEvent, wayland_source::WaylandSource, TX};
use calloop::channel::*;
use cosmic_panel_config::CosmicPanelConfig;
use std::{
env, os::unix::net::UnixStream, path::PathBuf,time::Duration,
use cosmic_protocols::{
toplevel_info::v1::client::{
zcosmic_toplevel_handle_v1::{self, ZcosmicToplevelHandleV1},
zcosmic_toplevel_info_v1::{self, ZcosmicToplevelInfoV1},
},
toplevel_management::v1::client::zcosmic_toplevel_manager_v1::{
self, ZcosmicToplevelManagerV1,
},
workspace::v1::client::{
zcosmic_workspace_group_handle_v1::{self, ZcosmicWorkspaceGroupHandleV1},
zcosmic_workspace_handle_v1::{self, ZcosmicWorkspaceHandleV1},
zcosmic_workspace_manager_v1::{self, ZcosmicWorkspaceManagerV1},
},
};
use std::{env, os::unix::net::UnixStream, path::PathBuf, time::Duration};
use wayland_client::{
event_created_child,
protocol::{
@ -13,14 +25,7 @@ use wayland_client::{
},
ConnectError, Proxy,
};
use cosmic_protocols::{workspace::v1::client::{
zcosmic_workspace_manager_v1::{self, ZcosmicWorkspaceManagerV1},
zcosmic_workspace_group_handle_v1::{self, ZcosmicWorkspaceGroupHandleV1},
zcosmic_workspace_handle_v1::{self, ZcosmicWorkspaceHandleV1},
}, toplevel_info::v1::client::{zcosmic_toplevel_info_v1::{ZcosmicToplevelInfoV1, self}, zcosmic_toplevel_handle_v1::{ZcosmicToplevelHandleV1, self}}, toplevel_management::v1::client::zcosmic_toplevel_manager_v1::{self, ZcosmicToplevelManagerV1}};
use wayland_client::{Connection, Dispatch, QueueHandle};
use calloop::channel::*;
use crate::config::AppListConfig;
#[derive(Debug, Clone)]
pub enum ToplevelEvent {
@ -47,8 +52,9 @@ pub fn spawn_toplevels() -> SyncSender<ToplevelEvent> {
{
std::thread::spawn(move || {
let output = match config.filter_top_levels {
Some(TopLevelFilter::ConfiguredOutput) => CosmicPanelConfig::load_from_env()
.ok().map(|c| c.output),
Some(TopLevelFilter::ConfiguredOutput) => {
CosmicPanelConfig::load_from_env().ok().map(|c| c.output)
}
_ => None,
};
let mut event_loop = calloop::EventLoop::<State>::try_new().unwrap();
@ -73,14 +79,14 @@ pub fn spawn_toplevels() -> SyncSender<ToplevelEvent> {
configured_output: output,
expected_output: None,
running: true,
toplevels: vec![]
toplevels: vec![],
};
let loop_handle = event_loop.handle();
loop_handle
.insert_source(workspaces_rx, |e, _, state| match e {
Event::Msg(ToplevelEvent::Activate(_t)) => {
todo!()
}
}
Event::Msg(ToplevelEvent::Close(_t)) => {
todo!()
}
@ -136,12 +142,17 @@ impl State {
.iter()
.filter_map(|g| {
if g.output == self.expected_output {
Some(g.workspaces.iter().map(|w| (w.name.clone(), match &w.states {
x if x.contains(&zcosmic_workspace_handle_v1::State::Active) => 0,
x if x.contains(&zcosmic_workspace_handle_v1::State::Urgent) => 1,
x if x.contains(&zcosmic_workspace_handle_v1::State::Hidden) => 2,
_ => 3,
})))
Some(g.workspaces.iter().map(|w| {
(
w.name.clone(),
match &w.states {
x if x.contains(&zcosmic_workspace_handle_v1::State::Active) => 0,
x if x.contains(&zcosmic_workspace_handle_v1::State::Urgent) => 1,
x if x.contains(&zcosmic_workspace_handle_v1::State::Hidden) => 2,
_ => 3,
},
)
}))
} else {
None
}
@ -193,34 +204,19 @@ impl Dispatch<wl_registry::WlRegistry, ()> for State {
match &interface[..] {
"zcosmic_toplevel_info_v1" => {
let ti = registry
.bind::<ZcosmicToplevelInfoV1, _, _>(
name,
1,
qh,
(),
)
.bind::<ZcosmicToplevelInfoV1, _, _>(name, 1, qh, ())
.unwrap();
state.toplevel_info = Some(ti);
}
"zcosmic_toplevel_manager_v1" => {
let tm = registry
.bind::<ZcosmicToplevelManagerV1, _, _>(
name,
1,
qh,
(),
)
.bind::<ZcosmicToplevelManagerV1, _, _>(name, 1, qh, ())
.unwrap();
state.toplevel_manager = Some(tm);
}
"zcosmic_workspace_manager_v1" => {
let workspace_manager = registry
.bind::<ZcosmicWorkspaceManagerV1, _, _>(
name,
1,
qh,
(),
)
.bind::<ZcosmicWorkspaceManagerV1, _, _>(name, 1, qh, ())
.unwrap();
state.workspace_manager = Some(workspace_manager);
}
@ -245,12 +241,19 @@ impl Dispatch<ZcosmicToplevelInfoV1, ()> for State {
dbg!(&event);
match event {
zcosmic_toplevel_info_v1::Event::Toplevel { toplevel } => {
state.toplevels.push(Toplevel { name: "".into(), app_id: "".into(), toplevel_handle: toplevel, states: vec![], output: None, workspace: None });
},
state.toplevels.push(Toplevel {
name: "".into(),
app_id: "".into(),
toplevel_handle: toplevel,
states: vec![],
output: None,
workspace: None,
});
}
zcosmic_toplevel_info_v1::Event::Finished => {
todo!()
},
_ => {},
}
_ => {}
}
}
@ -259,7 +262,6 @@ impl Dispatch<ZcosmicToplevelInfoV1, ()> for State {
]);
}
impl Dispatch<ZcosmicToplevelManagerV1, ()> for State {
fn event(
_: &mut Self,
@ -272,8 +274,8 @@ impl Dispatch<ZcosmicToplevelManagerV1, ()> for State {
match event {
zcosmic_toplevel_manager_v1::Event::Capabilities { .. } => {
// TODO capabilities affect what is shown to user in applet
},
_ => {},
}
_ => {}
}
}
}
@ -292,27 +294,33 @@ impl Dispatch<ZcosmicToplevelHandleV1, ()> for State {
if let Some(i) = state.toplevels.iter().position(|t| &t.toplevel_handle == p) {
state.toplevels.remove(i);
}
},
}
zcosmic_toplevel_handle_v1::Event::Done => {
let to_send = match state.config.filter_top_levels {
Some(TopLevelFilter::ActiveWorkspace) => {
state.toplevels.iter_mut().find(|t| {
if &t.toplevel_handle == p {
state
Some(TopLevelFilter::ActiveWorkspace) => state.toplevels.iter_mut().find(|t| {
if &t.toplevel_handle == p {
state
.workspace_groups
.iter()
.find(|g| {
g.workspaces
.iter()
.find(|w| w.states.contains(&zcosmic_workspace_handle_v1::State::Active) && Some(&w.workspace_handle) == t.workspace.as_ref()).is_some()
}).is_some()
} else {
false
}
})
},
Some(TopLevelFilter::ConfiguredOutput) =>
state.toplevels.iter_mut().find(|t| &t.toplevel_handle == p && state.expected_output == t.output),
.find(|w| {
w.states.contains(
&zcosmic_workspace_handle_v1::State::Active,
) && Some(&w.workspace_handle) == t.workspace.as_ref()
})
.is_some()
})
.is_some()
} else {
false
}
}),
Some(TopLevelFilter::ConfiguredOutput) => state
.toplevels
.iter_mut()
.find(|t| &t.toplevel_handle == p && state.expected_output == t.output),
_ => state.toplevels.iter_mut().find(|t| &t.toplevel_handle == p),
};
@ -321,49 +329,63 @@ impl Dispatch<ZcosmicToplevelHandleV1, ()> for State {
let _ = tx.send(AppListEvent::Add(toplevel));
}
},
}
zcosmic_toplevel_handle_v1::Event::Title { title } => {
if let Some(i) = state.toplevels.iter_mut().find(|t| &t.toplevel_handle == p) {
i.name = title;
}
},
}
zcosmic_toplevel_handle_v1::Event::AppId { app_id } => {
if let Some(i) = state.toplevels.iter_mut().find(|t| &t.toplevel_handle == p) {
i.app_id = app_id;
}
},
}
zcosmic_toplevel_handle_v1::Event::OutputEnter { output } => {
if let Some(i) = state.toplevels.iter_mut().find(|t| &t.toplevel_handle == p) {
i.output.replace(output);
}
},
}
zcosmic_toplevel_handle_v1::Event::OutputLeave { output } => {
if let Some(i) = state.toplevels.iter_mut().find(|t| &t.toplevel_handle == p && t.output.as_ref() == Some(&output)) {
if let Some(i) = state
.toplevels
.iter_mut()
.find(|t| &t.toplevel_handle == p && t.output.as_ref() == Some(&output))
{
i.output.take();
}
},
}
zcosmic_toplevel_handle_v1::Event::WorkspaceEnter { workspace } => {
if let Some(i) = state.toplevels.iter_mut().find(|t| &t.toplevel_handle == p) {
i.workspace.replace(workspace);
}
},
}
zcosmic_toplevel_handle_v1::Event::WorkspaceLeave { workspace } => {
if let Some(i) = state.toplevels.iter_mut().find(|t| &t.toplevel_handle == p && t.workspace.as_ref() == Some(&workspace)) {
if let Some(i) = state
.toplevels
.iter_mut()
.find(|t| &t.toplevel_handle == p && t.workspace.as_ref() == Some(&workspace))
{
i.workspace.take();
}
},
}
zcosmic_toplevel_handle_v1::Event::State { state: t_state } => {
if let Some(i) = state.toplevels.iter_mut().find(|t| &t.toplevel_handle == p) {
i.states = t_state.chunks(4).map(|chunk| zcosmic_toplevel_handle_v1::State::try_from(u32::from_ne_bytes(chunk.try_into().unwrap())).unwrap()).collect();
i.states = t_state
.chunks(4)
.map(|chunk| {
zcosmic_toplevel_handle_v1::State::try_from(u32::from_ne_bytes(
chunk.try_into().unwrap(),
))
.unwrap()
})
.collect();
}
},
}
_ => todo!(),
}
}
}
impl Dispatch<ZcosmicWorkspaceManagerV1, ()> for State {
fn event(
state: &mut Self,
@ -384,7 +406,9 @@ impl Dispatch<ZcosmicWorkspaceManagerV1, ()> for State {
zcosmic_workspace_manager_v1::Event::Done => {
for group in &mut state.workspace_groups {
group.workspaces.sort_by(|w1, w2| {
w1.coordinates.iter().zip(w2.coordinates.iter())
w1.coordinates
.iter()
.zip(w2.coordinates.iter())
.skip_while(|(coord1, coord2)| coord1 == coord2)
.next()
.map(|(coord1, coord2)| coord1.cmp(coord2))
@ -488,19 +512,31 @@ impl Dispatch<ZcosmicWorkspaceHandleV1, ()> for State {
.find(|w| &w.workspace_handle == workspace)
}) {
// wayland is host byte order
w.coordinates = coordinates.chunks(4).map(|chunk| u32::from_ne_bytes(chunk.try_into().unwrap())).collect();
w.coordinates = coordinates
.chunks(4)
.map(|chunk| u32::from_ne_bytes(chunk.try_into().unwrap()))
.collect();
}
}
zcosmic_workspace_handle_v1::Event::State { state: workspace_state } => {
zcosmic_workspace_handle_v1::Event::State {
state: workspace_state,
} => {
if let Some(w) = state.workspace_groups.iter_mut().find_map(|g| {
g.workspaces
.iter_mut()
.find(|w| &w.workspace_handle == workspace)
}) {
// wayland is host byte order
w.states = workspace_state.chunks(4).map(|chunk| zcosmic_workspace_handle_v1::State::try_from(u32::from_ne_bytes(chunk.try_into().unwrap())).unwrap()).collect();
w.states = workspace_state
.chunks(4)
.map(|chunk| {
zcosmic_workspace_handle_v1::State::try_from(u32::from_ne_bytes(
chunk.try_into().unwrap(),
))
.unwrap()
})
.collect();
// TODO if workspace active status changes while configured to only show active workspace, clear the list
}
}
zcosmic_workspace_handle_v1::Event::Remove => {

View file

@ -51,8 +51,6 @@ fn main() {
gtk4::STYLE_PROVIDER_PRIORITY_APPLICATION,
);
let current_graphics = RT
.block_on(get_current_graphics())
.expect("failed to connect to system76-power");

View file

@ -2,7 +2,13 @@ use crate::{
utils::{Activate, WorkspaceEvent},
wayland_source::WaylandSource,
};
use calloop::channel::*;
use cosmic_panel_config::CosmicPanelConfig;
use cosmic_protocols::workspace::v1::client::{
zcosmic_workspace_group_handle_v1::{self, ZcosmicWorkspaceGroupHandleV1},
zcosmic_workspace_handle_v1::{self, ZcosmicWorkspaceHandleV1},
zcosmic_workspace_manager_v1::{self, ZcosmicWorkspaceManagerV1},
};
use gtk4::glib;
use std::{
collections::HashMap, env, hash::Hash, mem, os::unix::net::UnixStream, path::PathBuf,
@ -18,13 +24,7 @@ use wayland_client::{
},
ConnectError, Proxy,
};
use cosmic_protocols::workspace::v1::client::{
zcosmic_workspace_manager_v1::{self, ZcosmicWorkspaceManagerV1},
zcosmic_workspace_group_handle_v1::{self, ZcosmicWorkspaceGroupHandleV1},
zcosmic_workspace_handle_v1::{self, ZcosmicWorkspaceHandleV1},
};
use wayland_client::{Connection, Dispatch, QueueHandle};
use calloop::channel::*;
pub fn spawn_workspaces(tx: glib::Sender<State>) -> SyncSender<WorkspaceEvent> {
let (workspaces_tx, workspaces_rx) = calloop::channel::sync_channel(100);
@ -80,19 +80,18 @@ pub fn spawn_workspaces(tx: glib::Sender<State>) -> SyncSender<WorkspaceEvent> {
}
}
Event::Msg(WorkspaceEvent::Scroll(v)) => {
if let Some((w_g, w_i)) = state
.workspace_groups
.iter()
.find_map(|g| {
if g.output != state.expected_output {
return None;
}
g.workspaces
.iter()
.position(|w| w.states.contains(&zcosmic_workspace_handle_v1::State::Active))
.map(|w_i| (g, w_i))
})
{
if let Some((w_g, w_i)) = state.workspace_groups.iter().find_map(|g| {
if g.output != state.expected_output {
return None;
}
g.workspaces
.iter()
.position(|w| {
w.states
.contains(&zcosmic_workspace_handle_v1::State::Active)
})
.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 {
@ -154,12 +153,17 @@ impl State {
.iter()
.filter_map(|g| {
if g.output == self.expected_output {
Some(g.workspaces.iter().map(|w| (w.name.clone(), match &w.states {
x if x.contains(&zcosmic_workspace_handle_v1::State::Active) => 0,
x if x.contains(&zcosmic_workspace_handle_v1::State::Urgent) => 1,
x if x.contains(&zcosmic_workspace_handle_v1::State::Hidden) => 2,
_ => 3,
})))
Some(g.workspaces.iter().map(|w| {
(
w.name.clone(),
match &w.states {
x if x.contains(&zcosmic_workspace_handle_v1::State::Active) => 0,
x if x.contains(&zcosmic_workspace_handle_v1::State::Urgent) => 1,
x if x.contains(&zcosmic_workspace_handle_v1::State::Hidden) => 2,
_ => 3,
},
)
}))
} else {
None
}
@ -201,12 +205,7 @@ impl Dispatch<wl_registry::WlRegistry, ()> for State {
match &interface[..] {
"zcosmic_workspace_manager_v1" => {
let workspace_manager = registry
.bind::<ZcosmicWorkspaceManagerV1, _, _>(
name,
1,
qh,
(),
)
.bind::<ZcosmicWorkspaceManagerV1, _, _>(name, 1, qh, ())
.unwrap();
state.workspace_manager = Some(workspace_manager);
}
@ -239,7 +238,9 @@ impl Dispatch<ZcosmicWorkspaceManagerV1, ()> for State {
zcosmic_workspace_manager_v1::Event::Done => {
for group in &mut state.workspace_groups {
group.workspaces.sort_by(|w1, w2| {
w1.coordinates.iter().zip(w2.coordinates.iter())
w1.coordinates
.iter()
.zip(w2.coordinates.iter())
.skip_while(|(coord1, coord2)| coord1 == coord2)
.next()
.map(|(coord1, coord2)| coord1.cmp(coord2))
@ -344,17 +345,30 @@ impl Dispatch<ZcosmicWorkspaceHandleV1, ()> for State {
.find(|w| &w.workspace_handle == workspace)
}) {
// wayland is host byte order
w.coordinates = coordinates.chunks(4).map(|chunk| u32::from_ne_bytes(chunk.try_into().unwrap())).collect();
w.coordinates = coordinates
.chunks(4)
.map(|chunk| u32::from_ne_bytes(chunk.try_into().unwrap()))
.collect();
}
}
zcosmic_workspace_handle_v1::Event::State { state: workspace_state } => {
zcosmic_workspace_handle_v1::Event::State {
state: workspace_state,
} => {
if let Some(w) = state.workspace_groups.iter_mut().find_map(|g| {
g.workspaces
.iter_mut()
.find(|w| &w.workspace_handle == workspace)
}) {
// wayland is host byte order
w.states = workspace_state.chunks(4).map(|chunk| zcosmic_workspace_handle_v1::State::try_from(u32::from_ne_bytes(chunk.try_into().unwrap())).unwrap()).collect();
w.states = workspace_state
.chunks(4)
.map(|chunk| {
zcosmic_workspace_handle_v1::State::try_from(u32::from_ne_bytes(
chunk.try_into().unwrap(),
))
.unwrap()
})
.collect();
}
}
zcosmic_workspace_handle_v1::Event::Remove => {