From 8fecf3aa8c0cdff23a75a5f20b4a3423a43e9bc5 Mon Sep 17 00:00:00 2001 From: alex-huff Date: Fri, 9 May 2025 14:35:30 -0500 Subject: [PATCH 01/11] transaction: reparent scenes of containers behind fullscreen containers Currently we do a good job of reparenting the scenes of a container when it moves into a disabled workspace. We need to do this since normally the scenes are reparented in the 'arrange_{children,container}' functions but these don't get called for disabled workspaces. However, the 'arrange_{children,container}' functions also don't get called when there is a fullscreen container hiding them. This commit makes sure to call 'disable_workspace' on workspaces with a fullscreen container so that when a container is moved into the workspace its scenes will be properly reparented. Also, when there is a fullscreen global container 'disable_workspace' is called for all workspaces since the scenes of a previously fullscreen global container may still be parented in the 'fullscreen_global' layer. Fixes #8705 #8659 #8432 --- sway/desktop/transaction.c | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/sway/desktop/transaction.c b/sway/desktop/transaction.c index f8bc64b5..7ec9b68d 100644 --- a/sway/desktop/transaction.c +++ b/sway/desktop/transaction.c @@ -587,13 +587,13 @@ static void arrange_output(struct sway_output *output, int width, int height) { wlr_scene_node_set_enabled(&child->layers.tiling->node, !fs); wlr_scene_node_set_enabled(&child->layers.fullscreen->node, fs); - arrange_workspace_floating(child); - wlr_scene_node_set_enabled(&output->layers.shell_background->node, !fs); wlr_scene_node_set_enabled(&output->layers.shell_bottom->node, !fs); wlr_scene_node_set_enabled(&output->layers.fullscreen->node, fs); if (fs) { + disable_workspace(child); + wlr_scene_rect_set_size(output->fullscreen_background, width, height); arrange_fullscreen(child->layers.fullscreen, fs, child, @@ -609,6 +609,8 @@ static void arrange_output(struct sway_output *output, int width, int height) { area->width - gaps->left - gaps->right, area->height - gaps->top - gaps->bottom); } + + arrange_workspace_floating(child); } else { wlr_scene_node_set_enabled(&child->layers.tiling->node, false); wlr_scene_node_set_enabled(&child->layers.fullscreen->node, false); @@ -665,6 +667,13 @@ static void arrange_root(struct sway_root *root) { wlr_scene_output_set_position(output->scene_output, output->lx, output->ly); + // disable all workspaces to get to a known state + for (int j = 0; j < output->current.workspaces->length; j++) { + struct sway_workspace *workspace = output->current.workspaces->items[j]; + disable_workspace(workspace); + } + + // arrange the active workspace if (ws) { arrange_workspace_floating(ws); } From 5cfcd1c7c2ee1e0a199fd5d62b1da962f2102a85 Mon Sep 17 00:00:00 2001 From: Simon Ser Date: Mon, 19 May 2025 18:25:16 +0200 Subject: [PATCH 02/11] input: fix udev_device leak libinput_device_get_udev_device() returns a ref'ed handle: https://wayland.freedesktop.org/libinput/doc/latest/api/group__device.html#gac13c64ba19fc19094cff0e5354a2a7ce Similar to this wlroots MR: https://gitlab.freedesktop.org/wlroots/wlroots/-/merge_requests/5074 --- sway/input/libinput.c | 26 ++++++++++++++++---------- 1 file changed, 16 insertions(+), 10 deletions(-) diff --git a/sway/input/libinput.c b/sway/input/libinput.c index f76c6505..b98c4cc8 100644 --- a/sway/input/libinput.c +++ b/sway/input/libinput.c @@ -399,6 +399,19 @@ void sway_input_reset_libinput_device(struct sway_input_device *input_device) { } } +static bool sway_udev_device_is_builtin(struct udev_device *udev_device) { + const char *id_path = udev_device_get_property_value(udev_device, "ID_PATH"); + if (!id_path) { + return false; + } + + if (has_prefix(id_path, "platform-")) { + return true; + } + + return has_prefix(id_path, "pci-") && strstr(id_path, "-platform-"); +} + bool sway_libinput_device_is_builtin(struct sway_input_device *sway_device) { if (!wlr_input_device_is_libinput(sway_device->wlr_device)) { return false; @@ -412,14 +425,7 @@ bool sway_libinput_device_is_builtin(struct sway_input_device *sway_device) { return false; } - const char *id_path = udev_device_get_property_value(udev_device, "ID_PATH"); - if (!id_path) { - return false; - } - - if (has_prefix(id_path, "platform-")) { - return true; - } - - return has_prefix(id_path, "pci-") && strstr(id_path, "-platform-"); + bool is_builtin = sway_udev_device_is_builtin(udev_device); + udev_device_unref(udev_device); + return is_builtin; } From 1b47277962fa04624a0b6835e81089110d258e7c Mon Sep 17 00:00:00 2001 From: alex-huff Date: Wed, 21 May 2025 18:47:10 -0500 Subject: [PATCH 03/11] layer-shell: reclaim space from unmapped layer surfaces wlroots resets 'initialized' when a layer surface is unmapped and sway doesn't rearrange the layer surfaces in response to a commit of a surface where 'initialized' is false. This results in space not getting reclaimed from a recently unmapped layer surface until some other action causes 'arrange_layers' to get called. This commit makes sure all layer surfaces get rearranged when a layer surface is unmapped. --- sway/desktop/layer_shell.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/sway/desktop/layer_shell.c b/sway/desktop/layer_shell.c index b14a9a4b..08b5b1de 100644 --- a/sway/desktop/layer_shell.c +++ b/sway/desktop/layer_shell.c @@ -269,12 +269,8 @@ static void handle_surface_commit(struct wl_listener *listener, void *data) { wl_container_of(listener, surface, surface_commit); struct wlr_layer_surface_v1 *layer_surface = surface->layer_surface; - if (!layer_surface->initialized) { - return; - } - uint32_t committed = layer_surface->current.committed; - if (committed & WLR_LAYER_SURFACE_V1_STATE_LAYER) { + if (layer_surface->initialized && committed & WLR_LAYER_SURFACE_V1_STATE_LAYER) { enum zwlr_layer_shell_v1_layer layer_type = layer_surface->current.layer; struct wlr_scene_tree *output_layer = sway_layer_get_scene( surface->output, layer_type); From 88c7b4a7ebe281ee771e3a1bfd8968046918a01a Mon Sep 17 00:00:00 2001 From: alex-huff Date: Wed, 21 May 2025 20:31:46 -0500 Subject: [PATCH 04/11] transaction: fix floating fullscreen containers 8fecf3a introduced a regression where fullscreening a child of a floating container would result in a black screen. This is because the order of 'arrange_fullscreen' and 'arrange_worksplace_floating' was swapped causing the fullscreen container's scene to get reparented after it was parented in the fullscreen layer. Fixes #8729 --- sway/desktop/transaction.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sway/desktop/transaction.c b/sway/desktop/transaction.c index 7ec9b68d..325a3022 100644 --- a/sway/desktop/transaction.c +++ b/sway/desktop/transaction.c @@ -596,6 +596,7 @@ static void arrange_output(struct sway_output *output, int width, int height) { wlr_scene_rect_set_size(output->fullscreen_background, width, height); + arrange_workspace_floating(child); arrange_fullscreen(child->layers.fullscreen, fs, child, width, height); } else { @@ -608,9 +609,8 @@ static void arrange_output(struct sway_output *output, int width, int height) { arrange_workspace_tiling(child, area->width - gaps->left - gaps->right, area->height - gaps->top - gaps->bottom); + arrange_workspace_floating(child); } - - arrange_workspace_floating(child); } else { wlr_scene_node_set_enabled(&child->layers.tiling->node, false); wlr_scene_node_set_enabled(&child->layers.fullscreen->node, false); From 005924f2609029612d4468c3436a816a48991246 Mon Sep 17 00:00:00 2001 From: Kenny Levinsen Date: Tue, 6 May 2025 01:35:05 +0200 Subject: [PATCH 05/11] output: Minimize interaction with output after destroy When an output is destroyed, we go through the process of disabling it. This includes evacuating all content away from the output, which can lead to various modifications to the scene. With the scene_output still present, this can lead to things like output_enter events being emitted for the output currently being destroyed. Ensure that the scene output is destroyed first and that the output is immediately considered disabled. References: https://gitlab.freedesktop.org/wlroots/wlroots/-/issues/3974 --- sway/desktop/output.c | 16 +++++++++------- sway/tree/output.c | 13 ++++++------- 2 files changed, 15 insertions(+), 14 deletions(-) diff --git a/sway/desktop/output.c b/sway/desktop/output.c index aec1d0a6..e6fe2ee4 100644 --- a/sway/desktop/output.c +++ b/sway/desktop/output.c @@ -422,13 +422,6 @@ void force_modeset(void) { } static void begin_destroy(struct sway_output *output) { - if (output->enabled) { - output_disable(output); - } - - output_begin_destroy(output); - - wl_list_remove(&output->link); wl_list_remove(&output->layout_destroy.link); wl_list_remove(&output->destroy.link); @@ -436,8 +429,17 @@ static void begin_destroy(struct sway_output *output) { wl_list_remove(&output->frame.link); wl_list_remove(&output->request_state.link); + // Remove the scene_output first to ensure that the scene does not emit + // events for this output. wlr_scene_output_destroy(output->scene_output); output->scene_output = NULL; + + if (output->enabled) { + output_disable(output); + } + output_begin_destroy(output); + wl_list_remove(&output->link); + output->wlr_output->data = NULL; output->wlr_output = NULL; diff --git a/sway/tree/output.c b/sway/tree/output.c index 65d9e3e7..bc380629 100644 --- a/sway/tree/output.c +++ b/sway/tree/output.c @@ -205,11 +205,8 @@ static void output_evacuate(struct sway_output *output) { return; } struct sway_output *fallback_output = NULL; - if (root->outputs->length > 1) { + if (root->outputs->length > 0) { fallback_output = root->outputs->items[0]; - if (fallback_output == output) { - fallback_output = root->outputs->items[1]; - } } while (output->workspaces->length) { @@ -289,11 +286,13 @@ void output_disable(struct sway_output *output) { sway_log(SWAY_DEBUG, "Disabling output '%s'", output->wlr_output->name); wl_signal_emit_mutable(&output->events.disable, output); - output_evacuate(output); - + // Remove the output now to avoid interacting with it during e.g., + // transactions, as the output might be physically removed with the scene + // output destroyed. list_del(root->outputs, index); - output->enabled = false; + + output_evacuate(output); } void output_begin_destroy(struct sway_output *output) { From 534491d3aa0c60d5c941f2f46b5d7f8978901f84 Mon Sep 17 00:00:00 2001 From: Kenny Levinsen Date: Tue, 6 May 2025 11:46:35 +0200 Subject: [PATCH 06/11] tree/workspace: Remove exclude arg from get_highest_available workspace_output_get_highest_available took an output to exclude as argument, meant to avoid accidentally reselecting an output we are evacuating workspaces from. Outputs are now removed from the list before we evacuate, making exclusion unnecessary. Remove the argument. --- include/sway/tree/workspace.h | 2 +- sway/tree/output.c | 4 ++-- sway/tree/workspace.c | 6 +----- 3 files changed, 4 insertions(+), 8 deletions(-) diff --git a/include/sway/tree/workspace.h b/include/sway/tree/workspace.h index 58bde20c..27ed649f 100644 --- a/include/sway/tree/workspace.h +++ b/include/sway/tree/workspace.h @@ -96,7 +96,7 @@ void workspace_output_add_priority(struct sway_workspace *workspace, struct sway_output *output); struct sway_output *workspace_output_get_highest_available( - struct sway_workspace *ws, struct sway_output *exclude); + struct sway_workspace *ws); void workspace_detect_urgent(struct sway_workspace *workspace); diff --git a/sway/tree/output.c b/sway/tree/output.c index bc380629..b02c1a2c 100644 --- a/sway/tree/output.c +++ b/sway/tree/output.c @@ -37,7 +37,7 @@ static void restore_workspaces(struct sway_output *output) { for (int j = 0; j < other->workspaces->length; j++) { struct sway_workspace *ws = other->workspaces->items[j]; struct sway_output *highest = - workspace_output_get_highest_available(ws, NULL); + workspace_output_get_highest_available(ws); if (highest == output) { workspace_detach(ws); output_add_workspace(output, ws); @@ -215,7 +215,7 @@ static void output_evacuate(struct sway_output *output) { workspace_detach(workspace); struct sway_output *new_output = - workspace_output_get_highest_available(workspace, output); + workspace_output_get_highest_available(workspace); if (!new_output) { new_output = fallback_output; } diff --git a/sway/tree/workspace.c b/sway/tree/workspace.c index a09dc3a4..f2be4cd1 100644 --- a/sway/tree/workspace.c +++ b/sway/tree/workspace.c @@ -659,13 +659,9 @@ void workspace_output_add_priority(struct sway_workspace *workspace, } struct sway_output *workspace_output_get_highest_available( - struct sway_workspace *ws, struct sway_output *exclude) { + struct sway_workspace *ws) { for (int i = 0; i < ws->output_priority->length; i++) { const char *name = ws->output_priority->items[i]; - if (exclude && output_match_name_or_id(exclude, name)) { - continue; - } - struct sway_output *output = output_by_name_or_id(name); if (output) { return output; From 45267bb576559ac583daa4c73c64baef1d4f5ef3 Mon Sep 17 00:00:00 2001 From: Bonsaiiv Date: Sat, 24 May 2025 16:03:45 +0200 Subject: [PATCH 07/11] Improve example of input section in default config Previous example included a specific device name. This can be confusing for beginners, as the default did not work on most devices. --- config.in | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/config.in b/config.in index a2a01dda..872ef057 100644 --- a/config.in +++ b/config.in @@ -46,14 +46,18 @@ output * bg @datadir@/backgrounds/sway/Sway_Wallpaper_Blue_1920x1080.png fill # # Example configuration: # -# input "2:14:SynPS/2_Synaptics_TouchPad" { +# input type:touchpad { # dwt enabled # tap enabled # natural_scroll enabled # middle_emulation enabled # } # -# You can get the names of your inputs by running: swaymsg -t get_inputs +# input type:keyboard { +# xkb_layout "eu" +# } +# +# You can also configure each device individually. # Read `man 5 sway-input` for more information about this section. ### Key bindings From 63689bfb830b68eba8062aedef9928c55713c9bc Mon Sep 17 00:00:00 2001 From: Simon Ser Date: Sun, 27 Apr 2025 22:11:41 +0200 Subject: [PATCH 08/11] Log message on for_window command error --- sway/tree/view.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/sway/tree/view.c b/sway/tree/view.c index 16080a2f..9a5cf06e 100644 --- a/sway/tree/view.c +++ b/sway/tree/view.c @@ -517,10 +517,12 @@ void view_execute_criteria(struct sway_view *view) { sway_log(SWAY_DEBUG, "for_window '%s' matches view %p, cmd: '%s'", criteria->raw, view, criteria->cmdlist); list_add(view->executed_criteria, criteria); - list_t *res_list = execute_command( - criteria->cmdlist, NULL, view->container); + list_t *res_list = execute_command(criteria->cmdlist, NULL, view->container); while (res_list->length) { struct cmd_results *res = res_list->items[0]; + if (res->status != CMD_SUCCESS) { + sway_log(SWAY_ERROR, "for_window '%s' failed: %s", criteria->raw, res->error); + } free_cmd_results(res); list_del(res_list, 0); } From 7e7994dbb2a2c04f55b3c74eb61577c51e9a43ae Mon Sep 17 00:00:00 2001 From: Konstantin Pospelov Date: Thu, 27 Mar 2025 20:11:59 +0100 Subject: [PATCH 09/11] swaybar: deduplicate mode and workspace rendering code The render_workspace_button and render_binding_mode_indicator functions are almost the same. This commit extracts the common rendering code into a new render_box function. --- include/swaybar/config.h | 5 ++ swaybar/render.c | 169 ++++++++++++++++----------------------- 2 files changed, 73 insertions(+), 101 deletions(-) diff --git a/include/swaybar/config.h b/include/swaybar/config.h index 361acd99..ad58b3c3 100644 --- a/include/swaybar/config.h +++ b/include/swaybar/config.h @@ -14,6 +14,11 @@ struct box_colors { uint32_t text; }; +struct box_size { + uint32_t width; + uint32_t height; +}; + struct config_output { struct wl_list link; // swaybar_config::outputs char *name; diff --git a/swaybar/render.c b/swaybar/render.c index 45faefa9..c51321f1 100644 --- a/swaybar/render.c +++ b/swaybar/render.c @@ -13,7 +13,6 @@ #include "swaybar/ipc.h" #include "swaybar/render.h" #include "swaybar/status_line.h" -#include "log.h" #if HAVE_TRAY #include "swaybar/tray/tray.h" #endif @@ -21,7 +20,7 @@ static const int WS_HORIZONTAL_PADDING = 5; static const double WS_VERTICAL_PADDING = 1.5; -static const double BORDER_WIDTH = 1; +static const int BORDER_WIDTH = 1; struct render_context { cairo_t *cairo; @@ -541,6 +540,63 @@ static uint32_t render_status_line(struct render_context *ctx, double *x) { return 0; } +static struct box_size render_box(struct render_context *ctx, double x, + struct box_colors colors, const char *label, bool pango_markup) { + struct swaybar_output *output = ctx->output; + struct swaybar_config *config = output->bar->config; + cairo_t *cairo = ctx->cairo; + + int text_width, text_height; + get_text_size(cairo, config->font_description, &text_width, &text_height, NULL, + 1, pango_markup, "%s", label); + + uint32_t width = text_width + WS_HORIZONTAL_PADDING * 2 + BORDER_WIDTH * 2; + if (width < config->workspace_min_width) { + width = config->workspace_min_width; + } + + uint32_t ideal_height = text_height + WS_VERTICAL_PADDING * 2 + + BORDER_WIDTH * 2; + uint32_t ideal_surface_height = ideal_height; + if (!output->bar->config->height && + output->height < ideal_surface_height) { + return (struct box_size) { + .width = width, + .height = ideal_surface_height, + }; + } + + uint32_t height = output->height; + cairo_set_operator(cairo, CAIRO_OPERATOR_SOURCE); + cairo_set_source_u32(cairo, colors.background); + ctx->background_color = colors.background; + ctx->has_transparency |= (colors.background & 0xFF) != 0xFF; + cairo_rectangle(cairo, x, 0, width, height); + cairo_fill(cairo); + + cairo_set_source_u32(cairo, colors.border); + cairo_rectangle(cairo, x, 0, width, BORDER_WIDTH); + cairo_fill(cairo); + cairo_rectangle(cairo, x, 0, BORDER_WIDTH, height); + cairo_fill(cairo); + cairo_rectangle(cairo, x + width - BORDER_WIDTH, 0, BORDER_WIDTH, height); + cairo_fill(cairo); + cairo_rectangle(cairo, x, height - BORDER_WIDTH, width, BORDER_WIDTH); + cairo_fill(cairo); + + double text_y = height / 2.0 - text_height / 2.0; + cairo_set_source_u32(cairo, colors.text); + cairo_move_to(cairo, x + width / 2 - text_width / 2, (int)floor(text_y)); + choose_text_aa_mode(ctx, colors.text); + render_text(cairo, config->font_description, 1, pango_markup, + "%s", label); + + return (struct box_size) { + .width = width, + .height = output->height, + }; +} + static uint32_t render_binding_mode_indicator(struct render_context *ctx, double x) { struct swaybar_output *output = ctx->output; @@ -549,54 +605,9 @@ static uint32_t render_binding_mode_indicator(struct render_context *ctx, return 0; } - cairo_t *cairo = ctx->cairo; - struct swaybar_config *config = output->bar->config; - int text_width, text_height; - get_text_size(cairo, config->font_description, &text_width, &text_height, NULL, - 1, output->bar->mode_pango_markup, - "%s", mode); - - int ws_vertical_padding = WS_VERTICAL_PADDING; - int ws_horizontal_padding = WS_HORIZONTAL_PADDING; - int border_width = BORDER_WIDTH; - - uint32_t ideal_height = text_height + ws_vertical_padding * 2 - + border_width * 2; - uint32_t ideal_surface_height = ideal_height; - if (!output->bar->config->height && - output->height < ideal_surface_height) { - return ideal_surface_height; - } - uint32_t width = text_width + ws_horizontal_padding * 2 + border_width * 2; - if (width < config->workspace_min_width) { - width = config->workspace_min_width; - } - - uint32_t height = output->height; - cairo_set_operator(cairo, CAIRO_OPERATOR_SOURCE); - cairo_set_source_u32(cairo, config->colors.binding_mode.background); - ctx->background_color = config->colors.binding_mode.background; - ctx->has_transparency |= (config->colors.binding_mode.background & 0xFF) != 0xFF; - cairo_rectangle(cairo, x, 0, width, height); - cairo_fill(cairo); - - cairo_set_source_u32(cairo, config->colors.binding_mode.border); - cairo_rectangle(cairo, x, 0, width, border_width); - cairo_fill(cairo); - cairo_rectangle(cairo, x, 0, border_width, height); - cairo_fill(cairo); - cairo_rectangle(cairo, x + width - border_width, 0, border_width, height); - cairo_fill(cairo); - cairo_rectangle(cairo, x, height - border_width, width, border_width); - cairo_fill(cairo); - - double text_y = height / 2.0 - text_height / 2.0; - cairo_set_source_u32(cairo, config->colors.binding_mode.text); - cairo_move_to(cairo, x + width / 2 - text_width / 2, (int)floor(text_y)); - choose_text_aa_mode(ctx, config->colors.binding_mode.text); - render_text(cairo, config->font_description, 1, output->bar->mode_pango_markup, - "%s", mode); - return output->height; + struct box_size size = render_box(ctx, x, output->bar->config->colors.binding_mode, + mode, output->bar->mode_pango_markup); + return size.height; } static enum hotspot_event_handling workspace_hotspot_callback( @@ -618,6 +629,7 @@ static uint32_t render_workspace_button(struct render_context *ctx, struct swaybar_workspace *ws, double *x) { struct swaybar_output *output = ctx->output; struct swaybar_config *config = output->bar->config; + struct box_colors box_colors; if (ws->urgent) { box_colors = config->colors.urgent_workspace; @@ -629,66 +641,21 @@ static uint32_t render_workspace_button(struct render_context *ctx, box_colors = config->colors.inactive_workspace; } - uint32_t height = output->height; - - cairo_t *cairo = ctx->cairo; - int text_width, text_height; - get_text_size(cairo, config->font_description, &text_width, &text_height, NULL, - 1, config->pango_markup, "%s", ws->label); - - int ws_vertical_padding = WS_VERTICAL_PADDING; - int ws_horizontal_padding = WS_HORIZONTAL_PADDING; - int border_width = BORDER_WIDTH; - - uint32_t ideal_height = ws_vertical_padding * 2 + text_height - + border_width * 2; - uint32_t ideal_surface_height = ideal_height; - if (!output->bar->config->height && - output->height < ideal_surface_height) { - return ideal_surface_height; - } - - uint32_t width = text_width + ws_horizontal_padding * 2 + border_width * 2; - if (width < config->workspace_min_width) { - width = config->workspace_min_width; - } - - cairo_set_operator(cairo, CAIRO_OPERATOR_SOURCE); - cairo_set_source_u32(cairo, box_colors.background); - ctx->background_color = box_colors.background; - ctx->has_transparency |= (box_colors.background & 0xFF) != 0xFF; - cairo_rectangle(cairo, *x, 0, width, height); - cairo_fill(cairo); - - cairo_set_source_u32(cairo, box_colors.border); - cairo_rectangle(cairo, *x, 0, width, border_width); - cairo_fill(cairo); - cairo_rectangle(cairo, *x, 0, border_width, height); - cairo_fill(cairo); - cairo_rectangle(cairo, *x + width - border_width, 0, border_width, height); - cairo_fill(cairo); - cairo_rectangle(cairo, *x, height - border_width, width, border_width); - cairo_fill(cairo); - - double text_y = height / 2.0 - text_height / 2.0; - cairo_set_source_u32(cairo, box_colors.text); - cairo_move_to(cairo, *x + width / 2 - text_width / 2, (int)floor(text_y)); - choose_text_aa_mode(ctx, box_colors.text); - render_text(cairo, config->font_description, 1, config->pango_markup, - "%s", ws->label); + struct box_size size = render_box(ctx, *x, box_colors, + ws->label, config->pango_markup); struct swaybar_hotspot *hotspot = calloc(1, sizeof(struct swaybar_hotspot)); hotspot->x = *x; hotspot->y = 0; - hotspot->width = width; - hotspot->height = height; + hotspot->width = size.width; + hotspot->height = size.height; hotspot->callback = workspace_hotspot_callback; hotspot->destroy = free; hotspot->data = strdup(ws->name); wl_list_insert(&output->hotspots, &hotspot->link); - *x += width; - return output->height; + *x += size.width; + return size.height; } static uint32_t render_to_cairo(struct render_context *ctx) { From 9fb9e9f7d555ae7504b8ae53250020797d70e887 Mon Sep 17 00:00:00 2001 From: YaoBing Xiao Date: Thu, 5 Jun 2025 13:46:06 +0800 Subject: [PATCH 10/11] server: fix socket path memory leak The socket path allocated with strdup() in server_init() was not being freed in server_fini(). Remove const qualifier and add proper cleanup. --- include/sway/server.h | 2 +- sway/server.c | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/include/sway/server.h b/include/sway/server.h index e7d7094f..1cb72e77 100644 --- a/include/sway/server.h +++ b/include/sway/server.h @@ -27,7 +27,7 @@ struct sway_session_lock { struct sway_server { struct wl_display *wl_display; struct wl_event_loop *wl_event_loop; - const char *socket; + char *socket; struct wlr_backend *backend; struct wlr_session *session; diff --git a/sway/server.c b/sway/server.c index 97976148..e8a6ce64 100644 --- a/sway/server.c +++ b/sway/server.c @@ -502,6 +502,7 @@ void server_fini(struct sway_server *server) { wlr_backend_destroy(server->backend); wl_display_destroy(server->wl_display); list_free(server->dirty_nodes); + free(server->socket); } bool server_start(struct sway_server *server) { From 6816b51c86846afc5eaa1dea2541410058347a6e Mon Sep 17 00:00:00 2001 From: Simon Ser Date: Thu, 5 Jun 2025 18:15:56 +0200 Subject: [PATCH 11/11] Remove trailing spaces --- include/sway/server.h | 2 +- include/sway/tree/container.h | 2 +- sway/commands/ws_auto_back_and_forth.c | 2 +- sway/input/keyboard.c | 4 ++-- sway/input/seatop_default.c | 2 +- sway/sway-output.5.scd | 6 +++--- sway/sway.5.scd | 4 ++-- 7 files changed, 11 insertions(+), 11 deletions(-) diff --git a/include/sway/server.h b/include/sway/server.h index 1cb72e77..8e859702 100644 --- a/include/sway/server.h +++ b/include/sway/server.h @@ -117,7 +117,7 @@ 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 diff --git a/include/sway/tree/container.h b/include/sway/tree/container.h index 4fb2d720..e18fd00a 100644 --- a/include/sway/tree/container.h +++ b/include/sway/tree/container.h @@ -103,7 +103,7 @@ struct sway_container { char *title; // The view's title (unformatted) char *formatted_title; // The title displayed in the title bar int title_width; - + char *title_format; enum sway_container_layout prev_split_layout; diff --git a/sway/commands/ws_auto_back_and_forth.c b/sway/commands/ws_auto_back_and_forth.c index e4411c8e..5827c389 100644 --- a/sway/commands/ws_auto_back_and_forth.c +++ b/sway/commands/ws_auto_back_and_forth.c @@ -8,7 +8,7 @@ struct cmd_results *cmd_ws_auto_back_and_forth(int argc, char **argv) { if ((error = checkarg(argc, "workspace_auto_back_and_forth", EXPECTED_EQUAL_TO, 1))) { return error; } - config->auto_back_and_forth = + config->auto_back_and_forth = parse_boolean(argv[0], config->auto_back_and_forth); return cmd_results_new(CMD_SUCCESS, NULL); } diff --git a/sway/input/keyboard.c b/sway/input/keyboard.c index 651c44c5..d1823737 100644 --- a/sway/input/keyboard.c +++ b/sway/input/keyboard.c @@ -980,10 +980,10 @@ static void sway_keyboard_group_add(struct sway_keyboard *keyboard) { wl_signal_add(&sway_group->wlr_group->keyboard.events.modifiers, &sway_group->keyboard_modifiers); sway_group->keyboard_modifiers.notify = handle_keyboard_group_modifiers; - + wl_signal_add(&sway_group->wlr_group->events.enter, &sway_group->enter); sway_group->enter.notify = handle_keyboard_group_enter; - + wl_signal_add(&sway_group->wlr_group->events.leave, &sway_group->leave); sway_group->leave.notify = handle_keyboard_group_leave; return; diff --git a/sway/input/seatop_default.c b/sway/input/seatop_default.c index 6a7dddd9..a2e99d2b 100644 --- a/sway/input/seatop_default.c +++ b/sway/input/seatop_default.c @@ -793,7 +793,7 @@ static void handle_pointer_axis(struct sway_seat *seat, if (!handled) { wlr_seat_pointer_notify_axis(cursor->seat->wlr_seat, event->time_msec, - event->orientation, scroll_factor * event->delta, + event->orientation, scroll_factor * event->delta, roundf(scroll_factor * event->delta_discrete), event->source, event->relative_direction); } diff --git a/sway/sway-output.5.scd b/sway/sway-output.5.scd index dc16c257..dfe0d678 100644 --- a/sway/sway-output.5.scd +++ b/sway/sway-output.5.scd @@ -196,9 +196,9 @@ must be separated by one space. For example: 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). - + 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 diff --git a/sway/sway.5.scd b/sway/sway.5.scd index 9bc03c9d..dbdf1f1a 100644 --- a/sway/sway.5.scd +++ b/sway/sway.5.scd @@ -228,8 +228,8 @@ set|plus|minus|toggle 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. + 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_