1
0
Fork 0
forked from wry/wry

config: split workspace handling

This commit is contained in:
kossLAN 2026-05-29 19:08:40 -04:00
parent 814ba579bf
commit b08a8b63c9
No known key found for this signature in database
2 changed files with 187 additions and 169 deletions

View file

@ -93,6 +93,7 @@ mod matchers;
mod outputs;
mod theme;
mod windows;
mod workspaces;
pub(super) struct ConfigProxyHandler {
pub client_data: Cell<*const u8>,
@ -219,20 +220,6 @@ impl ConfigProxyHandler {
self.next_id.fetch_add(1)
}
fn get_workspace_by_name(&self, name: &String) -> Workspace {
let id = match self.workspaces_by_name.get(name) {
None => {
let id = self.workspace_ids.fetch_add(1);
let name = Rc::new(name.clone());
self.workspaces_by_name.set(name.clone(), id);
self.workspaces_by_id.set(id, name);
id
}
Some(id) => id,
};
Workspace(id)
}
fn handle_log_request(
&self,
level: ConfigLogLevel,
@ -447,14 +434,6 @@ impl ConfigProxyHandler {
self.respond(Response::GetConfigDir { dir });
}
fn handle_get_workspaces(&self) {
let mut workspaces = vec![];
for ws in self.state.workspaces.lock().values() {
workspaces.push(self.get_workspace_by_name(&ws.name));
}
self.respond(Response::GetWorkspaces { workspaces });
}
fn handle_program_timer(
&self,
timer: JayTimer,
@ -567,24 +546,6 @@ impl ConfigProxyHandler {
Ok(())
}
fn get_workspace(&self, ws: Workspace) -> Result<Rc<String>, CphError> {
match self.workspaces_by_id.get(&ws.0) {
Some(ws) => Ok(ws),
_ => Err(CphError::WorkspaceDoesNotExist(ws)),
}
}
fn get_existing_workspace(&self, ws: Workspace) -> Result<Option<Rc<WorkspaceNode>>, CphError> {
self.get_workspace(ws).map(|name| {
self.state
.workspaces
.lock()
.values()
.find(|ws| ws.name.as_str() == name.as_str())
.cloned()
})
}
fn get_device_handler_data(
&self,
device: InputDevice,
@ -667,34 +628,6 @@ impl ConfigProxyHandler {
self.state.set_ei_socket_enabled(enabled);
}
fn handle_get_workspace(&self, name: &str) {
self.respond(Response::GetWorkspace {
workspace: self.get_workspace_by_name(&name.to_owned()),
});
}
fn handle_get_workspace_capture(&self, workspace: Workspace) -> Result<(), CphError> {
let ws = self.get_existing_workspace(workspace)?;
let capture = match ws {
Some(ws) => ws.may_capture.get(),
None => self.state.default_workspace_capture.get(),
};
self.respond(Response::GetWorkspaceCapture { capture });
Ok(())
}
fn handle_set_workspace_capture(
&self,
workspace: Workspace,
capture: bool,
) -> Result<(), CphError> {
if let Some(ws) = self.get_existing_workspace(workspace)? {
ws.may_capture.set(capture);
ws.update_has_captures();
}
Ok(())
}
fn handle_set_gfx_api(&self, device: Option<DrmDevice>, api: GfxApi) -> Result<(), CphError> {
let Ok(api) = api.try_into() else {
return Err(CphError::UnknownGfxApi(api));
@ -776,16 +709,6 @@ impl ConfigProxyHandler {
Ok(())
}
fn handle_get_default_workspace_capture(&self) {
self.respond(Response::GetDefaultWorkspaceCapture {
capture: self.state.default_workspace_capture.get(),
});
}
fn handle_set_default_workspace_capture(&self, capture: bool) {
self.state.default_workspace_capture.set(capture);
}
fn handle_set_double_click_interval_usec(&self, usec: u64) {
self.state.double_click_interval_usec.set(usec);
}
@ -794,93 +717,6 @@ impl ConfigProxyHandler {
self.state.double_click_distance.set(dist);
}
fn handle_get_seat_cursor_workspace(&self, seat: Seat) -> Result<(), CphError> {
let seat = self.get_seat(seat)?;
let output = seat.get_cursor_output();
let mut workspace = Workspace(0);
if !output.is_dummy
&& let Some(ws) = output.workspace.get()
{
workspace = self.get_workspace_by_name(&ws.name);
}
self.respond(Response::GetSeatCursorWorkspace { workspace });
Ok(())
}
fn handle_get_seat_keyboard_workspace(&self, seat: Seat) -> Result<(), CphError> {
let seat = self.get_seat(seat)?;
let mut workspace = Workspace(0);
if let Some(output) = seat.get_keyboard_output()
&& !output.is_dummy
&& let Some(ws) = output.workspace.get()
{
workspace = self.get_workspace_by_name(&ws.name);
}
self.respond(Response::GetSeatKeyboardWorkspace { workspace });
Ok(())
}
fn handle_show_workspace(
&self,
seat: Seat,
ws: Workspace,
output: Option<Connector>,
) -> Result<(), CphError> {
let seat = self.get_seat(seat)?;
let name = self.get_workspace(ws)?;
let output = output.map(|o| self.get_output_node(o)).transpose()?;
self.state.show_workspace(&seat, &name, output);
Ok(())
}
fn handle_set_seat_workspace(&self, seat: Seat, ws: Workspace) -> Result<(), CphError> {
let seat = self.get_seat(seat)?;
let name = self.get_workspace(ws)?;
let output = seat.get_fallback_output();
let workspace = match output.find_workspace(name.deref()) {
Some(ws) => ws,
_ => output.create_workspace(name.deref()),
};
seat.set_workspace(&workspace);
Ok(())
}
fn handle_set_window_workspace(&self, window: Window, ws: Workspace) -> Result<(), CphError> {
let window = self.get_window(window)?;
let name = self.get_workspace(ws)?;
let Some(output) = window.node_output() else {
return Ok(());
};
let workspace = match output.find_workspace(name.deref()) {
Some(ws) => ws,
_ => output.create_workspace(name.deref()),
};
toplevel_set_workspace(&self.state, window, &workspace);
Ok(())
}
fn handle_move_to_output(
&self,
workspace: WorkspaceSource,
connector: Connector,
) -> Result<(), CphError> {
let output = self.get_output_node(connector)?;
let ws = match workspace {
WorkspaceSource::Explicit(ws) => match self.get_existing_workspace(ws)? {
Some(ws) => ws,
_ => return Ok(()),
},
WorkspaceSource::Seat(s) => {
match self.get_seat(s)?.get_fallback_output().workspace.get() {
Some(ws) => ws,
_ => return Ok(()),
}
}
};
self.state.move_ws_to_output(&ws, &output);
Ok(())
}
fn handle_set_idle(&self, timeout: Duration) {
self.state.idle.set_timeout(&self.state, timeout);
}
@ -931,10 +767,6 @@ impl ConfigProxyHandler {
Ok(())
}
fn handle_set_workspace_display_order(&self, order: WorkspaceDisplayOrder) {
self.state.set_workspace_display_order(order.into());
}
fn handle_get_seat_float_pinned(&self, seat: Seat) -> Result<(), CphError> {
let seat = self.get_seat(seat)?;
self.respond(Response::GetFloatPinned {

View file

@ -0,0 +1,186 @@
use super::*;
impl ConfigProxyHandler {
pub(super) fn get_workspace_by_name(&self, name: &String) -> Workspace {
let id = match self.workspaces_by_name.get(name) {
None => {
let id = self.workspace_ids.fetch_add(1);
let name = Rc::new(name.clone());
self.workspaces_by_name.set(name.clone(), id);
self.workspaces_by_id.set(id, name);
id
}
Some(id) => id,
};
Workspace(id)
}
pub(super) fn get_workspace(&self, ws: Workspace) -> Result<Rc<String>, CphError> {
match self.workspaces_by_id.get(&ws.0) {
Some(ws) => Ok(ws),
_ => Err(CphError::WorkspaceDoesNotExist(ws)),
}
}
pub(super) fn get_existing_workspace(
&self,
ws: Workspace,
) -> Result<Option<Rc<WorkspaceNode>>, CphError> {
self.get_workspace(ws).map(|name| {
self.state
.workspaces
.lock()
.values()
.find(|ws| ws.name.as_str() == name.as_str())
.cloned()
})
}
pub(super) fn handle_get_workspaces(&self) {
let mut workspaces = vec![];
for ws in self.state.workspaces.lock().values() {
workspaces.push(self.get_workspace_by_name(&ws.name));
}
self.respond(Response::GetWorkspaces { workspaces });
}
pub(super) fn handle_get_workspace(&self, name: &str) {
self.respond(Response::GetWorkspace {
workspace: self.get_workspace_by_name(&name.to_owned()),
});
}
pub(super) fn handle_get_workspace_capture(
&self,
workspace: Workspace,
) -> Result<(), CphError> {
let ws = self.get_existing_workspace(workspace)?;
let capture = match ws {
Some(ws) => ws.may_capture.get(),
None => self.state.default_workspace_capture.get(),
};
self.respond(Response::GetWorkspaceCapture { capture });
Ok(())
}
pub(super) fn handle_set_workspace_capture(
&self,
workspace: Workspace,
capture: bool,
) -> Result<(), CphError> {
if let Some(ws) = self.get_existing_workspace(workspace)? {
ws.may_capture.set(capture);
ws.update_has_captures();
}
Ok(())
}
pub(super) fn handle_get_default_workspace_capture(&self) {
self.respond(Response::GetDefaultWorkspaceCapture {
capture: self.state.default_workspace_capture.get(),
});
}
pub(super) fn handle_set_default_workspace_capture(&self, capture: bool) {
self.state.default_workspace_capture.set(capture);
}
pub(super) fn handle_get_seat_cursor_workspace(&self, seat: Seat) -> Result<(), CphError> {
let seat = self.get_seat(seat)?;
let output = seat.get_cursor_output();
let mut workspace = Workspace(0);
if !output.is_dummy
&& let Some(ws) = output.workspace.get()
{
workspace = self.get_workspace_by_name(&ws.name);
}
self.respond(Response::GetSeatCursorWorkspace { workspace });
Ok(())
}
pub(super) fn handle_get_seat_keyboard_workspace(&self, seat: Seat) -> Result<(), CphError> {
let seat = self.get_seat(seat)?;
let mut workspace = Workspace(0);
if let Some(output) = seat.get_keyboard_output()
&& !output.is_dummy
&& let Some(ws) = output.workspace.get()
{
workspace = self.get_workspace_by_name(&ws.name);
}
self.respond(Response::GetSeatKeyboardWorkspace { workspace });
Ok(())
}
pub(super) fn handle_show_workspace(
&self,
seat: Seat,
ws: Workspace,
output: Option<Connector>,
) -> Result<(), CphError> {
let seat = self.get_seat(seat)?;
let name = self.get_workspace(ws)?;
let output = output.map(|o| self.get_output_node(o)).transpose()?;
self.state.show_workspace(&seat, &name, output);
Ok(())
}
pub(super) fn handle_set_seat_workspace(
&self,
seat: Seat,
ws: Workspace,
) -> Result<(), CphError> {
let seat = self.get_seat(seat)?;
let name = self.get_workspace(ws)?;
let output = seat.get_fallback_output();
let workspace = match output.find_workspace(name.deref()) {
Some(ws) => ws,
_ => output.create_workspace(name.deref()),
};
seat.set_workspace(&workspace);
Ok(())
}
pub(super) fn handle_set_window_workspace(
&self,
window: Window,
ws: Workspace,
) -> Result<(), CphError> {
let window = self.get_window(window)?;
let name = self.get_workspace(ws)?;
let Some(output) = window.node_output() else {
return Ok(());
};
let workspace = match output.find_workspace(name.deref()) {
Some(ws) => ws,
_ => output.create_workspace(name.deref()),
};
toplevel_set_workspace(&self.state, window, &workspace);
Ok(())
}
pub(super) fn handle_move_to_output(
&self,
workspace: WorkspaceSource,
connector: Connector,
) -> Result<(), CphError> {
let output = self.get_output_node(connector)?;
let ws = match workspace {
WorkspaceSource::Explicit(ws) => match self.get_existing_workspace(ws)? {
Some(ws) => ws,
_ => return Ok(()),
},
WorkspaceSource::Seat(s) => {
match self.get_seat(s)?.get_fallback_output().workspace.get() {
Some(ws) => ws,
_ => return Ok(()),
}
}
};
self.state.move_ws_to_output(&ws, &output);
Ok(())
}
pub(super) fn handle_set_workspace_display_order(&self, order: WorkspaceDisplayOrder) {
self.state.set_workspace_display_order(order.into());
}
}