Merge branch 'master' into tray-dbus-menu

This commit is contained in:
RogueAI 2025-06-09 10:34:44 +02:00 committed by GitHub
commit a262ad1fb6
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
19 changed files with 143 additions and 156 deletions

View file

@ -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

View file

@ -43,7 +43,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;
@ -133,7 +133,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

View file

@ -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;

View file

@ -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);

View file

@ -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;

View file

@ -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);
}

View file

@ -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);

View file

@ -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;

View file

@ -587,15 +587,16 @@ 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_workspace_floating(child);
arrange_fullscreen(child->layers.fullscreen, fs, child,
width, height);
} else {
@ -608,6 +609,7 @@ 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);
}
} else {
wlr_scene_node_set_enabled(&child->layers.tiling->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);
}

View file

@ -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;

View file

@ -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;
}

View file

@ -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);
}

View file

@ -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) {

View file

@ -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

View file

@ -228,8 +228,8 @@ set|plus|minus|toggle <amount>
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> px]
Moves the focused container in the direction specified. The optional _px_

View file

@ -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);
@ -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) {
@ -218,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;
}
@ -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) {

View file

@ -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);
}

View file

@ -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;

View file

@ -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;
@ -542,6 +541,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;
@ -550,54 +606,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(
@ -620,6 +631,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;
@ -631,66 +643,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) {