1
0
Fork 0
forked from wry/wry

feat(config): Add directional output selection via separate direction field

Add support for directional output selection in the move-to-output action
using a separate `direction` field instead of overloading OutputMatch.

API additions:
- Add Workspace::connector() to get the connector showing a workspace
- Add Connector::connector_in_direction() to find outputs directionally

Implementation:
- Move directional finding logic from toml-config to compositor
- Algorithm uses center-to-center distance with axis-aligned preference
- Add GetWorkspaceConnector and GetConnectorInDirection IPC messages

Configuration changes:
- Add optional `direction` field to move-to-output action
- Either `output` or `direction` must be specified (not both)
- Valid directions: "left", "right", "up", "down"

Example usage:
  logo+control+shift+right = { type = "move-to-output", direction = "right" }

Signed-off-by: Arthur Heymans <arthur@aheymans.xyz>
This commit is contained in:
Arthur Heymans 2025-11-27 09:49:33 +01:00 committed by Julian Orth
parent e81b31b452
commit 5529306c67
13 changed files with 348 additions and 25 deletions

View file

@ -360,20 +360,52 @@ impl Action {
set_idle_grace_period(period)
}
}),
Action::MoveToOutput { output, workspace } => {
Action::MoveToOutput {
output,
workspace,
direction,
} => {
let state = state.clone();
b.new(move || {
let output = 'get_output: {
for connector in connectors() {
if connector.connected() && output.matches(connector, &state) {
break 'get_output connector;
let target_output = {
// Handle directional output selection
if let Some(direction) = direction {
// Get the current workspace to determine the source output
let current_ws = match workspace {
Some(ws) => ws,
None => s.get_workspace(),
};
if !current_ws.exists() {
return;
}
// Get the connector that currently has this workspace
let source_connector = current_ws.connector();
if !source_connector.exists() {
return;
}
// Find the connector in the given direction
let target = source_connector.connector_in_direction(direction);
if !target.exists() {
return;
}
target
} else if let Some(output) = &output {
// Handle normal output matching
'match_output: {
for connector in connectors() {
if connector.connected() && output.matches(connector, &state) {
break 'match_output connector;
}
}
return;
}
} else {
return;
}
return;
};
match workspace {
Some(ws) => ws.move_to_output(output),
None => s.move_to_output(output),
Some(ws) => ws.move_to_output(target_output),
None => s.move_to_output(target_output),
}
})
}