sort by output
This commit is contained in:
parent
5ba7b66d93
commit
bb9fdfa83d
2 changed files with 97 additions and 31 deletions
|
|
@ -36,6 +36,7 @@ pub fn listen_workspaces(sink: StreamSink<Vec<Vec<Workspace>>>) -> Result<()> {
|
|||
let qh = event_queue.handle();
|
||||
|
||||
let mut state = AppState {
|
||||
outputs: HashMap::new(),
|
||||
workspaces: HashMap::new(),
|
||||
workspace_groups: HashMap::new(),
|
||||
workspace_handles: HashMap::new(),
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ use crate::{frb_generated::StreamSink, workspace_api::Workspace};
|
|||
use std::collections::HashMap;
|
||||
|
||||
use wayland_client::{
|
||||
self, event_created_child, protocol::wl_registry, Connection, Dispatch, Proxy, QueueHandle,
|
||||
self, event_created_child, protocol::{wl_registry, wl_output}, Connection, Dispatch, Proxy, QueueHandle,
|
||||
};
|
||||
|
||||
use wayland_protocols::ext::workspace::v1::client::{
|
||||
|
|
@ -14,36 +14,47 @@ pub struct WorkspaceHandles {
|
|||
pub manager_handle: ext_workspace_manager_v1::ExtWorkspaceManagerV1,
|
||||
}
|
||||
|
||||
pub struct Output {
|
||||
pub coords: (i32, i32),
|
||||
}
|
||||
|
||||
pub struct WorkspaceGroup {
|
||||
pub output_id: Option<u32>,
|
||||
pub children: Vec<u32>,
|
||||
}
|
||||
|
||||
pub struct AppState {
|
||||
pub outputs: HashMap<u32, Output>,
|
||||
pub workspaces: HashMap<u32, Workspace>,
|
||||
pub workspace_groups: HashMap<u32, u32>,
|
||||
pub workspace_groups: HashMap<u32, WorkspaceGroup>,
|
||||
pub workspace_handles: HashMap<u32, WorkspaceHandles>,
|
||||
pub sink: StreamSink<Vec<Vec<Workspace>>>,
|
||||
}
|
||||
|
||||
impl AppState {
|
||||
fn emit(&self) {
|
||||
let mut groups: HashMap<u32, Vec<(&u32, &Workspace)>> = HashMap::new();
|
||||
let mut groups: Vec<_> = self.workspace_groups.values().collect();
|
||||
|
||||
for (ws_id, ws) in &self.workspaces {
|
||||
if let Some(group_id) = self.workspace_groups.get(ws_id) {
|
||||
groups
|
||||
.entry(group_id.clone())
|
||||
.or_insert_with(Vec::new)
|
||||
.push((ws_id, ws));
|
||||
}
|
||||
}
|
||||
groups.sort_by_key(|group| {
|
||||
group.output_id.as_ref().and_then(|o| {
|
||||
self.outputs.get(o).map(|info| info.coords.0)
|
||||
})
|
||||
});
|
||||
|
||||
let mut grouped: Vec<(u32, Vec<(&u32, &Workspace)>)> = groups.into_iter().collect();
|
||||
|
||||
grouped.sort_by_key(|(group_id, _)| group_id.clone());
|
||||
|
||||
let result = grouped
|
||||
let result: Vec<Vec<Workspace>> = groups
|
||||
.into_iter()
|
||||
.map(|(_, mut entries)| {
|
||||
entries.sort_by_key(|(_, value)| value.coords);
|
||||
.map(|group| {
|
||||
let mut workspaces: Vec<Workspace> = group
|
||||
.children
|
||||
.iter()
|
||||
.filter_map(|id| self.workspaces.get(id))
|
||||
.cloned()
|
||||
.collect();
|
||||
|
||||
entries.into_iter().map(|(_, ws)| ws.clone()).collect()
|
||||
workspaces.sort_by_key(|ws|
|
||||
ws.coords.as_ref().map(|coords| coords.0)
|
||||
);
|
||||
workspaces
|
||||
})
|
||||
.collect();
|
||||
|
||||
|
|
@ -66,7 +77,8 @@ impl Dispatch<wl_registry::WlRegistry, ()> for AppState {
|
|||
version,
|
||||
} = event
|
||||
{
|
||||
if interface == "ext_workspace_manager_v1" {
|
||||
match interface.as_str() {
|
||||
"ext_workspace_manager_v1" => {
|
||||
registry.bind::<ext_workspace_manager_v1::ExtWorkspaceManagerV1, (), AppState>(
|
||||
name,
|
||||
version,
|
||||
|
|
@ -74,6 +86,18 @@ impl Dispatch<wl_registry::WlRegistry, ()> for AppState {
|
|||
(),
|
||||
);
|
||||
}
|
||||
|
||||
"wl_output" => {
|
||||
registry.bind::<wl_output::WlOutput, (), AppState>(
|
||||
name,
|
||||
version,
|
||||
qh,
|
||||
(),
|
||||
);
|
||||
}
|
||||
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -192,7 +216,25 @@ impl Dispatch<ext_workspace_group_handle_v1::ExtWorkspaceGroupHandleV1, ()> for
|
|||
ext_workspace_group_handle_v1::Event::WorkspaceEnter { workspace } => {
|
||||
state
|
||||
.workspace_groups
|
||||
.insert(workspace.id().protocol_id(), group_id.protocol_id());
|
||||
.entry(group_id.protocol_id())
|
||||
.or_insert_with(|| WorkspaceGroup {
|
||||
output_id: None,
|
||||
children: Vec::new(),
|
||||
})
|
||||
.children
|
||||
.push(workspace.id().protocol_id());
|
||||
state.emit();
|
||||
}
|
||||
|
||||
ext_workspace_group_handle_v1::Event::OutputEnter { output } => {
|
||||
state
|
||||
.workspace_groups
|
||||
.entry(group_id.protocol_id())
|
||||
.or_insert_with(|| WorkspaceGroup {
|
||||
output_id: None,
|
||||
children: Vec::new(),
|
||||
})
|
||||
.output_id = Some(output.id().protocol_id());
|
||||
state.emit();
|
||||
}
|
||||
|
||||
|
|
@ -205,3 +247,26 @@ impl Dispatch<ext_workspace_group_handle_v1::ExtWorkspaceGroupHandleV1, ()> for
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Dispatch<wl_output::WlOutput, ()> for AppState {
|
||||
fn event(
|
||||
state: &mut Self,
|
||||
proxy: &wl_output::WlOutput,
|
||||
event: wl_output::Event,
|
||||
_data: &(),
|
||||
_conn: &Connection,
|
||||
_qh: &QueueHandle<Self>,
|
||||
) {
|
||||
match event {
|
||||
wl_output::Event::Geometry {
|
||||
x,
|
||||
y,
|
||||
..
|
||||
} => {
|
||||
state.outputs.insert(proxy.id().protocol_id(), Output { coords: ( x, y ) });
|
||||
state.emit();
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue