From 8fdf85fee09ebd76482e97149b27cd02008bd092 Mon Sep 17 00:00:00 2001 From: Nate Symer Date: Thu, 12 Jul 2018 11:51:25 -0400 Subject: [PATCH] gaps improvements --- CONTRIBUTING.md | 2 +- HACKING.md | 6 +- common/background-image.c | 8 +- common/ipc-client.c | 2 +- common/list.c | 15 - common/log.c | 4 +- common/pango.c | 2 +- common/readline.c | 4 +- common/unicode.c | 2 +- common/util.c | 4 +- completions/zsh/_swaymsg | 1 + include/ipc.h | 5 +- include/list.h | 2 - include/log.h | 10 +- include/sway/commands.h | 3 +- include/sway/config.h | 10 +- include/sway/desktop.h | 4 - include/sway/desktop/idle_inhibit_v1.h | 28 - include/sway/ipc-server.h | 4 +- include/sway/output.h | 43 - include/sway/server.h | 5 +- include/sway/tree/container.h | 6 - include/swaylock/swaylock.h | 25 +- sway/commands.c | 37 +- sway/commands/assign.c | 3 +- sway/commands/bar.c | 6 +- sway/commands/bar/binding_mode_indicator.c | 4 +- sway/commands/bar/font.c | 4 +- sway/commands/bar/height.c | 2 +- sway/commands/bar/hidden_state.c | 2 +- sway/commands/bar/id.c | 2 +- sway/commands/bar/mode.c | 2 +- sway/commands/bar/modifier.c | 7 +- sway/commands/bar/output.c | 2 +- sway/commands/bar/pango_markup.c | 4 +- sway/commands/bar/position.c | 2 +- sway/commands/bar/separator_symbol.c | 2 +- sway/commands/bar/status_command.c | 2 +- sway/commands/bar/strip_workspace_numbers.c | 4 +- sway/commands/bar/swaybar_command.c | 2 +- sway/commands/bar/workspace_buttons.c | 4 +- sway/commands/bar/wrap_scroll.c | 4 +- sway/commands/bind.c | 4 +- sway/commands/exec.c | 2 +- sway/commands/exec_always.c | 33 +- sway/commands/floating_minmax_size.c | 53 -- sway/commands/focus.c | 32 +- sway/commands/for_window.c | 2 +- sway/commands/gaps.c | 30 +- sway/commands/input.c | 2 +- sway/commands/input/accel_profile.c | 1 - sway/commands/input/click_method.c | 1 - sway/commands/input/drag_lock.c | 1 - sway/commands/input/dwt.c | 1 - sway/commands/input/events.c | 3 +- sway/commands/input/left_handed.c | 1 - sway/commands/input/map_from_region.c | 8 - sway/commands/input/middle_emulation.c | 1 - sway/commands/input/natural_scroll.c | 1 - sway/commands/input/pointer_accel.c | 1 - sway/commands/input/repeat_delay.c | 1 - sway/commands/input/repeat_rate.c | 1 - sway/commands/input/scroll_method.c | 1 - sway/commands/input/tap.c | 3 +- sway/commands/input/xkb_layout.c | 2 +- sway/commands/input/xkb_model.c | 2 +- sway/commands/input/xkb_options.c | 2 +- sway/commands/input/xkb_rules.c | 2 +- sway/commands/input/xkb_variant.c | 2 +- sway/commands/mode.c | 19 +- sway/commands/move.c | 122 +-- sway/commands/output.c | 6 +- sway/commands/output/background.c | 11 +- sway/commands/output/mode.c | 2 +- sway/commands/output/position.c | 2 +- sway/commands/reload.c | 2 +- sway/commands/rename.c | 2 +- sway/commands/resize.c | 2 +- sway/commands/set.c | 2 +- sway/commands/swaybg_command.c | 2 +- sway/commands/workspace.c | 2 +- sway/config.c | 126 +-- sway/config/bar.c | 40 +- sway/config/input.c | 8 +- sway/config/output.c | 26 +- sway/config/seat.c | 6 +- sway/criteria.c | 2 +- sway/desktop/desktop.c | 9 - sway/desktop/idle_inhibit_v1.c | 79 -- sway/desktop/layer_shell.c | 6 +- sway/desktop/output.c | 938 ++++++++++++++++++-- sway/desktop/render.c | 904 ------------------- sway/desktop/transaction.c | 29 +- sway/desktop/xdg_shell.c | 12 +- sway/desktop/xdg_shell_v6.c | 12 +- sway/desktop/xwayland.c | 19 +- sway/input/cursor.c | 14 +- sway/input/input-manager.c | 44 +- sway/input/keyboard.c | 11 +- sway/input/seat.c | 46 +- sway/ipc-json.c | 2 - sway/ipc-server.c | 196 ++-- sway/main.c | 58 +- sway/meson.build | 3 - sway/server.c | 23 +- sway/sway-input.5.scd | 4 +- sway/sway.5.scd | 16 +- sway/tree/arrange.c | 56 +- sway/tree/container.c | 106 +-- sway/tree/layout.c | 72 +- sway/tree/output.c | 6 +- sway/tree/view.c | 96 +- sway/tree/workspace.c | 32 +- swaybar/bar.c | 2 +- swaybar/i3bar.c | 4 +- swaybar/ipc.c | 4 +- swaybar/main.c | 8 +- swaybar/render.c | 7 +- swaybar/status_line.c | 6 +- swaybg/main.c | 6 +- swayidle/main.c | 78 +- swaylock/main.c | 327 +------ swaylock/password.c | 25 +- swaylock/render.c | 77 +- swaylock/seat.c | 4 +- swaylock/swaylock.1.scd | 121 +-- swaymsg/main.c | 51 +- swaymsg/swaymsg.1.scd | 10 +- 128 files changed, 1670 insertions(+), 2718 deletions(-) delete mode 100644 include/sway/desktop/idle_inhibit_v1.h delete mode 100644 sway/commands/floating_minmax_size.c delete mode 100644 sway/desktop/idle_inhibit_v1.c delete mode 100644 sway/desktop/render.c diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index f450563aa..8a6c0208a 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -107,7 +107,7 @@ int main(int argc, const char **argv) { } 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; struct output_state *output = registry->outputs->items[desired_output]; struct window *window = window_setup(registry, 100, 100, false); diff --git a/HACKING.md b/HACKING.md index 8965d3ec6..3600db242 100644 --- a/HACKING.md +++ b/HACKING.md @@ -3,9 +3,9 @@ Use `sway_log(importance, fmt, ...)` to log. The following importances are available: -* `WLR_DEBUG`: Debug messages, only shows with `sway -d` -* `WLR_INFO`: Informational messages -* `WLR_ERROR`: Error messages +* `L_DEBUG`: Debug messages, only shows with `sway -d` +* `L_INFO`: Informational messages +* `L_ERROR`: Error messages `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. diff --git a/common/background-image.c b/common/background-image.c index f3d2551e7..e5fb4433e 100644 --- a/common/background-image.c +++ b/common/background-image.c @@ -18,7 +18,7 @@ enum background_mode parse_background_mode(const char *mode) { } else if (strcmp(mode, "solid_color") == 0) { 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; } @@ -28,7 +28,7 @@ cairo_surface_t *load_background_image(const char *path) { GError *err = NULL; GdkPixbuf *pixbuf = gdk_pixbuf_new_from_file(path, &err); if (!pixbuf) { - wlr_log(WLR_ERROR, "Failed to load background image (%s).", + wlr_log(L_ERROR, "Failed to load background image (%s).", err->message); return false; } @@ -38,11 +38,11 @@ cairo_surface_t *load_background_image(const char *path) { image = cairo_image_surface_create_from_png(path); #endif //HAVE_GDK_PIXBUF if (!image) { - wlr_log(WLR_ERROR, "Failed to read background image."); + wlr_log(L_ERROR, "Failed to read background image."); return NULL; } 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 "\nSway was compiled without gdk_pixbuf support, so only" "\nPNG images can be loaded. This is the likely cause." diff --git a/common/ipc-client.c b/common/ipc-client.c index 4d2d88ccf..a88df0800 100644 --- a/common/ipc-client.c +++ b/common/ipc-client.c @@ -97,7 +97,7 @@ struct ipc_response *ipc_recv_response(int socketfd) { error_2: free(response); 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; } diff --git a/common/list.c b/common/list.c index 66d52f700..39cc10e19 100644 --- a/common/list.c +++ b/common/list.c @@ -2,7 +2,6 @@ #include #include #include -#include "log.h" list_t *create_list(void) { 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; } -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) { void *tmp = list->items[to]; diff --git a/common/log.c b/common/log.c index 847f3952a..2cc7289c5 100644 --- a/common/log.c +++ b/common/log.c @@ -8,7 +8,7 @@ void sway_terminate(int code); void _sway_abort(const char *format, ...) { va_list args; va_start(args, format); - _wlr_vlog(WLR_ERROR, format, args); + _wlr_vlog(L_ERROR, format, args); va_end(args); sway_terminate(EXIT_FAILURE); } @@ -20,7 +20,7 @@ bool _sway_assert(bool condition, const char *format, ...) { va_list args; va_start(args, format); - _wlr_vlog(WLR_ERROR, format, args); + _wlr_vlog(L_ERROR, format, args); va_end(args); #ifndef NDEBUG diff --git a/common/pango.c b/common/pango.c index 92703f804..c88e50ce1 100644 --- a/common/pango.c +++ b/common/pango.c @@ -81,7 +81,7 @@ PangoLayout *get_pango_layout(cairo_t *cairo, const char *font, pango_layout_set_markup(layout, buf, -1); free(buf); } 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); g_error_free(error); markup = false; // fallback to plain text diff --git a/common/readline.c b/common/readline.c index a2c690185..1c396a909 100644 --- a/common/readline.c +++ b/common/readline.c @@ -9,7 +9,7 @@ char *read_line(FILE *file) { char *string = malloc(size); char lastChar = '\0'; 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; } while (1) { @@ -30,7 +30,7 @@ char *read_line(FILE *file) { char *new_string = realloc(string, size *= 2); if (!new_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; } string = new_string; diff --git a/common/unicode.c b/common/unicode.c index 5070e0835..38a9b48eb 100644 --- a/common/unicode.c +++ b/common/unicode.c @@ -92,7 +92,7 @@ static const struct { int utf8_size(const char *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) { return sizes[i].octets; } diff --git a/common/util.c b/common/util.c index e8a88772f..fb7f94541 100644 --- a/common/util.c +++ b/common/util.c @@ -95,7 +95,7 @@ pid_t get_parent_pid(pid_t child) { token = strtok(NULL, sep); // parent pid parent = strtol(token, NULL, 10); } - free(buffer); + fclose(stat); } @@ -113,7 +113,7 @@ uint32_t parse_color(const char *color) { int len = strlen(color); 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; } uint32_t res = (uint32_t)strtoul(color, NULL, 16); diff --git a/completions/zsh/_swaymsg b/completions/zsh/_swaymsg index 2e39deb6c..6bb032792 100644 --- a/completions/zsh/_swaymsg +++ b/completions/zsh/_swaymsg @@ -22,6 +22,7 @@ types=( 'get_marks' 'get_bar_config' 'get_version' +'get_clipboard' ) _arguments -s \ diff --git a/include/ipc.h b/include/ipc.h index 0010718bd..8172c782c 100644 --- a/include/ipc.h +++ b/include/ipc.h @@ -13,12 +13,11 @@ enum ipc_command_type { IPC_GET_MARKS = 5, IPC_GET_BAR_CONFIG = 6, IPC_GET_VERSION = 7, - IPC_GET_BINDING_MODES = 8, - IPC_GET_CONFIG = 9, // sway-specific command types 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. IPC_EVENT_WORKSPACE = ((1<<31) | 0), diff --git a/include/list.h b/include/list.h index 5a0d7d809..7eead4acc 100644 --- a/include/list.h +++ b/include/list.h @@ -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)); // swap two elements in a list 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 diff --git a/include/log.h b/include/log.h index dd5261433..a97481274 100644 --- a/include/log.h +++ b/include/log.h @@ -3,19 +3,13 @@ #include #include -#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); #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); #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); diff --git a/include/sway/commands.h b/include/sway/commands.h index dda0606a6..7ca0bda88 100644 --- a/include/sway/commands.h +++ b/include/sway/commands.h @@ -79,7 +79,7 @@ void free_cmd_results(struct cmd_results *results); * * 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, char *buffer, const char *color); @@ -95,6 +95,7 @@ sway_cmd cmd_client_unfocused; sway_cmd cmd_client_urgent; sway_cmd cmd_client_placeholder; sway_cmd cmd_client_background; +sway_cmd cmd_clipboard; sway_cmd cmd_commands; sway_cmd cmd_debuglog; sway_cmd cmd_default_border; diff --git a/include/sway/config.h b/include/sway/config.h index 995752742..e75b06643 100644 --- a/include/sway/config.h +++ b/include/sway/config.h @@ -50,7 +50,6 @@ struct sway_mode { char *name; list_t *keysym_bindings; list_t *keycode_bindings; - bool pango; }; struct input_config_mapped_from_region { @@ -271,10 +270,11 @@ enum ipc_feature { IPC_FEATURE_EVENT_WINDOW = 2048, IPC_FEATURE_EVENT_BINDING = 4096, IPC_FEATURE_EVENT_INPUT = 8192, - IPC_FEATURE_GET_SEATS = 16384, + IPC_FEATURE_GET_CLIPBOARD = 16384, + IPC_FEATURE_GET_SEATS = 32768, 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 = IPC_FEATURE_ALL_COMMANDS | IPC_FEATURE_ALL_EVENTS, @@ -340,7 +340,6 @@ struct sway_config { int gaps_outer; list_t *config_chain; - const char *current_config_path; const char *current_config; enum sway_container_border border; @@ -496,4 +495,7 @@ void config_update_font_height(bool recalculate); /* Global config singleton. */ extern struct sway_config *config; +/* Config file currently being read */ +extern const char *current_config_path; + #endif diff --git a/include/sway/desktop.h b/include/sway/desktop.h index 348fb1870..f1ad759a1 100644 --- a/include/sway/desktop.h +++ b/include/sway/desktop.h @@ -1,8 +1,4 @@ #include -struct sway_container; - void desktop_damage_surface(struct wlr_surface *surface, double lx, double ly, bool whole); - -void desktop_damage_whole_container(struct sway_container *con); diff --git a/include/sway/desktop/idle_inhibit_v1.h b/include/sway/desktop/idle_inhibit_v1.h deleted file mode 100644 index e5ed8a3de..000000000 --- a/include/sway/desktop/idle_inhibit_v1.h +++ /dev/null @@ -1,28 +0,0 @@ -#ifndef _SWAY_DESKTOP_IDLE_INHIBIT_V1_H -#define _SWAY_DESKTOP_IDLE_INHIBIT_V1_H -#include -#include -#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 diff --git a/include/sway/ipc-server.h b/include/sway/ipc-server.h index 6469f097c..dd16a175e 100644 --- a/include/sway/ipc-server.h +++ b/include/sway/ipc-server.h @@ -9,12 +9,14 @@ struct sway_server; void ipc_init(struct sway_server *server); +void ipc_terminate(void); + struct sockaddr_un *ipc_user_sockaddr(void); void ipc_event_workspace(struct sway_container *old, struct sway_container *new, 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_mode(const char *mode, bool pango); +void ipc_event_mode(const char *mode); #endif diff --git a/include/sway/output.h b/include/sway/output.h index b6cda83c2..19fc5e990 100644 --- a/include/sway/output.h +++ b/include/sway/output.h @@ -38,16 +38,6 @@ struct sway_output { } 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_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); 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 diff --git a/include/sway/server.h b/include/sway/server.h index a3e32898d..1e1aa3cc0 100644 --- a/include/sway/server.h +++ b/include/sway/server.h @@ -23,14 +23,12 @@ struct sway_server { struct wlr_compositor *compositor; struct wlr_data_device_manager *data_device_manager; + struct wlr_idle *idle; struct sway_input_manager *input; 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 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_idle_inhibitor_v1(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_surface(struct wl_listener *listener, void *data); diff --git a/include/sway/tree/container.h b/include/sway/tree/container.h index a69da9db8..728daa847 100644 --- a/include/sway/tree/container.h +++ b/include/sway/tree/container.h @@ -297,10 +297,4 @@ bool container_is_floating(struct sway_container *container); */ 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 diff --git a/include/swaylock/swaylock.h b/include/swaylock/swaylock.h index 950cfaafa..2931fd616 100644 --- a/include/swaylock/swaylock.h +++ b/include/swaylock/swaylock.h @@ -19,33 +19,10 @@ enum auth_state { 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_colors colors; + uint32_t color; enum background_mode mode; - char *font; - uint32_t radius; - uint32_t thickness; - bool ignore_empty; bool show_indicator; - bool daemonize; }; struct swaylock_password { diff --git a/sway/commands.c b/sway/commands.c index addd64a69..5b20857ab 100644 --- a/sway/commands.c +++ b/sway/commands.c @@ -100,8 +100,6 @@ static struct cmd_handler handlers[] = { { "default_border", cmd_default_border }, { "exec", cmd_exec }, { "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_wrapping", cmd_focus_wrapping }, { "font", cmd_font }, @@ -165,7 +163,7 @@ struct cmd_handler *find_handler(char *line, struct cmd_handler *cmd_handlers, int handlers_size) { struct cmd_handler d = { .command=line }; 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; @@ -250,10 +248,10 @@ struct cmd_results *execute_command(char *_exec, struct sway_seat *seat) { cmd = argsep(&cmdlist, ","); cmd += strspn(cmd, whitespace); if (strcmp(cmd, "") == 0) { - wlr_log(WLR_INFO, "Ignoring empty command."); + wlr_log(L_INFO, "Ignoring empty command."); continue; } - wlr_log(WLR_INFO, "Handling command '%s'", cmd); + wlr_log(L_INFO, "Handling command '%s'", cmd); //TODO better handling of argv int argc; char **argv = split_args(cmd, &argc); @@ -346,7 +344,7 @@ struct cmd_results *config_command(char *exec) { // Start block if (argc > 1 && strcmp(argv[argc - 1], "{") == 0) { - char *block = join_args(argv, argc - 1); + char *block = join_args(argv, argc - 1); results = cmd_results_new(CMD_BLOCK, block, NULL); free(block); goto cleanup; @@ -357,7 +355,7 @@ struct cmd_results *config_command(char *exec) { results = cmd_results_new(CMD_BLOCK_END, NULL, NULL); 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); if (!handler) { char *input = argv[0] ? argv[0] : "(empty)"; @@ -390,7 +388,7 @@ cleanup: struct cmd_results *config_subcommand(char **argv, int argc, struct cmd_handler *handlers, size_t handlers_size) { char *command = join_args(argv, argc); - wlr_log(WLR_DEBUG, "Subcommand: %s", command); + wlr_log(L_DEBUG, "Subcommand: %s", command); free(command); 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); 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; } @@ -472,16 +471,14 @@ struct cmd_results *config_commands_command(char *exec) { } if (!policy) { policy = alloc_command_policy(cmd); - if (!sway_assert(policy, "Unable to allocate security policy")) { - results = cmd_results_new(CMD_INVALID, cmd, - "Unable to allocate memory"); - goto cleanup; + sway_assert(policy, "Unable to allocate security policy"); + if (policy) { + list_add(config->command_policies, policy); } - list_add(config->command_policies, policy); } 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); 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, ...) { struct cmd_results *results = malloc(sizeof(struct cmd_results)); if (!results) { - wlr_log(WLR_ERROR, "Unable to allocate command results"); + wlr_log(L_ERROR, "Unable to allocate command results"); return NULL; } results->status = status; @@ -529,7 +526,7 @@ void free_cmd_results(struct cmd_results *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 *root = json_object_new_object(); 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); const char *json = json_object_to_json_string(result_array); - char *res = strdup(json); - json_object_put(result_array); - return res; + free(result_array); + free(root); + return json; } /** diff --git a/sway/commands/assign.c b/sway/commands/assign.c index 0bc0929a2..9d15e166e 100644 --- a/sway/commands/assign.c +++ b/sway/commands/assign.c @@ -27,7 +27,6 @@ struct cmd_results *cmd_assign(int argc, char **argv) { if (strncmp(*argv, "→", strlen("→")) == 0) { if (argc < 3) { - free(criteria); return cmd_results_new(CMD_INVALID, "assign", "Missing workspace"); } ++argv; @@ -45,7 +44,7 @@ struct cmd_results *cmd_assign(int argc, char **argv) { criteria->target = join_args(argv, target_len); 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); return cmd_results_new(CMD_SUCCESS, NULL, NULL); diff --git a/sway/commands/bar.c b/sway/commands/bar.c index f6a70c175..d84ce8080 100644 --- a/sway/commands/bar.c +++ b/sway/commands/bar.c @@ -63,13 +63,13 @@ struct cmd_results *cmd_bar(int argc, char **argv) { for (int i = 0; i < config->bars->length; ++i) { struct bar_config *item = config->bars->items[i]; 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; break; } } if (!bar) { - wlr_log(WLR_DEBUG, "Creating bar: %s", argv[0]); + wlr_log(L_DEBUG, "Creating bar: %s", argv[0]); bar = default_bar_config(); if (!bar) { return cmd_results_new(CMD_FAILURE, "bar", @@ -108,7 +108,7 @@ struct cmd_results *cmd_bar(int argc, char **argv) { // Set current 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)); diff --git a/sway/commands/bar/binding_mode_indicator.c b/sway/commands/bar/binding_mode_indicator.c index 0c48bee97..3ba5f33f8 100644 --- a/sway/commands/bar/binding_mode_indicator.c +++ b/sway/commands/bar/binding_mode_indicator.c @@ -15,11 +15,11 @@ struct cmd_results *bar_cmd_binding_mode_indicator(int argc, char **argv) { } if (strcasecmp("yes", argv[0]) == 0) { 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); } else if (strcasecmp("no", argv[0]) == 0) { 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); } return cmd_results_new(CMD_INVALID, "binding_mode_indicator", diff --git a/sway/commands/bar/font.c b/sway/commands/bar/font.c index 2aa4e895c..80b7a5931 100644 --- a/sway/commands/bar/font.c +++ b/sway/commands/bar/font.c @@ -14,8 +14,8 @@ struct cmd_results *bar_cmd_font(int argc, char **argv) { } char *font = join_args(argv, argc); free(config->current_bar->font); - config->current_bar->font = font; - wlr_log(WLR_DEBUG, "Settings font '%s' for bar: %s", + config->current_bar->font = strdup(font); + wlr_log(L_DEBUG, "Settings font '%s' for bar: %s", config->current_bar->font, config->current_bar->id); return cmd_results_new(CMD_SUCCESS, NULL, NULL); } diff --git a/sway/commands/bar/height.c b/sway/commands/bar/height.c index 182585265..3160caed8 100644 --- a/sway/commands/bar/height.c +++ b/sway/commands/bar/height.c @@ -14,7 +14,7 @@ struct cmd_results *bar_cmd_height(int argc, char **argv) { "Invalid height value: %s", argv[0]); } 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); return cmd_results_new(CMD_SUCCESS, NULL, NULL); } diff --git a/sway/commands/bar/hidden_state.c b/sway/commands/bar/hidden_state.c index 502ce2c41..6641f1848 100644 --- a/sway/commands/bar/hidden_state.c +++ b/sway/commands/bar/hidden_state.c @@ -27,7 +27,7 @@ static struct cmd_results *bar_set_hidden_state(struct bar_config *bar, if (!config->reading) { 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); } // free old mode diff --git a/sway/commands/bar/id.c b/sway/commands/bar/id.c index 65fa69fda..6ce86fefc 100644 --- a/sway/commands/bar/id.c +++ b/sway/commands/bar/id.c @@ -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(config->current_bar->id); diff --git a/sway/commands/bar/mode.c b/sway/commands/bar/mode.c index 28e2d77bf..34bb0a4ff 100644 --- a/sway/commands/bar/mode.c +++ b/sway/commands/bar/mode.c @@ -28,7 +28,7 @@ static struct cmd_results *bar_set_mode(struct bar_config *bar, const char *mode if (!config->reading) { 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 diff --git a/sway/commands/bar/modifier.c b/sway/commands/bar/modifier.c index 09025fffb..7ba4b125d 100644 --- a/sway/commands/bar/modifier.c +++ b/sway/commands/bar/modifier.c @@ -22,15 +22,14 @@ struct cmd_results *bar_cmd_modifier(int argc, char **argv) { mod |= tmp_mod; continue; } else { - error = cmd_results_new(CMD_INVALID, "modifier", - "Unknown modifier '%s'", split->items[i]); free_flat_list(split); - return error; + return cmd_results_new(CMD_INVALID, "modifier", + "Unknown modifier '%s'", split->items[i]); } } free_flat_list(split); 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]); return cmd_results_new(CMD_SUCCESS, NULL, NULL); } diff --git a/sway/commands/bar/output.c b/sway/commands/bar/output.c index 72754e055..f7ca0aa41 100644 --- a/sway/commands/bar/output.c +++ b/sway/commands/bar/output.c @@ -42,7 +42,7 @@ struct cmd_results *bar_cmd_output(int argc, char **argv) { if (add_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); } return cmd_results_new(CMD_SUCCESS, NULL, NULL); diff --git a/sway/commands/bar/pango_markup.c b/sway/commands/bar/pango_markup.c index 857571fbd..480af724b 100644 --- a/sway/commands/bar/pango_markup.c +++ b/sway/commands/bar/pango_markup.c @@ -13,11 +13,11 @@ struct cmd_results *bar_cmd_pango_markup(int argc, char **argv) { } if (strcasecmp("enabled", argv[0]) == 0) { 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); } else if (strcasecmp("disabled", argv[0]) == 0) { 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); } else { error = cmd_results_new(CMD_INVALID, "pango_markup", diff --git a/sway/commands/bar/position.c b/sway/commands/bar/position.c index 48e7ddbd2..9c5804839 100644 --- a/sway/commands/bar/position.c +++ b/sway/commands/bar/position.c @@ -15,7 +15,7 @@ struct cmd_results *bar_cmd_position(int argc, char **argv) { char *valid[] = { "top", "bottom", "left", "right" }; for (size_t i = 0; i < sizeof(valid) / sizeof(valid[0]); ++i) { 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); config->current_bar->position = strdup(argv[0]); return cmd_results_new(CMD_SUCCESS, NULL, NULL); diff --git a/sway/commands/bar/separator_symbol.c b/sway/commands/bar/separator_symbol.c index 392ab730e..1e08df6d2 100644 --- a/sway/commands/bar/separator_symbol.c +++ b/sway/commands/bar/separator_symbol.c @@ -14,7 +14,7 @@ struct cmd_results *bar_cmd_separator_symbol(int argc, char **argv) { } free(config->current_bar->separator_symbol); 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); return cmd_results_new(CMD_SUCCESS, NULL, NULL); } diff --git a/sway/commands/bar/status_command.c b/sway/commands/bar/status_command.c index 6f6f81a32..5e199cde6 100644 --- a/sway/commands/bar/status_command.c +++ b/sway/commands/bar/status_command.c @@ -14,7 +14,7 @@ struct cmd_results *bar_cmd_status_command(int argc, char **argv) { } free(config->current_bar->status_command); 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); return cmd_results_new(CMD_SUCCESS, NULL, NULL); } diff --git a/sway/commands/bar/strip_workspace_numbers.c b/sway/commands/bar/strip_workspace_numbers.c index 4e47d0472..4f24a3563 100644 --- a/sway/commands/bar/strip_workspace_numbers.c +++ b/sway/commands/bar/strip_workspace_numbers.c @@ -15,11 +15,11 @@ struct cmd_results *bar_cmd_strip_workspace_numbers(int argc, char **argv) { } if (strcasecmp("yes", argv[0]) == 0) { 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); } else if (strcasecmp("no", argv[0]) == 0) { 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); } else { return cmd_results_new(CMD_INVALID, diff --git a/sway/commands/bar/swaybar_command.c b/sway/commands/bar/swaybar_command.c index 04e78e776..520cdd118 100644 --- a/sway/commands/bar/swaybar_command.c +++ b/sway/commands/bar/swaybar_command.c @@ -14,7 +14,7 @@ struct cmd_results *bar_cmd_swaybar_command(int argc, char **argv) { } free(config->current_bar->swaybar_command); 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); return cmd_results_new(CMD_SUCCESS, NULL, NULL); } diff --git a/sway/commands/bar/workspace_buttons.c b/sway/commands/bar/workspace_buttons.c index a4079b2a4..6edc3a0de 100644 --- a/sway/commands/bar/workspace_buttons.c +++ b/sway/commands/bar/workspace_buttons.c @@ -14,11 +14,11 @@ struct cmd_results *bar_cmd_workspace_buttons(int argc, char **argv) { } if (strcasecmp("yes", argv[0]) == 0) { 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); } else if (strcasecmp("no", argv[0]) == 0) { 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); } else { return cmd_results_new(CMD_INVALID, "workspace_buttons", diff --git a/sway/commands/bar/wrap_scroll.c b/sway/commands/bar/wrap_scroll.c index 701de00a6..7386f82ce 100644 --- a/sway/commands/bar/wrap_scroll.c +++ b/sway/commands/bar/wrap_scroll.c @@ -13,11 +13,11 @@ struct cmd_results *bar_cmd_wrap_scroll(int argc, char **argv) { } if (strcasecmp("yes", argv[0]) == 0) { 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); } else if (strcasecmp("no", argv[0]) == 0) { 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); } else { return cmd_results_new(CMD_INVALID, diff --git a/sway/commands/bind.c b/sway/commands/bind.c index 83e9e432a..821f9cd13 100644 --- a/sway/commands/bind.c +++ b/sway/commands/bind.c @@ -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) { struct sway_binding *config_binding = mode_bindings->items[i]; 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); free_sway_binding(config_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); } - 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); return cmd_results_new(CMD_SUCCESS, NULL, NULL); diff --git a/sway/commands/exec.c b/sway/commands/exec.c index 7fc54123d..363d5bef4 100644 --- a/sway/commands/exec.c +++ b/sway/commands/exec.c @@ -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->reloading) { 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); return cmd_results_new(CMD_SUCCESS, NULL, NULL); } diff --git a/sway/commands/exec_always.c b/sway/commands/exec_always.c index c7727857c..682d195ef 100644 --- a/sway/commands/exec_always.c +++ b/sway/commands/exec_always.c @@ -20,7 +20,7 @@ struct cmd_results *cmd_exec_always(int argc, char **argv) { char *tmp = NULL; 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))) { return error; } @@ -35,49 +35,50 @@ struct cmd_results *cmd_exec_always(int argc, char **argv) { strncpy(cmd, tmp, sizeof(cmd) - 1); cmd[sizeof(cmd) - 1] = 0; free(tmp); - wlr_log(WLR_DEBUG, "Executing %s", cmd); + wlr_log(L_DEBUG, "Executing %s", cmd); int fd[2]; 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 if ((pid = fork()) == 0) { // Fork child process again setsid(); - close(fd[0]); - if ((child = fork()) == 0) { - close(fd[1]); + if ((*child = fork()) == 0) { execl("/bin/sh", "/bin/sh", "-c", cmd, (void *)NULL); - _exit(0); + // Not reached } + close(fd[0]); ssize_t s = 0; 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]); _exit(0); // Close child process } else if (pid < 0) { - close(fd[0]); - close(fd[1]); + free(child); return cmd_results_new(CMD_FAILURE, "exec_always", "fork() failed"); } close(fd[1]); // close write ssize_t s = 0; 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]); // cleanup child process waitpid(pid, NULL, 0); - if (child > 0) { - wlr_log(WLR_DEBUG, "Child process created with pid %d", child); + if (*child > 0) { + wlr_log(L_DEBUG, "Child process created with pid %d", *child); // TODO: add PID to active workspace } else { - return cmd_results_new(CMD_FAILURE, "exec_always", - "Second fork() failed"); + free(child); } return cmd_results_new(CMD_SUCCESS, NULL, NULL); diff --git a/sway/commands/floating_minmax_size.c b/sway/commands/floating_minmax_size.c deleted file mode 100644 index 0af789082..000000000 --- a/sway/commands/floating_minmax_size.c +++ /dev/null @@ -1,53 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include "sway/commands.h" -#include "log.h" - -static const char* min_usage = - "Expected 'floating_minimum_size x '"; - -static const char* max_usage = - "Expected 'floating_maximum_size x '"; - -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); -} diff --git a/sway/commands/focus.c b/sway/commands/focus.c index b24d50070..74d9d5359 100644 --- a/sway/commands/focus.c +++ b/sway/commands/focus.c @@ -1,12 +1,10 @@ #include #include #include "log.h" -#include "sway/commands.h" #include "sway/input/input-manager.h" #include "sway/input/seat.h" -#include "sway/tree/arrange.h" #include "sway/tree/view.h" -#include "sway/tree/workspace.h" +#include "sway/commands.h" static bool parse_movement_direction(const char *name, enum movement_direction *out) { @@ -29,21 +27,6 @@ static bool parse_movement_direction(const char *name, 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 sway_container *con = config->handler_context.current_container; 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); } - if (strcmp(argv[0], "floating") == 0) { - 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 + // TODO mode_toggle enum movement_direction direction = 0; if (!parse_movement_direction(argv[0], &direction)) { return cmd_results_new(CMD_INVALID, "focus", - "Expected 'focus ' " - "or 'focus output '"); + "Expected 'focus ' or 'focus output '"); } struct sway_container *next_focus = container_get_in_direction( diff --git a/sway/commands/for_window.c b/sway/commands/for_window.c index ac4d6563a..8c425a1dd 100644 --- a/sway/commands/for_window.c +++ b/sway/commands/for_window.c @@ -24,7 +24,7 @@ struct cmd_results *cmd_for_window(int argc, char **argv) { criteria->cmdlist = join_args(argv + 1, argc - 1); 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); } diff --git a/sway/commands/gaps.c b/sway/commands/gaps.c index 801fb1795..c6e8bd37a 100644 --- a/sway/commands/gaps.c +++ b/sway/commands/gaps.c @@ -6,6 +6,11 @@ #include "stringop.h" #include +#define GAPS_EDGE_GAPS_LINE "gaps edge_gaps on|off|toggle" +#define GAPS_SHORT_LINE "gaps " +#define GAPS_MEDIUM_LINE "gaps inner|outer " +#define GAPS_LONG_LINE "gaps inner|outer all|current set|plus|minus " + enum gaps_op { GAPS_OP_SET, GAPS_OP_ADD, @@ -14,7 +19,6 @@ enum gaps_op { enum gaps_scope { GAPS_SCOPE_ALL, - GAPS_SCOPE_WORKSPACE, GAPS_SCOPE_CURRENT }; @@ -25,7 +29,7 @@ struct cmd_results *cmd_gaps(int argc, char **argv) { } 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; } @@ -40,8 +44,7 @@ struct cmd_results *cmd_gaps(int argc, char **argv) { } config->edge_gaps = !config->edge_gaps; } else { - return cmd_results_new(CMD_INVALID, "gaps", - "gaps edge_gaps on|off|toggle"); + return cmd_results_new(CMD_INVALID, "gaps", GAPS_EDGE_GAPS_LINE); } arrange_and_commit(&root_container); } else { @@ -80,16 +83,15 @@ struct cmd_results *cmd_gaps(int argc, char **argv) { } if (argc == 4) { - // Long format: all|workspace|current. + // Long format: all|current if (strcmp(argv[amount_idx], "all") == 0) { amount_idx++; 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) { amount_idx++; scope = GAPS_SCOPE_CURRENT; + } else { + return cmd_results_new(CMD_INVALID, "gaps", GAPS_LONG_LINE); } // 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) { amount_idx++; 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 // guess which variant of the command was attempted if (argc == 1) { - return cmd_results_new(CMD_INVALID, "gaps", "gaps "); + return cmd_results_new(CMD_INVALID, "gaps", GAPS_SHORT_LINE); } if (argc == 2) { - return cmd_results_new(CMD_INVALID, "gaps", - "gaps inner|outer "); + return cmd_results_new(CMD_INVALID, "gaps", GAPS_MEDIUM_LINE); } - return cmd_results_new(CMD_INVALID, "gaps", - "gaps inner|outer all|workspace|current set|plus|minus "); + return cmd_results_new(CMD_INVALID, "gaps", GAPS_LONG_LINE); } if (amount_idx == 0) { // gaps @@ -159,7 +161,7 @@ struct cmd_results *cmd_gaps(int argc, char **argv) { } else { struct sway_container *c = 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->has_gaps = true; diff --git a/sway/commands/input.c b/sway/commands/input.c index 574e1f8ce..678c57c43 100644 --- a/sway/commands/input.c +++ b/sway/commands/input.c @@ -35,7 +35,7 @@ struct cmd_results *cmd_input(int argc, char **argv) { 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]); if (!config->handler_context.input_config) { diff --git a/sway/commands/input/accel_profile.c b/sway/commands/input/accel_profile.c index a4108ec34..37d6e1338 100644 --- a/sway/commands/input/accel_profile.c +++ b/sway/commands/input/accel_profile.c @@ -23,7 +23,6 @@ struct cmd_results *input_cmd_accel_profile(int argc, char **argv) { } else if (strcasecmp(argv[0], "flat") == 0) { new_config->accel_profile = LIBINPUT_CONFIG_ACCEL_PROFILE_FLAT; } else { - free_input_config(new_config); return cmd_results_new(CMD_INVALID, "accel_profile", "Expected 'accel_profile '"); } diff --git a/sway/commands/input/click_method.c b/sway/commands/input/click_method.c index 5d0d8cc24..8f1f0aa7c 100644 --- a/sway/commands/input/click_method.c +++ b/sway/commands/input/click_method.c @@ -26,7 +26,6 @@ struct cmd_results *input_cmd_click_method(int argc, char **argv) { } else if (strcasecmp(argv[0], "clickfinger") == 0) { new_config->click_method = LIBINPUT_CONFIG_CLICK_METHOD_CLICKFINGER; } else { - free_input_config(new_config); return cmd_results_new(CMD_INVALID, "click_method", "Expected 'click_method drag_lock = LIBINPUT_CONFIG_DRAG_LOCK_DISABLED; } else { - free_input_config(new_config); return cmd_results_new(CMD_INVALID, "drag_lock", "Expected 'drag_lock '"); } diff --git a/sway/commands/input/dwt.c b/sway/commands/input/dwt.c index 73937507a..995a2f47e 100644 --- a/sway/commands/input/dwt.c +++ b/sway/commands/input/dwt.c @@ -22,7 +22,6 @@ struct cmd_results *input_cmd_dwt(int argc, char **argv) { } else if (strcasecmp(argv[0], "disabled") == 0) { new_config->dwt = LIBINPUT_CONFIG_DWT_DISABLED; } else { - free_input_config(new_config); return cmd_results_new(CMD_INVALID, "dwt", "Expected 'dwt '"); } diff --git a/sway/commands/input/events.c b/sway/commands/input/events.c index abfe3b12a..2217f5cec 100644 --- a/sway/commands/input/events.c +++ b/sway/commands/input/events.c @@ -16,7 +16,7 @@ struct cmd_results *input_cmd_events(int argc, char **argv) { return cmd_results_new(CMD_FAILURE, "events", "No input device defined."); } - wlr_log(WLR_DEBUG, "events for device: %s", + wlr_log(L_DEBUG, "events for device: %s", current_input_config->identifier); struct input_config *new_config = 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 = LIBINPUT_CONFIG_SEND_EVENTS_DISABLED_ON_EXTERNAL_MOUSE; } else { - free_input_config(new_config); return cmd_results_new(CMD_INVALID, "events", "Expected 'events '"); } diff --git a/sway/commands/input/left_handed.c b/sway/commands/input/left_handed.c index 769ce98c5..94b8e03ee 100644 --- a/sway/commands/input/left_handed.c +++ b/sway/commands/input/left_handed.c @@ -23,7 +23,6 @@ struct cmd_results *input_cmd_left_handed(int argc, char **argv) { } else if (strcasecmp(argv[0], "disabled") == 0) { new_config->left_handed = 0; } else { - free_input_config(new_config); return cmd_results_new(CMD_INVALID, "left_handed", "Expected 'left_handed '"); } diff --git a/sway/commands/input/map_from_region.c b/sway/commands/input/map_from_region.c index 40f04214b..80bb856de 100644 --- a/sway/commands/input/map_from_region.c +++ b/sway/commands/input/map_from_region.c @@ -54,28 +54,20 @@ struct cmd_results *input_cmd_map_from_region(int argc, char **argv) { bool mm1, mm2; if (!parse_coords(argv[0], &new_config->mapped_from_region->x1, &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", "Invalid top-left coordinates"); } if (!parse_coords(argv[1], &new_config->mapped_from_region->x2, &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", "Invalid bottom-right coordinates"); } 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) { - free(new_config->mapped_from_region); - free_input_config(new_config); return cmd_results_new(CMD_FAILURE, "map_from_region", "Invalid rectangle"); } if (mm1 != mm2) { - free(new_config->mapped_from_region); - free_input_config(new_config); return cmd_results_new(CMD_FAILURE, "map_from_region", "Both coordinates must be in the same unit"); } diff --git a/sway/commands/input/middle_emulation.c b/sway/commands/input/middle_emulation.c index 7ca016293..a551fd51e 100644 --- a/sway/commands/input/middle_emulation.c +++ b/sway/commands/input/middle_emulation.c @@ -24,7 +24,6 @@ struct cmd_results *input_cmd_middle_emulation(int argc, char **argv) { new_config->middle_emulation = LIBINPUT_CONFIG_MIDDLE_EMULATION_DISABLED; } else { - free_input_config(new_config); return cmd_results_new(CMD_INVALID, "middle_emulation", "Expected 'middle_emulation '"); } diff --git a/sway/commands/input/natural_scroll.c b/sway/commands/input/natural_scroll.c index 552367902..c4e19b78b 100644 --- a/sway/commands/input/natural_scroll.c +++ b/sway/commands/input/natural_scroll.c @@ -23,7 +23,6 @@ struct cmd_results *input_cmd_natural_scroll(int argc, char **argv) { } else if (strcasecmp(argv[0], "disabled") == 0) { new_config->natural_scroll = 0; } else { - free_input_config(new_config); return cmd_results_new(CMD_INVALID, "natural_scroll", "Expected 'natural_scroll '"); } diff --git a/sway/commands/input/pointer_accel.c b/sway/commands/input/pointer_accel.c index 8bbd0724e..171063aa0 100644 --- a/sway/commands/input/pointer_accel.c +++ b/sway/commands/input/pointer_accel.c @@ -20,7 +20,6 @@ struct cmd_results *input_cmd_pointer_accel(int argc, char **argv) { float pointer_accel = atof(argv[0]); if (pointer_accel < -1 || pointer_accel > 1) { - free_input_config(new_config); return cmd_results_new(CMD_INVALID, "pointer_accel", "Input out of range [-1, 1]"); } diff --git a/sway/commands/input/repeat_delay.c b/sway/commands/input/repeat_delay.c index c9ddbf0ec..ce2658415 100644 --- a/sway/commands/input/repeat_delay.c +++ b/sway/commands/input/repeat_delay.c @@ -20,7 +20,6 @@ struct cmd_results *input_cmd_repeat_delay(int argc, char **argv) { int repeat_delay = atoi(argv[0]); if (repeat_delay < 0) { - free_input_config(new_config); return cmd_results_new(CMD_INVALID, "repeat_delay", "Repeat delay cannot be negative"); } diff --git a/sway/commands/input/repeat_rate.c b/sway/commands/input/repeat_rate.c index 568781769..f2ea2e692 100644 --- a/sway/commands/input/repeat_rate.c +++ b/sway/commands/input/repeat_rate.c @@ -20,7 +20,6 @@ struct cmd_results *input_cmd_repeat_rate(int argc, char **argv) { int repeat_rate = atoi(argv[0]); if (repeat_rate < 0) { - free_input_config(new_config); return cmd_results_new(CMD_INVALID, "repeat_rate", "Repeat rate cannot be negative"); } diff --git a/sway/commands/input/scroll_method.c b/sway/commands/input/scroll_method.c index 4c6ac6b67..0a1c57ac5 100644 --- a/sway/commands/input/scroll_method.c +++ b/sway/commands/input/scroll_method.c @@ -27,7 +27,6 @@ struct cmd_results *input_cmd_scroll_method(int argc, char **argv) { } else if (strcasecmp(argv[0], "on_button_down") == 0) { new_config->scroll_method = LIBINPUT_CONFIG_SCROLL_ON_BUTTON_DOWN; } else { - free_input_config(new_config); return cmd_results_new(CMD_INVALID, "scroll_method", "Expected 'scroll_method '"); } diff --git a/sway/commands/input/tap.c b/sway/commands/input/tap.c index a8d1a10ca..e7f030581 100644 --- a/sway/commands/input/tap.c +++ b/sway/commands/input/tap.c @@ -23,12 +23,11 @@ struct cmd_results *input_cmd_tap(int argc, char **argv) { } else if (strcasecmp(argv[0], "disabled") == 0) { new_config->tap = LIBINPUT_CONFIG_TAP_DISABLED; } else { - free_input_config(new_config); return cmd_results_new(CMD_INVALID, "tap", "Expected 'tap '"); } - wlr_log(WLR_DEBUG, "apply-tap for device: %s", + wlr_log(L_DEBUG, "apply-tap for device: %s", current_input_config->identifier); apply_input_config(new_config); return cmd_results_new(CMD_SUCCESS, NULL, NULL); diff --git a/sway/commands/input/xkb_layout.c b/sway/commands/input/xkb_layout.c index 9fa5a344b..867e65d3a 100644 --- a/sway/commands/input/xkb_layout.c +++ b/sway/commands/input/xkb_layout.c @@ -19,7 +19,7 @@ struct cmd_results *input_cmd_xkb_layout(int argc, char **argv) { 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); apply_input_config(new_config); return cmd_results_new(CMD_SUCCESS, NULL, NULL); diff --git a/sway/commands/input/xkb_model.c b/sway/commands/input/xkb_model.c index 0d0826259..e8c8e04eb 100644 --- a/sway/commands/input/xkb_model.c +++ b/sway/commands/input/xkb_model.c @@ -19,7 +19,7 @@ struct cmd_results *input_cmd_xkb_model(int argc, char **argv) { 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); apply_input_config(new_config); return cmd_results_new(CMD_SUCCESS, NULL, NULL); diff --git a/sway/commands/input/xkb_options.c b/sway/commands/input/xkb_options.c index 3059d9410..e9ddd6e31 100644 --- a/sway/commands/input/xkb_options.c +++ b/sway/commands/input/xkb_options.c @@ -19,7 +19,7 @@ struct cmd_results *input_cmd_xkb_options(int argc, char **argv) { 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); apply_input_config(new_config); return cmd_results_new(CMD_SUCCESS, NULL, NULL); diff --git a/sway/commands/input/xkb_rules.c b/sway/commands/input/xkb_rules.c index 560f088e1..926d0ac15 100644 --- a/sway/commands/input/xkb_rules.c +++ b/sway/commands/input/xkb_rules.c @@ -19,7 +19,7 @@ struct cmd_results *input_cmd_xkb_rules(int argc, char **argv) { 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); apply_input_config(new_config); return cmd_results_new(CMD_SUCCESS, NULL, NULL); diff --git a/sway/commands/input/xkb_variant.c b/sway/commands/input/xkb_variant.c index 0aa03440a..0e3ffd41e 100644 --- a/sway/commands/input/xkb_variant.c +++ b/sway/commands/input/xkb_variant.c @@ -19,7 +19,7 @@ struct cmd_results *input_cmd_xkb_variant(int argc, char **argv) { 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); apply_input_config(new_config); return cmd_results_new(CMD_SUCCESS, NULL, NULL); diff --git a/sway/commands/mode.c b/sway/commands/mode.c index b460fcb5a..00331ccc1 100644 --- a/sway/commands/mode.c +++ b/sway/commands/mode.c @@ -26,17 +26,7 @@ struct cmd_results *cmd_mode(int argc, char **argv) { "mode", "Can only be used in config file."); } - bool pango = strcmp(*argv, "--pango_markup") == 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); + const char *mode_name = argv[0]; struct sway_mode *mode = NULL; // Find mode 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->keysym_bindings = create_list(); mode->keycode_bindings = create_list(); - mode->pango = pango; list_add(config->modes, mode); } if (!mode) { @@ -65,15 +54,13 @@ struct cmd_results *cmd_mode(int argc, char **argv) { return error; } if ((config->reading && argc > 1) || (!config->reading && argc == 1)) { - wlr_log(WLR_DEBUG, "Switching to mode `%s' (pango=%d)", - mode->name, mode->pango); + wlr_log(L_DEBUG, "Switching to mode `%s'",mode->name); } // Set current mode config->current_mode = mode; if (argc == 1) { // trigger IPC mode event - ipc_event_mode(config->current_mode->name, - config->current_mode->pango); + ipc_event_mode(config->current_mode->name); return cmd_results_new(CMD_SUCCESS, NULL, NULL); } diff --git a/sway/commands/move.c b/sway/commands/move.c index a1c1e018d..a4fae3887 100644 --- a/sway/commands/move.c +++ b/sway/commands/move.c @@ -1,13 +1,11 @@ #define _XOPEN_SOURCE 500 #include #include -#include #include #include #include #include "sway/commands.h" #include "sway/desktop/transaction.h" -#include "sway/input/cursor.h" #include "sway/input/seat.h" #include "sway/output.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, - enum movement_direction direction, int argc, char **argv) { - 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"); - } - } - + enum movement_direction direction, int move_amt) { if (container->type == C_WORKSPACE) { return cmd_results_new(CMD_FAILURE, "move", "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 // is moving the container might reap the old parent, and container_move // 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); } -static const char* expected_position_syntax = - "Expected 'move [absolute] position ' 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 *error = NULL; + int move_amt = 10; if ((error = checkarg(argc, "move", EXPECTED_AT_LEAST, 1))) { return error; } 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) { - 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) { - 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) { - 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) { - 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 || strcasecmp(argv[0], "window") == 0) { return cmd_move_container(current, argc, argv); @@ -331,9 +244,8 @@ struct cmd_results *cmd_move(int argc, char **argv) { // TODO: scratchpad return cmd_results_new(CMD_FAILURE, "move", "Unimplemented"); } else if (strcasecmp(argv[0], "position") == 0) { - return move_to_position(current, argc, argv); - } else if (strcasecmp(argv[0], "absolute") == 0) { - return move_to_position(current, argc, argv); + // TODO: floating + return cmd_results_new(CMD_FAILURE, "move", "Unimplemented"); } else { return cmd_results_new(CMD_INVALID, "move", expected_syntax); } diff --git a/sway/commands/output.c b/sway/commands/output.c index 15bbd687b..f955bf906 100644 --- a/sway/commands/output.c +++ b/sway/commands/output.c @@ -29,7 +29,7 @@ struct cmd_results *cmd_output(int argc, char **argv) { struct output_config *output = new_output_config(argv[0]); if (!output) { - wlr_log(WLR_ERROR, "Failed to allocate output config"); + wlr_log(L_ERROR, "Failed to allocate output config"); return NULL; } argc--; argv++; @@ -71,7 +71,7 @@ struct cmd_results *cmd_output(int argc, char **argv) { 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)", output->name, output->enabled, output->width, output->height, 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; wl_list_for_each(sway_output, &root_container.sway_root->outputs, link) { 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 || strcmp(identifier, output->name) == 0) { if (!sway_output->swayc) { diff --git a/sway/commands/output/background.c b/sway/commands/output/background.c index 4ed56c2ac..55cbdff00 100644 --- a/sway/commands/output/background.c +++ b/sway/commands/output/background.c @@ -72,7 +72,7 @@ struct cmd_results *output_cmd_background(int argc, char **argv) { src = strdup(p.we_wordv[0]); wordfree(&p); 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", "Unable to allocate resource"); } @@ -80,10 +80,9 @@ struct cmd_results *output_cmd_background(int argc, char **argv) { if (config->reading && *src != '/') { // src file is inside configuration dir - char *conf = strdup(config->current_config_path); - if (!conf) { - wlr_log(WLR_ERROR, "Failed to duplicate string"); - free(src); + char *conf = strdup(config->current_config); + if(!conf) { + wlr_log(L_ERROR, "Failed to duplicate string"); return cmd_results_new(CMD_FAILURE, "output", "Unable to allocate resources"); } @@ -94,7 +93,7 @@ struct cmd_results *output_cmd_background(int argc, char **argv) { if (!src) { free(rel_path); 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", "Unable to allocate resources"); } diff --git a/sway/commands/output/mode.c b/sway/commands/output/mode.c index ef56ae9e7..daec6d448 100644 --- a/sway/commands/output/mode.c +++ b/sway/commands/output/mode.c @@ -36,11 +36,11 @@ struct cmd_results *output_cmd_mode(int argc, char **argv) { } } else { // Format is 1234 4321 - argc--; argv++; if (!argc) { return cmd_results_new(CMD_INVALID, "output", "Missing mode argument (height)."); } + argc--; argv++; output->height = strtol(*argv, &end, 10); if (*end) { return cmd_results_new(CMD_INVALID, "output", diff --git a/sway/commands/output/position.c b/sway/commands/output/position.c index 449767b13..c2aeb2815 100644 --- a/sway/commands/output/position.c +++ b/sway/commands/output/position.c @@ -27,11 +27,11 @@ struct cmd_results *output_cmd_position(int argc, char **argv) { } } else { // Format is 1234 4321 (legacy) - argc--; argv++; if (!argc) { return cmd_results_new(CMD_INVALID, "output", "Missing position argument (y)."); } + argc--; argv++; config->handler_context.output_config->y = strtol(*argv, &end, 10); if (*end) { return cmd_results_new(CMD_INVALID, "output", diff --git a/sway/commands/reload.c b/sway/commands/reload.c index c6715f9ca..9fc213c42 100644 --- a/sway/commands/reload.c +++ b/sway/commands/reload.c @@ -7,7 +7,7 @@ struct cmd_results *cmd_reload(int argc, char **argv) { if ((error = checkarg(argc, "reload", EXPECTED_EQUAL_TO, 0))) { 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."); } diff --git a/sway/commands/rename.c b/sway/commands/rename.c index a380ff9cd..104a33925 100644 --- a/sway/commands/rename.c +++ b/sway/commands/rename.c @@ -68,7 +68,7 @@ struct cmd_results *cmd_rename(int argc, char **argv) { "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); workspace->name = new_name; diff --git a/sway/commands/resize.c b/sway/commands/resize.c index 5efbd8b05..6357343e4 100644 --- a/sway/commands/resize.c +++ b/sway/commands/resize.c @@ -95,7 +95,7 @@ static void resize_tiled(int amount, enum resize_axis axis) { return; } - wlr_log(WLR_DEBUG, + wlr_log(L_DEBUG, "Found the proper parent: %p. It has %d l conts, and %d r conts", parent->parent, minor_weight, major_weight); diff --git a/sway/commands/set.c b/sway/commands/set.c index ea388d3b5..84e9b792c 100644 --- a/sway/commands/set.c +++ b/sway/commands/set.c @@ -32,7 +32,7 @@ struct cmd_results *cmd_set(int argc, char **argv) { } 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]); tmp = malloc(size + 1); diff --git a/sway/commands/swaybg_command.c b/sway/commands/swaybg_command.c index 36f7fdcd4..770d48214 100644 --- a/sway/commands/swaybg_command.c +++ b/sway/commands/swaybg_command.c @@ -13,7 +13,7 @@ struct cmd_results *cmd_swaybg_command(int argc, char **argv) { free(config->swaybg_command); } 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); return cmd_results_new(CMD_SUCCESS, NULL, NULL); diff --git a/sway/commands/workspace.c b/sway/commands/workspace.c index e8b371828..d15be5712 100644 --- a/sway/commands/workspace.c +++ b/sway/commands/workspace.c @@ -51,7 +51,7 @@ struct cmd_results *cmd_workspace(int argc, char **argv) { free(old); // workspaces can only be assigned to a single output 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); } else { if (config->reading || !config->active) { diff --git a/sway/config.c b/sway/config.c index c59f4f0da..12a021632 100644 --- a/sway/config.c +++ b/sway/config.c @@ -87,12 +87,7 @@ void free_config(struct sway_config *config) { list_free(config->cmd_queue); list_free(config->workspace_outputs); 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) { for (int i = 0; i < config->input_configs->length; 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_right_cmd); free(config->font); - free((char *)config->current_config_path); free((char *)config->current_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->config_chain = create_list())) goto cleanup; - config->current_config_path = NULL; config->current_config = NULL; // borders @@ -278,12 +271,12 @@ static char *get_config_path(void) { char *home = getenv("HOME"); char *config_home = malloc(strlen(home) + strlen("/.config") + 1); if (!config_home) { - wlr_log(WLR_ERROR, "Unable to allocate $HOME/.config"); + wlr_log(L_ERROR, "Unable to allocate $HOME/.config"); } else { strcpy(config_home, home); strcat(config_home, "/.config"); 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); } } @@ -306,22 +299,25 @@ static char *get_config_path(void) { return NULL; // Not reached } -static bool load_config(const char *path, struct sway_config *config) { - if (path == NULL) { - wlr_log(WLR_ERROR, "Unable to find a config file!"); - return false; - } +const char *current_config_path; - 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; if (stat(path, &sb) == 0 && S_ISDIR(sb.st_mode)) { return false; } + if (path == NULL) { + wlr_log(L_ERROR, "Unable to find a config file!"); + return false; + } + FILE *f = fopen(path, "r"); 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; } @@ -329,9 +325,10 @@ static bool load_config(const char *path, struct sway_config *config) { fclose(f); 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; } @@ -351,12 +348,12 @@ bool load_main_config(const char *file, bool is_active) { config_defaults(config); if (is_active) { - wlr_log(WLR_DEBUG, "Performing configuration file reload"); + wlr_log(L_DEBUG, "Performing configuration file reload"); config->reloading = true; config->active = true; } - config->current_config_path = path; + config->current_config = path; list_add(config->config_chain, path); config->reading = true; @@ -367,7 +364,7 @@ bool load_main_config(const char *file, bool is_active) { /* DIR *dir = opendir(SYSCONFDIR "/sway/security.d"); if (!dir) { - wlr_log(WLR_ERROR, + wlr_log(L_ERROR, "%s does not exist, sway will have no security configuration" " and will probably be broken", SYSCONFDIR "/sway/security.d"); } 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 || (((s.st_mode & 0777) != 0644) && (s.st_mode & 0777) != 0444)) { - wlr_log(WLR_ERROR, + wlr_log(L_ERROR, "Refusing to load %s - it must be owned by root " "and mode 644 or 444", _path); 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, struct sway_config *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); if (len >= 1 && path[0] != '/') { len = len + strlen(parent_dir) + 2; full_path = malloc(len * sizeof(char)); if (!full_path) { - wlr_log(WLR_ERROR, + wlr_log(L_ERROR, "Unable to allocate full path to included config"); return false; } snprintf(full_path, len, "%s/%s", parent_dir, path); - } else { - full_path = strdup(path); } char *real_path = realpath(full_path, NULL); free(full_path); if (real_path == NULL) { - wlr_log(WLR_DEBUG, "%s not found.", path); + wlr_log(L_DEBUG, "%s not found.", path); 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) { char *old_path = config->config_chain->items[j]; if (strcmp(real_path, old_path) == 0) { - wlr_log(WLR_DEBUG, + wlr_log(L_DEBUG, "%s already included once, won't be included again.", 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); int index = config->config_chain->length - 1; if (!load_config(real_path, config)) { free(real_path); - config->current_config_path = parent_config; + config->current_config = parent_config; list_del(config->config_chain, index); return false; } - // restore current_config_path - config->current_config_path = parent_config; + // restore current_config + config->current_config = parent_config; return true; } bool load_include_configs(const char *path, struct sway_config *config) { 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); if (chdir(parent_dir) < 0) { @@ -510,7 +505,7 @@ bool load_include_configs(const char *path, struct sway_config *config) { // restore wd if (chdir(wd) < 0) { free(wd); - wlr_log(WLR_ERROR, "failed to restore working directory"); + wlr_log(L_ERROR, "failed to restore working directory"); return false; } @@ -525,13 +520,13 @@ static int detect_brace_on_following_line(FILE *file, char *line, char *peeked = NULL; long position = 0; 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); peeked = peek_line(file, lines, &position); if (peeked) { peeked = strip_whitespace(peeked); } - wlr_log(WLR_DEBUG, "Peeked line: `%s`", peeked); + wlr_log(L_DEBUG, "Peeked line: `%s`", peeked); lines++; } 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; char *expanded = calloc(1, size); if (!expanded) { - wlr_log(WLR_ERROR, "Cannot allocate expanded line buffer"); + wlr_log(L_ERROR, "Cannot allocate expanded line buffer"); return NULL; } 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 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; int line_number = 0; char *line; @@ -587,15 +565,7 @@ bool read_config(FILE *file, struct sway_config *config) { continue; } line_number++; - wlr_log(WLR_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'; - } - + wlr_log(L_DEBUG, "Read line %d: %s", line_number, line); line = strip_whitespace(line); if (line[0] == '#') { free(line); @@ -609,17 +579,13 @@ bool read_config(FILE *file, struct sway_config *config) { line_number); if (brace_detected > 0) { 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); if (!expanded) { - list_foreach(stack, free); - list_free(stack); - free(line); - free(current_config); return false; } - wlr_log(WLR_DEBUG, "Expanded line: %s", expanded); + wlr_log(L_DEBUG, "Expanded line: %s", expanded); struct cmd_results *res; if (block && strcmp(block, "") == 0) { // Special case @@ -631,23 +597,23 @@ bool read_config(FILE *file, struct sway_config *config) { switch(res->status) { case CMD_FAILURE: case CMD_INVALID: - wlr_log(WLR_ERROR, "Error on line %i '%s': %s (%s)", line_number, - line, res->error, config->current_config_path); + wlr_log(L_ERROR, "Error on line %i '%s': %s (%s)", line_number, + line, res->error, config->current_config); success = false; break; 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)); break; case CMD_BLOCK_COMMANDS: - wlr_log(WLR_DEBUG, "Entering commands block"); + wlr_log(L_DEBUG, "Entering commands block"); list_insert(stack, 0, ""); break; 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)); if (strcmp(res->input, "bar") == 0) { config->current_bar = NULL; @@ -656,7 +622,7 @@ bool read_config(FILE *file, struct sway_config *config) { case CMD_BLOCK_END: if (!block) { - wlr_log(WLR_DEBUG, "Unmatched '}' on line %i", line_number); + wlr_log(L_DEBUG, "Unmatched '}' on line %i", line_number); success = false; break; } @@ -664,7 +630,7 @@ bool read_config(FILE *file, struct sway_config *config) { config->current_bar = NULL; } - wlr_log(WLR_DEBUG, "Exiting block '%s'", block); + wlr_log(L_DEBUG, "Exiting block '%s'", block); list_del(stack, 0); free(block); memset(&config->handler_context, 0, @@ -677,10 +643,6 @@ bool read_config(FILE *file, struct sway_config *config) { list_foreach(stack, free); list_free(stack); - if (reading_main_config) { - current_config[config_size - 1] = '\0'; - config->current_config = current_config; - } return success; } @@ -711,7 +673,7 @@ char *do_var_replacement(char *str) { int vvlen = strlen(var->value); char *newstr = malloc(strlen(str) - vnlen + vvlen + 1); if (!newstr) { - wlr_log(WLR_ERROR, + wlr_log(L_ERROR, "Unable to allocate replacement " "during variable expansion"); break; diff --git a/sway/config/bar.c b/sway/config/bar.c index 3a74331e4..5a97c3cc5 100644 --- a/sway/config/bar.c +++ b/sway/config/bar.c @@ -16,10 +16,10 @@ #include "log.h" 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); 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 { int status; waitpid(pid, &status, 0); @@ -30,7 +30,6 @@ void free_bar_config(struct bar_config *bar) { if (!bar) { return; } - free(bar->id); free(bar->mode); free(bar->position); 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 *bar = NULL; - bar = calloc(1, sizeof(struct bar_config)); + bar = malloc(sizeof(struct bar_config)); if (!bar) { return NULL; } + if (!(bar->mode = strdup("dock"))) goto cleanup; + if (!(bar->hidden_state = strdup("hide"))) goto cleanup; bar->outputs = NULL; 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->swaybar_command = NULL; bar->font = NULL; @@ -88,19 +91,6 @@ struct bar_config *default_bar_config(void) { bar->binding_mode_indicator = true; bar->verbose = false; 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 if (!(bar->colors.background = strndup("#000000ff", 9))) { goto cleanup; @@ -167,7 +157,7 @@ void invoke_swaybar(struct bar_config *bar) { // Pipe to communicate errors int filedes[2]; 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; } @@ -184,7 +174,7 @@ void invoke_swaybar(struct bar_config *bar) { if (!command) { const char msg[] = "Unable to allocate swaybar command string"; 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)) {}; close(filedes[1]); exit(1); @@ -197,17 +187,17 @@ void invoke_swaybar(struct bar_config *bar) { execvp(cmd[0], cmd); exit(1); } - wlr_log(WLR_DEBUG, "Spawned swaybar %d", bar->pid); + wlr_log(L_DEBUG, "Spawned swaybar %d", bar->pid); close(filedes[0]); - size_t len; - if (read(filedes[1], &len, sizeof(size_t)) == sizeof(size_t)) { + ssize_t len; + if (read(filedes[1], &len, sizeof(int)) == sizeof(int)) { char *buf = malloc(len); if(!buf) { - wlr_log(WLR_ERROR, "Cannot allocate error string"); + wlr_log(L_ERROR, "Cannot allocate error string"); return; } if (read(filedes[1], buf, len)) { - wlr_log(WLR_ERROR, "%s", buf); + wlr_log(L_ERROR, "%s", buf); } free(buf); } @@ -244,7 +234,7 @@ void load_swaybars() { if (bar->pid != 0) { 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); } } diff --git a/sway/config/input.c b/sway/config/input.c index 9840df183..17303ccc9 100644 --- a/sway/config/input.c +++ b/sway/config/input.c @@ -8,13 +8,13 @@ struct input_config *new_input_config(const char* identifier) { struct input_config *input = calloc(1, sizeof(struct input_config)); if (!input) { - wlr_log(WLR_DEBUG, "Unable to allocate input config"); + wlr_log(L_DEBUG, "Unable to allocate input config"); 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))) { free(input); - wlr_log(WLR_DEBUG, "Unable to allocate input config"); + wlr_log(L_DEBUG, "Unable to allocate input config"); 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 = calloc(1, sizeof(struct input_config)); if (copy == NULL) { - wlr_log(WLR_ERROR, "could not allocate input config"); + wlr_log(L_ERROR, "could not allocate input config"); return NULL; } merge_input_config(copy, ic); diff --git a/sway/config/output.c b/sway/config/output.c index 205e2633c..648ded27c 100644 --- a/sway/config/output.c +++ b/sway/config/output.c @@ -90,7 +90,7 @@ static void set_mode(struct wlr_output *output, int width, int height, float refresh_rate) { int mhz = (int)(refresh_rate * 1000); 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); return; } @@ -106,9 +106,9 @@ static void set_mode(struct wlr_output *output, int width, int height, } } 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 { - 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); } } @@ -116,7 +116,7 @@ static void set_mode(struct wlr_output *output, int width, int height, void terminate_swaybg(pid_t pid) { int ret = kill(pid, SIGTERM); 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 { int status; 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) { - 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); set_mode(wlr_output, oc->width, oc->height, oc->refresh_rate); } 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); } 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); } // Find position for it 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); } else { 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); } - 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); 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); char *command = malloc(len + 1); if (!command) { - wlr_log(WLR_DEBUG, "Unable to allocate swaybg command"); + wlr_log(L_DEBUG, "Unable to allocate swaybg command"); return; } snprintf(command, len + 1, "%s %d %s %s", config->swaybg_command ? config->swaybg_command : "swaybg", 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 }; 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) { switch (oc->dpms_state) { case DPMS_ON: - wlr_log(WLR_DEBUG, "Turning on screen"); + wlr_log(L_DEBUG, "Turning on screen"); wlr_output_enable(wlr_output, true); break; case DPMS_OFF: - wlr_log(WLR_DEBUG, "Turning off screen"); + wlr_log(L_DEBUG, "Turning off screen"); wlr_output_enable(wlr_output, false); break; case DPMS_IGNORE: diff --git a/sway/config/seat.c b/sway/config/seat.c index 83dac4c0f..bd8b45c87 100644 --- a/sway/config/seat.c +++ b/sway/config/seat.c @@ -7,11 +7,11 @@ struct seat_config *new_seat_config(const char* name) { struct seat_config *seat = calloc(1, sizeof(struct seat_config)); if (!seat) { - wlr_log(WLR_DEBUG, "Unable to allocate seat config"); + wlr_log(L_DEBUG, "Unable to allocate seat config"); return NULL; } - wlr_log(WLR_DEBUG, "new_seat_config(%s)", name); + wlr_log(L_DEBUG, "new_seat_config(%s)", name); seat->name = strdup(name); if (!sway_assert(seat->name, "could not allocate name for seat")) { free(seat); @@ -34,7 +34,7 @@ struct seat_attachment_config *seat_attachment_config_new() { struct seat_attachment_config *attachment = calloc(1, sizeof(struct seat_attachment_config)); if (!attachment) { - wlr_log(WLR_DEBUG, "cannot allocate attachment config"); + wlr_log(L_DEBUG, "cannot allocate attachment config"); return NULL; } return attachment; diff --git a/sway/criteria.c b/sway/criteria.c index 29a3668ba..d9f09ecc6 100644 --- a/sway/criteria.c +++ b/sway/criteria.c @@ -507,7 +507,7 @@ struct criteria *criteria_parse(char *raw, char **error_arg) { } 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)) { *error_arg = error; goto cleanup; diff --git a/sway/desktop/desktop.c b/sway/desktop/desktop.c index 6575519d4..e495790c8 100644 --- a/sway/desktop/desktop.c +++ b/sway/desktop/desktop.c @@ -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); - } - } -} diff --git a/sway/desktop/idle_inhibit_v1.c b/sway/desktop/idle_inhibit_v1.c deleted file mode 100644 index 108a84177..000000000 --- a/sway/desktop/idle_inhibit_v1.c +++ /dev/null @@ -1,79 +0,0 @@ -#include -#include -#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; -} diff --git a/sway/desktop/layer_shell.c b/sway/desktop/layer_shell.c index 16910c7e6..de1fe349d 100644 --- a/sway/desktop/layer_shell.c +++ b/sway/desktop/layer_shell.c @@ -174,7 +174,7 @@ void arrange_layers(struct sway_output *output) { if (memcmp(&usable_area, &output->usable_area, 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)); 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) { struct sway_layer_surface *sway_layer = 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); if (sway_layer->layer_surface->mapped) { 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 sway_server *server = 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", layer_surface->namespace, layer_surface->layer, layer_surface->layer, layer_surface->client_pending.desired_width, diff --git a/sway/desktop/output.c b/sway/desktop/output.c index 73108450f..1e7494b3e 100644 --- a/sway/desktop/output.c +++ b/sway/desktop/output.c @@ -56,15 +56,33 @@ static void rotate_child_position(double *sx, double *sy, double sw, double sh, *sy = ry + ph/2 - sh/2; } -bool output_get_surface_box(struct root_geometry *geo, +/** + * 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; +}; + +struct render_data { + struct root_geometry root_geo; + struct sway_output *output; + pixman_region32_t *damage; + struct sway_view *view; + float alpha; +}; + +static bool get_surface_box(struct root_geometry *geo, struct sway_output *output, struct wlr_surface *surface, int sx, int sy, struct wlr_box *surface_box) { if (!wlr_surface_has_buffer(surface)) { return false; } - int sw = surface->current.width; - int sh = surface->current.height; + int sw = surface->current->width; + int sh = surface->current->height; double _sx = sx, _sy = sy; rotate_child_position(&_sx, &_sy, sw, sh, geo->width, geo->height, @@ -92,23 +110,24 @@ bool output_get_surface_box(struct root_geometry *geo, return wlr_box_intersection(&output_box, &rotated_box, &intersection); } -void output_surface_for_each_surface(struct wlr_surface *surface, +static void 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) { geo->x = ox; geo->y = oy; - geo->width = surface->current.width; - geo->height = surface->current.height; + geo->width = surface->current->width; + geo->height = surface->current->height; geo->rotation = 0; wlr_surface_for_each_surface(surface, iterator, 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) { - geo->x = view->swayc->current.view_x - output->swayc->current.swayc_x; - geo->y = view->swayc->current.view_y - output->swayc->current.swayc_y; +static void output_view_for_each_surface(struct sway_view *view, + struct root_geometry *geo, wlr_surface_iterator_func_t iterator, + void *user_data) { + struct render_data *data = user_data; + geo->x = view->swayc->current.view_x - data->output->swayc->current.swayc_x; + geo->y = view->swayc->current.view_y - data->output->swayc->current.swayc_y; geo->width = view->swayc->current.view_width; geo->height = view->swayc->current.view_height; geo->rotation = 0; // TODO @@ -116,20 +135,20 @@ void output_view_for_each_surface(struct sway_view *view, view_for_each_surface(view, iterator, user_data); } -void output_layer_for_each_surface(struct wl_list *layer_surfaces, +static void layer_for_each_surface(struct wl_list *layer_surfaces, struct root_geometry *geo, wlr_surface_iterator_func_t iterator, void *user_data) { struct sway_layer_surface *layer_surface; wl_list_for_each(layer_surface, layer_surfaces, link) { struct wlr_layer_surface *wlr_layer_surface = layer_surface->layer_surface; - output_surface_for_each_surface(wlr_layer_surface->surface, + surface_for_each_surface(wlr_layer_surface->surface, layer_surface->geo.x, layer_surface->geo.y, geo, iterator, user_data); } } -void output_unmanaged_for_each_surface(struct wl_list *unmanaged, +static void 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) { struct sway_xwayland_unmanaged *unmanaged_surface; @@ -139,12 +158,12 @@ void output_unmanaged_for_each_surface(struct wl_list *unmanaged, double ox = unmanaged_surface->lx - output->swayc->current.swayc_x; double oy = unmanaged_surface->ly - output->swayc->current.swayc_y; - output_surface_for_each_surface(xsurface->surface, ox, oy, geo, + surface_for_each_surface(xsurface->surface, ox, oy, geo, iterator, user_data); } } -void output_drag_icons_for_each_surface(struct wl_list *drag_icons, +static void 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) { struct sway_drag_icon *drag_icon; @@ -153,7 +172,7 @@ void output_drag_icons_for_each_surface(struct wl_list *drag_icons, double oy = drag_icon->y - output->swayc->y; if (drag_icon->wlr_drag_icon->mapped) { - output_surface_for_each_surface(drag_icon->wlr_drag_icon->surface, + surface_for_each_surface(drag_icon->wlr_drag_icon->surface, ox, oy, geo, iterator, user_data); } } @@ -166,7 +185,722 @@ static void scale_box(struct wlr_box *box, float scale) { box->height *= scale; } -struct sway_container *output_get_active_workspace(struct sway_output *output) { +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 = 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, + }; + 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, + }; + 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, + }; + 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, &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_width = 0; + 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_width = texture_box.width; + } + + // Title text + size_t title_width = 0; + 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_width < texture_box.width) { + texture_box.width = inner_width * output_scale - marks_width; + } + render_texture(output->wlr_output, output_damage, title_texture, + &texture_box, matrix, con->alpha); + title_width = texture_box.width; + } + + // 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_width - marks_width; + if (box.width > 0) { + box.x = (x + TITLEBAR_H_PADDING) * output_scale + title_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; + + // Render tabs + for (int i = 0; i < con->current.children->length; ++i) { + struct sway_container *child = con->current.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 tab_width = pstate->swayc_width / pstate->children->length; + int x = pstate->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 - 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; + + // Render titles + for (int i = 0; i < con->current.children->length; ++i) { + struct sway_container *child = con->current.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 = pstate->swayc_y + container_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); + } + } + } +} + +static struct sway_container *output_get_active_workspace( + struct sway_output *output) { struct sway_seat *seat = input_manager_current_seat(input_manager); struct sway_container *focus = seat_get_focus_inactive(seat, output->swayc); @@ -181,58 +915,117 @@ struct sway_container *output_get_active_workspace(struct sway_output *output) { return workspace; } -bool output_has_opaque_lockscreen(struct sway_output *output, - struct sway_seat *seat) { - if (!seat->exclusive_client) { - return false; +static void render_output(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; } - struct wlr_layer_surface *wlr_layer_surface; - wl_list_for_each(wlr_layer_surface, &server.layer_shell->surfaces, link) { - if (wlr_layer_surface->output != output->wlr_output) { - continue; - } - struct wlr_surface *wlr_surface = wlr_layer_surface->surface; - if (wlr_surface->resource->client != seat->exclusive_client) { - continue; - } - struct sway_layer_surface *sway_layer_surface = - layer_from_wlr_layer_surface(wlr_layer_surface); - pixman_box32_t output_box = { - .x2 = output->swayc->current.swayc_width, - .y2 = output->swayc->current.swayc_height, - }; - pixman_region32_t surface_opaque_box; - pixman_region32_init(&surface_opaque_box); - pixman_region32_copy(&surface_opaque_box, &wlr_surface->current.opaque); - pixman_region32_translate(&surface_opaque_box, - sway_layer_surface->geo.x, sway_layer_surface->geo.y); - bool contains = pixman_region32_contains_rectangle( - &wlr_surface->current.opaque, &output_box); - pixman_region32_fini(&surface_opaque_box); - if (contains) { - return true; + 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); } } - return false; + + struct sway_container *workspace = output_get_active_workspace(output); + struct sway_view *fullscreen_view = workspace->current.ws_fullscreen; + + 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 + 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; } struct send_frame_done_data { struct root_geometry root_geo; struct sway_output *output; struct timespec *when; - struct wl_client *exclusive_client; }; static void send_frame_done_iterator(struct wlr_surface *surface, int sx, int sy, void *_data) { struct send_frame_done_data *data = _data; - if (data->exclusive_client && - data->exclusive_client != surface->resource->client) { - return; - } - bool intersects = output_get_surface_box(&data->root_geo, data->output, surface, + bool intersects = get_surface_box(&data->root_geo, data->output, surface, sx, sy, NULL); if (intersects) { wlr_surface_send_frame_done(surface, data->when); @@ -241,19 +1034,19 @@ static void send_frame_done_iterator(struct wlr_surface *surface, static void send_frame_done_layer(struct send_frame_done_data *data, struct wl_list *layer_surfaces) { - output_layer_for_each_surface(layer_surfaces, &data->root_geo, + layer_for_each_surface(layer_surfaces, &data->root_geo, send_frame_done_iterator, data); } static void send_frame_done_unmanaged(struct send_frame_done_data *data, struct wl_list *unmanaged) { - output_unmanaged_for_each_surface(unmanaged, data->output, &data->root_geo, + unmanaged_for_each_surface(unmanaged, data->output, &data->root_geo, send_frame_done_iterator, data); } static void send_frame_done_drag_icons(struct send_frame_done_data *data, struct wl_list *drag_icons) { - output_drag_icons_for_each_surface(drag_icons, data->output, &data->root_geo, + drag_icons_for_each_surface(drag_icons, data->output, &data->root_geo, send_frame_done_iterator, data); } @@ -268,7 +1061,7 @@ static void send_frame_done_container_iterator(struct sway_container *con, return; } - output_view_for_each_surface(con->sway_view, data->output, &data->root_geo, + output_view_for_each_surface(con->sway_view, &data->root_geo, send_frame_done_iterator, data); } @@ -279,12 +1072,9 @@ static void send_frame_done_container(struct send_frame_done_data *data, } static void send_frame_done(struct sway_output *output, struct timespec *when) { - struct sway_seat *seat = input_manager_current_seat(input_manager); struct send_frame_done_data data = { .output = output, .when = when, - .exclusive_client = output_has_opaque_lockscreen(output, seat) ? - seat->exclusive_client : NULL, }; struct sway_container *workspace = output_get_active_workspace(output); @@ -335,7 +1125,7 @@ static void damage_handle_frame(struct wl_listener *listener, void *data) { } if (needs_swap) { - output_render(output, &now, &damage); + render_output(output, &now, &damage); } pixman_region32_fini(&damage); @@ -362,7 +1152,7 @@ static void damage_surface_iterator(struct wlr_surface *surface, int sx, int sy, bool whole = data->whole; struct wlr_box box; - bool intersects = output_get_surface_box(&data->root_geo, data->output, surface, + bool intersects = get_surface_box(&data->root_geo, data->output, surface, sx, sy, &box); if (!intersects) { return; @@ -373,22 +1163,16 @@ static void damage_surface_iterator(struct wlr_surface *surface, int sx, int sy, int center_x = box.x + box.width/2; int center_y = box.y + box.height/2; - if (pixman_region32_not_empty(&surface->buffer_damage)) { - enum wl_output_transform transform = - wlr_output_transform_invert(surface->current.transform); - + if (pixman_region32_not_empty(&surface->current->surface_damage)) { pixman_region32_t damage; pixman_region32_init(&damage); - pixman_region32_copy(&damage, &surface->buffer_damage); - wlr_region_transform(&damage, &damage, transform, - surface->current.buffer_width, surface->current.buffer_height); - wlr_region_scale(&damage, &damage, - output->wlr_output->scale / (float)surface->current.scale); - if (ceil(output->wlr_output->scale) > surface->current.scale) { + pixman_region32_copy(&damage, &surface->current->surface_damage); + wlr_region_scale(&damage, &damage, output->wlr_output->scale); + if (ceil(output->wlr_output->scale) > surface->current->scale) { // When scaling up a surface, it'll become blurry so we need to // expand the damage region wlr_region_expand(&damage, &damage, - ceil(output->wlr_output->scale) - surface->current.scale); + ceil(output->wlr_output->scale) - surface->current->scale); } pixman_region32_translate(&damage, box.x, box.y); wlr_region_rotated_bounds(&damage, &damage, rotation, @@ -412,7 +1196,7 @@ void output_damage_surface(struct sway_output *output, double ox, double oy, .whole = whole, }; - output_surface_for_each_surface(surface, ox, oy, &data.root_geo, + surface_for_each_surface(surface, ox, oy, &data.root_geo, damage_surface_iterator, &data); } @@ -431,7 +1215,7 @@ static void output_damage_view(struct sway_output *output, .whole = whole, }; - output_view_for_each_surface(view, output, &data.root_geo, + output_view_for_each_surface(view, &data.root_geo, damage_surface_iterator, &data); } @@ -525,7 +1309,7 @@ struct sway_output *output_from_wlr_output(struct wlr_output *wlr_output) { void handle_new_output(struct wl_listener *listener, void *data) { struct sway_server *server = wl_container_of(listener, server, new_output); struct wlr_output *wlr_output = data; - wlr_log(WLR_DEBUG, "New output %p: %s", wlr_output, wlr_output->name); + wlr_log(L_DEBUG, "New output %p: %s", wlr_output, wlr_output->name); struct sway_output *output = calloc(1, sizeof(struct sway_output)); if (!output) { diff --git a/sway/desktop/render.c b/sway/desktop/render.c deleted file mode 100644 index b370f8a29..000000000 --- a/sway/desktop/render.c +++ /dev/null @@ -1,904 +0,0 @@ -#define _POSIX_C_SOURCE 200809L -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#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; -} diff --git a/sway/desktop/transaction.c b/sway/desktop/transaction.c index 2b3f87c3d..d2932c874 100644 --- a/sway/desktop/transaction.c +++ b/sway/desktop/transaction.c @@ -6,7 +6,6 @@ #include #include #include "sway/debug.h" -#include "sway/desktop/idle_inhibit_v1.h" #include "sway/desktop/transaction.h" #include "sway/output.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)) { instruction->saved_buffer = wlr_buffer_ref(view->surface->buffer); - instruction->saved_buffer_width = view->surface->current.width; - instruction->saved_buffer_height = view->surface->current.height; + instruction->saved_buffer_width = view->surface->current->width; + 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. */ 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) { struct timespec 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 + (now.tv_nsec - commit->tv_nsec) / 1000000.0; float ms_total = ms_arranging + ms_waiting; - wlr_log(WLR_DEBUG, "Transaction %p: %.1fms arranging, %.1fms waiting, " - "%.1fms total (%.1f frames if 60Hz)", transaction, - ms_arranging, ms_waiting, ms_total, ms_total / (1000.0f / 60)); + wlr_log(L_DEBUG, "Transaction %p: %.1fms arranging, %.1fms waiting, " + "%.1fms total (%.1f frames if 60Hz)", transaction, + ms_arranging, ms_waiting, ms_total, ms_total / (1000 / 60)); } // Apply the instruction state to the container's current state @@ -246,12 +245,11 @@ static void transaction_progress_queue() { transaction_destroy(transaction); } server.transactions->length = 0; - idle_inhibit_v1_check_active(server.idle_inhibit_manager_v1); } static int handle_timeout(void *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->num_waiting = 0; transaction_progress_queue(); @@ -286,7 +284,7 @@ static bool should_configure(struct sway_container *con, } 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->num_waiting = 0; for (int i = 0; i < transaction->instructions->length; ++i) { @@ -319,10 +317,9 @@ void transaction_commit(struct sway_transaction *transaction) { } else { // There are no other transactions in progress, and this one has nothing // 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_destroy(transaction); - idle_inhibit_v1_check_active(server.idle_inhibit_manager_v1); return; } @@ -350,7 +347,7 @@ static void set_instruction_ready( struct timespec *start = &transaction->commit_time; float ms = (now.tv_sec - start->tv_sec) * 1000 + (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->num_configures - transaction->num_waiting + 1, 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 (transaction->num_waiting > 0 && --transaction->num_waiting == 0) { #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); transaction_progress_queue(); #endif @@ -377,9 +374,7 @@ static void set_instructions_ready(struct sway_view *view, int index) { for (int i = 0; i <= index; ++i) { struct sway_transaction_instruction *instruction = view->swayc->instructions->items[i]; - if (!instruction->ready) { - set_instruction_ready(instruction); - } + set_instruction_ready(instruction); } } diff --git a/sway/desktop/xdg_shell.c b/sway/desktop/xdg_shell.c index be14adbec..82db40760 100644 --- a/sway/desktop/xdg_shell.c +++ b/sway/desktop/xdg_shell.c @@ -222,8 +222,8 @@ static void handle_request_fullscreen(struct wl_listener *listener, void *data) view_set_fullscreen(view, e->fullscreen); - struct sway_container *output = container_parent(view->swayc, C_OUTPUT); - arrange_and_commit(output); + struct sway_container *ws = container_parent(view->swayc, C_WORKSPACE); + arrange_and_commit(ws); } 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_height = view->wlr_xdg_surface->geometry.height; if (!view->natural_width && !view->natural_height) { - view->natural_width = view->wlr_xdg_surface->surface->current.width; - view->natural_height = view->wlr_xdg_surface->surface->current.height; + view->natural_width = view->wlr_xdg_surface->surface->current->width; + view->natural_height = view->wlr_xdg_surface->surface->current->height; } 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; 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; } - 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); wlr_xdg_surface_ping(xdg_surface); diff --git a/sway/desktop/xdg_shell_v6.c b/sway/desktop/xdg_shell_v6.c index f5cf085a7..0d3c16443 100644 --- a/sway/desktop/xdg_shell_v6.c +++ b/sway/desktop/xdg_shell_v6.c @@ -217,8 +217,8 @@ static void handle_request_fullscreen(struct wl_listener *listener, void *data) view_set_fullscreen(view, e->fullscreen); - struct sway_container *output = container_parent(view->swayc, C_OUTPUT); - arrange_and_commit(output); + struct sway_container *ws = container_parent(view->swayc, C_WORKSPACE); + arrange_and_commit(ws); } 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_height = view->wlr_xdg_surface_v6->geometry.height; if (!view->natural_width && !view->natural_height) { - view->natural_width = view->wlr_xdg_surface_v6->surface->current.width; - view->natural_height = view->wlr_xdg_surface_v6->surface->current.height; + view->natural_width = view->wlr_xdg_surface_v6->surface->current->width; + view->natural_height = view->wlr_xdg_surface_v6->surface->current->height; } 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; 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; } - 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); wlr_xdg_surface_v6_ping(xdg_surface); diff --git a/sway/desktop/xwayland.c b/sway/desktop/xwayland.c index 4e5cea7d0..4bb35f609 100644 --- a/sway/desktop/xwayland.c +++ b/sway/desktop/xwayland.c @@ -119,7 +119,7 @@ static struct sway_xwayland_unmanaged *create_unmanaged( struct sway_xwayland_unmanaged *surface = calloc(1, sizeof(struct sway_xwayland_unmanaged)); if (surface == NULL) { - wlr_log(WLR_ERROR, "Allocation failed"); + wlr_log(L_ERROR, "Allocation failed"); return NULL; } @@ -278,15 +278,12 @@ static void handle_commit(struct wl_listener *listener, void *data) { wl_container_of(listener, xwayland_view, commit); struct sway_view *view = &xwayland_view->view; 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) { transaction_notify_view_ready_by_size(view, 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); } @@ -382,8 +379,8 @@ static void handle_request_fullscreen(struct wl_listener *listener, void *data) } view_set_fullscreen(view, xsurface->fullscreen); - struct sway_container *output = container_parent(view->swayc, C_OUTPUT); - arrange_and_commit(output); + struct sway_container *ws = container_parent(view->swayc, C_WORKSPACE); + arrange_and_commit(ws); } 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) || xsurface->override_redirect) { - wlr_log(WLR_DEBUG, "New xwayland unmanaged surface"); + wlr_log(L_DEBUG, "New xwayland unmanaged surface"); create_unmanaged(xsurface); 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); 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); int err = xcb_connection_has_error(xcb_conn); if (err) { - wlr_log(WLR_ERROR, "XCB connect failed: %d", err); + wlr_log(L_ERROR, "XCB connect failed: %d", err); return; } @@ -509,7 +506,7 @@ void handle_xwayland_ready(struct wl_listener *listener, void *data) { free(reply); 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); free(error); break; diff --git a/sway/input/cursor.c b/sway/input/cursor.c index 307eedd4f..944e35aac 100644 --- a/sway/input/cursor.c +++ b/sway/input/cursor.c @@ -255,12 +255,14 @@ void dispatch_cursor_button(struct sway_cursor *cursor, wlr_layer_surface_from_wlr_surface(surface); if (layer->current.keyboard_interactive) { 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 - // that does not unless the change would move us to a new workspace. - // - // This prevents, for example, losing focus when clicking on swaybar. + } + // 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. + // + // This prevents, for example, losing focus when clicking on swaybar. + if (surface && cont && cont->type != C_VIEW) { struct sway_container *new_ws = cont; if (new_ws && new_ws->type != 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 if (focused_client == NULL || 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; } diff --git a/sway/input/input-manager.c b/sway/input/input-manager.c index daaf1fb62..29b47a7ba 100644 --- a/sway/input/input-manager.c +++ b/sway/input/input-manager.c @@ -61,7 +61,7 @@ static char *get_device_identifier(struct wlr_input_device *device) { int len = snprintf(NULL, 0, fmt, vendor, product, name) + 1; char *identifier = malloc(len); 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; } @@ -104,74 +104,74 @@ static void input_manager_libinput_config_pointer( } 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); 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); libinput_device_config_accel_set_profile(libinput_device, ic->accel_profile); } 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); libinput_device_config_click_set_method(libinput_device, ic->click_method); } if (ic->drag_lock != INT_MIN) { - wlr_log(WLR_DEBUG, + wlr_log(L_DEBUG, "libinput_config_pointer(%s) tap_set_drag_lock_enabled(%d)", ic->identifier, ic->click_method); libinput_device_config_tap_set_drag_lock_enabled(libinput_device, ic->drag_lock); } 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); libinput_device_config_dwt_set_enabled(libinput_device, ic->dwt); } if (ic->left_handed != INT_MIN) { - wlr_log(WLR_DEBUG, + wlr_log(L_DEBUG, "libinput_config_pointer(%s) left_handed_set_enabled(%d)", ic->identifier, ic->left_handed); libinput_device_config_left_handed_set(libinput_device, ic->left_handed); } if (ic->middle_emulation != INT_MIN) { - wlr_log(WLR_DEBUG, + wlr_log(L_DEBUG, "libinput_config_pointer(%s) middle_emulation_set_enabled(%d)", ic->identifier, ic->middle_emulation); libinput_device_config_middle_emulation_set_enabled(libinput_device, ic->middle_emulation); } if (ic->natural_scroll != INT_MIN) { - wlr_log(WLR_DEBUG, + wlr_log(L_DEBUG, "libinput_config_pointer(%s) natural_scroll_set_enabled(%d)", ic->identifier, ic->natural_scroll); libinput_device_config_scroll_set_natural_scroll_enabled( libinput_device, ic->natural_scroll); } 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); libinput_device_config_accel_set_speed(libinput_device, ic->pointer_accel); } 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); libinput_device_config_scroll_set_method(libinput_device, ic->scroll_method); } 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); libinput_device_config_send_events_set_mode(libinput_device, ic->send_events); } 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); 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; } - wlr_log(WLR_DEBUG, "removing device: '%s'", + wlr_log(L_DEBUG, "removing device: '%s'", input_device->identifier); 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); 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); if (input_device->wlr_device->type == WLR_INPUT_DEVICE_POINTER) { 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; 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_add_device(seat, input_device); return; @@ -259,10 +256,13 @@ static void handle_new_input(struct wl_listener *listener, void *data) { } if (!added) { - wlr_log(WLR_DEBUG, + wlr_log(L_DEBUG, "device '%s' is not configured on any seats", 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) { @@ -282,7 +282,7 @@ static void handle_inhibit_deactivate(struct wl_listener *listener, void *data) seat_set_exclusive_client(seat, NULL); struct sway_container *previous = seat_get_focus(seat); 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); // Hack to get seat to re-focus the return value of get_focus 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, 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); struct sway_seat *seat = input_manager_get_seat(input, seat_config->name); if (!seat) { diff --git a/sway/input/keyboard.c b/sway/input/keyboard.c index 580c0d4b0..ec149d060 100644 --- a/sway/input/keyboard.c +++ b/sway/input/keyboard.c @@ -108,7 +108,7 @@ static void get_active_binding(const struct sway_shortcut_state *state, } 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); } else { *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, struct sway_binding *binding) { - wlr_log(WLR_DEBUG, "running command for binding: %s", + wlr_log(L_DEBUG, "running command for binding: %s", binding->command); config->handler_context.seat = keyboard->seat_device->sway_seat; struct cmd_results *results = execute_command(binding->command, NULL); 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); } 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); 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); return; } @@ -420,9 +420,6 @@ void sway_keyboard_destroy(struct sway_keyboard *keyboard) { if (!keyboard) { return; } - if (keyboard->keymap) { - xkb_keymap_unref(keyboard->keymap); - } wl_list_remove(&keyboard->keyboard_key.link); wl_list_remove(&keyboard->keyboard_modifiers.link); free(keyboard); diff --git a/sway/input/seat.c b/sway/input/seat.c index 5e65ca704..2c2087da4 100644 --- a/sway/input/seat.c +++ b/sway/input/seat.c @@ -75,7 +75,7 @@ static void seat_send_activate(struct sway_container *con, struct sway_seat *seat) { if (con->type == C_VIEW) { 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; } 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)); if (seat_con == NULL) { - wlr_log(WLR_ERROR, "could not allocate seat container"); + wlr_log(L_ERROR, "could not allocate seat container"); 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)); if (icon == NULL) { - wlr_log(WLR_ERROR, "Allocation failed"); + wlr_log(L_ERROR, "Allocation failed"); return; } 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( sway_device->input_device); 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); 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; } 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); struct sway_container *output = NULL; 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, sway_device->input_device->wlr_device, 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); break; case WLR_INPUT_DEVICE_TABLET_PAD: - wlr_log(WLR_DEBUG, "TODO: configure tablet pad"); + wlr_log(L_DEBUG, "TODO: configure tablet pad"); break; } } @@ -510,11 +510,11 @@ void seat_add_device(struct sway_seat *seat, struct sway_seat_device *seat_device = calloc(1, sizeof(struct sway_seat_device)); if (!seat_device) { - wlr_log(WLR_DEBUG, "could not allocate seat device"); + wlr_log(L_DEBUG, "could not allocate seat device"); 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); seat_device->sway_seat = seat; @@ -533,7 +533,7 @@ void seat_remove_device(struct sway_seat *seat, 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); seat_device_destroy(seat_device); @@ -663,17 +663,7 @@ void seat_set_focus_warp(struct sway_seat *seat, } seat_send_focus(container, seat); - container_damage_whole(container->parent); - } - - // 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); - } + container_damage_whole(container); } // 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 = seat_get_focus_inactive(seat, &root_container); 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); // Hack to get seat to re-focus the return value of get_focus 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 *container) { - struct sway_seat_container *current = NULL; - wl_list_for_each(current, &seat->focus_stack, link) { - if (current->container->current.parent == container && - current->container->current.layout != L_FLOATING) { - return current->container; - } + struct sway_container *child = seat_get_active_child(seat, container); + if (child) { + return child; + } + if (container->current.children->length == 1) { + return container->current.children->items[0]; } return NULL; } diff --git a/sway/ipc-json.c b/sway/ipc-json.c index 3d0e88f05..b9289e256 100644 --- a/sway/ipc-json.c +++ b/sway/ipc-json.c @@ -2,7 +2,6 @@ #include #include #include "log.h" -#include "sway/config.h" #include "sway/ipc-json.h" #include "sway/tree/container.h" #include "sway/tree/workspace.h" @@ -42,7 +41,6 @@ json_object *ipc_json_get_version() { json_object_object_add(version, "major", json_object_new_int(major)); json_object_object_add(version, "minor", json_object_new_int(minor)); json_object_object_add(version, "patch", json_object_new_int(patch)); - json_object_object_add(version, "loaded_config_file_name", json_object_new_string(config->current_config_path)); return version; } diff --git a/sway/ipc-server.c b/sway/ipc-server.c index c5161a6bc..241fe742a 100644 --- a/sway/ipc-server.c +++ b/sway/ipc-server.c @@ -17,7 +17,6 @@ #include #include #include "sway/commands.h" -#include "sway/config.h" #include "sway/ipc-json.h" #include "sway/ipc-server.h" #include "sway/output.h" @@ -32,7 +31,6 @@ static int ipc_socket = -1; static struct wl_event_source *ipc_event_source = NULL; static struct sockaddr_un *ipc_sockaddr = NULL; static list_t *ipc_client_list = NULL; -static struct wl_listener ipc_display_destroy; static const char ipc_magic[] = {'i', '3', '-', 'i', 'p', 'c'}; @@ -58,26 +56,6 @@ void ipc_client_disconnect(struct ipc_client *client); void ipc_client_handle_command(struct ipc_client *client); bool ipc_send_reply(struct ipc_client *client, const char *payload, uint32_t payload_length); -static void handle_display_destroy(struct wl_listener *listener, void *data) { - if (ipc_event_source) { - wl_event_source_remove(ipc_event_source); - } - close(ipc_socket); - unlink(ipc_sockaddr->sun_path); - - while (ipc_client_list->length) { - struct ipc_client *client = ipc_client_list->items[0]; - ipc_client_disconnect(client); - } - list_free(ipc_client_list); - - if (ipc_sockaddr) { - free(ipc_sockaddr); - } - - wl_list_remove(&ipc_display_destroy.link); -} - void ipc_init(struct sway_server *server) { ipc_socket = socket(AF_UNIX, SOCK_STREAM | SOCK_NONBLOCK | SOCK_CLOEXEC, 0); if (ipc_socket == -1) { @@ -107,13 +85,24 @@ void ipc_init(struct sway_server *server) { ipc_client_list = create_list(); - ipc_display_destroy.notify = handle_display_destroy; - wl_display_add_destroy_listener(server->wl_display, &ipc_display_destroy); - ipc_event_source = wl_event_loop_add_fd(server->wl_event_loop, ipc_socket, WL_EVENT_READABLE, ipc_handle_connection, server); } +void ipc_terminate(void) { + if (ipc_event_source) { + wl_event_source_remove(ipc_event_source); + } + close(ipc_socket); + unlink(ipc_sockaddr->sun_path); + + list_free(ipc_client_list); + + if (ipc_sockaddr) { + free(ipc_sockaddr); + } +} + struct sockaddr_un *ipc_user_sockaddr(void) { struct sockaddr_un *ipc_sockaddr = malloc(sizeof(struct sockaddr_un)); if (ipc_sockaddr == NULL) { @@ -139,32 +128,32 @@ struct sockaddr_un *ipc_user_sockaddr(void) { int ipc_handle_connection(int fd, uint32_t mask, void *data) { (void) fd; struct sway_server *server = data; - wlr_log(WLR_DEBUG, "Event on IPC listening socket"); + wlr_log(L_DEBUG, "Event on IPC listening socket"); assert(mask == WL_EVENT_READABLE); int client_fd = accept(ipc_socket, NULL, NULL); if (client_fd == -1) { - wlr_log_errno(WLR_ERROR, "Unable to accept IPC client connection"); + wlr_log_errno(L_ERROR, "Unable to accept IPC client connection"); return 0; } int flags; if ((flags = fcntl(client_fd, F_GETFD)) == -1 || fcntl(client_fd, F_SETFD, flags|FD_CLOEXEC) == -1) { - wlr_log_errno(WLR_ERROR, "Unable to set CLOEXEC on IPC client socket"); + wlr_log_errno(L_ERROR, "Unable to set CLOEXEC on IPC client socket"); close(client_fd); return 0; } if ((flags = fcntl(client_fd, F_GETFL)) == -1 || fcntl(client_fd, F_SETFL, flags|O_NONBLOCK) == -1) { - wlr_log_errno(WLR_ERROR, "Unable to set NONBLOCK on IPC client socket"); + wlr_log_errno(L_ERROR, "Unable to set NONBLOCK on IPC client socket"); close(client_fd); return 0; } struct ipc_client *client = malloc(sizeof(struct ipc_client)); if (!client) { - wlr_log(WLR_ERROR, "Unable to allocate ipc client"); + wlr_log(L_ERROR, "Unable to allocate ipc client"); close(client_fd); return 0; } @@ -180,12 +169,12 @@ int ipc_handle_connection(int fd, uint32_t mask, void *data) { client->write_buffer_len = 0; client->write_buffer = malloc(client->write_buffer_size); if (!client->write_buffer) { - wlr_log(WLR_ERROR, "Unable to allocate ipc client write buffer"); + wlr_log(L_ERROR, "Unable to allocate ipc client write buffer"); close(client_fd); return 0; } - wlr_log(WLR_DEBUG, "New client: fd %d", client_fd); + wlr_log(L_DEBUG, "New client: fd %d", client_fd); list_add(ipc_client_list, client); return 0; } @@ -196,22 +185,22 @@ int ipc_client_handle_readable(int client_fd, uint32_t mask, void *data) { struct ipc_client *client = data; if (mask & WL_EVENT_ERROR) { - wlr_log(WLR_ERROR, "IPC Client socket error, removing client"); + wlr_log(L_ERROR, "IPC Client socket error, removing client"); ipc_client_disconnect(client); return 0; } if (mask & WL_EVENT_HANGUP) { - wlr_log(WLR_DEBUG, "Client %d hung up", client->fd); + wlr_log(L_DEBUG, "Client %d hung up", client->fd); ipc_client_disconnect(client); return 0; } - wlr_log(WLR_DEBUG, "Client %d readable", client->fd); + wlr_log(L_DEBUG, "Client %d readable", client->fd); int read_available; if (ioctl(client_fd, FIONREAD, &read_available) == -1) { - wlr_log_errno(WLR_INFO, "Unable to read IPC socket buffer size"); + wlr_log_errno(L_INFO, "Unable to read IPC socket buffer size"); ipc_client_disconnect(client); return 0; } @@ -233,13 +222,13 @@ int ipc_client_handle_readable(int client_fd, uint32_t mask, void *data) { // Should be fully available, because read_available >= ipc_header_size ssize_t received = recv(client_fd, buf, ipc_header_size, 0); if (received == -1) { - wlr_log_errno(WLR_INFO, "Unable to receive header from IPC client"); + wlr_log_errno(L_INFO, "Unable to receive header from IPC client"); ipc_client_disconnect(client); return 0; } if (memcmp(buf, ipc_magic, sizeof(ipc_magic)) != 0) { - wlr_log(WLR_DEBUG, "IPC header check failed"); + wlr_log(L_DEBUG, "IPC header check failed"); ipc_client_disconnect(client); return 0; } @@ -273,11 +262,8 @@ static void ipc_send_event(const char *json_string, enum ipc_command_type event) } client->current_command = event; if (!ipc_send_reply(client, json_string, (uint32_t) strlen(json_string))) { - wlr_log_errno(WLR_INFO, "Unable to send reply to IPC client"); - /* ipc_send_reply destroys client on error, which also - * removes it from the list, so we need to process - * current index again */ - i--; + wlr_log_errno(L_INFO, "Unable to send reply to IPC client"); + ipc_client_disconnect(client); } } } @@ -287,7 +273,7 @@ void ipc_event_workspace(struct sway_container *old, if (!ipc_has_event_listeners(IPC_EVENT_WORKSPACE)) { return; } - wlr_log(WLR_DEBUG, "Sending workspace::%s event", change); + wlr_log(L_DEBUG, "Sending workspace::%s event", change); json_object *obj = json_object_new_object(); json_object_object_add(obj, "change", json_object_new_string(change)); if (strcmp("focus", change) == 0) { @@ -315,7 +301,7 @@ void ipc_event_window(struct sway_container *window, const char *change) { if (!ipc_has_event_listeners(IPC_EVENT_WINDOW)) { return; } - wlr_log(WLR_DEBUG, "Sending window::%s event", change); + wlr_log(L_DEBUG, "Sending window::%s event", change); json_object *obj = json_object_new_object(); json_object_object_add(obj, "change", json_object_new_string(change)); json_object_object_add(obj, "container", ipc_json_describe_container_recursive(window)); @@ -329,7 +315,7 @@ void ipc_event_barconfig_update(struct bar_config *bar) { if (!ipc_has_event_listeners(IPC_EVENT_BARCONFIG_UPDATE)) { return; } - wlr_log(WLR_DEBUG, "Sending barconfig_update event"); + wlr_log(L_DEBUG, "Sending barconfig_update event"); json_object *json = ipc_json_describe_bar_config(bar); const char *json_string = json_object_to_json_string(json); @@ -337,15 +323,13 @@ void ipc_event_barconfig_update(struct bar_config *bar) { json_object_put(json); } -void ipc_event_mode(const char *mode, bool pango) { +void ipc_event_mode(const char *mode) { if (!ipc_has_event_listeners(IPC_EVENT_MODE)) { return; } - wlr_log(WLR_DEBUG, "Sending mode::%s event", mode); + wlr_log(L_DEBUG, "Sending mode::%s event", mode); json_object *obj = json_object_new_object(); json_object_object_add(obj, "change", json_object_new_string(mode)); - json_object_object_add(obj, "pango_markup", - json_object_new_boolean(pango)); const char *json_string = json_object_to_json_string(obj); ipc_send_event(json_string, IPC_EVENT_MODE); @@ -356,13 +340,13 @@ int ipc_client_handle_writable(int client_fd, uint32_t mask, void *data) { struct ipc_client *client = data; if (mask & WL_EVENT_ERROR) { - wlr_log(WLR_ERROR, "IPC Client socket error, removing client"); + wlr_log(L_ERROR, "IPC Client socket error, removing client"); ipc_client_disconnect(client); return 0; } if (mask & WL_EVENT_HANGUP) { - wlr_log(WLR_DEBUG, "Client %d hung up", client->fd); + wlr_log(L_DEBUG, "Client %d hung up", client->fd); ipc_client_disconnect(client); return 0; } @@ -371,14 +355,14 @@ int ipc_client_handle_writable(int client_fd, uint32_t mask, void *data) { return 0; } - wlr_log(WLR_DEBUG, "Client %d writable", client->fd); + wlr_log(L_DEBUG, "Client %d writable", client->fd); ssize_t written = write(client->fd, client->write_buffer, client->write_buffer_len); if (written == -1 && errno == EAGAIN) { return 0; } else if (written == -1) { - wlr_log_errno(WLR_INFO, "Unable to send data from queue to IPC client"); + wlr_log_errno(L_INFO, "Unable to send data from queue to IPC client"); ipc_client_disconnect(client); return 0; } @@ -399,9 +383,11 @@ void ipc_client_disconnect(struct ipc_client *client) { return; } - shutdown(client->fd, SHUT_RDWR); + if (client->fd != -1) { + shutdown(client->fd, SHUT_RDWR); + } - wlr_log(WLR_INFO, "IPC Client %d disconnected", client->fd); + wlr_log(L_INFO, "IPC Client %d disconnected", client->fd); wl_event_source_remove(client->event_source); if (client->writable_event_source) { wl_event_source_remove(client->writable_event_source); @@ -462,7 +448,7 @@ void ipc_client_handle_command(struct ipc_client *client) { char *buf = malloc(client->payload_length + 1); if (!buf) { - wlr_log_errno(WLR_INFO, "Unable to allocate IPC payload"); + wlr_log_errno(L_INFO, "Unable to allocate IPC payload"); ipc_client_disconnect(client); return; } @@ -471,7 +457,7 @@ void ipc_client_handle_command(struct ipc_client *client) { ssize_t received = recv(client->fd, buf, client->payload_length, 0); if (received == -1) { - wlr_log_errno(WLR_INFO, "Unable to receive payload from IPC client"); + wlr_log_errno(L_INFO, "Unable to receive payload from IPC client"); ipc_client_disconnect(client); free(buf); return; @@ -479,15 +465,16 @@ void ipc_client_handle_command(struct ipc_client *client) { } buf[client->payload_length] = '\0'; - bool client_valid = true; + const char *error_denied = "{ \"success\": false, \"error\": \"Permission denied\" }"; + switch (client->current_command) { case IPC_COMMAND: { struct cmd_results *results = execute_command(buf, NULL); - char *json = cmd_results_to_json(results); - int length = strlen(json); - client_valid = ipc_send_reply(client, json, (uint32_t)length); - free(json); + const char *json = cmd_results_to_json(results); + char reply[256]; + int length = snprintf(reply, sizeof(reply), "%s", json); + ipc_send_reply(client, reply, (uint32_t) length); free_cmd_results(results); goto exit_cleanup; } @@ -510,8 +497,7 @@ void ipc_client_handle_command(struct ipc_client *client) { } } const char *json_string = json_object_to_json_string(outputs); - client_valid = - ipc_send_reply(client, json_string, (uint32_t)strlen(json_string)); + ipc_send_reply(client, json_string, (uint32_t) strlen(json_string)); json_object_put(outputs); // free goto exit_cleanup; } @@ -522,8 +508,7 @@ void ipc_client_handle_command(struct ipc_client *client) { container_for_each_descendant_dfs(&root_container, ipc_get_workspaces_callback, workspaces); const char *json_string = json_object_to_json_string(workspaces); - client_valid = - ipc_send_reply(client, json_string, (uint32_t)strlen(json_string)); + ipc_send_reply(client, json_string, (uint32_t) strlen(json_string)); json_object_put(workspaces); // free goto exit_cleanup; } @@ -533,8 +518,8 @@ void ipc_client_handle_command(struct ipc_client *client) { // TODO: Check if they're permitted to use these events struct json_object *request = json_tokener_parse(buf); if (request == NULL) { - client_valid = ipc_send_reply(client, "{\"success\": false}", 18); - wlr_log_errno(WLR_INFO, "Failed to read request"); + ipc_send_reply(client, "{\"success\": false}", 18); + wlr_log_errno(L_INFO, "Failed to read request"); goto exit_cleanup; } @@ -554,16 +539,15 @@ void ipc_client_handle_command(struct ipc_client *client) { } else if (strcmp(event_type, "binding") == 0) { client->subscribed_events |= event_mask(IPC_EVENT_BINDING); } else { - client_valid = - ipc_send_reply(client, "{\"success\": false}", 18); + ipc_send_reply(client, "{\"success\": false}", 18); json_object_put(request); - wlr_log_errno(WLR_INFO, "Failed to parse request"); + wlr_log_errno(L_INFO, "Failed to parse request"); goto exit_cleanup; } } json_object_put(request); - client_valid = ipc_send_reply(client, "{\"success\": true}", 17); + ipc_send_reply(client, "{\"success\": true}", 17); goto exit_cleanup; } @@ -575,8 +559,7 @@ void ipc_client_handle_command(struct ipc_client *client) { json_object_array_add(inputs, ipc_json_describe_input(device)); } const char *json_string = json_object_to_json_string(inputs); - client_valid = - ipc_send_reply(client, json_string, (uint32_t)strlen(json_string)); + ipc_send_reply(client, json_string, (uint32_t)strlen(json_string)); json_object_put(inputs); // free goto exit_cleanup; } @@ -589,8 +572,7 @@ void ipc_client_handle_command(struct ipc_client *client) { json_object_array_add(seats, ipc_json_describe_seat(seat)); } const char *json_string = json_object_to_json_string(seats); - client_valid = - ipc_send_reply(client, json_string, (uint32_t)strlen(json_string)); + ipc_send_reply(client, json_string, (uint32_t)strlen(json_string)); json_object_put(seats); // free goto exit_cleanup; } @@ -600,8 +582,7 @@ void ipc_client_handle_command(struct ipc_client *client) { json_object *tree = ipc_json_describe_container_recursive(&root_container); const char *json_string = json_object_to_json_string(tree); - client_valid = - ipc_send_reply(client, json_string, (uint32_t) strlen(json_string)); + ipc_send_reply(client, json_string, (uint32_t) strlen(json_string)); json_object_put(tree); goto exit_cleanup; } @@ -612,8 +593,7 @@ void ipc_client_handle_command(struct ipc_client *client) { container_descendants(&root_container, C_VIEW, ipc_get_marks_callback, marks); const char *json_string = json_object_to_json_string(marks); - client_valid = - ipc_send_reply(client, json_string, (uint32_t)strlen(json_string)); + ipc_send_reply(client, json_string, (uint32_t)strlen(json_string)); json_object_put(marks); goto exit_cleanup; } @@ -622,8 +602,7 @@ void ipc_client_handle_command(struct ipc_client *client) { { json_object *version = ipc_json_get_version(); const char *json_string = json_object_to_json_string(version); - client_valid = - ipc_send_reply(client, json_string, (uint32_t)strlen(json_string)); + ipc_send_reply(client, json_string, (uint32_t)strlen(json_string)); json_object_put(version); // free goto exit_cleanup; } @@ -638,9 +617,7 @@ void ipc_client_handle_command(struct ipc_client *client) { json_object_array_add(bars, json_object_new_string(bar->id)); } const char *json_string = json_object_to_json_string(bars); - client_valid = - ipc_send_reply(client, json_string, - (uint32_t)strlen(json_string)); + ipc_send_reply(client, json_string, (uint32_t)strlen(json_string)); json_object_put(bars); // free } else { // Send particular bar's details @@ -654,54 +631,27 @@ void ipc_client_handle_command(struct ipc_client *client) { } if (!bar) { const char *error = "{ \"success\": false, \"error\": \"No bar with that ID\" }"; - client_valid = - ipc_send_reply(client, error, (uint32_t)strlen(error)); + ipc_send_reply(client, error, (uint32_t)strlen(error)); goto exit_cleanup; } json_object *json = ipc_json_describe_bar_config(bar); const char *json_string = json_object_to_json_string(json); - client_valid = - ipc_send_reply(client, json_string, - (uint32_t)strlen(json_string)); + ipc_send_reply(client, json_string, (uint32_t)strlen(json_string)); json_object_put(json); // free } goto exit_cleanup; } - case IPC_GET_BINDING_MODES: - { - json_object *modes = json_object_new_array(); - for (int i = 0; i < config->modes->length; i++) { - struct sway_mode *mode = config->modes->items[i]; - json_object_array_add(modes, json_object_new_string(mode->name)); - } - const char *json_string = json_object_to_json_string(modes); - client_valid = - ipc_send_reply(client, json_string, (uint32_t)strlen(json_string)); - json_object_put(modes); // free - goto exit_cleanup; - } - - case IPC_GET_CONFIG: - { - json_object *json = json_object_new_object(); - json_object_object_add(json, "config", json_object_new_string(config->current_config)); - const char *json_string = json_object_to_json_string(json); - client_valid = - ipc_send_reply(client, json_string, (uint32_t)strlen(json_string)); - json_object_put(json); // free - goto exit_cleanup; - } - default: - wlr_log(WLR_INFO, "Unknown IPC command type %i", client->current_command); + wlr_log(L_INFO, "Unknown IPC command type %i", client->current_command); goto exit_cleanup; } + ipc_send_reply(client, error_denied, (uint32_t)strlen(error_denied)); + wlr_log(L_DEBUG, "Denied IPC client access to %i", client->current_command); + exit_cleanup: - if (client_valid) { - client->payload_length = 0; - } + client->payload_length = 0; free(buf); return; } @@ -722,14 +672,14 @@ bool ipc_send_reply(struct ipc_client *client, const char *payload, uint32_t pay } if (client->write_buffer_size > 4e6) { // 4 MB - wlr_log(WLR_ERROR, "Client write buffer too big, disconnecting client"); + wlr_log(L_ERROR, "Client write buffer too big, disconnecting client"); ipc_client_disconnect(client); return false; } char *new_buffer = realloc(client->write_buffer, client->write_buffer_size); if (!new_buffer) { - wlr_log(WLR_ERROR, "Unable to reallocate ipc client write buffer"); + wlr_log(L_ERROR, "Unable to reallocate ipc client write buffer"); ipc_client_disconnect(client); return false; } @@ -746,6 +696,6 @@ bool ipc_send_reply(struct ipc_client *client, const char *payload, uint32_t pay ipc_client_handle_writable, client); } - wlr_log(WLR_DEBUG, "Added IPC reply to client %d queue: %s", client->fd, payload); + wlr_log(L_DEBUG, "Added IPC reply to client %d queue: %s", client->fd, payload); return true; } diff --git a/sway/main.c b/sway/main.c index c64532264..a325dc3ad 100644 --- a/sway/main.c +++ b/sway/main.c @@ -1,7 +1,6 @@ #define _XOPEN_SOURCE 700 #define _POSIX_C_SOURCE 200112L #include -#include #include #include #include @@ -129,7 +128,7 @@ static void log_env() { "SWAYSOCK" }; for (size_t i = 0; i < sizeof(log_vars) / sizeof(char *); ++i) { - wlr_log(WLR_INFO, "%s=%s", log_vars[i], getenv(log_vars[i])); + wlr_log(L_INFO, "%s=%s", log_vars[i], getenv(log_vars[i])); } } @@ -144,14 +143,14 @@ static void log_distro() { for (size_t i = 0; i < sizeof(paths) / sizeof(char *); ++i) { FILE *f = fopen(paths[i], "r"); if (f) { - wlr_log(WLR_INFO, "Contents of %s:", paths[i]); + wlr_log(L_INFO, "Contents of %s:", paths[i]); while (!feof(f)) { char *line; if (!(line = read_line(f))) { break; } if (*line) { - wlr_log(WLR_INFO, "%s", line); + wlr_log(L_INFO, "%s", line); } free(line); } @@ -163,7 +162,7 @@ static void log_distro() { static void log_kernel() { FILE *f = popen("uname -a", "r"); if (!f) { - wlr_log(WLR_INFO, "Unable to determine kernel version"); + wlr_log(L_INFO, "Unable to determine kernel version"); return; } while (!feof(f)) { @@ -172,25 +171,25 @@ static void log_kernel() { break; } if (*line) { - wlr_log(WLR_INFO, "%s", line); + wlr_log(L_INFO, "%s", line); } free(line); } - pclose(f); + fclose(f); } static void security_sanity_check() { // TODO: Notify users visually if this has issues struct stat s; if (stat("/proc", &s)) { - wlr_log(WLR_ERROR, + wlr_log(L_ERROR, "!! DANGER !! /proc is not available - sway CANNOT enforce security rules!"); } #ifdef __linux__ cap_flag_value_t v; cap_t cap = cap_get_proc(); if (!cap || cap_get_flag(cap, CAP_SYS_PTRACE, CAP_PERMITTED, &v) != 0 || v != CAP_SET) { - wlr_log(WLR_ERROR, + wlr_log(L_ERROR, "!! DANGER !! Sway does not have CAP_SYS_PTRACE and cannot enforce security rules for processes running as other users."); } if (cap) { @@ -206,13 +205,13 @@ static void executable_sanity_check() { stat(exe, &sb); // We assume that cap_get_file returning NULL implies ENODATA if (sb.st_mode & (S_ISUID|S_ISGID) && cap_get_file(exe)) { - wlr_log(WLR_ERROR, + wlr_log(L_ERROR, "sway executable has both the s(g)uid bit AND file caps set."); - wlr_log(WLR_ERROR, + wlr_log(L_ERROR, "This is strongly discouraged (and completely broken)."); - wlr_log(WLR_ERROR, + wlr_log(L_ERROR, "Please clear one of them (either the suid bit, or the file caps)."); - wlr_log(WLR_ERROR, + wlr_log(L_ERROR, "If unsure, strip the file caps."); exit(EXIT_FAILURE); } @@ -223,16 +222,16 @@ static void executable_sanity_check() { static void drop_permissions(bool keep_caps) { if (getuid() != geteuid() || getgid() != getegid()) { if (setgid(getgid()) != 0) { - wlr_log(WLR_ERROR, "Unable to drop root"); + wlr_log(L_ERROR, "Unable to drop root"); exit(EXIT_FAILURE); } if (setuid(getuid()) != 0) { - wlr_log(WLR_ERROR, "Unable to drop root"); + wlr_log(L_ERROR, "Unable to drop root"); exit(EXIT_FAILURE); } } if (setuid(0) != -1) { - wlr_log(WLR_ERROR, "Root privileges can be restored."); + wlr_log(L_ERROR, "Root privileges can be restored."); exit(EXIT_FAILURE); } #ifdef __linux__ @@ -240,11 +239,11 @@ static void drop_permissions(bool keep_caps) { // Drop every cap except CAP_SYS_PTRACE cap_t caps = cap_init(); cap_value_t keep = CAP_SYS_PTRACE; - wlr_log(WLR_INFO, "Dropping extra capabilities"); + wlr_log(L_INFO, "Dropping extra capabilities"); if (cap_set_flag(caps, CAP_PERMITTED, 1, &keep, CAP_SET) || cap_set_flag(caps, CAP_EFFECTIVE, 1, &keep, CAP_SET) || cap_set_proc(caps)) { - wlr_log(WLR_ERROR, "Failed to drop extra capabilities"); + wlr_log(L_ERROR, "Failed to drop extra capabilities"); exit(EXIT_FAILURE); } } @@ -335,22 +334,22 @@ int main(int argc, char **argv) { // TODO: switch logging over to wlroots? if (debug) { - wlr_log_init(WLR_DEBUG, NULL); + wlr_log_init(L_DEBUG, NULL); } else if (verbose || validate) { - wlr_log_init(WLR_INFO, NULL); + wlr_log_init(L_INFO, NULL); } else { - wlr_log_init(WLR_ERROR, NULL); + wlr_log_init(L_ERROR, NULL); } if (optind < argc) { // Behave as IPC client if(optind != 1) { - wlr_log(WLR_ERROR, "Don't use options with the IPC client"); + wlr_log(L_ERROR, "Don't use options with the IPC client"); exit(EXIT_FAILURE); } drop_permissions(false); char *socket_path = getenv("SWAYSOCK"); if (!socket_path) { - wlr_log(WLR_ERROR, "Unable to retrieve socket path"); + wlr_log(L_ERROR, "Unable to retrieve socket path"); exit(EXIT_FAILURE); } char *command = join_args(argv + optind, argc - optind); @@ -369,7 +368,7 @@ int main(int argc, char **argv) { if (getuid() != geteuid() || getgid() != getegid()) { // Retain capabilities after setuid() if (prctl(PR_SET_KEEPCAPS, 1, 0, 0, 0)) { - wlr_log(WLR_ERROR, "Cannot keep caps after setuid()"); + wlr_log(L_ERROR, "Cannot keep caps after setuid()"); exit(EXIT_FAILURE); } suid = true; @@ -390,7 +389,7 @@ int main(int argc, char **argv) { // prevent ipc from crashing sway signal(SIGPIPE, SIG_IGN); - wlr_log(WLR_INFO, "Starting sway version " SWAY_VERSION); + wlr_log(L_INFO, "Starting sway version " SWAY_VERSION); layout_init(); @@ -417,13 +416,12 @@ int main(int argc, char **argv) { security_sanity_check(); config->active = true; - setenv("WAYLAND_DISPLAY", server.socket, true); // Execute commands until there are none left while (config->cmd_queue->length) { char *line = config->cmd_queue->items[0]; struct cmd_results *res = execute_command(line, NULL); if (res->status != CMD_SUCCESS) { - wlr_log(WLR_ERROR, "Error on line '%s': %s", line, res->error); + wlr_log(L_ERROR, "Error on line '%s': %s", line, res->error); } free_cmd_results(res); free(line); @@ -434,15 +432,15 @@ int main(int argc, char **argv) { server_run(&server); } - wlr_log(WLR_INFO, "Shutting down sway"); + wlr_log(L_INFO, "Shutting down sway"); server_fini(&server); + ipc_terminate(); + if (config) { free_config(config); } - pango_cairo_font_map_set_default(NULL); - return exit_value; } diff --git a/sway/meson.build b/sway/meson.build index 721929179..9ff3f05f1 100644 --- a/sway/meson.build +++ b/sway/meson.build @@ -10,10 +10,8 @@ sway_sources = files( 'security.c', 'desktop/desktop.c', - 'desktop/idle_inhibit_v1.c', 'desktop/layer_shell.c', 'desktop/output.c', - 'desktop/render.c', 'desktop/transaction.c', 'desktop/xdg_shell_v6.c', 'desktop/xdg_shell.c', @@ -40,7 +38,6 @@ sway_sources = files( 'commands/exec.c', 'commands/exec_always.c', 'commands/floating.c', - 'commands/floating_minmax_size.c', 'commands/focus.c', 'commands/focus_follows_mouse.c', 'commands/focus_wrapping.c', diff --git a/sway/server.c b/sway/server.c index 1d8eb9640..f5700c09c 100644 --- a/sway/server.c +++ b/sway/server.c @@ -7,13 +7,12 @@ #include #include #include -#include #include #include #include #include +#include #include -#include #include #include #include @@ -22,27 +21,26 @@ // TODO WLR: make Xwayland optional #include "list.h" #include "sway/config.h" -#include "sway/desktop/idle_inhibit_v1.h" #include "sway/input/input-manager.h" #include "sway/server.h" #include "sway/tree/layout.h" #include "sway/xwayland.h" bool server_privileged_prepare(struct sway_server *server) { - wlr_log(WLR_DEBUG, "Preparing Wayland server initialization"); + wlr_log(L_DEBUG, "Preparing Wayland server initialization"); server->wl_display = wl_display_create(); server->wl_event_loop = wl_display_get_event_loop(server->wl_display); server->backend = wlr_backend_autocreate(server->wl_display, NULL); if (!server->backend) { - wlr_log(WLR_ERROR, "Unable to create backend"); + wlr_log(L_ERROR, "Unable to create backend"); return false; } return true; } bool server_init(struct sway_server *server) { - wlr_log(WLR_DEBUG, "Initializing Wayland server"); + wlr_log(L_DEBUG, "Initializing Wayland server"); struct wlr_renderer *renderer = wlr_backend_get_renderer(server->backend); assert(renderer); @@ -53,6 +51,7 @@ bool server_init(struct sway_server *server) { server->data_device_manager = wlr_data_device_manager_create(server->wl_display); + server->idle = wlr_idle_create(server->wl_display); wlr_screenshooter_create(server->wl_display); wlr_gamma_control_manager_create(server->wl_display); wlr_primary_selection_device_manager_create(server->wl_display); @@ -63,10 +62,6 @@ bool server_init(struct sway_server *server) { wlr_xdg_output_manager_create(server->wl_display, root_container.sway_root->output_layout); - server->idle = wlr_idle_create(server->wl_display); - server->idle_inhibit_manager_v1 = - sway_idle_inhibit_manager_v1_create(server->wl_display, server->idle); - server->layer_shell = wlr_layer_shell_create(server->wl_display); wl_signal_add(&server->layer_shell->events.new_surface, &server->layer_shell_surface); @@ -112,11 +107,10 @@ bool server_init(struct sway_server *server) { wlr_linux_dmabuf_create(server->wl_display, renderer); wlr_export_dmabuf_manager_v1_create(server->wl_display); - wlr_screencopy_manager_v1_create(server->wl_display); server->socket = wl_display_add_socket_auto(server->wl_display); if (!server->socket) { - wlr_log(WLR_ERROR, "Unable to open wayland socket"); + wlr_log(L_ERROR, "Unable to open wayland socket"); wlr_backend_destroy(server->backend); return false; } @@ -141,10 +135,11 @@ void server_fini(struct sway_server *server) { } void server_run(struct sway_server *server) { - wlr_log(WLR_INFO, "Running compositor on wayland display '%s'", + wlr_log(L_INFO, "Running compositor on wayland display '%s'", server->socket); + setenv("WAYLAND_DISPLAY", server->socket, true); if (!wlr_backend_start(server->backend)) { - wlr_log(WLR_ERROR, "Failed to start backend"); + wlr_log(L_ERROR, "Failed to start backend"); wlr_backend_destroy(server->backend); return; } diff --git a/sway/sway-input.5.scd b/sway/sway-input.5.scd index cf7a6385f..c07460b12 100644 --- a/sway/sway-input.5.scd +++ b/sway/sway-input.5.scd @@ -67,8 +67,8 @@ For more information on these xkb configuration options, see Enables or disables disable-while-typing for the specified input device. *input* events enabled|disabled|disabled\_on\_external\_mouse - Enables or disables send\_events for specified input device. (Disabling - send\_events disables the input device) + Enables or disables send_events for specified input device. (Disabling + send_events disables the input device) *input* left\_handed enabled|disabled Enables or disables left handed mode for specified input device. diff --git a/sway/sway.5.scd b/sway/sway.5.scd index c6eb5e6d7..70cd58563 100644 --- a/sway/sway.5.scd +++ b/sway/sway.5.scd @@ -92,12 +92,6 @@ They are expected to be used with *bindsym* or at runtime through *swaymsg*(1). *focus* output Moves focus to the named output. -*focus tiling* - Sets focus to the last focused tiling container. - -*focus floating* - Sets focus to the last focused floating container. - *focus* mode\_toggle Moves focus between the floating and tiled layers. @@ -369,11 +363,9 @@ The default colors are: affects spacing between views and the latter affects the space around each workspace. -*gaps* inner|outer all|workspace|current set|plus|minus +*gaps* inner|outer all|current set|plus|minus Changes the gaps for the _inner_ or _outer_ gap. _all_ changes the gaps for - all views or workspace, _workspace_ changes gaps for all views in current - workspace (or current workspace), and _current_ changes gaps for the current - view or workspace. + all workspaces and _current_ changes gaps for all views in current workspace. *hide\_edge\_borders* none|vertical|horizontal|both|smart Hides window borders adjacent to the screen edges. Default is _none_. @@ -419,12 +411,10 @@ The default colors are: *mode* Switches to the specified mode. The default mode _default_. -*mode* [--pango\_markup] *{* *}* +*mode* *{* *}* _commands..._ after *{* will be added to the specified mode. A newline is required between *{* and the first command, and *}* must be alone on a line. Only *bindsym* and *bindcode* commands are permitted in mode blocks. - If _--pango\_markup_ is given, then _mode_ will be interpreted as pango - markup. *mouse\_warping* output|none If _output_ is specified, the mouse will be moved to new outputs as you diff --git a/sway/tree/arrange.c b/sway/tree/arrange.c index bcc3ee9a5..a71302563 100644 --- a/sway/tree/arrange.c +++ b/sway/tree/arrange.c @@ -47,11 +47,11 @@ static void apply_horiz_layout(struct sway_container *parent) { double scale = parent->width / total_width; // Resize windows - wlr_log(WLR_DEBUG, "Arranging %p horizontally", parent); + wlr_log(L_DEBUG, "Arranging %p horizontally", parent); double child_x = parent->x; for (size_t i = 0; i < num_children; ++i) { struct sway_container *child = parent->children->items[i]; - wlr_log(WLR_DEBUG, + wlr_log(L_DEBUG, "Calculating arrangement for %p:%d (will scale %f by %f)", child, child->type, child->width, scale); child->x = child_x; @@ -99,11 +99,11 @@ static void apply_vert_layout(struct sway_container *parent) { double scale = parent_height / total_height; // Resize - wlr_log(WLR_DEBUG, "Arranging %p vertically", parent); + wlr_log(L_DEBUG, "Arranging %p vertically", parent); double child_y = parent->y + parent_offset; for (size_t i = 0; i < num_children; ++i) { struct sway_container *child = parent->children->items[i]; - wlr_log(WLR_DEBUG, + wlr_log(L_DEBUG, "Calculating arrangement for %p:%d (will scale %f by %f)", child, child->type, child->height, scale); child->x = parent->x; @@ -179,9 +179,19 @@ static void arrange_children_of(struct sway_container *parent, if (config->reloading) { return; } - wlr_log(WLR_DEBUG, "Arranging layout for %p %s %fx%f+%f,%f", parent, + wlr_log(L_DEBUG, "Arranging layout for %p %s %fx%f+%f,%f", parent, parent->name, parent->width, parent->height, parent->x, parent->y); + // Pass down gaps + for (int i = 0; i < parent->children->length && parent->has_gaps; ++i) { + struct sway_container *child = parent->children->items[i]; + if (!child->has_gaps) { + child->has_gaps = true; + child->gaps_inner = parent->gaps_inner; + child->gaps_outer = parent->gaps_outer; + } + } + // Calculate x, y, width and height of children switch (parent->layout) { case L_HORIZ: @@ -205,11 +215,6 @@ static void arrange_children_of(struct sway_container *parent, // Recurse into child containers for (int i = 0; i < parent->children->length; ++i) { struct sway_container *child = parent->children->items[i]; - if (parent->has_gaps && !child->has_gaps) { - child->has_gaps = true; - child->gaps_inner = parent->gaps_inner; - child->gaps_outer = parent->gaps_outer; - } if (child->type == C_VIEW) { view_autoconfigure(child->sway_view); } else { @@ -226,7 +231,7 @@ static void arrange_workspace(struct sway_container *workspace, } struct sway_container *output = workspace->parent; struct wlr_box *area = &output->sway_output->usable_area; - wlr_log(WLR_DEBUG, "Usable area for ws: %dx%d@%d,%d", + wlr_log(L_DEBUG, "Usable area for ws: %dx%d@%d,%d", area->width, area->height, area->x, area->y); remove_gaps(workspace); workspace->width = area->width; @@ -235,7 +240,7 @@ static void arrange_workspace(struct sway_container *workspace, workspace->y = output->y + area->y; add_gaps(workspace); transaction_add_container(transaction, workspace); - wlr_log(WLR_DEBUG, "Arranging workspace '%s' at %f, %f", workspace->name, + wlr_log(L_DEBUG, "Arranging workspace '%s' at %f, %f", workspace->name, workspace->x, workspace->y); arrange_floating(workspace->sway_workspace->floating, transaction); arrange_children_of(workspace, transaction); @@ -254,7 +259,7 @@ static void arrange_output(struct sway_container *output, output->width = output_box->width; output->height = output_box->height; transaction_add_container(transaction, output); - wlr_log(WLR_DEBUG, "Arranging output '%s' at %f,%f", + wlr_log(L_DEBUG, "Arranging output '%s' at %f,%f", output->name, output->x, output->y); for (int i = 0; i < output->children->length; ++i) { struct sway_container *workspace = output->children->items[i]; @@ -315,7 +320,7 @@ void arrange_and_commit(struct sway_container *container) { void remove_gaps(struct sway_container *c) { if (c->current_gaps == 0) { - wlr_log(WLR_DEBUG, "Removing gaps: not gapped: %p", c); + wlr_log(L_DEBUG, "Removing gaps: not gapped: %p", c); return; } @@ -326,21 +331,28 @@ void remove_gaps(struct sway_container *c) { c->current_gaps = 0; - wlr_log(WLR_DEBUG, "Removing gaps %p", c); + wlr_log(L_DEBUG, "Removing gaps %p", c); } void add_gaps(struct sway_container *c) { if (c->current_gaps > 0 || c->type == C_CONTAINER) { - wlr_log(WLR_DEBUG, "Not adding gaps: %p", c); + wlr_log(L_DEBUG, "Not adding gaps: %p", c); return; } - if (c->type == C_WORKSPACE && - !(config->edge_gaps || (config->smart_gaps && c->children->length > 1))) { - return; - } + double gaps = 0; - double gaps = c->has_gaps ? c->gaps_inner : config->gaps_inner; + if (c->type == C_WORKSPACE) { + if (!config->edge_gaps || (config->smart_gaps && c->children->length == 1)) { + return; + } + gaps = c->has_gaps ? c->gaps_outer : config->gaps_outer; + } else { + if (config->smart_gaps && container_parent(c, C_WORKSPACE)->children->length < 2) { + return; + } + gaps = c->has_gaps ? c->gaps_inner : config->gaps_inner; + } c->x += gaps; c->y += gaps; @@ -348,5 +360,5 @@ void add_gaps(struct sway_container *c) { c->height -= 2 * gaps; c->current_gaps = gaps; - wlr_log(WLR_DEBUG, "Adding gaps: %p", c); + wlr_log(L_DEBUG, "Adding gaps: %p", c); } diff --git a/sway/tree/container.c b/sway/tree/container.c index 588527173..6f6137c4a 100644 --- a/sway/tree/container.c +++ b/sway/tree/container.c @@ -11,14 +11,11 @@ #include "cairo.h" #include "pango.h" #include "sway/config.h" -#include "sway/desktop.h" -#include "sway/desktop/transaction.h" #include "sway/input/input-manager.h" #include "sway/input/seat.h" #include "sway/ipc-server.h" #include "sway/output.h" #include "sway/server.h" -#include "sway/tree/arrange.h" #include "sway/tree/layout.h" #include "sway/tree/view.h" #include "sway/tree/workspace.h" @@ -31,7 +28,7 @@ static list_t *get_bfs_queue() { if (!bfs_queue) { bfs_queue = create_list(); if (!bfs_queue) { - wlr_log(WLR_ERROR, "could not allocate list for bfs queue"); + wlr_log(L_ERROR, "could not allocate list for bfs queue"); return NULL; } } @@ -154,7 +151,6 @@ void container_free(struct sway_container *cont) { return; } free(cont->name); - free(cont->formatted_title); wlr_texture_destroy(cont->title_focused); wlr_texture_destroy(cont->title_focused_inactive); wlr_texture_destroy(cont->title_unfocused); @@ -213,7 +209,7 @@ static struct sway_container *container_workspace_destroy( return NULL; } - wlr_log(WLR_DEBUG, "destroying workspace '%s'", workspace->name); + wlr_log(L_DEBUG, "destroying workspace '%s'", workspace->name); struct sway_container *parent = workspace->parent; if (!workspace_is_empty(workspace) && output) { @@ -226,7 +222,7 @@ static struct sway_container *container_workspace_destroy( } } - wlr_log(WLR_DEBUG, "moving children to different workspace '%s' -> '%s'", + wlr_log(L_DEBUG, "moving children to different workspace '%s' -> '%s'", workspace->name, new_workspace->name); for (int i = 0; i < workspace->children->length; i++) { container_move_to(workspace->children->items[i], new_workspace); @@ -292,7 +288,7 @@ static struct sway_container *container_output_destroy( output->sway_output->swayc = NULL; output->sway_output = NULL; - wlr_log(WLR_DEBUG, "OUTPUT: Destroying output '%s'", output->name); + wlr_log(L_DEBUG, "OUTPUT: Destroying output '%s'", output->name); return &root_container; } @@ -319,7 +315,7 @@ static struct sway_container *container_destroy_noreaping( // Workspaces will refuse to be destroyed if they're the last workspace // on their output. if (!container_workspace_destroy(con)) { - wlr_log(WLR_ERROR, "workspace doesn't want to destroy"); + wlr_log(L_ERROR, "workspace doesn't want to destroy"); return NULL; } } @@ -346,7 +342,7 @@ bool container_reap_empty(struct sway_container *con) { break; case C_WORKSPACE: if (!workspace_is_visible(con) && workspace_is_empty(con)) { - wlr_log(WLR_DEBUG, "Destroying workspace via reaper"); + wlr_log(L_DEBUG, "Destroying workspace via reaper"); container_destroy_noreaping(con); return true; } @@ -439,7 +435,7 @@ struct sway_container *container_view_create(struct sway_container *sibling, } const char *title = view_get_title(sway_view); struct sway_container *swayc = container_create(C_VIEW); - wlr_log(WLR_DEBUG, "Adding new view %p:%s to container %p %d %s", + wlr_log(L_DEBUG, "Adding new view %p:%s to container %p %d %s", swayc, title, sibling, sibling ? sibling->type : 0, sibling->name); // Setup values swayc->sway_view = sway_view; @@ -702,7 +698,7 @@ void container_for_each_descendant_bfs(struct sway_container *con, } if (queue == NULL) { - wlr_log(WLR_ERROR, "could not allocate list"); + wlr_log(L_ERROR, "could not allocate list"); return; } @@ -786,7 +782,7 @@ static void update_title_texture(struct sway_container *con, double scale = output->sway_output->wlr_output->scale; int width = 0; - int height = con->title_height * scale; + int height = config->font_height * scale; cairo_t *c = cairo_create(NULL); get_text_size(c, config->font, &width, NULL, scale, config->pango_markup, @@ -939,7 +935,6 @@ void container_set_floating(struct sway_container *container, bool enable) { container_add_child(workspace->sway_workspace->floating, container); if (container->type == C_VIEW) { view_init_floating(container->sway_view); - view_set_tiled(container->sway_view, false); } seat_set_focus(seat, seat_get_focus_inactive(seat, container)); container_reap_empty_recursive(workspace); @@ -992,86 +987,3 @@ void container_get_box(struct sway_container *container, struct wlr_box *box) { box->width = container->width; box->height = container->height; } - -/** - * Translate the container's position as well as all children. - */ -static void container_floating_translate(struct sway_container *con, - double x_amount, double y_amount) { - con->x += x_amount; - con->y += y_amount; - con->current.swayc_x += x_amount; - con->current.swayc_y += y_amount; - if (con->type == C_VIEW) { - con->sway_view->x += x_amount; - con->sway_view->y += y_amount; - con->current.view_x += x_amount; - con->current.view_y += y_amount; - } else { - for (int i = 0; i < con->children->length; ++i) { - struct sway_container *child = con->children->items[i]; - container_floating_translate(child, x_amount, y_amount); - } - } -} - -/** - * Choose an output for the floating container's new position. - * - * If the center of the container intersects an output then we'll choose that - * one, otherwise we'll choose whichever output is closest to the container's - * center. - */ -static struct sway_container *container_floating_find_output( - struct sway_container *con) { - double center_x = con->x + con->width / 2; - double center_y = con->y + con->height / 2; - struct sway_container *closest_output = NULL; - double closest_distance = DBL_MAX; - for (int i = 0; i < root_container.children->length; ++i) { - struct sway_container *output = root_container.children->items[i]; - struct wlr_box output_box; - double closest_x, closest_y; - container_get_box(output, &output_box); - wlr_box_closest_point(&output_box, center_x, center_y, - &closest_x, &closest_y); - if (center_x == closest_x && center_y == closest_y) { - // The center of the floating container is on this output - return output; - } - double x_dist = closest_x - center_x; - double y_dist = closest_y - center_y; - double distance = x_dist * x_dist + y_dist * y_dist; - if (distance < closest_distance) { - closest_output = output; - closest_distance = distance; - } - } - return closest_output; -} - -void container_floating_move_to(struct sway_container *con, - double lx, double ly) { - if (!sway_assert(container_is_floating(con), - "Expected a floating container")) { - return; - } - desktop_damage_whole_container(con); - container_floating_translate(con, lx - con->x, ly - con->y); - desktop_damage_whole_container(con); - struct sway_container *old_workspace = container_parent(con, C_WORKSPACE); - struct sway_container *new_output = container_floating_find_output(con); - if (!sway_assert(new_output, "Unable to find any output")) { - return; - } - struct sway_container *new_workspace = - output_get_active_workspace(new_output->sway_output); - if (old_workspace != new_workspace) { - container_remove_child(con); - container_add_child(new_workspace->sway_workspace->floating, con); - struct sway_transaction *transaction = transaction_create(); - arrange_windows(old_workspace, transaction); - arrange_windows(new_workspace, transaction); - transaction_commit(transaction); - } -} diff --git a/sway/tree/layout.c b/sway/tree/layout.c index ba234e895..14631ad41 100644 --- a/sway/tree/layout.c +++ b/sway/tree/layout.c @@ -101,7 +101,7 @@ void container_insert_child(struct sway_container *parent, if (old_parent) { container_remove_child(child); } - wlr_log(WLR_DEBUG, "Inserting id:%zd at index %d", child->id, i); + wlr_log(L_DEBUG, "Inserting id:%zd at index %d", child->id, i); list_insert(parent->children, i, child); child->parent = parent; container_handle_fullscreen_reparent(child, old_parent); @@ -127,7 +127,7 @@ struct sway_container *container_add_sibling(struct sway_container *fixed, void container_add_child(struct sway_container *parent, struct sway_container *child) { - wlr_log(WLR_DEBUG, "Adding %p (%d, %fx%f) to %p (%d, %fx%f)", + wlr_log(L_DEBUG, "Adding %p (%d, %fx%f) to %p (%d, %fx%f)", child, child->type, child->width, child->height, parent, parent->type, parent->width, parent->height); struct sway_container *old_parent = child->parent; @@ -168,12 +168,7 @@ void container_move_to(struct sway_container *container, struct sway_container *old_parent = container_remove_child(container); container->width = container->height = 0; container->saved_width = container->saved_height = 0; - - struct sway_container *new_parent, *new_parent_focus; - struct sway_seat *seat = input_manager_get_default_seat(input_manager); - - // Get the focus of the destination before we change it. - new_parent_focus = seat_get_focus_inactive(seat, destination); + struct sway_container *new_parent; if (destination->type == C_VIEW) { new_parent = container_add_sibling(destination, container); } else { @@ -181,20 +176,17 @@ void container_move_to(struct sway_container *container, container_add_child(destination, container); } wl_signal_emit(&container->events.reparent, old_parent); - if (container->type == C_WORKSPACE) { // If moving a workspace to a new output, maybe create a new workspace // on the previous output + struct sway_seat *seat = input_manager_get_default_seat(input_manager); if (old_parent->children->length == 0) { char *ws_name = workspace_next_name(old_parent->name); - struct sway_container *ws = workspace_create(old_parent, ws_name); + struct sway_container *ws = + workspace_create(old_parent, ws_name); free(ws_name); seat_set_focus(seat, ws); } - - // Try to remove an empty workspace from the destination output. - container_reap_empty_recursive(new_parent_focus); - container_sort_workspaces(new_parent); seat_set_focus(seat, new_parent); workspace_output_raise_priority(container, old_parent, new_parent); @@ -319,13 +311,13 @@ static void move_out_of_tabs_stacks(struct sway_container *container, int offs) { if (container->parent == current->parent && current->parent->children->length == 1) { - wlr_log(WLR_DEBUG, "Changing layout of %zd", current->parent->id); + wlr_log(L_DEBUG, "Changing layout of %zd", current->parent->id); current->parent->layout = move_dir == MOVE_LEFT || move_dir == MOVE_RIGHT ? L_HORIZ : L_VERT; return; } - wlr_log(WLR_DEBUG, "Moving out of tab/stack into a split"); + wlr_log(L_DEBUG, "Moving out of tab/stack into a split"); bool is_workspace = current->parent->type == C_WORKSPACE; struct sway_container *new_parent = container_split(current->parent, move_dir == MOVE_LEFT || move_dir == MOVE_RIGHT ? L_HORIZ : L_VERT); @@ -370,7 +362,7 @@ void container_move(struct sway_container *container, } parent = current->parent; - wlr_log(WLR_DEBUG, "Visiting %p %s '%s'", current, + wlr_log(L_DEBUG, "Visiting %p %s '%s'", current, container_type_to_str(current->type), current->name); int index = index_child(current); @@ -388,12 +380,12 @@ void container_move(struct sway_container *container, root_container.sway_root->output_layout, wlr_dir, current->sway_output->wlr_output, ref_lx, ref_ly); if (!next) { - wlr_log(WLR_DEBUG, "Hit edge of output, nowhere else to go"); + wlr_log(L_DEBUG, "Hit edge of output, nowhere else to go"); return; } struct sway_output *next_output = next->data; current = next_output->swayc; - wlr_log(WLR_DEBUG, "Selected next output (%s)", current->name); + wlr_log(L_DEBUG, "Selected next output (%s)", current->name); // Select workspace and get outta here current = seat_get_focus_inactive( config->handler_context.seat, current); @@ -406,20 +398,20 @@ void container_move(struct sway_container *container, case C_WORKSPACE: if (!is_parallel(current->layout, move_dir)) { if (current->children->length >= 2) { - wlr_log(WLR_DEBUG, "Rejiggering the workspace (%d kiddos)", + wlr_log(L_DEBUG, "Rejiggering the workspace (%d kiddos)", current->children->length); workspace_rejigger(current, container, move_dir); return; } else { - wlr_log(WLR_DEBUG, "Selecting output"); + wlr_log(L_DEBUG, "Selecting output"); current = current->parent; } } else if (current->layout == L_TABBED || current->layout == L_STACKED) { - wlr_log(WLR_DEBUG, "Rejiggering out of tabs/stacks"); + wlr_log(L_DEBUG, "Rejiggering out of tabs/stacks"); workspace_rejigger(current, container, move_dir); } else { - wlr_log(WLR_DEBUG, "Selecting output"); + wlr_log(L_DEBUG, "Selecting output"); current = current->parent; } break; @@ -435,11 +427,11 @@ void container_move(struct sway_container *container, move_dir, offs); return; } else { - wlr_log(WLR_DEBUG, "Hit limit, selecting parent"); + wlr_log(L_DEBUG, "Hit limit, selecting parent"); current = current->parent; } } else { - wlr_log(WLR_DEBUG, "Hit limit, " + wlr_log(L_DEBUG, "Hit limit, " "promoting descendant to sibling"); // Special case container_insert_child(current->parent, container, @@ -449,14 +441,14 @@ void container_move(struct sway_container *container, } } else { sibling = parent->children->items[index + offs]; - wlr_log(WLR_DEBUG, "Selecting sibling id:%zd", sibling->id); + wlr_log(L_DEBUG, "Selecting sibling id:%zd", sibling->id); } } else if (parent->layout == L_TABBED || parent->layout == L_STACKED) { move_out_of_tabs_stacks(container, current, move_dir, offs); return; } else { - wlr_log(WLR_DEBUG, "Moving up to find a parallel container"); + wlr_log(L_DEBUG, "Moving up to find a parallel container"); current = current->parent; } break; @@ -475,11 +467,11 @@ void container_move(struct sway_container *container, switch (sibling->type) { case C_VIEW: if (sibling->parent == container->parent) { - wlr_log(WLR_DEBUG, "Swapping siblings"); + wlr_log(L_DEBUG, "Swapping siblings"); sibling->parent->children->items[index + offs] = container; sibling->parent->children->items[index] = sibling; } else { - wlr_log(WLR_DEBUG, "Promoting to sibling of cousin"); + wlr_log(L_DEBUG, "Promoting to sibling of cousin"); container_insert_child(sibling->parent, container, index_child(sibling) + (offs > 0 ? 0 : 1)); container->width = container->height = 0; @@ -490,31 +482,31 @@ void container_move(struct sway_container *container, case C_CONTAINER: if (is_parallel(sibling->layout, move_dir)) { int limit = container_limit(sibling, invert_movement(move_dir)); - wlr_log(WLR_DEBUG, "limit: %d", limit); - wlr_log(WLR_DEBUG, + wlr_log(L_DEBUG, "limit: %d", limit); + wlr_log(L_DEBUG, "Reparenting container (parallel) to index %d " "(move dir: %d)", limit, move_dir); container_insert_child(sibling, container, limit); container->width = container->height = 0; sibling = NULL; } else { - wlr_log(WLR_DEBUG, "Reparenting container (perpendicular)"); + wlr_log(L_DEBUG, "Reparenting container (perpendicular)"); struct sway_container *focus_inactive = seat_get_focus_inactive( config->handler_context.seat, sibling); if (focus_inactive && focus_inactive != sibling) { while (focus_inactive->parent != sibling) { focus_inactive = focus_inactive->parent; } - wlr_log(WLR_DEBUG, "Focus inactive: id:%zd", + wlr_log(L_DEBUG, "Focus inactive: id:%zd", focus_inactive->id); sibling = focus_inactive; continue; } else if (sibling->children->length) { - wlr_log(WLR_DEBUG, "No focus-inactive, adding arbitrarily"); + wlr_log(L_DEBUG, "No focus-inactive, adding arbitrarily"); container_remove_child(container); container_add_sibling(sibling->children->items[0], container); } else { - wlr_log(WLR_DEBUG, "No kiddos, adding container alone"); + wlr_log(L_DEBUG, "No kiddos, adding container alone"); container_remove_child(container); container_add_child(sibling, container); } @@ -611,7 +603,7 @@ static struct sway_container *get_swayc_in_output_direction( } if (ws == NULL) { - wlr_log(WLR_ERROR, "got an output without a workspace"); + wlr_log(L_ERROR, "got an output without a workspace"); return NULL; } @@ -783,7 +775,7 @@ struct sway_container *container_get_in_direction( } else { struct sway_container *desired_con = parent->children->items[desired]; - wlr_log(WLR_DEBUG, + wlr_log(L_DEBUG, "cont %d-%p dir %i sibling %d: %p", idx, container, dir, desired, desired_con); return seat_get_focus_inactive_view(seat, desired_con); @@ -848,7 +840,7 @@ struct sway_container *container_split(struct sway_container *child, struct sway_container *cont = container_create(C_CONTAINER); - wlr_log(WLR_DEBUG, "creating container %p around %p", cont, child); + wlr_log(L_DEBUG, "creating container %p around %p", cont, child); remove_gaps(child); @@ -896,7 +888,7 @@ struct sway_container *container_split(struct sway_container *child, void container_recursive_resize(struct sway_container *container, double amount, enum resize_edge edge) { bool layout_match = true; - wlr_log(WLR_DEBUG, "Resizing %p with amount: %f", container, amount); + wlr_log(L_DEBUG, "Resizing %p with amount: %f", container, amount); if (edge == RESIZE_EDGE_LEFT || edge == RESIZE_EDGE_RIGHT) { container->width += amount; layout_match = container->layout == L_HORIZ; @@ -986,7 +978,7 @@ void container_swap(struct sway_container *con1, struct sway_container *con2) { return; } - wlr_log(WLR_DEBUG, "Swapping containers %zu and %zu", con1->id, con2->id); + wlr_log(L_DEBUG, "Swapping containers %zu and %zu", con1->id, con2->id); int fs1 = con1->type == C_VIEW && con1->sway_view->is_fullscreen; int fs2 = con2->type == C_VIEW && con2->sway_view->is_fullscreen; diff --git a/sway/tree/output.c b/sway/tree/output.c index da535c180..e2927cdb7 100644 --- a/sway/tree/output.c +++ b/sway/tree/output.c @@ -43,11 +43,11 @@ struct sway_container *output_create( if (strcasecmp(name, cur->name) == 0 || strcasecmp(identifier, cur->name) == 0) { - wlr_log(WLR_DEBUG, "Matched output config for %s", name); + wlr_log(L_DEBUG, "Matched output config for %s", name); oc = cur; } if (strcasecmp("*", cur->name) == 0) { - wlr_log(WLR_DEBUG, "Matched wildcard output config for %s", name); + wlr_log(L_DEBUG, "Matched wildcard output config for %s", name); all = cur; } @@ -86,7 +86,7 @@ struct sway_container *output_create( if (!output->children->length) { // Create workspace char *ws_name = workspace_next_name(output->name); - wlr_log(WLR_DEBUG, "Creating default workspace %s", ws_name); + wlr_log(L_DEBUG, "Creating default workspace %s", ws_name); struct sway_container *ws = workspace_create(output, ws_name); // Set each seat's focus if not already set struct sway_seat *seat = NULL; diff --git a/sway/tree/view.c b/sway/tree/view.c index 20cbaf1c7..442e9984d 100644 --- a/sway/tree/view.c +++ b/sway/tree/view.c @@ -150,43 +150,12 @@ uint32_t view_configure(struct sway_view *view, double lx, double ly, int width, void view_init_floating(struct sway_view *view) { struct sway_container *ws = container_parent(view->swayc, C_WORKSPACE); - int min_width, min_height; - int max_width, max_height; - - if (config->floating_minimum_width == -1) { // no minimum - min_width = 0; - } else if (config->floating_minimum_width == 0) { // automatic - min_width = 75; - } else { - min_width = config->floating_minimum_width; - } - - if (config->floating_minimum_height == -1) { // no minimum - min_height = 0; - } else if (config->floating_minimum_height == 0) { // automatic - min_height = 50; - } else { - min_height = config->floating_minimum_height; - } - - if (config->floating_maximum_width == -1) { // no maximum - max_width = INT_MAX; - } else if (config->floating_maximum_width == 0) { // automatic - max_width = ws->width * 0.6666; - } else { - max_width = config->floating_maximum_width; - } - - if (config->floating_maximum_height == -1) { // no maximum - max_height = INT_MAX; - } else if (config->floating_maximum_height == 0) { // automatic - max_height = ws->height * 0.6666; - } else { - max_height = config->floating_maximum_height; - } - - view->width = fmax(min_width, fmin(view->natural_width, max_width)); - view->height = fmax(min_height, fmin(view->natural_height, max_height)); + int max_width = ws->width * 0.6666; + int max_height = ws->height * 0.6666; + view->width = + view->natural_width > max_width ? max_width : view->natural_width; + view->height = + view->natural_height > max_height ? max_height : view->natural_height; view->x = ws->x + (ws->width - view->width) / 2; view->y = ws->y + (ws->height - view->height) / 2; @@ -195,6 +164,9 @@ void view_init_floating(struct sway_view *view) { view->border_left = view->border_right = true; container_set_geometry_from_floating_view(view->swayc); + + // Don't maximize floating windows + view_set_tiled(view, false); } void view_autoconfigure(struct sway_view *view) { @@ -306,6 +278,7 @@ void view_autoconfigure(struct sway_view *view) { view->y = y; view->width = width; view->height = height; + view_set_tiled(view, true); } void view_set_activated(struct sway_view *view, bool activated) { @@ -493,17 +466,17 @@ void view_execute_criteria(struct sway_view *view) { list_t *criterias = criteria_for_view(view, CT_COMMAND); for (int i = 0; i < criterias->length; i++) { struct criteria *criteria = criterias->items[i]; - wlr_log(WLR_DEBUG, "Checking criteria %s", criteria->raw); + wlr_log(L_DEBUG, "Checking criteria %s", criteria->raw); if (view_has_executed_criteria(view, criteria)) { - wlr_log(WLR_DEBUG, "Criteria already executed"); + wlr_log(L_DEBUG, "Criteria already executed"); continue; } - wlr_log(WLR_DEBUG, "for_window '%s' matches view %p, cmd: '%s'", + wlr_log(L_DEBUG, "for_window '%s' matches view %p, cmd: '%s'", criteria->raw, view, criteria->cmdlist); list_add(view->executed_criteria, criteria); struct cmd_results *res = execute_command(criteria->cmdlist, NULL); if (res->status != CMD_SUCCESS) { - wlr_log(WLR_ERROR, "Command '%s' failed: %s", res->input, res->error); + wlr_log(L_ERROR, "Command '%s' failed: %s", res->input, res->error); } free_cmd_results(res); // view must be focused for commands to affect it, @@ -514,6 +487,26 @@ void view_execute_criteria(struct sway_view *view) { seat_set_focus(seat, prior_focus); } +void prepare_workspace_of_smart_gaps(struct sway_container *cont) { + struct sway_container *ws = cont; + if (ws->type != C_WORKSPACE) { + ws = container_parent(ws, C_WORKSPACE); + } + + if (!(config->smart_gaps && (ws->children->length == 1 || ws->children->length == 2))) { + return; + } + + for (int i = 0; i < ws->children->length; i++) { + struct sway_container *sibling = cont->parent->children->items[i]; + if (sibling == cont) continue; + container_damage_whole(sibling); + } + + remove_gaps(ws); + add_gaps(ws); +} + void view_map(struct sway_view *view, struct wlr_surface *wlr_surface) { if (!sway_assert(view->surface == NULL, "cannot map mapped view")) { return; @@ -545,7 +538,7 @@ void view_map(struct sway_view *view, struct wlr_surface *wlr_surface) { if (container_is_floating(focus)) { focus = focus->parent->parent; } - list_free(criterias); + free(criterias); cont = container_view_create(focus, view); view->surface = wlr_surface; @@ -564,7 +557,8 @@ void view_map(struct sway_view *view, struct wlr_surface *wlr_surface) { if (view->impl->wants_floating && view->impl->wants_floating(view)) { container_set_floating(view->swayc, true); } else { - view_set_tiled(view, true); + prepare_workspace_of_smart_gaps(cont); + arrange_and_commit(cont->parent); } input_manager_set_focus(input_manager, cont); @@ -593,6 +587,7 @@ void view_unmap(struct sway_view *view) { arrange_and_commit(ws->parent); } else { struct sway_container *parent = container_destroy(view->swayc); + prepare_workspace_of_smart_gaps(parent); arrange_and_commit(parent); } view->surface = NULL; @@ -605,8 +600,6 @@ void view_update_position(struct sway_view *view, double lx, double ly) { container_damage_whole(view->swayc); view->x = lx; view->y = ly; - view->swayc->current.view_x = lx; - view->swayc->current.view_y = ly; if (container_is_floating(view->swayc)) { container_set_geometry_from_floating_view(view->swayc); } @@ -620,8 +613,6 @@ void view_update_size(struct sway_view *view, int width, int height) { container_damage_whole(view->swayc); view->width = width; view->height = height; - view->swayc->current.view_width = width; - view->swayc->current.view_height = height; if (container_is_floating(view->swayc)) { container_set_geometry_from_floating_view(view->swayc); } @@ -632,7 +623,7 @@ static void view_subsurface_create(struct sway_view *view, struct wlr_subsurface *subsurface) { struct sway_view_child *child = calloc(1, sizeof(struct sway_view_child)); if (child == NULL) { - wlr_log(WLR_ERROR, "Allocation failed"); + wlr_log(L_ERROR, "Allocation failed"); return; } view_child_init(child, NULL, view, subsurface->surface); @@ -752,9 +743,8 @@ struct sway_view *view_from_wlr_surface(struct wlr_surface *wlr_surface) { return NULL; } - const char *role = wlr_surface->role ? wlr_surface->role->name : NULL; - wlr_log(WLR_DEBUG, "Surface of unknown type (role %s): %p", - role, wlr_surface); + wlr_log(L_DEBUG, "Surface of unknown type (role %s): %p", + wlr_surface->role, wlr_surface); return NULL; } @@ -821,7 +811,7 @@ static char *escape_title(char *buffer) { char *escaped_title = calloc(length + 1, sizeof(char)); int result = escape_markup_text(buffer, escaped_title, length); if (result != length) { - wlr_log(WLR_ERROR, "Could not escape title: %s", buffer); + wlr_log(L_ERROR, "Could not escape title: %s", buffer); free(escaped_title); return buffer; } @@ -955,7 +945,7 @@ static void update_marks_texture(struct sway_view *view, double scale = output->sway_output->wlr_output->scale; int width = 0; - int height = view->swayc->title_height * scale; + int height = config->font_height * scale; cairo_t *c = cairo_create(NULL); get_text_size(c, config->font, &width, NULL, scale, false, "%s", buffer); diff --git a/sway/tree/workspace.c b/sway/tree/workspace.c index 50f9400af..5eb4be0f0 100644 --- a/sway/tree/workspace.c +++ b/sway/tree/workspace.c @@ -49,7 +49,7 @@ struct sway_container *workspace_create(struct sway_container *output, output = get_workspace_initial_output(name); } - wlr_log(WLR_DEBUG, "Added workspace %s for output %s", name, output->name); + wlr_log(L_DEBUG, "Added workspace %s for output %s", name, output->name); struct sway_container *workspace = container_create(C_WORKSPACE); workspace->x = output->x; @@ -107,8 +107,9 @@ static bool workspace_valid_on_output(const char *output_name, } char *workspace_next_name(const char *output_name) { - wlr_log(WLR_DEBUG, "Workspace: Generating new workspace name for output %s", + wlr_log(L_DEBUG, "Workspace: Generating new workspace name for output %s", output_name); + int l = 1; // Scan all workspace bindings to find the next available workspace name, // if none are found/available then default to a number struct sway_mode *mode = config->current_mode; @@ -135,7 +136,7 @@ char *workspace_next_name(const char *output_name) { while (isspace(*_target)) { memmove(_target, _target+1, strlen(_target+1)); } - wlr_log(WLR_DEBUG, "Got valid workspace command for target: '%s'", + wlr_log(L_DEBUG, "Got valid workspace command for target: '%s'", _target); // Make sure that the command references an actual workspace @@ -161,7 +162,7 @@ char *workspace_next_name(const char *output_name) { temp[length - 1] = '\0'; free(_target); _target = temp; - wlr_log(WLR_DEBUG, "Isolated name from workspace number: '%s'", _target); + wlr_log(L_DEBUG, "Isolated name from workspace number: '%s'", _target); // Make sure the workspace number doesn't already exist if (workspace_by_number(_target)) { @@ -190,9 +191,7 @@ char *workspace_next_name(const char *output_name) { order = binding->order; free(target); target = _target; - wlr_log(WLR_DEBUG, "Workspace: Found free name %s", _target); - } else { - free(_target); + wlr_log(L_DEBUG, "Workspace: Found free name %s", _target); } } free(dup); @@ -203,9 +202,14 @@ char *workspace_next_name(const char *output_name) { // As a fall back, get the current number of active workspaces // and return that + 1 for the next workspace's name int ws_num = root_container.children->length; - int l = snprintf(NULL, 0, "%d", ws_num); + if (ws_num >= 10) { + l = 2; + } else if (ws_num >= 100) { + l = 3; + } char *name = malloc(l + 1); - if (!sway_assert(name, "Cloud not allocate workspace name")) { + if (!name) { + wlr_log(L_ERROR, "Could not allocate workspace name"); return NULL; } sprintf(name, "%d", ws_num++); @@ -267,9 +271,6 @@ struct sway_container *workspace_by_name(const char *name) { */ struct sway_container *workspace_output_prev_next_impl( struct sway_container *output, bool next) { - if (!output) { - return NULL; - } if (!sway_assert(output->type == C_OUTPUT, "Argument must be an output, is %d", output->type)) { return NULL; @@ -302,9 +303,6 @@ struct sway_container *workspace_output_prev_next_impl( */ struct sway_container *workspace_prev_next_impl( struct sway_container *workspace, bool next) { - if (!workspace) { - return NULL; - } if (!sway_assert(workspace->type == C_WORKSPACE, "Argument must be a workspace, is %d", workspace->type)) { return NULL; @@ -387,7 +385,7 @@ bool workspace_switch(struct sway_container *workspace) { free(prev_workspace_name); prev_workspace_name = malloc(strlen(active_ws->name) + 1); if (!prev_workspace_name) { - wlr_log(WLR_ERROR, "Unable to allocate previous workspace name"); + wlr_log(L_ERROR, "Unable to allocate previous workspace name"); return false; } strcpy(prev_workspace_name, active_ws->name); @@ -409,7 +407,7 @@ bool workspace_switch(struct sway_container *workspace) { } } - wlr_log(WLR_DEBUG, "Switching to workspace %p:%s", + wlr_log(L_DEBUG, "Switching to workspace %p:%s", workspace, workspace->name); struct sway_container *next = seat_get_focus_inactive(seat, workspace); if (next == NULL) { diff --git a/swaybar/bar.c b/swaybar/bar.c index f03c5aead..5b8028e5a 100644 --- a/swaybar/bar.c +++ b/swaybar/bar.c @@ -46,7 +46,7 @@ static void swaybar_output_free(struct swaybar_output *output) { if (!output) { return; } - wlr_log(WLR_DEBUG, "Removing output %s", output->name); + wlr_log(L_DEBUG, "Removing output %s", output->name); zwlr_layer_surface_v1_destroy(output->layer_surface); wl_surface_destroy(output->surface); wl_output_destroy(output->output); diff --git a/swaybar/i3bar.c b/swaybar/i3bar.c index 26f073c87..141612a67 100644 --- a/swaybar/i3bar.c +++ b/swaybar/i3bar.c @@ -31,7 +31,7 @@ static bool i3bar_parse_json(struct status_line *status, const char *text) { status_error(status, "[failed to parse i3bar json]"); return false; } - wlr_log(WLR_DEBUG, "Got i3bar json: '%s'", text); + wlr_log(L_DEBUG, "Got i3bar json: '%s'", text); for (size_t i = 0; i < json_object_array_length(results); ++i) { json_object *full_text, *short_text, *color, *min_width, *align, *urgent; json_object *name, *instance, *separator, *separator_block_width; @@ -193,7 +193,7 @@ bool i3bar_handle_readable(struct status_line *status) { void i3bar_block_send_click(struct status_line *status, struct i3bar_block *block, int x, int y, uint32_t button) { - wlr_log(WLR_DEBUG, "block %s clicked", block->name ? block->name : "(nil)"); + wlr_log(L_DEBUG, "block %s clicked", block->name ? block->name : "(nil)"); if (!block->name || !status->i3bar_state.click_events) { return; } diff --git a/swaybar/ipc.c b/swaybar/ipc.c index 08531f2a4..959fa0953 100644 --- a/swaybar/ipc.c +++ b/swaybar/ipc.c @@ -327,7 +327,7 @@ bool handle_ipc_readable(struct swaybar *bar) { json_object *result = json_tokener_parse(resp->payload); if (!result) { free_ipc_response(resp); - wlr_log(WLR_ERROR, "failed to parse payload as json"); + wlr_log(L_ERROR, "failed to parse payload as json"); return false; } json_object *json_change, *json_pango_markup; @@ -340,7 +340,7 @@ bool handle_ipc_readable(struct swaybar *bar) { bar->config->mode = strdup(change); } } else { - wlr_log(WLR_ERROR, "failed to parse response"); + wlr_log(L_ERROR, "failed to parse response"); json_object_put(result); free_ipc_response(resp); return false; diff --git a/swaybar/main.c b/swaybar/main.c index 60e4b37cb..c897e1c92 100644 --- a/swaybar/main.c +++ b/swaybar/main.c @@ -75,13 +75,13 @@ int main(int argc, char **argv) { } if (debug) { - wlr_log_init(WLR_DEBUG, NULL); + wlr_log_init(L_DEBUG, NULL); } else { - wlr_log_init(WLR_ERROR, NULL); + wlr_log_init(L_ERROR, NULL); } if (!bar_id) { - wlr_log(WLR_ERROR, "No bar_id passed. " + wlr_log(L_ERROR, "No bar_id passed. " "Provide --bar_id or let sway start swaybar"); return 1; } @@ -89,7 +89,7 @@ int main(int argc, char **argv) { if (!socket_path) { socket_path = get_socketpath(); if (!socket_path) { - wlr_log(WLR_ERROR, "Unable to retrieve socket path"); + wlr_log(L_ERROR, "Unable to retrieve socket path"); return 1; } } diff --git a/swaybar/render.c b/swaybar/render.c index 2ebd338e8..327a6f5fa 100644 --- a/swaybar/render.c +++ b/swaybar/render.c @@ -298,8 +298,7 @@ static uint32_t render_binding_mode_indicator(cairo_t *cairo, int text_width, text_height; get_text_size(cairo, config->font, &text_width, &text_height, - output->scale, config->mode_pango_markup, - "%s", mode); + output->scale, config->pango_markup, "%s", mode); int ws_vertical_padding = WS_VERTICAL_PADDING * output->scale; int ws_horizontal_padding = WS_HORIZONTAL_PADDING * output->scale; @@ -330,7 +329,7 @@ static uint32_t render_binding_mode_indicator(cairo_t *cairo, double text_y = height / 2.0 - text_height / 2.0; cairo_set_source_u32(cairo, config->colors.binding_mode.text); cairo_move_to(cairo, x + width / 2 - text_width / 2, (int)floor(text_y)); - pango_printf(cairo, config->font, output->scale, config->mode_pango_markup, + pango_printf(cairo, config->font, output->scale, config->pango_markup, "%s", mode); return surface_height; } @@ -497,7 +496,7 @@ void render_frame(struct swaybar *bar, struct swaybar_output *output) { // different height than what we asked for wl_surface_commit(output->surface); wl_display_roundtrip(bar->display); - } else if (height > 0) { + } else { // Replay recording into shm and send it off output->current_buffer = get_next_buffer(bar->shm, output->buffers, diff --git a/swaybar/status_line.c b/swaybar/status_line.c index bc47580b9..e0e7414ab 100644 --- a/swaybar/status_line.c +++ b/swaybar/status_line.c @@ -49,14 +49,14 @@ bool status_handle_readable(struct status_line *status) { json_object *version; if (json_object_object_get_ex(proto, "version", &version) && json_object_get_int(version) == 1) { - wlr_log(WLR_DEBUG, "Switched to i3bar protocol."); + wlr_log(L_DEBUG, "Switched to i3bar protocol."); status->protocol = PROTOCOL_I3BAR; } json_object *click_events; if (json_object_object_get_ex( proto, "click_events", &click_events) && json_object_get_boolean(click_events)) { - wlr_log(WLR_DEBUG, "Enabled click events."); + wlr_log(L_DEBUG, "Enabled click events."); status->i3bar_state.click_events = true; const char *events_array = "[\n"; ssize_t len = strlen(events_array); @@ -91,7 +91,7 @@ struct status_line *status_line_init(char *cmd) { int pipe_read_fd[2]; int pipe_write_fd[2]; if (pipe(pipe_read_fd) != 0 || pipe(pipe_write_fd) != 0) { - wlr_log(WLR_ERROR, "Unable to create pipes for status_command fork"); + wlr_log(L_ERROR, "Unable to create pipes for status_command fork"); exit(1); } diff --git a/swaybg/main.c b/swaybg/main.c index 1796b2453..5b6c378c3 100644 --- a/swaybg/main.c +++ b/swaybg/main.c @@ -48,7 +48,7 @@ struct swaybg_state { bool is_valid_color(const char *color) { int len = strlen(color); if (len != 7 || color[0] != '#') { - wlr_log(WLR_ERROR, "%s is not a valid color for swaybg. " + wlr_log(L_ERROR, "%s is not a valid color for swaybg. " "Color should be specified as #rrggbb (no alpha).", color); return false; } @@ -185,10 +185,10 @@ int main(int argc, const char **argv) { struct swaybg_args args = {0}; struct swaybg_state state = {0}; state.args = &args; - wlr_log_init(WLR_DEBUG, NULL); + wlr_log_init(L_DEBUG, NULL); if (argc != 4) { - wlr_log(WLR_ERROR, "Do not run this program manually. " + wlr_log(L_ERROR, "Do not run this program manually. " "See man 5 sway and look for output options."); return 1; } diff --git a/swayidle/main.c b/swayidle/main.c index 64e450364..7666578fd 100644 --- a/swayidle/main.c +++ b/swayidle/main.c @@ -59,24 +59,24 @@ static void cmd_exec(void *data) { return; } char *param = (char *)data; - wlr_log(WLR_DEBUG, "Cmd exec %s", param); + wlr_log(L_DEBUG, "Cmd exec %s", param); pid_t pid = fork(); if (pid == 0) { pid = fork(); if (pid == 0) { char *const cmd[] = { "sh", "-c", param, NULL, }; execvp(cmd[0], cmd); - wlr_log_errno(WLR_ERROR, "execve failed!"); + wlr_log_errno(L_ERROR, "execve failed!"); exit(1); } else if (pid < 0) { - wlr_log_errno(WLR_ERROR, "fork failed"); + wlr_log_errno(L_ERROR, "fork failed"); exit(1); } exit(0); } else if (pid < 0) { - wlr_log_errno(WLR_ERROR, "fork failed"); + wlr_log_errno(L_ERROR, "fork failed"); } else { - wlr_log(WLR_DEBUG, "Spawned process %s", param); + wlr_log(L_DEBUG, "Spawned process %s", param); waitpid(pid, NULL, 0); } } @@ -86,7 +86,7 @@ static int lock_fd = -1; static int ongoing_fd = -1; static int release_lock(void *data) { - wlr_log(WLR_INFO, "Releasing sleep lock %d", ongoing_fd); + wlr_log(L_INFO, "Releasing sleep lock %d", ongoing_fd); if (ongoing_fd >= 0) { close(ongoing_fd); } @@ -101,7 +101,7 @@ void acquire_sleep_lock() { int ret = sd_bus_default_system(&bus); if (ret < 0) { - wlr_log(WLR_ERROR, "Failed to open D-Bus connection: %s", + wlr_log(L_ERROR, "Failed to open D-Bus connection: %s", strerror(-ret)); return; } @@ -112,17 +112,17 @@ void acquire_sleep_lock() { &error, &msg, "ssss", "sleep", "swayidle", "Setup Up Lock Screen", "delay"); if (ret < 0) { - wlr_log(WLR_ERROR, "Failed to send Inhibit signal: %s", + wlr_log(L_ERROR, "Failed to send Inhibit signal: %s", strerror(-ret)); } else { ret = sd_bus_message_read(msg, "h", &lock_fd); if (ret < 0) { - wlr_log(WLR_ERROR, + wlr_log(L_ERROR, "Failed to parse D-Bus response for Inhibit: %s", strerror(-ret)); } } - wlr_log(WLR_INFO, "Got sleep lock: %d", lock_fd); + wlr_log(L_INFO, "Got sleep lock: %d", lock_fd); } static int prepare_for_sleep(sd_bus_message *msg, void *userdata, @@ -131,10 +131,10 @@ static int prepare_for_sleep(sd_bus_message *msg, void *userdata, int going_down = 1; int ret = sd_bus_message_read(msg, "b", &going_down); if (ret < 0) { - wlr_log(WLR_ERROR, "Failed to parse D-Bus response for Inhibit: %s", + wlr_log(L_ERROR, "Failed to parse D-Bus response for Inhibit: %s", strerror(-ret)); } - wlr_log(WLR_DEBUG, "PrepareForSleep signal received %d", going_down); + wlr_log(L_DEBUG, "PrepareForSleep signal received %d", going_down); if (!going_down) { acquire_sleep_lock(); return 0; @@ -151,7 +151,7 @@ static int prepare_for_sleep(sd_bus_message *msg, void *userdata, wl_event_loop_add_timer(state.event_loop, release_lock, NULL); wl_event_source_timer_update(source, 1000); } - wlr_log(WLR_DEBUG, "Prepare for sleep done"); + wlr_log(L_DEBUG, "Prepare for sleep done"); return 0; } @@ -168,7 +168,7 @@ void setup_sleep_listener() { int ret = sd_bus_default_system(&bus); if (ret < 0) { - wlr_log(WLR_ERROR, "Failed to open D-Bus connection: %s", + wlr_log(L_ERROR, "Failed to open D-Bus connection: %s", strerror(-ret)); return; } @@ -183,7 +183,7 @@ void setup_sleep_listener() { "/org/freedesktop/login1"); ret = sd_bus_add_match(bus, NULL, str, prepare_for_sleep, NULL); if (ret < 0) { - wlr_log(WLR_ERROR, "Failed to add D-Bus match: %s", strerror(-ret)); + wlr_log(L_ERROR, "Failed to add D-Bus match: %s", strerror(-ret)); return; } acquire_sleep_lock(); @@ -214,7 +214,7 @@ static const struct wl_registry_listener registry_listener = { static void handle_idle(void *data, struct org_kde_kwin_idle_timeout *timer) { struct swayidle_timeout_cmd *cmd = data; - wlr_log(WLR_DEBUG, "idle state"); + wlr_log(L_DEBUG, "idle state"); if (cmd && cmd->idle_cmd && cmd->idle_cmd->callback) { cmd->idle_cmd->callback(cmd->idle_cmd->param); } @@ -222,7 +222,7 @@ static void handle_idle(void *data, struct org_kde_kwin_idle_timeout *timer) { static void handle_resume(void *data, struct org_kde_kwin_idle_timeout *timer) { struct swayidle_timeout_cmd *cmd = data; - wlr_log(WLR_DEBUG, "active state"); + wlr_log(L_DEBUG, "active state"); if (cmd && cmd->resume_cmd && cmd->resume_cmd->callback) { cmd->resume_cmd->callback(cmd->resume_cmd->param); } @@ -235,12 +235,12 @@ static const struct org_kde_kwin_idle_timeout_listener idle_timer_listener = { struct swayidle_cmd *parse_command(int argc, char **argv) { if (argc < 1) { - wlr_log(WLR_ERROR, "Too few parameters for command in parse_command"); + wlr_log(L_ERROR, "Too few parameters for command in parse_command"); return NULL; } struct swayidle_cmd *cmd = calloc(1, sizeof(struct swayidle_cmd)); - wlr_log(WLR_DEBUG, "Command: %s", argv[0]); + wlr_log(L_DEBUG, "Command: %s", argv[0]); cmd->callback = cmd_exec; cmd->param = argv[0]; return cmd; @@ -248,7 +248,7 @@ struct swayidle_cmd *parse_command(int argc, char **argv) { int parse_timeout(int argc, char **argv) { if (argc < 3) { - wlr_log(WLR_ERROR, "Too few parameters to timeout command. " + wlr_log(L_ERROR, "Too few parameters to timeout command. " "Usage: timeout "); exit(-1); } @@ -256,7 +256,7 @@ int parse_timeout(int argc, char **argv) { char *endptr; int seconds = strtoul(argv[1], &endptr, 10); if (errno != 0 || *endptr != '\0') { - wlr_log(WLR_ERROR, "Invalid timeout parameter '%s', it should be a " + wlr_log(L_ERROR, "Invalid timeout parameter '%s', it should be a " "numeric value representing seconds", optarg); exit(-1); } @@ -264,13 +264,13 @@ int parse_timeout(int argc, char **argv) { calloc(1, sizeof(struct swayidle_timeout_cmd)); cmd->timeout = seconds * 1000; - wlr_log(WLR_DEBUG, "Register idle timeout at %d ms", cmd->timeout); - wlr_log(WLR_DEBUG, "Setup idle"); + wlr_log(L_DEBUG, "Register idle timeout at %d ms", cmd->timeout); + wlr_log(L_DEBUG, "Setup idle"); cmd->idle_cmd = parse_command(argc - 2, &argv[2]); int result = 3; if (argc >= 5 && !strcmp("resume", argv[3])) { - wlr_log(WLR_DEBUG, "Setup resume"); + wlr_log(L_DEBUG, "Setup resume"); cmd->resume_cmd = parse_command(argc - 4, &argv[4]); result = 5; } @@ -280,14 +280,14 @@ int parse_timeout(int argc, char **argv) { int parse_sleep(int argc, char **argv) { if (argc < 2) { - wlr_log(WLR_ERROR, "Too few parameters to before-sleep command. " + wlr_log(L_ERROR, "Too few parameters to before-sleep command. " "Usage: before-sleep "); exit(-1); } lock_cmd = parse_command(argc - 1, &argv[1]); if (lock_cmd) { - wlr_log(WLR_DEBUG, "Setup sleep lock: %s", lock_cmd->param); + wlr_log(L_DEBUG, "Setup sleep lock: %s", lock_cmd->param); } return 2; @@ -314,10 +314,10 @@ int parse_args(int argc, char *argv[]) { } if (debug) { - wlr_log_init(WLR_DEBUG, NULL); - wlr_log(WLR_DEBUG, "Loglevel debug"); + wlr_log_init(L_DEBUG, NULL); + wlr_log(L_DEBUG, "Loglevel debug"); } else { - wlr_log_init(WLR_INFO, NULL); + wlr_log_init(L_INFO, NULL); } @@ -326,13 +326,13 @@ int parse_args(int argc, char *argv[]) { int i = optind; while (i < argc) { if (!strcmp("timeout", argv[i])) { - wlr_log(WLR_DEBUG, "Got timeout"); + wlr_log(L_DEBUG, "Got timeout"); i += parse_timeout(argc - i, &argv[i]); } else if (!strcmp("before-sleep", argv[i])) { - wlr_log(WLR_DEBUG, "Got before-sleep"); + wlr_log(L_DEBUG, "Got before-sleep"); i += parse_sleep(argc - i, &argv[i]); } else { - wlr_log(WLR_ERROR, "Unsupported command '%s'", argv[i]); + wlr_log(L_ERROR, "Unsupported command '%s'", argv[i]); exit(-1); } } @@ -358,7 +358,7 @@ static int display_event(int fd, uint32_t mask, void *data) { sway_terminate(0); } if (wl_display_dispatch(state.display) < 0) { - wlr_log_errno(WLR_ERROR, "wl_display_dispatch failed, exiting"); + wlr_log_errno(L_ERROR, "wl_display_dispatch failed, exiting"); sway_terminate(0); }; return 0; @@ -367,7 +367,7 @@ static int display_event(int fd, uint32_t mask, void *data) { void register_idle_timeout(void *item) { struct swayidle_timeout_cmd *cmd = item; if (cmd == NULL || !cmd->timeout) { - wlr_log(WLR_ERROR, "Invalid idle cmd, will not register"); + wlr_log(L_ERROR, "Invalid idle cmd, will not register"); return; } state.idle_timer = @@ -376,7 +376,7 @@ void register_idle_timeout(void *item) { org_kde_kwin_idle_timeout_add_listener(state.idle_timer, &idle_timer_listener, cmd); } else { - wlr_log(WLR_ERROR, "Could not create idle timer"); + wlr_log(L_ERROR, "Could not create idle timer"); } } @@ -390,7 +390,7 @@ int main(int argc, char *argv[]) { state.display = wl_display_connect(NULL); if (state.display == NULL) { - wlr_log(WLR_ERROR, "Failed to create display"); + wlr_log(L_ERROR, "Failed to create display"); return -3; } @@ -401,11 +401,11 @@ int main(int argc, char *argv[]) { state.event_loop = wl_event_loop_create(); if (idle_manager == NULL) { - wlr_log(WLR_ERROR, "Display doesn't support idle protocol"); + wlr_log(L_ERROR, "Display doesn't support idle protocol"); return -4; } if (seat == NULL) { - wlr_log(WLR_ERROR, "Seat error"); + wlr_log(L_ERROR, "Seat error"); return -5; } @@ -417,7 +417,7 @@ int main(int argc, char *argv[]) { } #endif if (!should_run) { - wlr_log(WLR_INFO, "No command specified! Nothing to do, will exit"); + wlr_log(L_INFO, "No command specified! Nothing to do, will exit"); sway_terminate(0); } list_foreach(state.timeout_cmds, register_idle_timeout); diff --git a/swaylock/main.c b/swaylock/main.c index faebc757e..591df7b4f 100644 --- a/swaylock/main.c +++ b/swaylock/main.c @@ -34,16 +34,14 @@ void sway_terminate(int exit_code) { static void daemonize() { int fds[2]; if (pipe(fds) != 0) { - wlr_log(WLR_ERROR, "Failed to pipe"); + wlr_log(L_ERROR, "Failed to pipe"); exit(1); } if (fork() == 0) { - setsid(); close(fds[0]); int devnull = open("/dev/null", O_RDWR); dup2(STDOUT_FILENO, devnull); dup2(STDERR_FILENO, devnull); - close(devnull); uint8_t success = 0; if (chdir("/") != 0) { write(fds[1], &success, 1); @@ -58,7 +56,7 @@ static void daemonize() { close(fds[1]); uint8_t success; if (read(fds[0], &success, 1) != 1 || !success) { - wlr_log(WLR_ERROR, "Failed to daemonize"); + wlr_log(L_ERROR, "Failed to daemonize"); exit(1); } close(fds[0]); @@ -85,13 +83,6 @@ static const struct zwlr_layer_surface_v1_listener layer_surface_listener; static cairo_surface_t *select_image(struct swaylock_state *state, struct swaylock_surface *surface); -static bool surface_is_opaque(struct swaylock_surface *surface) { - if (surface->image) { - return cairo_surface_get_content(surface->image) == CAIRO_CONTENT_COLOR; - } - return (surface->state->args.colors.background & 0xff) == 0xff; -} - static void create_layer_surface(struct swaylock_surface *surface) { struct swaylock_state *state = surface->state; @@ -116,17 +107,6 @@ static void create_layer_surface(struct swaylock_surface *surface) { surface->layer_surface, true); zwlr_layer_surface_v1_add_listener(surface->layer_surface, &layer_surface_listener, surface); - - if (surface_is_opaque(surface) && - surface->state->args.mode != BACKGROUND_MODE_CENTER && - surface->state->args.mode != BACKGROUND_MODE_FIT) { - struct wl_region *region = - wl_compositor_create_region(surface->state->compositor); - wl_region_add(region, 0, 0, INT32_MAX, INT32_MAX); - wl_surface_set_opaque_region(surface->surface, region); - wl_region_destroy(region); - } - wl_surface_commit(surface->surface); } @@ -238,7 +218,7 @@ static void handle_xdg_output_logical_position(void *data, static void handle_xdg_output_name(void *data, struct zxdg_output_v1 *output, const char *name) { - wlr_log(WLR_DEBUG, "output name is %s", name); + wlr_log(L_DEBUG, "output name is %s", name); struct swaylock_surface *surface = data; surface->xdg_output = output; surface->output_name = strdup(name); @@ -354,10 +334,10 @@ static void load_image(char *arg, struct swaylock_state *state) { } if (exists) { if (image->output_name) { - wlr_log(WLR_ERROR, "Multiple images defined for output %s", + wlr_log(L_ERROR, "Multiple images defined for output %s", image->output_name); } else { - wlr_log(WLR_ERROR, "Multiple default images defined"); + wlr_log(L_ERROR, "Multiple default images defined"); } } @@ -377,229 +357,63 @@ static void load_image(char *arg, struct swaylock_state *state) { } wl_list_insert(&state->images, &image->link); state->args.mode = BACKGROUND_MODE_FILL; - wlr_log(WLR_DEBUG, "Loaded image %s for output %s", + wlr_log(L_DEBUG, "Loaded image %s for output %s", image->path, image->output_name ? image->output_name : "*"); } -static void set_default_colors(struct swaylock_colors *colors) { - colors->background = 0xFFFFFFFF; - colors->bs_highlight = 0xDB3300FF; - colors->key_highlight = 0x33DB00FF; - colors->separator = 0x000000FF; - colors->inside = (struct swaylock_colorset){ - .input = 0x000000C0, - .cleared = 0xE5A445C0, - .verifying = 0x0072FFC0, - .wrong = 0xFA0000C0, - }; - colors->line = (struct swaylock_colorset){ - .input = 0x000000FF, - .cleared = 0x000000FF, - .verifying = 0x000000FF, - .wrong = 0x000000FF, - }; - colors->ring = (struct swaylock_colorset){ - .input = 0x337D00FF, - .cleared = 0xE5A445FF, - .verifying = 0x3300FFFF, - .wrong = 0x7D3300FF, - }; - colors->text = (struct swaylock_colorset){ - .input = 0xE5A445FF, - .cleared = 0x000000FF, - .verifying = 0x000000FF, - .wrong = 0x000000FF, - }; -} - static struct swaylock_state state; int main(int argc, char **argv) { - enum line_mode { - LM_LINE, - LM_INSIDE, - LM_RING, - }; - - enum long_option_codes { - LO_BS_HL_COLOR = 256, - LO_FONT, - LO_IND_RADIUS, - LO_IND_THICKNESS, - LO_INSIDE_COLOR, - LO_INSIDE_CLEAR_COLOR, - LO_INSIDE_VER_COLOR, - LO_INSIDE_WRONG_COLOR, - LO_KEY_HL_COLOR, - LO_LINE_COLOR, - LO_LINE_CLEAR_COLOR, - LO_LINE_VER_COLOR, - LO_LINE_WRONG_COLOR, - LO_RING_COLOR, - LO_RING_CLEAR_COLOR, - LO_RING_VER_COLOR, - LO_RING_WRONG_COLOR, - LO_SEP_COLOR, - LO_TEXT_COLOR, - LO_TEXT_CLEAR_COLOR, - LO_TEXT_VER_COLOR, - LO_TEXT_WRONG_COLOR, - }; - static struct option long_options[] = { - {"color", required_argument, NULL, 'c'}, - {"ignore-empty-password", no_argument, NULL, 'e'}, - {"daemonize", no_argument, NULL, 'f'}, {"help", no_argument, NULL, 'h'}, + {"color", required_argument, NULL, 'c'}, {"image", required_argument, NULL, 'i'}, - {"line-uses-inside", no_argument, NULL, 'n'}, - {"socket", required_argument, NULL, 'p'}, - {"line-uses-ring", no_argument, NULL, 'r'}, {"scaling", required_argument, NULL, 's'}, {"tiling", no_argument, NULL, 't'}, - {"no-unlock-indicator", no_argument, NULL, 'u'}, {"version", no_argument, NULL, 'v'}, - {"bs-hl-color", required_argument, NULL, LO_BS_HL_COLOR}, - {"font", required_argument, NULL, LO_FONT}, - {"indicator-radius", required_argument, NULL, LO_IND_RADIUS}, - {"indicator-thickness", required_argument, NULL, LO_IND_THICKNESS}, - {"inside-color", required_argument, NULL, LO_INSIDE_COLOR}, - {"inside-clear-color", required_argument, NULL, LO_INSIDE_CLEAR_COLOR}, - {"inside-ver-color", required_argument, NULL, LO_INSIDE_VER_COLOR}, - {"inside-wrong-color", required_argument, NULL, LO_INSIDE_WRONG_COLOR}, - {"key-hl-color", required_argument, NULL, LO_KEY_HL_COLOR}, - {"line-color", required_argument, NULL, LO_LINE_COLOR}, - {"line-clear-color", required_argument, NULL, LO_LINE_CLEAR_COLOR}, - {"line-ver-color", required_argument, NULL, LO_LINE_VER_COLOR}, - {"line-wrong-color", required_argument, NULL, LO_LINE_WRONG_COLOR}, - {"ring-color", required_argument, NULL, LO_RING_COLOR}, - {"ring-clear-color", required_argument, NULL, LO_RING_CLEAR_COLOR}, - {"ring-ver-color", required_argument, NULL, LO_RING_VER_COLOR}, - {"ring-wrong-color", required_argument, NULL, LO_RING_WRONG_COLOR}, - {"separator-color", required_argument, NULL, LO_SEP_COLOR}, - {"text-color", required_argument, NULL, LO_TEXT_COLOR}, - {"text-clear-color", required_argument, NULL, LO_TEXT_CLEAR_COLOR}, - {"text-ver-color", required_argument, NULL, LO_TEXT_VER_COLOR}, - {"text-wrong-color", required_argument, NULL, LO_TEXT_WRONG_COLOR}, + {"socket", required_argument, NULL, 'p'}, + {"no-unlock-indicator", no_argument, NULL, 'u'}, + {"daemonize", no_argument, NULL, 'f'}, {0, 0, 0, 0} }; const char usage[] = "Usage: swaylock [options...]\n" "\n" - " -c, --color " - "Turn the screen into the given color instead of white.\n" - " -e, --ignore-empty-password " - "When an empty password is provided, do not validate it.\n" - " -f, --daemonize " - "Detach from the controlling terminal after locking.\n" - " -h, --help " - "Show help message and quit.\n" - " -i, --image [:] " - "Display the given image.\n" - " -s, --scaling " - "Scaling mode: stretch, fill, fit, center, tile.\n" - " -t, --tiling " - "Same as --scaling=tile.\n" - " -u, --no-unlock-indicator " - "Disable the unlock indicator.\n" - " -v, --version " - "Show the version number and quit.\n" - " --bs-hl-color " - "Sets the color of backspace highlight segments.\n" - " --font " - "Sets the font of the text.\n" - " --indicator-radius " - "Sets the indicator radius.\n" - " --indicator-thickness " - "Sets the indicator thickness.\n" - " --inside-color " - "Sets the color of the inside of the indicator.\n" - " --inside-clear-color " - "Sets the color of the inside of the indicator when cleared.\n" - " --inside-ver-color " - "Sets the color of the inside of the indicator when verifying.\n" - " --inside-wrong-color " - "Sets the color of the inside of the indicator when invalid.\n" - " --key-hl-color " - "Sets the color of the key press highlight segments.\n" - " --line-color " - "Sets the color of the line between the inside and ring.\n" - " --line-clear-color " - "Sets the color of the line between the inside and ring when " - "cleared.\n" - " --line-ver-color " - "Sets the color of the line between the inside and ring when " - "verifying.\n" - " --line-wrong-color " - "Sets the color of the line between the inside and ring when " - "invalid.\n" - " -n, --line-uses-inside " - "Use the inside color for the line between the inside and ring.\n" - " -r, --line-uses-ring " - "Use the ring color for the line between the inside and ring.\n" - " --ring-color " - "Sets the color of the ring of the indicator.\n" - " --ring-clear-color " - "Sets the color of the ring of the indicator when cleared.\n" - " --ring-ver-color " - "Sets the color of the ring of the indicator when verifying.\n" - " --ring-wrong-color " - "Sets the color of the ring of the indicator when invalid.\n" - " --separator-color " - "Sets the color of the lines that separate highlight segments.\n" - " --text-color " - "Sets the color of the text.\n" - " --text-clear-color " - "Sets the color of the text when cleared.\n" - " --text-ver-color " - "Sets the color of the text when verifying.\n" - " --text-wrong-color " - "Sets the color of the text when invalid.\n" - "\n" - "All options are of the form .\n"; + " -h, --help Show help message and quit.\n" + " -c, --color Turn the screen into the given color instead of white.\n" + " -s, --scaling Scaling mode: stretch, fill, fit, center, tile.\n" + " -t, --tiling Same as --scaling=tile.\n" + " -v, --version Show the version number and quit.\n" + " -i, --image [:] Display the given image.\n" + " -u, --no-unlock-indicator Disable the unlock indicator.\n" + " -f, --daemonize Detach from the controlling terminal.\n"; - enum line_mode line_mode = LM_LINE; state.args = (struct swaylock_args){ .mode = BACKGROUND_MODE_SOLID_COLOR, - .font = strdup("sans-serif"), - .radius = 50, - .thickness = 10, - .ignore_empty = false, + .color = 0xFFFFFFFF, .show_indicator = true, }; wl_list_init(&state.images); - set_default_colors(&state.args.colors); - wlr_log_init(WLR_DEBUG, NULL); + wlr_log_init(L_DEBUG, NULL); int c; while (1) { - int opt_idx = 0; - c = getopt_long(argc, argv, "c:efhi:nrs:tuv", long_options, &opt_idx); + int option_index = 0; + c = getopt_long(argc, argv, "hc:i:s:tvuf", long_options, &option_index); if (c == -1) { break; } switch (c) { - case 'c': - state.args.colors.background = parse_color(optarg); + case 'c': { + state.args.color = parse_color(optarg); state.args.mode = BACKGROUND_MODE_SOLID_COLOR; break; - case 'e': - state.args.ignore_empty = true; - break; - case 'f': - state.args.daemonize = true; - break; + } case 'i': load_image(optarg, &state); break; - case 'n': - line_mode = LM_INSIDE; - break; - case 'r': - line_mode = LM_RING; - break; case 's': state.args.mode = parse_background_mode(optarg); if (state.args.mode == BACKGROUND_MODE_INVALID) { @@ -609,9 +423,6 @@ int main(int argc, char **argv) { case 't': state.args.mode = BACKGROUND_MODE_TILE; break; - case 'u': - state.args.show_indicator = false; - break; case 'v': #if defined SWAY_GIT_VERSION && defined SWAY_GIT_BRANCH && defined SWAY_VERSION_DATE fprintf(stdout, "swaylock version %s (%s, branch \"%s\")\n", @@ -620,72 +431,11 @@ int main(int argc, char **argv) { fprintf(stdout, "version unknown\n"); #endif return 0; - case LO_BS_HL_COLOR: - state.args.colors.bs_highlight = parse_color(optarg); + case 'u': + state.args.show_indicator = false; break; - case LO_FONT: - free(state.args.font); - state.args.font = strdup(optarg); - break; - case LO_IND_RADIUS: - state.args.radius = strtol(optarg, NULL, 0); - break; - case LO_IND_THICKNESS: - state.args.thickness = strtol(optarg, NULL, 0); - break; - case LO_INSIDE_COLOR: - state.args.colors.inside.input = parse_color(optarg); - break; - case LO_INSIDE_CLEAR_COLOR: - state.args.colors.inside.cleared = parse_color(optarg); - break; - case LO_INSIDE_VER_COLOR: - state.args.colors.inside.verifying = parse_color(optarg); - break; - case LO_INSIDE_WRONG_COLOR: - state.args.colors.inside.wrong = parse_color(optarg); - break; - case LO_KEY_HL_COLOR: - state.args.colors.key_highlight = parse_color(optarg); - break; - case LO_LINE_COLOR: - state.args.colors.line.input = parse_color(optarg); - break; - case LO_LINE_CLEAR_COLOR: - state.args.colors.line.cleared = parse_color(optarg); - break; - case LO_LINE_VER_COLOR: - state.args.colors.line.verifying = parse_color(optarg); - break; - case LO_LINE_WRONG_COLOR: - state.args.colors.line.wrong = parse_color(optarg); - break; - case LO_RING_COLOR: - state.args.colors.ring.input = parse_color(optarg); - break; - case LO_RING_CLEAR_COLOR: - state.args.colors.ring.cleared = parse_color(optarg); - break; - case LO_RING_VER_COLOR: - state.args.colors.ring.verifying = parse_color(optarg); - break; - case LO_RING_WRONG_COLOR: - state.args.colors.ring.wrong = parse_color(optarg); - break; - case LO_SEP_COLOR: - state.args.colors.separator = parse_color(optarg); - break; - case LO_TEXT_COLOR: - state.args.colors.text.input = parse_color(optarg); - break; - case LO_TEXT_CLEAR_COLOR: - state.args.colors.text.cleared = parse_color(optarg); - break; - case LO_TEXT_VER_COLOR: - state.args.colors.text.verifying = parse_color(optarg); - break; - case LO_TEXT_WRONG_COLOR: - state.args.colors.text.wrong = parse_color(optarg); + case 'f': + daemonize(); break; default: fprintf(stderr, "%s", usage); @@ -693,12 +443,6 @@ int main(int argc, char **argv) { } } - if (line_mode == LM_INSIDE) { - state.args.colors.line = state.args.colors.inside; - } else if (line_mode == LM_RING) { - state.args.colors.line = state.args.colors.ring; - } - #ifdef __linux__ // Most non-linux platforms require root to mlock() if (mlock(state.password.buffer, sizeof(state.password.buffer)) != 0) { @@ -716,13 +460,13 @@ int main(int argc, char **argv) { wl_display_roundtrip(state.display); assert(state.compositor && state.layer_shell && state.shm); if (!state.input_inhibit_manager) { - wlr_log(WLR_ERROR, "Compositor does not support the input inhibitor " + wlr_log(L_ERROR, "Compositor does not support the input inhibitor " "protocol, refusing to run insecurely"); return 1; } if (wl_list_empty(&state.surfaces)) { - wlr_log(WLR_DEBUG, "Exiting - no outputs to show on."); + wlr_log(L_DEBUG, "Exiting - no outputs to show on."); return 0; } @@ -738,7 +482,7 @@ int main(int argc, char **argv) { } wl_display_roundtrip(state.display); } else { - wlr_log(WLR_INFO, "Compositor does not support zxdg output manager, " + wlr_log(L_INFO, "Compositor does not support zxdg output manager, " "images assigned to named outputs will not work"); } @@ -747,16 +491,9 @@ int main(int argc, char **argv) { create_layer_surface(surface); } - if (state.args.daemonize) { - wl_display_roundtrip(state.display); - daemonize(); - } - state.run_display = true; while (wl_display_dispatch(state.display) != -1 && state.run_display) { // This space intentionally left blank } - - free(state.args.font); return 0; } diff --git a/swaylock/password.c b/swaylock/password.c index 7c686b344..bb32286e4 100644 --- a/swaylock/password.c +++ b/swaylock/password.c @@ -53,15 +53,15 @@ static bool attempt_password(struct swaylock_password *pw) { // TODO: only call pam_start once. keep the same handle the whole time if ((pam_err = pam_start("swaylock", username, &local_conversation, &local_auth_handle)) != PAM_SUCCESS) { - wlr_log(WLR_ERROR, "PAM returned error %d", pam_err); + wlr_log(L_ERROR, "PAM returned error %d", pam_err); } if ((pam_err = pam_authenticate(local_auth_handle, 0)) != PAM_SUCCESS) { - wlr_log(WLR_ERROR, "pam_authenticate failed"); + wlr_log(L_ERROR, "pam_authenticate failed"); goto fail; } // TODO: only call pam_end once we succeed at authing. refresh tokens beforehand if ((pam_err = pam_end(local_auth_handle, pam_err)) != PAM_SUCCESS) { - wlr_log(WLR_ERROR, "pam_end failed"); + wlr_log(L_ERROR, "pam_end failed"); goto fail; } clear_password_buffer(pw); @@ -95,26 +95,9 @@ void swaylock_handle_key(struct swaylock_state *state, switch (keysym) { case XKB_KEY_KP_Enter: /* fallthrough */ case XKB_KEY_Return: - if (state->args.ignore_empty && state->password.len == 0) { - break; - } - state->auth_state = AUTH_STATE_VALIDATING; damage_state(state); - while (wl_display_dispatch(state->display) != -1 && state->run_display) { - bool ok = 1; - struct swaylock_surface *surface; - wl_list_for_each(surface, &state->surfaces, link) { - if (surface->dirty) { - ok = 0; - } - } - if (ok) { - break; - } - } - wl_display_flush(state->display); - + wl_display_roundtrip(state->display); if (attempt_password(&state->password)) { state->run_display = false; break; diff --git a/swaylock/render.c b/swaylock/render.c index 66c55965d..2032ddcf3 100644 --- a/swaylock/render.c +++ b/swaylock/render.c @@ -7,22 +7,11 @@ #include "swaylock/swaylock.h" #define M_PI 3.14159265358979323846 +const int ARC_RADIUS = 50; +const int ARC_THICKNESS = 10; const float TYPE_INDICATOR_RANGE = M_PI / 3.0f; const float TYPE_INDICATOR_BORDER_THICKNESS = M_PI / 128.0f; -static void set_color_for_state(cairo_t *cairo, struct swaylock_state *state, - struct swaylock_colorset *colorset) { - if (state->auth_state == AUTH_STATE_VALIDATING) { - cairo_set_source_u32(cairo, colorset->verifying); - } else if (state->auth_state == AUTH_STATE_INVALID) { - cairo_set_source_u32(cairo, colorset->wrong); - } else if (state->auth_state == AUTH_STATE_CLEAR) { - cairo_set_source_u32(cairo, colorset->cleared); - } else { - cairo_set_source_u32(cairo, colorset->input); - } -} - void render_frame(struct swaylock_surface *surface) { struct swaylock_state *state = surface->state; @@ -41,37 +30,58 @@ void render_frame(struct swaylock_surface *surface) { cairo_t *cairo = surface->current_buffer->cairo; cairo_identity_matrix(cairo); - cairo_save(cairo); - cairo_set_operator(cairo, CAIRO_OPERATOR_SOURCE); if (state->args.mode == BACKGROUND_MODE_SOLID_COLOR || !surface->image) { - cairo_set_source_u32(cairo, state->args.colors.background); + cairo_set_source_u32(cairo, state->args.color); cairo_paint(cairo); } else { render_background_image(cairo, surface->image, state->args.mode, buffer_width, buffer_height); } - cairo_restore(cairo); cairo_identity_matrix(cairo); - int arc_radius = state->args.radius * surface->scale; - int arc_thickness = state->args.thickness * surface->scale; + int arc_radius = ARC_RADIUS * surface->scale; + int arc_thickness = ARC_THICKNESS * surface->scale; float type_indicator_border_thickness = TYPE_INDICATOR_BORDER_THICKNESS * surface->scale; if (state->args.show_indicator && state->auth_state != AUTH_STATE_IDLE) { // Draw circle cairo_set_line_width(cairo, arc_thickness); - cairo_arc(cairo, buffer_width / 2, buffer_height / 2, arc_radius, - 0, 2 * M_PI); - set_color_for_state(cairo, state, &state->args.colors.inside); - cairo_fill_preserve(cairo); - set_color_for_state(cairo, state, &state->args.colors.ring); - cairo_stroke(cairo); + cairo_arc(cairo, buffer_width / 2, buffer_height / 2, arc_radius, 0, 2 * M_PI); + switch (state->auth_state) { + case AUTH_STATE_INPUT: + case AUTH_STATE_INPUT_NOP: + case AUTH_STATE_BACKSPACE: { + cairo_set_source_rgba(cairo, 0, 0, 0, 0.75); + cairo_fill_preserve(cairo); + cairo_set_source_rgb(cairo, 51.0 / 255, 125.0 / 255, 0); + cairo_stroke(cairo); + } break; + case AUTH_STATE_VALIDATING: { + cairo_set_source_rgba(cairo, 0, 114.0 / 255, 255.0 / 255, 0.75); + cairo_fill_preserve(cairo); + cairo_set_source_rgb(cairo, 51.0 / 255, 0, 250.0 / 255); + cairo_stroke(cairo); + } break; + case AUTH_STATE_INVALID: { + cairo_set_source_rgba(cairo, 250.0 / 255, 0, 0, 0.75); + cairo_fill_preserve(cairo); + cairo_set_source_rgb(cairo, 125.0 / 255, 51.0 / 255, 0); + cairo_stroke(cairo); + } break; + case AUTH_STATE_CLEAR: { + cairo_set_source_rgba(cairo, 229.0/255, 164.0/255, 69.0/255, 0.75); + cairo_fill_preserve(cairo); + cairo_set_source_rgb(cairo, 229.0/255, 164.0/255, 69.0/255); + cairo_stroke(cairo); + } break; + default: break; + } // Draw a message char *text = NULL; - set_color_for_state(cairo, state, &state->args.colors.text); - cairo_select_font_face(cairo, state->args.font, + cairo_set_source_rgb(cairo, 0, 0, 0); + cairo_select_font_face(cairo, "sans-serif", CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_NORMAL); cairo_set_font_size(cairo, arc_radius / 3.0f); switch (state->auth_state) { @@ -88,10 +98,9 @@ void render_frame(struct swaylock_surface *surface) { case AUTH_STATE_INPUT_NOP: if (state->xkb.caps_lock) { text = "Caps Lock"; + cairo_set_source_rgb(cairo, 229.0/255, 164.0/255, 69.0/255); } - break; - default: - break; + default: break; } if (text) { @@ -119,14 +128,14 @@ void render_frame(struct swaylock_surface *surface) { arc_radius, highlight_start, highlight_start + TYPE_INDICATOR_RANGE); if (state->auth_state == AUTH_STATE_INPUT) { - cairo_set_source_u32(cairo, state->args.colors.key_highlight); + cairo_set_source_rgb(cairo, 51.0 / 255, 219.0 / 255, 0); } else { - cairo_set_source_u32(cairo, state->args.colors.bs_highlight); + cairo_set_source_rgb(cairo, 219.0 / 255, 51.0 / 255, 0); } cairo_stroke(cairo); // Draw borders - cairo_set_source_u32(cairo, state->args.colors.separator); + cairo_set_source_rgb(cairo, 0, 0, 0); cairo_arc(cairo, buffer_width / 2, buffer_height / 2, arc_radius, highlight_start, highlight_start + type_indicator_border_thickness); @@ -140,7 +149,7 @@ void render_frame(struct swaylock_surface *surface) { } // Draw inner + outer border of the circle - set_color_for_state(cairo, state, &state->args.colors.line); + cairo_set_source_rgb(cairo, 0, 0, 0); cairo_set_line_width(cairo, 2.0 * surface->scale); cairo_arc(cairo, buffer_width / 2, buffer_height / 2, arc_radius - arc_thickness / 2, 0, 2 * M_PI); diff --git a/swaylock/seat.c b/swaylock/seat.c index c2630d87d..6c66d2203 100644 --- a/swaylock/seat.c +++ b/swaylock/seat.c @@ -12,13 +12,13 @@ static void keyboard_keymap(void *data, struct wl_keyboard *wl_keyboard, struct swaylock_state *state = data; if (format != WL_KEYBOARD_KEYMAP_FORMAT_XKB_V1) { close(fd); - wlr_log(WLR_ERROR, "Unknown keymap format %d, aborting", format); + wlr_log(L_ERROR, "Unknown keymap format %d, aborting", format); exit(1); } char *map_shm = mmap(NULL, size, PROT_READ, MAP_SHARED, fd, 0); if (map_shm == MAP_FAILED) { close(fd); - wlr_log(WLR_ERROR, "Unable to initialize keymap shm, aborting"); + wlr_log(L_ERROR, "Unable to initialize keymap shm, aborting"); exit(1); } struct xkb_keymap *keymap = xkb_keymap_new_from_string( diff --git a/swaylock/swaylock.1.scd b/swaylock/swaylock.1.scd index eea62c2a7..35d6444cd 100644 --- a/swaylock/swaylock.1.scd +++ b/swaylock/swaylock.1.scd @@ -12,25 +12,23 @@ Locks your Wayland session. # OPTIONS +*-h, --help* + Show help message and quit. + *-c, --color* Turn the screen into the given color. If -i is used, this sets the background of the image to the given color. Defaults to white (FFFFFF), or transparent (00000000) if an image is in use. -*-e, --ignore-empty-password* - When an empty password is provided by the user, do not validate it. - *-f, --daemonize* - Detach from the controlling terminal after locking. - -*-h, --help* - Show help message and quit. + Fork into the background after spawning. Note: this is the default behavior + of i3lock. *-i, --image* [:] Display the given image, optionally only on the given output. Use -c to set a background color. -*-s, --scaling* +*--scaling* Scaling mode for images: _stretch_, _fill_, _fit_, _center_, or _tile_. *-t, --tiling* @@ -44,12 +42,51 @@ Locks your Wayland session. # APPEARANCE -*--bs-hl-color* +*--bshlcolor* Sets the color of backspace highlight segments. *--font* Sets the font of the text inside the indicator. +*--insidecolor* + Sets the color of the inside of the indicator when typing or idle. + +*--insidevercolor* + Sets the color of the inside of the indicator when verifying. + +*--insidewrongcolor* + Sets the color of the inside of the indicator when invalid. + +*--keyhlcolor* + Sets the color of keypress highlight segments. + +*--linecolor* + Sets the color of the lines that separate the inside and outside of the + indicator. + +*-s, --line-uses-inside* + Use the color of the inside of the indicator for the line separating the + inside and outside of the indicator. + +*-r, --line-uses-ring* + Use the outer ring's color for the line separating the inside and outside of + the indicator. + +*--ringcolor* + Sets the color of the outside of the indicator when typing or idle. + +*--ringvercolor* + Sets the color of the outside of the indicator when verifying. + +*--ringwrongcolor* + Sets the color of the outside of the indicator when invalid. + +*--separatorcolor* + Sets the color of the lines that seperate highlight segments. + +*--textcolor* + Sets the color of the text inside the indicator. + *--indicator-radius* Sets the radius of the indicator to _radius_ pixels. The default value is 50. @@ -58,72 +95,6 @@ Locks your Wayland session. Sets the thickness of the indicator to _thickness_ pixels. The default value is 10. -*--inside-color* - Sets the color of the inside of the indicator when typing or idle. - -*--inside-clear-color* - Sets the color of the inside of the indicator when cleared. - -*--inside-ver-color* - Sets the color of the inside of the indicator when verifying. - -*--inside-wrong-color* - Sets the color of the inside of the indicator when invalid. - -*--key-hl-color* - Sets the color of key press highlight segments. - -*--line-color* - Sets the color of the lines that separate the inside and outside of the - indicator when typing or idle. - -*--line-clear-color* - Sets the color of the lines that separate the inside and outside of the - indicator when cleared. - -*--line-ver-color* - Sets the color of the lines that separate the inside and outside of the - indicator when verifying. - -*--line-wrong-color* - Sets the color of the lines that separate the inside and outside of the - indicator when invalid. - -*-n, --line-uses-inside* - Use the color of the inside of the indicator for the line separating the - inside and outside of the indicator. - -*-r, --line-uses-ring* - Use the outer ring's color for the line separating the inside and outside of - the indicator. - -*--ring-color* - Sets the color of the outside of the indicator when typing or idle. - -*--ring-clear-color* - Sets the color of the outside of the indicator when cleared. - -*--ring-ver-color* - Sets the color of the outside of the indicator when verifying. - -*--ring-wrong-color* - Sets the color of the outside of the indicator when invalid. - -*--separator-color* - Sets the color of the lines that separate highlight segments. - -*--text-color* - Sets the color of the text inside the indicator when typing or idle. - -*--text-clear-color* - Sets the color of the text inside the indicator when cleared. - -*--text-ver-color* - Sets the color of the text inside the indicator when verifying. - -*--text-wrong-color* - Sets the color of the text inside the indicator when invalid. - # AUTHORS Maintained by Drew DeVault , who is assisted by other open diff --git a/swaymsg/main.c b/swaymsg/main.c index c4141ca57..4283bf00c 100644 --- a/swaymsg/main.c +++ b/swaymsg/main.c @@ -240,17 +240,44 @@ static void pretty_print_version(json_object *v) { printf("sway version %s\n", json_object_get_string(ver)); } -static void pretty_print_config(json_object *c) { - json_object *config; - json_object_object_get_ex(c, "config", &config); - printf("%s\n", json_object_get_string(config)); +static void pretty_print_clipboard(json_object *v) { + if (success(v, true)) { + if (json_object_is_type(v, json_type_array)) { + for (size_t i = 0; i < json_object_array_length(v); ++i) { + json_object *o = json_object_array_get_idx(v, i); + printf("%s\n", json_object_get_string(o)); + } + } else { + // NOTE: could be extended to print all received types + // instead just the first one when sways ipc server + // supports it + struct json_object_iterator iter = json_object_iter_begin(v); + struct json_object_iterator end = json_object_iter_end(v); + if (!json_object_iter_equal(&iter, &end)) { + json_object *obj = json_object_iter_peek_value(&iter); + if (success(obj, false)) { + json_object *content; + json_object_object_get_ex(obj, "content", &content); + printf("%s\n", json_object_get_string(content)); + } else { + json_object *error; + json_object_object_get_ex(obj, "error", &error); + printf("Error: %s\n", json_object_get_string(error)); + } + } + } + } else { + json_object *error; + json_object_object_get_ex(v, "error", &error); + printf("Error: %s\n", json_object_get_string(error)); + } } static void pretty_print(int type, json_object *resp) { if (type != IPC_COMMAND && type != IPC_GET_WORKSPACES && type != IPC_GET_INPUTS && type != IPC_GET_OUTPUTS && - type != IPC_GET_VERSION && type != IPC_GET_SEATS && - type != IPC_GET_CONFIG) { + type != IPC_GET_VERSION && type != IPC_GET_CLIPBOARD && + type != IPC_GET_SEATS) { printf("%s\n", json_object_to_json_string_ext(resp, JSON_C_TO_STRING_PRETTY | JSON_C_TO_STRING_SPACED)); return; @@ -261,8 +288,8 @@ static void pretty_print(int type, json_object *resp) { return; } - if (type == IPC_GET_CONFIG) { - pretty_print_config(resp); + if (type == IPC_GET_CLIPBOARD) { + pretty_print_clipboard(resp); return; } @@ -296,7 +323,7 @@ int main(int argc, char **argv) { char *socket_path = NULL; char *cmdtype = NULL; - wlr_log_init(WLR_INFO, NULL); + wlr_log_init(L_INFO, NULL); static struct option long_options[] = { {"help", no_argument, NULL, 'h'}, @@ -380,10 +407,8 @@ int main(int argc, char **argv) { type = IPC_GET_BAR_CONFIG; } else if (strcasecmp(cmdtype, "get_version") == 0) { type = IPC_GET_VERSION; - } else if (strcasecmp(cmdtype, "get_binding_modes") == 0) { - type = IPC_GET_BINDING_MODES; - } else if (strcasecmp(cmdtype, "get_config") == 0) { - type = IPC_GET_CONFIG; + } else if (strcasecmp(cmdtype, "get_clipboard") == 0) { + type = IPC_GET_CLIPBOARD; } else { sway_abort("Unknown message type %s", cmdtype); } diff --git a/swaymsg/swaymsg.1.scd b/swaymsg/swaymsg.1.scd index a6e279da9..1aa6a1b09 100644 --- a/swaymsg/swaymsg.1.scd +++ b/swaymsg/swaymsg.1.scd @@ -59,8 +59,8 @@ _swaymsg_ [options...] [message] *get\_version* Get JSON-encoded version information for the running instance of sway. -*get\_binding\_modes* - Gets a JSON-encoded list of currently configured binding modes. - -*get\_config* - Gets a JSON-encoded copy of the current configuration. +*get\_clipboard* + Get JSON-encoded information about the clipboard. + Returns the current clipboard mime-types if called without + arguments, otherwise returns the clipboard data in the requested + formats. Encodes the data using base64 for non-text mime types.