wip: use desktop file stem for app id
This commit is contained in:
parent
223c7855cf
commit
adc02df64f
12 changed files with 209 additions and 146 deletions
4
Cargo.lock
generated
4
Cargo.lock
generated
|
|
@ -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",
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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]
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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`.")
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
|
|
@ -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",
|
||||
|
|
|
|||
|
|
@ -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 => {
|
||||
|
|
|
|||
|
|
@ -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");
|
||||
|
|
|
|||
|
|
@ -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 => {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue