From fe26166e539632f153780bf34e3705ed6b630501 Mon Sep 17 00:00:00 2001 From: Simon Zeni Date: Thu, 6 Oct 2022 15:49:44 -0400 Subject: [PATCH] commands: introduce non_desktop command for output This command allows users to set a given output as non-desktop. The output is offered to the drm-lease-manager interface if available, for clients to lease. --- include/sway/commands.h | 1 + sway/commands/output.c | 1 + sway/commands/output/non_desktop.c | 106 +++++++++++++++++++++++++++++ sway/meson.build | 1 + sway/sway-output.5.scd | 5 ++ 5 files changed, 114 insertions(+) create mode 100644 sway/commands/output/non_desktop.c diff --git a/include/sway/commands.h b/include/sway/commands.h index 013a7b826..25a66f3ac 100644 --- a/include/sway/commands.h +++ b/include/sway/commands.h @@ -284,6 +284,7 @@ sway_cmd output_cmd_disable; sway_cmd output_cmd_dpms; sway_cmd output_cmd_enable; sway_cmd output_cmd_max_render_time; +sway_cmd output_cmd_non_desktop; sway_cmd output_cmd_mode; sway_cmd output_cmd_modeline; sway_cmd output_cmd_position; diff --git a/sway/commands/output.c b/sway/commands/output.c index c102344db..25e69e0e5 100644 --- a/sway/commands/output.c +++ b/sway/commands/output.c @@ -16,6 +16,7 @@ static const struct cmd_handler output_handlers[] = { { "max_render_time", output_cmd_max_render_time }, { "mode", output_cmd_mode }, { "modeline", output_cmd_modeline }, + { "non_desktop", output_cmd_non_desktop }, { "pos", output_cmd_position }, { "position", output_cmd_position }, { "power", output_cmd_power }, diff --git a/sway/commands/output/non_desktop.c b/sway/commands/output/non_desktop.c new file mode 100644 index 000000000..eefd6418b --- /dev/null +++ b/sway/commands/output/non_desktop.c @@ -0,0 +1,106 @@ +#include +#include +#include "sway/commands.h" +#include "sway/config.h" +#include "sway/output.h" +#include "sway/server.h" +#include "log.h" +#include "util.h" + +static int find_non_desktop_output(const void *item, const void *data) +{ + const struct sway_output_non_desktop *output = item; + const char *name = data; + return strcmp(output->wlr_output->name, name); +} + +static int find_output(const void *item, const void *data) +{ + const struct sway_output *output = item; + const char *name = data; + return strcmp(output->wlr_output->name, name); +} + +struct cmd_results *output_cmd_non_desktop(int argc, char **argv) { + if (argc == 0) { + return cmd_results_new(CMD_INVALID, "Missing non_desktop argument"); + } + + struct output_config *oc = config->handler_context.output_config; + + if (strcmp(oc->name, "*") == 0) { + return cmd_results_new(CMD_INVALID, + "Cannot apply non_desktop to all outputs"); + } + + if (parse_boolean(argv[0], true)) { + int index = list_seq_find(root->outputs, find_output, oc->name); + if (index == -1) { + return cmd_results_new(CMD_FAILURE, "unknown output %s ", oc->name); + } + + struct sway_output *output = root->outputs->items[index]; + struct wlr_output *wlr_output = output->wlr_output; + wlr_output->non_desktop = true; + + sway_log(SWAY_DEBUG, "output %s (%p) non-desktop on", wlr_output->name, + wlr_output); + + output_disable(output); + wlr_output_layout_remove(root->output_layout, wlr_output); + + struct sway_output_non_desktop *non_desktop = + output_non_desktop_create(wlr_output); + list_add(root->non_desktop_outputs, non_desktop); + + if (server.drm_lease_manager) { + wlr_drm_lease_v1_manager_offer_output(server.drm_lease_manager, + wlr_output); + } + + } else { + int index = list_seq_find(root->non_desktop_outputs, + find_non_desktop_output, oc->name); + if (index == -1) { + return cmd_results_new(CMD_FAILURE, "unknown non-desktop output %s", + oc->name); + } + struct sway_output_non_desktop *non_desktop = + root->non_desktop_outputs->items[index]; + struct wlr_output *wlr_output = non_desktop->wlr_output; + + wlr_output->non_desktop = false; + + sway_log(SWAY_DEBUG, "output %s (%p) non-desktop off", wlr_output->name, + wlr_output); + + if (server.drm_lease_manager) { + wlr_drm_lease_v1_manager_withdraw_output(server.drm_lease_manager, + wlr_output); + } + + struct sway_output *output = wlr_output->data; + if (output) { + output_enable(output); + } else { + struct sway_output *output = output_create(wlr_output); + if (!output) { + sway_log(SWAY_ERROR, "failed to allocate wlr_output"); + wlr_output->non_desktop = true; + if (server.drm_lease_manager) { + wlr_drm_lease_v1_manager_withdraw_output( + server.drm_lease_manager, wlr_output); + } + return cmd_results_new(CMD_FAILURE, "failed to create output");; + } + + output_init(output, &server); + } + + list_del(root->non_desktop_outputs, index); + wl_list_remove(&non_desktop->destroy.link); + free(non_desktop); + } + + return cmd_results_new(CMD_SUCCESS, NULL); +} diff --git a/sway/meson.build b/sway/meson.build index ced7419cd..d2c77b82c 100644 --- a/sway/meson.build +++ b/sway/meson.build @@ -189,6 +189,7 @@ sway_sources = files( 'commands/output/dpms.c', 'commands/output/enable.c', 'commands/output/max_render_time.c', + 'commands/output/non_desktop.c', 'commands/output/mode.c', 'commands/output/position.c', 'commands/output/power.c', diff --git a/sway/sway-output.5.scd b/sway/sway-output.5.scd index b7d5e5777..546af8790 100644 --- a/sway/sway-output.5.scd +++ b/sway/sway-output.5.scd @@ -180,6 +180,11 @@ must be separated by one space. For example: updated to work with different bit depths. This command is experimental, and may be removed or changed in the future. +*output* non_desktop on|off + Enables or disables the non-desktop property of a given output. When + enabled, the output is disabled and offered to the drm-lease-manager + interface if it is available. + # SEE ALSO *sway*(5) *sway-input*(5)