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 qh = event_queue.handle();
|
||||||
|
|
||||||
let mut state = AppState {
|
let mut state = AppState {
|
||||||
|
outputs: HashMap::new(),
|
||||||
workspaces: HashMap::new(),
|
workspaces: HashMap::new(),
|
||||||
workspace_groups: HashMap::new(),
|
workspace_groups: HashMap::new(),
|
||||||
workspace_handles: HashMap::new(),
|
workspace_handles: HashMap::new(),
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@ use crate::{frb_generated::StreamSink, workspace_api::Workspace};
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
|
|
||||||
use wayland_client::{
|
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::{
|
use wayland_protocols::ext::workspace::v1::client::{
|
||||||
|
|
@ -14,38 +14,49 @@ pub struct WorkspaceHandles {
|
||||||
pub manager_handle: ext_workspace_manager_v1::ExtWorkspaceManagerV1,
|
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 struct AppState {
|
||||||
|
pub outputs: HashMap<u32, Output>,
|
||||||
pub workspaces: HashMap<u32, Workspace>,
|
pub workspaces: HashMap<u32, Workspace>,
|
||||||
pub workspace_groups: HashMap<u32, u32>,
|
pub workspace_groups: HashMap<u32, WorkspaceGroup>,
|
||||||
pub workspace_handles: HashMap<u32, WorkspaceHandles>,
|
pub workspace_handles: HashMap<u32, WorkspaceHandles>,
|
||||||
pub sink: StreamSink<Vec<Vec<Workspace>>>,
|
pub sink: StreamSink<Vec<Vec<Workspace>>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl AppState {
|
impl AppState {
|
||||||
fn emit(&self) {
|
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 {
|
groups.sort_by_key(|group| {
|
||||||
if let Some(group_id) = self.workspace_groups.get(ws_id) {
|
group.output_id.as_ref().and_then(|o| {
|
||||||
groups
|
self.outputs.get(o).map(|info| info.coords.0)
|
||||||
.entry(group_id.clone())
|
})
|
||||||
.or_insert_with(Vec::new)
|
});
|
||||||
.push((ws_id, ws));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
let mut grouped: Vec<(u32, Vec<(&u32, &Workspace)>)> = groups.into_iter().collect();
|
let result: Vec<Vec<Workspace>> = groups
|
||||||
|
.into_iter()
|
||||||
|
.map(|group| {
|
||||||
|
let mut workspaces: Vec<Workspace> = group
|
||||||
|
.children
|
||||||
|
.iter()
|
||||||
|
.filter_map(|id| self.workspaces.get(id))
|
||||||
|
.cloned()
|
||||||
|
.collect();
|
||||||
|
|
||||||
grouped.sort_by_key(|(group_id, _)| group_id.clone());
|
workspaces.sort_by_key(|ws|
|
||||||
|
ws.coords.as_ref().map(|coords| coords.0)
|
||||||
let result = grouped
|
);
|
||||||
.into_iter()
|
workspaces
|
||||||
.map(|(_, mut entries)| {
|
})
|
||||||
entries.sort_by_key(|(_, value)| value.coords);
|
.collect();
|
||||||
|
|
||||||
entries.into_iter().map(|(_, ws)| ws.clone()).collect()
|
|
||||||
})
|
|
||||||
.collect();
|
|
||||||
|
|
||||||
self.sink.add(result).expect("Updating stream failed");
|
self.sink.add(result).expect("Updating stream failed");
|
||||||
}
|
}
|
||||||
|
|
@ -66,14 +77,27 @@ impl Dispatch<wl_registry::WlRegistry, ()> for AppState {
|
||||||
version,
|
version,
|
||||||
} = event
|
} = event
|
||||||
{
|
{
|
||||||
if interface == "ext_workspace_manager_v1" {
|
match interface.as_str() {
|
||||||
registry.bind::<ext_workspace_manager_v1::ExtWorkspaceManagerV1, (), AppState>(
|
"ext_workspace_manager_v1" => {
|
||||||
name,
|
registry.bind::<ext_workspace_manager_v1::ExtWorkspaceManagerV1, (), AppState>(
|
||||||
version,
|
name,
|
||||||
qh,
|
version,
|
||||||
(),
|
qh,
|
||||||
);
|
(),
|
||||||
}
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
"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 } => {
|
ext_workspace_group_handle_v1::Event::WorkspaceEnter { workspace } => {
|
||||||
state
|
state
|
||||||
.workspace_groups
|
.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();
|
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