Merge branch 'master' into document-headless-output-manpage

This commit is contained in:
Sooraj S 2023-05-01 19:33:44 +05:30 committed by GitHub
commit da862448f9
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
52 changed files with 327 additions and 314 deletions

1
.mailmap Normal file
View file

@ -0,0 +1 @@
Ronan Pigott <ronan@rjp.ie> <rpigott@berkeley.edu>

View file

@ -12,23 +12,6 @@
const uint8_t GESTURE_FINGERS_ANY = 0;
// Helper to easily allocate and format string
static char *strformat(const char *format, ...) {
va_list args;
va_start(args, format);
int length = vsnprintf(NULL, 0, format, args) + 1;
va_end(args);
char *result = malloc(length);
if (result) {
va_start(args, format);
vsnprintf(result, length, format, args);
va_end(args);
}
return result;
}
char *gesture_parse(const char *input, struct gesture *output) {
// Clear output in case of failure
output->type = GESTURE_TYPE_NONE;
@ -38,7 +21,7 @@ char *gesture_parse(const char *input, struct gesture *output) {
// Split input type, fingers and directions
list_t *split = split_string(input, ":");
if (split->length < 1 || split->length > 3) {
return strformat(
return format_str(
"expected <gesture>[:<fingers>][:direction], got %s",
input);
}
@ -51,8 +34,8 @@ char *gesture_parse(const char *input, struct gesture *output) {
} else if (strcmp(split->items[0], "swipe") == 0) {
output->type = GESTURE_TYPE_SWIPE;
} else {
return strformat("expected hold|pinch|swipe, got %s",
split->items[0]);
return format_str("expected hold|pinch|swipe, got %s",
(const char *)split->items[0]);
}
// Parse optional arguments
@ -67,7 +50,7 @@ char *gesture_parse(const char *input, struct gesture *output) {
next = split->length == 3 ? split->items[2] : NULL;
} else if (split->length == 3) {
// Fail here if argument can only be finger count
return strformat("expected 1-9, got %s", next);
return format_str("expected 1-9, got %s", next);
}
// If there is an argument left, try to parse as direction
@ -95,7 +78,7 @@ char *gesture_parse(const char *input, struct gesture *output) {
} else if (strcmp(item, "counterclockwise") == 0) {
output->directions |= GESTURE_DIRECTION_COUNTERCLOCKWISE;
} else {
return strformat("expected direction, got %s", item);
return format_str("expected direction, got %s", item);
}
}
list_free_items_and_destroy(directions);
@ -163,7 +146,7 @@ static char *gesture_directions_to_string(uint32_t directions) {
if (!result) {
result = strdup(name);
} else {
char *new = strformat("%s+%s", result, name);
char *new = format_str("%s+%s", result, name);
free(result);
result = new;
}
@ -179,7 +162,7 @@ static char *gesture_directions_to_string(uint32_t directions) {
char *gesture_to_string(struct gesture *gesture) {
char *directions = gesture_directions_to_string(gesture->directions);
char *result = strformat("%s:%u:%s",
char *result = format_str("%s:%u:%s",
gesture_type_string(gesture->type),
gesture->fingers, directions);
free(directions);

View file

@ -84,18 +84,11 @@ void get_text_size(cairo_t *cairo, const PangoFontDescription *desc, int *width,
int *baseline, double scale, bool markup, const char *fmt, ...) {
va_list args;
va_start(args, fmt);
// Add one since vsnprintf excludes null terminator.
int length = vsnprintf(NULL, 0, fmt, args) + 1;
char *buf = vformat_str(fmt, args);
va_end(args);
char *buf = malloc(length);
if (buf == NULL) {
sway_log(SWAY_ERROR, "Failed to allocate memory");
return;
}
va_start(args, fmt);
vsnprintf(buf, length, fmt, args);
va_end(args);
PangoLayout *layout = get_pango_layout(cairo, desc, buf, scale, markup);
pango_cairo_update_layout(cairo, layout);
@ -104,6 +97,7 @@ void get_text_size(cairo_t *cairo, const PangoFontDescription *desc, int *width,
*baseline = pango_layout_get_baseline(layout) / PANGO_SCALE;
}
g_object_unref(layout);
free(buf);
}
@ -125,18 +119,11 @@ void render_text(cairo_t *cairo, const PangoFontDescription *desc,
double scale, bool markup, const char *fmt, ...) {
va_list args;
va_start(args, fmt);
// Add one since vsnprintf excludes null terminator.
int length = vsnprintf(NULL, 0, fmt, args) + 1;
char *buf = vformat_str(fmt, args);
va_end(args);
char *buf = malloc(length);
if (buf == NULL) {
sway_log(SWAY_ERROR, "Failed to allocate memory");
return;
}
va_start(args, fmt);
vsnprintf(buf, length, fmt, args);
va_end(args);
PangoLayout *layout = get_pango_layout(cairo, desc, buf, scale, markup);
cairo_font_options_t *fo = cairo_font_options_create();
@ -146,5 +133,6 @@ void render_text(cairo_t *cairo, const PangoFontDescription *desc,
pango_cairo_update_layout(cairo, layout);
pango_cairo_show_layout(cairo, layout);
g_object_unref(layout);
free(buf);
}

View file

@ -1,5 +1,6 @@
#define _POSIX_C_SOURCE 200809L
#include <ctype.h>
#include <stdarg.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
@ -328,3 +329,35 @@ bool expand_path(char **path) {
wordfree(&p);
return true;
}
char *vformat_str(const char *fmt, va_list args) {
char *str = NULL;
va_list args_copy;
va_copy(args_copy, args);
int len = vsnprintf(NULL, 0, fmt, args);
if (len < 0) {
sway_log_errno(SWAY_ERROR, "vsnprintf(\"%s\") failed", fmt);
goto out;
}
str = malloc(len + 1);
if (str == NULL) {
sway_log_errno(SWAY_ERROR, "malloc() failed");
goto out;
}
vsnprintf(str, len + 1, fmt, args_copy);
out:
va_end(args_copy);
return str;
}
char *format_str(const char *fmt, ...) {
va_list args;
va_start(args, fmt);
char *str = vformat_str(fmt, args);
va_end(args);
return str;
}

View file

@ -5,6 +5,7 @@
#include <stdint.h>
#include <cairo.h>
#include <pango/pangocairo.h>
#include "stringop.h"
/**
* Utility function which escape characters a & < > ' ".
@ -16,9 +17,9 @@ size_t escape_markup_text(const char *src, char *dest);
PangoLayout *get_pango_layout(cairo_t *cairo, const PangoFontDescription *desc,
const char *text, double scale, bool markup);
void get_text_size(cairo_t *cairo, const PangoFontDescription *desc, int *width, int *height,
int *baseline, double scale, bool markup, const char *fmt, ...);
int *baseline, double scale, bool markup, const char *fmt, ...) _SWAY_ATTRIB_PRINTF(8, 9);
void get_text_metrics(const PangoFontDescription *desc, int *height, int *baseline);
void render_text(cairo_t *cairo, PangoFontDescription *desc,
double scale, bool markup, const char *fmt, ...);
double scale, bool markup, const char *fmt, ...) _SWAY_ATTRIB_PRINTF(5, 6);
#endif

View file

@ -5,6 +5,12 @@
#include <stddef.h>
#include "list.h"
#ifdef __GNUC__
#define _SWAY_ATTRIB_PRINTF(start, end) __attribute__((format(printf, start, end)))
#else
#define _SWAY_ATTRIB_PRINTF(start, end)
#endif
void strip_whitespace(char *str);
void strip_quotes(char *str);
@ -31,4 +37,7 @@ char *argsep(char **stringp, const char *delim, char *matched_delim);
// Expand a path using shell replacements such as $HOME and ~
bool expand_path(char **path);
char *vformat_str(const char *fmt, va_list args) _SWAY_ATTRIB_PRINTF(1, 0);
char *format_str(const char *fmt, ...) _SWAY_ATTRIB_PRINTF(1, 2);
#endif

View file

@ -3,6 +3,7 @@
#include <wlr/util/edges.h>
#include "config.h"
#include "stringop.h"
struct sway_container;
@ -76,7 +77,7 @@ struct cmd_results *config_commands_command(char *exec);
/**
* Allocates a cmd_results object.
*/
struct cmd_results *cmd_results_new(enum cmd_status status, const char *error, ...);
struct cmd_results *cmd_results_new(enum cmd_status status, const char *error, ...) _SWAY_ATTRIB_PRINTF(2, 3);
/**
* Frees a cmd_results object.
*/

View file

@ -12,6 +12,7 @@
#include "../include/config.h"
#include "gesture.h"
#include "list.h"
#include "stringop.h"
#include "swaynag.h"
#include "tree/container.h"
#include "sway/input/tablet.h"
@ -625,7 +626,7 @@ void run_deferred_bindings(void);
/**
* Adds a warning entry to the swaynag instance used for errors.
*/
void config_add_swaynag_warning(char *fmt, ...);
void config_add_swaynag_warning(char *fmt, ...) _SWAY_ATTRIB_PRINTF(1, 2);
/**
* Free config struct

View file

@ -96,6 +96,9 @@ void output_damage_box(struct sway_output *output, struct wlr_box *box);
void output_damage_whole_container(struct sway_output *output,
struct sway_container *con);
bool output_match_name_or_id(struct sway_output *output,
const char *name_or_id);
// this ONLY includes the enabled outputs
struct sway_output *output_by_name_or_id(const char *name_or_id);

View file

@ -1,6 +1,7 @@
#ifndef _SWAY_SWAYNAG_H
#define _SWAY_SWAYNAG_H
#include <wayland-server-core.h>
#include "stringop.h"
struct swaynag_instance {
struct wl_client *client;
@ -21,7 +22,7 @@ bool swaynag_spawn(const char *swaynag_command,
// Write a log message to swaynag->fd[1]. This will fail when swaynag->detailed
// is false.
void swaynag_log(const char *swaynag_command, struct swaynag_instance *swaynag,
const char *fmt, ...);
const char *fmt, ...) _SWAY_ATTRIB_PRINTF(3, 4);
// If swaynag->detailed, close swaynag->fd[1] so swaynag displays
void swaynag_show(struct swaynag_instance *swaynag);

View file

@ -113,6 +113,11 @@ struct sway_container {
// Hidden scratchpad containers have a NULL parent.
bool scratchpad;
// Stores last output size and position for adjusting coordinates of
// scratchpad windows.
// Unused for non-scratchpad windows.
struct wlr_box transform;
float alpha;
struct wlr_texture *title_focused;
@ -196,6 +201,9 @@ size_t container_titlebar_height(void);
void floating_calculate_constraints(int *min_width, int *max_width,
int *min_height, int *max_height);
void floating_fix_coordinates(struct sway_container *con,
struct wlr_box *old, struct wlr_box *new);
void container_floating_resize_and_center(struct sway_container *con);
void container_floating_set_default_size(struct sway_container *con);

View file

@ -18,6 +18,7 @@ add_project_arguments(
'-Wno-unused-parameter',
'-Wno-unused-result',
'-Wno-missing-braces',
'-Wno-format-zero-length',
'-Wundef',
'-Wvla',
],
@ -117,6 +118,11 @@ conf_data.set10('HAVE_LIBSYSTEMD', sdbus.found() and sdbus.name() == 'libsystemd
conf_data.set10('HAVE_LIBELOGIND', sdbus.found() and sdbus.name() == 'libelogind')
conf_data.set10('HAVE_BASU', sdbus.found() and sdbus.name() == 'basu')
conf_data.set10('HAVE_TRAY', have_tray)
conf_data.set10('HAVE_LIBINPUT_CONFIG_ACCEL_PROFILE_CUSTOM', cc.has_header_symbol(
'libinput.h',
'LIBINPUT_CONFIG_ACCEL_PROFILE_CUSTOM',
dependencies: libinput,
))
scdoc = dependency('scdoc', version: '>=1.9.2', native: true, required: get_option('man-pages'))
if scdoc.found()

View file

@ -381,10 +381,13 @@ struct cmd_results *config_command(char *exec, char **new_block) {
sway_log(SWAY_INFO, "Config command: %s", exec);
const struct cmd_handler *handler = find_core_handler(argv[0]);
if (!handler || !handler->handle) {
const char *error = handler
? "Command '%s' is shimmed, but unimplemented"
: "Unknown/invalid command '%s'";
results = cmd_results_new(CMD_INVALID, error, argv[0]);
if (handler) {
results = cmd_results_new(CMD_INVALID,
"Command '%s' is shimmed, but unimplemented", argv[0]);
} else {
results = cmd_results_new(CMD_INVALID,
"Unknown/invalid command '%s'", argv[0]);
}
goto cleanup;
}
@ -486,20 +489,10 @@ struct cmd_results *cmd_results_new(enum cmd_status status,
}
results->status = status;
if (format) {
char *error = NULL;
va_list args;
va_start(args, format);
int slen = vsnprintf(NULL, 0, format, args);
results->error = vformat_str(format, args);
va_end(args);
if (slen > 0) {
error = malloc(slen + 1);
if (error != NULL) {
va_start(args, format);
vsnprintf(error, slen + 1, format, args);
va_end(args);
}
}
results->error = error;
} else {
results->error = NULL;
}

View file

@ -17,7 +17,7 @@ struct cmd_results *cmd_assign(int argc, char **argv) {
char *err_str = NULL;
struct criteria *criteria = criteria_parse(argv[0], &err_str);
if (!criteria) {
error = cmd_results_new(CMD_INVALID, err_str);
error = cmd_results_new(CMD_INVALID, "%s", err_str);
free(err_str);
return error;
}

View file

@ -73,12 +73,10 @@ struct cmd_results *cmd_bar(int argc, char **argv) {
}
++argv; --argc;
} else if (config->reading && !config->current_bar) {
int len = snprintf(NULL, 0, "bar-%d", config->bars->length) + 1;
id = malloc(len * sizeof(char));
id = format_str("bar-%d", config->bars->length);
if (!id) {
return cmd_results_new(CMD_FAILURE, "Unable to allocate bar id");
}
snprintf(id, len, "bar-%d", config->bars->length);
} else if (!config->reading && strcmp(argv[0], "mode") != 0 &&
strcmp(argv[0], "hidden_state") != 0) {
if (is_subcommand(argv[0])) {

View file

@ -96,7 +96,7 @@ static struct cmd_results *bar_cmd_bind(int argc, char **argv, bool code,
}
if (message) {
free_bar_binding(binding);
error = cmd_results_new(CMD_INVALID, message);
error = cmd_results_new(CMD_INVALID, "%s", message);
free(message);
return error;
} else if (!binding->button) {

View file

@ -26,7 +26,7 @@ static struct cmd_results *tray_bind(int argc, char **argv, bool code) {
}
if (message) {
free(binding);
error = cmd_results_new(CMD_INVALID, message);
error = cmd_results_new(CMD_INVALID, "%s", message);
free(message);
return error;
} else if (!binding->button) {

View file

@ -127,7 +127,7 @@ static struct cmd_results *identify_key(const char* name, bool first_key,
if (!button) {
if (message) {
struct cmd_results *error =
cmd_results_new(CMD_INVALID, message);
cmd_results_new(CMD_INVALID, "%s", message);
free(message);
return error;
} else {
@ -143,7 +143,7 @@ static struct cmd_results *identify_key(const char* name, bool first_key,
if (!button) {
if (message) {
struct cmd_results *error =
cmd_results_new(CMD_INVALID, message);
cmd_results_new(CMD_INVALID, "%s", message);
free(message);
return error;
} else {
@ -182,7 +182,7 @@ static struct cmd_results *identify_key(const char* name, bool first_key,
uint32_t button = get_mouse_bindsym(name, &message);
if (message) {
struct cmd_results *error =
cmd_results_new(CMD_INVALID, message);
cmd_results_new(CMD_INVALID, "%s", message);
free(message);
return error;
} else if (button) {
@ -539,7 +539,7 @@ struct cmd_results *cmd_bind_or_unbind_switch(int argc, char **argv,
free_switch_binding(binding);
return cmd_results_new(CMD_FAILURE,
"Invalid %s command (expected binding with the form "
"<switch>:<state>)", bindtype, argc);
"<switch>:<state>)", bindtype);
}
if (strcmp(split->items[0], "tablet") == 0) {
binding->type = WLR_SWITCH_TYPE_TABLET_MODE;
@ -549,7 +549,8 @@ struct cmd_results *cmd_bind_or_unbind_switch(int argc, char **argv,
free_switch_binding(binding);
return cmd_results_new(CMD_FAILURE,
"Invalid %s command (expected switch binding: "
"unknown switch %s)", bindtype, split->items[0]);
"unknown switch %s)", bindtype,
(const char *)split->items[0]);
}
if (strcmp(split->items[1], "on") == 0) {
binding->trigger = SWAY_SWITCH_TRIGGER_ON;
@ -562,7 +563,7 @@ struct cmd_results *cmd_bind_or_unbind_switch(int argc, char **argv,
return cmd_results_new(CMD_FAILURE,
"Invalid %s command "
"(expected switch state: unknown state %s)",
bindtype, split->items[1]);
bindtype, (const char *)split->items[1]);
}
list_free_items_and_destroy(split);

View file

@ -23,16 +23,16 @@ static struct cmd_results *handle_command(int argc, char **argv, char *cmd_name,
char *err;
int width = (int)strtol(argv[0], &err, 10);
if (*err) {
return cmd_results_new(CMD_INVALID, cmd_name, usage);
return cmd_results_new(CMD_INVALID, "%s", usage);
}
if (strcmp(argv[1], "x") != 0) {
return cmd_results_new(CMD_INVALID, cmd_name, usage);
return cmd_results_new(CMD_INVALID, "%s", usage);
}
int height = (int)strtol(argv[2], &err, 10);
if (*err) {
return cmd_results_new(CMD_INVALID, cmd_name, usage);
return cmd_results_new(CMD_INVALID, "%s", usage);
}
*config_width = width;

View file

@ -14,7 +14,7 @@ struct cmd_results *cmd_for_window(int argc, char **argv) {
char *err_str = NULL;
struct criteria *criteria = criteria_parse(argv[0], &err_str);
if (!criteria) {
error = cmd_results_new(CMD_INVALID, err_str);
error = cmd_results_new(CMD_INVALID, "%s", err_str);
free(err_str);
return error;
}

View file

@ -20,7 +20,7 @@ struct cmd_results *cmd_hide_edge_borders(int argc, char **argv) {
}
if (!argc) {
return cmd_results_new(CMD_INVALID, expected_syntax);
return cmd_results_new(CMD_INVALID, "%s", expected_syntax);
}
if (strcmp(argv[0], "none") == 0) {
@ -38,7 +38,7 @@ struct cmd_results *cmd_hide_edge_borders(int argc, char **argv) {
config->hide_edge_borders = E_NONE;
config->hide_edge_borders_smart = ESMART_NO_GAPS;
} else {
return cmd_results_new(CMD_INVALID, expected_syntax);
return cmd_results_new(CMD_INVALID, "%s", expected_syntax);
}
config->hide_lone_tab = hide_lone_tab;

View file

@ -49,5 +49,5 @@ struct cmd_results *input_cmd_map_to_region(int argc, char **argv) {
error:
free(ic->mapped_to_region);
ic->mapped_to_region = NULL;
return cmd_results_new(CMD_FAILURE, errstr);
return cmd_results_new(CMD_FAILURE, "%s", errstr);
}

View file

@ -21,7 +21,7 @@ struct cmd_results *input_cmd_scroll_button(int argc, char **argv) {
char *message = NULL;
uint32_t button = get_mouse_button(*argv, &message);
if (message) {
error = cmd_results_new(CMD_INVALID, message);
error = cmd_results_new(CMD_INVALID, "%s", message);
free(message);
return error;
} else if (button == SWAY_SCROLL_UP || button == SWAY_SCROLL_DOWN

View file

@ -153,7 +153,7 @@ struct cmd_results *cmd_layout(int argc, char **argv) {
workspace->output);
}
if (new_layout == L_NONE) {
return cmd_results_new(CMD_INVALID, expected_syntax);
return cmd_results_new(CMD_INVALID, "%s", expected_syntax);
}
if (new_layout != old_layout) {
if (container) {

View file

@ -206,9 +206,17 @@ static void container_move_to_workspace(struct sway_container *container,
container_detach(container);
workspace_add_floating(workspace, container);
container_handle_fullscreen_reparent(container);
// If changing output, center it within the workspace
// If changing output, adjust the coordinates of the window.
if (old_output != workspace->output && !container->pending.fullscreen_mode) {
container_floating_move_to_center(container);
struct wlr_box workspace_box, old_workspace_box;
workspace_get_box(workspace, &workspace_box);
workspace_get_box(old_workspace, &old_workspace_box);
floating_fix_coordinates(container, &old_workspace_box, &workspace_box);
if (container->scratchpad && workspace->output) {
struct wlr_box output_box;
output_get_box(workspace->output, &output_box);
container->transform = workspace_box;
}
}
} else {
container_detach(container);
@ -462,7 +470,7 @@ static struct cmd_results *cmd_move_container(bool no_auto_back_and_forth,
if (strcasecmp(argv[1], "number") == 0) {
// move [window|container] [to] "workspace number x"
if (argc < 3) {
return cmd_results_new(CMD_INVALID, expected_syntax);
return cmd_results_new(CMD_INVALID, "%s", expected_syntax);
}
if (!isdigit(argv[2][0])) {
return cmd_results_new(CMD_INVALID,
@ -522,7 +530,7 @@ static struct cmd_results *cmd_move_container(bool no_auto_back_and_forth,
}
destination = &dest_con->node;
} else {
return cmd_results_new(CMD_INVALID, expected_syntax);
return cmd_results_new(CMD_INVALID, "%s", expected_syntax);
}
if (destination->type == N_CONTAINER &&
@ -821,7 +829,7 @@ static struct cmd_results *cmd_move_to_position(int argc, char **argv) {
}
if (!argc) {
return cmd_results_new(CMD_INVALID, expected_position_syntax);
return cmd_results_new(CMD_INVALID, "%s", expected_position_syntax);
}
bool absolute = false;
@ -831,19 +839,19 @@ static struct cmd_results *cmd_move_to_position(int argc, char **argv) {
++argv;
}
if (!argc) {
return cmd_results_new(CMD_INVALID, expected_position_syntax);
return cmd_results_new(CMD_INVALID, "%s", expected_position_syntax);
}
if (strcmp(argv[0], "position") == 0) {
--argc;
++argv;
}
if (!argc) {
return cmd_results_new(CMD_INVALID, expected_position_syntax);
return cmd_results_new(CMD_INVALID, "%s", expected_position_syntax);
}
if (strcmp(argv[0], "cursor") == 0 || strcmp(argv[0], "mouse") == 0 ||
strcmp(argv[0], "pointer") == 0) {
if (absolute) {
return cmd_results_new(CMD_INVALID, expected_position_syntax);
return cmd_results_new(CMD_INVALID, "%s", expected_position_syntax);
}
return cmd_move_to_position_pointer(container);
} else if (strcmp(argv[0], "center") == 0) {
@ -865,7 +873,7 @@ static struct cmd_results *cmd_move_to_position(int argc, char **argv) {
}
if (argc < 2) {
return cmd_results_new(CMD_FAILURE, expected_position_syntax);
return cmd_results_new(CMD_FAILURE, "%s", expected_position_syntax);
}
struct movement_amount lx = { .amount = 0, .unit = MOVEMENT_UNIT_INVALID };
@ -878,7 +886,7 @@ static struct cmd_results *cmd_move_to_position(int argc, char **argv) {
}
if (argc < 1) {
return cmd_results_new(CMD_FAILURE, expected_position_syntax);
return cmd_results_new(CMD_FAILURE, "%s", expected_position_syntax);
}
struct movement_amount ly = { .amount = 0, .unit = MOVEMENT_UNIT_INVALID };
@ -887,7 +895,7 @@ static struct cmd_results *cmd_move_to_position(int argc, char **argv) {
argc -= num_consumed_args;
argv += num_consumed_args;
if (argc > 0) {
return cmd_results_new(CMD_INVALID, expected_position_syntax);
return cmd_results_new(CMD_INVALID, "%s", expected_position_syntax);
}
if (ly.unit == MOVEMENT_UNIT_INVALID) {
return cmd_results_new(CMD_INVALID, "Invalid y position specified");
@ -1033,13 +1041,13 @@ struct cmd_results *cmd_move(int argc, char **argv) {
}
if (!argc) {
return cmd_results_new(CMD_INVALID, expected_full_syntax);
return cmd_results_new(CMD_INVALID, "%s", expected_full_syntax);
}
// Only `move [window|container] [to] workspace` supports
// `--no-auto-back-and-forth` so treat others as invalid syntax
if (no_auto_back_and_forth && strcasecmp(argv[0], "workspace") != 0) {
return cmd_results_new(CMD_INVALID, expected_full_syntax);
return cmd_results_new(CMD_INVALID, "%s", expected_full_syntax);
}
if (strcasecmp(argv[0], "workspace") == 0 ||
@ -1053,5 +1061,5 @@ struct cmd_results *cmd_move(int argc, char **argv) {
strcasecmp(argv[1], "position") == 0)) {
return cmd_move_to_position(argc, argv);
}
return cmd_results_new(CMD_INVALID, expected_full_syntax);
return cmd_results_new(CMD_INVALID, "%s", expected_full_syntax);
}

View file

@ -13,7 +13,7 @@ struct cmd_results *cmd_no_focus(int argc, char **argv) {
char *err_str = NULL;
struct criteria *criteria = criteria_parse(argv[0], &err_str);
if (!criteria) {
error = cmd_results_new(CMD_INVALID, err_str);
error = cmd_results_new(CMD_INVALID, "%s", err_str);
free(err_str);
return error;
}

View file

@ -26,7 +26,7 @@ struct cmd_results *cmd_rename(int argc, char **argv) {
"Can't run this command while there's no outputs connected.");
}
if (strcasecmp(argv[0], "workspace") != 0) {
return cmd_results_new(CMD_INVALID, expected_syntax);
return cmd_results_new(CMD_INVALID, "%s", expected_syntax);
}
int argn = 1;
@ -65,7 +65,7 @@ struct cmd_results *cmd_rename(int argc, char **argv) {
++argn; // move past "to"
if (argn >= argc) {
return cmd_results_new(CMD_INVALID, expected_syntax);
return cmd_results_new(CMD_INVALID, "%s", expected_syntax);
}
char *new_name = join_args(argv + argn, argc - argn);

View file

@ -415,7 +415,7 @@ static struct cmd_results *cmd_resize_set(int argc, char **argv) {
argc -= num_consumed_args;
argv += num_consumed_args;
if (width.unit == MOVEMENT_UNIT_INVALID) {
return cmd_results_new(CMD_INVALID, usage);
return cmd_results_new(CMD_INVALID, "%s", usage);
}
}
@ -427,10 +427,10 @@ static struct cmd_results *cmd_resize_set(int argc, char **argv) {
}
int num_consumed_args = parse_movement_amount(argc, argv, &height);
if (argc > num_consumed_args) {
return cmd_results_new(CMD_INVALID, usage);
return cmd_results_new(CMD_INVALID, "%s", usage);
}
if (width.unit == MOVEMENT_UNIT_INVALID) {
return cmd_results_new(CMD_INVALID, usage);
return cmd_results_new(CMD_INVALID, "%s", usage);
}
}
@ -462,7 +462,7 @@ static struct cmd_results *cmd_resize_adjust(int argc, char **argv,
"[<amount> px|ppt [or <amount> px|ppt]]'";
uint32_t axis = parse_resize_axis(*argv);
if (axis == WLR_EDGE_NONE) {
return cmd_results_new(CMD_INVALID, usage);
return cmd_results_new(CMD_INVALID, "%s", usage);
}
--argc; ++argv;
@ -473,7 +473,7 @@ static struct cmd_results *cmd_resize_adjust(int argc, char **argv,
argc -= num_consumed_args;
argv += num_consumed_args;
if (first_amount.unit == MOVEMENT_UNIT_INVALID) {
return cmd_results_new(CMD_INVALID, usage);
return cmd_results_new(CMD_INVALID, "%s", usage);
}
} else {
first_amount.amount = 10;
@ -483,7 +483,7 @@ static struct cmd_results *cmd_resize_adjust(int argc, char **argv,
// "or"
if (argc) {
if (strcmp(*argv, "or") != 0) {
return cmd_results_new(CMD_INVALID, usage);
return cmd_results_new(CMD_INVALID, "%s", usage);
}
--argc; ++argv;
}
@ -493,10 +493,10 @@ static struct cmd_results *cmd_resize_adjust(int argc, char **argv,
if (argc) {
int num_consumed_args = parse_movement_amount(argc, argv, &second_amount);
if (argc > num_consumed_args) {
return cmd_results_new(CMD_INVALID, usage);
return cmd_results_new(CMD_INVALID, "%s", usage);
}
if (second_amount.unit == MOVEMENT_UNIT_INVALID) {
return cmd_results_new(CMD_INVALID, usage);
return cmd_results_new(CMD_INVALID, "%s", usage);
}
} else {
second_amount.amount = 0;
@ -566,5 +566,5 @@ struct cmd_results *cmd_resize(int argc, char **argv) {
const char usage[] = "Expected 'resize <shrink|grow> "
"<width|height|up|down|left|right> [<amount>] [px|ppt]'";
return cmd_results_new(CMD_INVALID, usage);
return cmd_results_new(CMD_INVALID, "%s", usage);
}

View file

@ -18,7 +18,7 @@ static struct cmd_results *handle_command(struct sway_cursor *cursor,
int argc, char **argv) {
if (strcasecmp(argv[0], "move") == 0) {
if (argc < 3) {
return cmd_results_new(CMD_INVALID, expected_syntax);
return cmd_results_new(CMD_INVALID, "%s", expected_syntax);
}
int delta_x = strtol(argv[1], NULL, 10);
int delta_y = strtol(argv[2], NULL, 10);
@ -27,7 +27,7 @@ static struct cmd_results *handle_command(struct sway_cursor *cursor,
wlr_seat_pointer_notify_frame(cursor->seat->wlr_seat);
} else if (strcasecmp(argv[0], "set") == 0) {
if (argc < 3) {
return cmd_results_new(CMD_INVALID, expected_syntax);
return cmd_results_new(CMD_INVALID, "%s", expected_syntax);
}
// map absolute coords (0..1,0..1) to root container coords
float x = strtof(argv[1], NULL) / root->width;
@ -37,7 +37,7 @@ static struct cmd_results *handle_command(struct sway_cursor *cursor,
wlr_seat_pointer_notify_frame(cursor->seat->wlr_seat);
} else {
if (argc < 2) {
return cmd_results_new(CMD_INVALID, expected_syntax);
return cmd_results_new(CMD_INVALID, "%s", expected_syntax);
}
struct cmd_results *error = NULL;
if ((error = press_or_release(cursor, argv[0], argv[1]))) {
@ -92,14 +92,14 @@ static struct cmd_results *press_or_release(struct sway_cursor *cursor,
} else if (strcasecmp(action, "release") == 0) {
state = WLR_BUTTON_RELEASED;
} else {
return cmd_results_new(CMD_INVALID, expected_syntax);
return cmd_results_new(CMD_INVALID, "%s", expected_syntax);
}
char *message = NULL;
button = get_mouse_button(button_str, &message);
if (message) {
struct cmd_results *error =
cmd_results_new(CMD_INVALID, message);
cmd_results_new(CMD_INVALID, "%s", message);
free(message);
return error;
} else if (button == SWAY_SCROLL_UP || button == SWAY_SCROLL_DOWN

View file

@ -32,7 +32,7 @@ static struct cmd_results *do_split(int layout) {
return cmd_results_new(CMD_SUCCESS, NULL);
}
static struct cmd_results *do_unsplit() {
static struct cmd_results *do_unsplit(void) {
struct sway_container *con = config->handler_context.container;
struct sway_workspace *ws = config->handler_context.workspace;

View file

@ -46,7 +46,7 @@ struct cmd_results *cmd_swap(int argc, char **argv) {
}
if (strcasecmp(argv[0], "container") || strcasecmp(argv[1], "with")) {
return cmd_results_new(CMD_INVALID, expected_syntax);
return cmd_results_new(CMD_INVALID, "%s", expected_syntax);
}
struct sway_container *current = config->handler_context.container;
@ -65,7 +65,7 @@ struct cmd_results *cmd_swap(int argc, char **argv) {
other = root_find_container(test_mark, value);
} else {
free(value);
return cmd_results_new(CMD_INVALID, expected_syntax);
return cmd_results_new(CMD_INVALID, "%s", expected_syntax);
}
if (!other) {

View file

@ -61,7 +61,7 @@ static struct cmd_results *cmd_workspace_gaps(int argc, char **argv,
const char expected[] = "Expected 'workspace <name> gaps "
"inner|outer|horizontal|vertical|top|right|bottom|left <px>'";
if (gaps_location == 0) {
return cmd_results_new(CMD_INVALID, expected);
return cmd_results_new(CMD_INVALID, "%s", expected);
}
struct cmd_results *error = NULL;
if ((error = checkarg(argc, "workspace", EXPECTED_EQUAL_TO,
@ -79,7 +79,7 @@ static struct cmd_results *cmd_workspace_gaps(int argc, char **argv,
char *end;
int amount = strtol(argv[gaps_location + 2], &end, 10);
if (strlen(end)) {
return cmd_results_new(CMD_FAILURE, expected);
return cmd_results_new(CMD_FAILURE, "%s", expected);
}
bool valid = false;
@ -110,7 +110,7 @@ static struct cmd_results *cmd_workspace_gaps(int argc, char **argv,
}
}
if (!valid) {
return cmd_results_new(CMD_INVALID, expected);
return cmd_results_new(CMD_INVALID, "%s", expected);
}
// Prevent invalid gaps configurations.
@ -174,7 +174,7 @@ struct cmd_results *cmd_workspace(int argc, char **argv) {
}
if (root->fullscreen_global) {
return cmd_results_new(CMD_FAILURE, "workspace",
return cmd_results_new(CMD_FAILURE,
"Can't switch workspaces while fullscreen global");
}

View file

@ -924,23 +924,18 @@ void config_add_swaynag_warning(char *fmt, ...) {
if (config->reading && !config->validating) {
va_list args;
va_start(args, fmt);
size_t length = vsnprintf(NULL, 0, fmt, args) + 1;
char *str = vformat_str(fmt, args);
va_end(args);
char *temp = malloc(length + 1);
if (!temp) {
sway_log(SWAY_ERROR, "Failed to allocate buffer for warning.");
if (str == NULL) {
return;
}
va_start(args, fmt);
vsnprintf(temp, length, fmt, args);
va_end(args);
swaynag_log(config->swaynag_command, &config->swaynag_config_errors,
"Warning on line %i (%s) '%s': %s",
config->current_config_line_number, config->current_config_path,
config->current_config_line, temp);
config->current_config_line, str);
free(str);
}
}

View file

@ -153,25 +153,16 @@ static void merge_wildcard_on_all(struct output_config *wildcard) {
}
static void merge_id_on_name(struct output_config *oc) {
char *id_on_name = NULL;
char id[128];
char *name = NULL;
struct sway_output *output;
wl_list_for_each(output, &root->all_outputs, link) {
name = output->wlr_output->name;
output_get_identifier(id, sizeof(id), output);
if (strcmp(name, oc->name) == 0 || strcmp(id, oc->name) == 0) {
size_t length = snprintf(NULL, 0, "%s on %s", id, name) + 1;
id_on_name = malloc(length);
if (!id_on_name) {
sway_log(SWAY_ERROR, "Failed to allocate id on name string");
return;
}
snprintf(id_on_name, length, "%s on %s", id, name);
break;
}
struct sway_output *output = all_output_by_name_or_id(oc->name);
if (output == NULL) {
return;
}
const char *name = output->wlr_output->name;
char id[128];
output_get_identifier(id, sizeof(id), output);
char *id_on_name = format_str("%s on %s", id, name);
if (!id_on_name) {
return;
}
@ -639,9 +630,7 @@ static struct output_config *get_output_config(char *identifier,
struct output_config *oc_name = NULL;
struct output_config *oc_id = NULL;
size_t length = snprintf(NULL, 0, "%s on %s", identifier, name) + 1;
char *id_on_name = malloc(length);
snprintf(id_on_name, length, "%s on %s", identifier, name);
char *id_on_name = format_str("%s on %s", identifier, name);
int i = list_seq_find(config->output_configs, output_name_cmp, id_on_name);
if (i >= 0) {
oc_id_on_name = config->output_configs->items[i];
@ -728,12 +717,11 @@ void apply_output_config_to_outputs(struct output_config *oc) {
// this is during startup then there will be no container and config
// will be applied during normal "new output" event from wlroots.
bool wildcard = strcmp(oc->name, "*") == 0;
char id[128];
struct sway_output *sway_output, *tmp;
wl_list_for_each_safe(sway_output, tmp, &root->all_outputs, link) {
char *name = sway_output->wlr_output->name;
output_get_identifier(id, sizeof(id), sway_output);
if (wildcard || !strcmp(name, oc->name) || !strcmp(id, oc->name)) {
if (output_match_name_or_id(sway_output, oc->name)) {
char id[128];
output_get_identifier(id, sizeof(id), sway_output);
struct output_config *current = get_output_config(id, sway_output);
if (!current) {
// No stored output config matched, apply oc directly

View file

@ -228,7 +228,7 @@ struct launcher_ctx *launcher_ctx_create(struct wlr_xdg_activation_token_v1 *tok
}
// Creates a context with a new token for the internal launcher
struct launcher_ctx *launcher_ctx_create_internal() {
struct launcher_ctx *launcher_ctx_create_internal(void) {
struct sway_seat *seat = input_manager_current_seat();
struct sway_workspace *ws = seat_get_focused_workspace(seat);
if (!ws) {

View file

@ -36,13 +36,22 @@
#include <wlr/types/wlr_drm_lease_v1.h>
#endif
bool output_match_name_or_id(struct sway_output *output,
const char *name_or_id) {
if (strcmp(name_or_id, "*") == 0) {
return true;
}
char identifier[128];
output_get_identifier(identifier, sizeof(identifier), output);
return strcasecmp(identifier, name_or_id) == 0
|| strcasecmp(output->wlr_output->name, name_or_id) == 0;
}
struct sway_output *output_by_name_or_id(const char *name_or_id) {
for (int i = 0; i < root->outputs->length; ++i) {
struct sway_output *output = root->outputs->items[i];
char identifier[128];
output_get_identifier(identifier, sizeof(identifier), output);
if (strcasecmp(identifier, name_or_id) == 0
|| strcasecmp(output->wlr_output->name, name_or_id) == 0) {
if (output_match_name_or_id(output, name_or_id)) {
return output;
}
}
@ -52,10 +61,7 @@ struct sway_output *output_by_name_or_id(const char *name_or_id) {
struct sway_output *all_output_by_name_or_id(const char *name_or_id) {
struct sway_output *output;
wl_list_for_each(output, &root->all_outputs, link) {
char identifier[128];
output_get_identifier(identifier, sizeof(identifier), output);
if (strcasecmp(identifier, name_or_id) == 0
|| strcasecmp(output->wlr_output->name, name_or_id) == 0) {
if (output_match_name_or_id(output, name_or_id)) {
return output;
}
}
@ -512,6 +518,10 @@ static bool scan_out_fullscreen_view(struct sway_output *output,
return false;
}
if (!wlr_output_is_direct_scanout_allowed(wlr_output)) {
return false;
}
wlr_output_attach_buffer(wlr_output, &surface->buffer->base);
if (!wlr_output_test(wlr_output)) {
return false;
@ -552,6 +562,11 @@ static int output_repaint_timer_handler(void *data) {
wlr_output->frame_pending = false;
if (!wlr_output->needs_frame &&
!pixman_region32_not_empty(&output->damage_ring.current)) {
return 0;
}
struct sway_workspace *workspace = output->current.active_workspace;
if (workspace == NULL) {
return 0;
@ -562,6 +577,11 @@ static int output_repaint_timer_handler(void *data) {
fullscreen_con = workspace->current.fullscreen;
}
pixman_region32_t frame_damage;
get_frame_damage(output, &frame_damage);
wlr_output_set_damage(wlr_output, &frame_damage);
pixman_region32_fini(&frame_damage);
if (fullscreen_con && fullscreen_con->view && !debug.noscanout) {
// Try to scan-out the fullscreen view
static bool last_scanned_out = false;
@ -584,11 +604,6 @@ static int output_repaint_timer_handler(void *data) {
}
}
if (!output->wlr_output->needs_frame &&
!pixman_region32_not_empty(&output->damage_ring.current)) {
return 0;
}
int buffer_age;
if (!wlr_output_attach_render(output->wlr_output, &buffer_age)) {
return 0;
@ -605,11 +620,6 @@ static int output_repaint_timer_handler(void *data) {
pixman_region32_fini(&damage);
pixman_region32_t frame_damage;
get_frame_damage(output, &frame_damage);
wlr_output_set_damage(wlr_output, &frame_damage);
pixman_region32_fini(&frame_damage);
if (!wlr_output_commit(wlr_output)) {
return 0;
}
@ -884,11 +894,6 @@ static void handle_mode(struct sway_output *output) {
arrange_output(output);
transaction_commit_dirty();
int width, height;
wlr_output_transformed_resolution(output->wlr_output, &width, &height);
wlr_damage_ring_set_bounds(&output->damage_ring, width, height);
wlr_output_schedule_frame(output->wlr_output);
update_output_manager_config(output->server);
}
@ -1024,6 +1029,9 @@ void handle_new_output(struct wl_listener *listener, void *data) {
transaction_commit_dirty();
int width, height;
wlr_output_transformed_resolution(output->wlr_output, &width, &height);
wlr_damage_ring_set_bounds(&output->damage_ring, width, height);
update_output_manager_config(server);
}

View file

@ -67,7 +67,13 @@ static void popup_unconstrain(struct sway_xdg_popup *popup) {
struct sway_view *view = popup->child.view;
struct wlr_xdg_popup *wlr_popup = popup->wlr_xdg_popup;
struct sway_output *output = view->container->pending.workspace->output;
struct sway_workspace *workspace = view->container->pending.workspace;
if (!workspace) {
// is null if in the scratchpad
return;
}
struct sway_output *output = workspace->output;
// the output box expressed in the coordinate system of the toplevel parent
// of the popup

View file

@ -1273,11 +1273,7 @@ uint32_t get_mouse_bindsym(const char *name, char **error) {
// Get event code from name
int code = libevdev_event_code_from_name(EV_KEY, name);
if (code == -1) {
size_t len = snprintf(NULL, 0, "Unknown event %s", name) + 1;
*error = malloc(len);
if (*error) {
snprintf(*error, len, "Unknown event %s", name);
}
*error = format_str("Unknown event %s", name);
return 0;
}
return code;
@ -1299,13 +1295,8 @@ uint32_t get_mouse_bindcode(const char *name, char **error) {
}
const char *event = libevdev_event_code_get_name(EV_KEY, code);
if (!event || strncmp(event, "BTN_", strlen("BTN_")) != 0) {
size_t len = snprintf(NULL, 0, "Event code %d (%s) is not a button",
code, event ? event : "(null)") + 1;
*error = malloc(len);
if (*error) {
snprintf(*error, len, "Event code %d (%s) is not a button",
code, event ? event : "(null)");
}
*error = format_str("Event code %d (%s) is not a button",
code, event ? event : "(null)");
return 0;
}
return code;

View file

@ -80,15 +80,7 @@ char *input_device_get_identifier(struct wlr_input_device *device) {
}
}
const char *fmt = "%d:%d:%s";
int len = snprintf(NULL, 0, fmt, vendor, product, name) + 1;
char *identifier = malloc(len);
if (!identifier) {
sway_log(SWAY_ERROR, "Unable to allocate unique input device name");
return NULL;
}
snprintf(identifier, len, fmt, vendor, product, name);
char *identifier = format_str("%d:%d:%s", vendor, product, name);
free(name);
return identifier;
}

View file

@ -717,23 +717,11 @@ struct sway_keyboard *sway_keyboard_create(struct sway_seat *seat,
static void handle_xkb_context_log(struct xkb_context *context,
enum xkb_log_level level, const char *format, va_list args) {
va_list args_copy;
va_copy(args_copy, args);
size_t length = vsnprintf(NULL, 0, format, args_copy) + 1;
va_end(args_copy);
char *error = vformat_str(format, args);
char *error = malloc(length);
if (!error) {
sway_log(SWAY_ERROR, "Failed to allocate libxkbcommon log message");
return;
}
va_copy(args_copy, args);
vsnprintf(error, length, format, args_copy);
va_end(args_copy);
if (error[length - 2] == '\n') {
error[length - 2] = '\0';
size_t len = strlen(error);
if (error[len - 1] == '\n') {
error[len - 1] = '\0';
}
sway_log_importance_t importance = SWAY_DEBUG;
@ -768,13 +756,8 @@ struct xkb_keymap *sway_keyboard_compile_keymap(struct input_config *ic,
if (!keymap_file) {
sway_log_errno(SWAY_ERROR, "cannot read xkb file %s", ic->xkb_file);
if (error) {
size_t len = snprintf(NULL, 0, "cannot read xkb file %s: %s",
ic->xkb_file, strerror(errno)) + 1;
*error = malloc(len);
if (*error) {
snprintf(*error, len, "cannot read xkb_file %s: %s",
ic->xkb_file, strerror(errno));
}
*error = format_str("cannot read xkb file %s: %s",
ic->xkb_file, strerror(errno));
}
goto cleanup;
}

View file

@ -935,6 +935,11 @@ static json_object *describe_libinput_device(struct libinput_device *device) {
case LIBINPUT_CONFIG_ACCEL_PROFILE_ADAPTIVE:
accel_profile = "adaptive";
break;
#if HAVE_LIBINPUT_CONFIG_ACCEL_PROFILE_CUSTOM
case LIBINPUT_CONFIG_ACCEL_PROFILE_CUSTOM:
accel_profile = "custom";
break;
#endif
}
json_object_object_add(object, "accel_profile",
json_object_new_string(accel_profile));

View file

@ -103,7 +103,7 @@ bool server_init(struct sway_server *server) {
return false;
}
server->compositor = wlr_compositor_create(server->wl_display,
server->compositor = wlr_compositor_create(server->wl_display, 5,
server->renderer);
server->compositor_new_surface.notify = handle_compositor_new_surface;
wl_signal_add(&server->compositor->events.new_surface,

View file

@ -228,6 +228,8 @@ correct seat.
absolute coordinates (with respect to the global coordinate space).
Specifying either value as 0 will not update that coordinate.
Deprecated: use the virtual-pointer Wayland protocol instead.
*seat* <seat> cursor press|release button[1-9]|<event-name-or-code>
Simulate pressing (or releasing) the specified mouse button on the
specified seat. The button can either be provided as a button event name or
@ -236,6 +238,8 @@ correct seat.
event will be simulated, however _press_ and _release_ will be ignored and
both will occur.
Deprecated: use the virtual-pointer Wayland protocol instead.
*seat* <name> fallback true|false
Set this seat as the fallback seat. A fallback seat will attach any device
not explicitly attached to another seat (similar to a "default" seat).
@ -251,6 +255,10 @@ correct seat.
If _when-typing_ is enabled, then the cursor will be hidden whenever a key
is pressed.
Be aware that this setting can interfere with input handling in games and
certain types of software (Gimp, Blender etc) that rely on simultaneous
input from mouse and keyboard.
*seat* <name> idle_inhibit <sources...>
Sets the set of input event sources which can prevent the seat from
becoming idle, as a space separated list of source names. Valid names are

View file

@ -145,22 +145,16 @@ void swaynag_log(const char *swaynag_command, struct swaynag_instance *swaynag,
va_list args;
va_start(args, fmt);
size_t length = vsnprintf(NULL, 0, fmt, args) + 1;
char *str = vformat_str(fmt, args);
va_end(args);
char *temp = malloc(length + 1);
if (!temp) {
if (!str) {
sway_log(SWAY_ERROR, "Failed to allocate buffer for swaynag log entry.");
return;
}
va_start(args, fmt);
vsnprintf(temp, length, fmt, args);
va_end(args);
write(swaynag->fd[1], str, strlen(str));
write(swaynag->fd[1], temp, length);
free(temp);
free(str);
}
void swaynag_show(struct swaynag_instance *swaynag) {

View file

@ -264,6 +264,9 @@ void arrange_workspace(struct sway_workspace *workspace) {
area->width, area->height, area->x, area->y);
bool first_arrange = workspace->width == 0 && workspace->height == 0;
struct wlr_box prev_box;
workspace_get_box(workspace, &prev_box);
double prev_x = workspace->x - workspace->current_gaps.left;
double prev_y = workspace->y - workspace->current_gaps.top;
workspace->width = area->width;
@ -277,13 +280,14 @@ void arrange_workspace(struct sway_workspace *workspace) {
if (!first_arrange && (diff_x != 0 || diff_y != 0)) {
for (int i = 0; i < workspace->floating->length; ++i) {
struct sway_container *floater = workspace->floating->items[i];
container_floating_translate(floater, diff_x, diff_y);
double center_x = floater->pending.x + floater->pending.width / 2;
double center_y = floater->pending.y + floater->pending.height / 2;
struct wlr_box workspace_box;
workspace_get_box(workspace, &workspace_box);
if (!wlr_box_contains_point(&workspace_box, center_x, center_y)) {
container_floating_move_to_center(floater);
floating_fix_coordinates(floater, &prev_box, &workspace_box);
// Set transformation for scratchpad windows.
if (floater->scratchpad) {
struct wlr_box output_box;
output_get_box(output, &output_box);
floater->transform = output_box;
}
}
}

View file

@ -712,6 +712,21 @@ void floating_calculate_constraints(int *min_width, int *max_width,
}
void floating_fix_coordinates(struct sway_container *con, struct wlr_box *old, struct wlr_box *new) {
if (!old->width || !old->height) {
// 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);
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);
sway_log(SWAY_DEBUG, "Transformed container %p to coords (%f, %f)", con, con->pending.x, con->pending.y);
}
}
static void floating_natural_resize(struct sway_container *con) {
int min_width, max_width, min_height, max_height;
floating_calculate_constraints(&min_width, &max_width,
@ -1025,6 +1040,13 @@ void container_floating_move_to(struct sway_container *con,
workspace_add_floating(new_workspace, con);
arrange_workspace(old_workspace);
arrange_workspace(new_workspace);
// If the moved container was a visible scratchpad container, then
// update its transform.
if (con->scratchpad) {
struct wlr_box output_box;
output_get_box(new_output, &output_box);
con->transform = output_box;
}
workspace_detect_urgent(old_workspace);
workspace_detect_urgent(new_workspace);
}

View file

@ -56,6 +56,16 @@ void root_destroy(struct sway_root *root) {
free(root);
}
static void set_container_transform(struct sway_workspace *ws,
struct sway_container *con) {
struct sway_output *output = ws->output;
struct wlr_box box = {0};
if (output) {
output_get_box(output, &box);
}
con->transform = box;
}
void root_scratchpad_add_container(struct sway_container *con, struct sway_workspace *ws) {
if (!sway_assert(!con->scratchpad, "Container is already in scratchpad")) {
return;
@ -64,6 +74,8 @@ void root_scratchpad_add_container(struct sway_container *con, struct sway_works
struct sway_container *parent = con->pending.parent;
struct sway_workspace *workspace = con->pending.workspace;
set_container_transform(workspace, con);
// Clear the fullscreen mode when sending to the scratchpad
if (con->pending.fullscreen_mode != FULLSCREEN_NONE) {
container_fullscreen_disable(con);
@ -133,7 +145,10 @@ void root_scratchpad_show(struct sway_container *con) {
// Show the container
if (old_ws) {
container_detach(con);
workspace_consider_destroy(old_ws);
// Make sure the last inactive container on the old workspace is above
// the workspace itself in the focus stack.
struct sway_node *node = seat_get_focus_inactive(seat, &old_ws->node);
seat_set_raw_focus(seat, node);
} else {
// Act on the ancestor of scratchpad hidden split containers
while (con->pending.parent) {
@ -142,18 +157,18 @@ void root_scratchpad_show(struct sway_container *con) {
}
workspace_add_floating(new_ws, con);
// Make sure the container's center point overlaps this workspace
double center_lx = con->pending.x + con->pending.width / 2;
double center_ly = con->pending.y + con->pending.height / 2;
struct wlr_box workspace_box;
workspace_get_box(new_ws, &workspace_box);
if (!wlr_box_contains_point(&workspace_box, center_lx, center_ly)) {
container_floating_resize_and_center(con);
if (new_ws->output) {
struct wlr_box output_box;
output_get_box(new_ws->output, &output_box);
floating_fix_coordinates(con, &con->transform, &output_box);
}
set_container_transform(new_ws, con);
arrange_workspace(new_ws);
seat_set_focus(seat, seat_get_focus_inactive(seat, &con->node));
if (old_ws) {
workspace_consider_destroy(old_ws);
}
}
static void disable_fullscreen(struct sway_container *con, void *data) {
@ -173,6 +188,8 @@ void root_scratchpad_hide(struct sway_container *con) {
return;
}
set_container_transform(con->pending.workspace, con);
disable_fullscreen(con, NULL);
container_for_each_child(con, disable_fullscreen, NULL);
container_detach(con);

View file

@ -176,22 +176,16 @@ void workspace_consider_destroy(struct sway_workspace *ws) {
static bool workspace_valid_on_output(const char *output_name,
const char *ws_name) {
struct workspace_config *wsc = workspace_find_config(ws_name);
char identifier[128];
struct sway_output *output = output_by_name_or_id(output_name);
if (!output) {
return false;
}
output_name = output->wlr_output->name;
output_get_identifier(identifier, sizeof(identifier), output);
if (!wsc) {
return true;
}
for (int i = 0; i < wsc->outputs->length; i++) {
if (strcmp(wsc->outputs->items[i], "*") == 0 ||
strcmp(wsc->outputs->items[i], output_name) == 0 ||
strcmp(wsc->outputs->items[i], identifier) == 0) {
if (output_match_name_or_id(output, wsc->outputs->items[i])) {
return true;
}
}
@ -286,13 +280,10 @@ char *workspace_next_name(const char *output_name) {
// assignments primarily, falling back to bindings and numbers.
struct sway_mode *mode = config->current_mode;
char identifier[128];
struct sway_output *output = output_by_name_or_id(output_name);
if (!output) {
return NULL;
}
output_name = output->wlr_output->name;
output_get_identifier(identifier, sizeof(identifier), output);
int order = INT_MAX;
char *target = NULL;
@ -312,9 +303,7 @@ char *workspace_next_name(const char *output_name) {
}
bool found = false;
for (int j = 0; j < wsc->outputs->length; ++j) {
if (strcmp(wsc->outputs->items[j], "*") == 0 ||
strcmp(wsc->outputs->items[j], output_name) == 0 ||
strcmp(wsc->outputs->items[j], identifier) == 0) {
if (output_match_name_or_id(output, wsc->outputs->items[j])) {
found = true;
free(target);
target = strdup(wsc->workspace);
@ -654,15 +643,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) {
char exclude_id[128] = {'\0'};
if (exclude) {
output_get_identifier(exclude_id, sizeof(exclude_id), exclude);
}
for (int i = 0; i < ws->output_priority->length; i++) {
char *name = ws->output_priority->items[i];
if (exclude && (strcmp(name, exclude->wlr_output->name) == 0
|| strcmp(name, exclude_id) == 0)) {
const char *name = ws->output_priority->items[i];
if (exclude && output_match_name_or_id(exclude, name)) {
continue;
}

View file

@ -693,15 +693,6 @@ static uint32_t render_to_cairo(struct render_context *ctx) {
struct swaybar_output *output = ctx->output;
struct swaybar *bar = output->bar;
struct swaybar_config *config = bar->config;
cairo_set_operator(cairo, CAIRO_OPERATOR_SOURCE);
if (output->focused) {
ctx->background_color = config->colors.focused_background;
} else {
ctx->background_color = config->colors.background;
}
cairo_set_source_u32(cairo, ctx->background_color);
cairo_paint(cairo);
int th;
get_text_size(cairo, config->font_description, NULL, &th, NULL, 1, false, "");
@ -763,8 +754,17 @@ void render_frame(struct swaybar_output *output) {
free_hotspots(&output->hotspots);
uint32_t background_color;
if (output->focused) {
background_color = output->bar->config->colors.focused_background;
} else {
background_color = output->bar->config->colors.background;
}
struct render_context ctx = { 0 };
ctx.output = output;
// initial background color used for deciding the best way to antialias text
ctx.background_color = background_color;
cairo_surface_t *recorder = cairo_recording_surface_create(
CAIRO_CONTENT_COLOR_ALPHA, NULL);
@ -786,10 +786,11 @@ void render_frame(struct swaybar_output *output) {
ctx.textaa_sharp = fo;
}
cairo_save(cairo);
cairo_set_operator(cairo, CAIRO_OPERATOR_CLEAR);
cairo_set_operator(cairo, CAIRO_OPERATOR_SOURCE);
cairo_set_source_u32(cairo, background_color);
cairo_paint(cairo);
cairo_restore(cairo);
uint32_t height = render_to_cairo(&ctx);
int config_height = output->bar->config->height;
if (config_height > 0) {
@ -834,13 +835,15 @@ void render_frame(struct swaybar_output *output) {
wl_surface_damage(output->surface, 0, 0,
output->width, output->height);
uint32_t bg_alpha = ctx.background_color & 0xFF;
uint32_t bg_alpha = background_color & 0xFF;
if (bg_alpha == 0xFF) {
struct wl_region *region =
wl_compositor_create_region(output->bar->compositor);
wl_region_add(region, 0, 0, INT32_MAX, INT32_MAX);
wl_surface_set_opaque_region(output->surface, region);
wl_region_destroy(region);
} else {
wl_surface_set_opaque_region(output->surface, NULL);
}
struct wl_callback *frame_callback = wl_surface_frame(output->surface);

View file

@ -10,6 +10,7 @@
#include "swaybar/tray/tray.h"
#include "list.h"
#include "log.h"
#include "stringop.h"
static const char *watcher_path = "/StatusNotifierWatcher";
@ -138,12 +139,10 @@ static int handle_new_watcher(sd_bus_message *msg,
bool init_host(struct swaybar_host *host, char *protocol,
struct swaybar_tray *tray) {
size_t len = snprintf(NULL, 0, "org.%s.StatusNotifierWatcher", protocol) + 1;
host->watcher_interface = malloc(len);
host->watcher_interface = format_str("org.%s.StatusNotifierWatcher", protocol);
if (!host->watcher_interface) {
return false;
}
snprintf(host->watcher_interface, len, "org.%s.StatusNotifierWatcher", protocol);
sd_bus_slot *reg_slot = NULL, *unreg_slot = NULL, *watcher_slot = NULL;
int ret = sd_bus_match_signal(tray->bus, &reg_slot, host->watcher_interface,
@ -173,13 +172,10 @@ bool init_host(struct swaybar_host *host, char *protocol,
}
pid_t pid = getpid();
size_t service_len = snprintf(NULL, 0, "org.%s.StatusNotifierHost-%d",
protocol, pid) + 1;
host->service = malloc(service_len);
host->service = format_str("org.%s.StatusNotifierHost-%d", protocol, pid);
if (!host->service) {
goto error;
}
snprintf(host->service, service_len, "org.%s.StatusNotifierHost-%d", protocol, pid);
ret = sd_bus_request_name(tray->bus, host->service, 0);
if (ret < 0) {
sway_log(SWAY_DEBUG, "Failed to acquire service name: %s", strerror(-ret));

View file

@ -40,9 +40,7 @@ static list_t *get_basedirs(void) {
data_dirs = strdup(data_dirs);
char *dir = strtok(data_dirs, ":");
do {
size_t path_len = snprintf(NULL, 0, "%s/icons", dir) + 1;
char *path = malloc(path_len);
snprintf(path, path_len, "%s/icons", dir);
char *path = format_str("%s/icons", dir);
list_add(basedirs, path);
} while ((dir = strtok(NULL, ":")));
free(data_dirs);
@ -206,13 +204,7 @@ static const char *entry_handler(char *group, char *key, char *value,
*/
static struct icon_theme *read_theme_file(char *basedir, char *theme_name) {
// look for index.theme file
size_t path_len = snprintf(NULL, 0, "%s/%s/index.theme", basedir,
theme_name) + 1;
char *path = malloc(path_len);
if (!path) {
return NULL;
}
snprintf(path, path_len, "%s/%s/index.theme", basedir, theme_name);
char *path = format_str("%s/%s/index.theme", basedir, theme_name);
FILE *theme_file = fopen(path, "r");
free(path);
if (!theme_file) {
@ -416,26 +408,20 @@ static char *find_icon_in_subdir(char *name, char *basedir, char *theme,
#endif
};
size_t path_len = snprintf(NULL, 0, "%s/%s/%s/%s.EXT", basedir, theme,
subdir, name) + 1;
char *path = malloc(path_len);
for (size_t i = 0; i < sizeof(extensions) / sizeof(*extensions); ++i) {
snprintf(path, path_len, "%s/%s/%s/%s.%s", basedir, theme, subdir,
name, extensions[i]);
char *path = format_str("%s/%s/%s/%s.%s",
basedir, theme, subdir, name, extensions[i]);
if (access(path, R_OK) == 0) {
return path;
}
free(path);
}
free(path);
return NULL;
}
static bool theme_exists_in_basedir(char *theme, char *basedir) {
size_t path_len = snprintf(NULL, 0, "%s/%s", basedir, theme) + 1;
char *path = malloc(path_len);
snprintf(path, path_len, "%s/%s", basedir, theme);
char *path = format_str("%s/%s", basedir, theme);
bool ret = dir_exists(path);
free(path);
return ret;

View file

@ -6,6 +6,7 @@
#include <string.h>
#include "list.h"
#include "log.h"
#include "stringop.h"
#include "swaybar/tray/watcher.h"
static const char *obj_path = "/StatusNotifierWatcher";
@ -76,9 +77,7 @@ static int register_sni(sd_bus_message *msg, void *data, sd_bus_error *error) {
service = service_or_path;
path = "/StatusNotifierItem";
}
size_t id_len = snprintf(NULL, 0, "%s%s", service, path) + 1;
id = malloc(id_len);
snprintf(id, id_len, "%s%s", service, path);
id = format_str("%s%s", service, path);
}
if (list_seq_find(watcher->items, cmp_id, id) == -1) {
@ -159,9 +158,7 @@ struct swaybar_watcher *create_watcher(char *protocol, sd_bus *bus) {
return NULL;
}
size_t len = snprintf(NULL, 0, "org.%s.StatusNotifierWatcher", protocol) + 1;
watcher->interface = malloc(len);
snprintf(watcher->interface, len, "org.%s.StatusNotifierWatcher", protocol);
watcher->interface = format_str("org.%s.StatusNotifierWatcher", protocol);
sd_bus_slot *signal_slot = NULL, *vtable_slot = NULL;
int ret = sd_bus_add_object_vtable(bus, &vtable_slot, obj_path,