From bb3ab57064b190c339183a2d6c3d8a5462c4d5fe Mon Sep 17 00:00:00 2001 From: Kenny Levinsen Date: Sun, 17 Nov 2024 12:38:32 +0100 Subject: [PATCH] ipc-server: Force modeset if needed after executing commands IPC clients generally expect executed commands to have taken effect when the command completes, while delayed modeset means that it can take several milliseconds more before e.g. an output is enabled. However, modesetting on every output command in the IPC call could on systems with already slow modesetting behavior lead to an unresponsive system for a not insignificant period of time. To strike a balance, force modeset once all the commands of this IPC call have executed if a modeset is pending. --- include/sway/config.h | 1 + sway/desktop/output.c | 4 ++++ sway/ipc-server.c | 6 ++++++ 3 files changed, 11 insertions(+) diff --git a/include/sway/config.h b/include/sway/config.h index 013853c85..bb770c6f7 100644 --- a/include/sway/config.h +++ b/include/sway/config.h @@ -706,6 +706,7 @@ void free_output_config(struct output_config *oc); void request_modeset(void); void force_modeset(void); +bool modeset_is_pending(void); bool spawn_swaybg(void); diff --git a/sway/desktop/output.c b/sway/desktop/output.c index f4b77db43..bac997bff 100644 --- a/sway/desktop/output.c +++ b/sway/desktop/output.c @@ -408,6 +408,10 @@ void request_modeset(void) { } } +bool modeset_is_pending(void) { + return server.delayed_modeset != NULL; +} + void force_modeset(void) { if (server.delayed_modeset != NULL) { wl_event_source_remove(server.delayed_modeset); diff --git a/sway/ipc-server.c b/sway/ipc-server.c index 7f353c0ec..b934bb568 100644 --- a/sway/ipc-server.c +++ b/sway/ipc-server.c @@ -648,6 +648,12 @@ void ipc_client_handle_command(struct ipc_client *client, uint32_t payload_lengt } list_t *res_list = execute_command(buf, NULL, NULL); + if (modeset_is_pending()) { + // IPC expects commands to have taken immediate effect, so we need + // to force a modeset after output commands. We do a single modeset + // here to avoid modesetting for every output command in sequence. + force_modeset(); + } transaction_commit_dirty(); char *json = cmd_results_to_json(res_list); int length = strlen(json);