ext-workspace-v1: initial implementation

Maintain a 1:1 relationship between workspace groups and outputs, so
that moving a workspace across groups effectively moves it across
outputs.

ext_workspace_handle_v1::id is never emitted; sway has no concept of ids
or of stable vs temporary workspaces. Everything is ephemeral to the
current session.

ext_workspace_handle_v1::coordinates is never emitted; sway does not
organise workspaces into any sort of grid.

ext_workspace_handle_v1::assign is mostly untested, because no client
current implements this. Perhaps it's best to not-advertise the feature
for now?

Deactivating a workspace is a no-op. This functionality doesn't really
align with sway, although it could potentially be implemented to "switch
to previous workspace on this output" as a follow-up.

Removing a workspace is a no-op.

Implements: https://github.com/swaywm/sway/issues/8812
(cherry picked from commit f50f78c0d9)
This commit is contained in:
Hugo Osvaldo Barrera 2026-03-12 01:09:47 +01:00 committed by Simon Ser
parent 3aa4c46c13
commit 1e96e73767
8 changed files with 176 additions and 1 deletions

View file

@ -2,6 +2,8 @@
#include <ctype.h>
#include <string.h>
#include <strings.h>
#include <wlr/types/wlr_ext_workspace_v1.h>
#include "sway/tree/workspace.h"
#include "sway/ipc-server.h"
#include "sway/layers.h"
#include "sway/output.h"
@ -153,6 +155,7 @@ void output_enable(struct sway_output *output) {
output->enabled = true;
list_add(root->outputs, output);
sway_ext_workspace_output_enable(output);
restore_workspaces(output);
struct sway_workspace *ws = NULL;
@ -292,6 +295,7 @@ void output_disable(struct sway_output *output) {
destroy_layers(output);
output_evacuate(output);
sway_ext_workspace_output_disable(output);
}
void output_begin_destroy(struct sway_output *output) {
@ -333,6 +337,10 @@ void output_add_workspace(struct sway_output *output,
}
list_add(output->workspaces, workspace);
workspace->output = output;
if (workspace->output && workspace->output->ext_workspace_group) {
wlr_ext_workspace_handle_v1_set_group(workspace->ext_workspace,
workspace->output->ext_workspace_group);
}
node_set_dirty(&output->node);
node_set_dirty(&workspace->node);
}