This commit is contained in:
Nathaniel Symer 2018-07-12 15:51:57 +00:00 committed by GitHub
commit 0721e48062
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
128 changed files with 1670 additions and 2718 deletions

View file

@ -107,7 +107,7 @@ int main(int argc, const char **argv) {
} }
int desired_output = atoi(argv[1]); int desired_output = atoi(argv[1]);
sway_log(WLR_INFO, "Using output %d of %d", desired_output, registry->outputs->length); sway_log(L_INFO, "Using output %d of %d", desired_output, registry->outputs->length);
int i; int i;
struct output_state *output = registry->outputs->items[desired_output]; struct output_state *output = registry->outputs->items[desired_output];
struct window *window = window_setup(registry, 100, 100, false); struct window *window = window_setup(registry, 100, 100, false);

View file

@ -3,9 +3,9 @@
Use `sway_log(importance, fmt, ...)` to log. The following importances are Use `sway_log(importance, fmt, ...)` to log. The following importances are
available: available:
* `WLR_DEBUG`: Debug messages, only shows with `sway -d` * `L_DEBUG`: Debug messages, only shows with `sway -d`
* `WLR_INFO`: Informational messages * `L_INFO`: Informational messages
* `WLR_ERROR`: Error messages * `L_ERROR`: Error messages
`sway_log` is a macro that calls `_sway_log` with the current filename and line `sway_log` is a macro that calls `_sway_log` with the current filename and line
number, which are written into the log with your message. number, which are written into the log with your message.

View file

@ -18,7 +18,7 @@ enum background_mode parse_background_mode(const char *mode) {
} else if (strcmp(mode, "solid_color") == 0) { } else if (strcmp(mode, "solid_color") == 0) {
return BACKGROUND_MODE_SOLID_COLOR; return BACKGROUND_MODE_SOLID_COLOR;
} }
wlr_log(WLR_ERROR, "Unsupported background mode: %s", mode); wlr_log(L_ERROR, "Unsupported background mode: %s", mode);
return BACKGROUND_MODE_INVALID; return BACKGROUND_MODE_INVALID;
} }
@ -28,7 +28,7 @@ cairo_surface_t *load_background_image(const char *path) {
GError *err = NULL; GError *err = NULL;
GdkPixbuf *pixbuf = gdk_pixbuf_new_from_file(path, &err); GdkPixbuf *pixbuf = gdk_pixbuf_new_from_file(path, &err);
if (!pixbuf) { if (!pixbuf) {
wlr_log(WLR_ERROR, "Failed to load background image (%s).", wlr_log(L_ERROR, "Failed to load background image (%s).",
err->message); err->message);
return false; return false;
} }
@ -38,11 +38,11 @@ cairo_surface_t *load_background_image(const char *path) {
image = cairo_image_surface_create_from_png(path); image = cairo_image_surface_create_from_png(path);
#endif //HAVE_GDK_PIXBUF #endif //HAVE_GDK_PIXBUF
if (!image) { if (!image) {
wlr_log(WLR_ERROR, "Failed to read background image."); wlr_log(L_ERROR, "Failed to read background image.");
return NULL; return NULL;
} }
if (cairo_surface_status(image) != CAIRO_STATUS_SUCCESS) { if (cairo_surface_status(image) != CAIRO_STATUS_SUCCESS) {
wlr_log(WLR_ERROR, "Failed to read background image: %s." wlr_log(L_ERROR, "Failed to read background image: %s."
#ifndef HAVE_GDK_PIXBUF #ifndef HAVE_GDK_PIXBUF
"\nSway was compiled without gdk_pixbuf support, so only" "\nSway was compiled without gdk_pixbuf support, so only"
"\nPNG images can be loaded. This is the likely cause." "\nPNG images can be loaded. This is the likely cause."

View file

@ -97,7 +97,7 @@ struct ipc_response *ipc_recv_response(int socketfd) {
error_2: error_2:
free(response); free(response);
error_1: error_1:
wlr_log(WLR_ERROR, "Unable to allocate memory for IPC response"); wlr_log(L_ERROR, "Unable to allocate memory for IPC response");
return NULL; return NULL;
} }

View file

@ -2,7 +2,6 @@
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include "log.h"
list_t *create_list(void) { list_t *create_list(void) {
list_t *list = malloc(sizeof(list_t)); list_t *list = malloc(sizeof(list_t));
@ -83,20 +82,6 @@ void list_swap(list_t *list, int src, int dest) {
list->items[dest] = tmp; list->items[dest] = tmp;
} }
void list_move_to_end(list_t *list, void *item) {
int i;
for (i = 0; i < list->length; ++i) {
if (list->items[i] == item) {
break;
}
}
if (!sway_assert(i < list->length, "Item not found in list")) {
return;
}
list_del(list, i);
list_add(list, item);
}
static void list_rotate(list_t *list, int from, int to) { static void list_rotate(list_t *list, int from, int to) {
void *tmp = list->items[to]; void *tmp = list->items[to];

View file

@ -8,7 +8,7 @@ void sway_terminate(int code);
void _sway_abort(const char *format, ...) { void _sway_abort(const char *format, ...) {
va_list args; va_list args;
va_start(args, format); va_start(args, format);
_wlr_vlog(WLR_ERROR, format, args); _wlr_vlog(L_ERROR, format, args);
va_end(args); va_end(args);
sway_terminate(EXIT_FAILURE); sway_terminate(EXIT_FAILURE);
} }
@ -20,7 +20,7 @@ bool _sway_assert(bool condition, const char *format, ...) {
va_list args; va_list args;
va_start(args, format); va_start(args, format);
_wlr_vlog(WLR_ERROR, format, args); _wlr_vlog(L_ERROR, format, args);
va_end(args); va_end(args);
#ifndef NDEBUG #ifndef NDEBUG

View file

@ -81,7 +81,7 @@ PangoLayout *get_pango_layout(cairo_t *cairo, const char *font,
pango_layout_set_markup(layout, buf, -1); pango_layout_set_markup(layout, buf, -1);
free(buf); free(buf);
} else { } else {
wlr_log(WLR_ERROR, "pango_parse_markup '%s' -> error %s", text, wlr_log(L_ERROR, "pango_parse_markup '%s' -> error %s", text,
error->message); error->message);
g_error_free(error); g_error_free(error);
markup = false; // fallback to plain text markup = false; // fallback to plain text

View file

@ -9,7 +9,7 @@ char *read_line(FILE *file) {
char *string = malloc(size); char *string = malloc(size);
char lastChar = '\0'; char lastChar = '\0';
if (!string) { if (!string) {
wlr_log(WLR_ERROR, "Unable to allocate memory for read_line"); wlr_log(L_ERROR, "Unable to allocate memory for read_line");
return NULL; return NULL;
} }
while (1) { while (1) {
@ -30,7 +30,7 @@ char *read_line(FILE *file) {
char *new_string = realloc(string, size *= 2); char *new_string = realloc(string, size *= 2);
if (!new_string) { if (!new_string) {
free(string); free(string);
wlr_log(WLR_ERROR, "Unable to allocate memory for read_line"); wlr_log(L_ERROR, "Unable to allocate memory for read_line");
return NULL; return NULL;
} }
string = new_string; string = new_string;

View file

@ -92,7 +92,7 @@ static const struct {
int utf8_size(const char *s) { int utf8_size(const char *s) {
uint8_t c = (uint8_t)*s; uint8_t c = (uint8_t)*s;
for (size_t i = 0; i < sizeof(sizes) / sizeof(*sizes); ++i) { for (size_t i = 0; i < sizeof(sizes) / 2; ++i) {
if ((c & sizes[i].mask) == sizes[i].result) { if ((c & sizes[i].mask) == sizes[i].result) {
return sizes[i].octets; return sizes[i].octets;
} }

View file

@ -95,7 +95,7 @@ pid_t get_parent_pid(pid_t child) {
token = strtok(NULL, sep); // parent pid token = strtok(NULL, sep); // parent pid
parent = strtol(token, NULL, 10); parent = strtol(token, NULL, 10);
} }
free(buffer);
fclose(stat); fclose(stat);
} }
@ -113,7 +113,7 @@ uint32_t parse_color(const char *color) {
int len = strlen(color); int len = strlen(color);
if (len != 6 && len != 8) { if (len != 6 && len != 8) {
wlr_log(WLR_DEBUG, "Invalid color %s, defaulting to color 0xFFFFFFFF", color); wlr_log(L_DEBUG, "Invalid color %s, defaulting to color 0xFFFFFFFF", color);
return 0xFFFFFFFF; return 0xFFFFFFFF;
} }
uint32_t res = (uint32_t)strtoul(color, NULL, 16); uint32_t res = (uint32_t)strtoul(color, NULL, 16);

View file

@ -22,6 +22,7 @@ types=(
'get_marks' 'get_marks'
'get_bar_config' 'get_bar_config'
'get_version' 'get_version'
'get_clipboard'
) )
_arguments -s \ _arguments -s \

View file

@ -13,12 +13,11 @@ enum ipc_command_type {
IPC_GET_MARKS = 5, IPC_GET_MARKS = 5,
IPC_GET_BAR_CONFIG = 6, IPC_GET_BAR_CONFIG = 6,
IPC_GET_VERSION = 7, IPC_GET_VERSION = 7,
IPC_GET_BINDING_MODES = 8,
IPC_GET_CONFIG = 9,
// sway-specific command types // sway-specific command types
IPC_GET_INPUTS = 100, IPC_GET_INPUTS = 100,
IPC_GET_SEATS = 101, IPC_GET_CLIPBOARD = 101,
IPC_GET_SEATS = 102,
// Events sent from sway to clients. Events have the highest bits set. // Events sent from sway to clients. Events have the highest bits set.
IPC_EVENT_WORKSPACE = ((1<<31) | 0), IPC_EVENT_WORKSPACE = ((1<<31) | 0),

View file

@ -24,6 +24,4 @@ int list_seq_find(list_t *list, int compare(const void *item, const void *cmp_to
void list_stable_sort(list_t *list, int compare(const void *a, const void *b)); void list_stable_sort(list_t *list, int compare(const void *a, const void *b));
// swap two elements in a list // swap two elements in a list
void list_swap(list_t *list, int src, int dest); void list_swap(list_t *list, int src, int dest);
// move item to end of list
void list_move_to_end(list_t *list, void *item);
#endif #endif

View file

@ -3,19 +3,13 @@
#include <stdbool.h> #include <stdbool.h>
#include <wlr/util/log.h> #include <wlr/util/log.h>
#ifdef __GNUC__
#define ATTRIB_PRINTF(start, end) __attribute__((format(printf, start, end)))
#else
#define ATTRIB_PRINTF(start, end)
#endif
void _sway_abort(const char *filename, ...) ATTRIB_PRINTF(1, 2); void _sway_abort(const char *filename, ...) ATTRIB_PRINTF(1, 2);
#define sway_abort(FMT, ...) \ #define sway_abort(FMT, ...) \
_sway_abort("[%s:%d] " FMT, _wlr_strip_path(__FILE__), __LINE__, ##__VA_ARGS__) _sway_abort("[%s:%d] " FMT, wlr_strip_path(__FILE__), __LINE__, ##__VA_ARGS__)
bool _sway_assert(bool condition, const char* format, ...) ATTRIB_PRINTF(2, 3); bool _sway_assert(bool condition, const char* format, ...) ATTRIB_PRINTF(2, 3);
#define sway_assert(COND, FMT, ...) \ #define sway_assert(COND, FMT, ...) \
_sway_assert(COND, "[%s:%d] %s:" FMT, _wlr_strip_path(__FILE__), __LINE__, __PRETTY_FUNCTION__, ##__VA_ARGS__) _sway_assert(COND, "[%s:%d] %s:" FMT, wlr_strip_path(__FILE__), __LINE__, __PRETTY_FUNCTION__, ##__VA_ARGS__)
void error_handler(int sig); void error_handler(int sig);

View file

@ -79,7 +79,7 @@ void free_cmd_results(struct cmd_results *results);
* *
* Free the JSON string later on. * Free the JSON string later on.
*/ */
char *cmd_results_to_json(struct cmd_results *results); const char *cmd_results_to_json(struct cmd_results *results);
struct cmd_results *add_color(const char *name, struct cmd_results *add_color(const char *name,
char *buffer, const char *color); char *buffer, const char *color);
@ -95,6 +95,7 @@ sway_cmd cmd_client_unfocused;
sway_cmd cmd_client_urgent; sway_cmd cmd_client_urgent;
sway_cmd cmd_client_placeholder; sway_cmd cmd_client_placeholder;
sway_cmd cmd_client_background; sway_cmd cmd_client_background;
sway_cmd cmd_clipboard;
sway_cmd cmd_commands; sway_cmd cmd_commands;
sway_cmd cmd_debuglog; sway_cmd cmd_debuglog;
sway_cmd cmd_default_border; sway_cmd cmd_default_border;

View file

@ -50,7 +50,6 @@ struct sway_mode {
char *name; char *name;
list_t *keysym_bindings; list_t *keysym_bindings;
list_t *keycode_bindings; list_t *keycode_bindings;
bool pango;
}; };
struct input_config_mapped_from_region { struct input_config_mapped_from_region {
@ -271,10 +270,11 @@ enum ipc_feature {
IPC_FEATURE_EVENT_WINDOW = 2048, IPC_FEATURE_EVENT_WINDOW = 2048,
IPC_FEATURE_EVENT_BINDING = 4096, IPC_FEATURE_EVENT_BINDING = 4096,
IPC_FEATURE_EVENT_INPUT = 8192, IPC_FEATURE_EVENT_INPUT = 8192,
IPC_FEATURE_GET_SEATS = 16384, IPC_FEATURE_GET_CLIPBOARD = 16384,
IPC_FEATURE_GET_SEATS = 32768,
IPC_FEATURE_ALL_COMMANDS = IPC_FEATURE_ALL_COMMANDS =
1 | 2 | 4 | 8 | 16 | 32 | 64 | 128 | 16384, 1 | 2 | 4 | 8 | 16 | 32 | 64 | 128 | 16384 | 32768,
IPC_FEATURE_ALL_EVENTS = 256 | 512 | 1024 | 2048 | 4096 | 8192, IPC_FEATURE_ALL_EVENTS = 256 | 512 | 1024 | 2048 | 4096 | 8192,
IPC_FEATURE_ALL = IPC_FEATURE_ALL_COMMANDS | IPC_FEATURE_ALL_EVENTS, IPC_FEATURE_ALL = IPC_FEATURE_ALL_COMMANDS | IPC_FEATURE_ALL_EVENTS,
@ -340,7 +340,6 @@ struct sway_config {
int gaps_outer; int gaps_outer;
list_t *config_chain; list_t *config_chain;
const char *current_config_path;
const char *current_config; const char *current_config;
enum sway_container_border border; enum sway_container_border border;
@ -496,4 +495,7 @@ void config_update_font_height(bool recalculate);
/* Global config singleton. */ /* Global config singleton. */
extern struct sway_config *config; extern struct sway_config *config;
/* Config file currently being read */
extern const char *current_config_path;
#endif #endif

View file

@ -1,8 +1,4 @@
#include <wlr/types/wlr_surface.h> #include <wlr/types/wlr_surface.h>
struct sway_container;
void desktop_damage_surface(struct wlr_surface *surface, double lx, double ly, void desktop_damage_surface(struct wlr_surface *surface, double lx, double ly,
bool whole); bool whole);
void desktop_damage_whole_container(struct sway_container *con);

View file

@ -1,28 +0,0 @@
#ifndef _SWAY_DESKTOP_IDLE_INHIBIT_V1_H
#define _SWAY_DESKTOP_IDLE_INHIBIT_V1_H
#include <wlr/types/wlr_idle_inhibit_v1.h>
#include <wlr/types/wlr_idle.h>
#include "sway/server.h"
struct sway_idle_inhibit_manager_v1 {
struct wlr_idle_inhibit_manager_v1 *wlr_manager;
struct wl_listener new_idle_inhibitor_v1;
struct wl_list inhibitors;
struct wlr_idle *idle;
};
struct sway_idle_inhibitor_v1 {
struct sway_idle_inhibit_manager_v1 *manager;
struct sway_view *view;
struct wl_list link;
struct wl_listener destroy;
};
void idle_inhibit_v1_check_active(
struct sway_idle_inhibit_manager_v1 *manager);
struct sway_idle_inhibit_manager_v1 *sway_idle_inhibit_manager_v1_create(
struct wl_display *wl_display, struct wlr_idle *idle);
#endif

View file

@ -9,12 +9,14 @@ struct sway_server;
void ipc_init(struct sway_server *server); void ipc_init(struct sway_server *server);
void ipc_terminate(void);
struct sockaddr_un *ipc_user_sockaddr(void); struct sockaddr_un *ipc_user_sockaddr(void);
void ipc_event_workspace(struct sway_container *old, void ipc_event_workspace(struct sway_container *old,
struct sway_container *new, const char *change); struct sway_container *new, const char *change);
void ipc_event_window(struct sway_container *window, const char *change); void ipc_event_window(struct sway_container *window, const char *change);
void ipc_event_barconfig_update(struct bar_config *bar); void ipc_event_barconfig_update(struct bar_config *bar);
void ipc_event_mode(const char *mode, bool pango); void ipc_event_mode(const char *mode);
#endif #endif

View file

@ -38,16 +38,6 @@ struct sway_output {
} events; } events;
}; };
/**
* Contains a surface's root geometry information. For instance, when rendering
* a popup, this will contain the parent view's position and size.
*/
struct root_geometry {
double x, y;
int width, height;
float rotation;
};
void output_damage_whole(struct sway_output *output); void output_damage_whole(struct sway_output *output);
void output_damage_surface(struct sway_output *output, double ox, double oy, void output_damage_surface(struct sway_output *output, double ox, double oy,
@ -64,37 +54,4 @@ void output_damage_whole_container(struct sway_output *output,
struct sway_container *output_by_name(const char *name); struct sway_container *output_by_name(const char *name);
void output_enable(struct sway_output *output); void output_enable(struct sway_output *output);
bool output_has_opaque_lockscreen(struct sway_output *output,
struct sway_seat *seat);
struct sway_container *output_get_active_workspace(struct sway_output *output);
void output_render(struct sway_output *output, struct timespec *when,
pixman_region32_t *damage);
bool output_get_surface_box(struct root_geometry *geo,
struct sway_output *output, struct wlr_surface *surface, int sx, int sy,
struct wlr_box *surface_box);
void output_surface_for_each_surface(struct wlr_surface *surface,
double ox, double oy, struct root_geometry *geo,
wlr_surface_iterator_func_t iterator, void *user_data);
void output_view_for_each_surface(struct sway_view *view,
struct sway_output *output, struct root_geometry *geo,
wlr_surface_iterator_func_t iterator, void *user_data);
void output_layer_for_each_surface(struct wl_list *layer_surfaces,
struct root_geometry *geo, wlr_surface_iterator_func_t iterator,
void *user_data);
void output_unmanaged_for_each_surface(struct wl_list *unmanaged,
struct sway_output *output, struct root_geometry *geo,
wlr_surface_iterator_func_t iterator, void *user_data);
void output_drag_icons_for_each_surface(struct wl_list *drag_icons,
struct sway_output *output, struct root_geometry *geo,
wlr_surface_iterator_func_t iterator, void *user_data);
#endif #endif

View file

@ -23,14 +23,12 @@ struct sway_server {
struct wlr_compositor *compositor; struct wlr_compositor *compositor;
struct wlr_data_device_manager *data_device_manager; struct wlr_data_device_manager *data_device_manager;
struct wlr_idle *idle;
struct sway_input_manager *input; struct sway_input_manager *input;
struct wl_listener new_output; struct wl_listener new_output;
struct wlr_idle *idle;
struct sway_idle_inhibit_manager_v1 *idle_inhibit_manager_v1;
struct wlr_layer_shell *layer_shell; struct wlr_layer_shell *layer_shell;
struct wl_listener layer_shell_surface; struct wl_listener layer_shell_surface;
@ -63,7 +61,6 @@ void server_run(struct sway_server *server);
void handle_new_output(struct wl_listener *listener, void *data); void handle_new_output(struct wl_listener *listener, void *data);
void handle_idle_inhibitor_v1(struct wl_listener *listener, void *data);
void handle_layer_shell_surface(struct wl_listener *listener, void *data); void handle_layer_shell_surface(struct wl_listener *listener, void *data);
void handle_xdg_shell_v6_surface(struct wl_listener *listener, void *data); void handle_xdg_shell_v6_surface(struct wl_listener *listener, void *data);
void handle_xdg_shell_surface(struct wl_listener *listener, void *data); void handle_xdg_shell_surface(struct wl_listener *listener, void *data);

View file

@ -297,10 +297,4 @@ bool container_is_floating(struct sway_container *container);
*/ */
void container_get_box(struct sway_container *container, struct wlr_box *box); void container_get_box(struct sway_container *container, struct wlr_box *box);
/**
* Move a floating container to a new layout-local position.
*/
void container_floating_move_to(struct sway_container *con,
double lx, double ly);
#endif #endif

View file

@ -19,33 +19,10 @@ enum auth_state {
AUTH_STATE_INVALID, AUTH_STATE_INVALID,
}; };
struct swaylock_colorset {
uint32_t input;
uint32_t cleared;
uint32_t verifying;
uint32_t wrong;
};
struct swaylock_colors {
uint32_t background;
uint32_t bs_highlight;
uint32_t key_highlight;
uint32_t separator;
struct swaylock_colorset inside;
struct swaylock_colorset line;
struct swaylock_colorset ring;
struct swaylock_colorset text;
};
struct swaylock_args { struct swaylock_args {
struct swaylock_colors colors; uint32_t color;
enum background_mode mode; enum background_mode mode;
char *font;
uint32_t radius;
uint32_t thickness;
bool ignore_empty;
bool show_indicator; bool show_indicator;
bool daemonize;
}; };
struct swaylock_password { struct swaylock_password {

View file

@ -100,8 +100,6 @@ static struct cmd_handler handlers[] = {
{ "default_border", cmd_default_border }, { "default_border", cmd_default_border },
{ "exec", cmd_exec }, { "exec", cmd_exec },
{ "exec_always", cmd_exec_always }, { "exec_always", cmd_exec_always },
{ "floating_maximum_size", cmd_floating_maximum_size },
{ "floating_minimum_size", cmd_floating_minimum_size },
{ "focus_follows_mouse", cmd_focus_follows_mouse }, { "focus_follows_mouse", cmd_focus_follows_mouse },
{ "focus_wrapping", cmd_focus_wrapping }, { "focus_wrapping", cmd_focus_wrapping },
{ "font", cmd_font }, { "font", cmd_font },
@ -165,7 +163,7 @@ struct cmd_handler *find_handler(char *line, struct cmd_handler *cmd_handlers,
int handlers_size) { int handlers_size) {
struct cmd_handler d = { .command=line }; struct cmd_handler d = { .command=line };
struct cmd_handler *res = NULL; struct cmd_handler *res = NULL;
wlr_log(WLR_DEBUG, "find_handler(%s)", line); wlr_log(L_DEBUG, "find_handler(%s)", line);
bool config_loading = config->reading || !config->active; bool config_loading = config->reading || !config->active;
@ -250,10 +248,10 @@ struct cmd_results *execute_command(char *_exec, struct sway_seat *seat) {
cmd = argsep(&cmdlist, ","); cmd = argsep(&cmdlist, ",");
cmd += strspn(cmd, whitespace); cmd += strspn(cmd, whitespace);
if (strcmp(cmd, "") == 0) { if (strcmp(cmd, "") == 0) {
wlr_log(WLR_INFO, "Ignoring empty command."); wlr_log(L_INFO, "Ignoring empty command.");
continue; continue;
} }
wlr_log(WLR_INFO, "Handling command '%s'", cmd); wlr_log(L_INFO, "Handling command '%s'", cmd);
//TODO better handling of argv //TODO better handling of argv
int argc; int argc;
char **argv = split_args(cmd, &argc); char **argv = split_args(cmd, &argc);
@ -357,7 +355,7 @@ struct cmd_results *config_command(char *exec) {
results = cmd_results_new(CMD_BLOCK_END, NULL, NULL); results = cmd_results_new(CMD_BLOCK_END, NULL, NULL);
goto cleanup; goto cleanup;
} }
wlr_log(WLR_INFO, "handling config command '%s'", exec); wlr_log(L_INFO, "handling config command '%s'", exec);
struct cmd_handler *handler = find_handler(argv[0], NULL, 0); struct cmd_handler *handler = find_handler(argv[0], NULL, 0);
if (!handler) { if (!handler) {
char *input = argv[0] ? argv[0] : "(empty)"; char *input = argv[0] ? argv[0] : "(empty)";
@ -390,7 +388,7 @@ cleanup:
struct cmd_results *config_subcommand(char **argv, int argc, struct cmd_results *config_subcommand(char **argv, int argc,
struct cmd_handler *handlers, size_t handlers_size) { struct cmd_handler *handlers, size_t handlers_size) {
char *command = join_args(argv, argc); char *command = join_args(argv, argc);
wlr_log(WLR_DEBUG, "Subcommand: %s", command); wlr_log(L_DEBUG, "Subcommand: %s", command);
free(command); free(command);
struct cmd_handler *handler = find_handler(argv[0], handlers, struct cmd_handler *handler = find_handler(argv[0], handlers,
@ -430,7 +428,8 @@ struct cmd_results *config_commands_command(char *exec) {
struct cmd_handler *handler = find_handler(cmd, NULL, 0); struct cmd_handler *handler = find_handler(cmd, NULL, 0);
if (!handler && strcmp(cmd, "*") != 0) { if (!handler && strcmp(cmd, "*") != 0) {
results = cmd_results_new(CMD_INVALID, cmd, "Unknown/invalid command"); char *input = cmd ? cmd : "(empty)";
results = cmd_results_new(CMD_INVALID, input, "Unknown/invalid command");
goto cleanup; goto cleanup;
} }
@ -472,16 +471,14 @@ struct cmd_results *config_commands_command(char *exec) {
} }
if (!policy) { if (!policy) {
policy = alloc_command_policy(cmd); policy = alloc_command_policy(cmd);
if (!sway_assert(policy, "Unable to allocate security policy")) { sway_assert(policy, "Unable to allocate security policy");
results = cmd_results_new(CMD_INVALID, cmd, if (policy) {
"Unable to allocate memory");
goto cleanup;
}
list_add(config->command_policies, policy); list_add(config->command_policies, policy);
} }
}
policy->context = context; policy->context = context;
wlr_log(WLR_INFO, "Set command policy for %s to %d", wlr_log(L_INFO, "Set command policy for %s to %d",
policy->command, policy->context); policy->command, policy->context);
results = cmd_results_new(CMD_SUCCESS, NULL, NULL); results = cmd_results_new(CMD_SUCCESS, NULL, NULL);
@ -495,7 +492,7 @@ struct cmd_results *cmd_results_new(enum cmd_status status,
const char *input, const char *format, ...) { const char *input, const char *format, ...) {
struct cmd_results *results = malloc(sizeof(struct cmd_results)); struct cmd_results *results = malloc(sizeof(struct cmd_results));
if (!results) { if (!results) {
wlr_log(WLR_ERROR, "Unable to allocate command results"); wlr_log(L_ERROR, "Unable to allocate command results");
return NULL; return NULL;
} }
results->status = status; results->status = status;
@ -529,7 +526,7 @@ void free_cmd_results(struct cmd_results *results) {
free(results); free(results);
} }
char *cmd_results_to_json(struct cmd_results *results) { const char *cmd_results_to_json(struct cmd_results *results) {
json_object *result_array = json_object_new_array(); json_object *result_array = json_object_new_array();
json_object *root = json_object_new_object(); json_object *root = json_object_new_object();
json_object_object_add(root, "success", json_object_object_add(root, "success",
@ -544,9 +541,9 @@ char *cmd_results_to_json(struct cmd_results *results) {
} }
json_object_array_add(result_array, root); json_object_array_add(result_array, root);
const char *json = json_object_to_json_string(result_array); const char *json = json_object_to_json_string(result_array);
char *res = strdup(json); free(result_array);
json_object_put(result_array); free(root);
return res; return json;
} }
/** /**

View file

@ -27,7 +27,6 @@ struct cmd_results *cmd_assign(int argc, char **argv) {
if (strncmp(*argv, "", strlen("")) == 0) { if (strncmp(*argv, "", strlen("")) == 0) {
if (argc < 3) { if (argc < 3) {
free(criteria);
return cmd_results_new(CMD_INVALID, "assign", "Missing workspace"); return cmd_results_new(CMD_INVALID, "assign", "Missing workspace");
} }
++argv; ++argv;
@ -45,7 +44,7 @@ struct cmd_results *cmd_assign(int argc, char **argv) {
criteria->target = join_args(argv, target_len); criteria->target = join_args(argv, target_len);
list_add(config->criteria, criteria); list_add(config->criteria, criteria);
wlr_log(WLR_DEBUG, "assign: '%s' -> '%s' added", criteria->raw, wlr_log(L_DEBUG, "assign: '%s' -> '%s' added", criteria->raw,
criteria->target); criteria->target);
return cmd_results_new(CMD_SUCCESS, NULL, NULL); return cmd_results_new(CMD_SUCCESS, NULL, NULL);

View file

@ -63,13 +63,13 @@ struct cmd_results *cmd_bar(int argc, char **argv) {
for (int i = 0; i < config->bars->length; ++i) { for (int i = 0; i < config->bars->length; ++i) {
struct bar_config *item = config->bars->items[i]; struct bar_config *item = config->bars->items[i];
if (strcmp(item->id, argv[0]) == 0) { if (strcmp(item->id, argv[0]) == 0) {
wlr_log(WLR_DEBUG, "Selecting bar: %s", argv[0]); wlr_log(L_DEBUG, "Selecting bar: %s", argv[0]);
bar = item; bar = item;
break; break;
} }
} }
if (!bar) { if (!bar) {
wlr_log(WLR_DEBUG, "Creating bar: %s", argv[0]); wlr_log(L_DEBUG, "Creating bar: %s", argv[0]);
bar = default_bar_config(); bar = default_bar_config();
if (!bar) { if (!bar) {
return cmd_results_new(CMD_FAILURE, "bar", return cmd_results_new(CMD_FAILURE, "bar",
@ -108,7 +108,7 @@ struct cmd_results *cmd_bar(int argc, char **argv) {
// Set current bar // Set current bar
config->current_bar = bar; config->current_bar = bar;
wlr_log(WLR_DEBUG, "Creating bar %s", bar->id); wlr_log(L_DEBUG, "Creating bar %s", bar->id);
} }
return config_subcommand(argv, argc, bar_handlers, sizeof(bar_handlers)); return config_subcommand(argv, argc, bar_handlers, sizeof(bar_handlers));

View file

@ -15,11 +15,11 @@ struct cmd_results *bar_cmd_binding_mode_indicator(int argc, char **argv) {
} }
if (strcasecmp("yes", argv[0]) == 0) { if (strcasecmp("yes", argv[0]) == 0) {
config->current_bar->binding_mode_indicator = true; config->current_bar->binding_mode_indicator = true;
wlr_log(WLR_DEBUG, "Enabling binding mode indicator on bar: %s", wlr_log(L_DEBUG, "Enabling binding mode indicator on bar: %s",
config->current_bar->id); config->current_bar->id);
} else if (strcasecmp("no", argv[0]) == 0) { } else if (strcasecmp("no", argv[0]) == 0) {
config->current_bar->binding_mode_indicator = false; config->current_bar->binding_mode_indicator = false;
wlr_log(WLR_DEBUG, "Disabling binding mode indicator on bar: %s", wlr_log(L_DEBUG, "Disabling binding mode indicator on bar: %s",
config->current_bar->id); config->current_bar->id);
} }
return cmd_results_new(CMD_INVALID, "binding_mode_indicator", return cmd_results_new(CMD_INVALID, "binding_mode_indicator",

View file

@ -14,8 +14,8 @@ struct cmd_results *bar_cmd_font(int argc, char **argv) {
} }
char *font = join_args(argv, argc); char *font = join_args(argv, argc);
free(config->current_bar->font); free(config->current_bar->font);
config->current_bar->font = font; config->current_bar->font = strdup(font);
wlr_log(WLR_DEBUG, "Settings font '%s' for bar: %s", wlr_log(L_DEBUG, "Settings font '%s' for bar: %s",
config->current_bar->font, config->current_bar->id); config->current_bar->font, config->current_bar->id);
return cmd_results_new(CMD_SUCCESS, NULL, NULL); return cmd_results_new(CMD_SUCCESS, NULL, NULL);
} }

View file

@ -14,7 +14,7 @@ struct cmd_results *bar_cmd_height(int argc, char **argv) {
"Invalid height value: %s", argv[0]); "Invalid height value: %s", argv[0]);
} }
config->current_bar->height = height; config->current_bar->height = height;
wlr_log(WLR_DEBUG, "Setting bar height to %d on bar: %s", wlr_log(L_DEBUG, "Setting bar height to %d on bar: %s",
height, config->current_bar->id); height, config->current_bar->id);
return cmd_results_new(CMD_SUCCESS, NULL, NULL); return cmd_results_new(CMD_SUCCESS, NULL, NULL);
} }

View file

@ -27,7 +27,7 @@ static struct cmd_results *bar_set_hidden_state(struct bar_config *bar,
if (!config->reading) { if (!config->reading) {
ipc_event_barconfig_update(bar); ipc_event_barconfig_update(bar);
} }
wlr_log(WLR_DEBUG, "Setting hidden_state: '%s' for bar: %s", wlr_log(L_DEBUG, "Setting hidden_state: '%s' for bar: %s",
bar->hidden_state, bar->id); bar->hidden_state, bar->id);
} }
// free old mode // free old mode

View file

@ -24,7 +24,7 @@ struct cmd_results *bar_cmd_id(int argc, char **argv) {
} }
} }
wlr_log(WLR_DEBUG, "Renaming bar: '%s' to '%s'", oldname, name); wlr_log(L_DEBUG, "Renaming bar: '%s' to '%s'", oldname, name);
// free old bar id // free old bar id
free(config->current_bar->id); free(config->current_bar->id);

View file

@ -28,7 +28,7 @@ static struct cmd_results *bar_set_mode(struct bar_config *bar, const char *mode
if (!config->reading) { if (!config->reading) {
ipc_event_barconfig_update(bar); ipc_event_barconfig_update(bar);
} }
wlr_log(WLR_DEBUG, "Setting mode: '%s' for bar: %s", bar->mode, bar->id); wlr_log(L_DEBUG, "Setting mode: '%s' for bar: %s", bar->mode, bar->id);
} }
// free old mode // free old mode

View file

@ -22,15 +22,14 @@ struct cmd_results *bar_cmd_modifier(int argc, char **argv) {
mod |= tmp_mod; mod |= tmp_mod;
continue; continue;
} else { } else {
error = cmd_results_new(CMD_INVALID, "modifier",
"Unknown modifier '%s'", split->items[i]);
free_flat_list(split); free_flat_list(split);
return error; return cmd_results_new(CMD_INVALID, "modifier",
"Unknown modifier '%s'", split->items[i]);
} }
} }
free_flat_list(split); free_flat_list(split);
config->current_bar->modifier = mod; config->current_bar->modifier = mod;
wlr_log(WLR_DEBUG, wlr_log(L_DEBUG,
"Show/Hide the bar when pressing '%s' in hide mode.", argv[0]); "Show/Hide the bar when pressing '%s' in hide mode.", argv[0]);
return cmd_results_new(CMD_SUCCESS, NULL, NULL); return cmd_results_new(CMD_SUCCESS, NULL, NULL);
} }

View file

@ -42,7 +42,7 @@ struct cmd_results *bar_cmd_output(int argc, char **argv) {
if (add_output) { if (add_output) {
list_add(outputs, strdup(output)); list_add(outputs, strdup(output));
wlr_log(WLR_DEBUG, "Adding bar: '%s' to output '%s'", wlr_log(L_DEBUG, "Adding bar: '%s' to output '%s'",
config->current_bar->id, output); config->current_bar->id, output);
} }
return cmd_results_new(CMD_SUCCESS, NULL, NULL); return cmd_results_new(CMD_SUCCESS, NULL, NULL);

View file

@ -13,11 +13,11 @@ struct cmd_results *bar_cmd_pango_markup(int argc, char **argv) {
} }
if (strcasecmp("enabled", argv[0]) == 0) { if (strcasecmp("enabled", argv[0]) == 0) {
config->current_bar->pango_markup = true; config->current_bar->pango_markup = true;
wlr_log(WLR_DEBUG, "Enabling pango markup for bar: %s", wlr_log(L_DEBUG, "Enabling pango markup for bar: %s",
config->current_bar->id); config->current_bar->id);
} else if (strcasecmp("disabled", argv[0]) == 0) { } else if (strcasecmp("disabled", argv[0]) == 0) {
config->current_bar->pango_markup = false; config->current_bar->pango_markup = false;
wlr_log(WLR_DEBUG, "Disabling pango markup for bar: %s", wlr_log(L_DEBUG, "Disabling pango markup for bar: %s",
config->current_bar->id); config->current_bar->id);
} else { } else {
error = cmd_results_new(CMD_INVALID, "pango_markup", error = cmd_results_new(CMD_INVALID, "pango_markup",

View file

@ -15,7 +15,7 @@ struct cmd_results *bar_cmd_position(int argc, char **argv) {
char *valid[] = { "top", "bottom", "left", "right" }; char *valid[] = { "top", "bottom", "left", "right" };
for (size_t i = 0; i < sizeof(valid) / sizeof(valid[0]); ++i) { for (size_t i = 0; i < sizeof(valid) / sizeof(valid[0]); ++i) {
if (strcasecmp(valid[i], argv[0]) == 0) { if (strcasecmp(valid[i], argv[0]) == 0) {
wlr_log(WLR_DEBUG, "Setting bar position '%s' for bar: %s", wlr_log(L_DEBUG, "Setting bar position '%s' for bar: %s",
argv[0], config->current_bar->id); argv[0], config->current_bar->id);
config->current_bar->position = strdup(argv[0]); config->current_bar->position = strdup(argv[0]);
return cmd_results_new(CMD_SUCCESS, NULL, NULL); return cmd_results_new(CMD_SUCCESS, NULL, NULL);

View file

@ -14,7 +14,7 @@ struct cmd_results *bar_cmd_separator_symbol(int argc, char **argv) {
} }
free(config->current_bar->separator_symbol); free(config->current_bar->separator_symbol);
config->current_bar->separator_symbol = strdup(argv[0]); config->current_bar->separator_symbol = strdup(argv[0]);
wlr_log(WLR_DEBUG, "Settings separator_symbol '%s' for bar: %s", wlr_log(L_DEBUG, "Settings separator_symbol '%s' for bar: %s",
config->current_bar->separator_symbol, config->current_bar->id); config->current_bar->separator_symbol, config->current_bar->id);
return cmd_results_new(CMD_SUCCESS, NULL, NULL); return cmd_results_new(CMD_SUCCESS, NULL, NULL);
} }

View file

@ -14,7 +14,7 @@ struct cmd_results *bar_cmd_status_command(int argc, char **argv) {
} }
free(config->current_bar->status_command); free(config->current_bar->status_command);
config->current_bar->status_command = join_args(argv, argc); config->current_bar->status_command = join_args(argv, argc);
wlr_log(WLR_DEBUG, "Feeding bar with status command: %s", wlr_log(L_DEBUG, "Feeding bar with status command: %s",
config->current_bar->status_command); config->current_bar->status_command);
return cmd_results_new(CMD_SUCCESS, NULL, NULL); return cmd_results_new(CMD_SUCCESS, NULL, NULL);
} }

View file

@ -15,11 +15,11 @@ struct cmd_results *bar_cmd_strip_workspace_numbers(int argc, char **argv) {
} }
if (strcasecmp("yes", argv[0]) == 0) { if (strcasecmp("yes", argv[0]) == 0) {
config->current_bar->strip_workspace_numbers = true; config->current_bar->strip_workspace_numbers = true;
wlr_log(WLR_DEBUG, "Stripping workspace numbers on bar: %s", wlr_log(L_DEBUG, "Stripping workspace numbers on bar: %s",
config->current_bar->id); config->current_bar->id);
} else if (strcasecmp("no", argv[0]) == 0) { } else if (strcasecmp("no", argv[0]) == 0) {
config->current_bar->strip_workspace_numbers = false; config->current_bar->strip_workspace_numbers = false;
wlr_log(WLR_DEBUG, "Enabling workspace numbers on bar: %s", wlr_log(L_DEBUG, "Enabling workspace numbers on bar: %s",
config->current_bar->id); config->current_bar->id);
} else { } else {
return cmd_results_new(CMD_INVALID, return cmd_results_new(CMD_INVALID,

View file

@ -14,7 +14,7 @@ struct cmd_results *bar_cmd_swaybar_command(int argc, char **argv) {
} }
free(config->current_bar->swaybar_command); free(config->current_bar->swaybar_command);
config->current_bar->swaybar_command = join_args(argv, argc); config->current_bar->swaybar_command = join_args(argv, argc);
wlr_log(WLR_DEBUG, "Using custom swaybar command: %s", wlr_log(L_DEBUG, "Using custom swaybar command: %s",
config->current_bar->swaybar_command); config->current_bar->swaybar_command);
return cmd_results_new(CMD_SUCCESS, NULL, NULL); return cmd_results_new(CMD_SUCCESS, NULL, NULL);
} }

View file

@ -14,11 +14,11 @@ struct cmd_results *bar_cmd_workspace_buttons(int argc, char **argv) {
} }
if (strcasecmp("yes", argv[0]) == 0) { if (strcasecmp("yes", argv[0]) == 0) {
config->current_bar->workspace_buttons = true; config->current_bar->workspace_buttons = true;
wlr_log(WLR_DEBUG, "Enabling workspace buttons on bar: %s", wlr_log(L_DEBUG, "Enabling workspace buttons on bar: %s",
config->current_bar->id); config->current_bar->id);
} else if (strcasecmp("no", argv[0]) == 0) { } else if (strcasecmp("no", argv[0]) == 0) {
config->current_bar->workspace_buttons = false; config->current_bar->workspace_buttons = false;
wlr_log(WLR_DEBUG, "Disabling workspace buttons on bar: %s", wlr_log(L_DEBUG, "Disabling workspace buttons on bar: %s",
config->current_bar->id); config->current_bar->id);
} else { } else {
return cmd_results_new(CMD_INVALID, "workspace_buttons", return cmd_results_new(CMD_INVALID, "workspace_buttons",

View file

@ -13,11 +13,11 @@ struct cmd_results *bar_cmd_wrap_scroll(int argc, char **argv) {
} }
if (strcasecmp("yes", argv[0]) == 0) { if (strcasecmp("yes", argv[0]) == 0) {
config->current_bar->wrap_scroll = true; config->current_bar->wrap_scroll = true;
wlr_log(WLR_DEBUG, "Enabling wrap scroll on bar: %s", wlr_log(L_DEBUG, "Enabling wrap scroll on bar: %s",
config->current_bar->id); config->current_bar->id);
} else if (strcasecmp("no", argv[0]) == 0) { } else if (strcasecmp("no", argv[0]) == 0) {
config->current_bar->wrap_scroll = false; config->current_bar->wrap_scroll = false;
wlr_log(WLR_DEBUG, "Disabling wrap scroll on bar: %s", wlr_log(L_DEBUG, "Disabling wrap scroll on bar: %s",
config->current_bar->id); config->current_bar->id);
} else { } else {
return cmd_results_new(CMD_INVALID, return cmd_results_new(CMD_INVALID,

View file

@ -184,7 +184,7 @@ static struct cmd_results *cmd_bindsym_or_bindcode(int argc, char **argv,
for (int i = 0; i < mode_bindings->length; ++i) { for (int i = 0; i < mode_bindings->length; ++i) {
struct sway_binding *config_binding = mode_bindings->items[i]; struct sway_binding *config_binding = mode_bindings->items[i];
if (binding_key_compare(binding, config_binding)) { if (binding_key_compare(binding, config_binding)) {
wlr_log(WLR_DEBUG, "overwriting old binding with command '%s'", wlr_log(L_DEBUG, "overwriting old binding with command '%s'",
config_binding->command); config_binding->command);
free_sway_binding(config_binding); free_sway_binding(config_binding);
mode_bindings->items[i] = binding; mode_bindings->items[i] = binding;
@ -196,7 +196,7 @@ static struct cmd_results *cmd_bindsym_or_bindcode(int argc, char **argv,
list_add(mode_bindings, binding); list_add(mode_bindings, binding);
} }
wlr_log(WLR_DEBUG, "%s - Bound %s to command %s", wlr_log(L_DEBUG, "%s - Bound %s to command %s",
bindtype, argv[0], binding->command); bindtype, argv[0], binding->command);
return cmd_results_new(CMD_SUCCESS, NULL, NULL); return cmd_results_new(CMD_SUCCESS, NULL, NULL);

View file

@ -8,7 +8,7 @@ struct cmd_results *cmd_exec(int argc, char **argv) {
if (!config->active) return cmd_results_new(CMD_DEFER, "exec", NULL); if (!config->active) return cmd_results_new(CMD_DEFER, "exec", NULL);
if (config->reloading) { if (config->reloading) {
char *args = join_args(argv, argc); char *args = join_args(argv, argc);
wlr_log(WLR_DEBUG, "Ignoring 'exec %s' due to reload", args); wlr_log(L_DEBUG, "Ignoring 'exec %s' due to reload", args);
free(args); free(args);
return cmd_results_new(CMD_SUCCESS, NULL, NULL); return cmd_results_new(CMD_SUCCESS, NULL, NULL);
} }

View file

@ -20,7 +20,7 @@ struct cmd_results *cmd_exec_always(int argc, char **argv) {
char *tmp = NULL; char *tmp = NULL;
if (strcmp((char*)*argv, "--no-startup-id") == 0) { if (strcmp((char*)*argv, "--no-startup-id") == 0) {
wlr_log(WLR_INFO, "exec switch '--no-startup-id' not supported, ignored."); wlr_log(L_INFO, "exec switch '--no-startup-id' not supported, ignored.");
if ((error = checkarg(argc - 1, "exec_always", EXPECTED_MORE_THAN, 0))) { if ((error = checkarg(argc - 1, "exec_always", EXPECTED_MORE_THAN, 0))) {
return error; return error;
} }
@ -35,49 +35,50 @@ struct cmd_results *cmd_exec_always(int argc, char **argv) {
strncpy(cmd, tmp, sizeof(cmd) - 1); strncpy(cmd, tmp, sizeof(cmd) - 1);
cmd[sizeof(cmd) - 1] = 0; cmd[sizeof(cmd) - 1] = 0;
free(tmp); free(tmp);
wlr_log(WLR_DEBUG, "Executing %s", cmd); wlr_log(L_DEBUG, "Executing %s", cmd);
int fd[2]; int fd[2];
if (pipe(fd) != 0) { if (pipe(fd) != 0) {
wlr_log(WLR_ERROR, "Unable to create pipe for fork"); wlr_log(L_ERROR, "Unable to create pipe for fork");
} }
pid_t pid, child; pid_t pid;
pid_t *child = malloc(sizeof(pid_t)); // malloc'd so that Linux can avoid copying the process space
if (!child) {
return cmd_results_new(CMD_FAILURE, "exec_always", "Unable to allocate child pid");
}
// Fork process // Fork process
if ((pid = fork()) == 0) { if ((pid = fork()) == 0) {
// Fork child process again // Fork child process again
setsid(); setsid();
close(fd[0]); if ((*child = fork()) == 0) {
if ((child = fork()) == 0) {
close(fd[1]);
execl("/bin/sh", "/bin/sh", "-c", cmd, (void *)NULL); execl("/bin/sh", "/bin/sh", "-c", cmd, (void *)NULL);
_exit(0); // Not reached
} }
close(fd[0]);
ssize_t s = 0; ssize_t s = 0;
while ((size_t)s < sizeof(pid_t)) { while ((size_t)s < sizeof(pid_t)) {
s += write(fd[1], ((uint8_t *)&child) + s, sizeof(pid_t) - s); s += write(fd[1], ((uint8_t *)child) + s, sizeof(pid_t) - s);
} }
close(fd[1]); close(fd[1]);
_exit(0); // Close child process _exit(0); // Close child process
} else if (pid < 0) { } else if (pid < 0) {
close(fd[0]); free(child);
close(fd[1]);
return cmd_results_new(CMD_FAILURE, "exec_always", "fork() failed"); return cmd_results_new(CMD_FAILURE, "exec_always", "fork() failed");
} }
close(fd[1]); // close write close(fd[1]); // close write
ssize_t s = 0; ssize_t s = 0;
while ((size_t)s < sizeof(pid_t)) { while ((size_t)s < sizeof(pid_t)) {
s += read(fd[0], ((uint8_t *)&child) + s, sizeof(pid_t) - s); s += read(fd[0], ((uint8_t *)child) + s, sizeof(pid_t) - s);
} }
close(fd[0]); close(fd[0]);
// cleanup child process // cleanup child process
waitpid(pid, NULL, 0); waitpid(pid, NULL, 0);
if (child > 0) { if (*child > 0) {
wlr_log(WLR_DEBUG, "Child process created with pid %d", child); wlr_log(L_DEBUG, "Child process created with pid %d", *child);
// TODO: add PID to active workspace // TODO: add PID to active workspace
} else { } else {
return cmd_results_new(CMD_FAILURE, "exec_always", free(child);
"Second fork() failed");
} }
return cmd_results_new(CMD_SUCCESS, NULL, NULL); return cmd_results_new(CMD_SUCCESS, NULL, NULL);

View file

@ -1,53 +0,0 @@
#include <errno.h>
#include <math.h>
#include <stdbool.h>
#include <stdlib.h>
#include <string.h>
#include <strings.h>
#include <wlr/util/log.h>
#include "sway/commands.h"
#include "log.h"
static const char* min_usage =
"Expected 'floating_minimum_size <width> x <height>'";
static const char* max_usage =
"Expected 'floating_maximum_size <width> x <height>'";
static struct cmd_results *handle_command(int argc, char **argv, char *cmd_name,
const char *usage, int *config_width, int *config_height) {
struct cmd_results *error;
if ((error = checkarg(argc, cmd_name, EXPECTED_EQUAL_TO, 3))) {
return error;
}
char *err;
int width = (int)strtol(argv[0], &err, 10);
if (*err) {
return cmd_results_new(CMD_INVALID, cmd_name, usage);
}
if (strcmp(argv[1], "x") != 0) {
return cmd_results_new(CMD_INVALID, cmd_name, usage);
}
int height = (int)strtol(argv[2], &err, 10);
if (*err) {
return cmd_results_new(CMD_INVALID, cmd_name, usage);
}
*config_width = width;
*config_height = height;
return cmd_results_new(CMD_SUCCESS, NULL, NULL);
}
struct cmd_results *cmd_floating_minimum_size(int argc, char **argv) {
return handle_command(argc, argv, "floating_minimum_size", min_usage,
&config->floating_minimum_width, &config->floating_minimum_height);
}
struct cmd_results *cmd_floating_maximum_size(int argc, char **argv) {
return handle_command(argc, argv, "floating_maximum_size", max_usage,
&config->floating_maximum_width, &config->floating_maximum_height);
}

View file

@ -1,12 +1,10 @@
#include <strings.h> #include <strings.h>
#include <wlr/util/log.h> #include <wlr/util/log.h>
#include "log.h" #include "log.h"
#include "sway/commands.h"
#include "sway/input/input-manager.h" #include "sway/input/input-manager.h"
#include "sway/input/seat.h" #include "sway/input/seat.h"
#include "sway/tree/arrange.h"
#include "sway/tree/view.h" #include "sway/tree/view.h"
#include "sway/tree/workspace.h" #include "sway/commands.h"
static bool parse_movement_direction(const char *name, static bool parse_movement_direction(const char *name,
enum movement_direction *out) { enum movement_direction *out) {
@ -29,21 +27,6 @@ static bool parse_movement_direction(const char *name,
return true; return true;
} }
static struct cmd_results *focus_mode(struct sway_container *con,
struct sway_seat *seat, bool floating) {
struct sway_container *ws = con->type == C_WORKSPACE ?
con : container_parent(con, C_WORKSPACE);
struct sway_container *new_focus = ws;
if (floating) {
new_focus = ws->sway_workspace->floating;
if (new_focus->children->length == 0) {
return cmd_results_new(CMD_SUCCESS, NULL, NULL);
}
}
seat_set_focus(seat, seat_get_active_child(seat, new_focus));
return cmd_results_new(CMD_SUCCESS, NULL, NULL);
}
struct cmd_results *cmd_focus(int argc, char **argv) { struct cmd_results *cmd_focus(int argc, char **argv) {
struct sway_container *con = config->handler_context.current_container; struct sway_container *con = config->handler_context.current_container;
struct sway_seat *seat = config->handler_context.seat; struct sway_seat *seat = config->handler_context.seat;
@ -57,20 +40,11 @@ struct cmd_results *cmd_focus(int argc, char **argv) {
return cmd_results_new(CMD_SUCCESS, NULL, NULL); return cmd_results_new(CMD_SUCCESS, NULL, NULL);
} }
if (strcmp(argv[0], "floating") == 0) { // TODO mode_toggle
return focus_mode(con, seat, true);
} else if (strcmp(argv[0], "tiling") == 0) {
return focus_mode(con, seat, false);
} else if (strcmp(argv[0], "mode_toggle") == 0) {
return focus_mode(con, seat, !container_is_floating(con));
}
// TODO: focus output <direction|name>
enum movement_direction direction = 0; enum movement_direction direction = 0;
if (!parse_movement_direction(argv[0], &direction)) { if (!parse_movement_direction(argv[0], &direction)) {
return cmd_results_new(CMD_INVALID, "focus", return cmd_results_new(CMD_INVALID, "focus",
"Expected 'focus <direction|parent|child|mode_toggle|floating|tiling>' " "Expected 'focus <direction|parent|child|mode_toggle>' or 'focus output <direction|name>'");
"or 'focus output <direction|name>'");
} }
struct sway_container *next_focus = container_get_in_direction( struct sway_container *next_focus = container_get_in_direction(

View file

@ -24,7 +24,7 @@ struct cmd_results *cmd_for_window(int argc, char **argv) {
criteria->cmdlist = join_args(argv + 1, argc - 1); criteria->cmdlist = join_args(argv + 1, argc - 1);
list_add(config->criteria, criteria); list_add(config->criteria, criteria);
wlr_log(WLR_DEBUG, "for_window: '%s' -> '%s' added", criteria->raw, criteria->cmdlist); wlr_log(L_DEBUG, "for_window: '%s' -> '%s' added", criteria->raw, criteria->cmdlist);
return cmd_results_new(CMD_SUCCESS, NULL, NULL); return cmd_results_new(CMD_SUCCESS, NULL, NULL);
} }

View file

@ -6,6 +6,11 @@
#include "stringop.h" #include "stringop.h"
#include <math.h> #include <math.h>
#define GAPS_EDGE_GAPS_LINE "gaps edge_gaps on|off|toggle"
#define GAPS_SHORT_LINE "gaps <amount>"
#define GAPS_MEDIUM_LINE "gaps inner|outer <amount>"
#define GAPS_LONG_LINE "gaps inner|outer all|current set|plus|minus <amount>"
enum gaps_op { enum gaps_op {
GAPS_OP_SET, GAPS_OP_SET,
GAPS_OP_ADD, GAPS_OP_ADD,
@ -14,7 +19,6 @@ enum gaps_op {
enum gaps_scope { enum gaps_scope {
GAPS_SCOPE_ALL, GAPS_SCOPE_ALL,
GAPS_SCOPE_WORKSPACE,
GAPS_SCOPE_CURRENT GAPS_SCOPE_CURRENT
}; };
@ -25,7 +29,7 @@ struct cmd_results *cmd_gaps(int argc, char **argv) {
} }
if (strcmp(argv[0], "edge_gaps") == 0) { if (strcmp(argv[0], "edge_gaps") == 0) {
if ((error = checkarg(argc, "gaps", EXPECTED_AT_LEAST, 2))) { if ((error = checkarg(argc, "gaps", EXPECTED_EQUAL_TO, 2))) {
return error; return error;
} }
@ -40,8 +44,7 @@ struct cmd_results *cmd_gaps(int argc, char **argv) {
} }
config->edge_gaps = !config->edge_gaps; config->edge_gaps = !config->edge_gaps;
} else { } else {
return cmd_results_new(CMD_INVALID, "gaps", return cmd_results_new(CMD_INVALID, "gaps", GAPS_EDGE_GAPS_LINE);
"gaps edge_gaps on|off|toggle");
} }
arrange_and_commit(&root_container); arrange_and_commit(&root_container);
} else { } else {
@ -80,16 +83,15 @@ struct cmd_results *cmd_gaps(int argc, char **argv) {
} }
if (argc == 4) { if (argc == 4) {
// Long format: all|workspace|current. // Long format: all|current
if (strcmp(argv[amount_idx], "all") == 0) { if (strcmp(argv[amount_idx], "all") == 0) {
amount_idx++; amount_idx++;
scope = GAPS_SCOPE_ALL; scope = GAPS_SCOPE_ALL;
} else if (strcmp(argv[amount_idx], "workspace") == 0) {
amount_idx++;
scope = GAPS_SCOPE_WORKSPACE;
} else if (strcmp(argv[amount_idx], "current") == 0) { } else if (strcmp(argv[amount_idx], "current") == 0) {
amount_idx++; amount_idx++;
scope = GAPS_SCOPE_CURRENT; scope = GAPS_SCOPE_CURRENT;
} else {
return cmd_results_new(CMD_INVALID, "gaps", GAPS_LONG_LINE);
} }
// Long format: set|plus|minus // Long format: set|plus|minus
@ -102,6 +104,8 @@ struct cmd_results *cmd_gaps(int argc, char **argv) {
} else if (strcmp(argv[amount_idx], "minus") == 0) { } else if (strcmp(argv[amount_idx], "minus") == 0) {
amount_idx++; amount_idx++;
op = GAPS_OP_SUBTRACT; op = GAPS_OP_SUBTRACT;
} else {
return cmd_results_new(CMD_INVALID, "gaps", GAPS_LONG_LINE);
} }
} }
@ -111,14 +115,12 @@ struct cmd_results *cmd_gaps(int argc, char **argv) {
if (strlen(end) && val == 0.0) { // invalid <amount> if (strlen(end) && val == 0.0) { // invalid <amount>
// guess which variant of the command was attempted // guess which variant of the command was attempted
if (argc == 1) { if (argc == 1) {
return cmd_results_new(CMD_INVALID, "gaps", "gaps <amount>"); return cmd_results_new(CMD_INVALID, "gaps", GAPS_SHORT_LINE);
} }
if (argc == 2) { if (argc == 2) {
return cmd_results_new(CMD_INVALID, "gaps", return cmd_results_new(CMD_INVALID, "gaps", GAPS_MEDIUM_LINE);
"gaps inner|outer <amount>");
} }
return cmd_results_new(CMD_INVALID, "gaps", return cmd_results_new(CMD_INVALID, "gaps", GAPS_LONG_LINE);
"gaps inner|outer all|workspace|current set|plus|minus <amount>");
} }
if (amount_idx == 0) { // gaps <amount> if (amount_idx == 0) { // gaps <amount>
@ -159,7 +161,7 @@ struct cmd_results *cmd_gaps(int argc, char **argv) {
} else { } else {
struct sway_container *c = struct sway_container *c =
config->handler_context.current_container; config->handler_context.current_container;
if (scope == GAPS_SCOPE_WORKSPACE && c->type != C_WORKSPACE) { if (c->type != C_WORKSPACE) {
c = container_parent(c, C_WORKSPACE); c = container_parent(c, C_WORKSPACE);
} }
c->has_gaps = true; c->has_gaps = true;

View file

@ -35,7 +35,7 @@ struct cmd_results *cmd_input(int argc, char **argv) {
return error; return error;
} }
wlr_log(WLR_DEBUG, "entering input block: %s", argv[0]); wlr_log(L_DEBUG, "entering input block: %s", argv[0]);
config->handler_context.input_config = new_input_config(argv[0]); config->handler_context.input_config = new_input_config(argv[0]);
if (!config->handler_context.input_config) { if (!config->handler_context.input_config) {

View file

@ -23,7 +23,6 @@ struct cmd_results *input_cmd_accel_profile(int argc, char **argv) {
} else if (strcasecmp(argv[0], "flat") == 0) { } else if (strcasecmp(argv[0], "flat") == 0) {
new_config->accel_profile = LIBINPUT_CONFIG_ACCEL_PROFILE_FLAT; new_config->accel_profile = LIBINPUT_CONFIG_ACCEL_PROFILE_FLAT;
} else { } else {
free_input_config(new_config);
return cmd_results_new(CMD_INVALID, "accel_profile", return cmd_results_new(CMD_INVALID, "accel_profile",
"Expected 'accel_profile <adaptive|flat>'"); "Expected 'accel_profile <adaptive|flat>'");
} }

View file

@ -26,7 +26,6 @@ struct cmd_results *input_cmd_click_method(int argc, char **argv) {
} else if (strcasecmp(argv[0], "clickfinger") == 0) { } else if (strcasecmp(argv[0], "clickfinger") == 0) {
new_config->click_method = LIBINPUT_CONFIG_CLICK_METHOD_CLICKFINGER; new_config->click_method = LIBINPUT_CONFIG_CLICK_METHOD_CLICKFINGER;
} else { } else {
free_input_config(new_config);
return cmd_results_new(CMD_INVALID, "click_method", return cmd_results_new(CMD_INVALID, "click_method",
"Expected 'click_method <none|button_areas|clickfinger'"); "Expected 'click_method <none|button_areas|clickfinger'");
} }

View file

@ -23,7 +23,6 @@ struct cmd_results *input_cmd_drag_lock(int argc, char **argv) {
} else if (strcasecmp(argv[0], "disabled") == 0) { } else if (strcasecmp(argv[0], "disabled") == 0) {
new_config->drag_lock = LIBINPUT_CONFIG_DRAG_LOCK_DISABLED; new_config->drag_lock = LIBINPUT_CONFIG_DRAG_LOCK_DISABLED;
} else { } else {
free_input_config(new_config);
return cmd_results_new(CMD_INVALID, "drag_lock", return cmd_results_new(CMD_INVALID, "drag_lock",
"Expected 'drag_lock <enabled|disabled>'"); "Expected 'drag_lock <enabled|disabled>'");
} }

View file

@ -22,7 +22,6 @@ struct cmd_results *input_cmd_dwt(int argc, char **argv) {
} else if (strcasecmp(argv[0], "disabled") == 0) { } else if (strcasecmp(argv[0], "disabled") == 0) {
new_config->dwt = LIBINPUT_CONFIG_DWT_DISABLED; new_config->dwt = LIBINPUT_CONFIG_DWT_DISABLED;
} else { } else {
free_input_config(new_config);
return cmd_results_new(CMD_INVALID, "dwt", return cmd_results_new(CMD_INVALID, "dwt",
"Expected 'dwt <enabled|disabled>'"); "Expected 'dwt <enabled|disabled>'");
} }

View file

@ -16,7 +16,7 @@ struct cmd_results *input_cmd_events(int argc, char **argv) {
return cmd_results_new(CMD_FAILURE, "events", return cmd_results_new(CMD_FAILURE, "events",
"No input device defined."); "No input device defined.");
} }
wlr_log(WLR_DEBUG, "events for device: %s", wlr_log(L_DEBUG, "events for device: %s",
current_input_config->identifier); current_input_config->identifier);
struct input_config *new_config = struct input_config *new_config =
new_input_config(current_input_config->identifier); new_input_config(current_input_config->identifier);
@ -29,7 +29,6 @@ struct cmd_results *input_cmd_events(int argc, char **argv) {
new_config->send_events = new_config->send_events =
LIBINPUT_CONFIG_SEND_EVENTS_DISABLED_ON_EXTERNAL_MOUSE; LIBINPUT_CONFIG_SEND_EVENTS_DISABLED_ON_EXTERNAL_MOUSE;
} else { } else {
free_input_config(new_config);
return cmd_results_new(CMD_INVALID, "events", return cmd_results_new(CMD_INVALID, "events",
"Expected 'events <enabled|disabled|disabled_on_external_mouse>'"); "Expected 'events <enabled|disabled|disabled_on_external_mouse>'");
} }

View file

@ -23,7 +23,6 @@ struct cmd_results *input_cmd_left_handed(int argc, char **argv) {
} else if (strcasecmp(argv[0], "disabled") == 0) { } else if (strcasecmp(argv[0], "disabled") == 0) {
new_config->left_handed = 0; new_config->left_handed = 0;
} else { } else {
free_input_config(new_config);
return cmd_results_new(CMD_INVALID, "left_handed", return cmd_results_new(CMD_INVALID, "left_handed",
"Expected 'left_handed <enabled|disabled>'"); "Expected 'left_handed <enabled|disabled>'");
} }

View file

@ -54,28 +54,20 @@ struct cmd_results *input_cmd_map_from_region(int argc, char **argv) {
bool mm1, mm2; bool mm1, mm2;
if (!parse_coords(argv[0], &new_config->mapped_from_region->x1, if (!parse_coords(argv[0], &new_config->mapped_from_region->x1,
&new_config->mapped_from_region->y1, &mm1)) { &new_config->mapped_from_region->y1, &mm1)) {
free(new_config->mapped_from_region);
free_input_config(new_config);
return cmd_results_new(CMD_FAILURE, "map_from_region", return cmd_results_new(CMD_FAILURE, "map_from_region",
"Invalid top-left coordinates"); "Invalid top-left coordinates");
} }
if (!parse_coords(argv[1], &new_config->mapped_from_region->x2, if (!parse_coords(argv[1], &new_config->mapped_from_region->x2,
&new_config->mapped_from_region->y2, &mm2)) { &new_config->mapped_from_region->y2, &mm2)) {
free(new_config->mapped_from_region);
free_input_config(new_config);
return cmd_results_new(CMD_FAILURE, "map_from_region", return cmd_results_new(CMD_FAILURE, "map_from_region",
"Invalid bottom-right coordinates"); "Invalid bottom-right coordinates");
} }
if (new_config->mapped_from_region->x1 > new_config->mapped_from_region->x2 || if (new_config->mapped_from_region->x1 > new_config->mapped_from_region->x2 ||
new_config->mapped_from_region->y1 > new_config->mapped_from_region->y2) { new_config->mapped_from_region->y1 > new_config->mapped_from_region->y2) {
free(new_config->mapped_from_region);
free_input_config(new_config);
return cmd_results_new(CMD_FAILURE, "map_from_region", return cmd_results_new(CMD_FAILURE, "map_from_region",
"Invalid rectangle"); "Invalid rectangle");
} }
if (mm1 != mm2) { if (mm1 != mm2) {
free(new_config->mapped_from_region);
free_input_config(new_config);
return cmd_results_new(CMD_FAILURE, "map_from_region", return cmd_results_new(CMD_FAILURE, "map_from_region",
"Both coordinates must be in the same unit"); "Both coordinates must be in the same unit");
} }

View file

@ -24,7 +24,6 @@ struct cmd_results *input_cmd_middle_emulation(int argc, char **argv) {
new_config->middle_emulation = new_config->middle_emulation =
LIBINPUT_CONFIG_MIDDLE_EMULATION_DISABLED; LIBINPUT_CONFIG_MIDDLE_EMULATION_DISABLED;
} else { } else {
free_input_config(new_config);
return cmd_results_new(CMD_INVALID, "middle_emulation", return cmd_results_new(CMD_INVALID, "middle_emulation",
"Expected 'middle_emulation <enabled|disabled>'"); "Expected 'middle_emulation <enabled|disabled>'");
} }

View file

@ -23,7 +23,6 @@ struct cmd_results *input_cmd_natural_scroll(int argc, char **argv) {
} else if (strcasecmp(argv[0], "disabled") == 0) { } else if (strcasecmp(argv[0], "disabled") == 0) {
new_config->natural_scroll = 0; new_config->natural_scroll = 0;
} else { } else {
free_input_config(new_config);
return cmd_results_new(CMD_INVALID, "natural_scroll", return cmd_results_new(CMD_INVALID, "natural_scroll",
"Expected 'natural_scroll <enabled|disabled>'"); "Expected 'natural_scroll <enabled|disabled>'");
} }

View file

@ -20,7 +20,6 @@ struct cmd_results *input_cmd_pointer_accel(int argc, char **argv) {
float pointer_accel = atof(argv[0]); float pointer_accel = atof(argv[0]);
if (pointer_accel < -1 || pointer_accel > 1) { if (pointer_accel < -1 || pointer_accel > 1) {
free_input_config(new_config);
return cmd_results_new(CMD_INVALID, "pointer_accel", return cmd_results_new(CMD_INVALID, "pointer_accel",
"Input out of range [-1, 1]"); "Input out of range [-1, 1]");
} }

View file

@ -20,7 +20,6 @@ struct cmd_results *input_cmd_repeat_delay(int argc, char **argv) {
int repeat_delay = atoi(argv[0]); int repeat_delay = atoi(argv[0]);
if (repeat_delay < 0) { if (repeat_delay < 0) {
free_input_config(new_config);
return cmd_results_new(CMD_INVALID, "repeat_delay", return cmd_results_new(CMD_INVALID, "repeat_delay",
"Repeat delay cannot be negative"); "Repeat delay cannot be negative");
} }

View file

@ -20,7 +20,6 @@ struct cmd_results *input_cmd_repeat_rate(int argc, char **argv) {
int repeat_rate = atoi(argv[0]); int repeat_rate = atoi(argv[0]);
if (repeat_rate < 0) { if (repeat_rate < 0) {
free_input_config(new_config);
return cmd_results_new(CMD_INVALID, "repeat_rate", return cmd_results_new(CMD_INVALID, "repeat_rate",
"Repeat rate cannot be negative"); "Repeat rate cannot be negative");
} }

View file

@ -27,7 +27,6 @@ struct cmd_results *input_cmd_scroll_method(int argc, char **argv) {
} else if (strcasecmp(argv[0], "on_button_down") == 0) { } else if (strcasecmp(argv[0], "on_button_down") == 0) {
new_config->scroll_method = LIBINPUT_CONFIG_SCROLL_ON_BUTTON_DOWN; new_config->scroll_method = LIBINPUT_CONFIG_SCROLL_ON_BUTTON_DOWN;
} else { } else {
free_input_config(new_config);
return cmd_results_new(CMD_INVALID, "scroll_method", return cmd_results_new(CMD_INVALID, "scroll_method",
"Expected 'scroll_method <none|two_finger|edge|on_button_down>'"); "Expected 'scroll_method <none|two_finger|edge|on_button_down>'");
} }

View file

@ -23,12 +23,11 @@ struct cmd_results *input_cmd_tap(int argc, char **argv) {
} else if (strcasecmp(argv[0], "disabled") == 0) { } else if (strcasecmp(argv[0], "disabled") == 0) {
new_config->tap = LIBINPUT_CONFIG_TAP_DISABLED; new_config->tap = LIBINPUT_CONFIG_TAP_DISABLED;
} else { } else {
free_input_config(new_config);
return cmd_results_new(CMD_INVALID, "tap", return cmd_results_new(CMD_INVALID, "tap",
"Expected 'tap <enabled|disabled>'"); "Expected 'tap <enabled|disabled>'");
} }
wlr_log(WLR_DEBUG, "apply-tap for device: %s", wlr_log(L_DEBUG, "apply-tap for device: %s",
current_input_config->identifier); current_input_config->identifier);
apply_input_config(new_config); apply_input_config(new_config);
return cmd_results_new(CMD_SUCCESS, NULL, NULL); return cmd_results_new(CMD_SUCCESS, NULL, NULL);

View file

@ -19,7 +19,7 @@ struct cmd_results *input_cmd_xkb_layout(int argc, char **argv) {
new_config->xkb_layout = strdup(argv[0]); new_config->xkb_layout = strdup(argv[0]);
wlr_log(WLR_DEBUG, "apply-xkb_layout for device: %s layout: %s", wlr_log(L_DEBUG, "apply-xkb_layout for device: %s layout: %s",
current_input_config->identifier, new_config->xkb_layout); current_input_config->identifier, new_config->xkb_layout);
apply_input_config(new_config); apply_input_config(new_config);
return cmd_results_new(CMD_SUCCESS, NULL, NULL); return cmd_results_new(CMD_SUCCESS, NULL, NULL);

View file

@ -19,7 +19,7 @@ struct cmd_results *input_cmd_xkb_model(int argc, char **argv) {
new_config->xkb_model = strdup(argv[0]); new_config->xkb_model = strdup(argv[0]);
wlr_log(WLR_DEBUG, "apply-xkb_model for device: %s model: %s", wlr_log(L_DEBUG, "apply-xkb_model for device: %s model: %s",
current_input_config->identifier, new_config->xkb_model); current_input_config->identifier, new_config->xkb_model);
apply_input_config(new_config); apply_input_config(new_config);
return cmd_results_new(CMD_SUCCESS, NULL, NULL); return cmd_results_new(CMD_SUCCESS, NULL, NULL);

View file

@ -19,7 +19,7 @@ struct cmd_results *input_cmd_xkb_options(int argc, char **argv) {
new_config->xkb_options = strdup(argv[0]); new_config->xkb_options = strdup(argv[0]);
wlr_log(WLR_DEBUG, "apply-xkb_options for device: %s options: %s", wlr_log(L_DEBUG, "apply-xkb_options for device: %s options: %s",
current_input_config->identifier, new_config->xkb_options); current_input_config->identifier, new_config->xkb_options);
apply_input_config(new_config); apply_input_config(new_config);
return cmd_results_new(CMD_SUCCESS, NULL, NULL); return cmd_results_new(CMD_SUCCESS, NULL, NULL);

View file

@ -19,7 +19,7 @@ struct cmd_results *input_cmd_xkb_rules(int argc, char **argv) {
new_config->xkb_rules = strdup(argv[0]); new_config->xkb_rules = strdup(argv[0]);
wlr_log(WLR_DEBUG, "apply-xkb_rules for device: %s rules: %s", wlr_log(L_DEBUG, "apply-xkb_rules for device: %s rules: %s",
current_input_config->identifier, new_config->xkb_rules); current_input_config->identifier, new_config->xkb_rules);
apply_input_config(new_config); apply_input_config(new_config);
return cmd_results_new(CMD_SUCCESS, NULL, NULL); return cmd_results_new(CMD_SUCCESS, NULL, NULL);

View file

@ -19,7 +19,7 @@ struct cmd_results *input_cmd_xkb_variant(int argc, char **argv) {
new_config->xkb_variant = strdup(argv[0]); new_config->xkb_variant = strdup(argv[0]);
wlr_log(WLR_DEBUG, "apply-xkb_variant for device: %s variant: %s", wlr_log(L_DEBUG, "apply-xkb_variant for device: %s variant: %s",
current_input_config->identifier, new_config->xkb_variant); current_input_config->identifier, new_config->xkb_variant);
apply_input_config(new_config); apply_input_config(new_config);
return cmd_results_new(CMD_SUCCESS, NULL, NULL); return cmd_results_new(CMD_SUCCESS, NULL, NULL);

View file

@ -26,17 +26,7 @@ struct cmd_results *cmd_mode(int argc, char **argv) {
"mode", "Can only be used in config file."); "mode", "Can only be used in config file.");
} }
bool pango = strcmp(*argv, "--pango_markup") == 0; const char *mode_name = argv[0];
if (pango) {
argc--; argv++;
if (argc == 0) {
return cmd_results_new(CMD_FAILURE, "mode",
"Mode name is missing");
}
}
char *mode_name = *argv;
strip_quotes(mode_name);
struct sway_mode *mode = NULL; struct sway_mode *mode = NULL;
// Find mode // Find mode
for (int i = 0; i < config->modes->length; ++i) { for (int i = 0; i < config->modes->length; ++i) {
@ -56,7 +46,6 @@ struct cmd_results *cmd_mode(int argc, char **argv) {
mode->name = strdup(mode_name); mode->name = strdup(mode_name);
mode->keysym_bindings = create_list(); mode->keysym_bindings = create_list();
mode->keycode_bindings = create_list(); mode->keycode_bindings = create_list();
mode->pango = pango;
list_add(config->modes, mode); list_add(config->modes, mode);
} }
if (!mode) { if (!mode) {
@ -65,15 +54,13 @@ struct cmd_results *cmd_mode(int argc, char **argv) {
return error; return error;
} }
if ((config->reading && argc > 1) || (!config->reading && argc == 1)) { if ((config->reading && argc > 1) || (!config->reading && argc == 1)) {
wlr_log(WLR_DEBUG, "Switching to mode `%s' (pango=%d)", wlr_log(L_DEBUG, "Switching to mode `%s'",mode->name);
mode->name, mode->pango);
} }
// Set current mode // Set current mode
config->current_mode = mode; config->current_mode = mode;
if (argc == 1) { if (argc == 1) {
// trigger IPC mode event // trigger IPC mode event
ipc_event_mode(config->current_mode->name, ipc_event_mode(config->current_mode->name);
config->current_mode->pango);
return cmd_results_new(CMD_SUCCESS, NULL, NULL); return cmd_results_new(CMD_SUCCESS, NULL, NULL);
} }

View file

@ -1,13 +1,11 @@
#define _XOPEN_SOURCE 500 #define _XOPEN_SOURCE 500
#include <string.h> #include <string.h>
#include <strings.h> #include <strings.h>
#include <wlr/types/wlr_cursor.h>
#include <wlr/types/wlr_output.h> #include <wlr/types/wlr_output.h>
#include <wlr/types/wlr_output_layout.h> #include <wlr/types/wlr_output_layout.h>
#include <wlr/util/log.h> #include <wlr/util/log.h>
#include "sway/commands.h" #include "sway/commands.h"
#include "sway/desktop/transaction.h" #include "sway/desktop/transaction.h"
#include "sway/input/cursor.h"
#include "sway/input/seat.h" #include "sway/input/seat.h"
#include "sway/output.h" #include "sway/output.h"
#include "sway/tree/arrange.h" #include "sway/tree/arrange.h"
@ -186,49 +184,11 @@ static struct cmd_results *cmd_move_workspace(struct sway_container *current,
} }
static struct cmd_results *move_in_direction(struct sway_container *container, static struct cmd_results *move_in_direction(struct sway_container *container,
enum movement_direction direction, int argc, char **argv) { enum movement_direction direction, int move_amt) {
int move_amt = 10;
if (argc > 1) {
char *inv;
move_amt = (int)strtol(argv[1], &inv, 10);
if (*inv != '\0' && strcasecmp(inv, "px") != 0) {
return cmd_results_new(CMD_FAILURE, "move",
"Invalid distance specified");
}
}
if (container->type == C_WORKSPACE) { if (container->type == C_WORKSPACE) {
return cmd_results_new(CMD_FAILURE, "move", return cmd_results_new(CMD_FAILURE, "move",
"Cannot move workspaces in a direction"); "Cannot move workspaces in a direction");
} }
if (container_is_floating(container)) {
if (container->type == C_VIEW && container->sway_view->is_fullscreen) {
return cmd_results_new(CMD_FAILURE, "move",
"Cannot move fullscreen floating container");
}
double lx = container->x;
double ly = container->y;
switch (direction) {
case MOVE_LEFT:
lx -= move_amt;
break;
case MOVE_RIGHT:
lx += move_amt;
break;
case MOVE_UP:
ly -= move_amt;
break;
case MOVE_DOWN:
ly += move_amt;
break;
case MOVE_PARENT:
case MOVE_CHILD:
return cmd_results_new(CMD_FAILURE, "move",
"Cannot move floating container to parent or child");
}
container_floating_move_to(container, lx, ly);
return cmd_results_new(CMD_SUCCESS, NULL, NULL);
}
// For simplicity, we'll arrange the entire workspace. The reason for this // For simplicity, we'll arrange the entire workspace. The reason for this
// is moving the container might reap the old parent, and container_move // is moving the container might reap the old parent, and container_move
// does not return a surviving parent. // does not return a surviving parent.
@ -248,78 +208,31 @@ static struct cmd_results *move_in_direction(struct sway_container *container,
return cmd_results_new(CMD_SUCCESS, NULL, NULL); return cmd_results_new(CMD_SUCCESS, NULL, NULL);
} }
static const char* expected_position_syntax =
"Expected 'move [absolute] position <x> <y>' or "
"'move [absolute] position mouse'";
static struct cmd_results *move_to_position(struct sway_container *container,
int argc, char **argv) {
if (!container_is_floating(container)) {
return cmd_results_new(CMD_FAILURE, "move",
"Only floating containers "
"can be moved to an absolute position");
}
if (!argc) {
return cmd_results_new(CMD_FAILURE, "move", expected_position_syntax);
}
if (strcmp(argv[0], "absolute") == 0) {
--argc;
++argv;
}
if (!argc) {
return cmd_results_new(CMD_FAILURE, "move", expected_position_syntax);
}
if (strcmp(argv[0], "position") == 0) {
--argc;
++argv;
}
if (!argc) {
return cmd_results_new(CMD_FAILURE, "move", expected_position_syntax);
}
if (strcmp(argv[0], "mouse") == 0) {
struct sway_seat *seat = config->handler_context.seat;
if (!seat->cursor) {
return cmd_results_new(CMD_FAILURE, "move", "No cursor device");
}
double lx = seat->cursor->cursor->x - container->width / 2;
double ly = seat->cursor->cursor->y - container->height / 2;
container_floating_move_to(container, lx, ly);
return cmd_results_new(CMD_SUCCESS, NULL, NULL);
}
if (argc != 2) {
return cmd_results_new(CMD_FAILURE, "move", expected_position_syntax);
}
double lx, ly;
char *inv;
lx = (double)strtol(argv[0], &inv, 10);
if (*inv != '\0' && strcasecmp(inv, "px") != 0) {
return cmd_results_new(CMD_FAILURE, "move",
"Invalid position specified");
}
ly = (double)strtol(argv[1], &inv, 10);
if (*inv != '\0' && strcasecmp(inv, "px") != 0) {
return cmd_results_new(CMD_FAILURE, "move",
"Invalid position specified");
}
container_floating_move_to(container, lx, ly);
return cmd_results_new(CMD_SUCCESS, NULL, NULL);
}
struct cmd_results *cmd_move(int argc, char **argv) { struct cmd_results *cmd_move(int argc, char **argv) {
struct cmd_results *error = NULL; struct cmd_results *error = NULL;
int move_amt = 10;
if ((error = checkarg(argc, "move", EXPECTED_AT_LEAST, 1))) { if ((error = checkarg(argc, "move", EXPECTED_AT_LEAST, 1))) {
return error; return error;
} }
struct sway_container *current = config->handler_context.current_container; struct sway_container *current = config->handler_context.current_container;
if (argc == 2 || (argc == 3 && strcasecmp(argv[2], "px") == 0)) {
char *inv;
move_amt = (int)strtol(argv[1], &inv, 10);
if (*inv != '\0' && strcasecmp(inv, "px") != 0) {
return cmd_results_new(CMD_FAILURE, "move",
"Invalid distance specified");
}
}
if (strcasecmp(argv[0], "left") == 0) { if (strcasecmp(argv[0], "left") == 0) {
return move_in_direction(current, MOVE_LEFT, argc, argv); return move_in_direction(current, MOVE_LEFT, move_amt);
} else if (strcasecmp(argv[0], "right") == 0) { } else if (strcasecmp(argv[0], "right") == 0) {
return move_in_direction(current, MOVE_RIGHT, argc, argv); return move_in_direction(current, MOVE_RIGHT, move_amt);
} else if (strcasecmp(argv[0], "up") == 0) { } else if (strcasecmp(argv[0], "up") == 0) {
return move_in_direction(current, MOVE_UP, argc, argv); return move_in_direction(current, MOVE_UP, move_amt);
} else if (strcasecmp(argv[0], "down") == 0) { } else if (strcasecmp(argv[0], "down") == 0) {
return move_in_direction(current, MOVE_DOWN, argc, argv); return move_in_direction(current, MOVE_DOWN, move_amt);
} else if (strcasecmp(argv[0], "container") == 0 } else if (strcasecmp(argv[0], "container") == 0
|| strcasecmp(argv[0], "window") == 0) { || strcasecmp(argv[0], "window") == 0) {
return cmd_move_container(current, argc, argv); return cmd_move_container(current, argc, argv);
@ -331,9 +244,8 @@ struct cmd_results *cmd_move(int argc, char **argv) {
// TODO: scratchpad // TODO: scratchpad
return cmd_results_new(CMD_FAILURE, "move", "Unimplemented"); return cmd_results_new(CMD_FAILURE, "move", "Unimplemented");
} else if (strcasecmp(argv[0], "position") == 0) { } else if (strcasecmp(argv[0], "position") == 0) {
return move_to_position(current, argc, argv); // TODO: floating
} else if (strcasecmp(argv[0], "absolute") == 0) { return cmd_results_new(CMD_FAILURE, "move", "Unimplemented");
return move_to_position(current, argc, argv);
} else { } else {
return cmd_results_new(CMD_INVALID, "move", expected_syntax); return cmd_results_new(CMD_INVALID, "move", expected_syntax);
} }

View file

@ -29,7 +29,7 @@ struct cmd_results *cmd_output(int argc, char **argv) {
struct output_config *output = new_output_config(argv[0]); struct output_config *output = new_output_config(argv[0]);
if (!output) { if (!output) {
wlr_log(WLR_ERROR, "Failed to allocate output config"); wlr_log(L_ERROR, "Failed to allocate output config");
return NULL; return NULL;
} }
argc--; argv++; argc--; argv++;
@ -71,7 +71,7 @@ struct cmd_results *cmd_output(int argc, char **argv) {
list_add(config->output_configs, output); list_add(config->output_configs, output);
} }
wlr_log(WLR_DEBUG, "Config stored for output %s (enabled: %d) (%dx%d@%fHz " wlr_log(L_DEBUG, "Config stored for output %s (enabled: %d) (%dx%d@%fHz "
"position %d,%d scale %f transform %d) (bg %s %s) (dpms %d)", "position %d,%d scale %f transform %d) (bg %s %s) (dpms %d)",
output->name, output->enabled, output->width, output->height, output->name, output->enabled, output->width, output->height,
output->refresh_rate, output->x, output->y, output->scale, output->refresh_rate, output->x, output->y, output->scale,
@ -85,7 +85,7 @@ struct cmd_results *cmd_output(int argc, char **argv) {
struct sway_output *sway_output; struct sway_output *sway_output;
wl_list_for_each(sway_output, &root_container.sway_root->outputs, link) { wl_list_for_each(sway_output, &root_container.sway_root->outputs, link) {
output_get_identifier(identifier, sizeof(identifier), sway_output); output_get_identifier(identifier, sizeof(identifier), sway_output);
wlr_log(WLR_DEBUG, "Checking identifier %s", identifier); wlr_log(L_DEBUG, "Checking identifier %s", identifier);
if (all || strcmp(sway_output->wlr_output->name, output->name) == 0 if (all || strcmp(sway_output->wlr_output->name, output->name) == 0
|| strcmp(identifier, output->name) == 0) { || strcmp(identifier, output->name) == 0) {
if (!sway_output->swayc) { if (!sway_output->swayc) {

View file

@ -72,7 +72,7 @@ struct cmd_results *output_cmd_background(int argc, char **argv) {
src = strdup(p.we_wordv[0]); src = strdup(p.we_wordv[0]);
wordfree(&p); wordfree(&p);
if (!src) { if (!src) {
wlr_log(WLR_ERROR, "Failed to duplicate string"); wlr_log(L_ERROR, "Failed to duplicate string");
return cmd_results_new(CMD_FAILURE, "output", return cmd_results_new(CMD_FAILURE, "output",
"Unable to allocate resource"); "Unable to allocate resource");
} }
@ -80,10 +80,9 @@ struct cmd_results *output_cmd_background(int argc, char **argv) {
if (config->reading && *src != '/') { if (config->reading && *src != '/') {
// src file is inside configuration dir // src file is inside configuration dir
char *conf = strdup(config->current_config_path); char *conf = strdup(config->current_config);
if (!conf) { if(!conf) {
wlr_log(WLR_ERROR, "Failed to duplicate string"); wlr_log(L_ERROR, "Failed to duplicate string");
free(src);
return cmd_results_new(CMD_FAILURE, "output", return cmd_results_new(CMD_FAILURE, "output",
"Unable to allocate resources"); "Unable to allocate resources");
} }
@ -94,7 +93,7 @@ struct cmd_results *output_cmd_background(int argc, char **argv) {
if (!src) { if (!src) {
free(rel_path); free(rel_path);
free(conf); free(conf);
wlr_log(WLR_ERROR, "Unable to allocate memory"); wlr_log(L_ERROR, "Unable to allocate memory");
return cmd_results_new(CMD_FAILURE, "output", return cmd_results_new(CMD_FAILURE, "output",
"Unable to allocate resources"); "Unable to allocate resources");
} }

View file

@ -36,11 +36,11 @@ struct cmd_results *output_cmd_mode(int argc, char **argv) {
} }
} else { } else {
// Format is 1234 4321 // Format is 1234 4321
argc--; argv++;
if (!argc) { if (!argc) {
return cmd_results_new(CMD_INVALID, "output", return cmd_results_new(CMD_INVALID, "output",
"Missing mode argument (height)."); "Missing mode argument (height).");
} }
argc--; argv++;
output->height = strtol(*argv, &end, 10); output->height = strtol(*argv, &end, 10);
if (*end) { if (*end) {
return cmd_results_new(CMD_INVALID, "output", return cmd_results_new(CMD_INVALID, "output",

View file

@ -27,11 +27,11 @@ struct cmd_results *output_cmd_position(int argc, char **argv) {
} }
} else { } else {
// Format is 1234 4321 (legacy) // Format is 1234 4321 (legacy)
argc--; argv++;
if (!argc) { if (!argc) {
return cmd_results_new(CMD_INVALID, "output", return cmd_results_new(CMD_INVALID, "output",
"Missing position argument (y)."); "Missing position argument (y).");
} }
argc--; argv++;
config->handler_context.output_config->y = strtol(*argv, &end, 10); config->handler_context.output_config->y = strtol(*argv, &end, 10);
if (*end) { if (*end) {
return cmd_results_new(CMD_INVALID, "output", return cmd_results_new(CMD_INVALID, "output",

View file

@ -7,7 +7,7 @@ struct cmd_results *cmd_reload(int argc, char **argv) {
if ((error = checkarg(argc, "reload", EXPECTED_EQUAL_TO, 0))) { if ((error = checkarg(argc, "reload", EXPECTED_EQUAL_TO, 0))) {
return error; return error;
} }
if (!load_main_config(config->current_config_path, true)) { if (!load_main_config(config->current_config, true)) {
return cmd_results_new(CMD_FAILURE, "reload", "Error(s) reloading config."); return cmd_results_new(CMD_FAILURE, "reload", "Error(s) reloading config.");
} }

View file

@ -68,7 +68,7 @@ struct cmd_results *cmd_rename(int argc, char **argv) {
"Workspace already exists"); "Workspace already exists");
} }
wlr_log(WLR_DEBUG, "renaming workspace '%s' to '%s'", workspace->name, new_name); wlr_log(L_DEBUG, "renaming workspace '%s' to '%s'", workspace->name, new_name);
free(workspace->name); free(workspace->name);
workspace->name = new_name; workspace->name = new_name;

View file

@ -95,7 +95,7 @@ static void resize_tiled(int amount, enum resize_axis axis) {
return; return;
} }
wlr_log(WLR_DEBUG, wlr_log(L_DEBUG,
"Found the proper parent: %p. It has %d l conts, and %d r conts", "Found the proper parent: %p. It has %d l conts, and %d r conts",
parent->parent, minor_weight, major_weight); parent->parent, minor_weight, major_weight);

View file

@ -32,7 +32,7 @@ struct cmd_results *cmd_set(int argc, char **argv) {
} }
if (argv[0][0] != '$') { if (argv[0][0] != '$') {
wlr_log(WLR_INFO, "Warning: variable '%s' doesn't start with $", argv[0]); wlr_log(L_INFO, "Warning: variable '%s' doesn't start with $", argv[0]);
size_t size = snprintf(NULL, 0, "$%s", argv[0]); size_t size = snprintf(NULL, 0, "$%s", argv[0]);
tmp = malloc(size + 1); tmp = malloc(size + 1);

View file

@ -13,7 +13,7 @@ struct cmd_results *cmd_swaybg_command(int argc, char **argv) {
free(config->swaybg_command); free(config->swaybg_command);
} }
config->swaybg_command = join_args(argv, argc); config->swaybg_command = join_args(argv, argc);
wlr_log(WLR_DEBUG, "Using custom swaybg command: %s", wlr_log(L_DEBUG, "Using custom swaybg command: %s",
config->swaybg_command); config->swaybg_command);
return cmd_results_new(CMD_SUCCESS, NULL, NULL); return cmd_results_new(CMD_SUCCESS, NULL, NULL);

View file

@ -51,7 +51,7 @@ struct cmd_results *cmd_workspace(int argc, char **argv) {
free(old); // workspaces can only be assigned to a single output free(old); // workspaces can only be assigned to a single output
list_del(config->workspace_outputs, i); list_del(config->workspace_outputs, i);
} }
wlr_log(WLR_DEBUG, "Assigning workspace %s to output %s", wso->workspace, wso->output); wlr_log(L_DEBUG, "Assigning workspace %s to output %s", wso->workspace, wso->output);
list_add(config->workspace_outputs, wso); list_add(config->workspace_outputs, wso);
} else { } else {
if (config->reading || !config->active) { if (config->reading || !config->active) {

View file

@ -87,12 +87,7 @@ void free_config(struct sway_config *config) {
list_free(config->cmd_queue); list_free(config->cmd_queue);
list_free(config->workspace_outputs); list_free(config->workspace_outputs);
list_free(config->pid_workspaces); list_free(config->pid_workspaces);
if (config->output_configs) {
for (int i = 0; i < config->output_configs->length; i++) {
free_output_config(config->output_configs->items[i]);
}
list_free(config->output_configs); list_free(config->output_configs);
}
if (config->input_configs) { if (config->input_configs) {
for (int i = 0; i < config->input_configs->length; i++) { for (int i = 0; i < config->input_configs->length; i++) {
free_input_config(config->input_configs->items[i]); free_input_config(config->input_configs->items[i]);
@ -117,7 +112,6 @@ void free_config(struct sway_config *config) {
free(config->floating_scroll_left_cmd); free(config->floating_scroll_left_cmd);
free(config->floating_scroll_right_cmd); free(config->floating_scroll_right_cmd);
free(config->font); free(config->font);
free((char *)config->current_config_path);
free((char *)config->current_config); free((char *)config->current_config);
free(config); free(config);
} }
@ -206,7 +200,6 @@ static void config_defaults(struct sway_config *config) {
if (!(config->active_bar_modifiers = create_list())) goto cleanup; if (!(config->active_bar_modifiers = create_list())) goto cleanup;
if (!(config->config_chain = create_list())) goto cleanup; if (!(config->config_chain = create_list())) goto cleanup;
config->current_config_path = NULL;
config->current_config = NULL; config->current_config = NULL;
// borders // borders
@ -278,12 +271,12 @@ static char *get_config_path(void) {
char *home = getenv("HOME"); char *home = getenv("HOME");
char *config_home = malloc(strlen(home) + strlen("/.config") + 1); char *config_home = malloc(strlen(home) + strlen("/.config") + 1);
if (!config_home) { if (!config_home) {
wlr_log(WLR_ERROR, "Unable to allocate $HOME/.config"); wlr_log(L_ERROR, "Unable to allocate $HOME/.config");
} else { } else {
strcpy(config_home, home); strcpy(config_home, home);
strcat(config_home, "/.config"); strcat(config_home, "/.config");
setenv("XDG_CONFIG_HOME", config_home, 1); setenv("XDG_CONFIG_HOME", config_home, 1);
wlr_log(WLR_DEBUG, "Set XDG_CONFIG_HOME to %s", config_home); wlr_log(L_DEBUG, "Set XDG_CONFIG_HOME to %s", config_home);
free(config_home); free(config_home);
} }
} }
@ -306,22 +299,25 @@ static char *get_config_path(void) {
return NULL; // Not reached return NULL; // Not reached
} }
static bool load_config(const char *path, struct sway_config *config) { const char *current_config_path;
if (path == NULL) {
wlr_log(WLR_ERROR, "Unable to find a config file!");
return false;
}
wlr_log(WLR_INFO, "Loading config from %s", path); static bool load_config(const char *path, struct sway_config *config) {
wlr_log(L_INFO, "Loading config from %s", path);
current_config_path = path;
struct stat sb; struct stat sb;
if (stat(path, &sb) == 0 && S_ISDIR(sb.st_mode)) { if (stat(path, &sb) == 0 && S_ISDIR(sb.st_mode)) {
return false; return false;
} }
if (path == NULL) {
wlr_log(L_ERROR, "Unable to find a config file!");
return false;
}
FILE *f = fopen(path, "r"); FILE *f = fopen(path, "r");
if (!f) { if (!f) {
wlr_log(WLR_ERROR, "Unable to open %s for reading", path); wlr_log(L_ERROR, "Unable to open %s for reading", path);
return false; return false;
} }
@ -329,9 +325,10 @@ static bool load_config(const char *path, struct sway_config *config) {
fclose(f); fclose(f);
if (!config_load_success) { if (!config_load_success) {
wlr_log(WLR_ERROR, "Error(s) loading config!"); wlr_log(L_ERROR, "Error(s) loading config!");
} }
current_config_path = NULL;
return true; return true;
} }
@ -351,12 +348,12 @@ bool load_main_config(const char *file, bool is_active) {
config_defaults(config); config_defaults(config);
if (is_active) { if (is_active) {
wlr_log(WLR_DEBUG, "Performing configuration file reload"); wlr_log(L_DEBUG, "Performing configuration file reload");
config->reloading = true; config->reloading = true;
config->active = true; config->active = true;
} }
config->current_config_path = path; config->current_config = path;
list_add(config->config_chain, path); list_add(config->config_chain, path);
config->reading = true; config->reading = true;
@ -367,7 +364,7 @@ bool load_main_config(const char *file, bool is_active) {
/* /*
DIR *dir = opendir(SYSCONFDIR "/sway/security.d"); DIR *dir = opendir(SYSCONFDIR "/sway/security.d");
if (!dir) { if (!dir) {
wlr_log(WLR_ERROR, wlr_log(L_ERROR,
"%s does not exist, sway will have no security configuration" "%s does not exist, sway will have no security configuration"
" and will probably be broken", SYSCONFDIR "/sway/security.d"); " and will probably be broken", SYSCONFDIR "/sway/security.d");
} else { } else {
@ -396,7 +393,7 @@ bool load_main_config(const char *file, bool is_active) {
if (stat(_path, &s) || s.st_uid != 0 || s.st_gid != 0 || if (stat(_path, &s) || s.st_uid != 0 || s.st_gid != 0 ||
(((s.st_mode & 0777) != 0644) && (((s.st_mode & 0777) != 0644) &&
(s.st_mode & 0777) != 0444)) { (s.st_mode & 0777) != 0444)) {
wlr_log(WLR_ERROR, wlr_log(L_ERROR,
"Refusing to load %s - it must be owned by root " "Refusing to load %s - it must be owned by root "
"and mode 644 or 444", _path); "and mode 644 or 444", _path);
success = false; success = false;
@ -426,28 +423,26 @@ bool load_main_config(const char *file, bool is_active) {
static bool load_include_config(const char *path, const char *parent_dir, static bool load_include_config(const char *path, const char *parent_dir,
struct sway_config *config) { struct sway_config *config) {
// save parent config // save parent config
const char *parent_config = config->current_config_path; const char *parent_config = config->current_config;
char *full_path; char *full_path = strdup(path);
int len = strlen(path); int len = strlen(path);
if (len >= 1 && path[0] != '/') { if (len >= 1 && path[0] != '/') {
len = len + strlen(parent_dir) + 2; len = len + strlen(parent_dir) + 2;
full_path = malloc(len * sizeof(char)); full_path = malloc(len * sizeof(char));
if (!full_path) { if (!full_path) {
wlr_log(WLR_ERROR, wlr_log(L_ERROR,
"Unable to allocate full path to included config"); "Unable to allocate full path to included config");
return false; return false;
} }
snprintf(full_path, len, "%s/%s", parent_dir, path); snprintf(full_path, len, "%s/%s", parent_dir, path);
} else {
full_path = strdup(path);
} }
char *real_path = realpath(full_path, NULL); char *real_path = realpath(full_path, NULL);
free(full_path); free(full_path);
if (real_path == NULL) { if (real_path == NULL) {
wlr_log(WLR_DEBUG, "%s not found.", path); wlr_log(L_DEBUG, "%s not found.", path);
return false; return false;
} }
@ -456,7 +451,7 @@ static bool load_include_config(const char *path, const char *parent_dir,
for (j = 0; j < config->config_chain->length; ++j) { for (j = 0; j < config->config_chain->length; ++j) {
char *old_path = config->config_chain->items[j]; char *old_path = config->config_chain->items[j];
if (strcmp(real_path, old_path) == 0) { if (strcmp(real_path, old_path) == 0) {
wlr_log(WLR_DEBUG, wlr_log(L_DEBUG,
"%s already included once, won't be included again.", "%s already included once, won't be included again.",
real_path); real_path);
free(real_path); free(real_path);
@ -464,25 +459,25 @@ static bool load_include_config(const char *path, const char *parent_dir,
} }
} }
config->current_config_path = real_path; config->current_config = real_path;
list_add(config->config_chain, real_path); list_add(config->config_chain, real_path);
int index = config->config_chain->length - 1; int index = config->config_chain->length - 1;
if (!load_config(real_path, config)) { if (!load_config(real_path, config)) {
free(real_path); free(real_path);
config->current_config_path = parent_config; config->current_config = parent_config;
list_del(config->config_chain, index); list_del(config->config_chain, index);
return false; return false;
} }
// restore current_config_path // restore current_config
config->current_config_path = parent_config; config->current_config = parent_config;
return true; return true;
} }
bool load_include_configs(const char *path, struct sway_config *config) { bool load_include_configs(const char *path, struct sway_config *config) {
char *wd = getcwd(NULL, 0); char *wd = getcwd(NULL, 0);
char *parent_path = strdup(config->current_config_path); char *parent_path = strdup(config->current_config);
const char *parent_dir = dirname(parent_path); const char *parent_dir = dirname(parent_path);
if (chdir(parent_dir) < 0) { if (chdir(parent_dir) < 0) {
@ -510,7 +505,7 @@ bool load_include_configs(const char *path, struct sway_config *config) {
// restore wd // restore wd
if (chdir(wd) < 0) { if (chdir(wd) < 0) {
free(wd); free(wd);
wlr_log(WLR_ERROR, "failed to restore working directory"); wlr_log(L_ERROR, "failed to restore working directory");
return false; return false;
} }
@ -525,13 +520,13 @@ static int detect_brace_on_following_line(FILE *file, char *line,
char *peeked = NULL; char *peeked = NULL;
long position = 0; long position = 0;
do { do {
wlr_log(WLR_DEBUG, "Peeking line %d", line_number + lines + 1); wlr_log(L_DEBUG, "Peeking line %d", line_number + lines + 1);
free(peeked); free(peeked);
peeked = peek_line(file, lines, &position); peeked = peek_line(file, lines, &position);
if (peeked) { if (peeked) {
peeked = strip_whitespace(peeked); peeked = strip_whitespace(peeked);
} }
wlr_log(WLR_DEBUG, "Peeked line: `%s`", peeked); wlr_log(L_DEBUG, "Peeked line: `%s`", peeked);
lines++; lines++;
} while (peeked && strlen(peeked) == 0); } while (peeked && strlen(peeked) == 0);
@ -550,7 +545,7 @@ static char *expand_line(const char *block, const char *line, bool add_brace) {
+ (add_brace ? 2 : 0) + 1; + (add_brace ? 2 : 0) + 1;
char *expanded = calloc(1, size); char *expanded = calloc(1, size);
if (!expanded) { if (!expanded) {
wlr_log(WLR_ERROR, "Cannot allocate expanded line buffer"); wlr_log(L_ERROR, "Cannot allocate expanded line buffer");
return NULL; return NULL;
} }
snprintf(expanded, size, "%s%s%s%s", block ? block : "", snprintf(expanded, size, "%s%s%s%s", block ? block : "",
@ -559,23 +554,6 @@ static char *expand_line(const char *block, const char *line, bool add_brace) {
} }
bool read_config(FILE *file, struct sway_config *config) { bool read_config(FILE *file, struct sway_config *config) {
bool reading_main_config = false;
char *current_config, *config_pos;
long config_size = 0;
if (config->current_config == NULL) {
reading_main_config = true;
fseek(file, 0, SEEK_END);
config_size = ftell(file);
rewind(file);
config_pos = current_config = malloc(config_size + 1);
if (current_config == NULL) {
wlr_log(WLR_ERROR, "Unable to allocate buffer for config contents");
return false;
}
}
bool success = true; bool success = true;
int line_number = 0; int line_number = 0;
char *line; char *line;
@ -587,15 +565,7 @@ bool read_config(FILE *file, struct sway_config *config) {
continue; continue;
} }
line_number++; line_number++;
wlr_log(WLR_DEBUG, "Read line %d: %s", line_number, line); wlr_log(L_DEBUG, "Read line %d: %s", line_number, line);
if (reading_main_config) {
size_t l = strlen(line);
memcpy(config_pos, line, l); // don't copy terminating character
config_pos += l;
*config_pos++ = '\n';
}
line = strip_whitespace(line); line = strip_whitespace(line);
if (line[0] == '#') { if (line[0] == '#') {
free(line); free(line);
@ -609,17 +579,13 @@ bool read_config(FILE *file, struct sway_config *config) {
line_number); line_number);
if (brace_detected > 0) { if (brace_detected > 0) {
line_number += brace_detected; line_number += brace_detected;
wlr_log(WLR_DEBUG, "Detected open brace on line %d", line_number); wlr_log(L_DEBUG, "Detected open brace on line %d", line_number);
} }
char *expanded = expand_line(block, line, brace_detected > 0); char *expanded = expand_line(block, line, brace_detected > 0);
if (!expanded) { if (!expanded) {
list_foreach(stack, free);
list_free(stack);
free(line);
free(current_config);
return false; return false;
} }
wlr_log(WLR_DEBUG, "Expanded line: %s", expanded); wlr_log(L_DEBUG, "Expanded line: %s", expanded);
struct cmd_results *res; struct cmd_results *res;
if (block && strcmp(block, "<commands>") == 0) { if (block && strcmp(block, "<commands>") == 0) {
// Special case // Special case
@ -631,23 +597,23 @@ bool read_config(FILE *file, struct sway_config *config) {
switch(res->status) { switch(res->status) {
case CMD_FAILURE: case CMD_FAILURE:
case CMD_INVALID: case CMD_INVALID:
wlr_log(WLR_ERROR, "Error on line %i '%s': %s (%s)", line_number, wlr_log(L_ERROR, "Error on line %i '%s': %s (%s)", line_number,
line, res->error, config->current_config_path); line, res->error, config->current_config);
success = false; success = false;
break; break;
case CMD_DEFER: case CMD_DEFER:
wlr_log(WLR_DEBUG, "Deferring command `%s'", line); wlr_log(L_DEBUG, "Deferring command `%s'", line);
list_add(config->cmd_queue, strdup(line)); list_add(config->cmd_queue, strdup(line));
break; break;
case CMD_BLOCK_COMMANDS: case CMD_BLOCK_COMMANDS:
wlr_log(WLR_DEBUG, "Entering commands block"); wlr_log(L_DEBUG, "Entering commands block");
list_insert(stack, 0, "<commands>"); list_insert(stack, 0, "<commands>");
break; break;
case CMD_BLOCK: case CMD_BLOCK:
wlr_log(WLR_DEBUG, "Entering block '%s'", res->input); wlr_log(L_DEBUG, "Entering block '%s'", res->input);
list_insert(stack, 0, strdup(res->input)); list_insert(stack, 0, strdup(res->input));
if (strcmp(res->input, "bar") == 0) { if (strcmp(res->input, "bar") == 0) {
config->current_bar = NULL; config->current_bar = NULL;
@ -656,7 +622,7 @@ bool read_config(FILE *file, struct sway_config *config) {
case CMD_BLOCK_END: case CMD_BLOCK_END:
if (!block) { if (!block) {
wlr_log(WLR_DEBUG, "Unmatched '}' on line %i", line_number); wlr_log(L_DEBUG, "Unmatched '}' on line %i", line_number);
success = false; success = false;
break; break;
} }
@ -664,7 +630,7 @@ bool read_config(FILE *file, struct sway_config *config) {
config->current_bar = NULL; config->current_bar = NULL;
} }
wlr_log(WLR_DEBUG, "Exiting block '%s'", block); wlr_log(L_DEBUG, "Exiting block '%s'", block);
list_del(stack, 0); list_del(stack, 0);
free(block); free(block);
memset(&config->handler_context, 0, memset(&config->handler_context, 0,
@ -677,10 +643,6 @@ bool read_config(FILE *file, struct sway_config *config) {
list_foreach(stack, free); list_foreach(stack, free);
list_free(stack); list_free(stack);
if (reading_main_config) {
current_config[config_size - 1] = '\0';
config->current_config = current_config;
}
return success; return success;
} }
@ -711,7 +673,7 @@ char *do_var_replacement(char *str) {
int vvlen = strlen(var->value); int vvlen = strlen(var->value);
char *newstr = malloc(strlen(str) - vnlen + vvlen + 1); char *newstr = malloc(strlen(str) - vnlen + vvlen + 1);
if (!newstr) { if (!newstr) {
wlr_log(WLR_ERROR, wlr_log(L_ERROR,
"Unable to allocate replacement " "Unable to allocate replacement "
"during variable expansion"); "during variable expansion");
break; break;

View file

@ -16,10 +16,10 @@
#include "log.h" #include "log.h"
static void terminate_swaybar(pid_t pid) { static void terminate_swaybar(pid_t pid) {
wlr_log(WLR_DEBUG, "Terminating swaybar %d", pid); wlr_log(L_DEBUG, "Terminating swaybar %d", pid);
int ret = kill(-pid, SIGTERM); int ret = kill(-pid, SIGTERM);
if (ret != 0) { if (ret != 0) {
wlr_log_errno(WLR_ERROR, "Unable to terminate swaybar %d", pid); wlr_log_errno(L_ERROR, "Unable to terminate swaybar %d", pid);
} else { } else {
int status; int status;
waitpid(pid, &status, 0); waitpid(pid, &status, 0);
@ -30,7 +30,6 @@ void free_bar_config(struct bar_config *bar) {
if (!bar) { if (!bar) {
return; return;
} }
free(bar->id);
free(bar->mode); free(bar->mode);
free(bar->position); free(bar->position);
free(bar->hidden_state); free(bar->hidden_state);
@ -71,12 +70,16 @@ void free_bar_config(struct bar_config *bar) {
struct bar_config *default_bar_config(void) { struct bar_config *default_bar_config(void) {
struct bar_config *bar = NULL; struct bar_config *bar = NULL;
bar = calloc(1, sizeof(struct bar_config)); bar = malloc(sizeof(struct bar_config));
if (!bar) { if (!bar) {
return NULL; return NULL;
} }
if (!(bar->mode = strdup("dock"))) goto cleanup;
if (!(bar->hidden_state = strdup("hide"))) goto cleanup;
bar->outputs = NULL; bar->outputs = NULL;
bar->position = strdup("bottom"); bar->position = strdup("bottom");
if (!(bar->bindings = create_list())) goto cleanup;
if (!(bar->status_command = strdup("while :; do date +'%Y-%m-%d %l:%M:%S %p'; sleep 1; done"))) goto cleanup;
bar->pango_markup = false; bar->pango_markup = false;
bar->swaybar_command = NULL; bar->swaybar_command = NULL;
bar->font = NULL; bar->font = NULL;
@ -88,19 +91,6 @@ struct bar_config *default_bar_config(void) {
bar->binding_mode_indicator = true; bar->binding_mode_indicator = true;
bar->verbose = false; bar->verbose = false;
bar->pid = 0; bar->pid = 0;
if (!(bar->mode = strdup("dock"))) {
goto cleanup;
}
if (!(bar->hidden_state = strdup("hide"))) {
goto cleanup;
}
if (!(bar->bindings = create_list())) {
goto cleanup;
}
if (!(bar->status_command =
strdup("while date +'%Y-%m-%d %l:%M:%S %p'; do sleep 1; done"))) {
goto cleanup;
}
// set default colors // set default colors
if (!(bar->colors.background = strndup("#000000ff", 9))) { if (!(bar->colors.background = strndup("#000000ff", 9))) {
goto cleanup; goto cleanup;
@ -167,7 +157,7 @@ void invoke_swaybar(struct bar_config *bar) {
// Pipe to communicate errors // Pipe to communicate errors
int filedes[2]; int filedes[2];
if (pipe(filedes) == -1) { if (pipe(filedes) == -1) {
wlr_log(WLR_ERROR, "Pipe setup failed! Cannot fork into bar"); wlr_log(L_ERROR, "Pipe setup failed! Cannot fork into bar");
return; return;
} }
@ -184,7 +174,7 @@ void invoke_swaybar(struct bar_config *bar) {
if (!command) { if (!command) {
const char msg[] = "Unable to allocate swaybar command string"; const char msg[] = "Unable to allocate swaybar command string";
size_t msg_len = sizeof(msg); size_t msg_len = sizeof(msg);
if (write(filedes[1], &msg_len, sizeof(size_t))) {}; if (write(filedes[1], &msg_len, sizeof(int))) {};
if (write(filedes[1], msg, msg_len)) {}; if (write(filedes[1], msg, msg_len)) {};
close(filedes[1]); close(filedes[1]);
exit(1); exit(1);
@ -197,17 +187,17 @@ void invoke_swaybar(struct bar_config *bar) {
execvp(cmd[0], cmd); execvp(cmd[0], cmd);
exit(1); exit(1);
} }
wlr_log(WLR_DEBUG, "Spawned swaybar %d", bar->pid); wlr_log(L_DEBUG, "Spawned swaybar %d", bar->pid);
close(filedes[0]); close(filedes[0]);
size_t len; ssize_t len;
if (read(filedes[1], &len, sizeof(size_t)) == sizeof(size_t)) { if (read(filedes[1], &len, sizeof(int)) == sizeof(int)) {
char *buf = malloc(len); char *buf = malloc(len);
if(!buf) { if(!buf) {
wlr_log(WLR_ERROR, "Cannot allocate error string"); wlr_log(L_ERROR, "Cannot allocate error string");
return; return;
} }
if (read(filedes[1], buf, len)) { if (read(filedes[1], buf, len)) {
wlr_log(WLR_ERROR, "%s", buf); wlr_log(L_ERROR, "%s", buf);
} }
free(buf); free(buf);
} }
@ -244,7 +234,7 @@ void load_swaybars() {
if (bar->pid != 0) { if (bar->pid != 0) {
terminate_swaybar(bar->pid); terminate_swaybar(bar->pid);
} }
wlr_log(WLR_DEBUG, "Invoking swaybar for bar id '%s'", bar->id); wlr_log(L_DEBUG, "Invoking swaybar for bar id '%s'", bar->id);
invoke_swaybar(bar); invoke_swaybar(bar);
} }
} }

View file

@ -8,13 +8,13 @@
struct input_config *new_input_config(const char* identifier) { struct input_config *new_input_config(const char* identifier) {
struct input_config *input = calloc(1, sizeof(struct input_config)); struct input_config *input = calloc(1, sizeof(struct input_config));
if (!input) { if (!input) {
wlr_log(WLR_DEBUG, "Unable to allocate input config"); wlr_log(L_DEBUG, "Unable to allocate input config");
return NULL; return NULL;
} }
wlr_log(WLR_DEBUG, "new_input_config(%s)", identifier); wlr_log(L_DEBUG, "new_input_config(%s)", identifier);
if (!(input->identifier = strdup(identifier))) { if (!(input->identifier = strdup(identifier))) {
free(input); free(input);
wlr_log(WLR_DEBUG, "Unable to allocate input config"); wlr_log(L_DEBUG, "Unable to allocate input config");
return NULL; return NULL;
} }
@ -112,7 +112,7 @@ void merge_input_config(struct input_config *dst, struct input_config *src) {
struct input_config *copy_input_config(struct input_config *ic) { struct input_config *copy_input_config(struct input_config *ic) {
struct input_config *copy = calloc(1, sizeof(struct input_config)); struct input_config *copy = calloc(1, sizeof(struct input_config));
if (copy == NULL) { if (copy == NULL) {
wlr_log(WLR_ERROR, "could not allocate input config"); wlr_log(L_ERROR, "could not allocate input config");
return NULL; return NULL;
} }
merge_input_config(copy, ic); merge_input_config(copy, ic);

View file

@ -90,7 +90,7 @@ static void set_mode(struct wlr_output *output, int width, int height,
float refresh_rate) { float refresh_rate) {
int mhz = (int)(refresh_rate * 1000); int mhz = (int)(refresh_rate * 1000);
if (wl_list_empty(&output->modes)) { if (wl_list_empty(&output->modes)) {
wlr_log(WLR_DEBUG, "Assigning custom mode to %s", output->name); wlr_log(L_DEBUG, "Assigning custom mode to %s", output->name);
wlr_output_set_custom_mode(output, width, height, mhz); wlr_output_set_custom_mode(output, width, height, mhz);
return; return;
} }
@ -106,9 +106,9 @@ static void set_mode(struct wlr_output *output, int width, int height,
} }
} }
if (!best) { if (!best) {
wlr_log(WLR_ERROR, "Configured mode for %s not available", output->name); wlr_log(L_ERROR, "Configured mode for %s not available", output->name);
} else { } else {
wlr_log(WLR_DEBUG, "Assigning configured mode to %s", output->name); wlr_log(L_DEBUG, "Assigning configured mode to %s", output->name);
wlr_output_set_mode(output, best); wlr_output_set_mode(output, best);
} }
} }
@ -116,7 +116,7 @@ static void set_mode(struct wlr_output *output, int width, int height,
void terminate_swaybg(pid_t pid) { void terminate_swaybg(pid_t pid) {
int ret = kill(pid, SIGTERM); int ret = kill(pid, SIGTERM);
if (ret != 0) { if (ret != 0) {
wlr_log(WLR_ERROR, "Unable to terminate swaybg [pid: %d]", pid); wlr_log(L_ERROR, "Unable to terminate swaybg [pid: %d]", pid);
} else { } else {
int status; int status;
waitpid(pid, &status, 0); waitpid(pid, &status, 0);
@ -144,22 +144,22 @@ void apply_output_config(struct output_config *oc, struct sway_container *output
} }
if (oc && oc->width > 0 && oc->height > 0) { if (oc && oc->width > 0 && oc->height > 0) {
wlr_log(WLR_DEBUG, "Set %s mode to %dx%d (%f GHz)", oc->name, oc->width, wlr_log(L_DEBUG, "Set %s mode to %dx%d (%f GHz)", oc->name, oc->width,
oc->height, oc->refresh_rate); oc->height, oc->refresh_rate);
set_mode(wlr_output, oc->width, oc->height, oc->refresh_rate); set_mode(wlr_output, oc->width, oc->height, oc->refresh_rate);
} }
if (oc && oc->scale > 0) { if (oc && oc->scale > 0) {
wlr_log(WLR_DEBUG, "Set %s scale to %f", oc->name, oc->scale); wlr_log(L_DEBUG, "Set %s scale to %f", oc->name, oc->scale);
wlr_output_set_scale(wlr_output, oc->scale); wlr_output_set_scale(wlr_output, oc->scale);
} }
if (oc && oc->transform >= 0) { if (oc && oc->transform >= 0) {
wlr_log(WLR_DEBUG, "Set %s transform to %d", oc->name, oc->transform); wlr_log(L_DEBUG, "Set %s transform to %d", oc->name, oc->transform);
wlr_output_set_transform(wlr_output, oc->transform); wlr_output_set_transform(wlr_output, oc->transform);
} }
// Find position for it // Find position for it
if (oc && (oc->x != -1 || oc->y != -1)) { if (oc && (oc->x != -1 || oc->y != -1)) {
wlr_log(WLR_DEBUG, "Set %s position to %d, %d", oc->name, oc->x, oc->y); wlr_log(L_DEBUG, "Set %s position to %d, %d", oc->name, oc->x, oc->y);
wlr_output_layout_add(output_layout, wlr_output, oc->x, oc->y); wlr_output_layout_add(output_layout, wlr_output, oc->x, oc->y);
} else { } else {
wlr_output_layout_add_auto(output_layout, wlr_output); wlr_output_layout_add_auto(output_layout, wlr_output);
@ -187,7 +187,7 @@ void apply_output_config(struct output_config *oc, struct sway_container *output
terminate_swaybg(output->sway_output->bg_pid); terminate_swaybg(output->sway_output->bg_pid);
} }
wlr_log(WLR_DEBUG, "Setting background for output %d to %s", wlr_log(L_DEBUG, "Setting background for output %d to %s",
output_i, oc->background); output_i, oc->background);
size_t len = snprintf(NULL, 0, "%s %d %s %s", size_t len = snprintf(NULL, 0, "%s %d %s %s",
@ -195,13 +195,13 @@ void apply_output_config(struct output_config *oc, struct sway_container *output
output_i, oc->background, oc->background_option); output_i, oc->background, oc->background_option);
char *command = malloc(len + 1); char *command = malloc(len + 1);
if (!command) { if (!command) {
wlr_log(WLR_DEBUG, "Unable to allocate swaybg command"); wlr_log(L_DEBUG, "Unable to allocate swaybg command");
return; return;
} }
snprintf(command, len + 1, "%s %d %s %s", snprintf(command, len + 1, "%s %d %s %s",
config->swaybg_command ? config->swaybg_command : "swaybg", config->swaybg_command ? config->swaybg_command : "swaybg",
output_i, oc->background, oc->background_option); output_i, oc->background, oc->background_option);
wlr_log(WLR_DEBUG, "-> %s", command); wlr_log(L_DEBUG, "-> %s", command);
char *const cmd[] = { "sh", "-c", command, NULL }; char *const cmd[] = { "sh", "-c", command, NULL };
output->sway_output->bg_pid = fork(); output->sway_output->bg_pid = fork();
@ -212,11 +212,11 @@ void apply_output_config(struct output_config *oc, struct sway_container *output
if (oc && oc->dpms_state != DPMS_IGNORE) { if (oc && oc->dpms_state != DPMS_IGNORE) {
switch (oc->dpms_state) { switch (oc->dpms_state) {
case DPMS_ON: case DPMS_ON:
wlr_log(WLR_DEBUG, "Turning on screen"); wlr_log(L_DEBUG, "Turning on screen");
wlr_output_enable(wlr_output, true); wlr_output_enable(wlr_output, true);
break; break;
case DPMS_OFF: case DPMS_OFF:
wlr_log(WLR_DEBUG, "Turning off screen"); wlr_log(L_DEBUG, "Turning off screen");
wlr_output_enable(wlr_output, false); wlr_output_enable(wlr_output, false);
break; break;
case DPMS_IGNORE: case DPMS_IGNORE:

View file

@ -7,11 +7,11 @@
struct seat_config *new_seat_config(const char* name) { struct seat_config *new_seat_config(const char* name) {
struct seat_config *seat = calloc(1, sizeof(struct seat_config)); struct seat_config *seat = calloc(1, sizeof(struct seat_config));
if (!seat) { if (!seat) {
wlr_log(WLR_DEBUG, "Unable to allocate seat config"); wlr_log(L_DEBUG, "Unable to allocate seat config");
return NULL; return NULL;
} }
wlr_log(WLR_DEBUG, "new_seat_config(%s)", name); wlr_log(L_DEBUG, "new_seat_config(%s)", name);
seat->name = strdup(name); seat->name = strdup(name);
if (!sway_assert(seat->name, "could not allocate name for seat")) { if (!sway_assert(seat->name, "could not allocate name for seat")) {
free(seat); free(seat);
@ -34,7 +34,7 @@ struct seat_attachment_config *seat_attachment_config_new() {
struct seat_attachment_config *attachment = struct seat_attachment_config *attachment =
calloc(1, sizeof(struct seat_attachment_config)); calloc(1, sizeof(struct seat_attachment_config));
if (!attachment) { if (!attachment) {
wlr_log(WLR_DEBUG, "cannot allocate attachment config"); wlr_log(L_DEBUG, "cannot allocate attachment config");
return NULL; return NULL;
} }
return attachment; return attachment;

View file

@ -507,7 +507,7 @@ struct criteria *criteria_parse(char *raw, char **error_arg) {
} }
unescape(value); unescape(value);
} }
wlr_log(WLR_DEBUG, "Found pair: %s=%s", name, value); wlr_log(L_DEBUG, "Found pair: %s=%s", name, value);
if (!parse_token(criteria, name, value)) { if (!parse_token(criteria, name, value)) {
*error_arg = error; *error_arg = error;
goto cleanup; goto cleanup;

View file

@ -13,12 +13,3 @@ void desktop_damage_surface(struct wlr_surface *surface, double lx, double ly,
} }
} }
} }
void desktop_damage_whole_container(struct sway_container *con) {
for (int i = 0; i < root_container.children->length; ++i) {
struct sway_container *cont = root_container.children->items[i];
if (cont->type == C_OUTPUT) {
output_damage_whole_container(cont->sway_output, con);
}
}
}

View file

@ -1,79 +0,0 @@
#include <stdlib.h>
#include <wlr/types/wlr_idle.h>
#include "log.h"
#include "sway/desktop/idle_inhibit_v1.h"
#include "sway/tree/view.h"
#include "sway/server.h"
static void handle_destroy(struct wl_listener *listener, void *data) {
struct sway_idle_inhibitor_v1 *inhibitor =
wl_container_of(listener, inhibitor, destroy);
wlr_log(WLR_DEBUG, "Sway idle inhibitor destroyed");
wl_list_remove(&inhibitor->link);
wl_list_remove(&inhibitor->destroy.link);
idle_inhibit_v1_check_active(inhibitor->manager);
free(inhibitor);
}
void handle_idle_inhibitor_v1(struct wl_listener *listener, void *data) {
struct wlr_idle_inhibitor_v1 *wlr_inhibitor = data;
struct sway_idle_inhibit_manager_v1 *manager =
wl_container_of(listener, manager, new_idle_inhibitor_v1);
wlr_log(WLR_DEBUG, "New sway idle inhibitor");
struct sway_idle_inhibitor_v1 *inhibitor =
calloc(1, sizeof(struct sway_idle_inhibitor_v1));
if (!inhibitor) {
return;
}
inhibitor->manager = manager;
inhibitor->view = view_from_wlr_surface(wlr_inhibitor->surface);
wl_list_insert(&manager->inhibitors, &inhibitor->link);
inhibitor->destroy.notify = handle_destroy;
wl_signal_add(&wlr_inhibitor->events.destroy, &inhibitor->destroy);
idle_inhibit_v1_check_active(manager);
}
void idle_inhibit_v1_check_active(
struct sway_idle_inhibit_manager_v1 *manager) {
struct sway_idle_inhibitor_v1 *inhibitor;
bool inhibited = false;
wl_list_for_each(inhibitor, &manager->inhibitors, link) {
if (!inhibitor->view) {
/* Cannot guess if view is visible so assume it is */
inhibited = true;
break;
}
if (view_is_visible(inhibitor->view)) {
inhibited = true;
break;
}
}
wlr_idle_set_enabled(manager->idle, NULL, !inhibited);
}
struct sway_idle_inhibit_manager_v1 *sway_idle_inhibit_manager_v1_create(
struct wl_display *wl_display, struct wlr_idle *idle) {
struct sway_idle_inhibit_manager_v1 *manager =
calloc(1, sizeof(struct sway_idle_inhibit_manager_v1));
if (!manager) {
return NULL;
}
manager->wlr_manager = wlr_idle_inhibit_v1_create(wl_display);
if (!manager->wlr_manager) {
return NULL;
}
manager->idle = idle;
wl_signal_add(&manager->wlr_manager->events.new_inhibitor,
&manager->new_idle_inhibitor_v1);
manager->new_idle_inhibitor_v1.notify = handle_idle_inhibitor_v1;
wl_list_init(&manager->inhibitors);
return manager;
}

View file

@ -174,7 +174,7 @@ void arrange_layers(struct sway_output *output) {
if (memcmp(&usable_area, &output->usable_area, if (memcmp(&usable_area, &output->usable_area,
sizeof(struct wlr_box)) != 0) { sizeof(struct wlr_box)) != 0) {
wlr_log(WLR_DEBUG, "Usable area changed, rearranging output"); wlr_log(L_DEBUG, "Usable area changed, rearranging output");
memcpy(&output->usable_area, &usable_area, sizeof(struct wlr_box)); memcpy(&output->usable_area, &usable_area, sizeof(struct wlr_box));
arrange_and_commit(output->swayc); arrange_and_commit(output->swayc);
} }
@ -269,7 +269,7 @@ static void unmap(struct sway_layer_surface *sway_layer) {
static void handle_destroy(struct wl_listener *listener, void *data) { static void handle_destroy(struct wl_listener *listener, void *data) {
struct sway_layer_surface *sway_layer = struct sway_layer_surface *sway_layer =
wl_container_of(listener, sway_layer, destroy); wl_container_of(listener, sway_layer, destroy);
wlr_log(WLR_DEBUG, "Layer surface destroyed (%s)", wlr_log(L_DEBUG, "Layer surface destroyed (%s)",
sway_layer->layer_surface->namespace); sway_layer->layer_surface->namespace);
if (sway_layer->layer_surface->mapped) { if (sway_layer->layer_surface->mapped) {
unmap(sway_layer); unmap(sway_layer);
@ -316,7 +316,7 @@ void handle_layer_shell_surface(struct wl_listener *listener, void *data) {
struct wlr_layer_surface *layer_surface = data; struct wlr_layer_surface *layer_surface = data;
struct sway_server *server = struct sway_server *server =
wl_container_of(listener, server, layer_shell_surface); wl_container_of(listener, server, layer_shell_surface);
wlr_log(WLR_DEBUG, "new layer surface: namespace %s layer %d anchor %d " wlr_log(L_DEBUG, "new layer surface: namespace %s layer %d anchor %d "
"size %dx%d margin %d,%d,%d,%d", "size %dx%d margin %d,%d,%d,%d",
layer_surface->namespace, layer_surface->layer, layer_surface->layer, layer_surface->namespace, layer_surface->layer, layer_surface->layer,
layer_surface->client_pending.desired_width, layer_surface->client_pending.desired_width,

File diff suppressed because it is too large Load diff

View file

@ -1,904 +0,0 @@
#define _POSIX_C_SOURCE 200809L
#include <assert.h>
#include <stdlib.h>
#include <strings.h>
#include <time.h>
#include <wayland-server.h>
#include <wlr/render/wlr_renderer.h>
#include <wlr/types/wlr_box.h>
#include <wlr/types/wlr_buffer.h>
#include <wlr/types/wlr_matrix.h>
#include <wlr/types/wlr_output_damage.h>
#include <wlr/types/wlr_output_layout.h>
#include <wlr/types/wlr_output.h>
#include <wlr/types/wlr_surface.h>
#include <wlr/util/region.h>
#include "log.h"
#include "sway/config.h"
#include "sway/input/input-manager.h"
#include "sway/input/seat.h"
#include "sway/layers.h"
#include "sway/output.h"
#include "sway/server.h"
#include "sway/tree/arrange.h"
#include "sway/tree/container.h"
#include "sway/tree/layout.h"
#include "sway/tree/view.h"
#include "sway/tree/workspace.h"
struct render_data {
struct root_geometry root_geo;
struct sway_output *output;
pixman_region32_t *damage;
struct sway_view *view;
float alpha;
};
static void scale_box(struct wlr_box *box, float scale) {
box->x *= scale;
box->y *= scale;
box->width *= scale;
box->height *= scale;
}
static void scissor_output(struct wlr_output *wlr_output,
pixman_box32_t *rect) {
struct wlr_renderer *renderer = wlr_backend_get_renderer(wlr_output->backend);
assert(renderer);
struct wlr_box box = {
.x = rect->x1,
.y = rect->y1,
.width = rect->x2 - rect->x1,
.height = rect->y2 - rect->y1,
};
int ow, oh;
wlr_output_transformed_resolution(wlr_output, &ow, &oh);
enum wl_output_transform transform =
wlr_output_transform_invert(wlr_output->transform);
wlr_box_transform(&box, transform, ow, oh, &box);
wlr_renderer_scissor(renderer, &box);
}
static void render_texture(struct wlr_output *wlr_output,
pixman_region32_t *output_damage, struct wlr_texture *texture,
const struct wlr_box *box, const float matrix[static 9], float alpha) {
struct wlr_renderer *renderer =
wlr_backend_get_renderer(wlr_output->backend);
pixman_region32_t damage;
pixman_region32_init(&damage);
pixman_region32_union_rect(&damage, &damage, box->x, box->y,
box->width, box->height);
pixman_region32_intersect(&damage, &damage, output_damage);
bool damaged = pixman_region32_not_empty(&damage);
if (!damaged) {
goto damage_finish;
}
int nrects;
pixman_box32_t *rects = pixman_region32_rectangles(&damage, &nrects);
for (int i = 0; i < nrects; ++i) {
scissor_output(wlr_output, &rects[i]);
wlr_render_texture_with_matrix(renderer, texture, matrix, alpha);
}
damage_finish:
pixman_region32_fini(&damage);
}
static void render_surface_iterator(struct wlr_surface *surface, int sx, int sy,
void *_data) {
struct render_data *data = _data;
struct wlr_output *wlr_output = data->output->wlr_output;
float rotation = data->root_geo.rotation;
pixman_region32_t *output_damage = data->damage;
float alpha = data->alpha;
struct wlr_texture *texture = wlr_surface_get_texture(surface);
if (!texture) {
return;
}
struct wlr_box box;
bool intersects = output_get_surface_box(&data->root_geo, data->output,
surface, sx, sy, &box);
if (!intersects) {
return;
}
scale_box(&box, wlr_output->scale);
float matrix[9];
enum wl_output_transform transform =
wlr_output_transform_invert(surface->current.transform);
wlr_matrix_project_box(matrix, &box, transform, rotation,
wlr_output->transform_matrix);
render_texture(wlr_output, output_damage, texture, &box, matrix, alpha);
}
static void render_layer(struct sway_output *output,
pixman_region32_t *damage, struct wl_list *layer_surfaces) {
struct render_data data = {
.output = output,
.damage = damage,
.alpha = 1.0f,
};
output_layer_for_each_surface(layer_surfaces, &data.root_geo,
render_surface_iterator, &data);
}
static void render_unmanaged(struct sway_output *output,
pixman_region32_t *damage, struct wl_list *unmanaged) {
struct render_data data = {
.output = output,
.damage = damage,
.alpha = 1.0f,
};
output_unmanaged_for_each_surface(unmanaged, output, &data.root_geo,
render_surface_iterator, &data);
}
static void render_drag_icons(struct sway_output *output,
pixman_region32_t *damage, struct wl_list *drag_icons) {
struct render_data data = {
.output = output,
.damage = damage,
.alpha = 1.0f,
};
output_drag_icons_for_each_surface(drag_icons, output, &data.root_geo,
render_surface_iterator, &data);
}
static void render_rect(struct wlr_output *wlr_output,
pixman_region32_t *output_damage, const struct wlr_box *_box,
float color[static 4]) {
struct wlr_renderer *renderer =
wlr_backend_get_renderer(wlr_output->backend);
struct wlr_box box;
memcpy(&box, _box, sizeof(struct wlr_box));
box.x -= wlr_output->lx * wlr_output->scale;
box.y -= wlr_output->ly * wlr_output->scale;
pixman_region32_t damage;
pixman_region32_init(&damage);
pixman_region32_union_rect(&damage, &damage, box.x, box.y,
box.width, box.height);
pixman_region32_intersect(&damage, &damage, output_damage);
bool damaged = pixman_region32_not_empty(&damage);
if (!damaged) {
goto damage_finish;
}
int nrects;
pixman_box32_t *rects = pixman_region32_rectangles(&damage, &nrects);
for (int i = 0; i < nrects; ++i) {
scissor_output(wlr_output, &rects[i]);
wlr_render_rect(renderer, &box, color,
wlr_output->transform_matrix);
}
damage_finish:
pixman_region32_fini(&damage);
}
static void premultiply_alpha(float color[4], float opacity) {
color[3] *= opacity;
color[0] *= color[3];
color[1] *= color[3];
color[2] *= color[3];
}
static void render_view_surfaces(struct sway_view *view,
struct sway_output *output, pixman_region32_t *damage, float alpha) {
struct render_data data = {
.output = output,
.damage = damage,
.view = view,
.alpha = alpha,
};
output_view_for_each_surface(view, output, &data.root_geo,
render_surface_iterator, &data);
}
static void render_saved_view(struct sway_view *view,
struct sway_output *output, pixman_region32_t *damage, float alpha) {
struct wlr_output *wlr_output = output->wlr_output;
int width, height;
struct wlr_texture *texture =
transaction_get_saved_texture(view, &width, &height);
if (!texture) {
return;
}
struct wlr_box box = {
.x = view->swayc->current.view_x - output->swayc->current.swayc_x,
.y = view->swayc->current.view_y - output->swayc->current.swayc_y,
.width = width,
.height = height,
};
struct wlr_box output_box = {
.width = output->swayc->current.swayc_width,
.height = output->swayc->current.swayc_height,
};
struct wlr_box intersection;
bool intersects = wlr_box_intersection(&output_box, &box, &intersection);
if (!intersects) {
return;
}
scale_box(&box, wlr_output->scale);
float matrix[9];
wlr_matrix_project_box(matrix, &box, WL_OUTPUT_TRANSFORM_NORMAL, 0,
wlr_output->transform_matrix);
render_texture(wlr_output, damage, texture, &box, matrix, alpha);
}
/**
* Render a view's surface and left/bottom/right borders.
*/
static void render_view(struct sway_output *output, pixman_region32_t *damage,
struct sway_container *con, struct border_colors *colors) {
struct sway_view *view = con->sway_view;
if (view->swayc->instructions->length) {
render_saved_view(view, output, damage, view->swayc->alpha);
} else {
render_view_surfaces(view, output, damage, view->swayc->alpha);
}
struct wlr_box box;
float output_scale = output->wlr_output->scale;
float color[4];
struct sway_container_state *state = &con->current;
if (state->border != B_NONE) {
if (state->border_left) {
memcpy(&color, colors->child_border, sizeof(float) * 4);
premultiply_alpha(color, con->alpha);
box.x = state->swayc_x;
box.y = state->view_y;
box.width = state->border_thickness;
box.height = state->view_height;
scale_box(&box, output_scale);
render_rect(output->wlr_output, damage, &box, color);
}
if (state->border_right) {
if (state->parent->current.children->length == 1
&& state->parent->current.layout == L_HORIZ) {
memcpy(&color, colors->indicator, sizeof(float) * 4);
} else {
memcpy(&color, colors->child_border, sizeof(float) * 4);
}
premultiply_alpha(color, con->alpha);
box.x = state->view_x + state->view_width;
box.y = state->view_y;
box.width = state->border_thickness;
box.height = state->view_height;
scale_box(&box, output_scale);
render_rect(output->wlr_output, damage, &box, color);
}
if (state->border_bottom) {
if (state->parent->current.children->length == 1
&& con->current.parent->current.layout == L_VERT) {
memcpy(&color, colors->indicator, sizeof(float) * 4);
} else {
memcpy(&color, colors->child_border, sizeof(float) * 4);
}
premultiply_alpha(color, con->alpha);
box.x = state->swayc_x;
box.y = state->view_y + state->view_height;
box.width = state->swayc_width;
box.height = state->border_thickness;
scale_box(&box, output_scale);
render_rect(output->wlr_output, damage, &box, color);
}
}
}
/**
* Render a titlebar.
*
* Care must be taken not to render over the same pixel multiple times,
* otherwise the colors will be incorrect when using opacity.
*
* The height is: 1px border, 3px padding, font height, 3px padding, 1px border
* The left side for L_TABBED is: 1px border, 2px padding, title
* The left side for other layouts is: 3px padding, title
*/
static void render_titlebar(struct sway_output *output,
pixman_region32_t *output_damage, struct sway_container *con,
int x, int y, int width,
struct border_colors *colors, struct wlr_texture *title_texture,
struct wlr_texture *marks_texture) {
struct wlr_box box;
float color[4];
struct sway_container_state *state = &con->current;
float output_scale = output->wlr_output->scale;
enum sway_container_layout layout = state->parent->current.layout;
list_t *children = state->parent->current.children;
bool is_last_child = children->items[children->length - 1] == con;
double output_x = output->swayc->current.swayc_x;
double output_y = output->swayc->current.swayc_y;
// Single pixel bar above title
memcpy(&color, colors->border, sizeof(float) * 4);
premultiply_alpha(color, con->alpha);
box.x = x;
box.y = y;
box.width = width;
box.height = TITLEBAR_BORDER_THICKNESS;
scale_box(&box, output_scale);
render_rect(output->wlr_output, output_damage, &box, color);
// Single pixel bar below title
size_t left_offset = 0, right_offset = 0;
bool connects_sides = false;
if (layout == L_HORIZ || layout == L_VERT ||
(layout == L_STACKED && is_last_child)) {
if (con->type == C_VIEW) {
left_offset = state->border_left * state->border_thickness;
right_offset = state->border_right * state->border_thickness;
connects_sides = true;
}
}
box.x = x + left_offset;
box.y = y + container_titlebar_height() - TITLEBAR_BORDER_THICKNESS;
box.width = width - left_offset - right_offset;
box.height = TITLEBAR_BORDER_THICKNESS;
scale_box(&box, output_scale);
render_rect(output->wlr_output, output_damage, &box, color);
if (layout == L_TABBED) {
// Single pixel left edge
box.x = x;
box.y = y + TITLEBAR_BORDER_THICKNESS;
box.width = TITLEBAR_BORDER_THICKNESS;
box.height =
container_titlebar_height() - TITLEBAR_BORDER_THICKNESS * 2;
scale_box(&box, output_scale);
render_rect(output->wlr_output, output_damage, &box, color);
// Single pixel right edge
box.x = (x + width - TITLEBAR_BORDER_THICKNESS) * output_scale;
render_rect(output->wlr_output, output_damage, &box, color);
}
size_t inner_width = width - TITLEBAR_H_PADDING * 2;
// Marks
size_t marks_ob_width = 0; // output-buffer-local
if (config->show_marks && marks_texture) {
struct wlr_box texture_box;
wlr_texture_get_size(marks_texture,
&texture_box.width, &texture_box.height);
texture_box.x = (x - output_x + width - TITLEBAR_H_PADDING)
* output_scale - texture_box.width;
texture_box.y = (y - output_y + TITLEBAR_V_PADDING) * output_scale;
float matrix[9];
wlr_matrix_project_box(matrix, &texture_box,
WL_OUTPUT_TRANSFORM_NORMAL,
0.0, output->wlr_output->transform_matrix);
if (inner_width * output_scale < texture_box.width) {
texture_box.width = inner_width * output_scale;
}
render_texture(output->wlr_output, output_damage, marks_texture,
&texture_box, matrix, con->alpha);
marks_ob_width = texture_box.width;
// Gap between the marks and bottom padding, for when the marks texture
// height is smaller than the config's font height
memcpy(&color, colors->background, sizeof(float) * 4);
premultiply_alpha(color, con->alpha);
box.x = texture_box.x;
box.y = texture_box.y + texture_box.height;
box.width = texture_box.width;
box.height = config->font_height * output_scale - texture_box.height;
if (box.height > 0) {
render_rect(output->wlr_output, output_damage, &box, color);
}
}
// Title text
size_t title_ob_width = 0; // output-buffer-local
if (title_texture) {
struct wlr_box texture_box;
wlr_texture_get_size(title_texture,
&texture_box.width, &texture_box.height);
texture_box.x = (x - output_x + TITLEBAR_H_PADDING) * output_scale;
texture_box.y = (y - output_y + TITLEBAR_V_PADDING) * output_scale;
float matrix[9];
wlr_matrix_project_box(matrix, &texture_box,
WL_OUTPUT_TRANSFORM_NORMAL,
0.0, output->wlr_output->transform_matrix);
if (inner_width * output_scale - marks_ob_width < texture_box.width) {
texture_box.width = inner_width * output_scale - marks_ob_width;
}
render_texture(output->wlr_output, output_damage, title_texture,
&texture_box, matrix, con->alpha);
title_ob_width = texture_box.width;
// Gap between the title and bottom padding, for when the title texture
// height is smaller than the config's font height
memcpy(&color, colors->background, sizeof(float) * 4);
premultiply_alpha(color, con->alpha);
box.x = texture_box.x;
box.y = texture_box.y + texture_box.height;
box.width = texture_box.width;
box.height = config->font_height * output_scale - texture_box.height;
if (box.height > 0) {
render_rect(output->wlr_output, output_damage, &box, color);
}
}
// Padding above title
memcpy(&color, colors->background, sizeof(float) * 4);
premultiply_alpha(color, con->alpha);
box.x = x + (layout == L_TABBED) * TITLEBAR_BORDER_THICKNESS;
box.y = y + TITLEBAR_BORDER_THICKNESS;
box.width = width - (layout == L_TABBED) * TITLEBAR_BORDER_THICKNESS * 2;
box.height = TITLEBAR_V_PADDING - TITLEBAR_BORDER_THICKNESS;
scale_box(&box, output_scale);
render_rect(output->wlr_output, output_damage, &box, color);
// Padding below title
box.y = (y + TITLEBAR_V_PADDING + config->font_height) * output_scale;
render_rect(output->wlr_output, output_damage, &box, color);
// Filler between title and marks
box.width = inner_width * output_scale - title_ob_width - marks_ob_width;
if (box.width > 0) {
box.x = (x + TITLEBAR_H_PADDING) * output_scale + title_ob_width;
box.y = (y + TITLEBAR_V_PADDING) * output_scale;
box.height = config->font_height * output_scale;
render_rect(output->wlr_output, output_damage, &box, color);
}
// Padding left of title
left_offset = (layout == L_TABBED) * TITLEBAR_BORDER_THICKNESS;
box.x = x + left_offset;
box.y = y + TITLEBAR_V_PADDING;
box.width = TITLEBAR_H_PADDING - left_offset;
box.height = config->font_height;
scale_box(&box, output_scale);
render_rect(output->wlr_output, output_damage, &box, color);
// Padding right of marks
right_offset = (layout == L_TABBED) * TITLEBAR_BORDER_THICKNESS;
box.x = x + width - TITLEBAR_H_PADDING;
box.y = y + TITLEBAR_V_PADDING;
box.width = TITLEBAR_H_PADDING - right_offset;
box.height = config->font_height;
scale_box(&box, output_scale);
render_rect(output->wlr_output, output_damage, &box, color);
if (connects_sides) {
// Left pixel in line with bottom bar
box.x = x;
box.y = y + container_titlebar_height() - TITLEBAR_BORDER_THICKNESS;
box.width = state->border_thickness * state->border_left;
box.height = TITLEBAR_BORDER_THICKNESS;
scale_box(&box, output_scale);
render_rect(output->wlr_output, output_damage, &box, color);
// Right pixel in line with bottom bar
box.x = x + width - state->border_thickness * state->border_right;
box.y = y + container_titlebar_height() - TITLEBAR_BORDER_THICKNESS;
box.width = state->border_thickness * state->border_right;
box.height = TITLEBAR_BORDER_THICKNESS;
scale_box(&box, output_scale);
render_rect(output->wlr_output, output_damage, &box, color);
}
}
/**
* Render the top border line for a view using "border pixel".
*/
static void render_top_border(struct sway_output *output,
pixman_region32_t *output_damage, struct sway_container *con,
struct border_colors *colors) {
struct sway_container_state *state = &con->current;
if (!state->border_top) {
return;
}
struct wlr_box box;
float color[4];
float output_scale = output->wlr_output->scale;
// Child border - top edge
memcpy(&color, colors->child_border, sizeof(float) * 4);
premultiply_alpha(color, con->alpha);
box.x = state->swayc_x;
box.y = state->swayc_y;
box.width = state->swayc_width;
box.height = state->border_thickness;
scale_box(&box, output_scale);
render_rect(output->wlr_output, output_damage, &box, color);
}
static void render_container(struct sway_output *output,
pixman_region32_t *damage, struct sway_container *con, bool parent_focused);
/**
* Render a container's children using a L_HORIZ or L_VERT layout.
*
* Wrap child views in borders and leave child containers borderless because
* they'll apply their own borders to their children.
*/
static void render_container_simple(struct sway_output *output,
pixman_region32_t *damage, struct sway_container *con,
bool parent_focused) {
struct sway_seat *seat = input_manager_current_seat(input_manager);
struct sway_container *focus = seat_get_focus(seat);
for (int i = 0; i < con->current.children->length; ++i) {
struct sway_container *child = con->current.children->items[i];
if (child->type == C_VIEW) {
struct sway_view *view = child->sway_view;
struct border_colors *colors;
struct wlr_texture *title_texture;
struct wlr_texture *marks_texture;
struct sway_container_state *state = &child->current;
if (focus == child || parent_focused) {
colors = &config->border_colors.focused;
title_texture = child->title_focused;
marks_texture = view->marks_focused;
} else if (seat_get_focus_inactive(seat, con) == child) {
colors = &config->border_colors.focused_inactive;
title_texture = child->title_focused_inactive;
marks_texture = view->marks_focused_inactive;
} else {
colors = &config->border_colors.unfocused;
title_texture = child->title_unfocused;
marks_texture = view->marks_unfocused;
}
if (state->border == B_NORMAL) {
render_titlebar(output, damage, child, state->swayc_x,
state->swayc_y, state->swayc_width, colors,
title_texture, marks_texture);
} else {
render_top_border(output, damage, child, colors);
}
render_view(output, damage, child, colors);
} else {
render_container(output, damage, child,
parent_focused || focus == child);
}
}
}
/**
* Render a container's children using the L_TABBED layout.
*/
static void render_container_tabbed(struct sway_output *output,
pixman_region32_t *damage, struct sway_container *con,
bool parent_focused) {
if (!con->current.children->length) {
return;
}
struct sway_seat *seat = input_manager_current_seat(input_manager);
struct sway_container *focus = seat_get_focus(seat);
struct sway_container *current = seat_get_active_current_child(seat, con);
struct border_colors *current_colors = &config->border_colors.unfocused;
struct sway_container_state *pstate = &con->current;
double width_gap_adjustment = 2 * pstate->current_gaps;
int tab_width =
(pstate->swayc_width - width_gap_adjustment) / pstate->children->length;
// Render tabs
for (int i = 0; i < pstate->children->length; ++i) {
struct sway_container *child = pstate->children->items[i];
struct sway_view *view = child->type == C_VIEW ? child->sway_view : NULL;
struct sway_container_state *cstate = &child->current;
struct border_colors *colors;
struct wlr_texture *title_texture;
struct wlr_texture *marks_texture;
if (focus == child || parent_focused) {
colors = &config->border_colors.focused;
title_texture = child->title_focused;
marks_texture = view ? view->marks_focused : NULL;
} else if (child == current) {
colors = &config->border_colors.focused_inactive;
title_texture = child->title_focused_inactive;
marks_texture = view ? view->marks_focused_inactive : NULL;
} else {
colors = &config->border_colors.unfocused;
title_texture = child->title_unfocused;
marks_texture = view ? view->marks_unfocused : NULL;
}
int x = cstate->swayc_x + tab_width * i;
// Make last tab use the remaining width of the parent
if (i == pstate->children->length - 1) {
tab_width =
pstate->swayc_width - width_gap_adjustment - tab_width * i;
}
render_titlebar(output, damage, child, x, cstate->swayc_y, tab_width,
colors, title_texture, marks_texture);
if (child == current) {
current_colors = colors;
}
}
// Render surface and left/right/bottom borders
if (current) {
if (current->type == C_VIEW) {
render_view(output, damage, current, current_colors);
} else {
render_container(output, damage, current,
parent_focused || current == focus);
}
}
}
/**
* Render a container's children using the L_STACKED layout.
*/
static void render_container_stacked(struct sway_output *output,
pixman_region32_t *damage, struct sway_container *con,
bool parent_focused) {
if (!con->current.children->length) {
return;
}
struct sway_seat *seat = input_manager_current_seat(input_manager);
struct sway_container *focus = seat_get_focus(seat);
struct sway_container *current = seat_get_active_current_child(seat, con);
struct border_colors *current_colors = &config->border_colors.unfocused;
struct sway_container_state *pstate = &con->current;
size_t titlebar_height = container_titlebar_height();
// Render titles
for (int i = 0; i < pstate->children->length; ++i) {
struct sway_container *child = pstate->children->items[i];
struct sway_view *view = child->type == C_VIEW ? child->sway_view : NULL;
struct sway_container_state *cstate = &child->current;
struct border_colors *colors;
struct wlr_texture *title_texture;
struct wlr_texture *marks_texture;
if (focus == child || parent_focused) {
colors = &config->border_colors.focused;
title_texture = child->title_focused;
marks_texture = view ? view->marks_focused : NULL;
} else if (child == current) {
colors = &config->border_colors.focused_inactive;
title_texture = child->title_focused_inactive;
marks_texture = view ? view->marks_focused_inactive : NULL;
} else {
colors = &config->border_colors.unfocused;
title_texture = child->title_unfocused;
marks_texture = view ? view->marks_unfocused : NULL;
}
int y = cstate->swayc_y + titlebar_height * i;
render_titlebar(output, damage, child, cstate->swayc_x, y,
cstate->swayc_width, colors, title_texture, marks_texture);
if (child == current) {
current_colors = colors;
}
}
// Render surface and left/right/bottom borders
if (current) {
if (current->type == C_VIEW) {
render_view(output, damage, current, current_colors);
} else {
render_container(output, damage, current,
parent_focused || current == focus);
}
}
}
static void render_container(struct sway_output *output,
pixman_region32_t *damage, struct sway_container *con,
bool parent_focused) {
switch (con->current.layout) {
case L_NONE:
case L_HORIZ:
case L_VERT:
render_container_simple(output, damage, con, parent_focused);
break;
case L_STACKED:
render_container_stacked(output, damage, con, parent_focused);
break;
case L_TABBED:
render_container_tabbed(output, damage, con, parent_focused);
break;
case L_FLOATING:
sway_assert(false, "Didn't expect to see floating here");
}
}
static void render_floating_container(struct sway_output *soutput,
pixman_region32_t *damage, struct sway_container *con) {
if (con->type == C_VIEW) {
struct sway_view *view = con->sway_view;
struct sway_seat *seat = input_manager_current_seat(input_manager);
struct sway_container *focus = seat_get_focus(seat);
struct border_colors *colors;
struct wlr_texture *title_texture;
struct wlr_texture *marks_texture;
if (focus == con) {
colors = &config->border_colors.focused;
title_texture = con->title_focused;
marks_texture = view->marks_focused;
} else {
colors = &config->border_colors.unfocused;
title_texture = con->title_unfocused;
marks_texture = view->marks_unfocused;
}
if (con->current.border == B_NORMAL) {
render_titlebar(soutput, damage, con, con->current.swayc_x,
con->current.swayc_y, con->current.swayc_width, colors,
title_texture, marks_texture);
} else if (con->current.border != B_NONE) {
render_top_border(soutput, damage, con, colors);
}
render_view(soutput, damage, con, colors);
} else {
render_container(soutput, damage, con, false);
}
}
static void render_floating(struct sway_output *soutput,
pixman_region32_t *damage) {
for (int i = 0; i < root_container.current.children->length; ++i) {
struct sway_container *output =
root_container.current.children->items[i];
for (int j = 0; j < output->current.children->length; ++j) {
struct sway_container *ws = output->current.children->items[j];
if (!workspace_is_visible(ws)) {
continue;
}
list_t *floating =
ws->current.ws_floating->current.children;
for (int k = 0; k < floating->length; ++k) {
struct sway_container *floater = floating->items[k];
render_floating_container(soutput, damage, floater);
}
}
}
}
void output_render(struct sway_output *output, struct timespec *when,
pixman_region32_t *damage) {
struct wlr_output *wlr_output = output->wlr_output;
struct wlr_renderer *renderer =
wlr_backend_get_renderer(wlr_output->backend);
if (!sway_assert(renderer != NULL,
"expected the output backend to have a renderer")) {
return;
}
wlr_renderer_begin(renderer, wlr_output->width, wlr_output->height);
bool damage_whole_before_swap = false;
if (!pixman_region32_not_empty(damage)) {
// Output isn't damaged but needs buffer swap
goto renderer_end;
}
const char *damage_debug = getenv("SWAY_DAMAGE_DEBUG");
if (damage_debug != NULL) {
if (strcmp(damage_debug, "highlight") == 0) {
wlr_renderer_clear(renderer, (float[]){1, 1, 0, 1});
damage_whole_before_swap = true;
} else if (strcmp(damage_debug, "rerender") == 0) {
int width, height;
wlr_output_transformed_resolution(wlr_output, &width, &height);
pixman_region32_union_rect(damage, damage, 0, 0, width, height);
}
}
struct sway_container *workspace = output_get_active_workspace(output);
struct sway_view *fullscreen_view = workspace->current.ws_fullscreen;
struct sway_seat *seat = input_manager_current_seat(input_manager);
if (output_has_opaque_lockscreen(output, seat)) {
struct wlr_layer_surface *wlr_layer_surface = seat->focused_layer;
struct sway_layer_surface *sway_layer_surface =
layer_from_wlr_layer_surface(seat->focused_layer);
struct render_data data = {
.output = output,
.damage = damage,
.alpha = 1.0f,
};
output_surface_for_each_surface(wlr_layer_surface->surface,
sway_layer_surface->geo.x, sway_layer_surface->geo.y,
&data.root_geo, render_surface_iterator, &data);
} else if (fullscreen_view) {
float clear_color[] = {0.0f, 0.0f, 0.0f, 1.0f};
int nrects;
pixman_box32_t *rects = pixman_region32_rectangles(damage, &nrects);
for (int i = 0; i < nrects; ++i) {
scissor_output(wlr_output, &rects[i]);
wlr_renderer_clear(renderer, clear_color);
}
// TODO: handle views smaller than the output
if (fullscreen_view->swayc->instructions->length) {
render_saved_view(fullscreen_view, output, damage, 1.0f);
} else {
render_view_surfaces(fullscreen_view, output, damage, 1.0f);
}
if (fullscreen_view->type == SWAY_VIEW_XWAYLAND) {
render_unmanaged(output, damage,
&root_container.sway_root->xwayland_unmanaged);
}
} else {
float clear_color[] = {0.25f, 0.25f, 0.25f, 1.0f};
int nrects;
pixman_box32_t *rects = pixman_region32_rectangles(damage, &nrects);
for (int i = 0; i < nrects; ++i) {
scissor_output(wlr_output, &rects[i]);
wlr_renderer_clear(renderer, clear_color);
}
render_layer(output, damage,
&output->layers[ZWLR_LAYER_SHELL_V1_LAYER_BACKGROUND]);
render_layer(output, damage,
&output->layers[ZWLR_LAYER_SHELL_V1_LAYER_BOTTOM]);
struct sway_seat *seat = input_manager_current_seat(input_manager);
struct sway_container *focus = seat_get_focus(seat);
render_container(output, damage, workspace, focus == workspace);
render_floating(output, damage);
render_unmanaged(output, damage,
&root_container.sway_root->xwayland_unmanaged);
render_layer(output, damage,
&output->layers[ZWLR_LAYER_SHELL_V1_LAYER_TOP]);
}
render_layer(output, damage,
&output->layers[ZWLR_LAYER_SHELL_V1_LAYER_OVERLAY]);
render_drag_icons(output, damage, &root_container.sway_root->drag_icons);
renderer_end:
if (root_container.sway_root->debug_tree) {
wlr_render_texture(renderer, root_container.sway_root->debug_tree,
wlr_output->transform_matrix, 0, 0, 1);
}
if (damage_whole_before_swap || root_container.sway_root->debug_tree) {
int width, height;
wlr_output_transformed_resolution(wlr_output, &width, &height);
pixman_region32_union_rect(damage, damage, 0, 0, width, height);
}
wlr_renderer_scissor(renderer, NULL);
wlr_renderer_end(renderer);
if (!wlr_output_damage_swap_buffers(output->damage, when, damage)) {
return;
}
output->last_frame = *when;
}

View file

@ -6,7 +6,6 @@
#include <wlr/types/wlr_buffer.h> #include <wlr/types/wlr_buffer.h>
#include <wlr/types/wlr_linux_dmabuf.h> #include <wlr/types/wlr_linux_dmabuf.h>
#include "sway/debug.h" #include "sway/debug.h"
#include "sway/desktop/idle_inhibit_v1.h"
#include "sway/desktop/transaction.h" #include "sway/desktop/transaction.h"
#include "sway/output.h" #include "sway/output.h"
#include "sway/tree/container.h" #include "sway/tree/container.h"
@ -73,8 +72,8 @@ static void save_view_buffer(struct sway_view *view,
} }
if (view->surface && wlr_surface_has_buffer(view->surface)) { if (view->surface && wlr_surface_has_buffer(view->surface)) {
instruction->saved_buffer = wlr_buffer_ref(view->surface->buffer); instruction->saved_buffer = wlr_buffer_ref(view->surface->buffer);
instruction->saved_buffer_width = view->surface->current.width; instruction->saved_buffer_width = view->surface->current->width;
instruction->saved_buffer_height = view->surface->current.height; instruction->saved_buffer_height = view->surface->current->height;
} }
} }
@ -175,7 +174,7 @@ void transaction_add_container(struct sway_transaction *transaction,
* Apply a transaction to the "current" state of the tree. * Apply a transaction to the "current" state of the tree.
*/ */
static void transaction_apply(struct sway_transaction *transaction) { static void transaction_apply(struct sway_transaction *transaction) {
wlr_log(WLR_DEBUG, "Applying transaction %p", transaction); wlr_log(L_DEBUG, "Applying transaction %p", transaction);
if (server.debug_txn_timings) { if (server.debug_txn_timings) {
struct timespec now; struct timespec now;
clock_gettime(CLOCK_MONOTONIC, &now); clock_gettime(CLOCK_MONOTONIC, &now);
@ -186,9 +185,9 @@ static void transaction_apply(struct sway_transaction *transaction) {
float ms_waiting = (now.tv_sec - commit->tv_sec) * 1000 + float ms_waiting = (now.tv_sec - commit->tv_sec) * 1000 +
(now.tv_nsec - commit->tv_nsec) / 1000000.0; (now.tv_nsec - commit->tv_nsec) / 1000000.0;
float ms_total = ms_arranging + ms_waiting; float ms_total = ms_arranging + ms_waiting;
wlr_log(WLR_DEBUG, "Transaction %p: %.1fms arranging, %.1fms waiting, " wlr_log(L_DEBUG, "Transaction %p: %.1fms arranging, %.1fms waiting, "
"%.1fms total (%.1f frames if 60Hz)", transaction, "%.1fms total (%.1f frames if 60Hz)", transaction,
ms_arranging, ms_waiting, ms_total, ms_total / (1000.0f / 60)); ms_arranging, ms_waiting, ms_total, ms_total / (1000 / 60));
} }
// Apply the instruction state to the container's current state // Apply the instruction state to the container's current state
@ -246,12 +245,11 @@ static void transaction_progress_queue() {
transaction_destroy(transaction); transaction_destroy(transaction);
} }
server.transactions->length = 0; server.transactions->length = 0;
idle_inhibit_v1_check_active(server.idle_inhibit_manager_v1);
} }
static int handle_timeout(void *data) { static int handle_timeout(void *data) {
struct sway_transaction *transaction = data; struct sway_transaction *transaction = data;
wlr_log(WLR_DEBUG, "Transaction %p timed out (%li waiting)", wlr_log(L_DEBUG, "Transaction %p timed out (%li waiting)",
transaction, transaction->num_waiting); transaction, transaction->num_waiting);
transaction->num_waiting = 0; transaction->num_waiting = 0;
transaction_progress_queue(); transaction_progress_queue();
@ -286,7 +284,7 @@ static bool should_configure(struct sway_container *con,
} }
void transaction_commit(struct sway_transaction *transaction) { void transaction_commit(struct sway_transaction *transaction) {
wlr_log(WLR_DEBUG, "Transaction %p committing with %i instructions", wlr_log(L_DEBUG, "Transaction %p committing with %i instructions",
transaction, transaction->instructions->length); transaction, transaction->instructions->length);
transaction->num_waiting = 0; transaction->num_waiting = 0;
for (int i = 0; i < transaction->instructions->length; ++i) { for (int i = 0; i < transaction->instructions->length; ++i) {
@ -319,10 +317,9 @@ void transaction_commit(struct sway_transaction *transaction) {
} else { } else {
// There are no other transactions in progress, and this one has nothing // There are no other transactions in progress, and this one has nothing
// to wait for, so we can skip the queue. // to wait for, so we can skip the queue.
wlr_log(WLR_DEBUG, "Transaction %p has nothing to wait for", transaction); wlr_log(L_DEBUG, "Transaction %p has nothing to wait for", transaction);
transaction_apply(transaction); transaction_apply(transaction);
transaction_destroy(transaction); transaction_destroy(transaction);
idle_inhibit_v1_check_active(server.idle_inhibit_manager_v1);
return; return;
} }
@ -350,7 +347,7 @@ static void set_instruction_ready(
struct timespec *start = &transaction->commit_time; struct timespec *start = &transaction->commit_time;
float ms = (now.tv_sec - start->tv_sec) * 1000 + float ms = (now.tv_sec - start->tv_sec) * 1000 +
(now.tv_nsec - start->tv_nsec) / 1000000.0; (now.tv_nsec - start->tv_nsec) / 1000000.0;
wlr_log(WLR_DEBUG, "Transaction %p: %li/%li ready in %.1fms (%s)", wlr_log(L_DEBUG, "Transaction %p: %li/%li ready in %.1fms (%s)",
transaction, transaction,
transaction->num_configures - transaction->num_waiting + 1, transaction->num_configures - transaction->num_waiting + 1,
transaction->num_configures, ms, transaction->num_configures, ms,
@ -362,7 +359,7 @@ static void set_instruction_ready(
// If the transaction has timed out then its num_waiting will be 0 already. // If the transaction has timed out then its num_waiting will be 0 already.
if (transaction->num_waiting > 0 && --transaction->num_waiting == 0) { if (transaction->num_waiting > 0 && --transaction->num_waiting == 0) {
#if !TRANSACTION_DEBUG #if !TRANSACTION_DEBUG
wlr_log(WLR_DEBUG, "Transaction %p is ready", transaction); wlr_log(L_DEBUG, "Transaction %p is ready", transaction);
wl_event_source_timer_update(transaction->timer, 0); wl_event_source_timer_update(transaction->timer, 0);
transaction_progress_queue(); transaction_progress_queue();
#endif #endif
@ -377,10 +374,8 @@ static void set_instructions_ready(struct sway_view *view, int index) {
for (int i = 0; i <= index; ++i) { for (int i = 0; i <= index; ++i) {
struct sway_transaction_instruction *instruction = struct sway_transaction_instruction *instruction =
view->swayc->instructions->items[i]; view->swayc->instructions->items[i];
if (!instruction->ready) {
set_instruction_ready(instruction); set_instruction_ready(instruction);
} }
}
} }
void transaction_notify_view_ready(struct sway_view *view, uint32_t serial) { void transaction_notify_view_ready(struct sway_view *view, uint32_t serial) {

View file

@ -222,8 +222,8 @@ static void handle_request_fullscreen(struct wl_listener *listener, void *data)
view_set_fullscreen(view, e->fullscreen); view_set_fullscreen(view, e->fullscreen);
struct sway_container *output = container_parent(view->swayc, C_OUTPUT); struct sway_container *ws = container_parent(view->swayc, C_WORKSPACE);
arrange_and_commit(output); arrange_and_commit(ws);
} }
static void handle_unmap(struct wl_listener *listener, void *data) { static void handle_unmap(struct wl_listener *listener, void *data) {
@ -251,8 +251,8 @@ static void handle_map(struct wl_listener *listener, void *data) {
view->natural_width = view->wlr_xdg_surface->geometry.width; view->natural_width = view->wlr_xdg_surface->geometry.width;
view->natural_height = view->wlr_xdg_surface->geometry.height; view->natural_height = view->wlr_xdg_surface->geometry.height;
if (!view->natural_width && !view->natural_height) { if (!view->natural_width && !view->natural_height) {
view->natural_width = view->wlr_xdg_surface->surface->current.width; view->natural_width = view->wlr_xdg_surface->surface->current->width;
view->natural_height = view->wlr_xdg_surface->surface->current.height; view->natural_height = view->wlr_xdg_surface->surface->current->height;
} }
view_map(view, view->wlr_xdg_surface->surface); view_map(view, view->wlr_xdg_surface->surface);
@ -304,11 +304,11 @@ void handle_xdg_shell_surface(struct wl_listener *listener, void *data) {
struct wlr_xdg_surface *xdg_surface = data; struct wlr_xdg_surface *xdg_surface = data;
if (xdg_surface->role == WLR_XDG_SURFACE_ROLE_POPUP) { if (xdg_surface->role == WLR_XDG_SURFACE_ROLE_POPUP) {
wlr_log(WLR_DEBUG, "New xdg_shell popup"); wlr_log(L_DEBUG, "New xdg_shell popup");
return; return;
} }
wlr_log(WLR_DEBUG, "New xdg_shell toplevel title='%s' app_id='%s'", wlr_log(L_DEBUG, "New xdg_shell toplevel title='%s' app_id='%s'",
xdg_surface->toplevel->title, xdg_surface->toplevel->app_id); xdg_surface->toplevel->title, xdg_surface->toplevel->app_id);
wlr_xdg_surface_ping(xdg_surface); wlr_xdg_surface_ping(xdg_surface);

View file

@ -217,8 +217,8 @@ static void handle_request_fullscreen(struct wl_listener *listener, void *data)
view_set_fullscreen(view, e->fullscreen); view_set_fullscreen(view, e->fullscreen);
struct sway_container *output = container_parent(view->swayc, C_OUTPUT); struct sway_container *ws = container_parent(view->swayc, C_WORKSPACE);
arrange_and_commit(output); arrange_and_commit(ws);
} }
static void handle_unmap(struct wl_listener *listener, void *data) { static void handle_unmap(struct wl_listener *listener, void *data) {
@ -246,8 +246,8 @@ static void handle_map(struct wl_listener *listener, void *data) {
view->natural_width = view->wlr_xdg_surface_v6->geometry.width; view->natural_width = view->wlr_xdg_surface_v6->geometry.width;
view->natural_height = view->wlr_xdg_surface_v6->geometry.height; view->natural_height = view->wlr_xdg_surface_v6->geometry.height;
if (!view->natural_width && !view->natural_height) { if (!view->natural_width && !view->natural_height) {
view->natural_width = view->wlr_xdg_surface_v6->surface->current.width; view->natural_width = view->wlr_xdg_surface_v6->surface->current->width;
view->natural_height = view->wlr_xdg_surface_v6->surface->current.height; view->natural_height = view->wlr_xdg_surface_v6->surface->current->height;
} }
view_map(view, view->wlr_xdg_surface_v6->surface); view_map(view, view->wlr_xdg_surface_v6->surface);
@ -295,11 +295,11 @@ void handle_xdg_shell_v6_surface(struct wl_listener *listener, void *data) {
struct wlr_xdg_surface_v6 *xdg_surface = data; struct wlr_xdg_surface_v6 *xdg_surface = data;
if (xdg_surface->role == WLR_XDG_SURFACE_V6_ROLE_POPUP) { if (xdg_surface->role == WLR_XDG_SURFACE_V6_ROLE_POPUP) {
wlr_log(WLR_DEBUG, "New xdg_shell_v6 popup"); wlr_log(L_DEBUG, "New xdg_shell_v6 popup");
return; return;
} }
wlr_log(WLR_DEBUG, "New xdg_shell_v6 toplevel title='%s' app_id='%s'", wlr_log(L_DEBUG, "New xdg_shell_v6 toplevel title='%s' app_id='%s'",
xdg_surface->toplevel->title, xdg_surface->toplevel->app_id); xdg_surface->toplevel->title, xdg_surface->toplevel->app_id);
wlr_xdg_surface_v6_ping(xdg_surface); wlr_xdg_surface_v6_ping(xdg_surface);

View file

@ -119,7 +119,7 @@ static struct sway_xwayland_unmanaged *create_unmanaged(
struct sway_xwayland_unmanaged *surface = struct sway_xwayland_unmanaged *surface =
calloc(1, sizeof(struct sway_xwayland_unmanaged)); calloc(1, sizeof(struct sway_xwayland_unmanaged));
if (surface == NULL) { if (surface == NULL) {
wlr_log(WLR_ERROR, "Allocation failed"); wlr_log(L_ERROR, "Allocation failed");
return NULL; return NULL;
} }
@ -278,15 +278,12 @@ static void handle_commit(struct wl_listener *listener, void *data) {
wl_container_of(listener, xwayland_view, commit); wl_container_of(listener, xwayland_view, commit);
struct sway_view *view = &xwayland_view->view; struct sway_view *view = &xwayland_view->view;
struct wlr_xwayland_surface *xsurface = view->wlr_xwayland_surface; struct wlr_xwayland_surface *xsurface = view->wlr_xwayland_surface;
struct wlr_surface_state *surface_state = &xsurface->surface->current; struct wlr_surface_state *surface_state = xsurface->surface->current;
if (view->swayc->instructions->length) { if (view->swayc->instructions->length) {
transaction_notify_view_ready_by_size(view, transaction_notify_view_ready_by_size(view,
surface_state->width, surface_state->height); surface_state->width, surface_state->height);
} else if (container_is_floating(view->swayc)) {
view_update_size(view, surface_state->width, surface_state->height);
} }
view_damage_from(view); view_damage_from(view);
} }
@ -382,8 +379,8 @@ static void handle_request_fullscreen(struct wl_listener *listener, void *data)
} }
view_set_fullscreen(view, xsurface->fullscreen); view_set_fullscreen(view, xsurface->fullscreen);
struct sway_container *output = container_parent(view->swayc, C_OUTPUT); struct sway_container *ws = container_parent(view->swayc, C_WORKSPACE);
arrange_and_commit(output); arrange_and_commit(ws);
} }
static void handle_set_title(struct wl_listener *listener, void *data) { static void handle_set_title(struct wl_listener *listener, void *data) {
@ -432,12 +429,12 @@ void handle_xwayland_surface(struct wl_listener *listener, void *data) {
if (wlr_xwayland_surface_is_unmanaged(xsurface) || if (wlr_xwayland_surface_is_unmanaged(xsurface) ||
xsurface->override_redirect) { xsurface->override_redirect) {
wlr_log(WLR_DEBUG, "New xwayland unmanaged surface"); wlr_log(L_DEBUG, "New xwayland unmanaged surface");
create_unmanaged(xsurface); create_unmanaged(xsurface);
return; return;
} }
wlr_log(WLR_DEBUG, "New xwayland surface title='%s' class='%s'", wlr_log(L_DEBUG, "New xwayland surface title='%s' class='%s'",
xsurface->title, xsurface->class); xsurface->title, xsurface->class);
struct sway_xwayland_view *xwayland_view = struct sway_xwayland_view *xwayland_view =
@ -490,7 +487,7 @@ void handle_xwayland_ready(struct wl_listener *listener, void *data) {
xcb_connection_t *xcb_conn = xcb_connect(NULL, NULL); xcb_connection_t *xcb_conn = xcb_connect(NULL, NULL);
int err = xcb_connection_has_error(xcb_conn); int err = xcb_connection_has_error(xcb_conn);
if (err) { if (err) {
wlr_log(WLR_ERROR, "XCB connect failed: %d", err); wlr_log(L_ERROR, "XCB connect failed: %d", err);
return; return;
} }
@ -509,7 +506,7 @@ void handle_xwayland_ready(struct wl_listener *listener, void *data) {
free(reply); free(reply);
if (error != NULL) { if (error != NULL) {
wlr_log(WLR_ERROR, "could not resolve atom %s, X11 error code %d", wlr_log(L_ERROR, "could not resolve atom %s, X11 error code %d",
atom_map[i], error->error_code); atom_map[i], error->error_code);
free(error); free(error);
break; break;

View file

@ -255,12 +255,14 @@ void dispatch_cursor_button(struct sway_cursor *cursor,
wlr_layer_surface_from_wlr_surface(surface); wlr_layer_surface_from_wlr_surface(surface);
if (layer->current.keyboard_interactive) { if (layer->current.keyboard_interactive) {
seat_set_focus_layer(cursor->seat, layer); seat_set_focus_layer(cursor->seat, layer);
return;
}
} }
} else if (surface && cont && cont->type != C_VIEW) {
// Avoid moving keyboard focus from a surface that accepts it to one // Avoid moving keyboard focus from a surface that accepts it to one
// that does not unless the change would move us to a new workspace. // that does not unless the change would move us to a new workspace.
// //
// This prevents, for example, losing focus when clicking on swaybar. // This prevents, for example, losing focus when clicking on swaybar.
if (surface && cont && cont->type != C_VIEW) {
struct sway_container *new_ws = cont; struct sway_container *new_ws = cont;
if (new_ws && new_ws->type != C_WORKSPACE) { if (new_ws && new_ws->type != C_WORKSPACE) {
new_ws = container_parent(new_ws, C_WORKSPACE); new_ws = container_parent(new_ws, C_WORKSPACE);
@ -474,7 +476,7 @@ static void handle_request_set_cursor(struct wl_listener *listener,
// TODO: check cursor mode // TODO: check cursor mode
if (focused_client == NULL || if (focused_client == NULL ||
event->seat_client->client != focused_client) { event->seat_client->client != focused_client) {
wlr_log(WLR_DEBUG, "denying request to set cursor from unfocused client"); wlr_log(L_DEBUG, "denying request to set cursor from unfocused client");
return; return;
} }

View file

@ -61,7 +61,7 @@ static char *get_device_identifier(struct wlr_input_device *device) {
int len = snprintf(NULL, 0, fmt, vendor, product, name) + 1; int len = snprintf(NULL, 0, fmt, vendor, product, name) + 1;
char *identifier = malloc(len); char *identifier = malloc(len);
if (!identifier) { if (!identifier) {
wlr_log(WLR_ERROR, "Unable to allocate unique input device name"); wlr_log(L_ERROR, "Unable to allocate unique input device name");
return NULL; return NULL;
} }
@ -104,74 +104,74 @@ static void input_manager_libinput_config_pointer(
} }
libinput_device = wlr_libinput_get_device_handle(wlr_device); libinput_device = wlr_libinput_get_device_handle(wlr_device);
wlr_log(WLR_DEBUG, "input_manager_libinput_config_pointer(%s)", wlr_log(L_DEBUG, "input_manager_libinput_config_pointer(%s)",
ic->identifier); ic->identifier);
if (ic->accel_profile != INT_MIN) { if (ic->accel_profile != INT_MIN) {
wlr_log(WLR_DEBUG, "libinput_config_pointer(%s) accel_set_profile(%d)", wlr_log(L_DEBUG, "libinput_config_pointer(%s) accel_set_profile(%d)",
ic->identifier, ic->accel_profile); ic->identifier, ic->accel_profile);
libinput_device_config_accel_set_profile(libinput_device, libinput_device_config_accel_set_profile(libinput_device,
ic->accel_profile); ic->accel_profile);
} }
if (ic->click_method != INT_MIN) { if (ic->click_method != INT_MIN) {
wlr_log(WLR_DEBUG, "libinput_config_pointer(%s) click_set_method(%d)", wlr_log(L_DEBUG, "libinput_config_pointer(%s) click_set_method(%d)",
ic->identifier, ic->click_method); ic->identifier, ic->click_method);
libinput_device_config_click_set_method(libinput_device, libinput_device_config_click_set_method(libinput_device,
ic->click_method); ic->click_method);
} }
if (ic->drag_lock != INT_MIN) { if (ic->drag_lock != INT_MIN) {
wlr_log(WLR_DEBUG, wlr_log(L_DEBUG,
"libinput_config_pointer(%s) tap_set_drag_lock_enabled(%d)", "libinput_config_pointer(%s) tap_set_drag_lock_enabled(%d)",
ic->identifier, ic->click_method); ic->identifier, ic->click_method);
libinput_device_config_tap_set_drag_lock_enabled(libinput_device, libinput_device_config_tap_set_drag_lock_enabled(libinput_device,
ic->drag_lock); ic->drag_lock);
} }
if (ic->dwt != INT_MIN) { if (ic->dwt != INT_MIN) {
wlr_log(WLR_DEBUG, "libinput_config_pointer(%s) dwt_set_enabled(%d)", wlr_log(L_DEBUG, "libinput_config_pointer(%s) dwt_set_enabled(%d)",
ic->identifier, ic->dwt); ic->identifier, ic->dwt);
libinput_device_config_dwt_set_enabled(libinput_device, ic->dwt); libinput_device_config_dwt_set_enabled(libinput_device, ic->dwt);
} }
if (ic->left_handed != INT_MIN) { if (ic->left_handed != INT_MIN) {
wlr_log(WLR_DEBUG, wlr_log(L_DEBUG,
"libinput_config_pointer(%s) left_handed_set_enabled(%d)", "libinput_config_pointer(%s) left_handed_set_enabled(%d)",
ic->identifier, ic->left_handed); ic->identifier, ic->left_handed);
libinput_device_config_left_handed_set(libinput_device, libinput_device_config_left_handed_set(libinput_device,
ic->left_handed); ic->left_handed);
} }
if (ic->middle_emulation != INT_MIN) { if (ic->middle_emulation != INT_MIN) {
wlr_log(WLR_DEBUG, wlr_log(L_DEBUG,
"libinput_config_pointer(%s) middle_emulation_set_enabled(%d)", "libinput_config_pointer(%s) middle_emulation_set_enabled(%d)",
ic->identifier, ic->middle_emulation); ic->identifier, ic->middle_emulation);
libinput_device_config_middle_emulation_set_enabled(libinput_device, libinput_device_config_middle_emulation_set_enabled(libinput_device,
ic->middle_emulation); ic->middle_emulation);
} }
if (ic->natural_scroll != INT_MIN) { if (ic->natural_scroll != INT_MIN) {
wlr_log(WLR_DEBUG, wlr_log(L_DEBUG,
"libinput_config_pointer(%s) natural_scroll_set_enabled(%d)", "libinput_config_pointer(%s) natural_scroll_set_enabled(%d)",
ic->identifier, ic->natural_scroll); ic->identifier, ic->natural_scroll);
libinput_device_config_scroll_set_natural_scroll_enabled( libinput_device_config_scroll_set_natural_scroll_enabled(
libinput_device, ic->natural_scroll); libinput_device, ic->natural_scroll);
} }
if (ic->pointer_accel != FLT_MIN) { if (ic->pointer_accel != FLT_MIN) {
wlr_log(WLR_DEBUG, "libinput_config_pointer(%s) accel_set_speed(%f)", wlr_log(L_DEBUG, "libinput_config_pointer(%s) accel_set_speed(%f)",
ic->identifier, ic->pointer_accel); ic->identifier, ic->pointer_accel);
libinput_device_config_accel_set_speed(libinput_device, libinput_device_config_accel_set_speed(libinput_device,
ic->pointer_accel); ic->pointer_accel);
} }
if (ic->scroll_method != INT_MIN) { if (ic->scroll_method != INT_MIN) {
wlr_log(WLR_DEBUG, "libinput_config_pointer(%s) scroll_set_method(%d)", wlr_log(L_DEBUG, "libinput_config_pointer(%s) scroll_set_method(%d)",
ic->identifier, ic->scroll_method); ic->identifier, ic->scroll_method);
libinput_device_config_scroll_set_method(libinput_device, libinput_device_config_scroll_set_method(libinput_device,
ic->scroll_method); ic->scroll_method);
} }
if (ic->send_events != INT_MIN) { if (ic->send_events != INT_MIN) {
wlr_log(WLR_DEBUG, "libinput_config_pointer(%s) send_events_set_mode(%d)", wlr_log(L_DEBUG, "libinput_config_pointer(%s) send_events_set_mode(%d)",
ic->identifier, ic->send_events); ic->identifier, ic->send_events);
libinput_device_config_send_events_set_mode(libinput_device, libinput_device_config_send_events_set_mode(libinput_device,
ic->send_events); ic->send_events);
} }
if (ic->tap != INT_MIN) { if (ic->tap != INT_MIN) {
wlr_log(WLR_DEBUG, "libinput_config_pointer(%s) tap_set_enabled(%d)", wlr_log(L_DEBUG, "libinput_config_pointer(%s) tap_set_enabled(%d)",
ic->identifier, ic->tap); ic->identifier, ic->tap);
libinput_device_config_tap_set_enabled(libinput_device, ic->tap); libinput_device_config_tap_set_enabled(libinput_device, ic->tap);
} }
@ -187,7 +187,7 @@ static void handle_device_destroy(struct wl_listener *listener, void *data) {
return; return;
} }
wlr_log(WLR_DEBUG, "removing device: '%s'", wlr_log(L_DEBUG, "removing device: '%s'",
input_device->identifier); input_device->identifier);
struct sway_seat *seat = NULL; struct sway_seat *seat = NULL;
@ -217,19 +217,16 @@ static void handle_new_input(struct wl_listener *listener, void *data) {
input_device->identifier = get_device_identifier(device); input_device->identifier = get_device_identifier(device);
wl_list_insert(&input->devices, &input_device->link); wl_list_insert(&input->devices, &input_device->link);
wlr_log(WLR_DEBUG, "adding device: '%s'", wlr_log(L_DEBUG, "adding device: '%s'",
input_device->identifier); input_device->identifier);
if (input_device->wlr_device->type == WLR_INPUT_DEVICE_POINTER) { if (input_device->wlr_device->type == WLR_INPUT_DEVICE_POINTER) {
input_manager_libinput_config_pointer(input_device); input_manager_libinput_config_pointer(input_device);
} }
wl_signal_add(&device->events.destroy, &input_device->device_destroy);
input_device->device_destroy.notify = handle_device_destroy;
struct sway_seat *seat = NULL; struct sway_seat *seat = NULL;
if (!input_has_seat_configuration(input)) { if (!input_has_seat_configuration(input)) {
wlr_log(WLR_DEBUG, "no seat configuration, using default seat"); wlr_log(L_DEBUG, "no seat configuration, using default seat");
seat = input_manager_get_seat(input, default_seat); seat = input_manager_get_seat(input, default_seat);
seat_add_device(seat, input_device); seat_add_device(seat, input_device);
return; return;
@ -259,10 +256,13 @@ static void handle_new_input(struct wl_listener *listener, void *data) {
} }
if (!added) { if (!added) {
wlr_log(WLR_DEBUG, wlr_log(L_DEBUG,
"device '%s' is not configured on any seats", "device '%s' is not configured on any seats",
input_device->identifier); input_device->identifier);
} }
wl_signal_add(&device->events.destroy, &input_device->device_destroy);
input_device->device_destroy.notify = handle_device_destroy;
} }
static void handle_inhibit_activate(struct wl_listener *listener, void *data) { static void handle_inhibit_activate(struct wl_listener *listener, void *data) {
@ -282,7 +282,7 @@ static void handle_inhibit_deactivate(struct wl_listener *listener, void *data)
seat_set_exclusive_client(seat, NULL); seat_set_exclusive_client(seat, NULL);
struct sway_container *previous = seat_get_focus(seat); struct sway_container *previous = seat_get_focus(seat);
if (previous) { if (previous) {
wlr_log(WLR_DEBUG, "Returning focus to %p %s '%s'", previous, wlr_log(L_DEBUG, "Returning focus to %p %s '%s'", previous,
container_type_to_str(previous->type), previous->name); container_type_to_str(previous->type), previous->name);
// Hack to get seat to re-focus the return value of get_focus // Hack to get seat to re-focus the return value of get_focus
seat_set_focus(seat, previous->parent); seat_set_focus(seat, previous->parent);
@ -359,7 +359,7 @@ void input_manager_apply_input_config(struct sway_input_manager *input,
void input_manager_apply_seat_config(struct sway_input_manager *input, void input_manager_apply_seat_config(struct sway_input_manager *input,
struct seat_config *seat_config) { struct seat_config *seat_config) {
wlr_log(WLR_DEBUG, "applying new seat config for seat %s", wlr_log(L_DEBUG, "applying new seat config for seat %s",
seat_config->name); seat_config->name);
struct sway_seat *seat = input_manager_get_seat(input, seat_config->name); struct sway_seat *seat = input_manager_get_seat(input, seat_config->name);
if (!seat) { if (!seat) {

View file

@ -108,7 +108,7 @@ static void get_active_binding(const struct sway_shortcut_state *state,
} }
if (*current_binding && *current_binding != binding) { if (*current_binding && *current_binding != binding) {
wlr_log(WLR_DEBUG, "encountered duplicate bindings %d and %d", wlr_log(L_DEBUG, "encountered duplicate bindings %d and %d",
(*current_binding)->order, binding->order); (*current_binding)->order, binding->order);
} else { } else {
*current_binding = binding; *current_binding = binding;
@ -122,12 +122,12 @@ static void get_active_binding(const struct sway_shortcut_state *state,
*/ */
static void keyboard_execute_command(struct sway_keyboard *keyboard, static void keyboard_execute_command(struct sway_keyboard *keyboard,
struct sway_binding *binding) { struct sway_binding *binding) {
wlr_log(WLR_DEBUG, "running command for binding: %s", wlr_log(L_DEBUG, "running command for binding: %s",
binding->command); binding->command);
config->handler_context.seat = keyboard->seat_device->sway_seat; config->handler_context.seat = keyboard->seat_device->sway_seat;
struct cmd_results *results = execute_command(binding->command, NULL); struct cmd_results *results = execute_command(binding->command, NULL);
if (results->status != CMD_SUCCESS) { if (results->status != CMD_SUCCESS) {
wlr_log(WLR_DEBUG, "could not run command for binding: %s (%s)", wlr_log(L_DEBUG, "could not run command for binding: %s (%s)",
binding->command, results->error); binding->command, results->error);
} }
free_cmd_results(results); free_cmd_results(results);
@ -386,7 +386,7 @@ void sway_keyboard_configure(struct sway_keyboard *keyboard) {
xkb_keymap_new_from_names(context, &rules, XKB_KEYMAP_COMPILE_NO_FLAGS); xkb_keymap_new_from_names(context, &rules, XKB_KEYMAP_COMPILE_NO_FLAGS);
if (!keymap) { if (!keymap) {
wlr_log(WLR_DEBUG, "cannot configure keyboard: keymap does not exist"); wlr_log(L_DEBUG, "cannot configure keyboard: keymap does not exist");
xkb_context_unref(context); xkb_context_unref(context);
return; return;
} }
@ -420,9 +420,6 @@ void sway_keyboard_destroy(struct sway_keyboard *keyboard) {
if (!keyboard) { if (!keyboard) {
return; return;
} }
if (keyboard->keymap) {
xkb_keymap_unref(keyboard->keymap);
}
wl_list_remove(&keyboard->keyboard_key.link); wl_list_remove(&keyboard->keyboard_key.link);
wl_list_remove(&keyboard->keyboard_modifiers.link); wl_list_remove(&keyboard->keyboard_modifiers.link);
free(keyboard); free(keyboard);

View file

@ -75,7 +75,7 @@ static void seat_send_activate(struct sway_container *con,
struct sway_seat *seat) { struct sway_seat *seat) {
if (con->type == C_VIEW) { if (con->type == C_VIEW) {
if (!seat_is_input_allowed(seat, con->sway_view->surface)) { if (!seat_is_input_allowed(seat, con->sway_view->surface)) {
wlr_log(WLR_DEBUG, "Refusing to set focus, input is inhibited"); wlr_log(L_DEBUG, "Refusing to set focus, input is inhibited");
return; return;
} }
view_set_activated(con->sway_view, true); view_set_activated(con->sway_view, true);
@ -219,7 +219,7 @@ static struct sway_seat_container *seat_container_from_container(
seat_con = calloc(1, sizeof(struct sway_seat_container)); seat_con = calloc(1, sizeof(struct sway_seat_container));
if (seat_con == NULL) { if (seat_con == NULL) {
wlr_log(WLR_ERROR, "could not allocate seat container"); wlr_log(L_ERROR, "could not allocate seat container");
return NULL; return NULL;
} }
@ -301,7 +301,7 @@ static void handle_new_drag_icon(struct wl_listener *listener, void *data) {
struct sway_drag_icon *icon = calloc(1, sizeof(struct sway_drag_icon)); struct sway_drag_icon *icon = calloc(1, sizeof(struct sway_drag_icon));
if (icon == NULL) { if (icon == NULL) {
wlr_log(WLR_ERROR, "Allocation failed"); wlr_log(L_ERROR, "Allocation failed");
return; return;
} }
icon->seat = seat; icon->seat = seat;
@ -391,7 +391,7 @@ static void seat_apply_input_config(struct sway_seat *seat,
struct input_config *ic = input_device_get_config( struct input_config *ic = input_device_get_config(
sway_device->input_device); sway_device->input_device);
if (ic != NULL) { if (ic != NULL) {
wlr_log(WLR_DEBUG, "Applying input config to %s", wlr_log(L_DEBUG, "Applying input config to %s",
sway_device->input_device->identifier); sway_device->input_device->identifier);
mapped_to_output = ic->mapped_to_output; mapped_to_output = ic->mapped_to_output;
@ -401,7 +401,7 @@ static void seat_apply_input_config(struct sway_seat *seat,
mapped_to_output = sway_device->input_device->wlr_device->output_name; mapped_to_output = sway_device->input_device->wlr_device->output_name;
} }
if (mapped_to_output != NULL) { if (mapped_to_output != NULL) {
wlr_log(WLR_DEBUG, "Mapping input device %s to output %s", wlr_log(L_DEBUG, "Mapping input device %s to output %s",
sway_device->input_device->identifier, mapped_to_output); sway_device->input_device->identifier, mapped_to_output);
struct sway_container *output = NULL; struct sway_container *output = NULL;
for (int i = 0; i < root_container.children->length; ++i) { for (int i = 0; i < root_container.children->length; ++i) {
@ -415,7 +415,7 @@ static void seat_apply_input_config(struct sway_seat *seat,
wlr_cursor_map_input_to_output(seat->cursor->cursor, wlr_cursor_map_input_to_output(seat->cursor->cursor,
sway_device->input_device->wlr_device, sway_device->input_device->wlr_device,
output->sway_output->wlr_output); output->sway_output->wlr_output);
wlr_log(WLR_DEBUG, "Mapped to output %s", output->name); wlr_log(L_DEBUG, "Mapped to output %s", output->name);
} }
} }
} }
@ -495,7 +495,7 @@ void seat_configure_device(struct sway_seat *seat,
seat_configure_tablet_tool(seat, seat_device); seat_configure_tablet_tool(seat, seat_device);
break; break;
case WLR_INPUT_DEVICE_TABLET_PAD: case WLR_INPUT_DEVICE_TABLET_PAD:
wlr_log(WLR_DEBUG, "TODO: configure tablet pad"); wlr_log(L_DEBUG, "TODO: configure tablet pad");
break; break;
} }
} }
@ -510,11 +510,11 @@ void seat_add_device(struct sway_seat *seat,
struct sway_seat_device *seat_device = struct sway_seat_device *seat_device =
calloc(1, sizeof(struct sway_seat_device)); calloc(1, sizeof(struct sway_seat_device));
if (!seat_device) { if (!seat_device) {
wlr_log(WLR_DEBUG, "could not allocate seat device"); wlr_log(L_DEBUG, "could not allocate seat device");
return; return;
} }
wlr_log(WLR_DEBUG, "adding device %s to seat %s", wlr_log(L_DEBUG, "adding device %s to seat %s",
input_device->identifier, seat->wlr_seat->name); input_device->identifier, seat->wlr_seat->name);
seat_device->sway_seat = seat; seat_device->sway_seat = seat;
@ -533,7 +533,7 @@ void seat_remove_device(struct sway_seat *seat,
return; return;
} }
wlr_log(WLR_DEBUG, "removing device %s from seat %s", wlr_log(L_DEBUG, "removing device %s from seat %s",
input_device->identifier, seat->wlr_seat->name); input_device->identifier, seat->wlr_seat->name);
seat_device_destroy(seat_device); seat_device_destroy(seat_device);
@ -663,17 +663,7 @@ void seat_set_focus_warp(struct sway_seat *seat,
} }
seat_send_focus(container, seat); seat_send_focus(container, seat);
container_damage_whole(container->parent); container_damage_whole(container);
}
// If we've focused a floating container, bring it to the front.
// We do this by putting it at the end of the floating list.
// This must happen for both the pending and current children lists.
if (container && container_is_floating(container)) {
list_move_to_end(container->parent->children, container);
if (container_has_ancestor(container, container->current.parent)) {
list_move_to_end(container->parent->current.children, container);
}
} }
// clean up unfocused empty workspace on new output // clean up unfocused empty workspace on new output
@ -762,7 +752,7 @@ void seat_set_focus_layer(struct sway_seat *seat,
struct sway_container *previous = struct sway_container *previous =
seat_get_focus_inactive(seat, &root_container); seat_get_focus_inactive(seat, &root_container);
if (previous) { if (previous) {
wlr_log(WLR_DEBUG, "Returning focus to %p %s '%s'", previous, wlr_log(L_DEBUG, "Returning focus to %p %s '%s'", previous,
container_type_to_str(previous->type), previous->name); container_type_to_str(previous->type), previous->name);
// Hack to get seat to re-focus the return value of get_focus // Hack to get seat to re-focus the return value of get_focus
seat_set_focus(seat, previous->parent); seat_set_focus(seat, previous->parent);
@ -842,12 +832,12 @@ struct sway_container *seat_get_active_child(struct sway_seat *seat,
struct sway_container *seat_get_active_current_child(struct sway_seat *seat, struct sway_container *seat_get_active_current_child(struct sway_seat *seat,
struct sway_container *container) { struct sway_container *container) {
struct sway_seat_container *current = NULL; struct sway_container *child = seat_get_active_child(seat, container);
wl_list_for_each(current, &seat->focus_stack, link) { if (child) {
if (current->container->current.parent == container && return child;
current->container->current.layout != L_FLOATING) {
return current->container;
} }
if (container->current.children->length == 1) {
return container->current.children->items[0];
} }
return NULL; return NULL;
} }

Some files were not shown because too many files have changed in this diff Show more