From 6e4ccb99c3a2197468f8f34c290b7cd5612ff80b Mon Sep 17 00:00:00 2001 From: James Knight Date: Sat, 3 Aug 2024 12:30:17 -0400 Subject: [PATCH 01/21] build: avoid git repository discovery when determining version When attempting to use Git to populate commit/branch information in a version string, it is possible through repository discovery that it uses Git information not relevant to project. For example, if repository content is extract into an interim build location when using an embedded build framework (e.g. Buildroot), the project will not have its Git repository to refer to. When it cannot find its repository, it will look into its parent folders and may find the Git repository of another project and use its branch/commit information. This commit provides an explicit path to the project's Git repository when consider commit/branch information. This will prevent any repository discovery from occurring. Signed-off-by: James Knight --- meson.build | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/meson.build b/meson.build index 0d5b0cc6c..71e75fd9b 100644 --- a/meson.build +++ b/meson.build @@ -160,8 +160,8 @@ add_project_arguments('-DSYSCONFDIR="/@0@"'.format(join_paths(prefix, sysconfdir version = '"@0@"'.format(meson.project_version()) git = find_program('git', native: true, required: false) if git.found() - git_commit = run_command([git, 'rev-parse', '--short', 'HEAD'], check: false) - git_branch = run_command([git, 'rev-parse', '--abbrev-ref', 'HEAD'], check: false) + git_commit = run_command([git, '--git-dir=.git', 'rev-parse', '--short', 'HEAD'], check: false) + git_branch = run_command([git, '--git-dir=.git', 'rev-parse', '--abbrev-ref', 'HEAD'], check: false) if git_commit.returncode() == 0 and git_branch.returncode() == 0 version = '"@0@-@1@ (" __DATE__ ", branch \'@2@\')"'.format( meson.project_version(), From b881c2e84c4be3c7b996f85200cfe391a7979267 Mon Sep 17 00:00:00 2001 From: Alexander Orzechowski Date: Wed, 10 Jul 2024 12:20:53 -0400 Subject: [PATCH 02/21] transaction: Reparent all container children when disabling for scratchpad Fixes: #8205 --- sway/desktop/transaction.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/sway/desktop/transaction.c b/sway/desktop/transaction.c index 7568990bf..2ee5a5dff 100644 --- a/sway/desktop/transaction.c +++ b/sway/desktop/transaction.c @@ -632,6 +632,15 @@ static void arrange_root(struct sway_root *root) { for (int i = 0; i < root->scratchpad->length; i++) { struct sway_container *con = root->scratchpad->items[i]; + // When a container is moved to a scratchpad, it's possible that it + // was moved into a floating container as part of the same transaction. + // In this case, we need to make sure we reparent all the container's + // children so that disabling the container will disable all descendants. + if (!con->view) for (int ii = 0; ii < con->current.children->length; ii++) { + struct sway_container *child = con->current.children->items[ii]; + wlr_scene_node_reparent(&child->scene_tree->node, con->content_tree); + } + wlr_scene_node_set_enabled(&con->scene_tree->node, false); } From 9a1c411abd8261c121dcd50dfe54132718768084 Mon Sep 17 00:00:00 2001 From: Ricardo Steijn <61013287+RicArch97@users.noreply.github.com> Date: Mon, 5 Aug 2024 02:13:49 +0200 Subject: [PATCH 03/21] Add support for tearing-control-v1 References: https://gitlab.freedesktop.org/wlroots/wlroots/-/merge_requests/3871 Adds option to allow tearing per output, as well as an option to force enable or disable tearing for a specific application using a window rule. Only works with fullscreen applications. --- include/sway/commands.h | 2 + include/sway/config.h | 1 + include/sway/output.h | 1 + include/sway/server.h | 6 +++ include/sway/tree/view.h | 12 ++++++ protocols/meson.build | 1 + sway/commands.c | 1 + sway/commands/allow_tearing.c | 24 +++++++++++ sway/commands/output.c | 1 + sway/commands/output/allow_tearing.c | 23 +++++++++++ sway/config/output.c | 16 ++++++- sway/desktop/output.c | 28 +++++++++++++ sway/desktop/tearing.c | 62 ++++++++++++++++++++++++++++ sway/ipc-json.c | 4 ++ sway/meson.build | 3 ++ sway/server.c | 7 ++++ sway/sway-output.5.scd | 20 +++++++++ sway/sway.5.scd | 14 +++++++ sway/tree/view.c | 14 +++++++ swaymsg/main.c | 6 ++- 20 files changed, 243 insertions(+), 3 deletions(-) create mode 100644 sway/commands/allow_tearing.c create mode 100644 sway/commands/output/allow_tearing.c create mode 100644 sway/desktop/tearing.c diff --git a/include/sway/commands.h b/include/sway/commands.h index 15cd86982..5210d3ba7 100644 --- a/include/sway/commands.h +++ b/include/sway/commands.h @@ -104,6 +104,7 @@ struct sway_container *container_find_resize_parent(struct sway_container *con, sway_cmd cmd_exec_validate; sway_cmd cmd_exec_process; +sway_cmd cmd_allow_tearing; sway_cmd cmd_assign; sway_cmd cmd_bar; sway_cmd cmd_bindcode; @@ -283,6 +284,7 @@ sway_cmd input_cmd_xkb_switch_layout; sway_cmd input_cmd_xkb_variant; sway_cmd output_cmd_adaptive_sync; +sway_cmd output_cmd_allow_tearing; sway_cmd output_cmd_background; sway_cmd output_cmd_color_profile; sway_cmd output_cmd_disable; diff --git a/include/sway/config.h b/include/sway/config.h index dfa3c1b7b..d9f561571 100644 --- a/include/sway/config.h +++ b/include/sway/config.h @@ -289,6 +289,7 @@ struct output_config { enum render_bit_depth render_bit_depth; bool set_color_transform; struct wlr_color_transform *color_transform; + int allow_tearing; char *background; char *background_option; diff --git a/include/sway/output.h b/include/sway/output.h index 2189c6e87..7e2d58927 100644 --- a/include/sway/output.h +++ b/include/sway/output.h @@ -73,6 +73,7 @@ struct sway_output { int max_render_time; // In milliseconds struct wl_event_source *repaint_timer; bool gamma_lut_changed; + bool allow_tearing; }; struct sway_output_non_desktop { diff --git a/include/sway/server.h b/include/sway/server.h index abf1b6b4e..460f9e17f 100644 --- a/include/sway/server.h +++ b/include/sway/server.h @@ -115,6 +115,10 @@ struct sway_server { struct wl_listener xdg_activation_v1_new_token; struct wl_listener request_set_cursor_shape; + + struct wlr_tearing_control_manager_v1 *tearing_control_v1; + struct wl_listener tearing_control_new_object; + struct wl_list tearing_controllers; // sway_tearing_controller::link struct wl_list pending_launcher_ctxs; // launcher_ctx::link @@ -182,4 +186,6 @@ void xdg_activation_v1_handle_new_token(struct wl_listener *listener, void set_rr_scheduling(void); +void handle_new_tearing_hint(struct wl_listener *listener, void *data); + #endif diff --git a/include/sway/tree/view.h b/include/sway/tree/view.h index 3ae8cf224..14aad1a18 100644 --- a/include/sway/tree/view.h +++ b/include/sway/tree/view.h @@ -4,6 +4,7 @@ #include #include #include +#include #include "sway/config.h" #if WLR_HAS_XWAYLAND #include @@ -34,6 +35,12 @@ enum sway_view_prop { #endif }; +enum sway_view_tearing_mode { + TEARING_OVERRIDE_FALSE, + TEARING_OVERRIDE_TRUE, + TEARING_WINDOW_HINT, +}; + struct sway_view_impl { void (*get_constraints)(struct sway_view *view, double *min_width, double *max_width, double *min_height, double *max_height); @@ -111,6 +118,9 @@ struct sway_view { int max_render_time; // In milliseconds enum seat_config_shortcuts_inhibit shortcuts_inhibit; + + enum sway_view_tearing_mode tearing_mode; + enum wp_tearing_control_v1_presentation_hint tearing_hint; }; struct sway_xdg_shell_view { @@ -335,4 +345,6 @@ void view_assign_ctx(struct sway_view *view, struct launcher_ctx *ctx); void view_send_frame_done(struct sway_view *view); +bool view_can_tear(struct sway_view *view); + #endif diff --git a/protocols/meson.build b/protocols/meson.build index 6eac8542c..d96f87575 100644 --- a/protocols/meson.build +++ b/protocols/meson.build @@ -14,6 +14,7 @@ protocols = [ wl_protocol_dir / 'unstable/linux-dmabuf/linux-dmabuf-unstable-v1.xml', wl_protocol_dir / 'staging/content-type/content-type-v1.xml', wl_protocol_dir / 'staging/cursor-shape/cursor-shape-v1.xml', + wl_protocol_dir / 'staging/tearing-control/tearing-control-v1.xml', 'wlr-layer-shell-unstable-v1.xml', 'idle.xml', 'wlr-output-power-management-unstable-v1.xml', diff --git a/sway/commands.c b/sway/commands.c index 8d003dfa6..c2c12ee65 100644 --- a/sway/commands.c +++ b/sway/commands.c @@ -112,6 +112,7 @@ static const struct cmd_handler config_handlers[] = { /* Runtime-only commands. Keep alphabetized */ static const struct cmd_handler command_handlers[] = { + { "allow_tearing", cmd_allow_tearing }, { "border", cmd_border }, { "create_output", cmd_create_output }, { "exit", cmd_exit }, diff --git a/sway/commands/allow_tearing.c b/sway/commands/allow_tearing.c new file mode 100644 index 000000000..ee5941381 --- /dev/null +++ b/sway/commands/allow_tearing.c @@ -0,0 +1,24 @@ +#include +#include "sway/config.h" +#include "sway/tree/view.h" +#include "util.h" + +struct cmd_results *cmd_allow_tearing(int argc, char **argv) { + struct cmd_results *error = NULL; + if ((error = checkarg(argc, "allow_tearing", EXPECTED_AT_LEAST, 1))) { + return error; + } + + struct sway_container *container = config->handler_context.container; + if (!container || !container->view) { + return cmd_results_new(CMD_INVALID, "Tearing can only be allowed on views"); + } + + bool wants_tearing = parse_boolean(argv[0], true); + + struct sway_view *view = container->view; + view->tearing_mode = wants_tearing ? TEARING_OVERRIDE_TRUE : + TEARING_OVERRIDE_FALSE; + + return cmd_results_new(CMD_SUCCESS, NULL); +} diff --git a/sway/commands/output.c b/sway/commands/output.c index b822e770a..9478e0bad 100644 --- a/sway/commands/output.c +++ b/sway/commands/output.c @@ -8,6 +8,7 @@ // must be in order for the bsearch static const struct cmd_handler output_handlers[] = { { "adaptive_sync", output_cmd_adaptive_sync }, + { "allow_tearing", output_cmd_allow_tearing }, { "background", output_cmd_background }, { "bg", output_cmd_background }, { "color_profile", output_cmd_color_profile }, diff --git a/sway/commands/output/allow_tearing.c b/sway/commands/output/allow_tearing.c new file mode 100644 index 000000000..9a183b96c --- /dev/null +++ b/sway/commands/output/allow_tearing.c @@ -0,0 +1,23 @@ +#include "sway/commands.h" +#include "sway/config.h" +#include "util.h" + +struct cmd_results *output_cmd_allow_tearing(int argc, char **argv) { + if (!config->handler_context.output_config) { + return cmd_results_new(CMD_FAILURE, "Missing output config"); + } + if (argc == 0) { + return cmd_results_new(CMD_INVALID, "Missing allow_tearing argument"); + } + + if (parse_boolean(argv[0], + (config->handler_context.output_config->allow_tearing == 1))) { + config->handler_context.output_config->allow_tearing = 1; + } else { + config->handler_context.output_config->allow_tearing = 0; + } + + config->handler_context.leftovers.argc = argc - 1; + config->handler_context.leftovers.argv = argv + 1; + return NULL; +} diff --git a/sway/config/output.c b/sway/config/output.c index e64efb7ff..940c75fe3 100644 --- a/sway/config/output.c +++ b/sway/config/output.c @@ -79,6 +79,7 @@ struct output_config *new_output_config(const char *name) { oc->set_color_transform = false; oc->color_transform = NULL; oc->power = -1; + oc->allow_tearing = -1; return oc; } @@ -216,6 +217,9 @@ static void merge_output_config(struct output_config *dst, struct output_config if (src->power != -1) { dst->power = src->power; } + if (src->allow_tearing != -1) { + dst->allow_tearing = src->allow_tearing; + } } void store_output_config(struct output_config *oc) { @@ -258,11 +262,11 @@ void store_output_config(struct output_config *oc) { sway_log(SWAY_DEBUG, "Config stored for output %s (enabled: %d) (%dx%d@%fHz " "position %d,%d scale %f subpixel %s transform %d) (bg %s %s) (power %d) " - "(max render time: %d)", + "(max render time: %d) (allow tearing: %d)", oc->name, oc->enabled, oc->width, oc->height, oc->refresh_rate, oc->x, oc->y, oc->scale, sway_wl_output_subpixel_to_string(oc->subpixel), oc->transform, oc->background, oc->background_option, oc->power, - oc->max_render_time); + oc->max_render_time, oc->allow_tearing); // If the configuration was not merged into an existing configuration, add // it to the list. Otherwise we're done with it and can free it. @@ -574,6 +578,13 @@ static bool finalize_output_config(struct output_config *oc, struct sway_output wlr_color_transform_unref(output->color_transform); output->color_transform = oc->color_transform; } + + if (oc && oc->allow_tearing >= 0) { + sway_log(SWAY_DEBUG, "Set %s allow tearing to %d", + oc->name, oc->allow_tearing); + output->allow_tearing = oc->allow_tearing; + } + return true; } @@ -594,6 +605,7 @@ static void default_output_config(struct output_config *oc, oc->subpixel = output->detected_subpixel; oc->transform = WL_OUTPUT_TRANSFORM_NORMAL; oc->max_render_time = 0; + oc->allow_tearing = 0; } // find_output_config returns a merged output_config containing all stored diff --git a/sway/desktop/output.c b/sway/desktop/output.c index 27ede68ee..f1e08eff8 100644 --- a/sway/desktop/output.c +++ b/sway/desktop/output.c @@ -232,6 +232,23 @@ static void output_configure_scene(struct sway_output *output, } } +static bool output_can_tear(struct sway_output *output) { + struct sway_workspace *workspace = output->current.active_workspace; + if (!workspace) { + return false; + } + + struct sway_container *fullscreen_con = root->fullscreen_global; + if (!fullscreen_con) { + fullscreen_con = workspace->current.fullscreen; + } + if (fullscreen_con && fullscreen_con->view) { + return (output->allow_tearing && view_can_tear(fullscreen_con->view)); + } + + return false; +} + static int output_repaint_timer_handler(void *data) { struct sway_output *output = data; @@ -275,6 +292,17 @@ static int output_repaint_timer_handler(void *data) { wlr_output_state_set_gamma_lut(&pending, 0, NULL, NULL, NULL); } } + + if (output_can_tear(output)) { + pending.tearing_page_flip = true; + + if (!wlr_output_test_state(output->wlr_output, &pending)) { + sway_log(SWAY_DEBUG, "Output test failed on '%s', retrying without tearing page-flip", + output->wlr_output->name); + + pending.tearing_page_flip = false; + } + } if (!wlr_output_commit_state(output->wlr_output, &pending)) { sway_log(SWAY_ERROR, "Page-flip failed on output %s", output->wlr_output->name); diff --git a/sway/desktop/tearing.c b/sway/desktop/tearing.c new file mode 100644 index 000000000..36cc48bfe --- /dev/null +++ b/sway/desktop/tearing.c @@ -0,0 +1,62 @@ +#include +#include +#include "sway/server.h" +#include "sway/tree/view.h" +#include "sway/output.h" +#include "log.h" + +struct sway_tearing_controller { + struct wlr_tearing_control_v1 *tearing_control; + struct wl_listener set_hint; + struct wl_listener destroy; + + struct wl_list link; // sway_server::tearing_controllers +}; + +static void handle_tearing_controller_set_hint(struct wl_listener *listener, + void *data) { + struct sway_tearing_controller *controller = + wl_container_of(listener, controller, set_hint); + + struct sway_view *view = view_from_wlr_surface( + controller->tearing_control->surface); + if (view) { + view->tearing_hint = controller->tearing_control->current; + } +} + +static void handle_tearing_controller_destroy(struct wl_listener *listener, + void *data) { + struct sway_tearing_controller *controller = + wl_container_of(listener, controller, destroy); + wl_list_remove(&controller->link); + free(controller); +} + +void handle_new_tearing_hint(struct wl_listener *listener, + void *data) { + struct sway_server *server = + wl_container_of(listener, server, tearing_control_new_object); + struct wlr_tearing_control_v1 *tearing_control = data; + + enum wp_tearing_control_v1_presentation_hint hint = + wlr_tearing_control_manager_v1_surface_hint_from_surface( + server->tearing_control_v1, tearing_control->surface); + sway_log(SWAY_DEBUG, "New presentation hint %d received for surface %p", + hint, tearing_control->surface); + + struct sway_tearing_controller *controller = + calloc(1, sizeof(struct sway_tearing_controller)); + if (!controller) { + return; + } + + controller->tearing_control = tearing_control; + controller->set_hint.notify = handle_tearing_controller_set_hint; + wl_signal_add(&tearing_control->events.set_hint, &controller->set_hint); + controller->destroy.notify = handle_tearing_controller_destroy; + wl_signal_add(&tearing_control->events.destroy, &controller->destroy); + wl_list_init(&controller->link); + + wl_list_insert(&server->tearing_controllers, &controller->link); +} diff --git a/sway/ipc-json.c b/sway/ipc-json.c index e512a2239..8eaa8324a 100644 --- a/sway/ipc-json.c +++ b/sway/ipc-json.c @@ -399,6 +399,8 @@ static void ipc_json_describe_enabled_output(struct sway_output *output, } json_object_object_add(object, "max_render_time", json_object_new_int(output->max_render_time)); + + json_object_object_add(object, "allow_tearing", json_object_new_boolean(output->allow_tearing)); } json_object *ipc_json_describe_disabled_output(struct sway_output *output) { @@ -593,6 +595,8 @@ static void ipc_json_describe_view(struct sway_container *c, json_object *object json_object_object_add(object, "max_render_time", json_object_new_int(c->view->max_render_time)); + json_object_object_add(object, "allow_tearing", json_object_new_boolean(view_can_tear(c->view))); + json_object_object_add(object, "shell", json_object_new_string(view_get_shell(c->view))); json_object_object_add(object, "inhibit_idle", diff --git a/sway/meson.build b/sway/meson.build index 2f4406abb..8042c89be 100644 --- a/sway/meson.build +++ b/sway/meson.build @@ -18,6 +18,7 @@ sway_sources = files( 'desktop/idle_inhibit_v1.c', 'desktop/layer_shell.c', 'desktop/output.c', + 'desktop/tearing.c', 'desktop/transaction.c', 'desktop/xdg_shell.c', 'desktop/launcher.c', @@ -41,6 +42,7 @@ sway_sources = files( 'config/seat.c', 'config/input.c', + 'commands/allow_tearing.c', 'commands/assign.c', 'commands/bar.c', 'commands/bind.c', @@ -188,6 +190,7 @@ sway_sources = files( 'commands/input/xkb_variant.c', 'commands/output/adaptive_sync.c', + 'commands/output/allow_tearing.c', 'commands/output/background.c', 'commands/output/disable.c', 'commands/output/dpms.c', diff --git a/sway/server.c b/sway/server.c index edbc1a4b1..bb895377b 100644 --- a/sway/server.c +++ b/sway/server.c @@ -371,6 +371,13 @@ bool server_init(struct sway_server *server) { server->content_type_manager_v1 = wlr_content_type_manager_v1_create(server->wl_display, 1); wlr_fractional_scale_manager_v1_create(server->wl_display, 1); + + server->tearing_control_v1 = + wlr_tearing_control_manager_v1_create(server->wl_display, 1); + server->tearing_control_new_object.notify = handle_new_tearing_hint; + wl_signal_add(&server->tearing_control_v1->events.new_object, + &server->tearing_control_new_object); + wl_list_init(&server->tearing_controllers); struct wlr_xdg_foreign_registry *foreign_registry = wlr_xdg_foreign_registry_create(server->wl_display); diff --git a/sway/sway-output.5.scd b/sway/sway-output.5.scd index 6d7c08604..d9a28807a 100644 --- a/sway/sway-output.5.scd +++ b/sway/sway-output.5.scd @@ -190,6 +190,26 @@ must be separated by one space. For example: may have no effect or produce unexpected output when used together with future HDR support features. +*output* allow_tearing yes|no + Allows or disallows screen tearing as a result of immediate page flips, + and an immediate presentation mode from a client. The default is that no + screen tearing is allowed. + + With immediate page flips, frames from the client are presented as soon + as possible instead of synchronizing with the monitor's vblank interval + (VSync). + + It is recommended to set *max_render_time* to *off*. In that case a page flip + happens as soon as a client updates. Otherwise, tearing will only happen if + rendering takes longer than the configured milliseconds before the next + display refresh. + + To adjust whether tearing is allowed for specific applications, see + *allow_tearing* in *sway*(5). Note that tearing will only be enabled + when it's allowed for both the output and the application. + + This setting only has effect when a window is fullscreen on the output. + # SEE ALSO *sway*(5) *sway-input*(5) diff --git a/sway/sway.5.scd b/sway/sway.5.scd index 9f8239473..0b36a7572 100644 --- a/sway/sway.5.scd +++ b/sway/sway.5.scd @@ -215,6 +215,20 @@ set|plus|minus|toggle effect on the output the window is currently on. See *sway-output*(5) for further details. +*allow_tearing* yes|no + Allows or disallows screen tearing as a result of immediate page flips + for a fullscreen application. + + When this option is not set, the tearing hints provided by the application + determine whether tearing is allowed. When _yes_ is specified, + the application allows tearing regardless of the tearing hints. + When _no_ is specified, tearing will never be allowed on the application, + regardless of the tearing hints. + + This setting only has an effect if tearing is allowed on the output through + the per-output *allow_tearing* setting. See *sway-output*(5) + for further details. + *move* left|right|up|down [ px] Moves the focused container in the direction specified. The optional _px_ argument specifies how many pixels to move the container. If unspecified, diff --git a/sway/tree/view.c b/sway/tree/view.c index 229d765ea..423473879 100644 --- a/sway/tree/view.c +++ b/sway/tree/view.c @@ -58,6 +58,7 @@ bool view_init(struct sway_view *view, enum sway_view_type type, view->executed_criteria = create_list(); view->allow_request_urgent = true; view->shortcuts_inhibit = SHORTCUTS_INHIBIT_DEFAULT; + view->tearing_mode = TEARING_WINDOW_HINT; wl_signal_init(&view->events.unmap); return true; } @@ -1260,6 +1261,19 @@ bool view_is_transient_for(struct sway_view *child, child->impl->is_transient_for(child, ancestor); } +bool view_can_tear(struct sway_view *view) { + switch (view->tearing_mode) { + case TEARING_OVERRIDE_FALSE: + return false; + case TEARING_OVERRIDE_TRUE: + return true; + case TEARING_WINDOW_HINT: + return view->tearing_hint == + WP_TEARING_CONTROL_V1_PRESENTATION_HINT_ASYNC; + } + return false; +} + static void send_frame_done_iterator(struct wlr_scene_buffer *scene_buffer, int x, int y, void *data) { struct timespec *when = data; diff --git a/swaymsg/main.c b/swaymsg/main.c index 573a7b166..5c57171e7 100644 --- a/swaymsg/main.c +++ b/swaymsg/main.c @@ -193,7 +193,7 @@ static void pretty_print_output(json_object *o) { json_object_object_get_ex(o, "current_workspace", &ws); json_object_object_get_ex(o, "non_desktop", &non_desktop); json_object *make, *model, *serial, *scale, *scale_filter, *subpixel, - *transform, *max_render_time, *adaptive_sync_status; + *transform, *max_render_time, *adaptive_sync_status, *allow_tearing; json_object_object_get_ex(o, "make", &make); json_object_object_get_ex(o, "model", &model); json_object_object_get_ex(o, "serial", &serial); @@ -203,6 +203,7 @@ static void pretty_print_output(json_object *o) { json_object_object_get_ex(o, "transform", &transform); json_object_object_get_ex(o, "max_render_time", &max_render_time); json_object_object_get_ex(o, "adaptive_sync_status", &adaptive_sync_status); + json_object_object_get_ex(o, "allow_tearing", &allow_tearing); json_object *x, *y; json_object_object_get_ex(rect, "x", &x); json_object_object_get_ex(rect, "y", &y); @@ -256,6 +257,9 @@ static void pretty_print_output(json_object *o) { printf(" Adaptive sync: %s\n", json_object_get_string(adaptive_sync_status)); + + printf(" Allow tearing: %s\n", + json_object_get_boolean(allow_tearing) ? "yes" : "no"); } else { printf( "Output %s '%s %s %s' (disabled)\n", From 05e895c4638293a6bfe594ff0cae4eaab63b740e Mon Sep 17 00:00:00 2001 From: Simon Ser Date: Fri, 10 May 2024 16:11:38 +0200 Subject: [PATCH 04/21] Add support for linux-drm-syncobj-v1 References: https://gitlab.freedesktop.org/wlroots/wlroots/-/merge_requests/4262 --- sway/server.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/sway/server.c b/sway/server.c index bb895377b..537febe83 100644 --- a/sway/server.c +++ b/sway/server.c @@ -23,6 +23,7 @@ #include #include #include +#include #include #include #include @@ -248,6 +249,11 @@ bool server_init(struct sway_server *server) { wlr_drm_create(server->wl_display, server->renderer); } } + if (wlr_renderer_get_drm_fd(server->renderer) >= 0 && + server->renderer->features.timeline) { + wlr_linux_drm_syncobj_manager_v1_create(server->wl_display, 1, + wlr_renderer_get_drm_fd(server->renderer)); + } server->allocator = wlr_allocator_autocreate(server->backend, server->renderer); From 3e956b922958b182912775497812cd42439b2955 Mon Sep 17 00:00:00 2001 From: Kirill Primak Date: Wed, 7 Aug 2024 15:26:49 +0300 Subject: [PATCH 05/21] tearing: remove trailing whitespace --- sway/config/output.c | 4 ++-- sway/desktop/output.c | 5 ++--- sway/desktop/tearing.c | 16 ++++++++-------- sway/server.c | 4 ++-- sway/tree/view.c | 2 +- 5 files changed, 15 insertions(+), 16 deletions(-) diff --git a/sway/config/output.c b/sway/config/output.c index 940c75fe3..1b378078e 100644 --- a/sway/config/output.c +++ b/sway/config/output.c @@ -578,9 +578,9 @@ static bool finalize_output_config(struct output_config *oc, struct sway_output wlr_color_transform_unref(output->color_transform); output->color_transform = oc->color_transform; } - + if (oc && oc->allow_tearing >= 0) { - sway_log(SWAY_DEBUG, "Set %s allow tearing to %d", + sway_log(SWAY_DEBUG, "Set %s allow tearing to %d", oc->name, oc->allow_tearing); output->allow_tearing = oc->allow_tearing; } diff --git a/sway/desktop/output.c b/sway/desktop/output.c index f1e08eff8..c1aa4483e 100644 --- a/sway/desktop/output.c +++ b/sway/desktop/output.c @@ -292,14 +292,13 @@ static int output_repaint_timer_handler(void *data) { wlr_output_state_set_gamma_lut(&pending, 0, NULL, NULL, NULL); } } - + if (output_can_tear(output)) { pending.tearing_page_flip = true; - + if (!wlr_output_test_state(output->wlr_output, &pending)) { sway_log(SWAY_DEBUG, "Output test failed on '%s', retrying without tearing page-flip", output->wlr_output->name); - pending.tearing_page_flip = false; } } diff --git a/sway/desktop/tearing.c b/sway/desktop/tearing.c index 36cc48bfe..b74c74d25 100644 --- a/sway/desktop/tearing.c +++ b/sway/desktop/tearing.c @@ -17,7 +17,7 @@ static void handle_tearing_controller_set_hint(struct wl_listener *listener, void *data) { struct sway_tearing_controller *controller = wl_container_of(listener, controller, set_hint); - + struct sway_view *view = view_from_wlr_surface( controller->tearing_control->surface); if (view) { @@ -25,27 +25,27 @@ static void handle_tearing_controller_set_hint(struct wl_listener *listener, } } -static void handle_tearing_controller_destroy(struct wl_listener *listener, +static void handle_tearing_controller_destroy(struct wl_listener *listener, void *data) { - struct sway_tearing_controller *controller = + struct sway_tearing_controller *controller = wl_container_of(listener, controller, destroy); wl_list_remove(&controller->link); free(controller); } -void handle_new_tearing_hint(struct wl_listener *listener, +void handle_new_tearing_hint(struct wl_listener *listener, void *data) { - struct sway_server *server = + struct sway_server *server = wl_container_of(listener, server, tearing_control_new_object); struct wlr_tearing_control_v1 *tearing_control = data; - - enum wp_tearing_control_v1_presentation_hint hint = + + enum wp_tearing_control_v1_presentation_hint hint = wlr_tearing_control_manager_v1_surface_hint_from_surface( server->tearing_control_v1, tearing_control->surface); sway_log(SWAY_DEBUG, "New presentation hint %d received for surface %p", hint, tearing_control->surface); - struct sway_tearing_controller *controller = + struct sway_tearing_controller *controller = calloc(1, sizeof(struct sway_tearing_controller)); if (!controller) { return; diff --git a/sway/server.c b/sway/server.c index 537febe83..f89bd529b 100644 --- a/sway/server.c +++ b/sway/server.c @@ -377,8 +377,8 @@ bool server_init(struct sway_server *server) { server->content_type_manager_v1 = wlr_content_type_manager_v1_create(server->wl_display, 1); wlr_fractional_scale_manager_v1_create(server->wl_display, 1); - - server->tearing_control_v1 = + + server->tearing_control_v1 = wlr_tearing_control_manager_v1_create(server->wl_display, 1); server->tearing_control_new_object.notify = handle_new_tearing_hint; wl_signal_add(&server->tearing_control_v1->events.new_object, diff --git a/sway/tree/view.c b/sway/tree/view.c index 423473879..d25a09c2a 100644 --- a/sway/tree/view.c +++ b/sway/tree/view.c @@ -1268,7 +1268,7 @@ bool view_can_tear(struct sway_view *view) { case TEARING_OVERRIDE_TRUE: return true; case TEARING_WINDOW_HINT: - return view->tearing_hint == + return view->tearing_hint == WP_TEARING_CONTROL_V1_PRESENTATION_HINT_ASYNC; } return false; From 32e5e5232d1b0b5a34b4296a79a4e8cfa32b5090 Mon Sep 17 00:00:00 2001 From: Kirill Primak Date: Wed, 7 Aug 2024 15:27:02 +0300 Subject: [PATCH 06/21] tearing: fix UAF on destroy Fixes: 9a1c411abd8261c121dcd50dfe54132718768084 --- sway/desktop/tearing.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/sway/desktop/tearing.c b/sway/desktop/tearing.c index b74c74d25..d8d276451 100644 --- a/sway/desktop/tearing.c +++ b/sway/desktop/tearing.c @@ -29,6 +29,8 @@ static void handle_tearing_controller_destroy(struct wl_listener *listener, void *data) { struct sway_tearing_controller *controller = wl_container_of(listener, controller, destroy); + wl_list_remove(&controller->set_hint.link); + wl_list_remove(&controller->destroy.link); wl_list_remove(&controller->link); free(controller); } From 951a22c2445f5c32b831bac0db86869627940402 Mon Sep 17 00:00:00 2001 From: Alexander Orzechowski Date: Wed, 7 Aug 2024 16:52:49 -0400 Subject: [PATCH 07/21] xwayland: Let scene restack --- sway/desktop/xwayland.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/sway/desktop/xwayland.c b/sway/desktop/xwayland.c index 805c9b9d5..b83537a0a 100644 --- a/sway/desktop/xwayland.c +++ b/sway/desktop/xwayland.c @@ -289,9 +289,6 @@ static void set_activated(struct sway_view *view, bool activated) { } wlr_xwayland_surface_activate(surface, activated); - if (activated) { - wlr_xwayland_surface_restack(surface, NULL, XCB_STACK_MODE_ABOVE); - } } static void set_tiled(struct sway_view *view, bool tiled) { From f344e9d5a5afe6ba1aeaf781be3bd18dbf8596f1 Mon Sep 17 00:00:00 2001 From: JingMatrix Date: Fri, 9 Aug 2024 00:26:03 +0200 Subject: [PATCH 08/21] Add null-safety check for virtual keyboard keymaps Note that in the `sway_keyboard_configure` function of sway/input/keyboard.c, we have skipped the `sway_keyboard_set_layout` function for virtual keyboards, which then have null keymaps. Hence, a null-safety check is needed at runtime. --- sway/commands/input/xkb_switch_layout.c | 10 +++++++++- sway/ipc-json.c | 4 +++- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/sway/commands/input/xkb_switch_layout.c b/sway/commands/input/xkb_switch_layout.c index 8d600fcad..623dfa186 100644 --- a/sway/commands/input/xkb_switch_layout.c +++ b/sway/commands/input/xkb_switch_layout.c @@ -95,10 +95,18 @@ struct cmd_results *input_cmd_xkb_switch_layout(int argc, char **argv) { continue; } + struct wlr_keyboard *keyboard = + wlr_keyboard_from_input_device(dev->wlr_device); + if (keyboard->keymap == NULL && dev->is_virtual) { + // The `sway_keyboard_set_layout` function is by default skipped + // when configuring virtual keyboards. + continue; + } + struct xkb_switch_layout_action *action = &actions[actions_len++]; + action->keyboard = keyboard; - action->keyboard = wlr_keyboard_from_input_device(dev->wlr_device); if (relative) { action->layout = get_layout_relative(action->keyboard, relative); } else { diff --git a/sway/ipc-json.c b/sway/ipc-json.c index 8eaa8324a..571338a4f 100644 --- a/sway/ipc-json.c +++ b/sway/ipc-json.c @@ -1133,7 +1133,9 @@ json_object *ipc_json_describe_input(struct sway_input_device *device) { json_object *layouts_arr = json_object_new_array(); json_object_object_add(object, "xkb_layout_names", layouts_arr); - xkb_layout_index_t num_layouts = xkb_keymap_num_layouts(keymap); + xkb_layout_index_t num_layouts = + keymap ? xkb_keymap_num_layouts(keymap) : 0; + // Virtual keyboards might have null keymap xkb_layout_index_t layout_idx; for (layout_idx = 0; layout_idx < num_layouts; layout_idx++) { const char *layout = xkb_keymap_layout_get_name(keymap, layout_idx); From 9ba1beee580d07adfba903257ce8762b96ea3833 Mon Sep 17 00:00:00 2001 From: Simon Ser Date: Thu, 29 Feb 2024 01:03:11 +0100 Subject: [PATCH 09/21] Bind a few utilities to special keys in default config --- config.in | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/config.in b/config.in index a5173165b..811365e1a 100644 --- a/config.in +++ b/config.in @@ -195,6 +195,19 @@ mode "resize" { bindsym Escape mode "default" } bindsym $mod+r mode "resize" +# +# Utilities: +# + # Special keys to adjust volume via PulseAudio + bindsym --locked XF86AudioMute exec pactl set-sink-mute \@DEFAULT_SINK@ toggle + bindsym --locked XF86AudioLowerVolume exec pactl set-sink-volume \@DEFAULT_SINK@ -5% + bindsym --locked XF86AudioRaiseVolume exec pactl set-sink-volume \@DEFAULT_SINK@ +5% + bindsym --locked XF86AudioMicMute exec pactl set-source-mute \@DEFAULT_SOURCE@ toggle + # Special keys to adjust brightness via brightnessctl + bindsym --locked XF86MonBrightnessDown exec brightnessctl set 5%- + bindsym --locked XF86MonBrightnessUp exec brightnessctl set 5%+ + # Special key to take a screenshot with grim + bindsym Print exec grim # # Status Bar: From b44015578a3d53cdd9436850202d4405696c1f52 Mon Sep 17 00:00:00 2001 From: Simon Ser Date: Sun, 11 Aug 2024 19:03:19 +0200 Subject: [PATCH 10/21] Switch default config to wmenu-run This removes the last dependency bit on dmenu. No need for "swaymsg exec" anymore: wmenu-run handles the xdg-activation shenanigans. --- config.in | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/config.in b/config.in index 811365e1a..a2a01dda9 100644 --- a/config.in +++ b/config.in @@ -16,9 +16,7 @@ set $right l # Your preferred terminal emulator set $term foot # Your preferred application launcher -# Note: pass the final command to swaymsg so that the resulting window can be opened -# on the original workspace that the command was run on. -set $menu dmenu_path | wmenu | xargs swaymsg exec -- +set $menu wmenu-run ### Output configuration # From 6576b99c243e2b66d077db0a99ec9683747e3fe9 Mon Sep 17 00:00:00 2001 From: Felix Pehla <74104874+FelixPehla@users.noreply.github.com> Date: Wed, 7 Aug 2024 18:34:59 +0200 Subject: [PATCH 11/21] commands/output/color_profile: allows use of relative path for ICC profile --- sway/commands/output/color_profile.c | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/sway/commands/output/color_profile.c b/sway/commands/output/color_profile.c index 792bd55fb..98481329b 100644 --- a/sway/commands/output/color_profile.c +++ b/sway/commands/output/color_profile.c @@ -5,6 +5,7 @@ #include #include "sway/commands.h" #include "sway/config.h" +#include "stringop.h" static bool read_file_into_buf(const char *path, void **buf, size_t *size) { /* Why not use fopen/fread directly? glibc will succesfully open directories, @@ -70,12 +71,23 @@ struct cmd_results *output_cmd_color_profile(int argc, char **argv) { return cmd_results_new(CMD_INVALID, "Invalid color profile specification: icc type requires a file"); } + + char *icc_path = strdup(argv[1]); + if (!expand_path(&icc_path)) { + struct cmd_results *cmd_res = cmd_results_new(CMD_INVALID, + "Invalid color profile specification: invalid file path"); + free(icc_path); + return cmd_res; + } + void *data = NULL; size_t size = 0; - if (!read_file_into_buf(argv[1], &data, &size)) { + if (!read_file_into_buf(icc_path, &data, &size)) { + free(icc_path); return cmd_results_new(CMD_FAILURE, "Failed to load color profile: could not read ICC file"); } + free(icc_path); struct wlr_color_transform *tmp = wlr_color_transform_init_linear_to_icc(data, size); From 5a3621460f193416605ad786e33687952527df21 Mon Sep 17 00:00:00 2001 From: Alexander Orzechowski Date: Wed, 14 Aug 2024 12:52:51 -0400 Subject: [PATCH 12/21] output: Use wlr_scene_output_needs_frame --- sway/desktop/output.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/sway/desktop/output.c b/sway/desktop/output.c index c1aa4483e..7f5ec5f82 100644 --- a/sway/desktop/output.c +++ b/sway/desktop/output.c @@ -266,8 +266,7 @@ static int output_repaint_timer_handler(void *data) { struct wlr_output *wlr_output = output->wlr_output; struct wlr_scene_output *scene_output = output->scene_output; - if (!wlr_output->needs_frame && !output->gamma_lut_changed && - !pixman_region32_not_empty(&scene_output->pending_commit_damage)) { + if (!wlr_scene_output_needs_frame(scene_output)) { return 0; } From c3279944fb195a5169eb540ef8285533dc5edfba Mon Sep 17 00:00:00 2001 From: Alexander Orzechowski Date: Wed, 14 Aug 2024 13:42:53 -0400 Subject: [PATCH 13/21] output: Use wlr_scene_set_gamma_control_manager_v1 --- include/sway/output.h | 3 --- sway/desktop/output.c | 37 ------------------------------------- sway/server.c | 5 ++--- 3 files changed, 2 insertions(+), 43 deletions(-) diff --git a/include/sway/output.h b/include/sway/output.h index 7e2d58927..1dcabc256 100644 --- a/include/sway/output.h +++ b/include/sway/output.h @@ -72,7 +72,6 @@ struct sway_output { uint32_t refresh_nsec; int max_render_time; // In milliseconds struct wl_event_source *repaint_timer; - bool gamma_lut_changed; bool allow_tearing; }; @@ -138,8 +137,6 @@ enum wlr_direction opposite_direction(enum wlr_direction d); void handle_output_layout_change(struct wl_listener *listener, void *data); -void handle_gamma_control_set_gamma(struct wl_listener *listener, void *data); - void handle_output_manager_apply(struct wl_listener *listener, void *data); void handle_output_manager_test(struct wl_listener *listener, void *data); diff --git a/sway/desktop/output.c b/sway/desktop/output.c index 7f5ec5f82..72f753b02 100644 --- a/sway/desktop/output.c +++ b/sway/desktop/output.c @@ -264,7 +264,6 @@ static int output_repaint_timer_handler(void *data) { .color_transform = output->color_transform, }; - struct wlr_output *wlr_output = output->wlr_output; struct wlr_scene_output *scene_output = output->scene_output; if (!wlr_scene_output_needs_frame(scene_output)) { return 0; @@ -276,22 +275,6 @@ static int output_repaint_timer_handler(void *data) { return 0; } - if (output->gamma_lut_changed) { - output->gamma_lut_changed = false; - struct wlr_gamma_control_v1 *gamma_control = - wlr_gamma_control_manager_v1_get_control( - server.gamma_control_manager_v1, output->wlr_output); - if (!wlr_gamma_control_v1_apply(gamma_control, &pending)) { - wlr_output_state_finish(&pending); - return 0; - } - - if (!wlr_output_test_state(output->wlr_output, &pending)) { - wlr_gamma_control_v1_send_failed_and_destroy(gamma_control); - wlr_output_state_set_gamma_lut(&pending, 0, NULL, NULL, NULL); - } - } - if (output_can_tear(output)) { pending.tearing_page_flip = true; @@ -472,11 +455,6 @@ static void handle_commit(struct wl_listener *listener, void *data) { update_output_manager_config(output->server); } - - // Next time the output is enabled, try to re-apply the gamma LUT - if ((event->state->committed & WLR_OUTPUT_STATE_ENABLED) && !output->wlr_output->enabled) { - output->gamma_lut_changed = true; - } } static void handle_present(struct wl_listener *listener, void *data) { @@ -585,21 +563,6 @@ void handle_output_layout_change(struct wl_listener *listener, update_output_manager_config(server); } -void handle_gamma_control_set_gamma(struct wl_listener *listener, void *data) { - struct sway_server *server = - wl_container_of(listener, server, gamma_control_set_gamma); - const struct wlr_gamma_control_manager_v1_set_gamma_event *event = data; - - struct sway_output *output = event->output->data; - - if(!output) { - return; - } - - output->gamma_lut_changed = true; - wlr_output_schedule_frame(output->wlr_output); -} - static struct output_config *output_config_for_config_head( struct wlr_output_configuration_head_v1 *config_head, struct sway_output *output) { diff --git a/sway/server.c b/sway/server.c index f89bd529b..1ca560869 100644 --- a/sway/server.c +++ b/sway/server.c @@ -272,9 +272,8 @@ bool server_init(struct sway_server *server) { server->gamma_control_manager_v1 = wlr_gamma_control_manager_v1_create(server->wl_display); - server->gamma_control_set_gamma.notify = handle_gamma_control_set_gamma; - wl_signal_add(&server->gamma_control_manager_v1->events.set_gamma, - &server->gamma_control_set_gamma); + wlr_scene_set_gamma_control_manager_v1(root->root_scene, + server->gamma_control_manager_v1); server->new_output.notify = handle_new_output; wl_signal_add(&server->backend->events.new_output, &server->new_output); From c30c4519079e804c35e71810875c10f48097d230 Mon Sep 17 00:00:00 2001 From: Kirill Primak Date: Wed, 14 Aug 2024 21:57:47 +0300 Subject: [PATCH 14/21] xdg-shell: chase xdg_surface geometry updates --- sway/desktop/xdg_shell.c | 21 ++++++++------------- 1 file changed, 8 insertions(+), 13 deletions(-) diff --git a/sway/desktop/xdg_shell.c b/sway/desktop/xdg_shell.c index fdfa7b652..3aed4ec7e 100644 --- a/sway/desktop/xdg_shell.c +++ b/sway/desktop/xdg_shell.c @@ -299,18 +299,17 @@ static void handle_commit(struct wl_listener *listener, void *data) { return; } - struct wlr_box new_geo; - wlr_xdg_surface_get_geometry(xdg_surface, &new_geo); - bool new_size = new_geo.width != view->geometry.width || - new_geo.height != view->geometry.height || - new_geo.x != view->geometry.x || - new_geo.y != view->geometry.y; + struct wlr_box *new_geo = &xdg_surface->geometry; + bool new_size = new_geo->width != view->geometry.width || + new_geo->height != view->geometry.height || + new_geo->x != view->geometry.x || + new_geo->y != view->geometry.y; if (new_size) { // The client changed its surface size in this commit. For floating // containers, we resize the container to match. For tiling containers, // we only recenter the surface. - memcpy(&view->geometry, &new_geo, sizeof(struct wlr_box)); + memcpy(&view->geometry, new_geo, sizeof(struct wlr_box)); if (container_is_floating(view->container)) { view_update_size(view); // Only set the toplevel size the current container actually has a size. @@ -463,12 +462,8 @@ static void handle_map(struct wl_listener *listener, void *data) { struct sway_view *view = &xdg_shell_view->view; struct wlr_xdg_toplevel *toplevel = view->wlr_xdg_toplevel; - view->natural_width = toplevel->base->current.geometry.width; - view->natural_height = toplevel->base->current.geometry.height; - if (!view->natural_width && !view->natural_height) { - view->natural_width = toplevel->base->surface->current.width; - view->natural_height = toplevel->base->surface->current.height; - } + view->natural_width = toplevel->base->geometry.width; + view->natural_height = toplevel->base->geometry.height; bool csd = false; From ae7c1b139a3c71d3e11fe2477d8b21c36de6770e Mon Sep 17 00:00:00 2001 From: Kenny Levinsen Date: Sun, 18 Aug 2024 14:50:48 +0200 Subject: [PATCH 15/21] config/output: Do not set adaptive_sync if not supported After 4e38f93f367d ("config/output: Skip VRR tests when not supported"), the configuration search no longer touches VRR state for outputs that are known to not support it. This also means that it will not remove VRR if already set, which could cause output configuration to fail. Ensure that VRR state is never set for outputs that do not support it by adding the same test for support to queue_output_config. Fixes: 4e38f93f367d ("config/output: Skip VRR tests when not supported") Fixes: https://github.com/swaywm/sway/issues/8296 --- sway/config/output.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sway/config/output.c b/sway/config/output.c index 1b378078e..cc3bf457f 100644 --- a/sway/config/output.c +++ b/sway/config/output.c @@ -491,7 +491,7 @@ static void queue_output_config(struct output_config *oc, wlr_output_state_set_scale(pending, scale); } - if (oc && oc->adaptive_sync != -1) { + if (oc && oc->adaptive_sync != -1 && wlr_output->adaptive_sync_supported) { sway_log(SWAY_DEBUG, "Set %s adaptive sync to %d", wlr_output->name, oc->adaptive_sync); wlr_output_state_set_adaptive_sync_enabled(pending, oc->adaptive_sync == 1); From f9c0f043e5ec39574c9d9b0fb3dece6169a0e67d Mon Sep 17 00:00:00 2001 From: Kenny Levinsen Date: Mon, 19 Aug 2024 13:02:55 +0200 Subject: [PATCH 16/21] config/output: Skip search if config has a mode When doing an output configuration search, the intent is to only look for modes if the output's configuration does not contain a specific mode. This was done by testing if config_has_auto_mode returned false. config_has_auto_mode had its return values backwards, leading to other modes being tested if the output configuration had specified modes or modelines, leading to unwanted modes being selected. Invert the function to config_has_manual_mode to give it a clearer name, and fix the return values in the process. --- sway/config/output.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/sway/config/output.c b/sway/config/output.c index cc3bf457f..d33ea11a9 100644 --- a/sway/config/output.c +++ b/sway/config/output.c @@ -651,9 +651,9 @@ struct output_config *find_output_config(struct sway_output *sway_output) { return result; } -static bool config_has_auto_mode(struct output_config *oc) { +static bool config_has_manual_mode(struct output_config *oc) { if (!oc) { - return true; + return false; } if (oc->drm_mode.type != 0 && oc->drm_mode.type != (uint32_t)-1) { return true; @@ -754,7 +754,8 @@ static bool search_mode(struct search_context *ctx, size_t output_idx) { struct wlr_output_state *state = &backend_state->base; struct wlr_output *wlr_output = backend_state->output; - if (!config_has_auto_mode(cfg->config)) { + // We only search for mode if one is not explicitly specified in the config + if (config_has_manual_mode(cfg->config)) { return search_adaptive_sync(ctx, output_idx); } From 7288f77bbe275825a0e0b011db873d9367782af0 Mon Sep 17 00:00:00 2001 From: Alexander Orzechowski Date: Wed, 21 Aug 2024 10:58:18 -0400 Subject: [PATCH 17/21] output: Chase wlroots!4803 --- sway/desktop/output.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sway/desktop/output.c b/sway/desktop/output.c index 72f753b02..a71430fe5 100644 --- a/sway/desktop/output.c +++ b/sway/desktop/output.c @@ -465,7 +465,7 @@ static void handle_present(struct wl_listener *listener, void *data) { return; } - output->last_presentation = *output_event->when; + output->last_presentation = output_event->when; output->refresh_nsec = output_event->refresh; } From f00f964abf0eae36a1cce03c532115319499e570 Mon Sep 17 00:00:00 2001 From: "Anna (navi) Figueiredo Gomes" Date: Sat, 29 Jun 2024 11:00:09 +0200 Subject: [PATCH 18/21] sway/commands/move.c: arrange new workspace When moving a container to a new workspace, the workspace's dimension are left unset. Usually this doesn't matter, but when moving a floating container to a new workspace on a different output, this leads to the position of the container being calculated with 0, so the container ends up halfway offscreen on the leftmost topmost monitor. Signed-off-by: Anna (navi) Figueiredo Gomes --- sway/commands/move.c | 1 + 1 file changed, 1 insertion(+) diff --git a/sway/commands/move.c b/sway/commands/move.c index ff656cfbd..ad106c648 100644 --- a/sway/commands/move.c +++ b/sway/commands/move.c @@ -510,6 +510,7 @@ static struct cmd_results *cmd_move_container(bool no_auto_back_and_forth, } } ws = workspace_create(NULL, ws_name); + arrange_workspace(ws); } free(ws_name); struct sway_container *dst = seat_get_focus_inactive_tiling(seat, ws); From 77b9ddabe2a97c5d04c30929b0f8cbde3470fdd7 Mon Sep 17 00:00:00 2001 From: llyyr Date: Fri, 23 Aug 2024 01:55:42 +0530 Subject: [PATCH 19/21] sway/tree/container: don't trunc coords in `floating_fix_coordinates` This can cause issues such as the window not being shown at the exact same coordinates when the old and new wlr_box aren't the same dimensions and the container is being moved back-and-forth between them. For example, in the case where a floating window gets moved from one output to another but the outputs aren't the same resolution. For e.g. have two displays that aren't the same resolution then: 1. Open a floating window and set it to pos 0,0 on output 2 2. Send it to scratchpad then `scratchpad show` on output 1 3. `scratchpad show` on output 2 again Observe that the window isn't at 0,0 on output 2 anymore. --- sway/tree/container.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/sway/tree/container.c b/sway/tree/container.c index 80ef34fe9..46c388b3e 100644 --- a/sway/tree/container.c +++ b/sway/tree/container.c @@ -773,11 +773,11 @@ void floating_fix_coordinates(struct sway_container *con, struct wlr_box *old, s // Fall back to centering on the workspace. container_floating_move_to_center(con); } else { - int rel_x = con->pending.x - old->x + (con->pending.width / 2); - int rel_y = con->pending.y - old->y + (con->pending.height / 2); + double rel_x = con->pending.x - old->x + (con->pending.width / 2); + double rel_y = con->pending.y - old->y + (con->pending.height / 2); - con->pending.x = new->x + (double)(rel_x * new->width) / old->width - (con->pending.width / 2); - con->pending.y = new->y + (double)(rel_y * new->height) / old->height - (con->pending.height / 2); + con->pending.x = new->x + (rel_x * new->width) / old->width - (con->pending.width / 2); + con->pending.y = new->y + (rel_y * new->height) / old->height - (con->pending.height / 2); sway_log(SWAY_DEBUG, "Transformed container %p to coords (%f, %f)", con, con->pending.x, con->pending.y); } From f2b2a8114900060f667d7ddd55ef9f8a1e74c1b4 Mon Sep 17 00:00:00 2001 From: Jon Wallace Date: Mon, 26 Aug 2024 22:15:55 -0700 Subject: [PATCH 20/21] Use heading markdown to demarcate sections of commands Its a little tought to notice that the COMMANDS section is actually 3 sections. Use markdown to make this easier to see for the user. --- sway/sway.5.scd | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/sway/sway.5.scd b/sway/sway.5.scd index 0b36a7572..c867c5f7d 100644 --- a/sway/sway.5.scd +++ b/sway/sway.5.scd @@ -52,7 +52,7 @@ Throughout the documentation, *|* is used to distinguish between arguments for which you may only select one. *[...]* is used for optional arguments, and *<...>* for arguments where you are expected to supply some value. -# COMMANDS +# COMMANDS - CONFIG ONLY This section only lists general commands. For input and output commands, refer to *sway-input*(5) and *sway-output*(5). @@ -98,6 +98,8 @@ The following commands may only be used in the configuration file. machines, it may be desirable to have Xwayland started immediately by using _force_ instead of _enable_. +# COMMANDS - RUNTIME ONLY + The following commands cannot be used directly in the configuration file. They are expected to be used with *bindsym* or at runtime through *swaymsg*(1). @@ -385,6 +387,8 @@ set|plus|minus|toggle The default format is "%title". +# COMMANDS - CONFIG OR RUNTIME + The following commands may be used either in the configuration file or at runtime. From 980a4e02113789d0cca94aa023557c6f6e87ec73 Mon Sep 17 00:00:00 2001 From: Jon Wallace Date: Tue, 27 Aug 2024 10:42:58 -0700 Subject: [PATCH 21/21] use subheadings instead --- sway/sway.5.scd | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/sway/sway.5.scd b/sway/sway.5.scd index c867c5f7d..bb958ebfd 100644 --- a/sway/sway.5.scd +++ b/sway/sway.5.scd @@ -52,11 +52,12 @@ Throughout the documentation, *|* is used to distinguish between arguments for which you may only select one. *[...]* is used for optional arguments, and *<...>* for arguments where you are expected to supply some value. -# COMMANDS - CONFIG ONLY +# COMMANDS This section only lists general commands. For input and output commands, refer to *sway-input*(5) and *sway-output*(5). +## Config only commands The following commands may only be used in the configuration file. *bar* [] @@ -98,8 +99,7 @@ The following commands may only be used in the configuration file. machines, it may be desirable to have Xwayland started immediately by using _force_ instead of _enable_. -# COMMANDS - RUNTIME ONLY - +## Runtime only commands The following commands cannot be used directly in the configuration file. They are expected to be used with *bindsym* or at runtime through *swaymsg*(1). @@ -387,8 +387,7 @@ set|plus|minus|toggle The default format is "%title". -# COMMANDS - CONFIG OR RUNTIME - +## Config or runtime commands The following commands may be used either in the configuration file or at runtime.