aboutsummaryrefslogtreecommitdiff
path: root/sway
diff options
context:
space:
mode:
Diffstat (limited to 'sway')
-rw-r--r--sway/config.c7
-rw-r--r--sway/config/input.c10
-rw-r--r--sway/config/seat.c11
-rw-r--r--sway/input/input-manager.c7
-rw-r--r--sway/input/seat.c7
-rw-r--r--sway/old/border.c510
-rw-r--r--sway/old/commands.c686
-rw-r--r--sway/old/commands/assign.c57
-rw-r--r--sway/old/commands/bar.c59
-rw-r--r--sway/old/commands/bar/activate_button.c26
-rw-r--r--sway/old/commands/bar/binding_mode_indicator.c27
-rw-r--r--sway/old/commands/bar/bindsym.c48
-rw-r--r--sway/old/commands/bar/colors.c129
-rw-r--r--sway/old/commands/bar/context_button.c26
-rw-r--r--sway/old/commands/bar/font.c26
-rw-r--r--sway/old/commands/bar/height.c21
-rw-r--r--sway/old/commands/bar/hidden_state.c79
-rw-r--r--sway/old/commands/bar/icon_theme.c25
-rw-r--r--sway/old/commands/bar/id.c33
-rw-r--r--sway/old/commands/bar/mode.c81
-rw-r--r--sway/old/commands/bar/modifier.c35
-rw-r--r--sway/old/commands/bar/output.c50
-rw-r--r--sway/old/commands/bar/pango_markup.c27
-rw-r--r--sway/old/commands/bar/position.c33
-rw-r--r--sway/old/commands/bar/secondary_button.c26
-rw-r--r--sway/old/commands/bar/separator_symbol.c21
-rw-r--r--sway/old/commands/bar/status_command.c21
-rw-r--r--sway/old/commands/bar/strip_workspace_numbers.c27
-rw-r--r--sway/old/commands/bar/swaybar_command.c21
-rw-r--r--sway/old/commands/bar/tray_output.c29
-rw-r--r--sway/old/commands/bar/tray_padding.c34
-rw-r--r--sway/old/commands/bar/workspace_buttons.c27
-rw-r--r--sway/old/commands/bar/wrap_scroll.c27
-rw-r--r--sway/old/commands/bind.c170
-rw-r--r--sway/old/commands/border.c65
-rw-r--r--sway/old/commands/client.c72
-rw-r--r--sway/old/commands/clipboard.c38
-rw-r--r--sway/old/commands/commands.c26
-rw-r--r--sway/old/commands/debuglog.c27
-rw-r--r--sway/old/commands/default_border.c44
-rw-r--r--sway/old/commands/default_floating_border.c45
-rw-r--r--sway/old/commands/exec.c16
-rw-r--r--sway/old/commands/exec_always.c85
-rw-r--r--sway/old/commands/exit.c17
-rw-r--r--sway/old/commands/floating.c81
-rw-r--r--sway/old/commands/floating_maximum_size.c38
-rw-r--r--sway/old/commands/floating_minimum_size.c38
-rw-r--r--sway/old/commands/floating_mod.c42
-rw-r--r--sway/old/commands/floating_scroll.c46
-rw-r--r--sway/old/commands/focus.c100
-rw-r--r--sway/old/commands/focus_follows_mouse.c13
-rw-r--r--sway/old/commands/font.c27
-rw-r--r--sway/old/commands/for_window.c41
-rw-r--r--sway/old/commands/force_focus_wrapping.c13
-rw-r--r--sway/old/commands/fullscreen.c60
-rw-r--r--sway/old/commands/gaps.c166
-rw-r--r--sway/old/commands/hide_edge_borders.c27
-rw-r--r--sway/old/commands/include.c15
-rw-r--r--sway/old/commands/input.c55
-rw-r--r--sway/old/commands/input/accel_profile.c27
-rw-r--r--sway/old/commands/input/click_method.c30
-rw-r--r--sway/old/commands/input/drag_lock.c26
-rw-r--r--sway/old/commands/input/dwt.c26
-rw-r--r--sway/old/commands/input/events.c30
-rw-r--r--sway/old/commands/input/left_handed.c26
-rw-r--r--sway/old/commands/input/middle_emulation.c26
-rw-r--r--sway/old/commands/input/natural_scroll.c26
-rw-r--r--sway/old/commands/input/pointer_accel.c24
-rw-r--r--sway/old/commands/input/scroll_method.c30
-rw-r--r--sway/old/commands/input/tap.c29
-rw-r--r--sway/old/commands/ipc.c162
-rw-r--r--sway/old/commands/kill.c12
-rw-r--r--sway/old/commands/layout.c196
-rw-r--r--sway/old/commands/log_colors.c22
-rw-r--r--sway/old/commands/mark.c87
-rw-r--r--sway/old/commands/mode.c57
-rw-r--r--sway/old/commands/mouse_warping.c17
-rw-r--r--sway/old/commands/move.c189
-rw-r--r--sway/old/commands/new_float.c8
-rw-r--r--sway/old/commands/new_window.c8
-rw-r--r--sway/old/commands/no_focus.c41
-rw-r--r--sway/old/commands/orientation.c21
-rw-r--r--sway/old/commands/output.c219
-rw-r--r--sway/old/commands/permit.c108
-rw-r--r--sway/old/commands/reload.c19
-rw-r--r--sway/old/commands/resize.c375
-rw-r--r--sway/old/commands/scratchpad.c72
-rw-r--r--sway/old/commands/seamless_mouse.c13
-rw-r--r--sway/old/commands/set.c61
-rw-r--r--sway/old/commands/show_marks.c13
-rw-r--r--sway/old/commands/smart_gaps.c20
-rw-r--r--sway/old/commands/split.c98
-rw-r--r--sway/old/commands/sticky.c25
-rw-r--r--sway/old/commands/unmark.c31
-rw-r--r--sway/old/commands/workspace.c92
-rw-r--r--sway/old/commands/workspace_auto_back_and_forth.c18
-rw-r--r--sway/old/commands/workspace_layout.c40
-rw-r--r--sway/old/config.c1313
-rw-r--r--sway/old/container.c1024
-rw-r--r--sway/old/criteria.c451
-rw-r--r--sway/old/focus.c278
-rw-r--r--sway/old/handlers.c1143
-rw-r--r--sway/old/input_state.c490
-rw-r--r--sway/old/ipc-json.c521
-rw-r--r--sway/old/ipc-server.c840
-rw-r--r--sway/old/layout.c1773
-rw-r--r--sway/old/output.c278
-rw-r--r--sway/old/security.c228
-rw-r--r--sway/old/workspace.c373
109 files changed, 35 insertions, 14621 deletions
diff --git a/sway/config.c b/sway/config.c
index 2683d6bc..1fd123b7 100644
--- a/sway/config.c
+++ b/sway/config.c
@@ -86,7 +86,12 @@ void free_config(struct sway_config *config) {
}
list_free(config->input_configs);
}
- list_free(config->seat_configs);
+ if (config->seat_configs) {
+ for (i = 0; i < config->seat_configs->length; i++) {
+ free_seat_config(config->seat_configs->items[i]);
+ }
+ list_free(config->seat_configs);
+ }
list_free(config->criteria);
list_free(config->no_focus);
list_free(config->active_bar_modifiers);
diff --git a/sway/config/input.c b/sway/config/input.c
index 96181302..c4f6211d 100644
--- a/sway/config/input.c
+++ b/sway/config/input.c
@@ -90,6 +90,16 @@ 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(L_ERROR, "could not allocate input config");
+ return NULL;
+ }
+ merge_input_config(copy, ic);
+ return copy;
+}
+
void free_input_config(struct input_config *ic) {
if (!ic) {
return;
diff --git a/sway/config/seat.c b/sway/config/seat.c
index 03cc6d4e..bd8b45c8 100644
--- a/sway/config/seat.c
+++ b/sway/config/seat.c
@@ -99,6 +99,17 @@ void merge_seat_config(struct seat_config *dest, struct seat_config *source) {
}
}
+struct seat_config *copy_seat_config(struct seat_config *seat) {
+ struct seat_config *copy = new_seat_config(seat->name);
+ if (copy == NULL) {
+ return NULL;
+ }
+
+ merge_seat_config(copy, seat);
+
+ return copy;
+}
+
void free_seat_config(struct seat_config *seat) {
if (!seat) {
return;
diff --git a/sway/input/input-manager.c b/sway/input/input-manager.c
index 7b19991b..2d119cf2 100644
--- a/sway/input/input-manager.c
+++ b/sway/input/input-manager.c
@@ -174,7 +174,8 @@ static void input_add_notify(struct wl_listener *listener, void *data) {
for (int i = 0; i < config->input_configs->length; ++i) {
struct input_config *input_config = config->input_configs->items[i];
if (strcmp(input_config->identifier, input_device->identifier) == 0) {
- input_device->config = input_config;
+ free_input_config(input_device->config);
+ input_device->config = copy_input_config(input_config);
break;
}
}
@@ -240,6 +241,7 @@ static void input_remove_notify(struct wl_listener *listener, void *data) {
}
wl_list_remove(&input_device->link);
+ free_input_config(input_device->config);
free(input_device->identifier);
free(input_device);
}
@@ -293,7 +295,8 @@ void sway_input_manager_apply_input_config(struct sway_input_manager *input,
struct sway_input_device *input_device = NULL;
wl_list_for_each(input_device, &input->devices, link) {
if (strcmp(input_device->identifier, input_config->identifier) == 0) {
- input_device->config = input_config;
+ free_input_config(input_device->config);
+ input_device->config = copy_input_config(input_config);
if (input_device->wlr_device->type == WLR_INPUT_DEVICE_POINTER) {
sway_input_manager_libinput_config_pointer(input_device);
diff --git a/sway/input/seat.c b/sway/input/seat.c
index ae6dc7c4..e9b375e0 100644
--- a/sway/input/seat.c
+++ b/sway/input/seat.c
@@ -241,6 +241,7 @@ void sway_seat_set_focus(struct sway_seat *seat, swayc_t *container) {
void sway_seat_set_config(struct sway_seat *seat,
struct seat_config *seat_config) {
// clear configs
+ free_seat_config(seat->config);
seat->config = NULL;
struct sway_seat_device *seat_device = NULL;
@@ -253,11 +254,9 @@ void sway_seat_set_config(struct sway_seat *seat,
}
// add configs
- seat->config = seat_config;
+ seat->config = copy_seat_config(seat_config);
wl_list_for_each(seat_device, &seat->devices, link) {
- seat_device->attachment_config =
- seat_config_get_attachment(seat_config,
- seat_device->input_device->identifier);
+ sway_seat_configure_device(seat, seat_device->input_device);
}
}
diff --git a/sway/old/border.c b/sway/old/border.c
deleted file mode 100644
index df0022ce..00000000
--- a/sway/old/border.c
+++ /dev/null
@@ -1,510 +0,0 @@
-#define _XOPEN_SOURCE 700
-#include <wlc/wlc-render.h>
-#include <cairo/cairo.h>
-#include <pango/pangocairo.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include <strings.h>
-#include <arpa/inet.h>
-#include "sway/border.h"
-#include "sway/container.h"
-#include "sway/config.h"
-#include "client/pango.h"
-
-void cairo_set_source_u32(cairo_t *cairo, uint32_t color) {
- color = htonl(color);
-
- cairo_set_source_rgba(cairo,
- (color >> (2*8) & 0xFF) / 255.0,
- (color >> (1*8) & 0xFF) / 255.0,
- (color >> (0*8) & 0xFF) / 255.0,
- (color >> (3*8) & 0xFF) / 255.0);
-}
-
-void border_clear(struct border *border) {
- if (border && border->buffer) {
- free(border->buffer);
- border->buffer = NULL;
- }
-}
-
-static cairo_t *create_border_buffer(swayc_t *view, struct wlc_geometry g, cairo_surface_t **surface) {
- if (view->border == NULL) {
- view->border = malloc(sizeof(struct border));
- if (!view->border) {
- sway_log(L_ERROR, "Unable to allocate window border information");
- return NULL;
- }
- }
- cairo_t *cr;
- int stride = cairo_format_stride_for_width(CAIRO_FORMAT_ARGB32, g.size.w);
- view->border->buffer = calloc(stride * g.size.h, sizeof(unsigned char));
- view->border->geometry = g;
- if (!view->border->buffer) {
- sway_log(L_ERROR, "Unable to allocate window border buffer");
- return NULL;
- }
- *surface = cairo_image_surface_create_for_data(view->border->buffer,
- CAIRO_FORMAT_ARGB32, g.size.w, g.size.h, stride);
- if (cairo_surface_status(*surface) != CAIRO_STATUS_SUCCESS) {
- border_clear(view->border);
- sway_log(L_ERROR, "Unable to allocate window border surface");
- return NULL;
- }
- cr = cairo_create(*surface);
- cairo_set_operator(cr, CAIRO_OPERATOR_SOURCE);
- if (cairo_status(cr) != CAIRO_STATUS_SUCCESS) {
- cairo_surface_destroy(*surface);
- border_clear(view->border);
- sway_log(L_ERROR, "Unable to create cairo context");
- return NULL;
- }
- return cr;
-}
-
-// TODO: move to client/cairo.h when local set_source_u32 is fixed.
-/**
- * Renders a sharp line of any width and height.
- *
- * The line is drawn from (x,y) to (x+width,y+height) where width/height is 0
- * if the line has a width/height of one pixel, respectively.
- */
-static void render_sharp_line(cairo_t *cairo, uint32_t color, double x, double y, double width, double height) {
- cairo_set_source_u32(cairo, color);
-
- if (width > 1 && height > 1) {
- cairo_rectangle(cairo, x, y, width, height);
- cairo_fill(cairo);
- } else {
- if (width == 1) {
- x += 0.5;
- height += y;
- width = x;
- }
-
- if (height == 1) {
- y += 0.5;
- width += x;
- height = y;
- }
-
- cairo_move_to(cairo, x, y);
- cairo_set_line_width(cairo, 1.0);
- cairo_line_to(cairo, width, height);
- cairo_stroke(cairo);
- }
-}
-
-int get_font_text_height(const char *font) {
- cairo_surface_t *surface = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, 200, 200);
- cairo_t *cr = cairo_create(surface);
- int width, height;
- get_text_size(cr, font, &width, &height, 1, false, "Gg");
- cairo_surface_destroy(surface);
- cairo_destroy(cr);
- return height;
-}
-
-static void render_borders(swayc_t *view, cairo_t *cr, struct border_colors *colors, bool top) {
- struct wlc_geometry *g = &view->border->geometry;
- struct wlc_geometry *b = &view->border_geometry;
- struct wlc_geometry *v = &view->actual_geometry;
- enum swayc_layouts layout = view->parent->layout;
- uint32_t color;
-
- int x = b->origin.x - g->origin.x;
- int y = b->origin.y - g->origin.y;
-
- // draw vertical/horizontal indicator if container is the only child of its parent container
- bool is_only_child = view->parent && view->parent->children && view->parent->children->length == 1;
-
- // left border
- int left_border = v->origin.x - b->origin.x;
- if (left_border > 0) {
- render_sharp_line(cr,
- colors->child_border,
- x, y,
- left_border,
- b->size.h);
- }
-
- // right border
- int right_border = b->size.w - v->size.w - left_border;
- if (right_border > 0) {
- if (is_only_child && layout == L_HORIZ && !view->is_floating) {
- color = colors->indicator;
- } else {
- color = colors->child_border;
- }
- render_sharp_line(cr,
- color,
- x + b->size.w - right_border,
- y,
- right_border,
- b->size.h);
- }
-
- // top border
- int top_border = v->origin.y - b->origin.y;
- if (top && top_border > 0) {
- render_sharp_line(cr,
- colors->child_border,
- x, y,
- b->size.w,
- top_border);
- }
-
- // bottom border
- int bottom_border = b->size.h - (top_border + v->size.h);
- if (bottom_border > 0) {
- if (is_only_child && layout == L_VERT && !view->is_floating) {
- color = colors->indicator;
- } else {
- color = colors->child_border;
- }
- render_sharp_line(cr,
- color,
- x,
- y + b->size.h - bottom_border,
- b->size.w,
- bottom_border);
- }
-}
-
-static void render_title_bar(swayc_t *view, cairo_t *cr, struct wlc_geometry *b, struct border_colors *colors) {
- struct wlc_geometry *tb = &view->title_bar_geometry;
- int x = MIN(tb->origin.x, tb->origin.x - b->origin.x);
- int y = MIN(tb->origin.y, tb->origin.y - b->origin.y);
-
- // title bar background
- cairo_set_source_u32(cr, colors->background);
- cairo_rectangle(cr, x, y, tb->size.w, tb->size.h);
- cairo_fill(cr);
-
- // header top line
- render_sharp_line(cr, colors->border, x, y, tb->size.w, 1);
-
- // text
- if (view->name) {
- int width, height;
- get_text_size(cr, config->font, &width, &height, 1, false, "%s", view->name);
- cairo_move_to(cr, x + 2, y + 2);
- cairo_set_source_u32(cr, colors->text);
- pango_printf(cr, config->font, 1, false, "%s", view->name);
- }
- // Marks
- if (config->show_marks && view->marks) {
- int total_len = 0;
-
- for(int i = view->marks->length - 1; i >= 0; --i) {
- char *mark = (char *)view->marks->items[i];
- if (*mark != '_') {
- int width, height;
- get_text_size(cr, config->font, &width, &height, 1, false, "[%s]", mark);
- total_len += width;
- if ((int)tb->size.w + x - (total_len + 2) < x + 2) {
- break;
- } else {
- cairo_move_to(cr, (int)tb->size.w + x - (total_len + 2), y + 2);
- cairo_set_source_u32(cr, colors->text);
- pango_printf(cr, config->font, 1, false, "[%s]", mark);
- }
- }
- }
- }
-
- // titlebars has a border all around for tabbed layouts
- if (view->parent->layout == L_TABBED) {
- // header bottom line
- render_sharp_line(cr, colors->border, x, y + tb->size.h - 1,
- tb->size.w, 1);
-
- // left border
- render_sharp_line(cr, colors->border, x, y, 1, tb->size.h);
-
- // right border
- render_sharp_line(cr, colors->border, x + tb->size.w - 1, y,
- 1, tb->size.h);
-
- return;
- }
-
- if ((uint32_t)(view->actual_geometry.origin.y - tb->origin.y) == tb->size.h) {
- // header bottom line
- render_sharp_line(cr, colors->border,
- x + view->actual_geometry.origin.x - tb->origin.x,
- y + tb->size.h - 1,
- view->actual_geometry.size.w, 1);
- } else {
- // header bottom line
- render_sharp_line(cr, colors->border, x,
- y + tb->size.h - 1,
- tb->size.w, 1);
- }
-}
-
-/**
- * Generate nested container title for tabbed/stacked layouts
- */
-static char *generate_container_title(swayc_t *container) {
- char layout = 'H';
- char *name, *prev_name = NULL;
- switch (container->layout) {
- case L_TABBED:
- layout = 'T';
- break;
- case L_STACKED:
- layout = 'S';
- break;
- case L_VERT:
- layout = 'V';
- break;
- default:
- layout = 'H';
- }
- int len = 9;
- name = malloc(len * sizeof(char));
- if (!name) {
- sway_log(L_ERROR, "Unable to allocate container title");
- return NULL;
- }
- snprintf(name, len, "sway: %c[", layout);
-
- int i;
- for (i = 0; i < container->children->length; ++i) {
- prev_name = name;
- swayc_t* child = container->children->items[i];
- const char *title = NULL;
- if (child->type == C_VIEW) {
- title = child->app_id ? child->app_id :
- (child->instance ? child->instance :
- (child->class ? child->class :"(null)"));
- } else { //child->type == C_CONTAINER
- title = generate_container_title(child);
- }
-
- len = strlen(name) + strlen(title) + 1;
- if (i < container->children->length-1) {
- len++;
- }
-
- name = malloc(len * sizeof(char));
- if (!name) {
- free(prev_name);
- sway_log(L_ERROR, "Unable to allocate container title");
- return NULL;
- }
- if (i < container->children->length-1) {
- snprintf(name, len, "%s%s ", prev_name, title);
- } else {
- snprintf(name, len, "%s%s", prev_name, title);
- }
- free(prev_name);
- }
-
- prev_name = name;
- len = strlen(name) + 2;
- name = malloc(len * sizeof(char));
- if (!name) {
- free(prev_name);
- sway_log(L_ERROR, "Unable to allocate container title");
- return NULL;
- }
- snprintf(name, len, "%s]", prev_name);
- free(prev_name);
- free(container->name);
- container->name = name;
- return container->name + 6; // don't include "sway: "
-}
-
-void update_tabbed_stacked_titlebars(swayc_t *c, cairo_t *cr, struct wlc_geometry *g, swayc_t *focused, swayc_t *focused_inactive) {
- if (c->type == C_CONTAINER) {
- if (c->parent->focused == c) {
- render_title_bar(c, cr, g, &config->border_colors.focused_inactive);
- } else {
- render_title_bar(c, cr, g, &config->border_colors.unfocused);
- }
-
- if (!c->visible) {
- return;
- }
-
- int i;
- for (i = 0; i < c->children->length; ++i) {
- swayc_t *child = c->children->items[i];
- update_tabbed_stacked_titlebars(child, cr, g, focused, focused_inactive);
- }
- } else {
- bool is_child_of_focused = swayc_is_child_of(c, get_focused_container(&root_container));
-
- if (focused == c || is_child_of_focused) {
- render_title_bar(c, cr, g, &config->border_colors.focused);
- } else if (focused_inactive == c) {
- render_title_bar(c, cr, g, &config->border_colors.focused_inactive);
- } else {
- render_title_bar(c, cr, g, &config->border_colors.unfocused);
- }
- }
-}
-
-static void update_view_border(swayc_t *view) {
- if (!view->visible) {
- return;
- }
-
- cairo_t *cr = NULL;
- cairo_surface_t *surface = NULL;
-
- // clear previous border buffer.
- border_clear(view->border);
-
- // get focused and focused_inactive views
- swayc_t *focused = get_focused_view(&root_container);
- swayc_t *container = swayc_parent_by_type(view, C_CONTAINER);
- swayc_t *focused_inactive = NULL;
-
- bool is_child_of_focused = swayc_is_parent_of(get_focused_container(&root_container), view);
-
- if (container) {
- focused_inactive = swayc_focus_by_type(container, C_VIEW);
- } else {
- container = swayc_parent_by_type(view, C_WORKSPACE);
- if (container) {
- focused_inactive = swayc_focus_by_type(container, C_VIEW);
- }
- }
-
- // for tabbed/stacked layouts the focused view has to draw all the
- // titlebars of the hidden views.
- swayc_t *p = NULL;
- if (view->parent->focused == view && (p = swayc_tabbed_stacked_ancestor(view))) {
- struct wlc_geometry g = {
- .origin = {
- .x = p->x,
- .y = p->y
- },
- .size = {
- .w = p->width,
- .h = p->height
- }
- };
- cr = create_border_buffer(view, g, &surface);
- if (!cr) {
- goto cleanup;
- }
-
- bool render_top = !should_hide_top_border(view, view->y);
- if (view == focused || is_child_of_focused) {
- render_borders(view, cr, &config->border_colors.focused, render_top);
- } else {
- render_borders(view, cr, &config->border_colors.focused_inactive, render_top);
- }
-
- // generate container titles
- int i;
- for (i = 0; i < p->children->length; ++i) {
- swayc_t *child = p->children->items[i];
- if (child->type == C_CONTAINER) {
- generate_container_title(child);
- }
- }
-
- update_tabbed_stacked_titlebars(p, cr, &g, focused, focused_inactive);
- } else {
- switch (view->border_type) {
- case B_NONE:
- break;
- case B_PIXEL:
- cr = create_border_buffer(view, view->border_geometry, &surface);
- if (!cr) {
- break;
- }
-
- if (focused == view || is_child_of_focused) {
- render_borders(view, cr, &config->border_colors.focused, true);
- } else if (focused_inactive == view) {
- render_borders(view, cr, &config->border_colors.focused_inactive, true);
- } else {
- render_borders(view, cr, &config->border_colors.unfocused, true);
- }
-
- break;
- case B_NORMAL:
- cr = create_border_buffer(view, view->border_geometry, &surface);
- if (!cr) {
- break;
- }
-
- if (focused == view || is_child_of_focused) {
- render_borders(view, cr, &config->border_colors.focused, false);
- render_title_bar(view, cr, &view->border_geometry,
- &config->border_colors.focused);
- } else if (focused_inactive == view) {
- render_borders(view, cr, &config->border_colors.focused_inactive, false);
- render_title_bar(view, cr, &view->border_geometry,
- &config->border_colors.focused_inactive);
- } else {
- render_borders(view, cr, &config->border_colors.unfocused, false);
- render_title_bar(view, cr, &view->border_geometry,
- &config->border_colors.unfocused);
- }
-
- break;
- }
- }
-
-cleanup:
-
- if (surface) {
- cairo_surface_flush(surface);
- cairo_surface_destroy(surface);
- }
-
- if (cr) {
- cairo_destroy(cr);
- }
-}
-
-void update_container_border(swayc_t *container) {
- if (container->type == C_VIEW) {
- update_view_border(container);
- return;
- } else {
- for (int i = 0; i < container->children->length; ++i) {
- update_container_border(container->children->items[i]);
- }
- }
-}
-
-void render_view_borders(wlc_handle view) {
- swayc_t *c = swayc_by_handle(view);
-
-
- // emulate i3 behavior for drawing borders for tabbed and stacked layouts:
- // if we are not the only child in the container, always draw borders,
- // regardless of the border setting on the individual view
- if (!c || (c->border_type == B_NONE
- && !((c->parent->layout == L_TABBED || c->parent->layout == L_STACKED)
- && c->parent->children->length > 1))) {
- return;
- }
-
- if (c->border && c->border->buffer) {
- wlc_pixels_write(WLC_RGBA8888, &c->border->geometry, c->border->buffer);
- }
-}
-
-bool should_hide_top_border(swayc_t *con, double y) {
- // returns true if container is child of tabbed/stacked layout and is
- // sharing top border with tabbed titlebar
- swayc_t *par = con->parent;
- while (par->type != C_WORKSPACE) {
- if (par->layout == L_TABBED || par->layout == L_STACKED) {
- return con->y == y;
- }
- con = par;
- par = par->parent;
- }
- return false;
-}
diff --git a/sway/old/commands.c b/sway/old/commands.c
deleted file mode 100644
index e1181893..00000000
--- a/sway/old/commands.c
+++ /dev/null
@@ -1,686 +0,0 @@
-#define _XOPEN_SOURCE 700
-#include <xkbcommon/xkbcommon.h>
-#include <xkbcommon/xkbcommon-names.h>
-#include <wlc/wlc.h>
-#include <wlc/wlc-render.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <errno.h>
-#include <string.h>
-#include <strings.h>
-#include <unistd.h>
-#include <ctype.h>
-#include <wordexp.h>
-#include <libgen.h>
-#include <sys/types.h>
-#include <sys/wait.h>
-#include <limits.h>
-#include <float.h>
-#include <libinput.h>
-#include "sway/layout.h"
-#include "sway/focus.h"
-#include "sway/workspace.h"
-#include "sway/commands.h"
-#include "sway/container.h"
-#include "sway/output.h"
-#include "sway/handlers.h"
-#include "sway/input_state.h"
-#include "sway/criteria.h"
-#include "sway/ipc-server.h"
-#include "sway/security.h"
-#include "sway/input.h"
-#include "sway/border.h"
-#include "stringop.h"
-#include "sway.h"
-#include "util.h"
-#include "list.h"
-#include "log.h"
-
-struct cmd_handler {
- char *command;
- sway_cmd *handle;
-};
-
-int sp_index = 0;
-
-swayc_t *current_container = NULL;
-
-// Returns error object, or NULL if check succeeds.
-struct cmd_results *checkarg(int argc, const char *name, enum expected_args type, int val) {
- struct cmd_results *error = NULL;
- switch (type) {
- case EXPECTED_MORE_THAN:
- if (argc > val) {
- return NULL;
- }
- error = cmd_results_new(CMD_INVALID, name, "Invalid %s command "
- "(expected more than %d argument%s, got %d)",
- name, val, (char*[2]){"s", ""}[argc==1], argc);
- break;
- case EXPECTED_AT_LEAST:
- if (argc >= val) {
- return NULL;
- }
- error = cmd_results_new(CMD_INVALID, name, "Invalid %s command "
- "(expected at least %d argument%s, got %d)",
- name, val, (char*[2]){"s", ""}[argc==1], argc);
- break;
- case EXPECTED_LESS_THAN:
- if (argc < val) {
- return NULL;
- };
- error = cmd_results_new(CMD_INVALID, name, "Invalid %s command "
- "(expected less than %d argument%s, got %d)",
- name, val, (char*[2]){"s", ""}[argc==1], argc);
- break;
- case EXPECTED_EQUAL_TO:
- if (argc == val) {
- return NULL;
- };
- error = cmd_results_new(CMD_INVALID, name, "Invalid %s command "
- "(expected %d arguments, got %d)", name, val, argc);
- break;
- }
- return error;
-}
-
-void hide_view_in_scratchpad(swayc_t *sp_view) {
- if (sp_view == NULL) {
- return;
- }
-
- wlc_view_set_mask(sp_view->handle, 0);
- sp_view->visible = false;
- swayc_t *ws = sp_view->parent;
- remove_child(sp_view);
- if (swayc_active_workspace() != ws && ws->floating->length == 0 && ws->children->length == 0) {
- destroy_workspace(ws);
- } else {
- arrange_windows(ws, -1, -1);
- }
- set_focused_container(container_under_pointer());
-}
-
-void input_cmd_apply(struct input_config *input) {
- int i;
- i = list_seq_find(config->input_configs, input_identifier_cmp, input->identifier);
- if (i >= 0) {
- // merge existing config
- struct input_config *ic = config->input_configs->items[i];
- merge_input_config(ic, input);
- free_input_config(input);
- input = ic;
- } else {
- list_add(config->input_configs, input);
- }
-
- current_input_config = input;
-
- if (input->identifier) {
- // Try to find the input device and apply configuration now. If
- // this is during startup then there will be no container and config
- // will be applied during normal "new input" event from wlc.
- /* TODO WLR
- struct libinput_device *device = NULL;
- for (int i = 0; i < input_devices->length; ++i) {
- device = input_devices->items[i];
- char* dev_identifier = libinput_dev_unique_id(device);
- if (!dev_identifier) {
- break;
- }
- int match = dev_identifier && strcmp(dev_identifier, input->identifier) == 0;
- free(dev_identifier);
- if (match) {
- apply_input_config(input, device);
- break;
- }
- }
- */
- }
-}
-
-void remove_view_from_scratchpad(swayc_t *view) {
- int i;
- for (i = 0; i < scratchpad->length; i++) {
- if (scratchpad->items[i] == view) {
- if (sp_index == 0) {
- sp_index = scratchpad->length - 1;
- } else {
- sp_index--;
- }
- list_del(scratchpad, sp_index);
- sp_view = NULL;
- }
- }
-}
-
-/* Keep alphabetized */
-static struct cmd_handler handlers[] = {
- { "assign", cmd_assign },
- { "bar", cmd_bar },
- { "bindcode", cmd_bindcode },
- { "bindsym", cmd_bindsym },
- { "border", cmd_border },
- { "client.background", cmd_client_background },
- { "client.focused", cmd_client_focused },
- { "client.focused_inactive", cmd_client_focused_inactive },
- { "client.placeholder", cmd_client_placeholder },
- { "client.unfocused", cmd_client_unfocused },
- { "client.urgent", cmd_client_urgent },
- { "clipboard", cmd_clipboard },
- { "commands", cmd_commands },
- { "debuglog", cmd_debuglog },
- { "default_border", cmd_default_border },
- { "default_floating_border", cmd_default_floating_border },
- { "default_orientation", cmd_orientation },
- { "exec", cmd_exec },
- { "exec_always", cmd_exec_always },
- { "exit", cmd_exit },
- { "floating", cmd_floating },
- { "floating_maximum_size", cmd_floating_maximum_size },
- { "floating_minimum_size", cmd_floating_minimum_size },
- { "floating_modifier", cmd_floating_mod },
- { "floating_scroll", cmd_floating_scroll },
- { "focus", cmd_focus },
- { "focus_follows_mouse", cmd_focus_follows_mouse },
- { "font", cmd_font },
- { "for_window", cmd_for_window },
- { "force_focus_wrapping", cmd_force_focus_wrapping },
- { "fullscreen", cmd_fullscreen },
- { "gaps", cmd_gaps },
- { "hide_edge_borders", cmd_hide_edge_borders },
- { "include", cmd_include },
- { "input", cmd_input },
- { "ipc", cmd_ipc },
- { "kill", cmd_kill },
- { "layout", cmd_layout },
- { "log_colors", cmd_log_colors },
- { "mark", cmd_mark },
- { "mode", cmd_mode },
- { "mouse_warping", cmd_mouse_warping },
- { "move", cmd_move },
- { "new_float", cmd_new_float },
- { "new_window", cmd_new_window },
- { "no_focus", cmd_no_focus },
- { "output", cmd_output },
- { "permit", cmd_permit },
- { "reject", cmd_reject },
- { "reload", cmd_reload },
- { "resize", cmd_resize },
- { "scratchpad", cmd_scratchpad },
- { "seamless_mouse", cmd_seamless_mouse },
- { "set", cmd_set },
- { "show_marks", cmd_show_marks },
- { "smart_gaps", cmd_smart_gaps },
- { "split", cmd_split },
- { "splith", cmd_splith },
- { "splitt", cmd_splitt },
- { "splitv", cmd_splitv },
- { "sticky", cmd_sticky },
- { "unmark", cmd_unmark },
- { "workspace", cmd_workspace },
- { "workspace_auto_back_and_forth", cmd_ws_auto_back_and_forth },
- { "workspace_layout", cmd_workspace_layout },
-};
-
-static struct cmd_handler bar_handlers[] = {
- { "activate_button", bar_cmd_activate_button },
- { "binding_mode_indicator", bar_cmd_binding_mode_indicator },
- { "bindsym", bar_cmd_bindsym },
- { "colors", bar_cmd_colors },
- { "context_button", bar_cmd_context_button },
- { "font", bar_cmd_font },
- { "height", bar_cmd_height },
- { "hidden_state", bar_cmd_hidden_state },
- { "icon_theme", bar_cmd_icon_theme },
- { "id", bar_cmd_id },
- { "mode", bar_cmd_mode },
- { "modifier", bar_cmd_modifier },
- { "output", bar_cmd_output },
- { "pango_markup", bar_cmd_pango_markup },
- { "position", bar_cmd_position },
- { "secondary_button", bar_cmd_secondary_button },
- { "separator_symbol", bar_cmd_separator_symbol },
- { "status_command", bar_cmd_status_command },
- { "strip_workspace_numbers", bar_cmd_strip_workspace_numbers },
- { "swaybar_command", bar_cmd_swaybar_command },
- { "tray_output", bar_cmd_tray_output },
- { "tray_padding", bar_cmd_tray_padding },
- { "workspace_buttons", bar_cmd_workspace_buttons },
- { "wrap_scroll", bar_cmd_wrap_scroll },
-};
-
-/**
- * Check and add color to buffer.
- *
- * return error object, or NULL if color is valid.
- */
-struct cmd_results *add_color(const char *name, char *buffer, const char *color) {
- int len = strlen(color);
- if (len != 7 && len != 9) {
- return cmd_results_new(CMD_INVALID, name, "Invalid color definition %s", color);
- }
-
- if (color[0] != '#') {
- return cmd_results_new(CMD_INVALID, name, "Invalid color definition %s", color);
- }
-
- int i;
- for (i = 1; i < len; ++i) {
- if (!isxdigit(color[i])) {
- return cmd_results_new(CMD_INVALID, name, "Invalid color definition %s", color);
- }
- }
-
- // copy color to buffer
- strncpy(buffer, color, len);
- // add default alpha channel if color was defined without it
- if (len == 7) {
- buffer[7] = 'f';
- buffer[8] = 'f';
- }
- buffer[9] = '\0';
-
- return NULL;
-}
-
-static struct cmd_handler input_handlers[] = {
- { "accel_profile", input_cmd_accel_profile },
- { "click_method", input_cmd_click_method },
- { "drag_lock", input_cmd_drag_lock },
- { "dwt", input_cmd_dwt },
- { "events", input_cmd_events },
- { "left_handed", input_cmd_left_handed },
- { "middle_emulation", input_cmd_middle_emulation },
- { "natural_scroll", input_cmd_natural_scroll },
- { "pointer_accel", input_cmd_pointer_accel },
- { "scroll_method", input_cmd_scroll_method },
- { "tap", input_cmd_tap },
-};
-
-static struct cmd_handler bar_colors_handlers[] = {
- { "active_workspace", bar_colors_cmd_active_workspace },
- { "background", bar_colors_cmd_background },
- { "binding_mode", bar_colors_cmd_binding_mode },
- { "focused_background", bar_colors_cmd_focused_background },
- { "focused_separator", bar_colors_cmd_focused_separator },
- { "focused_statusline", bar_colors_cmd_focused_statusline },
- { "focused_workspace", bar_colors_cmd_focused_workspace },
- { "inactive_workspace", bar_colors_cmd_inactive_workspace },
- { "separator", bar_colors_cmd_separator },
- { "statusline", bar_colors_cmd_statusline },
- { "urgent_workspace", bar_colors_cmd_urgent_workspace },
-};
-
-static struct cmd_handler ipc_handlers[] = {
- { "*", cmd_ipc_cmd },
- { "bar-config", cmd_ipc_cmd },
- { "command", cmd_ipc_cmd },
- { "events", cmd_ipc_events },
- { "inputs", cmd_ipc_cmd },
- { "marks", cmd_ipc_cmd },
- { "outputs", cmd_ipc_cmd },
- { "tree", cmd_ipc_cmd },
- { "workspaces", cmd_ipc_cmd },
-};
-
-static struct cmd_handler ipc_event_handlers[] = {
- { "*", cmd_ipc_event_cmd },
- { "binding", cmd_ipc_event_cmd },
- { "input", cmd_ipc_event_cmd },
- { "mode", cmd_ipc_event_cmd },
- { "output", cmd_ipc_event_cmd },
- { "window", cmd_ipc_event_cmd },
- { "workspace", cmd_ipc_event_cmd },
-};
-
-static int handler_compare(const void *_a, const void *_b) {
- const struct cmd_handler *a = _a;
- const struct cmd_handler *b = _b;
- return strcasecmp(a->command, b->command);
-}
-
-static struct cmd_handler *find_handler(char *line, enum cmd_status block) {
- struct cmd_handler d = { .command=line };
- struct cmd_handler *res = NULL;
- sway_log(L_DEBUG, "find_handler(%s) %d", line, block == CMD_BLOCK_INPUT);
- if (block == CMD_BLOCK_BAR) {
- res = bsearch(&d, bar_handlers,
- sizeof(bar_handlers) / sizeof(struct cmd_handler),
- sizeof(struct cmd_handler), handler_compare);
- } else if (block == CMD_BLOCK_BAR_COLORS){
- res = bsearch(&d, bar_colors_handlers,
- sizeof(bar_colors_handlers) / sizeof(struct cmd_handler),
- sizeof(struct cmd_handler), handler_compare);
- } else if (block == CMD_BLOCK_INPUT) {
- res = bsearch(&d, input_handlers,
- sizeof(input_handlers) / sizeof(struct cmd_handler),
- sizeof(struct cmd_handler), handler_compare);
- } else if (block == CMD_BLOCK_IPC) {
- res = bsearch(&d, ipc_handlers,
- sizeof(ipc_handlers) / sizeof(struct cmd_handler),
- sizeof(struct cmd_handler), handler_compare);
- } else if (block == CMD_BLOCK_IPC_EVENTS) {
- res = bsearch(&d, ipc_event_handlers,
- sizeof(ipc_event_handlers) / sizeof(struct cmd_handler),
- sizeof(struct cmd_handler), handler_compare);
- } else {
- res = bsearch(&d, handlers,
- sizeof(handlers) / sizeof(struct cmd_handler),
- sizeof(struct cmd_handler), handler_compare);
- }
- return res;
-}
-
-struct cmd_results *handle_command(char *_exec, enum command_context context) {
- // Even though this function will process multiple commands we will only
- // return the last error, if any (for now). (Since we have access to an
- // error string we could e.g. concatonate all errors there.)
- struct cmd_results *results = NULL;
- char *exec = strdup(_exec);
- char *head = exec;
- char *cmdlist;
- char *cmd;
- list_t *containers = NULL;
-
- head = exec;
- do {
- // Extract criteria (valid for this command list only).
- if (*head == '[') {
- ++head;
- char *criteria_string = argsep(&head, "]");
- if (head) {
- ++head;
- list_t *tokens = create_list();
- char *error;
-
- if ((error = extract_crit_tokens(tokens, criteria_string))) {
- results = cmd_results_new(CMD_INVALID, criteria_string,
- "Can't parse criteria string: %s", error);
- free(error);
- free(tokens);
- goto cleanup;
- }
- containers = container_for(tokens);
-
- free(tokens);
- } else {
- if (!results) {
- results = cmd_results_new(CMD_INVALID, criteria_string, "Unmatched [");
- }
- goto cleanup;
- }
- // Skip leading whitespace
- head += strspn(head, whitespace);
- }
- // Split command list
- cmdlist = argsep(&head, ";");
- cmdlist += strspn(cmdlist, whitespace);
- do {
- // Split commands
- cmd = argsep(&cmdlist, ",");
- cmd += strspn(cmd, whitespace);
- if (strcmp(cmd, "") == 0) {
- sway_log(L_INFO, "Ignoring empty command.");
- continue;
- }
- sway_log(L_INFO, "Handling command '%s'", cmd);
- //TODO better handling of argv
- int argc;
- char **argv = split_args(cmd, &argc);
- if (strcmp(argv[0], "exec") != 0) {
- int i;
- for (i = 1; i < argc; ++i) {
- if (*argv[i] == '\"' || *argv[i] == '\'') {
- strip_quotes(argv[i]);
- }
- }
- }
- struct cmd_handler *handler = find_handler(argv[0], CMD_BLOCK_END);
- if (!handler) {
- if (results) {
- free_cmd_results(results);
- }
- results = cmd_results_new(CMD_INVALID, cmd, "Unknown/invalid command");
- free_argv(argc, argv);
- goto cleanup;
- }
- if (!(get_command_policy_mask(argv[0]) & context)) {
- if (results) {
- free_cmd_results(results);
- }
- results = cmd_results_new(CMD_INVALID, cmd,
- "Permission denied for %s via %s", cmd,
- command_policy_str(context));
- free_argv(argc, argv);
- goto cleanup;
- }
- int i = 0;
- do {
- if (!containers) {
- current_container = get_focused_container(&root_container);
- } else if (containers->length == 0) {
- if (results) {
- free_cmd_results(results);
- }
- results = cmd_results_new(CMD_FAILURE, argv[0], "No matching container");
- goto cleanup;
- } else {
- current_container = (swayc_t *)containers->items[i];
- }
- sway_log(L_INFO, "Running on container '%s'", current_container->name);
-
- struct cmd_results *res = handler->handle(argc-1, argv+1);
- if (res->status != CMD_SUCCESS) {
- free_argv(argc, argv);
- if (results) {
- free_cmd_results(results);
- }
- results = res;
- goto cleanup;
- }
- free_cmd_results(res);
- ++i;
- } while(containers && i < containers->length);
-
- free_argv(argc, argv);
- } while(cmdlist);
-
- if (containers) {
- list_free(containers);
- containers = NULL;
- }
- } while(head);
- cleanup:
- free(exec);
- if (containers) {
- free(containers);
- }
- if (!results) {
- results = cmd_results_new(CMD_SUCCESS, NULL, NULL);
- }
- return results;
-}
-
-// this is like handle_command above, except:
-// 1) it ignores empty commands (empty lines)
-// 2) it does variable substitution
-// 3) it doesn't split commands (because the multiple commands are supposed to
-// be chained together)
-// 4) handle_command handles all state internally while config_command has some
-// state handled outside (notably the block mode, in read_config)
-struct cmd_results *config_command(char *exec, enum cmd_status block) {
- struct cmd_results *results = NULL;
- int argc;
- char **argv = split_args(exec, &argc);
- if (!argc) {
- results = cmd_results_new(CMD_SUCCESS, NULL, NULL);
- goto cleanup;
- }
-
- sway_log(L_INFO, "handling config command '%s'", exec);
- // Endblock
- if (**argv == '}') {
- results = cmd_results_new(CMD_BLOCK_END, NULL, NULL);
- goto cleanup;
- }
- struct cmd_handler *handler = find_handler(argv[0], block);
- if (!handler) {
- char *input = argv[0] ? argv[0] : "(empty)";
- results = cmd_results_new(CMD_INVALID, input, "Unknown/invalid command");
- goto cleanup;
- }
- int i;
- // Var replacement, for all but first argument of set
- for (i = handler->handle == cmd_set ? 2 : 1; i < argc; ++i) {
- argv[i] = do_var_replacement(argv[i]);
- unescape_string(argv[i]);
- }
- /* Strip quotes for first argument.
- * TODO This part needs to be handled much better */
- if (argc>1 && (*argv[1] == '\"' || *argv[1] == '\'')) {
- strip_quotes(argv[1]);
- }
- if (handler->handle) {
- results = handler->handle(argc-1, argv+1);
- } else {
- results = cmd_results_new(CMD_INVALID, argv[0], "This command is shimmed, but unimplemented");
- }
-
-cleanup:
- free_argv(argc, argv);
- return results;
-}
-
-struct cmd_results *config_commands_command(char *exec) {
- struct cmd_results *results = NULL;
- int argc;
- char **argv = split_args(exec, &argc);
- if (!argc) {
- results = cmd_results_new(CMD_SUCCESS, NULL, NULL);
- goto cleanup;
- }
-
- // Find handler for the command this is setting a policy for
- char *cmd = argv[0];
-
- if (strcmp(cmd, "}") == 0) {
- results = cmd_results_new(CMD_BLOCK_END, NULL, NULL);
- goto cleanup;
- }
-
- struct cmd_handler *handler = find_handler(cmd, CMD_BLOCK_END);
- if (!handler && strcmp(cmd, "*") != 0) {
- char *input = cmd ? cmd : "(empty)";
- results = cmd_results_new(CMD_INVALID, input, "Unknown/invalid command");
- goto cleanup;
- }
-
- enum command_context context = 0;
-
- struct {
- char *name;
- enum command_context context;
- } context_names[] = {
- { "config", CONTEXT_CONFIG },
- { "binding", CONTEXT_BINDING },
- { "ipc", CONTEXT_IPC },
- { "criteria", CONTEXT_CRITERIA },
- { "all", CONTEXT_ALL },
- };
-
- for (int i = 1; i < argc; ++i) {
- size_t j;
- for (j = 0; j < sizeof(context_names) / sizeof(context_names[0]); ++j) {
- if (strcmp(context_names[j].name, argv[i]) == 0) {
- break;
- }
- }
- if (j == sizeof(context_names) / sizeof(context_names[0])) {
- results = cmd_results_new(CMD_INVALID, cmd,
- "Invalid command context %s", argv[i]);
- goto cleanup;
- }
- context |= context_names[j].context;
- }
-
- struct command_policy *policy = NULL;
- for (int i = 0; i < config->command_policies->length; ++i) {
- struct command_policy *p = config->command_policies->items[i];
- if (strcmp(p->command, cmd) == 0) {
- policy = p;
- break;
- }
- }
- if (!policy) {
- policy = alloc_command_policy(cmd);
- sway_assert(policy, "Unable to allocate security policy");
- if (policy) {
- list_add(config->command_policies, policy);
- }
- }
- policy->context = context;
-
- sway_log(L_INFO, "Set command policy for %s to %d",
- policy->command, policy->context);
-
- results = cmd_results_new(CMD_SUCCESS, NULL, NULL);
-
-cleanup:
- free_argv(argc, argv);
- return results;
-}
-
-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) {
- sway_log(L_ERROR, "Unable to allocate command results");
- return NULL;
- }
- results->status = status;
- if (input) {
- results->input = strdup(input); // input is the command name
- } else {
- results->input = NULL;
- }
- if (format) {
- char *error = malloc(256);
- va_list args;
- va_start(args, format);
- if (error) {
- vsnprintf(error, 256, format, args);
- }
- va_end(args);
- results->error = error;
- } else {
- results->error = NULL;
- }
- return results;
-}
-
-void free_cmd_results(struct cmd_results *results) {
- if (results->input) {
- free(results->input);
- }
- if (results->error) {
- free(results->error);
- }
- free(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", json_object_new_boolean(results->status == CMD_SUCCESS));
- if (results->input) {
- json_object_object_add(root, "input", json_object_new_string(results->input));
- }
- if (results->error) {
- json_object_object_add(root, "error", json_object_new_string(results->error));
- }
- json_object_array_add(result_array, root);
- const char *json = json_object_to_json_string(result_array);
- free(result_array);
- free(root);
- return json;
-}
diff --git a/sway/old/commands/assign.c b/sway/old/commands/assign.c
deleted file mode 100644
index c3b03bbc..00000000
--- a/sway/old/commands/assign.c
+++ /dev/null
@@ -1,57 +0,0 @@
-#define _XOPEN_SOURCE 700
-#include <stdio.h>
-#include <string.h>
-#include "sway/commands.h"
-#include "sway/criteria.h"
-#include "list.h"
-#include "log.h"
-
-struct cmd_results *cmd_assign(int argc, char **argv) {
- struct cmd_results *error = NULL;
- if ((error = checkarg(argc, "assign", EXPECTED_AT_LEAST, 2))) {
- return error;
- }
-
- char *criteria = *argv++;
-
- if (strncmp(*argv, "→", strlen("→")) == 0) {
- if (argc < 3) {
- return cmd_results_new(CMD_INVALID, "assign", "Missing workspace");
- }
- argv++;
- }
-
- char *movecmd = "move container to workspace ";
- int arglen = strlen(movecmd) + strlen(*argv) + 1;
- char *cmdlist = calloc(1, arglen);
- if (!cmdlist) {
- return cmd_results_new(CMD_FAILURE, "assign", "Unable to allocate command list");
- }
- snprintf(cmdlist, arglen, "%s%s", movecmd, *argv);
-
- struct criteria *crit = malloc(sizeof(struct criteria));
- if (!crit) {
- free(cmdlist);
- return cmd_results_new(CMD_FAILURE, "assign", "Unable to allocate criteria");
- }
- crit->crit_raw = strdup(criteria);
- crit->cmdlist = cmdlist;
- crit->tokens = create_list();
- char *err_str = extract_crit_tokens(crit->tokens, crit->crit_raw);
-
- if (err_str) {
- error = cmd_results_new(CMD_INVALID, "assign", err_str);
- free(err_str);
- free_criteria(crit);
- } else if (crit->tokens->length == 0) {
- error = cmd_results_new(CMD_INVALID, "assign", "Found no name/value pairs in criteria");
- free_criteria(crit);
- } else if (list_seq_find(config->criteria, criteria_cmp, crit) != -1) {
- sway_log(L_DEBUG, "assign: Duplicate, skipping.");
- free_criteria(crit);
- } else {
- sway_log(L_DEBUG, "assign: '%s' -> '%s' added", crit->crit_raw, crit->cmdlist);
- list_add(config->criteria, crit);
- }
- return error ? error : cmd_results_new(CMD_SUCCESS, NULL, NULL);
-}
diff --git a/sway/old/commands/bar.c b/sway/old/commands/bar.c
deleted file mode 100644
index 04745a6e..00000000
--- a/sway/old/commands/bar.c
+++ /dev/null
@@ -1,59 +0,0 @@
-#include <stdio.h>
-#include <string.h>
-#include <strings.h>
-#include "sway/commands.h"
-#include "sway/config.h"
-#include "log.h"
-#include "util.h"
-
-struct cmd_results *cmd_bar(int argc, char **argv) {
- struct cmd_results *error = NULL;
- if ((error = checkarg(argc, "bar", EXPECTED_AT_LEAST, 1))) {
- return error;
- }
-
- if (config->reading && strcmp("{", argv[0]) != 0) {
- return cmd_results_new(CMD_INVALID, "bar",
- "Expected '{' at start of bar config definition.");
- }
-
- if (!config->reading) {
- if (argc > 1) {
- if (strcasecmp("mode", argv[0]) == 0) {
- return bar_cmd_mode(argc-1, argv + 1);
- }
-
- if (strcasecmp("hidden_state", argv[0]) == 0) {
- return bar_cmd_hidden_state(argc-1, argv + 1);
- }
- }
-
- return cmd_results_new(CMD_FAILURE, "bar", "Can only be used in config file.");
- }
-
- // Create new bar with default values
- struct bar_config *bar = default_bar_config();
- if (!bar) {
- return cmd_results_new(CMD_FAILURE, "bar", "Unable to allocate bar state");
- }
-
- // set bar id
- int i;
- for (i = 0; i < config->bars->length; ++i) {
- if (bar == config->bars->items[i]) {
- const int len = 5 + numlen(i); // "bar-" + i + \0
- bar->id = malloc(len * sizeof(char));
- if (bar->id) {
- snprintf(bar->id, len, "bar-%d", i);
- } else {
- return cmd_results_new(CMD_FAILURE, "bar", "Unable to allocate bar ID");
- }
- break;
- }
- }
-
- // Set current bar
- config->current_bar = bar;
- sway_log(L_DEBUG, "Configuring bar %s", bar->id);
- return cmd_results_new(CMD_BLOCK_BAR, NULL, NULL);
-}
diff --git a/sway/old/commands/bar/activate_button.c b/sway/old/commands/bar/activate_button.c
deleted file mode 100644
index 32a1d3e5..00000000
--- a/sway/old/commands/bar/activate_button.c
+++ /dev/null
@@ -1,26 +0,0 @@
-#include <stdlib.h>
-#include "sway/commands.h"
-#include "log.h"
-
-struct cmd_results *bar_cmd_activate_button(int argc, char **argv) {
- const char *cmd_name = "activate_button";
-#ifndef ENABLE_TRAY
- return cmd_results_new(CMD_INVALID, cmd_name, "Invalid %s command "
- "%s called, but sway was compiled without tray support",
- cmd_name, cmd_name);
-#else
- struct cmd_results *error = NULL;
- if ((error = checkarg(argc, cmd_name, EXPECTED_EQUAL_TO, 1))) {
- return error;
- }
-
- if (!config->current_bar) {
- return cmd_results_new(CMD_FAILURE, cmd_name, "No bar defined.");
- }
-
- // User should be able to prefix with 0x or whatever they want
- config->current_bar->secondary_button = strtoul(argv[0], NULL, 0);
-
- return cmd_results_new(CMD_SUCCESS, NULL, NULL);
-#endif
-}
diff --git a/sway/old/commands/bar/binding_mode_indicator.c b/sway/old/commands/bar/binding_mode_indicator.c
deleted file mode 100644
index 64f5b84f..00000000
--- a/sway/old/commands/bar/binding_mode_indicator.c
+++ /dev/null
@@ -1,27 +0,0 @@
-#include <string.h>
-#include <strings.h>
-#include "sway/commands.h"
-#include "log.h"
-
-struct cmd_results *bar_cmd_binding_mode_indicator(int argc, char **argv) {
- struct cmd_results *error = NULL;
- if ((error = checkarg(argc, "binding_mode_indicator", EXPECTED_EQUAL_TO, 1))) {
- return error;
- }
-
- if (!config->current_bar) {
- return cmd_results_new(CMD_FAILURE, "binding_mode_indicator", "No bar defined.");
- }
-
- if (strcasecmp("yes", argv[0]) == 0) {
- config->current_bar->binding_mode_indicator = true;
- sway_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;
- sway_log(L_DEBUG, "Disabling binding mode indicator on bar: %s", config->current_bar->id);
- } else {
- error = cmd_results_new(CMD_INVALID, "binding_mode_indicator", "Invalid value %s", argv[0]);
- return error;
- }
- return cmd_results_new(CMD_SUCCESS, NULL, NULL);
-}
diff --git a/sway/old/commands/bar/bindsym.c b/sway/old/commands/bar/bindsym.c
deleted file mode 100644
index 5f90b51a..00000000
--- a/sway/old/commands/bar/bindsym.c
+++ /dev/null
@@ -1,48 +0,0 @@
-#include <stdlib.h>
-#include <string.h>
-#include "sway/commands.h"
-#include "sway/config.h"
-#include "list.h"
-#include "log.h"
-#include "stringop.h"
-
-struct cmd_results *bar_cmd_bindsym(int argc, char **argv) {
- struct cmd_results *error = NULL;
- if ((error = checkarg(argc, "bindsym", EXPECTED_MORE_THAN, 1))) {
- return error;
- } else if (!config->reading) {
- return cmd_results_new(CMD_FAILURE, "bindsym", "Can only be used in config file.");
- }
-
- if (!config->current_bar) {
- return cmd_results_new(CMD_FAILURE, "bindsym", "No bar defined.");
- }
-
- if (strlen(argv[1]) != 7) {
- return cmd_results_new(CMD_INVALID, "bindsym", "Invalid mouse binding %s", argv[1]);
- }
- uint32_t numbutton = (uint32_t)atoi(argv[1] + 6);
- if (numbutton < 1 || numbutton > 5 || strncmp(argv[1], "button", 6) != 0) {
- return cmd_results_new(CMD_INVALID, "bindsym", "Invalid mouse binding %s", argv[1]);
- }
- struct sway_mouse_binding *binding = malloc(sizeof(struct sway_mouse_binding));
- if (!binding) {
- return cmd_results_new(CMD_FAILURE, "bindsym", "Unable to allocate binding");
- }
- binding->button = numbutton;
- binding->command = join_args(argv + 1, argc - 1);
-
- struct bar_config *bar = config->current_bar;
- int i = list_seq_find(bar->bindings, sway_mouse_binding_cmp_buttons, binding);
- if (i > -1) {
- sway_log(L_DEBUG, "bindsym - '%s' for swaybar already exists, overwriting", argv[0]);
- struct sway_mouse_binding *dup = bar->bindings->items[i];
- free_sway_mouse_binding(dup);
- list_del(bar->bindings, i);
- }
- list_add(bar->bindings, binding);
- list_qsort(bar->bindings, sway_mouse_binding_cmp_qsort);
-
- sway_log(L_DEBUG, "bindsym - Bound %s to command %s when clicking swaybar", argv[0], binding->command);
- return cmd_results_new(CMD_SUCCESS, NULL, NULL);
-}
diff --git a/sway/old/commands/bar/colors.c b/sway/old/commands/bar/colors.c
deleted file mode 100644
index 8b3b0aac..00000000
--- a/sway/old/commands/bar/colors.c
+++ /dev/null
@@ -1,129 +0,0 @@
-#include <string.h>
-#include "sway/commands.h"
-
-static struct cmd_results *parse_single_color(char **color, const char *cmd_name, int argc, char **argv) {
- struct cmd_results *error = NULL;
- if ((error = checkarg(argc, cmd_name, EXPECTED_EQUAL_TO, 1))) {
- return error;
- }
-
- if (!*color) {
- *color = malloc(10);
- if (!*color) {
- return cmd_results_new(CMD_FAILURE, cmd_name, "Unable to allocate color");
- }
- }
-
- error = add_color(cmd_name, *color, argv[0]);
- if (error) {
- return error;
- }
-
- return cmd_results_new(CMD_SUCCESS, NULL, NULL);
-}
-
-static struct cmd_results *parse_three_colors(char ***colors, const char *cmd_name, int argc, char **argv) {
- struct cmd_results *error = NULL;
- if (argc != 3) {
- return cmd_results_new(CMD_INVALID, cmd_name, "Requires exactly three color values");
- }
-
- int i;
- for (i = 0; i < 3; i++) {
- if (!*colors[i]) {
- *(colors[i]) = malloc(10);
- if (!*(colors[i])) {
- return cmd_results_new(CMD_FAILURE, cmd_name, "Unable to allocate color");
- }
- }
- error = add_color(cmd_name, *(colors[i]), argv[i]);
- if (error) {
- return error;
- }
- }
-
- return cmd_results_new(CMD_SUCCESS, NULL, NULL);
-}
-
-struct cmd_results *bar_cmd_colors(int argc, char **argv) {
- struct cmd_results *error = NULL;
- if ((error = checkarg(argc, "colors", EXPECTED_EQUAL_TO, 1))) {
- return error;
- }
-
- if (strcmp("{", argv[0]) != 0) {
- return cmd_results_new(CMD_INVALID, "colors",
- "Expected '{' at the start of colors config definition.");
- }
-
- return cmd_results_new(CMD_BLOCK_BAR_COLORS, NULL, NULL);
-}
-
-struct cmd_results *bar_colors_cmd_active_workspace(int argc, char **argv) {
- char **colors[3] = {
- &(config->current_bar->colors.active_workspace_border),
- &(config->current_bar->colors.active_workspace_bg),
- &(config->current_bar->colors.active_workspace_text)
- };
- return parse_three_colors(colors, "active_workspace", argc, argv);
-}
-
-struct cmd_results *bar_colors_cmd_background(int argc, char **argv) {
- return parse_single_color(&(config->current_bar->colors.background), "background", argc, argv);
-}
-
-struct cmd_results *bar_colors_cmd_focused_background(int argc, char **argv) {
- return parse_single_color(&(config->current_bar->colors.focused_background), "focused_background", argc, argv);
-}
-
-struct cmd_results *bar_colors_cmd_binding_mode(int argc, char **argv) {
- char **colors[3] = {
- &(config->current_bar->colors.binding_mode_border),
- &(config->current_bar->colors.binding_mode_bg),
- &(config->current_bar->colors.binding_mode_text)
- };
- return parse_three_colors(colors, "binding_mode", argc, argv);
-}
-
-struct cmd_results *bar_colors_cmd_focused_workspace(int argc, char **argv) {
- char **colors[3] = {
- &(config->current_bar->colors.focused_workspace_border),
- &(config->current_bar->colors.focused_workspace_bg),
- &(config->current_bar->colors.focused_workspace_text)
- };
- return parse_three_colors(colors, "focused_workspace", argc, argv);
-}
-
-struct cmd_results *bar_colors_cmd_inactive_workspace(int argc, char **argv) {
- char **colors[3] = {
- &(config->current_bar->colors.inactive_workspace_border),
- &(config->current_bar->colors.inactive_workspace_bg),
- &(config->current_bar->colors.inactive_workspace_text)
- };
- return parse_three_colors(colors, "inactive_workspace", argc, argv);
-}
-
-struct cmd_results *bar_colors_cmd_separator(int argc, char **argv) {
- return parse_single_color(&(config->current_bar->colors.separator), "separator", argc, argv);
-}
-
-struct cmd_results *bar_colors_cmd_focused_separator(int argc, char **argv) {
- return parse_single_color(&(config->current_bar->colors.focused_separator), "focused_separator", argc, argv);
-}
-
-struct cmd_results *bar_colors_cmd_statusline(int argc, char **argv) {
- return parse_single_color(&(config->current_bar->colors.statusline), "statusline", argc, argv);
-}
-
-struct cmd_results *bar_colors_cmd_focused_statusline(int argc, char **argv) {
- return parse_single_color(&(config->current_bar->colors.focused_separator), "focused_separator", argc, argv);
-}
-
-struct cmd_results *bar_colors_cmd_urgent_workspace(int argc, char **argv) {
- char **colors[3] = {
- &(config->current_bar->colors.urgent_workspace_border),
- &(config->current_bar->colors.urgent_workspace_bg),
- &(config->current_bar->colors.urgent_workspace_text)
- };
- return parse_three_colors(colors, "urgent_workspace", argc, argv);
-}
diff --git a/sway/old/commands/bar/context_button.c b/sway/old/commands/bar/context_button.c
deleted file mode 100644
index 6d7d7aec..00000000
--- a/sway/old/commands/bar/context_button.c
+++ /dev/null
@@ -1,26 +0,0 @@
-#include <stdlib.h>
-#include "sway/commands.h"
-#include "log.h"
-
-struct cmd_results *bar_cmd_context_button(int argc, char **argv) {
- const char *cmd_name = "context_button";
-#ifndef ENABLE_TRAY
- return cmd_results_new(CMD_INVALID, cmd_name, "Invalid %s command "
- "%s called, but sway was compiled without tray support",
- cmd_name, cmd_name);
-#else
- struct cmd_results *error = NULL;
- if ((error = checkarg(argc, cmd_name, EXPECTED_EQUAL_TO, 1))) {
- return error;
- }
-
- if (!config->current_bar) {
- return cmd_results_new(CMD_FAILURE, cmd_name, "No bar defined.");
- }
-
- // User should be able to prefix with 0x or whatever they want
- config->current_bar->context_button = strtoul(argv[0], NULL, 0);
-
- return cmd_results_new(CMD_SUCCESS, NULL, NULL);
-#endif
-}
diff --git a/sway/old/commands/bar/font.c b/sway/old/commands/bar/font.c
deleted file mode 100644
index c586c5bc..00000000
--- a/sway/old/commands/bar/font.c
+++ /dev/null
@@ -1,26 +0,0 @@
-#include <string.h>
-#include "sway/commands.h"
-#include "log.h"
-#include "stringop.h"
-
-struct cmd_results *bar_cmd_font(int argc, char **argv) {
- struct cmd_results *error = NULL;
- if ((error = checkarg(argc, "font", EXPECTED_AT_LEAST, 1))) {
- return error;
- }
-
- if (!config->current_bar) {
- return cmd_results_new(CMD_FAILURE, "font", "No bar defined.");
- }
-
- char *font = join_args(argv, argc);
- free(config->current_bar->font);
- if (strlen(font) > 6 && strncmp("pango:", font, 6) == 0) {
- config->current_bar->font = font;
- } else {
- config->current_bar->font = font;
- }
-
- sway_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/old/commands/bar/height.c b/sway/old/commands/bar/height.c
deleted file mode 100644
index eb576ab3..00000000
--- a/sway/old/commands/bar/height.c
+++ /dev/null
@@ -1,21 +0,0 @@
-#include <stdlib.h>
-#include <string.h>
-#include "sway/commands.h"
-#include "log.h"
-
-struct cmd_results *bar_cmd_height(int argc, char **argv) {
- struct cmd_results *error = NULL;
- if ((error = checkarg(argc, "height", EXPECTED_EQUAL_TO, 1))) {
- return error;
- }
-
- int height = atoi(argv[0]);
- if (height < 0) {
- return cmd_results_new(CMD_INVALID, "height",
- "Invalid height value: %s", argv[0]);
- }
-
- config->current_bar->height = height;
- sway_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/old/commands/bar/hidden_state.c b/sway/old/commands/bar/hidden_state.c
deleted file mode 100644
index 0b49aa6b..00000000
--- a/sway/old/commands/bar/hidden_state.c
+++ /dev/null
@@ -1,79 +0,0 @@
-#define _XOPEN_SOURCE 500
-#include <string.h>
-#include <strings.h>
-#include "sway/commands.h"
-#include "sway/config.h"
-#include "sway/ipc-server.h"
-#include "log.h"
-
-static struct cmd_results *bar_set_hidden_state(struct bar_config *bar, const char *hidden_state) {
- char *old_state = bar->hidden_state;
- if (strcasecmp("toggle", hidden_state) == 0 && !config->reading) {
- if (strcasecmp("hide", bar->hidden_state) == 0) {
- bar->hidden_state = strdup("show");
- } else if (strcasecmp("show", bar->hidden_state) == 0) {
- bar->hidden_state = strdup("hide");
- }
- } else if (strcasecmp("hide", hidden_state) == 0) {
- bar->hidden_state = strdup("hide");
- } else if (strcasecmp("show", hidden_state) == 0) {
- bar->hidden_state = strdup("show");
- } else {
- return cmd_results_new(CMD_INVALID, "hidden_state", "Invalid value %s", hidden_state);
- }
-
- if (strcmp(old_state, bar->hidden_state) != 0) {
- if (!config->reading) {
- ipc_event_barconfig_update(bar);
- }
- sway_log(L_DEBUG, "Setting hidden_state: '%s' for bar: %s", bar->hidden_state, bar->id);
- }
-
- // free old mode
- free(old_state);
- return cmd_results_new(CMD_SUCCESS, NULL, NULL);
-}
-
-struct cmd_results *bar_cmd_hidden_state(int argc, char **argv) {
- struct cmd_results *error = NULL;
- if ((error = checkarg(argc, "hidden_state", EXPECTED_AT_LEAST, 1))) {
- return error;
- }
- if ((error = checkarg(argc, "hidden_state", EXPECTED_LESS_THAN, 3))) {
- return error;
- }
-
- if (config->reading && argc > 1) {
- return cmd_results_new(CMD_INVALID, "hidden_state", "Unexpected value %s in config mode", argv[1]);
- }
-
- const char *state = argv[0];
-
- if (config->reading) {
- return bar_set_hidden_state(config->current_bar, state);
- }
-
- const char *id = NULL;
- if (argc == 2) {
- id = argv[1];
- }
-
- int i;
- struct bar_config *bar;
- for (i = 0; i < config->bars->length; ++i) {
- bar = config->bars->items[i];
- if (id && strcmp(id, bar->id) == 0) {
- return bar_set_hidden_state(bar, state);
- }
-
- error = bar_set_hidden_state(bar, state);
- if (error) {
- return error;
- }
- }
-
- // active bar modifiers might have changed.
- update_active_bar_modifiers();
-
- return cmd_results_new(CMD_SUCCESS, NULL, NULL);
-}
diff --git a/sway/old/commands/bar/icon_theme.c b/sway/old/commands/bar/icon_theme.c
deleted file mode 100644
index cbfc0be5..00000000
--- a/sway/old/commands/bar/icon_theme.c
+++ /dev/null
@@ -1,25 +0,0 @@
-#define _XOPEN_SOURCE 500
-#include <string.h>
-#include "sway/commands.h"
-
-struct cmd_results *bar_cmd_icon_theme(int argc, char **argv) {
- const char *cmd_name = "tray_output";
-#ifndef ENABLE_TRAY
- return cmd_results_new(CMD_INVALID, cmd_name, "Invalid %s command "
- "%s called, but sway was compiled without tray support",
- cmd_name, cmd_name);
-#else
- struct cmd_results *error = NULL;
- if ((error = checkarg(argc, cmd_name, EXPECTED_EQUAL_TO, 1))) {
- return error;
- }
-
- if (!config->current_bar) {
- return cmd_results_new(CMD_FAILURE, cmd_name, "No bar defined.");
- }
-
- config->current_bar->icon_theme = strdup(argv[0]);
-
- return cmd_results_new(CMD_SUCCESS, NULL, NULL);
-#endif
-}
diff --git a/sway/old/commands/bar/id.c b/sway/old/commands/bar/id.c
deleted file mode 100644
index 1221ebf6..00000000
--- a/sway/old/commands/bar/id.c
+++ /dev/null
@@ -1,33 +0,0 @@
-#define _XOPEN_SOURCE 500
-#include <string.h>
-#include "sway/commands.h"
-#include "log.h"
-
-struct cmd_results *bar_cmd_id(int argc, char **argv) {
- struct cmd_results *error = NULL;
- if ((error = checkarg(argc, "id", EXPECTED_EQUAL_TO, 1))) {
- return error;
- }
-
- const char *name = argv[0];
- const char *oldname = config->current_bar->id;
-
- // check if id is used by a previously defined bar
- int i;
- for (i = 0; i < config->bars->length; ++i) {
- struct bar_config *find = config->bars->items[i];
- if (strcmp(name, find->id) == 0 && config->current_bar != find) {
- return cmd_results_new(CMD_FAILURE, "id",
- "Id '%s' already defined for another bar. Id unchanged (%s).",
- name, oldname);
- }
- }
-
- sway_log(L_DEBUG, "Renaming bar: '%s' to '%s'", oldname, name);
-
- // free old bar id
- free(config->current_bar->id);
-
- config->current_bar->id = strdup(name);
- return cmd_results_new(CMD_SUCCESS, NULL, NULL);
-}
diff --git a/sway/old/commands/bar/mode.c b/sway/old/commands/bar/mode.c
deleted file mode 100644
index 36816b93..00000000
--- a/sway/old/commands/bar/mode.c
+++ /dev/null
@@ -1,81 +0,0 @@
-#define _XOPEN_SOURCE 500
-#include <string.h>
-#include <strings.h>
-#include "sway/commands.h"
-#include "sway/config.h"
-#include "sway/ipc-server.h"
-#include "log.h"
-
-static struct cmd_results *bar_set_mode(struct bar_config *bar, const char *mode) {
- char *old_mode = bar->mode;
- if (strcasecmp("toggle", mode) == 0 && !config->reading) {
- if (strcasecmp("dock", bar->mode) == 0) {
- bar->mode = strdup("hide");
- } else if (strcasecmp("hide", bar->mode) == 0) {
- bar->mode = strdup("dock");
- }
- } else if (strcasecmp("dock", mode) == 0) {
- bar->mode = strdup("dock");
- } else if (strcasecmp("hide", mode) == 0) {
- bar->mode = strdup("hide");
- } else if (strcasecmp("invisible", mode) == 0) {
- bar->mode = strdup("invisible");
- } else {
- return cmd_results_new(CMD_INVALID, "mode", "Invalid value %s", mode);
- }
-
- if (strcmp(old_mode, bar->mode) != 0) {
- if (!config->reading) {
- ipc_event_barconfig_update(bar);
-
- // active bar modifiers might have changed.
- update_active_bar_modifiers();
- }
- sway_log(L_DEBUG, "Setting mode: '%s' for bar: %s", bar->mode, bar->id);
- }
-
- // free old mode
- free(old_mode);
- return cmd_results_new(CMD_SUCCESS, NULL, NULL);
-}
-
-struct cmd_results *bar_cmd_mode(int argc, char **argv) {
- struct cmd_results *error = NULL;
- if ((error = checkarg(argc, "mode", EXPECTED_AT_LEAST, 1))) {
- return error;
- }
- if ((error = checkarg(argc, "mode", EXPECTED_LESS_THAN, 3))) {
- return error;
- }
-
- if (config->reading && argc > 1) {
- return cmd_results_new(CMD_INVALID, "mode", "Unexpected value %s in config mode", argv[1]);
- }
-
- const char *mode = argv[0];
-
- if (config->reading) {
- return bar_set_mode(config->current_bar, mode);
- }
-
- const char *id = NULL;
- if (argc == 2) {
- id = argv[1];
- }
-
- int i;
- struct bar_config *bar;
- for (i = 0; i < config->bars->length; ++i) {
- bar = config->bars->items[i];
- if (id && strcmp(id, bar->id) == 0) {
- return bar_set_mode(bar, mode);
- }
-
- error = bar_set_mode(bar, mode);
- if (error) {
- return error;
- }
- }
-
- return cmd_results_new(CMD_SUCCESS, NULL, NULL);
-}
diff --git a/sway/old/commands/bar/modifier.c b/sway/old/commands/bar/modifier.c
deleted file mode 100644
index 153d87e6..00000000
--- a/sway/old/commands/bar/modifier.c
+++ /dev/null
@@ -1,35 +0,0 @@
-#include <string.h>
-#include "sway/commands.h"
-#include "log.h"
-#include "stringop.h"
-#include "util.h"
-
-struct cmd_results *bar_cmd_modifier(int argc, char **argv) {
- struct cmd_results *error = NULL;
- if ((error = checkarg(argc, "modifier", EXPECTED_EQUAL_TO, 1))) {
- return error;
- }
-
- if (!config->current_bar) {
- return cmd_results_new(CMD_FAILURE, "modifier", "No bar defined.");
- }
-
- uint32_t mod = 0;
-
- list_t *split = split_string(argv[0], "+");
- for (int i = 0; i < split->length; ++i) {
- uint32_t tmp_mod;
- if ((tmp_mod = get_modifier_mask_by_name(split->items[i])) > 0) {
- mod |= tmp_mod;
- continue;
- } else {
- free_flat_list(split);
- return cmd_results_new(CMD_INVALID, "modifier", "Unknown modifier '%s'", split->items[i]);
- }
- }
- free_flat_list(split);
-
- config->current_bar->modifier = mod;
- sway_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/old/commands/bar/output.c b/sway/old/commands/bar/output.c
deleted file mode 100644
index a5710bc0..00000000
--- a/sway/old/commands/bar/output.c
+++ /dev/null
@@ -1,50 +0,0 @@
-#define _XOPEN_SOURCE 500
-#include <string.h>
-#include "sway/commands.h"
-#include "list.h"
-#include "log.h"
-
-struct cmd_results *bar_cmd_output(int argc, char **argv) {
- struct cmd_results *error = NULL;
- if ((error = checkarg(argc, "output", EXPECTED_EQUAL_TO, 1))) {
- return error;
- }
-
- if (!config->current_bar) {
- return cmd_results_new(CMD_FAILURE, "output", "No bar defined.");
- }
-
- const char *output = argv[0];
- list_t *outputs = config->current_bar->outputs;
- if (!outputs) {
- outputs = create_list();
- config->current_bar->outputs = outputs;
- }
-
- int i;
- int add_output = 1;
- if (strcmp("*", output) == 0) {
- // remove all previous defined outputs and replace with '*'
- for (i = 0; i < outputs->length; ++i) {
- free(outputs->items[i]);
- list_del(outputs, i);
- }
- } else {
- // only add output if not already defined with either the same
- // name or as '*'
- for (i = 0; i < outputs->length; ++i) {
- const char *find = outputs->items[i];
- if (strcmp("*", find) == 0 || strcmp(output, find) == 0) {
- add_output = 0;
- break;
- }
- }
- }
-
- if (add_output) {
- list_add(outputs, strdup(output));
- sway_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/old/commands/bar/pango_markup.c b/sway/old/commands/bar/pango_markup.c
deleted file mode 100644
index f69e882f..00000000
--- a/sway/old/commands/bar/pango_markup.c
+++ /dev/null
@@ -1,27 +0,0 @@
-#include <string.h>
-#include <strings.h>
-#include "sway/commands.h"
-#include "log.h"
-
-struct cmd_results *bar_cmd_pango_markup(int argc, char **argv) {
- struct cmd_results *error = NULL;
- if ((error = checkarg(argc, "pango_markup", EXPECTED_EQUAL_TO, 1))) {
- return error;
- }
-
- if (!config->current_bar) {
- return cmd_results_new(CMD_FAILURE, "pango_markup", "No bar defined.");
- }
-
- if (strcasecmp("enabled", argv[0]) == 0) {
- config->current_bar->pango_markup = true;
- sway_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;
- sway_log(L_DEBUG, "Disabling pango markup for bar: %s", config->current_bar->id);
- } else {
- error = cmd_results_new(CMD_INVALID, "pango_markup", "Invalid value %s", argv[0]);
- return error;
- }
- return cmd_results_new(CMD_SUCCESS, NULL, NULL);
-}
diff --git a/sway/old/commands/bar/position.c b/sway/old/commands/bar/position.c
deleted file mode 100644
index 50de58e2..00000000
--- a/sway/old/commands/bar/position.c
+++ /dev/null
@@ -1,33 +0,0 @@
-#include <string.h>
-#include <strings.h>
-#include "sway/commands.h"
-#include "log.h"
-
-struct cmd_results *bar_cmd_position(int argc, char **argv) {
- struct cmd_results *error = NULL;
- if ((error = checkarg(argc, "position", EXPECTED_EQUAL_TO, 1))) {
- return error;
- }
-
- if (!config->current_bar) {
- return cmd_results_new(CMD_FAILURE, "position", "No bar defined.");
- }
-
- if (strcasecmp("top", argv[0]) == 0) {
- config->current_bar->position = DESKTOP_SHELL_PANEL_POSITION_TOP;
- } else if (strcasecmp("bottom", argv[0]) == 0) {
- config->current_bar->position = DESKTOP_SHELL_PANEL_POSITION_BOTTOM;
- } else if (strcasecmp("left", argv[0]) == 0) {
- sway_log(L_INFO, "Warning: swaybar currently only supports top and bottom positioning. YMMV");
- config->current_bar->position = DESKTOP_SHELL_PANEL_POSITION_LEFT;
- } else if (strcasecmp("right", argv[0]) == 0) {
- sway_log(L_INFO, "Warning: swaybar currently only supports top and bottom positioning. YMMV");
- config->current_bar->position = DESKTOP_SHELL_PANEL_POSITION_RIGHT;
- } else {
- error = cmd_results_new(CMD_INVALID, "position", "Invalid value %s", argv[0]);
- return error;
- }
-
- sway_log(L_DEBUG, "Setting bar position '%s' for bar: %s", argv[0], config->current_bar->id);
- return cmd_results_new(CMD_SUCCESS, NULL, NULL);
-}
diff --git a/sway/old/commands/bar/secondary_button.c b/sway/old/commands/bar/secondary_button.c
deleted file mode 100644
index 745045c5..00000000
--- a/sway/old/commands/bar/secondary_button.c
+++ /dev/null
@@ -1,26 +0,0 @@
-#include <stdlib.h>
-#include "sway/commands.h"
-#include "log.h"
-
-struct cmd_results *bar_cmd_secondary_button(int argc, char **argv) {
- const char *cmd_name = "secondary_button";
-#ifndef ENABLE_TRAY
- return cmd_results_new(CMD_INVALID, cmd_name, "Invalid %s command "
- "%s called, but sway was compiled without tray support",
- cmd_name, cmd_name);
-#else
- struct cmd_results *error = NULL;
- if ((error = checkarg(argc, cmd_name, EXPECTED_EQUAL_TO, 1))) {
- return error;
- }
-
- if (!config->current_bar) {
- return cmd_results_new(CMD_FAILURE, cmd_name, "No bar defined.");
- }
-
- // User should be able to prefix with 0x or whatever they want
- config->current_bar->secondary_button = strtoul(argv[0], NULL, 0);
-
- return cmd_results_new(CMD_SUCCESS, NULL, NULL);
-#endif
-}
diff --git a/sway/old/commands/bar/separator_symbol.c b/sway/old/commands/bar/separator_symbol.c
deleted file mode 100644
index 2766d8a2..00000000
--- a/sway/old/commands/bar/separator_symbol.c
+++ /dev/null
@@ -1,21 +0,0 @@
-#define _XOPEN_SOURCE 500
-#include <string.h>
-#include "sway/commands.h"
-#include "log.h"
-
-struct cmd_results *bar_cmd_separator_symbol(int argc, char **argv) {
- struct cmd_results *error = NULL;
- if ((error = checkarg(argc, "separator_symbol", EXPECTED_EQUAL_TO, 1))) {
- return error;
- }
-
- if (!config->current_bar) {
- return cmd_results_new(CMD_FAILURE, "separator_symbol", "No bar defined.");
- }
-
- free(config->current_bar->separator_symbol);
- config->current_bar->separator_symbol = strdup(argv[0]);
- sway_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/old/commands/bar/status_command.c b/sway/old/commands/bar/status_command.c
deleted file mode 100644
index b227ac47..00000000
--- a/sway/old/commands/bar/status_command.c
+++ /dev/null
@@ -1,21 +0,0 @@
-#include <string.h>
-#include "sway/commands.h"
-#include "log.h"
-#include "stringop.h"
-
-struct cmd_results *bar_cmd_status_command(int argc, char **argv) {
- struct cmd_results *error = NULL;
- if ((error = checkarg(argc, "status_command", EXPECTED_AT_LEAST, 1))) {
- return error;
- }
-
- if (!config->current_bar) {
- return cmd_results_new(CMD_FAILURE, "status_command", "No bar defined.");
- }
-
- free(config->current_bar->status_command);
- config->current_bar->status_command = join_args(argv, argc);
- sway_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/old/commands/bar/strip_workspace_numbers.c b/sway/old/commands/bar/strip_workspace_numbers.c
deleted file mode 100644
index 9ac32482..00000000
--- a/sway/old/commands/bar/strip_workspace_numbers.c
+++ /dev/null
@@ -1,27 +0,0 @@
-#include <string.h>
-#include <strings.h>
-#include "sway/commands.h"
-#include "log.h"
-
-struct cmd_results *bar_cmd_strip_workspace_numbers(int argc, char **argv) {
- struct cmd_results *error = NULL;
- if ((error = checkarg(argc, "strip_workspace_numbers", EXPECTED_EQUAL_TO, 1))) {
- return error;
- }
-
- if (!config->current_bar) {
- return cmd_results_new(CMD_FAILURE, "strip_workspace_numbers", "No bar defined.");
- }
-
- if (strcasecmp("yes", argv[0]) == 0) {
- config->current_bar->strip_workspace_numbers = true;
- sway_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;
- sway_log(L_DEBUG, "Enabling workspace numbers on bar: %s", config->current_bar->id);
- } else {
- error = cmd_results_new(CMD_INVALID, "strip_workspace_numbers", "Invalid value %s", argv[0]);
- return error;
- }
- return cmd_results_new(CMD_SUCCESS, NULL, NULL);
-}
diff --git a/sway/old/commands/bar/swaybar_command.c b/sway/old/commands/bar/swaybar_command.c
deleted file mode 100644
index 452e2df5..00000000
--- a/sway/old/commands/bar/swaybar_command.c
+++ /dev/null
@@ -1,21 +0,0 @@
-#include <string.h>
-#include "sway/commands.h"
-#include "log.h"
-#include "stringop.h"
-
-struct cmd_results *bar_cmd_swaybar_command(int argc, char **argv) {
- struct cmd_results *error = NULL;
- if ((error = checkarg(argc, "swaybar_command", EXPECTED_AT_LEAST, 1))) {
- return error;
- }
-
- if (!config->current_bar) {
- return cmd_results_new(CMD_FAILURE, "swaybar_command", "No bar defined.");
- }
-
- free(config->current_bar->swaybar_command);
- config->current_bar->swaybar_command = join_args(argv, argc);
- sway_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/old/commands/bar/tray_output.c b/sway/old/commands/bar/tray_output.c
deleted file mode 100644
index 012304a9..00000000
--- a/sway/old/commands/bar/tray_output.c
+++ /dev/null
@@ -1,29 +0,0 @@
-#define _XOPEN_SOURCE 500
-#include <string.h>
-#include "sway/commands.h"
-
-struct cmd_results *bar_cmd_tray_output(int argc, char **argv) {
- const char *cmd_name = "tray_output";
-#ifndef ENABLE_TRAY
- return cmd_results_new(CMD_INVALID, cmd_name, "Invalid %s command "
- "%s called, but sway was compiled without tray support",
- cmd_name, cmd_name);
-#else
- struct cmd_results *error = NULL;
- if ((error = checkarg(argc, cmd_name, EXPECTED_EQUAL_TO, 1))) {
- return error;
- }
-
- if (!config->current_bar) {
- return cmd_results_new(CMD_FAILURE, cmd_name, "No bar defined.");
- }
-
- if (strcmp(argv[0], "all") == 0) {
- // Default behaviour
- return cmd_results_new(CMD_SUCCESS, NULL, NULL);
- }
- config->current_bar->tray_output = strdup(argv[0]);
-
- return cmd_results_new(CMD_SUCCESS, NULL, NULL);
-#endif
-}
diff --git a/sway/old/commands/bar/tray_padding.c b/sway/old/commands/bar/tray_padding.c
deleted file mode 100644
index ac0572ce..00000000
--- a/sway/old/commands/bar/tray_padding.c
+++ /dev/null
@@ -1,34 +0,0 @@
-#include <stdlib.h>
-#include <strings.h>
-#include "sway/commands.h"
-#include "log.h"
-
-struct cmd_results *bar_cmd_tray_padding(int argc, char **argv) {
- const char *cmd_name = "tray_padding";
-#ifndef ENABLE_TRAY
- return cmd_results_new(CMD_INVALID, cmd_name, "Invalid %s command"
- "%s called, but sway was compiled without tray support",
- cmd_name, cmd_name);
-#else
- struct cmd_results *error = NULL;
- if ((error = checkarg(argc, cmd_name, EXPECTED_AT_LEAST, 1))) {
- return error;
- }
-
- if (!config->current_bar) {
- return cmd_results_new(CMD_FAILURE, cmd_name, "No bar defined.");
- }
-
- if (argc == 1 || (argc == 2 && strcasecmp("px", argv[1]) == 0)) {
- char *inv;
- uint32_t padding = strtoul(argv[0], &inv, 10);
- if (*inv == '\0' || strcasecmp(inv, "px") == 0) {
- config->current_bar->tray_padding = padding;
- sway_log(L_DEBUG, "Enabling tray padding of %d px on bar: %s", padding, config->current_bar->id);
- return cmd_results_new(CMD_SUCCESS, NULL, NULL);
- }
- }
- return cmd_results_new(CMD_FAILURE, cmd_name,
- "Expected 'tray_padding <padding>[px]'");
-#endif
-}
diff --git a/sway/old/commands/bar/workspace_buttons.c b/sway/old/commands/bar/workspace_buttons.c
deleted file mode 100644
index 67dd2d31..00000000
--- a/sway/old/commands/bar/workspace_buttons.c
+++ /dev/null
@@ -1,27 +0,0 @@
-#include <string.h>
-#include <strings.h>
-#include "sway/commands.h"
-#include "log.h"
-
-struct cmd_results *bar_cmd_workspace_buttons(int argc, char **argv) {
- struct cmd_results *error = NULL;
- if ((error = checkarg(argc, "workspace_buttons", EXPECTED_EQUAL_TO, 1))) {
- return error;
- }
-
- if (!config->current_bar) {
- return cmd_results_new(CMD_FAILURE, "workspace_buttons", "No bar defined.");
- }
-
- if (strcasecmp("yes", argv[0]) == 0) {
- config->current_bar->workspace_buttons = true;
- sway_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;
- sway_log(L_DEBUG, "Disabling workspace buttons on bar: %s", config->current_bar->id);
- } else {
- error = cmd_results_new(CMD_INVALID, "workspace_buttons", "Invalid value %s", argv[0]);
- return error;
- }
- return cmd_results_new(CMD_SUCCESS, NULL, NULL);
-}
diff --git a/sway/old/commands/bar/wrap_scroll.c b/sway/old/commands/bar/wrap_scroll.c
deleted file mode 100644
index 4ed1f12a..00000000
--- a/sway/old/commands/bar/wrap_scroll.c
+++ /dev/null
@@ -1,27 +0,0 @@
-#include <string.h>
-#include <strings.h>
-#include "sway/commands.h"
-#include "log.h"
-
-struct cmd_results *bar_cmd_wrap_scroll(int argc, char **argv) {
- struct cmd_results *error = NULL;
- if ((error = checkarg(argc, "wrap_scroll", EXPECTED_EQUAL_TO, 1))) {
- return error;
- }
-
- if (!config->current_bar) {
- return cmd_results_new(CMD_FAILURE, "wrap_scroll", "No bar defined.");
- }
-
- if (strcasecmp("yes", argv[0]) == 0) {
- config->current_bar->wrap_scroll = true;
- sway_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;
- sway_log(L_DEBUG, "Disabling wrap scroll on bar: %s", config->current_bar->id);
- } else {
- error = cmd_results_new(CMD_INVALID, "wrap_scroll", "Invalid value %s", argv[0]);
- return error;
- }
- return cmd_results_new(CMD_SUCCESS, NULL, NULL);
-}
diff --git a/sway/old/commands/bind.c b/sway/old/commands/bind.c
deleted file mode 100644
index d9ea37b7..00000000
--- a/sway/old/commands/bind.c
+++ /dev/null
@@ -1,170 +0,0 @@
-#include <xkbcommon/xkbcommon.h>
-#include <xkbcommon/xkbcommon-names.h>
-#include <strings.h>
-#include "sway/commands.h"
-#include "sway/config.h"
-#include "sway/input_state.h"
-#include "list.h"
-#include "log.h"
-#include "stringop.h"
-#include "util.h"
-
-int binding_order = 0;
-
-struct cmd_results *cmd_bindsym(int argc, char **argv) {
- struct cmd_results *error = NULL;
- if ((error = checkarg(argc, "bindsym", EXPECTED_MORE_THAN, 1))) {
- return error;
- }
-
- struct sway_binding *binding = malloc(sizeof(struct sway_binding));
- if (!binding) {
- return cmd_results_new(CMD_FAILURE, "bindsym",
- "Unable to allocate binding");
- }
- binding->keys = create_list();
- binding->modifiers = 0;
- binding->release = false;
- binding->bindcode = false;
-
- // Handle --release
- if (strcmp("--release", argv[0]) == 0) {
- if (argc >= 3) {
- binding->release = true;
- argv++;
- argc--;
- } else {
- free_sway_binding(binding);
- return cmd_results_new(CMD_FAILURE, "bindsym",
- "Invalid bindsym command "
- "(expected more than 2 arguments, got %d)", argc);
- }
- }
-
- binding->command = join_args(argv + 1, argc - 1);
-
- list_t *split = split_string(argv[0], "+");
- for (int i = 0; i < split->length; ++i) {
- // Check for a modifier key
- uint32_t mod;
- if ((mod = get_modifier_mask_by_name(split->items[i])) > 0) {
- binding->modifiers |= mod;
- continue;
- }
- // Check for xkb key
- xkb_keysym_t sym = xkb_keysym_from_name(split->items[i],
- XKB_KEYSYM_CASE_INSENSITIVE);
-
- // Check for mouse binding
- if (strncasecmp(split->items[i], "button", strlen("button")) == 0 &&
- strlen(split->items[i]) == strlen("button0")) {
- sym = ((char *)split->items[i])[strlen("button")] - '1' + M_LEFT_CLICK;
- }
- if (!sym) {
- struct cmd_results *ret = cmd_results_new(CMD_INVALID, "bindsym",
- "Unknown key '%s'", (char *)split->items[i]);
- free_sway_binding(binding);
- free_flat_list(split);
- return ret;
- }
- xkb_keysym_t *key = malloc(sizeof(xkb_keysym_t));
- if (!key) {
- free_sway_binding(binding);
- free_flat_list(split);
- return cmd_results_new(CMD_FAILURE, "bindsym",
- "Unable to allocate binding");
- }
- *key = sym;
- list_add(binding->keys, key);
- }
- free_flat_list(split);
-
- struct sway_mode *mode = config->current_mode;
- int i = list_seq_find(mode->bindings, sway_binding_cmp_keys, binding);
- if (i > -1) {
- sway_log(L_DEBUG, "bindsym - '%s' already exists, overwriting", argv[0]);
- struct sway_binding *dup = mode->bindings->items[i];
- free_sway_binding(dup);
- list_del(mode->bindings, i);
- }
- binding->order = binding_order++;
- list_add(mode->bindings, binding);
- list_qsort(mode->bindings, sway_binding_cmp_qsort);
-
- sway_log(L_DEBUG, "bindsym - Bound %s to command %s", argv[0], binding->command);
- return cmd_results_new(CMD_SUCCESS, NULL, NULL);
-}
-
-struct cmd_results *cmd_bindcode(int argc, char **argv) {
- struct cmd_results *error = NULL;
- if ((error = checkarg(argc, "bindcode", EXPECTED_MORE_THAN, 1))) {
- return error;
- }
-
- struct sway_binding *binding = malloc(sizeof(struct sway_binding));
- if (!binding) {
- return cmd_results_new(CMD_FAILURE, "bindsym",
- "Unable to allocate binding");
- }
- binding->keys = create_list();
- binding->modifiers = 0;
- binding->release = false;
- binding->bindcode = true;
-
- // Handle --release
- if (strcmp("--release", argv[0]) == 0) {
- if (argc >= 3) {
- binding->release = true;
- argv++;
- argc--;
- } else {
- free_sway_binding(binding);
- return cmd_results_new(CMD_FAILURE, "bindcode",
- "Invalid bindcode command "
- "(expected more than 2 arguments, got %d)", argc);
- }
- }
-
- binding->command = join_args(argv + 1, argc - 1);
-
- list_t *split = split_string(argv[0], "+");
- for (int i = 0; i < split->length; ++i) {
- // Check for a modifier key
- uint32_t mod;
- if ((mod = get_modifier_mask_by_name(split->items[i])) > 0) {
- binding->modifiers |= mod;
- continue;
- }
- // parse keycode
- xkb_keycode_t keycode = (int)strtol(split->items[i], NULL, 10);
- if (!xkb_keycode_is_legal_ext(keycode)) {
- error = cmd_results_new(CMD_INVALID, "bindcode", "Invalid keycode '%s'", (char *)split->items[i]);
- free_sway_binding(binding);
- list_free(split);
- return error;
- }
- xkb_keycode_t *key = malloc(sizeof(xkb_keycode_t));
- *key = keycode - 8;
- list_add(binding->keys, key);
- }
- free_flat_list(split);
-
- struct sway_mode *mode = config->current_mode;
- int i = list_seq_find(mode->bindings, sway_binding_cmp_keys, binding);
- if (i > -1) {
- struct sway_binding *dup = mode->bindings->items[i];
- if (dup->bindcode) {
- sway_log(L_DEBUG, "bindcode - '%s' already exists, overwriting", argv[0]);
- } else {
- sway_log(L_DEBUG, "bindcode - '%s' already exists as bindsym, overwriting", argv[0]);
- }
- free_sway_binding(dup);
- list_del(mode->bindings, i);
- }
- binding->order = binding_order++;
- list_add(mode->bindings, binding);
- list_qsort(mode->bindings, sway_binding_cmp_qsort);
-
- sway_log(L_DEBUG, "bindcode - Bound %s to command %s", argv[0], binding->command);
- return cmd_results_new(CMD_SUCCESS, NULL, NULL);
-}
diff --git a/sway/old/commands/border.c b/sway/old/commands/border.c
deleted file mode 100644
index c888622e..00000000
--- a/sway/old/commands/border.c
+++ /dev/null
@@ -1,65 +0,0 @@
-#include <errno.h>
-#include <stdlib.h>
-#include <string.h>
-#include <strings.h>
-#include "sway/commands.h"
-#include "sway/container.h"
-#include "sway/focus.h"
-
-struct cmd_results *cmd_border(int argc, char **argv) {
- struct cmd_results *error = NULL;
- if (!config->active) {
- return cmd_results_new(CMD_FAILURE, "border", "Can only be used when sway is running.");
- }
- if ((error = checkarg(argc, "border", EXPECTED_AT_LEAST, 1))) {
- return error;
- }
-
- if (argc > 2) {
- return cmd_results_new(CMD_INVALID, "border",
- "Expected 'border <normal|pixel|none|toggle> [<n>]");
- }
-
- swayc_t *view = current_container;
- enum swayc_border_types border = view->border_type;
- int thickness = view->border_thickness;
-
- if (strcasecmp(argv[0], "none") == 0) {
- border = B_NONE;
- } else if (strcasecmp(argv[0], "normal") == 0) {
- border = B_NORMAL;
- } else if (strcasecmp(argv[0], "pixel") == 0) {
- border = B_PIXEL;
- } else if (strcasecmp(argv[0], "toggle") == 0) {
- switch (border) {
- case B_NONE:
- border = B_PIXEL;
- break;
- case B_NORMAL:
- border = B_NONE;
- break;
- case B_PIXEL:
- border = B_NORMAL;
- break;
- }
- } else {
- return cmd_results_new(CMD_INVALID, "border",
- "Expected 'border <normal|pixel|none|toggle>");
- }
-
- if (argc == 2 && (border == B_NORMAL || border == B_PIXEL)) {
- thickness = (int)strtol(argv[1], NULL, 10);
- if (errno == ERANGE || thickness < 0) {
- errno = 0;
- return cmd_results_new(CMD_INVALID, "border", "Number is out of range.");
- }
- }
-
- if (view) {
- view->border_type = border;
- view->border_thickness = thickness;
- update_geometry(view);
- }
-
- return cmd_results_new(CMD_SUCCESS, NULL, NULL);
-}
diff --git a/sway/old/commands/client.c b/sway/old/commands/client.c
deleted file mode 100644
index f3d879cd..00000000
--- a/sway/old/commands/client.c
+++ /dev/null
@@ -1,72 +0,0 @@
-#include <stdlib.h>
-#include <string.h>
-#include "sway/commands.h"
-
-static struct cmd_results *parse_border_color(struct border_colors *border_colors, const char *cmd_name, int argc, char **argv) {
- struct cmd_results *error = NULL;
- if (argc < 3 || argc > 5) {
- return cmd_results_new(CMD_INVALID, cmd_name, "Requires between three and five color values");
- }
-
- uint32_t *colors[5] = {
- &border_colors->border,
- &border_colors->background,
- &border_colors->text,
- &border_colors->indicator,
- &border_colors->child_border
- };
- int i;
- for (i = 0; i < argc; i++) {
- char buffer[10];
- error = add_color(cmd_name, buffer, argv[i]);
- if (error) {
- return error;
- }
- *colors[i] = strtoul(buffer + 1, NULL, 16);
- }
-
- if (argc < 5) {
- border_colors->child_border = border_colors->background;
- }
-
- return cmd_results_new(CMD_SUCCESS, NULL, NULL);
-}
-
-struct cmd_results *cmd_client_focused(int argc, char **argv) {
- return parse_border_color(&config->border_colors.focused, "client.focused", argc, argv);
-}
-
-struct cmd_results *cmd_client_focused_inactive(int argc, char **argv) {
- return parse_border_color(&config->border_colors.focused_inactive, "client.focused_inactive", argc, argv);
-}
-
-struct cmd_results *cmd_client_unfocused(int argc, char **argv) {
- return parse_border_color(&config->border_colors.unfocused, "client.unfocused", argc, argv);
-}
-
-struct cmd_results *cmd_client_urgent(int argc, char **argv) {
- return parse_border_color(&config->border_colors.urgent, "client.urgent", argc, argv);
-}
-
-struct cmd_results *cmd_client_placeholder(int argc, char **argv) {
- return parse_border_color(&config->border_colors.placeholder, "client.placeholder", argc, argv);
-}
-
-struct cmd_results *cmd_client_background(int argc, char **argv) {
- char buffer[10];
- struct cmd_results *error = NULL;
- uint32_t background;
-
- if (argc != 1) {
- return cmd_results_new(CMD_INVALID, "client.background", "Requires exactly one color value");
- }
-
- error = add_color("client.background", buffer, argv[0]);
- if (error) {
- return error;
- }
-
- background = strtoul(buffer+1, NULL, 16);
- config->border_colors.background = background;
- return cmd_results_new(CMD_SUCCESS, NULL, NULL);
-}
diff --git a/sway/old/commands/clipboard.c b/sway/old/commands/clipboard.c
deleted file mode 100644
index 95514e78..00000000
--- a/sway/old/commands/clipboard.c
+++ /dev/null
@@ -1,38 +0,0 @@
-#include <wlc/wlc.h>
-#include <unistd.h>
-#include <string.h>
-#include "sway/commands.h"
-#include "stringop.h"
-
-static void send_clipboard(void *data, const char *type, int fd) {
- if (strcmp(type, "text/plain") != 0
- && strcmp(type, "text/plain;charset=utf-8") != 0) {
- close(fd);
- return;
- }
-
- const char *str = data;
- write(fd, str, strlen(str));
- close(fd);
-}
-
-struct cmd_results *cmd_clipboard(int argc, char **argv) {
- static char *current_data = NULL;
-
- struct cmd_results *error = NULL;
- if ((error = checkarg(argc, "clipboard", EXPECTED_AT_LEAST, 1))) {
- return error;
- }
-
- static const char *types[2] = {
- "text/plain",
- "text/plain;charset=utf-8"
- };
-
- char *str = join_args(argv, argc);
- wlc_set_selection(str, types, 2, &send_clipboard);
-
- free(current_data);
- current_data = str;
- return cmd_results_new(CMD_SUCCESS, NULL, NULL);
-}
diff --git a/sway/old/commands/commands.c b/sway/old/commands/commands.c
deleted file mode 100644
index 0c64970c..00000000
--- a/sway/old/commands/commands.c
+++ /dev/null
@@ -1,26 +0,0 @@
-#include <stdbool.h>
-#include <string.h>
-#include "sway/commands.h"
-#include "sway/config.h"
-#include "list.h"
-#include "log.h"
-
-struct cmd_results *cmd_commands(int argc, char **argv) {
- struct cmd_results *error = NULL;
- if ((error = checkarg(argc, "commands", EXPECTED_EQUAL_TO, 1))) {
- return error;
- }
- if ((error = check_security_config())) {
- return error;
- }
-
- if (strcmp(argv[0], "{") != 0) {
- return cmd_results_new(CMD_FAILURE, "commands", "Expected block declaration");
- }
-
- if (!config->reading) {
- return cmd_results_new(CMD_FAILURE, "commands", "Can only be used in config file.");
- }
-
- return cmd_results_new(CMD_BLOCK_COMMANDS, NULL, NULL);
-}
diff --git a/sway/old/commands/debuglog.c b/sway/old/commands/debuglog.c
deleted file mode 100644
index 658d6165..00000000
--- a/sway/old/commands/debuglog.c
+++ /dev/null
@@ -1,27 +0,0 @@
-#include <string.h>
-#include <strings.h>
-#include "sway/commands.h"
-#include "log.h"
-
-struct cmd_results *cmd_debuglog(int argc, char **argv) {
- struct cmd_results *error = NULL;
- if ((error = checkarg(argc, "debuglog", EXPECTED_EQUAL_TO, 1))) {
- return error;
- } else if (strcasecmp(argv[0], "toggle") == 0) {
- if (config->reading) {
- return cmd_results_new(CMD_FAILURE, "debuglog toggle", "Can't be used in config file.");
- }
- if (toggle_debug_logging()) {
- sway_log(L_DEBUG, "Debuglog turned on.");
- }
- } else if (strcasecmp(argv[0], "on") == 0) {
- set_log_level(L_DEBUG);
- sway_log(L_DEBUG, "Debuglog turned on.");
- } else if (strcasecmp(argv[0], "off") == 0) {
- reset_log_level();
- } else {
- return cmd_results_new(CMD_FAILURE, "debuglog", "Expected 'debuglog on|off|toggle'");
- }
- return cmd_results_new(CMD_SUCCESS, NULL, NULL);
-}
-
diff --git a/sway/old/commands/default_border.c b/sway/old/commands/default_border.c
deleted file mode 100644
index 8fbe8d19..00000000
--- a/sway/old/commands/default_border.c
+++ /dev/null
@@ -1,44 +0,0 @@
-#include <errno.h>
-#include <string.h>
-#include <strings.h>
-#include "sway/commands.h"
-#include "sway/container.h"
-
-struct cmd_results *cmd_default_border(int argc, char **argv) {
- struct cmd_results *error = NULL;
- if ((error = checkarg(argc, "default_border", EXPECTED_AT_LEAST, 1))) {
- return error;
- }
-
- if (argc > 2) {
- return cmd_results_new(CMD_INVALID, "default_border",
- "Expected 'default_border <normal|none|pixel> [<n>]");
- }
-
- enum swayc_border_types border = config->border;
- int thickness = config->border_thickness;
-
- if (strcasecmp(argv[0], "none") == 0) {
- border = B_NONE;
- } else if (strcasecmp(argv[0], "normal") == 0) {
- border = B_NORMAL;
- } else if (strcasecmp(argv[0], "pixel") == 0) {
- border = B_PIXEL;
- } else {
- return cmd_results_new(CMD_INVALID, "default_border",
- "Expected 'default_border <normal|none|pixel> [<n>]");
- }
-
- if (argc == 2 && (border == B_NORMAL || border == B_PIXEL)) {
- thickness = (int)strtol(argv[1], NULL, 10);
- if (errno == ERANGE || thickness < 0) {
- errno = 0;
- return cmd_results_new(CMD_INVALID, "default_border", "Number is out out of range.");
- }
- }
-
- config->border = border;
- config->border_thickness = thickness;
-
- return cmd_results_new(CMD_SUCCESS, NULL, NULL);
-}
diff --git a/sway/old/commands/default_floating_border.c b/sway/old/commands/default_floating_border.c
deleted file mode 100644
index fb48c1c0..00000000
--- a/sway/old/commands/default_floating_border.c
+++ /dev/null
@@ -1,45 +0,0 @@
-#include <errno.h>
-#include <string.h>
-#include <strings.h>
-#include "sway/commands.h"
-#include "sway/container.h"
-
-struct cmd_results *cmd_default_floating_border(int argc, char **argv) {
- struct cmd_results *error = NULL;
- if ((error = checkarg(argc, "default_floating_border", EXPECTED_AT_LEAST, 1))) {
- return error;
- }
-
- if (argc > 2) {
- return cmd_results_new(CMD_INVALID, "default_floating_border",
- "Expected 'default_floating_border <normal|none|pixel> [<n>]");
- }
-
- enum swayc_border_types border = config->floating_border;
- int thickness = config->floating_border_thickness;
-
- if (strcasecmp(argv[0], "none") == 0) {
- border = B_NONE;
- } else if (strcasecmp(argv[0], "normal") == 0) {
- border = B_NORMAL;
- } else if (strcasecmp(argv[0], "pixel") == 0) {
- border = B_PIXEL;
- } else {
- return cmd_results_new(CMD_INVALID, "default_floating_border",
- "Expected 'default_floating_border <normal|none|pixel> [<n>]");
- }
-
- if (argc == 2 && (border == B_NORMAL || border == B_PIXEL)) {
- thickness = (int)strtol(argv[1], NULL, 10);
- if (errno == ERANGE || thickness < 0) {
- errno = 0;
- return cmd_results_new(CMD_INVALID, "default_floating_border",
- "Number is out out of range.");
- }
- }
-
- config->floating_border = border;
- config->floating_border_thickness = thickness;
-
- return cmd_results_new(CMD_SUCCESS, NULL, NULL);
-}
diff --git a/sway/old/commands/exec.c b/sway/old/commands/exec.c
deleted file mode 100644
index 58ef5f94..00000000
--- a/sway/old/commands/exec.c
+++ /dev/null
@@ -1,16 +0,0 @@
-#include <string.h>
-#include "sway/commands.h"
-#include "log.h"
-#include "stringop.h"
-
-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);
- sway_log(L_DEBUG, "Ignoring 'exec %s' due to reload", args);
- free(args);
- return cmd_results_new(CMD_SUCCESS, NULL, NULL);
- }
- return cmd_exec_always(argc, argv);
-}
-
diff --git a/sway/old/commands/exec_always.c b/sway/old/commands/exec_always.c
deleted file mode 100644
index ab2d8622..00000000
--- a/sway/old/commands/exec_always.c
+++ /dev/null
@@ -1,85 +0,0 @@
-#define _XOPEN_SOURCE 500
-#include <string.h>
-#include <sys/wait.h>
-#include <unistd.h>
-#include "sway/commands.h"
-#include "sway/config.h"
-#include "log.h"
-#include "stringop.h"
-
-struct cmd_results *cmd_exec_always(int argc, char **argv) {
- struct cmd_results *error = NULL;
- if (!config->active) return cmd_results_new(CMD_DEFER, NULL, NULL);
- if ((error = checkarg(argc, "exec_always", EXPECTED_MORE_THAN, 0))) {
- return error;
- }
-
- char *tmp = NULL;
- if (strcmp((char*)*argv, "--no-startup-id") == 0) {
- sway_log(L_INFO, "exec switch '--no-startup-id' not supported, ignored.");
- if ((error = checkarg(argc - 1, "exec_always", EXPECTED_MORE_THAN, 0))) {
- return error;
- }
-
- tmp = join_args(argv + 1, argc - 1);
- } else {
- tmp = join_args(argv, argc);
- }
-
- // Put argument into cmd array
- char cmd[4096];
- strncpy(cmd, tmp, sizeof(cmd));
- cmd[sizeof(cmd) - 1] = 0;
- free(tmp);
- sway_log(L_DEBUG, "Executing %s", cmd);
-
- int fd[2];
- if (pipe(fd) != 0) {
- sway_log(L_ERROR, "Unable to create pipe for fork");
- }
-
- 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();
- if ((*child = fork()) == 0) {
- execl("/bin/sh", "/bin/sh", "-c", cmd, (void *)NULL);
- /* 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);
- }
- close(fd[1]);
- _exit(0); // Close child process
- } else if (pid < 0) {
- 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);
- }
- close(fd[0]);
- // cleanup child process
- wait(0);
- swayc_t *ws = swayc_active_workspace();
- if (*child > 0 && ws) {
- sway_log(L_DEBUG, "Child process created with pid %d for workspace %s", *child, ws->name);
- struct pid_workspace *pw = malloc(sizeof(struct pid_workspace));
- pw->pid = child;
- pw->workspace = strdup(ws->name);
- pid_workspace_add(pw);
- } else {
- free(child);
- }
-
- return cmd_results_new(CMD_SUCCESS, NULL, NULL);
-}
diff --git a/sway/old/commands/exit.c b/sway/old/commands/exit.c
deleted file mode 100644
index f192f86a..00000000
--- a/sway/old/commands/exit.c
+++ /dev/null
@@ -1,17 +0,0 @@
-#include "sway/commands.h"
-#include "sway/container.h"
-
-void sway_terminate(int exit_code);
-
-struct cmd_results *cmd_exit(int argc, char **argv) {
- struct cmd_results *error = NULL;
- if (config->reading) return cmd_results_new(CMD_FAILURE, "exit", "Can't be used in config file.");
- if ((error = checkarg(argc, "exit", EXPECTED_EQUAL_TO, 0))) {
- return error;
- }
- // Close all views
- close_views(&root_container);
- sway_terminate(EXIT_SUCCESS);
- return cmd_results_new(CMD_SUCCESS, NULL, NULL);
-}
-
diff --git a/sway/old/commands/floating.c b/sway/old/commands/floating.c
deleted file mode 100644
index ccfde532..00000000
--- a/sway/old/commands/floating.c
+++ /dev/null
@@ -1,81 +0,0 @@
-#include <string.h>
-#include <strings.h>
-#include "sway/commands.h"
-#include "sway/container.h"
-#include "sway/ipc-server.h"
-#include "sway/layout.h"
-#include "list.h"
-#include "log.h"
-
-struct cmd_results *cmd_floating(int argc, char **argv) {
- struct cmd_results *error = NULL;
- if (config->reading) return cmd_results_new(CMD_FAILURE, "floating", "Can't be used in config file.");
- if ((error = checkarg(argc, "floating", EXPECTED_EQUAL_TO, 1))) {
- return error;
- }
- swayc_t *view = current_container;
- bool wants_floating;
- if (strcasecmp(argv[0], "enable") == 0) {
- wants_floating = true;
- } else if (strcasecmp(argv[0], "disable") == 0) {
- wants_floating = false;
- } else if (strcasecmp(argv[0], "toggle") == 0) {
- wants_floating = !view->is_floating;
- } else {
- return cmd_results_new(CMD_FAILURE, "floating",
- "Expected 'floating <enable|disable|toggle>");
- }
-
- // Prevent running floating commands on things like workspaces
- if (view->type != C_VIEW) {
- return cmd_results_new(CMD_SUCCESS, NULL, NULL);
- }
-
- // Change from nonfloating to floating
- if (!view->is_floating && wants_floating) {
- // Remove view from its current location
- destroy_container(remove_child(view));
-
- // and move it into workspace floating
- add_floating(swayc_active_workspace(), view);
- view->x = (swayc_active_workspace()->width - view->width)/2;
- view->y = (swayc_active_workspace()->height - view->height)/2;
- if (view->desired_width != -1) {
- view->width = view->desired_width;
- }
- if (view->desired_height != -1) {
- view->height = view->desired_height;
- }
- arrange_windows(swayc_active_workspace(), -1, -1);
-
- } else if (view->is_floating && !wants_floating) {
- // Delete the view from the floating list and unset its is_floating flag
- remove_child(view);
- view->is_floating = false;
- // Get the properly focused container, and add in the view there
- swayc_t *focused = container_under_pointer();
- // If focused is null, it's because the currently focused container is a workspace
- if (focused == NULL || focused->is_floating) {
- focused = swayc_active_workspace();
- }
- set_focused_container(focused);
-
- sway_log(L_DEBUG, "Non-floating focused container is %p", focused);
-
- // Case of focused workspace, just create as child of it
- if (focused->type == C_WORKSPACE) {
- add_child(focused, view);
- }
- // Regular case, create as sibling of current container
- else {
- add_sibling(focused, view);
- }
- // Refocus on the view once its been put back into the layout
- view->width = view->height = 0;
- arrange_windows(swayc_active_workspace(), -1, -1);
- remove_view_from_scratchpad(view);
- ipc_event_window(view, "floating");
- }
- set_focused_container(view);
- return cmd_results_new(CMD_SUCCESS, NULL, NULL);
-}
diff --git a/sway/old/commands/floating_maximum_size.c b/sway/old/commands/floating_maximum_size.c
deleted file mode 100644
index 5bca4d7c..00000000
--- a/sway/old/commands/floating_maximum_size.c
+++ /dev/null
@@ -1,38 +0,0 @@
-#include <stdlib.h>
-#include <string.h>
-#include "sway/commands.h"
-#include "log.h"
-
-struct cmd_results *cmd_floating_maximum_size(int argc, char **argv) {
- struct cmd_results *error = NULL;
- int32_t width;
- int32_t height;
- char *ptr;
-
- if ((error = checkarg(argc, "floating_maximum_size", EXPECTED_EQUAL_TO, 3))) {
- return error;
- }
- width = strtol(argv[0], &ptr, 10);
- height = strtol(argv[2], &ptr, 10);
-
- if (width < -1) {
- sway_log(L_DEBUG, "floating_maximum_size invalid width value: '%s'", argv[0]);
-
- } else {
- config->floating_maximum_width = width;
-
- }
-
- if (height < -1) {
- sway_log(L_DEBUG, "floating_maximum_size invalid height value: '%s'", argv[2]);
- }
- else {
- config->floating_maximum_height = height;
-
- }
-
- sway_log(L_DEBUG, "New floating_maximum_size: '%d' x '%d'", config->floating_maximum_width,
- config->floating_maximum_height);
-
- return cmd_results_new(CMD_SUCCESS, NULL, NULL);
-}
diff --git a/sway/old/commands/floating_minimum_size.c b/sway/old/commands/floating_minimum_size.c
deleted file mode 100644
index ba72454c..00000000
--- a/sway/old/commands/floating_minimum_size.c
+++ /dev/null
@@ -1,38 +0,0 @@
-#include <stdlib.h>
-#include <string.h>
-#include "sway/commands.h"
-#include "log.h"
-
-struct cmd_results *cmd_floating_minimum_size(int argc, char **argv) {
- struct cmd_results *error = NULL;
- int32_t width;
- int32_t height;
- char *ptr;
-
- if ((error = checkarg(argc, "floating_minimum_size", EXPECTED_EQUAL_TO, 3))) {
- return error;
- }
- width = strtol(argv[0], &ptr, 10);
- height = strtol(argv[2], &ptr, 10);
-
- if (width <= 0) {
- sway_log(L_DEBUG, "floating_minimum_size invalid width value: '%s'", argv[0]);
-
- } else {
- config->floating_minimum_width = width;
-
- }
-
- if (height <= 0) {
- sway_log(L_DEBUG, "floating_minimum_size invalid height value: '%s'", argv[2]);
- }
- else {
- config->floating_minimum_height = height;
-
- }
-
- sway_log(L_DEBUG, "New floating_minimum_size: '%d' x '%d'", config->floating_minimum_width,
- config->floating_minimum_height);
-
- return cmd_results_new(CMD_SUCCESS, NULL, NULL);
-}
diff --git a/sway/old/commands/floating_mod.c b/sway/old/commands/floating_mod.c
deleted file mode 100644
index b8e81ab9..00000000
--- a/sway/old/commands/floating_mod.c
+++ /dev/null
@@ -1,42 +0,0 @@
-#include <string.h>
-#include <strings.h>
-#include "sway/commands.h"
-#include "sway/input_state.h"
-#include "list.h"
-#include "log.h"
-#include "stringop.h"
-#include "util.h"
-
-struct cmd_results *cmd_floating_mod(int argc, char **argv) {
- struct cmd_results *error = NULL;
- if ((error = checkarg(argc, "floating_modifier", EXPECTED_AT_LEAST, 1))) {
- return error;
- }
- int i;
- list_t *split = split_string(argv[0], "+");
- config->floating_mod = 0;
-
- // set modifier keys
- for (i = 0; i < split->length; ++i) {
- config->floating_mod |= get_modifier_mask_by_name(split->items[i]);
- }
- free_flat_list(split);
- if (!config->floating_mod) {
- error = cmd_results_new(CMD_INVALID, "floating_modifier", "Unknown keys %s", argv[0]);
- return error;
- }
-
- if (argc >= 2) {
- if (strcasecmp("inverse", argv[1]) == 0) {
- config->dragging_key = M_RIGHT_CLICK;
- config->resizing_key = M_LEFT_CLICK;
- } else if (strcasecmp("normal", argv[1]) == 0) {
- config->dragging_key = M_LEFT_CLICK;
- config->resizing_key = M_RIGHT_CLICK;
- } else {
- error = cmd_results_new(CMD_INVALID, "floating_modifier", "Invalid definition %s", argv[1]);
- return error;
- }
- }
- return cmd_results_new(CMD_SUCCESS, NULL, NULL);
-}
diff --git a/sway/old/commands/floating_scroll.c b/sway/old/commands/floating_scroll.c
deleted file mode 100644
index 8c50c5bd..00000000
--- a/sway/old/commands/floating_scroll.c
+++ /dev/null
@@ -1,46 +0,0 @@
-#define _XOPEN_SOURCE 500
-#include <string.h>
-#include <strings.h>
-#include "sway/commands.h"
-#include "log.h"
-#include "stringop.h"
-
-struct cmd_results *cmd_floating_scroll(int argc, char **argv) {
- struct cmd_results *error = NULL;
- if ((error = checkarg(argc, "floating_scroll", EXPECTED_AT_LEAST, 1))) {
- return error;
- }
- if (!strcasecmp("up", argv[0])) {
- free(config->floating_scroll_up_cmd);
- if (argc < 2) {
- config->floating_scroll_up_cmd = strdup("");
- } else {
- config->floating_scroll_up_cmd = join_args(argv + 1, argc - 1);
- }
- } else if (!strcasecmp("down", argv[0])) {
- free(config->floating_scroll_down_cmd);
- if (argc < 2) {
- config->floating_scroll_down_cmd = strdup("");
- } else {
- config->floating_scroll_down_cmd = join_args(argv + 1, argc - 1);
- }
- } else if (!strcasecmp("left", argv[0])) {
- free(config->floating_scroll_left_cmd);
- if (argc < 2) {
- config->floating_scroll_left_cmd = strdup("");
- } else {
- config->floating_scroll_left_cmd = join_args(argv + 1, argc - 1);
- }
- } else if (!strcasecmp("right", argv[0])) {
- free(config->floating_scroll_right_cmd);
- if (argc < 2) {
- config->floating_scroll_right_cmd = strdup("");
- } else {
- config->floating_scroll_right_cmd = join_args(argv + 1, argc - 1);
- }
- } else {
- error = cmd_results_new(CMD_INVALID, "floating_scroll", "Unknown command: '%s'", argv[0]);
- return error;
- }
- return cmd_results_new(CMD_SUCCESS, NULL, NULL);
-}
diff --git a/sway/old/commands/focus.c b/sway/old/commands/focus.c
deleted file mode 100644
index c83157b8..00000000
--- a/sway/old/commands/focus.c
+++ /dev/null
@@ -1,100 +0,0 @@
-#define _POSIX_C_SOURCE 200809L
-#include <string.h>
-#include <strings.h>
-#include <wlc/wlc.h>
-#include "sway/commands.h"
-#include "sway/container.h"
-#include "sway/focus.h"
-#include "sway/input_state.h"
-#include "sway/output.h"
-#include "sway/workspace.h"
-
-struct cmd_results *cmd_focus(int argc, char **argv) {
- if (config->reading) return cmd_results_new(CMD_FAILURE, "focus", "Can't be used in config file.");
- struct cmd_results *error = NULL;
- if (argc > 0 && strcasecmp(argv[0], "output") == 0) {
- swayc_t *output = NULL;
- struct wlc_point abs_pos;
- get_absolute_center_position(get_focused_container(&root_container), &abs_pos);
- if ((error = checkarg(argc, "focus", EXPECTED_EQUAL_TO, 2))) {
- return error;
- } else if (!(output = output_by_name(argv[1], &abs_pos))) {
- return cmd_results_new(CMD_FAILURE, "focus output",
- "Can't find output with name/at direction '%s' @ (%i,%i)", argv[1], abs_pos.x, abs_pos.y);
- } else if (!workspace_switch(swayc_active_workspace_for(output))) {
- return cmd_results_new(CMD_FAILURE, "focus output",
- "Switching to workspace on output '%s' was blocked", argv[1]);
- } else if (config->mouse_warping) {
- swayc_t *focused = get_focused_view(output);
- if (focused && focused->type == C_VIEW) {
- center_pointer_on(focused);
- }
- }
- return cmd_results_new(CMD_SUCCESS, NULL, NULL);
- } else if (argc == 0) {
- set_focused_container(current_container);
- return cmd_results_new(CMD_SUCCESS, NULL, NULL);
- } else if ((error = checkarg(argc, "focus", EXPECTED_EQUAL_TO, 1))) {
- return error;
- }
- static int floating_toggled_index = 0;
- static int tiled_toggled_index = 0;
- if (strcasecmp(argv[0], "left") == 0) {
- move_focus(MOVE_LEFT);
- } else if (strcasecmp(argv[0], "right") == 0) {
- move_focus(MOVE_RIGHT);
- } else if (strcasecmp(argv[0], "up") == 0) {
- move_focus(MOVE_UP);
- } else if (strcasecmp(argv[0], "down") == 0) {
- move_focus(MOVE_DOWN);
- } else if (strcasecmp(argv[0], "parent") == 0) {
- move_focus(MOVE_PARENT);
- } else if (strcasecmp(argv[0], "child") == 0) {
- move_focus(MOVE_CHILD);
- } else if (strcasecmp(argv[0], "next") == 0) {
- move_focus(MOVE_NEXT);
- } else if (strcasecmp(argv[0], "prev") == 0) {
- move_focus(MOVE_PREV);
- } else if (strcasecmp(argv[0], "mode_toggle") == 0) {
- int i;
- swayc_t *workspace = swayc_active_workspace();
- swayc_t *focused = get_focused_view(workspace);
- if (focused->is_floating) {
- if (workspace->children->length > 0) {
- for (i = 0;i < workspace->floating->length; i++) {
- if (workspace->floating->items[i] == focused) {
- floating_toggled_index = i;
- break;
- }
- }
- if (workspace->children->length > tiled_toggled_index) {
- set_focused_container(get_focused_view(workspace->children->items[tiled_toggled_index]));
- } else {
- set_focused_container(get_focused_view(workspace->children->items[0]));
- tiled_toggled_index = 0;
- }
- }
- } else {
- if (workspace->floating->length > 0) {
- for (i = 0;i < workspace->children->length; i++) {
- if (workspace->children->items[i] == focused) {
- tiled_toggled_index = i;
- break;
- }
- }
- if (workspace->floating->length > floating_toggled_index) {
- swayc_t *floating = workspace->floating->items[floating_toggled_index];
- set_focused_container(get_focused_view(floating));
- } else {
- swayc_t *floating = workspace->floating->items[workspace->floating->length - 1];
- set_focused_container(get_focused_view(floating));
- tiled_toggled_index = workspace->floating->length - 1;
- }
- }
- }
- } else {
- return cmd_results_new(CMD_INVALID, "focus",
- "Expected 'focus <direction|parent|child|mode_toggle>' or 'focus output <direction|name>'");
- }
- return cmd_results_new(CMD_SUCCESS, NULL, NULL);
-}
diff --git a/sway/old/commands/focus_follows_mouse.c b/sway/old/commands/focus_follows_mouse.c
deleted file mode 100644
index 7c9c2b13..00000000
--- a/sway/old/commands/focus_follows_mouse.c
+++ /dev/null
@@ -1,13 +0,0 @@
-#include <string.h>
-#include <strings.h>
-#include "sway/commands.h"
-
-struct cmd_results *cmd_focus_follows_mouse(int argc, char **argv) {
- struct cmd_results *error = NULL;
- if ((error = checkarg(argc, "focus_follows_mouse", EXPECTED_EQUAL_TO, 1))) {
- return error;
- }
-
- config->focus_follows_mouse = !strcasecmp(argv[0], "yes");
- return cmd_results_new(CMD_SUCCESS, NULL, NULL);
-}
diff --git a/sway/old/commands/font.c b/sway/old/commands/font.c
deleted file mode 100644
index 32994f8a..00000000
--- a/sway/old/commands/font.c
+++ /dev/null
@@ -1,27 +0,0 @@
-#define _XOPEN_SOURCE 500
-#include <string.h>
-#include "sway/border.h"
-#include "sway/commands.h"
-#include "log.h"
-#include "stringop.h"
-
-struct cmd_results *cmd_font(int argc, char **argv) {
- struct cmd_results *error = NULL;
- if ((error = checkarg(argc, "font", EXPECTED_AT_LEAST, 1))) {
- return error;
- }
-
- char *font = join_args(argv, argc);
- free(config->font);
- if (strlen(font) > 6 && strncmp("pango:", font, 6) == 0) {
- config->font = strdup(font + 6);
- free(font);
- } else {
- config->font = font;
- }
-
- config->font_height = get_font_text_height(config->font);
-
- sway_log(L_DEBUG, "Settings font %s", config->font);
- return cmd_results_new(CMD_SUCCESS, NULL, NULL);
-}
diff --git a/sway/old/commands/for_window.c b/sway/old/commands/for_window.c
deleted file mode 100644
index d1fd1641..00000000
--- a/sway/old/commands/for_window.c
+++ /dev/null
@@ -1,41 +0,0 @@
-#define _XOPEN_SOURCE 500
-#include <string.h>
-#include "sway/commands.h"
-#include "sway/criteria.h"
-#include "list.h"
-#include "log.h"
-#include "stringop.h"
-
-struct cmd_results *cmd_for_window(int argc, char **argv) {
- struct cmd_results *error = NULL;
- if ((error = checkarg(argc, "for_window", EXPECTED_AT_LEAST, 2))) {
- return error;
- }
- // add command to a criteria/command pair that is run against views when they appear.
- char *criteria = argv[0], *cmdlist = join_args(argv + 1, argc - 1);
-
- struct criteria *crit = malloc(sizeof(struct criteria));
- if (!crit) {
- return cmd_results_new(CMD_FAILURE, "for_window", "Unable to allocate criteria");
- }
- crit->crit_raw = strdup(criteria);
- crit->cmdlist = cmdlist;
- crit->tokens = create_list();
- char *err_str = extract_crit_tokens(crit->tokens, crit->crit_raw);
-
- if (err_str) {
- error = cmd_results_new(CMD_INVALID, "for_window", err_str);
- free(err_str);
- free_criteria(crit);
- } else if (crit->tokens->length == 0) {
- error = cmd_results_new(CMD_INVALID, "for_window", "Found no name/value pairs in criteria");
- free_criteria(crit);
- } else if (list_seq_find(config->criteria, criteria_cmp, crit) != -1) {
- sway_log(L_DEBUG, "for_window: Duplicate, skipping.");
- free_criteria(crit);
- } else {
- sway_log(L_DEBUG, "for_window: '%s' -> '%s' added", crit->crit_raw, crit->cmdlist);
- list_add(config->criteria, crit);
- }
- return error ? error : cmd_results_new(CMD_SUCCESS, NULL, NULL);
-}
diff --git a/sway/old/commands/force_focus_wrapping.c b/sway/old/commands/force_focus_wrapping.c
deleted file mode 100644
index f19dd163..00000000
--- a/sway/old/commands/force_focus_wrapping.c
+++ /dev/null
@@ -1,13 +0,0 @@
-#include <string.h>
-#include <strings.h>
-#include "sway/commands.h"
-
-struct cmd_results *cmd_force_focus_wrapping(int argc, char **argv) {
- struct cmd_results *error = NULL;
- if ((error = checkarg(argc, "force_focus_wrapping", EXPECTED_EQUAL_TO, 1))) {
- return error;
- }
-
- config->force_focus_wrapping = !strcasecmp(argv[0], "yes");
- return cmd_results_new(CMD_SUCCESS, NULL, NULL);
-}
diff --git a/sway/old/commands/fullscreen.c b/sway/old/commands/fullscreen.c
deleted file mode 100644
index bfff82f9..00000000
--- a/sway/old/commands/fullscreen.c
+++ /dev/null
@@ -1,60 +0,0 @@
-#include <stdbool.h>
-#include <string.h>
-#include <wlc/wlc.h>
-#include "sway/commands.h"
-#include "sway/container.h"
-#include "sway/focus.h"
-#include "sway/ipc-server.h"
-#include "sway/layout.h"
-
-struct cmd_results *cmd_fullscreen(int argc, char **argv) {
- struct cmd_results *error = NULL;
- if (config->reading) return cmd_results_new(CMD_FAILURE, "fullscreen", "Can't be used in config file.");
- if (!config->active) return cmd_results_new(CMD_FAILURE, "fullscreen", "Can only be used when sway is running.");
- if ((error = checkarg(argc, "fullscreen", EXPECTED_AT_LEAST, 0))) {
- return error;
- }
- swayc_t *container = current_container;
- if(container->type != C_VIEW){
- return cmd_results_new(CMD_INVALID, "fullscreen", "Only views can fullscreen");
- }
- swayc_t *workspace = swayc_parent_by_type(container, C_WORKSPACE);
- bool current = swayc_is_fullscreen(container);
- wlc_view_set_state(container->handle, WLC_BIT_FULLSCREEN, !current);
-
- if (container->is_floating) {
- if (current) {
- // set dimensions back to what they were before we fullscreened this
- container->x = container->cached_geometry.origin.x;
- container->y = container->cached_geometry.origin.y;
- container->width = container->cached_geometry.size.w;
- container->height = container->cached_geometry.size.h;
- } else {
- // cache dimensions so we can reset them after we "unfullscreen" this
- struct wlc_geometry geo = {
- .origin = {
- .x = container->x,
- .y = container->y
- },
- .size = {
- .w = container->width,
- .h = container->height
- }
- };
- container->cached_geometry = geo;
- }
- }
-
- // Resize workspace if going from fullscreen -> notfullscreen
- // otherwise just resize container
- if (!current) {
- arrange_windows(workspace, -1, -1);
- workspace->fullscreen = container;
- } else {
- arrange_windows(container, -1, -1);
- workspace->fullscreen = NULL;
- }
- ipc_event_window(container, "fullscreen_mode");
-
- return cmd_results_new(CMD_SUCCESS, NULL, NULL);
-}
diff --git a/sway/old/commands/gaps.c b/sway/old/commands/gaps.c
deleted file mode 100644
index 0a48592d..00000000
--- a/sway/old/commands/gaps.c
+++ /dev/null
@@ -1,166 +0,0 @@
-#include <ctype.h>
-#include <errno.h>
-#include <stdlib.h>
-#include <string.h>
-#include <strings.h>
-#include "sway/commands.h"
-#include "sway/container.h"
-#include "sway/focus.h"
-#include "sway/layout.h"
-
-struct cmd_results *cmd_gaps(int argc, char **argv) {
- struct cmd_results *error = NULL;
- if ((error = checkarg(argc, "gaps", EXPECTED_AT_LEAST, 1))) {
- return error;
- }
- const char *expected_syntax =
- "Expected 'gaps edge_gaps <on|off|toggle>' or "
- "'gaps <inner|outer> <current|all|workspace> <set|plus|minus n>'";
- const char *amount_str = argv[0];
- // gaps amount
- if (argc >= 1 && isdigit(*amount_str)) {
- int amount = (int)strtol(amount_str, NULL, 10);
- if (errno == ERANGE) {
- errno = 0;
- return cmd_results_new(CMD_INVALID, "gaps", "Number is out out of range.");
- }
- config->gaps_inner = config->gaps_outer = amount;
- arrange_windows(&root_container, -1, -1);
- return cmd_results_new(CMD_SUCCESS, NULL, NULL);
- }
- // gaps inner|outer n
- else if (argc >= 2 && isdigit((amount_str = argv[1])[0])) {
- int amount = (int)strtol(amount_str, NULL, 10);
- if (errno == ERANGE) {
- errno = 0;
- return cmd_results_new(CMD_INVALID, "gaps", "Number is out out of range.");
- }
- const char *target_str = argv[0];
- if (strcasecmp(target_str, "inner") == 0) {
- config->gaps_inner = amount;
- } else if (strcasecmp(target_str, "outer") == 0) {
- config->gaps_outer = amount;
- }
- arrange_windows(&root_container, -1, -1);
- return cmd_results_new(CMD_SUCCESS, NULL, NULL);
- } else if (argc == 2 && strcasecmp(argv[0], "edge_gaps") == 0) {
- // gaps edge_gaps <on|off|toggle>
- if (strcasecmp(argv[1], "toggle") == 0) {
- if (config->reading) {
- return cmd_results_new(CMD_FAILURE, "gaps edge_gaps toggle",
- "Can't be used in config file.");
- }
- config->edge_gaps = !config->edge_gaps;
- } else {
- config->edge_gaps =
- (strcasecmp(argv[1], "yes") == 0 || strcasecmp(argv[1], "on") == 0);
- }
- arrange_windows(&root_container, -1, -1);
- return cmd_results_new(CMD_SUCCESS, NULL, NULL);
- }
- // gaps inner|outer current|all set|plus|minus n
- if (argc < 4 || config->reading) {
- return cmd_results_new(CMD_INVALID, "gaps", expected_syntax);
- }
- // gaps inner|outer ...
- const char *inout_str = argv[0];
- enum {INNER, OUTER} inout;
- if (strcasecmp(inout_str, "inner") == 0) {
- inout = INNER;
- } else if (strcasecmp(inout_str, "outer") == 0) {
- inout = OUTER;
- } else {
- return cmd_results_new(CMD_INVALID, "gaps", expected_syntax);
- }
-
- // gaps ... current|all ...
- const char *target_str = argv[1];
- enum {CURRENT, WORKSPACE, ALL} target;
- if (strcasecmp(target_str, "current") == 0) {
- target = CURRENT;
- } else if (strcasecmp(target_str, "all") == 0) {
- target = ALL;
- } else if (strcasecmp(target_str, "workspace") == 0) {
- if (inout == OUTER) {
- target = CURRENT;
- } else {
- // Set gap for views in workspace
- target = WORKSPACE;
- }
- } else {
- return cmd_results_new(CMD_INVALID, "gaps", expected_syntax);
- }
-
- // gaps ... n
- amount_str = argv[3];
- int amount = (int)strtol(amount_str, NULL, 10);
- if (errno == ERANGE) {
- errno = 0;
- return cmd_results_new(CMD_INVALID, "gaps", "Number is out out of range.");
- }
-
- // gaps ... set|plus|minus ...
- const char *method_str = argv[2];
- enum {SET, ADD} method;
- if (strcasecmp(method_str, "set") == 0) {
- method = SET;
- } else if (strcasecmp(method_str, "plus") == 0) {
- method = ADD;
- } else if (strcasecmp(method_str, "minus") == 0) {
- method = ADD;
- amount *= -1;
- } else {
- return cmd_results_new(CMD_INVALID, "gaps", expected_syntax);
- }
-
- if (target == CURRENT) {
- swayc_t *cont;
- if (inout == OUTER) {
- if ((cont = swayc_active_workspace()) == NULL) {
- return cmd_results_new(CMD_FAILURE, "gaps", "There's no active workspace.");
- }
- } else {
- if ((cont = get_focused_view(&root_container))->type != C_VIEW) {
- return cmd_results_new(CMD_FAILURE, "gaps", "Currently focused item is not a view.");
- }
- }
- cont->gaps = swayc_gap(cont);
- if (method == SET) {
- cont->gaps = amount;
- } else if ((cont->gaps += amount) < 0) {
- cont->gaps = 0;
- }
- arrange_windows(cont->parent, -1, -1);
- } else if (inout == OUTER) {
- //resize all workspace.
- int i,j;
- for (i = 0; i < root_container.children->length; ++i) {
- swayc_t *op = root_container.children->items[i];
- for (j = 0; j < op->children->length; ++j) {
- swayc_t *ws = op->children->items[j];
- if (method == SET) {
- ws->gaps = amount;
- } else if ((ws->gaps += amount) < 0) {
- ws->gaps = 0;
- }
- }
- }
- arrange_windows(&root_container, -1, -1);
- } else {
- // Resize gaps for all views in workspace
- swayc_t *top;
- if (target == WORKSPACE) {
- if ((top = swayc_active_workspace()) == NULL) {
- return cmd_results_new(CMD_FAILURE, "gaps", "There's currently no active workspace.");
- }
- } else {
- top = &root_container;
- }
- int top_gap = top->gaps;
- container_map(top, method == SET ? set_gaps : add_gaps, &amount);
- top->gaps = top_gap;
- arrange_windows(top, -1, -1);
- }
-
- return cmd_results_new(CMD_SUCCESS, NULL, NULL);
-}
diff --git a/sway/old/commands/hide_edge_borders.c b/sway/old/commands/hide_edge_borders.c
deleted file mode 100644
index ee2a2644..00000000
--- a/sway/old/commands/hide_edge_borders.c
+++ /dev/null
@@ -1,27 +0,0 @@
-#include <string.h>
-#include <strings.h>
-#include "sway/commands.h"
-
-struct cmd_results *cmd_hide_edge_borders(int argc, char **argv) {
- struct cmd_results *error = NULL;
- if ((error = checkarg(argc, "hide_edge_borders", EXPECTED_EQUAL_TO, 1))) {
- return error;
- }
-
- if (strcasecmp(argv[0], "none") == 0) {
- config->hide_edge_borders = E_NONE;
- } else if (strcasecmp(argv[0], "vertical") == 0) {
- config->hide_edge_borders = E_VERTICAL;
- } else if (strcasecmp(argv[0], "horizontal") == 0) {
- config->hide_edge_borders = E_HORIZONTAL;
- } else if (strcasecmp(argv[0], "both") == 0) {
- config->hide_edge_borders = E_BOTH;
- } else if (strcasecmp(argv[0], "smart") == 0) {
- config->hide_edge_borders = E_SMART;
- } else {
- return cmd_results_new(CMD_INVALID, "hide_edge_borders",
- "Expected 'hide_edge_borders <none|vertical|horizontal|both>'");
- }
-
- return cmd_results_new(CMD_SUCCESS, NULL, NULL);
-}
diff --git a/sway/old/commands/include.c b/sway/old/commands/include.c
deleted file mode 100644
index 1ba9a10d..00000000
--- a/sway/old/commands/include.c
+++ /dev/null
@@ -1,15 +0,0 @@
-#include "sway/commands.h"
-#include "sway/config.h"
-
-struct cmd_results *cmd_include(int argc, char **argv) {
- struct cmd_results *error = NULL;
- if ((error = checkarg(argc, "include", EXPECTED_EQUAL_TO, 1))) {
- return error;
- }
-
- if (!load_include_configs(argv[0], config)) {
- return cmd_results_new(CMD_INVALID, "include", "Failed to include sub configuration file: %s", argv[0]);
- }
-
- return cmd_results_new(CMD_SUCCESS, NULL, NULL);
-}
diff --git a/sway/old/commands/input.c b/sway/old/commands/input.c
deleted file mode 100644
index ad53d272..00000000
--- a/sway/old/commands/input.c
+++ /dev/null
@@ -1,55 +0,0 @@
-#include <string.h>
-#include <strings.h>
-#include "sway/commands.h"
-#include "sway/input.h"
-#include "log.h"
-
-struct cmd_results *cmd_input(int argc, char **argv) {
- struct cmd_results *error = NULL;
- if ((error = checkarg(argc, "input", EXPECTED_AT_LEAST, 2))) {
- return error;
- }
-
- if (config->reading && strcmp("{", argv[1]) == 0) {
- current_input_config = new_input_config(argv[0]);
- sway_log(L_DEBUG, "entering input block: %s", current_input_config->identifier);
- return cmd_results_new(CMD_BLOCK_INPUT, NULL, NULL);
- }
-
- if (argc > 2) {
- int argc_new = argc-2;
- char **argv_new = argv+2;
-
- struct cmd_results *res;
- current_input_config = new_input_config(argv[0]);
- if (strcasecmp("accel_profile", argv[1]) == 0) {
- res = input_cmd_accel_profile(argc_new, argv_new);
- } else if (strcasecmp("click_method", argv[1]) == 0) {
- res = input_cmd_click_method(argc_new, argv_new);
- } else if (strcasecmp("drag_lock", argv[1]) == 0) {
- res = input_cmd_drag_lock(argc_new, argv_new);
- } else if (strcasecmp("dwt", argv[1]) == 0) {
- res = input_cmd_dwt(argc_new, argv_new);
- } else if (strcasecmp("events", argv[1]) == 0) {
- res = input_cmd_events(argc_new, argv_new);
- } else if (strcasecmp("left_handed", argv[1]) == 0) {
- res = input_cmd_left_handed(argc_new, argv_new);
- } else if (strcasecmp("middle_emulation", argv[1]) == 0) {
- res = input_cmd_middle_emulation(argc_new, argv_new);
- } else if (strcasecmp("natural_scroll", argv[1]) == 0) {
- res = input_cmd_natural_scroll(argc_new, argv_new);
- } else if (strcasecmp("pointer_accel", argv[1]) == 0) {
- res = input_cmd_pointer_accel(argc_new, argv_new);
- } else if (strcasecmp("scroll_method", argv[1]) == 0) {
- res = input_cmd_scroll_method(argc_new, argv_new);
- } else if (strcasecmp("tap", argv[1]) == 0) {
- res = input_cmd_tap(argc_new, argv_new);
- } else {
- res = cmd_results_new(CMD_INVALID, "input <device>", "Unknown command %s", argv[1]);
- }
- current_input_config = NULL;
- return res;
- }
-
- return cmd_results_new(CMD_BLOCK_INPUT, NULL, NULL);
-}
diff --git a/sway/old/commands/input/accel_profile.c b/sway/old/commands/input/accel_profile.c
deleted file mode 100644
index 8288c1ad..00000000
--- a/sway/old/commands/input/accel_profile.c
+++ /dev/null
@@ -1,27 +0,0 @@
-#include <string.h>
-#include <strings.h>
-#include "sway/commands.h"
-#include "sway/input.h"
-
-struct cmd_results *input_cmd_accel_profile(int argc, char **argv) {
- struct cmd_results *error = NULL;
- if ((error = checkarg(argc, "accel_profile", EXPECTED_AT_LEAST, 1))) {
- return error;
- }
- if (!current_input_config) {
- return cmd_results_new(CMD_FAILURE, "accel_profile", "No input device defined.");
- }
- struct input_config *new_config = new_input_config(current_input_config->identifier);
-
- if (strcasecmp(argv[0], "adaptive") == 0) {
- new_config->accel_profile = LIBINPUT_CONFIG_ACCEL_PROFILE_ADAPTIVE;
- } else if (strcasecmp(argv[0], "flat") == 0) {
- new_config->accel_profile = LIBINPUT_CONFIG_ACCEL_PROFILE_FLAT;
- } else {
- return cmd_results_new(CMD_INVALID, "accel_profile",
- "Expected 'accel_profile <adaptive|flat>'");
- }
-
- input_cmd_apply(new_config);
- return cmd_results_new(CMD_SUCCESS, NULL, NULL);
-}
diff --git a/sway/old/commands/input/click_method.c b/sway/old/commands/input/click_method.c
deleted file mode 100644
index 5e9d3dcb..00000000
--- a/sway/old/commands/input/click_method.c
+++ /dev/null
@@ -1,30 +0,0 @@
-#include <string.h>
-#include <strings.h>
-#include "sway/commands.h"
-#include "sway/input.h"
-#include "log.h"
-
-struct cmd_results *input_cmd_click_method(int argc, char **argv) {
- sway_log(L_DEBUG, "click_method for device: %d %s", current_input_config==NULL, current_input_config->identifier);
- struct cmd_results *error = NULL;
- if ((error = checkarg(argc, "click_method", EXPECTED_AT_LEAST, 1))) {
- return error;
- }
- if (!current_input_config) {
- return cmd_results_new(CMD_FAILURE, "click_method", "No input device defined.");
- }
- struct input_config *new_config = new_input_config(current_input_config->identifier);
-
- if (strcasecmp(argv[0], "none") == 0) {
- new_config->click_method = LIBINPUT_CONFIG_CLICK_METHOD_NONE;
- } else if (strcasecmp(argv[0], "button_areas") == 0) {
- new_config->click_method = LIBINPUT_CONFIG_CLICK_METHOD_BUTTON_AREAS;
- } else if (strcasecmp(argv[0], "clickfinger") == 0) {
- new_config->click_method = LIBINPUT_CONFIG_CLICK_METHOD_CLICKFINGER;
- } else {
- return cmd_results_new(CMD_INVALID, "click_method", "Expected 'click_method <none|button_areas|clickfinger'");
- }
-
- input_cmd_apply(new_config);
- return cmd_results_new(CMD_SUCCESS, NULL, NULL);
-}
diff --git a/sway/old/commands/input/drag_lock.c b/sway/old/commands/input/drag_lock.c
deleted file mode 100644
index f5a7beb4..00000000
--- a/sway/old/commands/input/drag_lock.c
+++ /dev/null
@@ -1,26 +0,0 @@
-#include <string.h>
-#include <strings.h>
-#include "sway/commands.h"
-#include "sway/input.h"
-
-struct cmd_results *input_cmd_drag_lock(int argc, char **argv) {
- struct cmd_results *error = NULL;
- if ((error = checkarg(argc, "drag_lock", EXPECTED_AT_LEAST, 1))) {
- return error;
- }
- if (!current_input_config) {
- return cmd_results_new(CMD_FAILURE, "drag_lock", "No input device defined.");
- }
- struct input_config *new_config = new_input_config(current_input_config->identifier);
-
- if (strcasecmp(argv[0], "enabled") == 0) {
- new_config->drag_lock = LIBINPUT_CONFIG_DRAG_LOCK_ENABLED;
- } else if (strcasecmp(argv[0], "disabled") == 0) {
- new_config->drag_lock = LIBINPUT_CONFIG_DRAG_LOCK_DISABLED;
- } else {
- return cmd_results_new(CMD_INVALID, "drag_lock", "Expected 'drag_lock <enabled|disabled>'");
- }
-
- input_cmd_apply(new_config);
- return cmd_results_new(CMD_SUCCESS, NULL, NULL);
-}
diff --git a/sway/old/commands/input/dwt.c b/sway/old/commands/input/dwt.c
deleted file mode 100644
index 557b2207..00000000
--- a/sway/old/commands/input/dwt.c
+++ /dev/null
@@ -1,26 +0,0 @@
-#include <string.h>
-#include <strings.h>
-#include "sway/commands.h"
-#include "sway/input.h"
-
-struct cmd_results *input_cmd_dwt(int argc, char **argv) {
- struct cmd_results *error = NULL;
- if ((error = checkarg(argc, "dwt", EXPECTED_AT_LEAST, 1))) {
- return error;
- }
- if (!current_input_config) {
- return cmd_results_new(CMD_FAILURE, "dwt", "No input device defined.");
- }
- struct input_config *new_config = new_input_config(current_input_config->identifier);
-
- if (strcasecmp(argv[0], "enabled") == 0) {
- new_config->dwt = LIBINPUT_CONFIG_DWT_ENABLED;
- } else if (strcasecmp(argv[0], "disabled") == 0) {
- new_config->dwt = LIBINPUT_CONFIG_DWT_DISABLED;
- } else {
- return cmd_results_new(CMD_INVALID, "dwt", "Expected 'dwt <enabled|disabled>'");
- }
-
- input_cmd_apply(new_config);
- return cmd_results_new(CMD_SUCCESS, NULL, NULL);
-}
diff --git a/sway/old/commands/input/events.c b/sway/old/commands/input/events.c
deleted file mode 100644
index 9d54287a..00000000
--- a/sway/old/commands/input/events.c
+++ /dev/null
@@ -1,30 +0,0 @@
-#include <string.h>
-#include <strings.h>
-#include "sway/commands.h"
-#include "sway/input.h"
-#include "log.h"
-
-struct cmd_results *input_cmd_events(int argc, char **argv) {
- sway_log(L_DEBUG, "events for device: %s", current_input_config->identifier);
- struct cmd_results *error = NULL;
- if ((error = checkarg(argc, "events", EXPECTED_AT_LEAST, 1))) {
- return error;
- }
- if (!current_input_config) {
- return cmd_results_new(CMD_FAILURE, "events", "No input device defined.");
- }
- struct input_config *new_config = new_input_config(current_input_config->identifier);
-
- if (strcasecmp(argv[0], "enabled") == 0) {
- new_config->send_events = LIBINPUT_CONFIG_SEND_EVENTS_ENABLED;
- } else if (strcasecmp(argv[0], "disabled") == 0) {
- new_config->send_events = LIBINPUT_CONFIG_SEND_EVENTS_DISABLED;
- } else if (strcasecmp(argv[0], "disabled_on_external_mouse") == 0) {
- new_config->send_events = LIBINPUT_CONFIG_SEND_EVENTS_DISABLED_ON_EXTERNAL_MOUSE;
- } else {
- return cmd_results_new(CMD_INVALID, "events", "Expected 'events <enabled|disabled|disabled_on_external_mouse>'");
- }
-
- input_cmd_apply(new_config);
- return cmd_results_new(CMD_SUCCESS, NULL, NULL);
-}
diff --git a/sway/old/commands/input/left_handed.c b/sway/old/commands/input/left_handed.c
deleted file mode 100644
index 6c913e70..00000000
--- a/sway/old/commands/input/left_handed.c
+++ /dev/null
@@ -1,26 +0,0 @@
-#include <string.h>
-#include <strings.h>
-#include "sway/commands.h"
-#include "sway/input.h"
-
-struct cmd_results *input_cmd_left_handed(int argc, char **argv) {
- struct cmd_results *error = NULL;
- if ((error = checkarg(argc, "left_handed", EXPECTED_AT_LEAST, 1))) {
- return error;
- }
- if (!current_input_config) {
- return cmd_results_new(CMD_FAILURE, "left_handed", "No input device defined.");
- }
- struct input_config *new_config = new_input_config(current_input_config->identifier);
-
- if (strcasecmp(argv[0], "enabled") == 0) {
- new_config->left_handed = 1;
- } else if (strcasecmp(argv[0], "disabled") == 0) {
- new_config->left_handed = 0;
- } else {
- return cmd_results_new(CMD_INVALID, "left_handed", "Expected 'left_handed <enabled|disabled>'");
- }
-
- input_cmd_apply(new_config);
- return cmd_results_new(CMD_SUCCESS, NULL, NULL);
-}
diff --git a/sway/old/commands/input/middle_emulation.c b/sway/old/commands/input/middle_emulation.c
deleted file mode 100644
index 33cdd7d6..00000000
--- a/sway/old/commands/input/middle_emulation.c
+++ /dev/null
@@ -1,26 +0,0 @@
-#include <string.h>
-#include <strings.h>
-#include "sway/commands.h"
-#include "sway/input.h"
-
-struct cmd_results *input_cmd_middle_emulation(int argc, char **argv) {
- struct cmd_results *error = NULL;
- if ((error = checkarg(argc, "middle_emulation", EXPECTED_AT_LEAST, 1))) {
- return error;
- }
- if (!current_input_config) {
- return cmd_results_new(CMD_FAILURE, "middle_emulation", "No input device defined.");
- }
- struct input_config *new_config = new_input_config(current_input_config->identifier);
-
- if (strcasecmp(argv[0], "enabled") == 0) {
- new_config->middle_emulation = LIBINPUT_CONFIG_MIDDLE_EMULATION_ENABLED;
- } else if (strcasecmp(argv[0], "disabled") == 0) {
- new_config->middle_emulation = LIBINPUT_CONFIG_MIDDLE_EMULATION_DISABLED;
- } else {
- return cmd_results_new(CMD_INVALID, "middle_emulation", "Expected 'middle_emulation <enabled|disabled>'");
- }
-
- input_cmd_apply(new_config);
- return cmd_results_new(CMD_SUCCESS, NULL, NULL);
-}
diff --git a/sway/old/commands/input/natural_scroll.c b/sway/old/commands/input/natural_scroll.c
deleted file mode 100644
index 7bc8b8d0..00000000
--- a/sway/old/commands/input/natural_scroll.c
+++ /dev/null
@@ -1,26 +0,0 @@
-#include <string.h>
-#include <strings.h>
-#include "sway/commands.h"
-#include "sway/input.h"
-
-struct cmd_results *input_cmd_natural_scroll(int argc, char **argv) {
- struct cmd_results *error = NULL;
- if ((error = checkarg(argc, "natural_scroll", EXPECTED_AT_LEAST, 1))) {
- return error;
- }
- if (!current_input_config) {
- return cmd_results_new(CMD_FAILURE, "natural_scoll", "No input device defined.");
- }
- struct input_config *new_config = new_input_config(current_input_config->identifier);
-
- if (strcasecmp(argv[0], "enabled") == 0) {
- new_config->natural_scroll = 1;
- } else if (strcasecmp(argv[0], "disabled") == 0) {
- new_config->natural_scroll = 0;
- } else {
- return cmd_results_new(CMD_INVALID, "natural_scroll", "Expected 'natural_scroll <enabled|disabled>'");
- }
-
- input_cmd_apply(new_config);
- return cmd_results_new(CMD_SUCCESS, NULL, NULL);
-}
diff --git a/sway/old/commands/input/pointer_accel.c b/sway/old/commands/input/pointer_accel.c
deleted file mode 100644
index 94f595d1..00000000
--- a/sway/old/commands/input/pointer_accel.c
+++ /dev/null
@@ -1,24 +0,0 @@
-#include <stdlib.h>
-#include <string.h>
-#include "sway/commands.h"
-#include "sway/input.h"
-
-struct cmd_results *input_cmd_pointer_accel(int argc, char **argv) {
- struct cmd_results *error = NULL;
- if ((error = checkarg(argc, "pointer_accel", EXPECTED_AT_LEAST, 1))) {
- return error;
- }
- if (!current_input_config) {
- return cmd_results_new(CMD_FAILURE, "pointer_accel", "No input device defined.");
- }
- struct input_config *new_config = new_input_config(current_input_config->identifier);
-
- float pointer_accel = atof(argv[0]);
- if (pointer_accel < -1 || pointer_accel > 1) {
- return cmd_results_new(CMD_INVALID, "pointer_accel", "Input out of range [-1, 1]");
- }
- new_config->pointer_accel = pointer_accel;
-
- input_cmd_apply(new_config);
- return cmd_results_new(CMD_SUCCESS, NULL, NULL);
-}
diff --git a/sway/old/commands/input/scroll_method.c b/sway/old/commands/input/scroll_method.c
deleted file mode 100644
index 5c6c3d7a..00000000
--- a/sway/old/commands/input/scroll_method.c
+++ /dev/null
@@ -1,30 +0,0 @@
-#include <string.h>
-#include <strings.h>
-#include "sway/commands.h"
-#include "sway/input.h"
-
-struct cmd_results *input_cmd_scroll_method(int argc, char **argv) {
- struct cmd_results *error = NULL;
- if ((error = checkarg(argc, "scroll_method", EXPECTED_AT_LEAST, 1))) {
- return error;
- }
- if (!current_input_config) {
- return cmd_results_new(CMD_FAILURE, "scroll_method", "No input device defined.");
- }
- struct input_config *new_config = new_input_config(current_input_config->identifier);
-
- if (strcasecmp(argv[0], "none") == 0) {
- new_config->scroll_method = LIBINPUT_CONFIG_SCROLL_NO_SCROLL;
- } else if (strcasecmp(argv[0], "two_finger") == 0) {
- new_config->scroll_method = LIBINPUT_CONFIG_SCROLL_2FG;
- } else if (strcasecmp(argv[0], "edge") == 0) {
- new_config->scroll_method = LIBINPUT_CONFIG_SCROLL_EDGE;
- } else if (strcasecmp(argv[0], "on_button_down") == 0) {
- new_config->scroll_method = LIBINPUT_CONFIG_SCROLL_ON_BUTTON_DOWN;
- } else {
- return cmd_results_new(CMD_INVALID, "scroll_method", "Expected 'scroll_method <none|two_finger|edge|on_button_down>'");
- }
-
- input_cmd_apply(new_config);
- return cmd_results_new(CMD_SUCCESS, NULL, NULL);
-}
diff --git a/sway/old/commands/input/tap.c b/sway/old/commands/input/tap.c
deleted file mode 100644
index 9e3ca2af..00000000
--- a/sway/old/commands/input/tap.c
+++ /dev/null
@@ -1,29 +0,0 @@
-#include <string.h>
-#include <strings.h>
-#include "sway/commands.h"
-#include "sway/input.h"
-#include "log.h"
-
-struct cmd_results *input_cmd_tap(int argc, char **argv) {
- sway_log(L_DEBUG, "tap for device: %s", current_input_config->identifier);
- struct cmd_results *error = NULL;
- if ((error = checkarg(argc, "tap", EXPECTED_AT_LEAST, 1))) {
- return error;
- }
- if (!current_input_config) {
- return cmd_results_new(CMD_FAILURE, "tap", "No input device defined.");
- }
- struct input_config *new_config = new_input_config(current_input_config->identifier);
-
- if (strcasecmp(argv[0], "enabled") == 0) {
- new_config->tap = LIBINPUT_CONFIG_TAP_ENABLED;
- } else if (strcasecmp(argv[0], "disabled") == 0) {
- new_config->tap = LIBINPUT_CONFIG_TAP_DISABLED;
- } else {
- return cmd_results_new(CMD_INVALID, "tap", "Expected 'tap <enabled|disabled>'");
- }
-
- sway_log(L_DEBUG, "apply-tap for device: %s", current_input_config->identifier);
- input_cmd_apply(new_config);
- return cmd_results_new(CMD_SUCCESS, NULL, NULL);
-}
diff --git a/sway/old/commands/ipc.c b/sway/old/commands/ipc.c
deleted file mode 100644
index 0c678961..00000000
--- a/sway/old/commands/ipc.c
+++ /dev/null
@@ -1,162 +0,0 @@
-#define _XOPEN_SOURCE 500
-#include <stdio.h>
-#include <string.h>
-#include "sway/security.h"
-#include "sway/commands.h"
-#include "sway/config.h"
-#include "ipc.h"
-#include "log.h"
-#include "util.h"
-
-static struct ipc_policy *current_policy = NULL;
-
-struct cmd_results *cmd_ipc(int argc, char **argv) {
- struct cmd_results *error = NULL;
- if ((error = checkarg(argc, "ipc", EXPECTED_EQUAL_TO, 2))) {
- return error;
- }
- if ((error = check_security_config())) {
- return error;
- }
-
- char *program = NULL;
-
- if (!strcmp(argv[0], "*")) {
- program = strdup(argv[0]);
- } else if (!(program = resolve_path(argv[0]))) {
- return cmd_results_new(
- CMD_INVALID, "ipc", "Unable to resolve IPC Policy target.");
- }
- if (config->reading && strcmp("{", argv[1]) != 0) {
- return cmd_results_new(CMD_INVALID, "ipc",
- "Expected '{' at start of IPC config definition.");
- }
-
- if (!config->reading) {
- return cmd_results_new(CMD_FAILURE, "ipc", "Can only be used in config file.");
- }
-
- current_policy = alloc_ipc_policy(program);
- list_add(config->ipc_policies, current_policy);
-
- free(program);
- return cmd_results_new(CMD_BLOCK_IPC, NULL, NULL);
-}
-
-struct cmd_results *cmd_ipc_events(int argc, char **argv) {
- struct cmd_results *error = NULL;
- if ((error = checkarg(argc, "events", EXPECTED_EQUAL_TO, 1))) {
- return error;
- }
-
- if (config->reading && strcmp("{", argv[0]) != 0) {
- return cmd_results_new(CMD_INVALID, "events",
- "Expected '{' at start of IPC event config definition.");
- }
-
- if (!config->reading) {
- return cmd_results_new(CMD_FAILURE, "events", "Can only be used in config file.");
- }
-
- return cmd_results_new(CMD_BLOCK_IPC_EVENTS, NULL, NULL);
-}
-
-struct cmd_results *cmd_ipc_cmd(int argc, char **argv) {
- struct cmd_results *error = NULL;
- if ((error = checkarg(argc, "ipc", EXPECTED_EQUAL_TO, 1))) {
- return error;
- }
-
- bool enabled;
- if (strcmp(argv[0], "enabled") == 0) {
- enabled = true;
- } else if (strcmp(argv[0], "disabled") == 0) {
- enabled = false;
- } else {
- return cmd_results_new(CMD_INVALID, argv[-1],
- "Argument must be one of 'enabled' or 'disabled'");
- }
-
- struct {
- char *name;
- enum ipc_feature type;
- } types[] = {
- { "*", IPC_FEATURE_ALL_COMMANDS },
- { "command", IPC_FEATURE_COMMAND },
- { "workspaces", IPC_FEATURE_GET_WORKSPACES },
- { "outputs", IPC_FEATURE_GET_OUTPUTS },
- { "tree", IPC_FEATURE_GET_TREE },
- { "marks", IPC_FEATURE_GET_MARKS },
- { "bar-config", IPC_FEATURE_GET_BAR_CONFIG },
- { "inputs", IPC_FEATURE_GET_INPUTS },
- { "clipboard", IPC_FEATURE_GET_CLIPBOARD },
- };
-
- uint32_t type = 0;
-
- for (size_t i = 0; i < sizeof(types) / sizeof(types[0]); ++i) {
- if (strcmp(types[i].name, argv[-1]) == 0) {
- type = types[i].type;
- break;
- }
- }
-
- if (enabled) {
- current_policy->features |= type;
- sway_log(L_DEBUG, "Enabled IPC %s feature", argv[-1]);
- } else {
- current_policy->features &= ~type;
- sway_log(L_DEBUG, "Disabled IPC %s feature", argv[-1]);
- }
-
- return cmd_results_new(CMD_SUCCESS, NULL, NULL);
-}
-
-struct cmd_results *cmd_ipc_event_cmd(int argc, char **argv) {
- struct cmd_results *error = NULL;
- if ((error = checkarg(argc, "ipc", EXPECTED_EQUAL_TO, 1))) {
- return error;
- }
-
- bool enabled;
- if (strcmp(argv[0], "enabled") == 0) {
- enabled = true;
- } else if (strcmp(argv[0], "disabled") == 0) {
- enabled = false;
- } else {
- return cmd_results_new(CMD_INVALID, argv[-1],
- "Argument must be one of 'enabled' or 'disabled'");
- }
-
- struct {
- char *name;
- enum ipc_feature type;
- } types[] = {
- { "*", IPC_FEATURE_ALL_EVENTS },
- { "workspace", IPC_FEATURE_EVENT_WORKSPACE },
- { "output", IPC_FEATURE_EVENT_OUTPUT },
- { "mode", IPC_FEATURE_EVENT_MODE },
- { "window", IPC_FEATURE_EVENT_WINDOW },
- { "binding", IPC_FEATURE_EVENT_BINDING },
- { "input", IPC_FEATURE_EVENT_INPUT },
- };
-
- uint32_t type = 0;
-
- for (size_t i = 0; i < sizeof(types) / sizeof(types[0]); ++i) {
- if (strcmp(types[i].name, argv[-1]) == 0) {
- type = types[i].type;
- break;
- }
- }
-
- if (enabled) {
- current_policy->features |= type;
- sway_log(L_DEBUG, "Enabled IPC %s event", argv[-1]);
- } else {
- current_policy->features &= ~type;
- sway_log(L_DEBUG, "Disabled IPC %s event", argv[-1]);
- }
-
- return cmd_results_new(CMD_SUCCESS, NULL, NULL);
-}
diff --git a/sway/old/commands/kill.c b/sway/old/commands/kill.c
deleted file mode 100644
index 742e2b86..00000000
--- a/sway/old/commands/kill.c
+++ /dev/null
@@ -1,12 +0,0 @@
-#include "sway/commands.h"
-#include "sway/container.h"
-#include "sway/focus.h"
-
-struct cmd_results *cmd_kill(int argc, char **argv) {
- if (config->reading) return cmd_results_new(CMD_FAILURE, "kill", "Can't be used in config file.");
- if (!config->active) return cmd_results_new(CMD_FAILURE, "kill", "Can only be used when sway is running.");
-
- swayc_t *container = current_container;
- close_views(container);
- return cmd_results_new(CMD_SUCCESS, NULL, NULL);
-}
diff --git a/sway/old/commands/layout.c b/sway/old/commands/layout.c
deleted file mode 100644
index 57a86565..00000000
--- a/sway/old/commands/layout.c
+++ /dev/null
@@ -1,196 +0,0 @@
-#include <string.h>
-#include <strings.h>
-#include "sway/commands.h"
-#include "sway/container.h"
-#include "sway/layout.h"
-
-/**
- * handle "layout auto" command group
- */
-static struct cmd_results *cmd_layout_auto(swayc_t *container, int argc, char **argv);
-
-struct cmd_results *cmd_layout(int argc, char **argv) {
- struct cmd_results *error = NULL;
- if (config->reading) return cmd_results_new(CMD_FAILURE, "layout", "Can't be used in config file.");
- if (!config->active) return cmd_results_new(CMD_FAILURE, "layout", "Can only be used when sway is running.");
- if ((error = checkarg(argc, "layout", EXPECTED_MORE_THAN, 0))) {
- return error;
- }
- swayc_t *parent = current_container;
- if (parent->is_floating) {
- return cmd_results_new(CMD_FAILURE, "layout", "Unable to change layout of floating windows");
- }
-
- while (parent->type == C_VIEW) {
- parent = parent->parent;
- }
-
- enum swayc_layouts old_layout = parent->layout;
-
- if (strcasecmp(argv[0], "default") == 0) {
- swayc_change_layout(parent, parent->prev_layout);
- if (parent->layout == L_NONE) {
- swayc_t *output = swayc_parent_by_type(parent, C_OUTPUT);
- swayc_change_layout(parent, default_layout(output));
- }
- } else {
- if (parent->layout != L_TABBED && parent->layout != L_STACKED) {
- parent->prev_layout = parent->layout;
- }
-
- if (strcasecmp(argv[0], "tabbed") == 0) {
- if (parent->type != C_CONTAINER && !swayc_is_empty_workspace(parent)){
- parent = new_container(parent, L_TABBED);
- }
-
- swayc_change_layout(parent, L_TABBED);
- } else if (strcasecmp(argv[0], "stacking") == 0) {
- if (parent->type != C_CONTAINER && !swayc_is_empty_workspace(parent)) {
- parent = new_container(parent, L_STACKED);
- }
-
- swayc_change_layout(parent, L_STACKED);
- } else if (strcasecmp(argv[0], "splith") == 0) {
- swayc_change_layout(parent, L_HORIZ);
- } else if (strcasecmp(argv[0], "splitv") == 0) {
- swayc_change_layout(parent, L_VERT);
- } else if (strcasecmp(argv[0], "toggle") == 0 && argc == 2 && strcasecmp(argv[1], "split") == 0) {
- if (parent->layout == L_HORIZ && (parent->workspace_layout == L_NONE
- || parent->workspace_layout == L_HORIZ)) {
- swayc_change_layout(parent, L_VERT);
- } else {
- swayc_change_layout(parent, L_HORIZ);
- }
- } else if (strcasecmp(argv[0], "auto") == 0) {
- return cmd_layout_auto(parent, argc, argv);
- }
- }
-
- update_layout_geometry(parent, old_layout);
- update_geometry(parent);
-
- arrange_windows(parent, parent->width, parent->height);
-
- return cmd_results_new(CMD_SUCCESS, NULL, NULL);
-}
-
-static struct cmd_results *cmd_layout_auto(swayc_t *container, int argc, char **argv) {
- // called after checking that argv[0] is auto, so just continue parsing from there
- struct cmd_results *error = NULL;
- const char *cmd_name = "layout auto";
- const char *set_inc_cmd_name = "layout auto [master|ncol] [set|inc]";
- const char *err_msg = "Allowed arguments are <right|left|top|bottom|next|prev|master|ncol>";
-
- bool need_layout_update = false;
- enum swayc_layouts old_layout = container->layout;
- enum swayc_layouts layout = old_layout;
-
- if ((error = checkarg(argc, "layout auto", EXPECTED_MORE_THAN, 1))) {
- return error;
- }
-
- if (strcasecmp(argv[1], "left") == 0) {
- layout = L_AUTO_LEFT;
- } else if (strcasecmp(argv[1], "right") == 0) {
- layout = L_AUTO_RIGHT;
- } else if (strcasecmp(argv[1], "top") == 0) {
- layout = L_AUTO_TOP;
- } else if (strcasecmp(argv[1], "bottom") == 0) {
- layout = L_AUTO_BOTTOM;
- } else if (strcasecmp(argv[1], "next") == 0) {
- if (is_auto_layout(container->layout) && container->layout < L_AUTO_LAST) {
- layout = container->layout + 1;
- } else {
- layout = L_AUTO_FIRST;
- }
- } else if (strcasecmp(argv[1], "prev") == 0) {
- if (is_auto_layout(container->layout) && container->layout > L_AUTO_FIRST) {
- layout = container->layout - 1;
- } else {
- layout = L_AUTO_LAST;
- }
- } else {
- bool is_nmaster;
- bool is_set;
- if (strcasecmp(argv[1], "master") == 0) {
- is_nmaster = true;
- } else if (strcasecmp(argv[1], "ncol") == 0) {
- is_nmaster = false;
- } else {
- return cmd_results_new(CMD_INVALID, cmd_name, "Invalid %s command. %s",
- cmd_name, err_msg);
- }
- if ((error = checkarg(argc, "auto <master|ncol>", EXPECTED_EQUAL_TO, 4))) {
- return error;
- }
- if (strcasecmp(argv[2], "set") == 0) {
- is_set = true;
- } else if (strcasecmp(argv[2], "inc") == 0) {
- is_set = false;
- } else {
- return cmd_results_new(CMD_INVALID, set_inc_cmd_name, "Invalid %s command. %s, "
- "Argument must be on of <set|inc>",
- set_inc_cmd_name);
- }
- char *end;
- int n = (int)strtol(argv[3], &end, 10);
- if (*end) {
- return cmd_results_new(CMD_INVALID, set_inc_cmd_name, "Invalid %s command "
- "(argument must be an integer)", set_inc_cmd_name);
- }
- if (is_auto_layout(container->layout)) {
- int inc = 0; /* difference between current master/ncol and requested value */
- if (is_nmaster) {
- if (is_set) {
- if (n < 0) {
- return cmd_results_new(CMD_INVALID, set_inc_cmd_name, "Invalid %s command "
- "(master must be >= 0)", set_inc_cmd_name);
- }
- inc = n - (int)container->nb_master;
- } else { /* inc command */
- if ((int)container->nb_master + n >= 0) {
- inc = n;
- }
- }
- if (inc) {
- for (int i = container->nb_master;
- i >= 0 && i < container->children->length
- && i != (int)container->nb_master + inc;) {
- ((swayc_t *)container->children->items[i])->height = -1;
- ((swayc_t *)container->children->items[i])->width = -1;
- i += inc > 0 ? 1 : -1;
- }
- container->nb_master += inc;
- need_layout_update = true;
- }
- } else { /* ncol modification */
- if (is_set) {
- if (n <= 0) {
- return cmd_results_new(CMD_INVALID, set_inc_cmd_name, "Invalid %s command "
- "(ncol must be > 0)", set_inc_cmd_name);
- }
- inc = n - (int)container->nb_slave_groups;
- } else { /* inc command */
- if ((int)container->nb_slave_groups + n > 0) {
- inc = n;
- }
- }
- if (inc) {
- container->nb_slave_groups += inc;
- need_layout_update = true;
- }
- }
- }
- }
-
- if (layout != old_layout) {
- swayc_change_layout(container, layout);
- update_layout_geometry(container, old_layout);
- need_layout_update = true;
- }
- if (need_layout_update) {
- update_geometry(container);
- arrange_windows(container, container->width, container->height);
- }
- return cmd_results_new(CMD_SUCCESS, NULL, NULL);
-}
diff --git a/sway/old/commands/log_colors.c b/sway/old/commands/log_colors.c
deleted file mode 100644
index 815d1942..00000000
--- a/sway/old/commands/log_colors.c
+++ /dev/null
@@ -1,22 +0,0 @@
-#include <string.h>
-#include <strings.h>
-#include "sway/commands.h"
-#include "log.h"
-
-struct cmd_results *cmd_log_colors(int argc, char **argv) {
- struct cmd_results *error = NULL;
- if (!config->reading) return cmd_results_new(CMD_FAILURE, "log_colors", "Can only be used in config file.");
- if ((error = checkarg(argc, "log_colors", EXPECTED_EQUAL_TO, 1))) {
- return error;
- }
- if (strcasecmp(argv[0], "no") == 0) {
- sway_log_colors(0);
- } else if (strcasecmp(argv[0], "yes") == 0) {
- sway_log_colors(1);
- } else {
- error = cmd_results_new(CMD_FAILURE, "log_colors",
- "Invalid log_colors command (expected `yes` or `no`, got '%s')", argv[0]);
- return error;
- }
- return cmd_results_new(CMD_SUCCESS, NULL, NULL);
-}
diff --git a/sway/old/commands/mark.c b/sway/old/commands/mark.c
deleted file mode 100644
index c1d959df..00000000
--- a/sway/old/commands/mark.c
+++ /dev/null
@@ -1,87 +0,0 @@
-#include <string.h>
-#include <strings.h>
-#include <stdbool.h>
-#include "sway/commands.h"
-#include "list.h"
-#include "stringop.h"
-
-static void find_marks_callback(swayc_t *container, void *_mark) {
- char *mark = (char *)_mark;
-
- int index;
- if (container->marks && ((index = list_seq_find(container->marks, (int (*)(const void *, const void *))strcmp, mark)) != -1)) {
- list_del(container->marks, index);
- }
-}
-
-struct cmd_results *cmd_mark(int argc, char **argv) {
- struct cmd_results *error = NULL;
- if (config->reading) return cmd_results_new(CMD_FAILURE, "mark", "Can't be used in config file.");
- if ((error = checkarg(argc, "mark", EXPECTED_AT_LEAST, 1))) {
- return error;
- }
-
- swayc_t *view = current_container;
- bool add = false;
- bool toggle = false;
-
- if (strcmp(argv[0], "--add") == 0) {
- --argc; ++argv;
- add = true;
- } else if (strcmp(argv[0], "--replace") == 0) {
- --argc; ++argv;
- }
-
- if (argc && strcmp(argv[0], "--toggle") == 0) {
- --argc; ++argv;
- toggle = true;
- }
-
- if (argc) {
- char *mark = join_args(argv, argc);
-
- // Remove all existing marks of this type
- container_map(&root_container, find_marks_callback, mark);
-
- if (view->marks) {
- if (add) {
- int index;
- if ((index = list_seq_find(view->marks, (int (*)(const void *, const void *))strcmp, mark)) != -1) {
- if (toggle) {
- free(view->marks->items[index]);
- list_del(view->marks, index);
-
- if (0 == view->marks->length) {
- list_free(view->marks);
- view->marks = NULL;
- }
- }
- free(mark);
- } else {
- list_add(view->marks, mark);
- }
- } else {
- if (toggle && list_seq_find(view->marks, (int (*)(const void *, const void *))strcmp, mark) != -1) {
- // Delete the list
- list_foreach(view->marks, free);
- list_free(view->marks);
- view->marks = NULL;
- } else {
- // Delete and replace with a new list
- list_foreach(view->marks, free);
- list_free(view->marks);
-
- view->marks = create_list();
- list_add(view->marks, mark);
- }
- }
- } else {
- view->marks = create_list();
- list_add(view->marks, mark);
- }
- } else {
- return cmd_results_new(CMD_FAILURE, "mark",
- "Expected 'mark [--add|--replace] [--toggle] <mark>'");
- }
- return cmd_results_new(CMD_SUCCESS, NULL, NULL);
-}
diff --git a/sway/old/commands/mode.c b/sway/old/commands/mode.c
deleted file mode 100644
index d2985c54..00000000
--- a/sway/old/commands/mode.c
+++ /dev/null
@@ -1,57 +0,0 @@
-#define _XOPEN_SOURCE 500
-#include <stdbool.h>
-#include <string.h>
-#include <strings.h>
-#include "sway/commands.h"
-#include "sway/config.h"
-#include "sway/ipc-server.h"
-#include "list.h"
-#include "log.h"
-
-struct cmd_results *cmd_mode(int argc, char **argv) {
- struct cmd_results *error = NULL;
- if ((error = checkarg(argc, "mode", EXPECTED_AT_LEAST, 1))) {
- return error;
- }
-
- const char *mode_name = argv[0];
- bool mode_make = (argc == 2 && strcmp(argv[1], "{") == 0);
- if (mode_make) {
- if (!config->reading)
- return cmd_results_new(CMD_FAILURE, "mode", "Can only be used in config file.");
- }
- struct sway_mode *mode = NULL;
- // Find mode
- int i, len = config->modes->length;
- for (i = 0; i < len; ++i) {
- struct sway_mode *find = config->modes->items[i];
- if (strcasecmp(find->name, mode_name) == 0) {
- mode = find;
- break;
- }
- }
- // Create mode if it doesn't exist
- if (!mode && mode_make) {
- mode = malloc(sizeof(struct sway_mode));
- if (!mode) {
- return cmd_results_new(CMD_FAILURE, "mode", "Unable to allocate mode");
- }
- mode->name = strdup(mode_name);
- mode->bindings = create_list();
- list_add(config->modes, mode);
- }
- if (!mode) {
- error = cmd_results_new(CMD_INVALID, "mode", "Unknown mode `%s'", mode_name);
- return error;
- }
- if ((config->reading && mode_make) || (!config->reading && !mode_make)) {
- sway_log(L_DEBUG, "Switching to mode `%s'",mode->name);
- }
- // Set current mode
- config->current_mode = mode;
- if (!mode_make) {
- // trigger IPC mode event
- ipc_event_mode(config->current_mode->name);
- }
- return cmd_results_new(mode_make ? CMD_BLOCK_MODE : CMD_SUCCESS, NULL, NULL);
-}
diff --git a/sway/old/commands/mouse_warping.c b/sway/old/commands/mouse_warping.c
deleted file mode 100644
index 5596d483..00000000
--- a/sway/old/commands/mouse_warping.c
+++ /dev/null
@@ -1,17 +0,0 @@
-#include <string.h>
-#include <strings.h>
-#include "sway/commands.h"
-
-struct cmd_results *cmd_mouse_warping(int argc, char **argv) {
- struct cmd_results *error = NULL;
- if ((error = checkarg(argc, "mouse_warping", EXPECTED_EQUAL_TO, 1))) {
- return error;
- } else if (strcasecmp(argv[0], "output") == 0) {
- config->mouse_warping = true;
- } else if (strcasecmp(argv[0], "none") == 0) {
- config->mouse_warping = false;
- } else {
- return cmd_results_new(CMD_FAILURE, "mouse_warping", "Expected 'mouse_warping output|none'");
- }
- return cmd_results_new(CMD_SUCCESS, NULL, NULL);
-}
diff --git a/sway/old/commands/move.c b/sway/old/commands/move.c
deleted file mode 100644
index 52c73e22..00000000
--- a/sway/old/commands/move.c
+++ /dev/null
@@ -1,189 +0,0 @@
-#define _POSIX_C_SOURCE 200809L
-#include <string.h>
-#include <strings.h>
-#include <wlc/wlc.h>
-#include "sway/commands.h"
-#include "sway/container.h"
-#include "sway/layout.h"
-#include "sway/output.h"
-#include "sway/workspace.h"
-#include "list.h"
-#include "stringop.h"
-
-struct cmd_results *cmd_move(int argc, char **argv) {
- struct cmd_results *error = NULL;
- int move_amt = 10;
-
- if (config->reading) return cmd_results_new(CMD_FAILURE, "move", "Can't be used in config file.");
- if ((error = checkarg(argc, "move", EXPECTED_AT_LEAST, 1))) {
- return error;
- }
- const char* expected_syntax = "Expected 'move <left|right|up|down|next|prev|first> <[px] px>' or "
- "'move <container|window> to workspace <name>' or "
- "'move <container|window|workspace> to output <name|direction>' or "
- "'move position mouse'";
- swayc_t *view = 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) {
- move_amt = 10;
- }
- }
-
- if (strcasecmp(argv[0], "left") == 0) {
- move_container(view, MOVE_LEFT, move_amt);
- } else if (strcasecmp(argv[0], "right") == 0) {
- move_container(view, MOVE_RIGHT, move_amt);
- } else if (strcasecmp(argv[0], "up") == 0) {
- move_container(view, MOVE_UP, move_amt);
- } else if (strcasecmp(argv[0], "down") == 0) {
- move_container(view, MOVE_DOWN, move_amt);
- } else if (strcasecmp(argv[0], "next") == 0) {
- move_container(view, MOVE_NEXT, move_amt);
- } else if (strcasecmp(argv[0], "prev") == 0) {
- move_container(view, MOVE_PREV, move_amt);
- } else if (strcasecmp(argv[0], "first") == 0) {
- move_container(view, MOVE_FIRST, move_amt);
- } else if (strcasecmp(argv[0], "container") == 0 || strcasecmp(argv[0], "window") == 0) {
- // "move container ...
- if ((error = checkarg(argc, "move container/window", EXPECTED_AT_LEAST, 4))) {
- return error;
- } else if (strcasecmp(argv[1], "to") == 0 && strcasecmp(argv[2], "workspace") == 0) {
- // move container to workspace x
- if (view->type == C_WORKSPACE) {
- if (!view->children || view->children->length == 0) {
- return cmd_results_new(CMD_FAILURE, "move", "Cannot move an empty workspace");
- }
- view = new_container(view, view->workspace_layout);
- } if (view->type != C_CONTAINER && view->type != C_VIEW) {
- return cmd_results_new(CMD_FAILURE, "move", "Can only move containers and views.");
- }
-
- swayc_t *ws;
- const char *num_name = NULL;
- char *ws_name = NULL;
- if (argc == 5 && strcasecmp(argv[3], "number") == 0) {
- // move "container to workspace number x"
- num_name = argv[4];
- ws = workspace_by_number(num_name);
- } else {
- ws_name = join_args(argv + 3, argc - 3);
- ws = workspace_by_name(ws_name);
- }
-
- if (ws == NULL) {
- ws = workspace_create(ws_name ? ws_name : num_name);
- }
- if (ws_name) {
- free(ws_name);
- }
- move_container_to(view, get_focused_container(ws));
- } else if (strcasecmp(argv[1], "to") == 0 && strcasecmp(argv[2], "output") == 0) {
- // move container to output x
- swayc_t *output = NULL;
- struct wlc_point abs_pos;
- get_absolute_center_position(view, &abs_pos);
- if (view->type == C_WORKSPACE) {
- if (!view->children || view->children->length == 0) {
- return cmd_results_new(CMD_FAILURE, "move", "Cannot move an empty workspace");
- }
- view = new_container(view, view->workspace_layout);
- } else if (view->type != C_CONTAINER && view->type != C_VIEW) {
- return cmd_results_new(CMD_FAILURE, "move", "Can only move containers and views.");
- } else if (!(output = output_by_name(argv[3], &abs_pos))) {
- return cmd_results_new(CMD_FAILURE, "move",
- "Can't find output with name/direction '%s' @ (%i,%i)", argv[3], abs_pos.x, abs_pos.y);
- }
-
- swayc_t *container = get_focused_container(output);
- if (container->is_floating) {
- move_container_to(view, container->parent);
- } else {
- move_container_to(view, container);
- }
- } else {
- return cmd_results_new(CMD_INVALID, "move", expected_syntax);
- }
- } else if (strcasecmp(argv[0], "workspace") == 0) {
- // move workspace (to output x)
- swayc_t *output = NULL;
- struct wlc_point abs_pos;
- get_absolute_center_position(view, &abs_pos);
- if ((error = checkarg(argc, "move workspace", EXPECTED_EQUAL_TO, 4))) {
- return error;
- } else if (strcasecmp(argv[1], "to") != 0 || strcasecmp(argv[2], "output") != 0) {
- return cmd_results_new(CMD_INVALID, "move", expected_syntax);
- } else if (!(output = output_by_name(argv[3], &abs_pos))) {
- return cmd_results_new(CMD_FAILURE, "move workspace",
- "Can't find output with name/direction '%s' @ (%i,%i)", argv[3], abs_pos.x, abs_pos.y);
- }
- if (view->type == C_WORKSPACE) {
- // This probably means we're moving an empty workspace, but
- // that's fine.
- move_workspace_to(view, output);
- } else {
- swayc_t *workspace = swayc_parent_by_type(view, C_WORKSPACE);
- move_workspace_to(workspace, output);
- }
- } else if (strcasecmp(argv[0], "scratchpad") == 0 || (strcasecmp(argv[0], "to") == 0 && strcasecmp(argv[1], "scratchpad") == 0)) {
- // move scratchpad ...
- if (view->type != C_CONTAINER && view->type != C_VIEW) {
- return cmd_results_new(CMD_FAILURE, "move scratchpad", "Can only move containers and views.");
- }
- swayc_t *view = current_container;
- int i;
- for (i = 0; i < scratchpad->length; i++) {
- if (scratchpad->items[i] == view) {
- hide_view_in_scratchpad(view);
- sp_view = NULL;
- return cmd_results_new(CMD_SUCCESS, NULL, NULL);
- }
- }
- list_add(scratchpad, view);
- if (!view->is_floating) {
- destroy_container(remove_child(view));
- } else {
- remove_child(view);
- }
- wlc_view_set_mask(view->handle, 0);
- arrange_windows(swayc_active_workspace(), -1, -1);
- swayc_t *focused = container_under_pointer();
- if (focused == NULL) {
- focused = swayc_active_workspace();
- }
- set_focused_container(focused);
- } else if (strcasecmp(argv[0], "position") == 0) {
- if ((error = checkarg(argc, "move workspace", EXPECTED_EQUAL_TO, 2))) {
- return error;
- }
- if (strcasecmp(argv[1], "mouse")) {
- return cmd_results_new(CMD_INVALID, "move", expected_syntax);
- }
-
- if (view->is_floating) {
- swayc_t *output = swayc_parent_by_type(view, C_OUTPUT);
- struct wlc_geometry g;
- wlc_view_get_visible_geometry(view->handle, &g);
- const struct wlc_size *size = wlc_output_get_resolution(output->handle);
-
- double x_pos, y_pos;
- wlc_pointer_get_position_v2(&x_pos, &y_pos);
-
- int32_t x = x_pos - g.size.w / 2;
- int32_t y = y_pos - g.size.h / 2;
-
- uint32_t w = size->w - g.size.w;
- uint32_t h = size->h - g.size.h;
-
- view->x = g.origin.x = MIN((int32_t)w, MAX(x, 0));
- view->y = g.origin.y = MIN((int32_t)h, MAX(y, 0));
-
- wlc_view_set_geometry(view->handle, 0, &g);
- }
- } else {
- return cmd_results_new(CMD_INVALID, "move", expected_syntax);
- }
- return cmd_results_new(CMD_SUCCESS, NULL, NULL);
-}
diff --git a/sway/old/commands/new_float.c b/sway/old/commands/new_float.c
deleted file mode 100644
index d0f96093..00000000
--- a/sway/old/commands/new_float.c
+++ /dev/null
@@ -1,8 +0,0 @@
-#include "log.h"
-#include "sway/commands.h"
-
-struct cmd_results *cmd_new_float(int argc, char **argv) {
- sway_log(L_INFO, "`new_float` is deprecated and will be removed in the future. "
- "Please use `default_floating_border` instead.");
- return cmd_default_floating_border(argc, argv);
-}
diff --git a/sway/old/commands/new_window.c b/sway/old/commands/new_window.c
deleted file mode 100644
index 574a4527..00000000
--- a/sway/old/commands/new_window.c
+++ /dev/null
@@ -1,8 +0,0 @@
-#include "log.h"
-#include "sway/commands.h"
-
-struct cmd_results *cmd_new_window(int argc, char **argv) {
- sway_log(L_INFO, "`new_window` is deprecated and will be removed in the future. "
- "Please use `default_border` instead.");
- return cmd_default_border(argc, argv);
-}
diff --git a/sway/old/commands/no_focus.c b/sway/old/commands/no_focus.c
deleted file mode 100644
index b3b88e5a..00000000
--- a/sway/old/commands/no_focus.c
+++ /dev/null
@@ -1,41 +0,0 @@
-#define _XOPEN_SOURCE 500
-#include <string.h>
-#include "sway/commands.h"
-#include "sway/criteria.h"
-#include "list.h"
-#include "log.h"
-#include "stringop.h"
-
-struct cmd_results *cmd_no_focus(int argc, char **argv) {
- struct cmd_results *error = NULL;
- if ((error = checkarg(argc, "no_focus", EXPECTED_EQUAL_TO, 1))) {
- return error;
- }
- // add command to a criteria/command pair that is run against views when they appear.
- char *criteria = argv[0];
-
- struct criteria *crit = malloc(sizeof(struct criteria));
- if (!crit) {
- return cmd_results_new(CMD_FAILURE, "no_focus", "Unable to allocate criteria");
- }
- crit->crit_raw = strdup(criteria);
- crit->tokens = create_list();
- crit->cmdlist = NULL;
- char *err_str = extract_crit_tokens(crit->tokens, crit->crit_raw);
-
- if (err_str) {
- error = cmd_results_new(CMD_INVALID, "no_focus", err_str);
- free(err_str);
- free_criteria(crit);
- } else if (crit->tokens->length == 0) {
- error = cmd_results_new(CMD_INVALID, "no_focus", "Found no name/value pairs in criteria");
- free_criteria(crit);
- } else if (list_seq_find(config->no_focus, criteria_cmp, crit) != -1) {
- sway_log(L_DEBUG, "no_focus: Duplicate, skipping.");
- free_criteria(crit);
- } else {
- sway_log(L_DEBUG, "no_focus: '%s' added", crit->crit_raw);
- list_add(config->no_focus, crit);
- }
- return error ? error : cmd_results_new(CMD_SUCCESS, NULL, NULL);
-}
diff --git a/sway/old/commands/orientation.c b/sway/old/commands/orientation.c
deleted file mode 100644
index e54b60ee..00000000
--- a/sway/old/commands/orientation.c
+++ /dev/null
@@ -1,21 +0,0 @@
-#include <string.h>
-#include <strings.h>
-#include "sway/commands.h"
-
-struct cmd_results *cmd_orientation(int argc, char **argv) {
- struct cmd_results *error = NULL;
- if (!config->reading) return cmd_results_new(CMD_FAILURE, "orientation", "Can only be used in config file.");
- if ((error = checkarg(argc, "orientation", EXPECTED_EQUAL_TO, 1))) {
- return error;
- }
- if (strcasecmp(argv[0], "horizontal") == 0) {
- config->default_orientation = L_HORIZ;
- } else if (strcasecmp(argv[0], "vertical") == 0) {
- config->default_orientation = L_VERT;
- } else if (strcasecmp(argv[0], "auto") == 0) {
- // Do nothing
- } else {
- return cmd_results_new(CMD_INVALID, "orientation", "Expected 'orientation <horizontal|vertical|auto>'");
- }
- return cmd_results_new(CMD_SUCCESS, NULL, NULL);
-}
diff --git a/sway/old/commands/output.c b/sway/old/commands/output.c
deleted file mode 100644
index 911391d2..00000000
--- a/sway/old/commands/output.c
+++ /dev/null
@@ -1,219 +0,0 @@
-#define _XOPEN_SOURCE 500
-#include <ctype.h>
-#include <libgen.h>
-#include <stdlib.h>
-#include <string.h>
-#include <strings.h>
-#include <unistd.h>
-#include <wordexp.h>
-#include "sway/commands.h"
-#include "sway/config.h"
-#include "list.h"
-#include "log.h"
-#include "stringop.h"
-
-static char *bg_options[] = {
- "stretch",
- "center",
- "fill",
- "fit",
- "tile"
-};
-
-struct cmd_results *cmd_output(int argc, char **argv) {
- struct cmd_results *error = NULL;
- if ((error = checkarg(argc, "output", EXPECTED_AT_LEAST, 1))) {
- return error;
- }
- const char *name = argv[0];
-
- struct output_config *output = calloc(1, sizeof(struct output_config));
- if (!output) {
- return cmd_results_new(CMD_FAILURE, "output", "Unable to allocate output config");
- }
- output->x = output->y = output->width = output->height = -1;
- output->name = strdup(name);
- output->enabled = -1;
- output->scale = 1;
-
- // TODO: atoi doesn't handle invalid numbers
-
- int i;
- for (i = 1; i < argc; ++i) {
- const char *command = argv[i];
-
- if (strcasecmp(command, "disable") == 0) {
- output->enabled = 0;
- } else if (strcasecmp(command, "resolution") == 0 || strcasecmp(command, "res") == 0) {
- if (++i >= argc) {
- error = cmd_results_new(CMD_INVALID, "output", "Missing resolution argument.");
- goto fail;
- }
- char *res = argv[i];
- char *x = strchr(res, 'x');
- int width = -1, height = -1;
- if (x != NULL) {
- // Format is 1234x4321
- *x = '\0';
- width = atoi(res);
- height = atoi(x + 1);
- *x = 'x';
- } else {
- // Format is 1234 4321
- width = atoi(res);
- if (++i >= argc) {
- error = cmd_results_new(CMD_INVALID, "output", "Missing resolution argument (height).");
- goto fail;
- }
- res = argv[i];
- height = atoi(res);
- }
- output->width = width;
- output->height = height;
- } else if (strcasecmp(command, "position") == 0 || strcasecmp(command, "pos") == 0) {
- if (++i >= argc) {
- error = cmd_results_new(CMD_INVALID, "output", "Missing position argument.");
- goto fail;
- }
- char *res = argv[i];
- char *c = strchr(res, ',');
- int x = -1, y = -1;
- if (c != NULL) {
- // Format is 1234,4321
- *c = '\0';
- x = atoi(res);
- y = atoi(c + 1);
- *c = ',';
- } else {
- // Format is 1234 4321
- x = atoi(res);
- if (++i >= argc) {
- error = cmd_results_new(CMD_INVALID, "output", "Missing position argument (y).");
- goto fail;
- }
- res = argv[i];
- y = atoi(res);
- }
- output->x = x;
- output->y = y;
- } else if (strcasecmp(command, "scale") == 0) {
- if (++i >= argc) {
- error = cmd_results_new(CMD_INVALID, "output", "Missing scale parameter.");
- goto fail;
- }
- output->scale = atoi(argv[i]);
- } else if (strcasecmp(command, "background") == 0 || strcasecmp(command, "bg") == 0) {
- wordexp_t p;
- if (++i >= argc) {
- error = cmd_results_new(CMD_INVALID, "output", "Missing background file or color specification.");
- goto fail;
- }
- if (i + 1 >= argc) {
- error = cmd_results_new(CMD_INVALID, "output", "Missing background scaling mode or `solid_color`.");
- goto fail;
- }
- if (strcasecmp(argv[i + 1], "solid_color") == 0) {
- output->background = strdup(argv[argc - 2]);
- output->background_option = strdup("solid_color");
- } else {
- // argv[i+j]=bg_option
- bool valid = false;
- char *mode;
- size_t j;
- for (j = 0; j < (size_t) (argc - i); ++j) {
- mode = argv[i + j];
- for (size_t k = 0; k < sizeof(bg_options) / sizeof(char *); ++k) {
- if (strcasecmp(mode, bg_options[k]) == 0) {
- valid = true;
- break;
- }
- }
- if (valid) {
- break;
- }
- }
- if (!valid) {
- error = cmd_results_new(CMD_INVALID, "output", "Missing background scaling mode.");
- goto fail;
- }
-
- char *src = join_args(argv + i, j);
- if (wordexp(src, &p, 0) != 0 || p.we_wordv[0] == NULL) {
- error = cmd_results_new(CMD_INVALID, "output", "Invalid syntax (%s)", src);
- goto fail;
- }
- free(src);
- src = p.we_wordv[0];
- if (config->reading && *src != '/') {
- char *conf = strdup(config->current_config);
- if (conf) {
- char *conf_path = dirname(conf);
- src = malloc(strlen(conf_path) + strlen(src) + 2);
- if (src) {
- sprintf(src, "%s/%s", conf_path, p.we_wordv[0]);
- } else {
- sway_log(L_ERROR, "Unable to allocate background source");
- }
- free(conf);
- } else {
- sway_log(L_ERROR, "Unable to allocate background source");
- }
- }
- if (!src || access(src, F_OK) == -1) {
- error = cmd_results_new(CMD_INVALID, "output", "Background file unreadable (%s)", src);
- wordfree(&p);
- goto fail;
- }
-
- output->background = strdup(src);
- output->background_option = strdup(mode);
- if (src != p.we_wordv[0]) {
- free(src);
- }
- wordfree(&p);
-
- i += j;
- }
- }
- }
-
- i = list_seq_find(config->output_configs, output_name_cmp, name);
- if (i >= 0) {
- // merge existing config
- struct output_config *oc = config->output_configs->items[i];
- merge_output_config(oc, output);
- free_output_config(output);
- output = oc;
- } else {
- list_add(config->output_configs, output);
- }
-
- sway_log(L_DEBUG, "Config stored for output %s (enabled:%d) (%d x %d @ %d, %d scale %d) (bg %s %s)",
- output->name, output->enabled, output->width,
- output->height, output->x, output->y, output->scale,
- output->background, output->background_option);
-
- if (output->name) {
- // Try to find the output container and apply configuration now. If
- // this is during startup then there will be no container and config
- // will be applied during normal "new output" event from wlc.
- swayc_t *cont = NULL;
- for (int i = 0; i < root_container.children->length; ++i) {
- cont = root_container.children->items[i];
- if (cont->name && ((strcmp(cont->name, output->name) == 0) || (strcmp(output->name, "*") == 0))) {
- apply_output_config(output, cont);
-
- if (strcmp(output->name, "*") != 0) {
- // stop looking if the output config isn't applicable to all outputs
- break;
- }
- }
- }
- }
-
- return cmd_results_new(CMD_SUCCESS, NULL, NULL);
-
-fail:
- free_output_config(output);
- return error;
-}
diff --git a/sway/old/commands/permit.c b/sway/old/commands/permit.c
deleted file mode 100644
index 7a5e06f7..00000000
--- a/sway/old/commands/permit.c
+++ /dev/null
@@ -1,108 +0,0 @@
-#define _XOPEN_SOURCE 500
-#include <string.h>
-#include "sway/commands.h"
-#include "sway/config.h"
-#include "sway/security.h"
-#include "util.h"
-#include "log.h"
-
-static enum secure_feature get_features(int argc, char **argv,
- struct cmd_results **error) {
- enum secure_feature features = 0;
-
- struct {
- char *name;
- enum secure_feature feature;
- } feature_names[] = {
- { "lock", FEATURE_LOCK },
- { "panel", FEATURE_PANEL },
- { "background", FEATURE_BACKGROUND },
- { "screenshot", FEATURE_SCREENSHOT },
- { "fullscreen", FEATURE_FULLSCREEN },
- { "keyboard", FEATURE_KEYBOARD },
- { "mouse", FEATURE_MOUSE },
- };
-
- for (int i = 1; i < argc; ++i) {
- size_t j;
- for (j = 0; j < sizeof(feature_names) / sizeof(feature_names[0]); ++j) {
- if (strcmp(feature_names[j].name, argv[i]) == 0) {
- break;
- }
- }
- if (j == sizeof(feature_names) / sizeof(feature_names[0])) {
- *error = cmd_results_new(CMD_INVALID,
- "permit", "Invalid feature grant %s", argv[i]);
- return 0;
- }
- features |= feature_names[j].feature;
- }
- return features;
-}
-
-struct cmd_results *cmd_permit(int argc, char **argv) {
- struct cmd_results *error = NULL;
- if ((error = checkarg(argc, "permit", EXPECTED_MORE_THAN, 1))) {
- return error;
- }
- if ((error = check_security_config())) {
- return error;
- }
-
- bool assign_perms = true;
- char *program = NULL;
-
- if (!strcmp(argv[0], "*")) {
- program = strdup(argv[0]);
- } else {
- program = resolve_path(argv[0]);
- }
- if (!program) {
- sway_assert(program, "Unable to resolve IPC permit target '%s'."
- " will issue empty policy", argv[0]);
- assign_perms = false;
- program = strdup(argv[0]);
- }
-
- struct feature_policy *policy = get_feature_policy(program);
- if (policy && assign_perms) {
- policy->features |= get_features(argc, argv, &error);
- sway_log(L_DEBUG, "Permissions granted to %s for features %d",
- policy->program, policy->features);
- }
-
- free(program);
- return cmd_results_new(CMD_SUCCESS, NULL, NULL);
-}
-
-struct cmd_results *cmd_reject(int argc, char **argv) {
- struct cmd_results *error = NULL;
- if ((error = checkarg(argc, "reject", EXPECTED_MORE_THAN, 1))) {
- return error;
- }
- if ((error = check_security_config())) {
- return error;
- }
-
- char *program = NULL;
- if (!strcmp(argv[0], "*")) {
- program = strdup(argv[0]);
- } else {
- program = resolve_path(argv[0]);
- }
- if (!program) {
- // Punt
- sway_log(L_INFO, "Unable to resolve IPC reject target '%s'."
- " Will use provided path", argv[0]);
- program = strdup(argv[0]);
- }
-
- struct feature_policy *policy = get_feature_policy(program);
- policy->features &= ~get_features(argc, argv, &error);
-
- sway_log(L_DEBUG, "Permissions granted to %s for features %d",
- policy->program, policy->features);
-
- free(program);
- return cmd_results_new(CMD_SUCCESS, NULL, NULL);
-}
diff --git a/sway/old/commands/reload.c b/sway/old/commands/reload.c
deleted file mode 100644
index 01fcc5ba..00000000
--- a/sway/old/commands/reload.c
+++ /dev/null
@@ -1,19 +0,0 @@
-#include "sway/commands.h"
-#include "sway/config.h"
-#include "sway/layout.h"
-
-struct cmd_results *cmd_reload(int argc, char **argv) {
- struct cmd_results *error = NULL;
- if (config->reading) return cmd_results_new(CMD_FAILURE, "reload", "Can't be used in config file.");
- if ((error = checkarg(argc, "reload", EXPECTED_EQUAL_TO, 0))) {
- return error;
- }
- if (!load_main_config(config->current_config, true)) {
- return cmd_results_new(CMD_FAILURE, "reload", "Error(s) reloading config.");
- }
-
- load_swaybars();
-
- arrange_windows(&root_container, -1, -1);
- return cmd_results_new(CMD_SUCCESS, NULL, NULL);
-}
diff --git a/sway/old/commands/resize.c b/sway/old/commands/resize.c
deleted file mode 100644
index ef52bb07..00000000
--- a/sway/old/commands/resize.c
+++ /dev/null
@@ -1,375 +0,0 @@
-#include <errno.h>
-#include <math.h>
-#include <stdbool.h>
-#include <stdlib.h>
-#include <string.h>
-#include <strings.h>
-#include <wlc/wlc.h>
-#include "sway/commands.h"
-#include "sway/layout.h"
-#include "sway/focus.h"
-#include "sway/input_state.h"
-#include "sway/handlers.h"
-#include "log.h"
-
-enum resize_dim_types {
- RESIZE_DIM_PX,
- RESIZE_DIM_PPT,
- RESIZE_DIM_DEFAULT,
-};
-
-static bool set_size_floating(int new_dimension, bool use_width) {
- swayc_t *view = current_container;
- if (view) {
- if (use_width) {
- int current_width = view->width;
- view->desired_width = new_dimension;
- floating_view_sane_size(view);
-
- int new_x = view->x + (int)(((view->desired_width - current_width) / 2) * -1);
- view->width = view->desired_width;
- view->x = new_x;
-
- update_geometry(view);
- } else {
- int current_height = view->height;
- view->desired_height = new_dimension;
- floating_view_sane_size(view);
-
- int new_y = view->y + (int)(((view->desired_height - current_height) / 2) * -1);
- view->height = view->desired_height;
- view->y = new_y;
-
- update_geometry(view);
- }
-
- return true;
- }
-
- return false;
-}
-
-static bool resize_floating(int amount, bool use_width) {
- swayc_t *view = current_container;
-
- if (view) {
- if (use_width) {
- return set_size_floating(view->width + amount, true);
- } else {
- return set_size_floating(view->height + amount, false);
- }
- }
-
- return false;
-}
-
-static bool resize_tiled(int amount, bool use_width) {
- swayc_t *container = current_container;
- swayc_t *parent = container->parent;
- int idx_focused = 0;
- bool use_major = false;
- size_t nb_before = 0;
- size_t nb_after = 0;
-
- // 1. Identify a container ancestor that will allow the focused child to grow in the requested
- // direction.
- while (container->parent) {
- parent = container->parent;
- if ((parent->children && parent->children->length > 1)
- && (is_auto_layout(parent->layout)
- || (use_width ? parent->layout == L_HORIZ : parent->layout == L_VERT))) {
- // check if container has siblings that can provide/absorb the space needed for
- // the resize operation.
- use_major = use_width
- ? parent->layout == L_AUTO_LEFT || parent->layout == L_AUTO_RIGHT
- : parent->layout == L_AUTO_TOP || parent->layout == L_AUTO_BOTTOM;
- // Note: use_major will be false for L_HORIZ and L_VERT
-
- idx_focused = index_child(container);
- if (idx_focused < 0) {
- sway_log(L_ERROR, "Something weird is happening, child container not "
- "present in its parent's children list.");
- continue;
- }
- if (use_major) {
- nb_before = auto_group_index(parent, idx_focused);
- nb_after = auto_group_count(parent) - nb_before - 1;
- } else {
- nb_before = idx_focused - auto_group_start_index(parent, idx_focused);
- nb_after = auto_group_end_index(parent, idx_focused) - idx_focused - 1;
- sway_log(L_DEBUG, "+++ focused: %d, start: %d, end: %d, before: %d, after: %d",
- idx_focused,
- (int)auto_group_start_index(parent, idx_focused),
- (int)auto_group_end_index(parent, idx_focused),
- (int)nb_before, (int)nb_after);
-
- }
- if (nb_before || nb_after) {
- break;
- }
- }
- container = parent; /* continue up the tree to the next ancestor */
- }
- if (parent == &root_container) {
- return true;
- }
- sway_log(L_DEBUG, "Found the proper parent: %p. It has %zu before conts, "
- "and %zu after conts", parent, nb_before, nb_after);
- // 2. Ensure that the resize operation will not make one of the resized containers drop
- // below the "sane" size threshold.
- bool valid = true;
- swayc_t *focused = parent->children->items[idx_focused];
- int start = use_major ? 0 : auto_group_start_index(parent, idx_focused);
- int end = use_major ? parent->children->length : auto_group_end_index(parent, idx_focused);
- sway_log(L_DEBUG, "Check children of container %p [%d,%d[", container, start, end);
- for (int i = start; i < end; ) {
- swayc_t *sibling = parent->children->items[i];
- double pixels = amount;
- bool is_before = use_width ? sibling->x < focused->x : sibling->y < focused->y;
- bool is_after = use_width ? sibling->x > focused->x : sibling->y > focused->y;
- if (is_before || is_after) {
- pixels = -pixels;
- pixels /= is_before ? nb_before : nb_after;
- if (nb_after != 0 && nb_before != 0) {
- pixels /= 2;
- }
- }
- sway_log(L_DEBUG, "Check container %p: width %g vs %d, height %g vs %d", sibling, sibling->width + pixels, min_sane_w, sibling->height + pixels, min_sane_h);
- if (use_width ?
- sibling->width + pixels < min_sane_w :
- sibling->height + pixels < min_sane_h) {
- valid = false;
- sway_log(L_DEBUG, "Container size no longer sane");
- break;
- }
- i = use_major ? auto_group_end_index(parent, i) : (i + 1);
- sway_log(L_DEBUG, "+++++ check %i", i);
- }
- // 3. Apply the size change
- if (valid) {
- for (int i = start; i < end; ) {
- int next_i = use_major ? auto_group_end_index(parent, i) : (i + 1);
- swayc_t *sibling = parent->children->items[i];
- double pixels = amount;
- bool is_before = use_width ? sibling->x < focused->x : sibling->y < focused->y;
- bool is_after = use_width ? sibling->x > focused->x : sibling->y > focused->y;
- if (is_before || is_after) {
- pixels = -pixels;
- pixels /= is_before ? nb_before : nb_after;
- if (nb_after != 0 && nb_before != 0) {
- pixels /= 2;
- }
- sway_log(L_DEBUG, "%p: %s", sibling, is_before ? "before" : "after");
- if (use_major) {
- for (int j = i; j < next_i; ++j) {
- recursive_resize(parent->children->items[j], pixels,
- use_width ?
- (is_before ? WLC_RESIZE_EDGE_RIGHT : WLC_RESIZE_EDGE_LEFT) :
- (is_before ? WLC_RESIZE_EDGE_BOTTOM : WLC_RESIZE_EDGE_TOP));
- }
- } else {
- recursive_resize(sibling, pixels,
- use_width ?
- (is_before ? WLC_RESIZE_EDGE_RIGHT : WLC_RESIZE_EDGE_LEFT) :
- (is_before ? WLC_RESIZE_EDGE_BOTTOM : WLC_RESIZE_EDGE_TOP));
- }
- } else {
- if (use_major) {
- for (int j = i; j < next_i; ++j) {
- recursive_resize(parent->children->items[j], pixels / 2,
- use_width ? WLC_RESIZE_EDGE_LEFT : WLC_RESIZE_EDGE_TOP);
- recursive_resize(parent->children->items[j], pixels / 2,
- use_width ? WLC_RESIZE_EDGE_RIGHT : WLC_RESIZE_EDGE_BOTTOM);
- }
- } else {
- recursive_resize(sibling, pixels / 2,
- use_width ? WLC_RESIZE_EDGE_LEFT : WLC_RESIZE_EDGE_TOP);
- recursive_resize(sibling, pixels / 2,
- use_width ? WLC_RESIZE_EDGE_RIGHT : WLC_RESIZE_EDGE_BOTTOM);
- }
- }
- i = next_i;
- }
- // Recursive resize does not handle positions, let arrange_windows
- // take care of that.
- arrange_windows(swayc_active_workspace(), -1, -1);
- }
- return true;
-}
-
-static bool set_size_tiled(int amount, bool use_width) {
- int desired;
- swayc_t *focused = current_container;
-
- if (use_width) {
- desired = amount - focused->width;
- } else {
- desired = amount - focused->height;
- }
-
- return resize_tiled(desired, use_width);
-}
-
-static bool set_size(int dimension, bool use_width) {
- swayc_t *focused = current_container;
-
- if (focused) {
- if (focused->is_floating) {
- return set_size_floating(dimension, use_width);
- } else {
- return set_size_tiled(dimension, use_width);
- }
- }
-
- return false;
-}
-
-static bool resize(int dimension, bool use_width, enum resize_dim_types dim_type) {
- swayc_t *focused = current_container;
-
- // translate "10 ppt" (10%) to appropriate # of pixels in case we need it
- float ppt_dim = (float)dimension / 100;
-
- if (use_width) {
- ppt_dim = focused->width * ppt_dim;
- } else {
- ppt_dim = focused->height * ppt_dim;
- }
-
- if (focused) {
- if (focused->is_floating) {
- // floating view resize dimensions should default to px, so only
- // use ppt if specified
- if (dim_type == RESIZE_DIM_PPT) {
- dimension = (int)ppt_dim;
- }
-
- return resize_floating(dimension, use_width);
- } else {
- // tiled view resize dimensions should default to ppt, so only use
- // px if specified
- if (dim_type != RESIZE_DIM_PX) {
- dimension = (int)ppt_dim;
- }
-
- return resize_tiled(dimension, use_width);
- }
- }
-
- return false;
-}
-
-static struct cmd_results *cmd_resize_set(int argc, char **argv) {
- struct cmd_results *error = NULL;
- if ((error = checkarg(argc, "resize set", EXPECTED_AT_LEAST, 2))) {
- return error;
- }
-
- if (strcasecmp(argv[0], "width") == 0 || strcasecmp(argv[0], "height") == 0) {
- // handle `reset set width 100 px height 100 px` syntax, also allows
- // specifying only one dimension for a `resize set`
- int cmd_num = 0;
- int dim;
-
- while ((cmd_num + 1) < argc) {
- dim = (int)strtol(argv[cmd_num + 1], NULL, 10);
- if (errno == ERANGE || dim == 0) {
- errno = 0;
- return cmd_results_new(CMD_INVALID, "resize set",
- "Expected 'resize set <width|height> <amount> [px] [<width|height> <amount> [px]]'");
- }
-
- if (strcasecmp(argv[cmd_num], "width") == 0) {
- set_size(dim, true);
- } else if (strcasecmp(argv[cmd_num], "height") == 0) {
- set_size(dim, false);
- } else {
- return cmd_results_new(CMD_INVALID, "resize set",
- "Expected 'resize set <width|height> <amount> [px] [<width|height> <amount> [px]]'");
- }
-
- cmd_num += 2;
-
- if (cmd_num < argc && strcasecmp(argv[cmd_num], "px") == 0) {
- // if this was `resize set width 400 px height 300 px`, disregard the `px` arg
- cmd_num++;
- }
- }
- } else {
- // handle `reset set 100 px 100 px` syntax
- int width = (int)strtol(argv[0], NULL, 10);
- if (errno == ERANGE || width == 0) {
- errno = 0;
- return cmd_results_new(CMD_INVALID, "resize set",
- "Expected 'resize set <width> [px] <height> [px]'");
- }
-
- int height_arg = 1;
- if (strcasecmp(argv[1], "px") == 0) {
- height_arg = 2;
- }
-
- int height = (int)strtol(argv[height_arg], NULL, 10);
- if (errno == ERANGE || height == 0) {
- errno = 0;
- return cmd_results_new(CMD_INVALID, "resize set",
- "Expected 'resize set <width> [px] <height> [px]'");
- }
-
- set_size(width, true);
- set_size(height, false);
- }
-
- return cmd_results_new(CMD_SUCCESS, NULL, NULL);
-}
-
-struct cmd_results *cmd_resize(int argc, char **argv) {
- struct cmd_results *error = NULL;
- if (config->reading) return cmd_results_new(CMD_FAILURE, "resize", "Can't be used in config file.");
- if (!config->active) return cmd_results_new(CMD_FAILURE, "resize", "Can only be used when sway is running.");
-
- if (strcasecmp(argv[0], "set") == 0) {
- return cmd_resize_set(argc - 1, &argv[1]);
- }
-
- if ((error = checkarg(argc, "resize", EXPECTED_AT_LEAST, 2))) {
- return error;
- }
-
- int dim_arg = argc - 1;
-
- enum resize_dim_types dim_type = RESIZE_DIM_DEFAULT;
- if (strcasecmp(argv[dim_arg], "ppt") == 0) {
- dim_type = RESIZE_DIM_PPT;
- dim_arg--;
- } else if (strcasecmp(argv[dim_arg], "px") == 0) {
- dim_type = RESIZE_DIM_PX;
- dim_arg--;
- }
-
- int amount = (int)strtol(argv[dim_arg], NULL, 10);
- if (errno == ERANGE || amount == 0) {
- errno = 0;
- amount = 10; // this is the default resize dimension used by i3 for both px and ppt
- sway_log(L_DEBUG, "Tried to get resize dimension out of '%s' but failed; setting dimension to default %d",
- argv[dim_arg], amount);
- }
-
- bool use_width = false;
- if (strcasecmp(argv[1], "width") == 0) {
- use_width = true;
- } else if (strcasecmp(argv[1], "height") != 0) {
- return cmd_results_new(CMD_INVALID, "resize",
- "Expected 'resize <shrink|grow> <width|height> [<amount>] [px|ppt]'");
- }
-
- if (strcasecmp(argv[0], "shrink") == 0) {
- amount *= -1;
- } else if (strcasecmp(argv[0], "grow") != 0) {
- return cmd_results_new(CMD_INVALID, "resize",
- "Expected 'resize <shrink|grow> <width|height> [<amount>] [px|ppt]'");
- }
-
- resize(amount, use_width, dim_type);
- return cmd_results_new(CMD_SUCCESS, NULL, NULL);
-}
diff --git a/sway/old/commands/scratchpad.c b/sway/old/commands/scratchpad.c
deleted file mode 100644
index 6c5c92df..00000000
--- a/sway/old/commands/scratchpad.c
+++ /dev/null
@@ -1,72 +0,0 @@
-#include <string.h>
-#include <strings.h>
-#include <wlc/wlc.h>
-#include "sway/commands.h"
-#include "sway/container.h"
-#include "sway/focus.h"
-#include "sway/layout.h"
-
-static swayc_t *fetch_view_from_scratchpad() {
- sp_index = (sp_index + 1) % scratchpad->length;
- swayc_t *view = scratchpad->items[sp_index];
-
- if (wlc_view_get_output(view->handle) != swayc_active_output()->handle) {
- wlc_view_set_output(view->handle, swayc_active_output()->handle);
- }
- if (!view->is_floating) {
- view->width = swayc_active_workspace()->width * 0.5;
- view->height = swayc_active_workspace()->height * 0.75;
- view->x = (swayc_active_workspace()->width - view->width)/2;
- view->y = (swayc_active_workspace()->height - view->height)/2;
- }
- if (swayc_active_workspace()->width < view->x + 20 || view->x + view->width < 20) {
- view->x = (swayc_active_workspace()->width - view->width)/2;
- }
- if (swayc_active_workspace()->height < view->y + 20 || view->y + view->height < 20) {
- view->y = (swayc_active_workspace()->height - view->height)/2;
- }
-
- add_floating(swayc_active_workspace(), view);
- wlc_view_set_mask(view->handle, VISIBLE);
- view->visible = true;
- arrange_windows(swayc_active_workspace(), -1, -1);
- set_focused_container(view);
- return view;
-}
-
-struct cmd_results *cmd_scratchpad(int argc, char **argv) {
- struct cmd_results *error = NULL;
- if (config->reading) return cmd_results_new(CMD_FAILURE, "scratchpad", "Can't be used in config file.");
- if (!config->active) return cmd_results_new(CMD_FAILURE, "scratchpad", "Can only be used when sway is running.");
- if ((error = checkarg(argc, "scratchpad", EXPECTED_EQUAL_TO, 1))) {
- return error;
- }
-
- if (strcasecmp(argv[0], "show") == 0 && scratchpad->length > 0) {
- if (!sp_view) {
- if (current_container) {
- // Haxor the scratchpad index if criteria'd
- for (int i = 0; i < scratchpad->length; ++i) {
- if (scratchpad->items[i] == current_container) {
- sp_index = (i - 1) % scratchpad->length;
- }
- }
- }
- sp_view = fetch_view_from_scratchpad();
- } else {
- if (swayc_active_workspace() != sp_view->parent) {
- hide_view_in_scratchpad(sp_view);
- if (sp_index == 0) {
- sp_index = scratchpad->length;
- }
- sp_index--;
- sp_view = fetch_view_from_scratchpad();
- } else {
- hide_view_in_scratchpad(sp_view);
- sp_view = NULL;
- }
- }
- return cmd_results_new(CMD_SUCCESS, NULL, NULL);
- }
- return cmd_results_new(CMD_FAILURE, "scratchpad", "Expected 'scratchpad show' when scratchpad is not empty.");
-}
diff --git a/sway/old/commands/seamless_mouse.c b/sway/old/commands/seamless_mouse.c
deleted file mode 100644
index 7760e88d..00000000
--- a/sway/old/commands/seamless_mouse.c
+++ /dev/null
@@ -1,13 +0,0 @@
-#include <string.h>
-#include <strings.h>
-#include "sway/commands.h"
-
-struct cmd_results *cmd_seamless_mouse(int argc, char **argv) {
- struct cmd_results *error = NULL;
- if ((error = checkarg(argc, "seamless_mouse", EXPECTED_EQUAL_TO, 1))) {
- return error;
- }
-
- config->seamless_mouse = (strcasecmp(argv[0], "on") == 0 || strcasecmp(argv[0], "yes") == 0);
- return cmd_results_new(CMD_SUCCESS, NULL, NULL);
-}
diff --git a/sway/old/commands/set.c b/sway/old/commands/set.c
deleted file mode 100644
index 46fc6d38..00000000
--- a/sway/old/commands/set.c
+++ /dev/null
@@ -1,61 +0,0 @@
-#define _XOPEN_SOURCE 700
-#include <stdio.h>
-#include <string.h>
-#include <strings.h>
-#include "sway/commands.h"
-#include "sway/config.h"
-#include "list.h"
-#include "stringop.h"
-
-// sort in order of longest->shortest
-static int compare_set_qsort(const void *_l, const void *_r) {
- struct sway_variable const *l = *(void **)_l;
- struct sway_variable const *r = *(void **)_r;
- return strlen(r->name) - strlen(l->name);
-}
-
-struct cmd_results *cmd_set(int argc, char **argv) {
- char *tmp;
- struct cmd_results *error = NULL;
- if (!config->reading) return cmd_results_new(CMD_FAILURE, "set", "Can only be used in config file.");
- if ((error = checkarg(argc, "set", EXPECTED_AT_LEAST, 2))) {
- return error;
- }
-
- if (argv[0][0] != '$') {
- sway_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);
- if (!tmp) {
- return cmd_results_new(CMD_FAILURE, "set", "Not possible to create variable $'%s'", argv[0]);
- }
- snprintf(tmp, size+1, "$%s", argv[0]);
-
- argv[0] = tmp;
- }
-
- struct sway_variable *var = NULL;
- // Find old variable if it exists
- int i;
- for (i = 0; i < config->symbols->length; ++i) {
- var = config->symbols->items[i];
- if (strcmp(var->name, argv[0]) == 0) {
- break;
- }
- var = NULL;
- }
- if (var) {
- free(var->value);
- } else {
- var = malloc(sizeof(struct sway_variable));
- if (!var) {
- return cmd_results_new(CMD_FAILURE, "set", "Unable to allocate variable");
- }
- var->name = strdup(argv[0]);
- list_add(config->symbols, var);
- list_qsort(config->symbols, compare_set_qsort);
- }
- var->value = join_args(argv + 1, argc - 1);
- return cmd_results_new(CMD_SUCCESS, NULL, NULL);
-}
diff --git a/sway/old/commands/show_marks.c b/sway/old/commands/show_marks.c
deleted file mode 100644
index ed56d9e5..00000000
--- a/sway/old/commands/show_marks.c
+++ /dev/null
@@ -1,13 +0,0 @@
-#include <string.h>
-#include <strings.h>
-#include "sway/commands.h"
-
-struct cmd_results *cmd_show_marks(int argc, char **argv) {
- struct cmd_results *error = NULL;
- if ((error = checkarg(argc, "show_marks", EXPECTED_EQUAL_TO, 1))) {
- return error;
- }
-
- config->show_marks = !strcasecmp(argv[0], "on");
- return cmd_results_new(CMD_SUCCESS, NULL, NULL);
-}
diff --git a/sway/old/commands/smart_gaps.c b/sway/old/commands/smart_gaps.c
deleted file mode 100644
index 815fc501..00000000
--- a/sway/old/commands/smart_gaps.c
+++ /dev/null
@@ -1,20 +0,0 @@
-#include <string.h>
-#include <strings.h>
-#include "sway/commands.h"
-
-struct cmd_results *cmd_smart_gaps(int argc, char **argv) {
- struct cmd_results *error = NULL;
- if ((error = checkarg(argc, "smart_gaps", EXPECTED_EQUAL_TO, 1))) {
- return error;
- }
-
- if (strcasecmp(argv[0], "on") == 0) {
- config->smart_gaps = true;
- } else if (strcasecmp(argv[0], "off") == 0) {
- config->smart_gaps = false;
- } else {
- return cmd_results_new(CMD_INVALID, "smart_gaps", "Expected 'smart_gaps <on|off>'");
- }
-
- return cmd_results_new(CMD_SUCCESS, NULL, NULL);
-}
diff --git a/sway/old/commands/split.c b/sway/old/commands/split.c
deleted file mode 100644
index e3045a4f..00000000
--- a/sway/old/commands/split.c
+++ /dev/null
@@ -1,98 +0,0 @@
-#include <string.h>
-#include <strings.h>
-#include <wlc/wlc-render.h>
-#include "sway/border.h"
-#include "sway/commands.h"
-#include "sway/container.h"
-#include "sway/focus.h"
-#include "sway/layout.h"
-#include "log.h"
-
-static struct cmd_results *_do_split(int argc, char **argv, int layout) {
- char *name = layout == L_VERT ? "splitv" :
- layout == L_HORIZ ? "splith" : "split";
- struct cmd_results *error = NULL;
- if (config->reading) return cmd_results_new(CMD_FAILURE, name, "Can't be used in config file.");
- if (!config->active) return cmd_results_new(CMD_FAILURE, name, "Can only be used when sway is running.");
- if ((error = checkarg(argc, name, EXPECTED_EQUAL_TO, 0))) {
- return error;
- }
- swayc_t *focused = current_container;
-
- // Case of floating window, don't split
- if (focused->is_floating) {
- return cmd_results_new(CMD_SUCCESS, NULL, NULL);
- }
- /* Case that focus is on an workspace with 0/1 children.change its layout */
- if (focused->type == C_WORKSPACE && focused->children->length <= 1) {
- sway_log(L_DEBUG, "changing workspace layout");
- swayc_change_layout(focused, layout);
- } else if (focused->type != C_WORKSPACE && focused->parent->children->length == 1) {
- /* Case of no siblings. change parent layout */
- sway_log(L_DEBUG, "changing container layout");
- swayc_change_layout(focused->parent, layout);
- } else {
- /* regular case where new split container is build around focused container
- * or in case of workspace, container inherits its children */
- sway_log(L_DEBUG, "Adding new container around current focused container");
- sway_log(L_INFO, "FOCUSED SIZE: %.f %.f", focused->width, focused->height);
- swayc_t *parent = new_container(focused, layout);
- set_focused_container(focused);
- arrange_windows(parent, -1, -1);
- }
-
- // update container every time
- // if it is tabbed/stacked then the title must change
- // if the indicator color is different then the border must change
- update_container_border(focused);
- swayc_t *output = swayc_parent_by_type(focused, C_OUTPUT);
- // schedule render to make changes take effect right away,
- // otherwise we would have to wait for the view to render,
- // which is unpredictable.
- wlc_output_schedule_render(output->handle);
-
- return cmd_results_new(CMD_SUCCESS, NULL, NULL);
-}
-
-struct cmd_results *cmd_split(int argc, char **argv) {
- struct cmd_results *error = NULL;
- if (config->reading) return cmd_results_new(CMD_FAILURE, "split", "Can't be used in config file.");
- if (!config->active) return cmd_results_new(CMD_FAILURE, "split", "Can only be used when sway is running.");
- if ((error = checkarg(argc, "split", EXPECTED_EQUAL_TO, 1))) {
- return error;
- }
- if (strcasecmp(argv[0], "v") == 0 || strcasecmp(argv[0], "vertical") == 0) {
- _do_split(argc - 1, argv + 1, L_VERT);
- } else if (strcasecmp(argv[0], "h") == 0 || strcasecmp(argv[0], "horizontal") == 0) {
- _do_split(argc - 1, argv + 1, L_HORIZ);
- } else if (strcasecmp(argv[0], "t") == 0 || strcasecmp(argv[0], "toggle") == 0) {
- swayc_t *focused = current_container;
- if (focused->parent->layout == L_VERT) {
- _do_split(argc - 1, argv + 1, L_HORIZ);
- } else {
- _do_split(argc - 1, argv + 1, L_VERT);
- }
- } else {
- error = cmd_results_new(CMD_FAILURE, "split",
- "Invalid split command (expected either horizontal or vertical).");
- return error;
- }
- return cmd_results_new(CMD_SUCCESS, NULL, NULL);
-}
-
-struct cmd_results *cmd_splitv(int argc, char **argv) {
- return _do_split(argc, argv, L_VERT);
-}
-
-struct cmd_results *cmd_splith(int argc, char **argv) {
- return _do_split(argc, argv, L_HORIZ);
-}
-
-struct cmd_results *cmd_splitt(int argc, char **argv) {
- swayc_t *focused = current_container;
- if (focused->parent->layout == L_VERT) {
- return _do_split(argc, argv, L_HORIZ);
- } else {
- return _do_split(argc, argv, L_VERT);
- }
-}
diff --git a/sway/old/commands/sticky.c b/sway/old/commands/sticky.c
deleted file mode 100644
index 4899e061..00000000
--- a/sway/old/commands/sticky.c
+++ /dev/null
@@ -1,25 +0,0 @@
-#include <string.h>
-#include "sway/commands.h"
-#include "sway/focus.h"
-
-struct cmd_results *cmd_sticky(int argc, char **argv) {
- struct cmd_results *error = NULL;
- if (config->reading) return cmd_results_new(CMD_FAILURE, "sticky", "Can't be used in config file.");
- if (!config->active) return cmd_results_new(CMD_FAILURE, "sticky", "Can only be used when sway is running.");
- if ((error = checkarg(argc, "sticky", EXPECTED_EQUAL_TO, 1))) {
- return error;
- }
- char *action = argv[0];
- swayc_t *cont = get_focused_view(&root_container);
- if (strcmp(action, "toggle") == 0) {
- cont->sticky = !cont->sticky;
- } else if (strcmp(action, "enable") == 0) {
- cont->sticky = true;
- } else if (strcmp(action, "disable") == 0) {
- cont->sticky = false;
- } else {
- return cmd_results_new(CMD_FAILURE, "sticky",
- "Expected 'sticky enable|disable|toggle'");
- }
- return cmd_results_new(CMD_SUCCESS, NULL, NULL);
-}
diff --git a/sway/old/commands/unmark.c b/sway/old/commands/unmark.c
deleted file mode 100644
index ac213261..00000000
--- a/sway/old/commands/unmark.c
+++ /dev/null
@@ -1,31 +0,0 @@
-#include <string.h>
-#include <strings.h>
-#include "sway/commands.h"
-#include "list.h"
-#include "stringop.h"
-
-struct cmd_results *cmd_unmark(int argc, char **argv) {
- swayc_t *view = current_container;
-
- if (view->marks) {
- if (argc) {
- char *mark = join_args(argv, argc);
- int index;
- if ((index = list_seq_find(view->marks, (int (*)(const void *, const void *))strcmp, mark)) != -1) {
- free(view->marks->items[index]);
- list_del(view->marks, index);
-
- if (view->marks->length == 0) {
- list_free(view->marks);
- view->marks = NULL;
- }
- }
- free(mark);
- } else {
- list_foreach(view->marks, free);
- list_free(view->marks);
- view->marks = NULL;
- }
- }
- return cmd_results_new(CMD_SUCCESS, NULL, NULL);
-}
diff --git a/sway/old/commands/workspace.c b/sway/old/commands/workspace.c
deleted file mode 100644
index a7839746..00000000
--- a/sway/old/commands/workspace.c
+++ /dev/null
@@ -1,92 +0,0 @@
-#define _XOPEN_SOURCE 500
-#include <string.h>
-#include <strings.h>
-#include "sway/commands.h"
-#include "sway/config.h"
-#include "sway/input_state.h"
-#include "sway/workspace.h"
-#include "list.h"
-#include "log.h"
-#include "stringop.h"
-
-struct cmd_results *cmd_workspace(int argc, char **argv) {
- struct cmd_results *error = NULL;
- if ((error = checkarg(argc, "workspace", EXPECTED_AT_LEAST, 1))) {
- return error;
- }
-
- int output_location = -1;
-
- for (int i = 0; i < argc; ++i) {
- if (strcasecmp(argv[i], "output") == 0) {
- output_location = i;
- break;
- }
- }
- if (output_location >= 0) {
- if ((error = checkarg(argc, "workspace", EXPECTED_EQUAL_TO, output_location + 2))) {
- return error;
- }
- struct workspace_output *wso = calloc(1, sizeof(struct workspace_output));
- if (!wso) {
- return cmd_results_new(CMD_FAILURE, "workspace output",
- "Unable to allocate workspace output");
- }
- wso->workspace = join_args(argv, argc - 2);
- wso->output = strdup(argv[output_location + 1]);
- int i = -1;
- if ((i = list_seq_find(config->workspace_outputs, workspace_output_cmp_workspace, wso)) != -1) {
- struct workspace_output *old = config->workspace_outputs->items[i];
- free(old); // workspaces can only be assigned to a single output
- list_del(config->workspace_outputs, i);
- }
- sway_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) {
- return cmd_results_new(CMD_DEFER, "workspace", NULL);
- }
- swayc_t *ws = NULL;
- if (strcasecmp(argv[0], "number") == 0) {
- if (!(ws = workspace_by_number(argv[1]))) {
- char *name = join_args(argv + 1, argc - 1);
- ws = workspace_create(name);
- free(name);
- }
- } else if (strcasecmp(argv[0], "next") == 0) {
- ws = workspace_next();
- } else if (strcasecmp(argv[0], "prev") == 0) {
- ws = workspace_prev();
- } else if (strcasecmp(argv[0], "next_on_output") == 0) {
- ws = workspace_output_next();
- } else if (strcasecmp(argv[0], "prev_on_output") == 0) {
- ws = workspace_output_prev();
- } else if (strcasecmp(argv[0], "back_and_forth") == 0) {
- // if auto_back_and_forth is enabled, workspace_switch will swap
- // the workspaces. If we created prev_workspace here, workspace_switch
- // would put us back on original workspace.
- if (config->auto_back_and_forth) {
- ws = swayc_active_workspace();
- } else if (prev_workspace_name && !(ws = workspace_by_name(prev_workspace_name))) {
- ws = workspace_create(prev_workspace_name);
- }
- } else {
- char *name = join_args(argv, argc);
- if (!(ws = workspace_by_name(name))) {
- ws = workspace_create(name);
- }
- free(name);
- }
- swayc_t *old_output = swayc_active_output();
- workspace_switch(ws);
- swayc_t *new_output = swayc_active_output();
-
- if (config->mouse_warping && old_output != new_output) {
- swayc_t *focused = get_focused_view(ws);
- if (focused && focused->type == C_VIEW) {
- center_pointer_on(focused);
- }
- }
- }
- return cmd_results_new(CMD_SUCCESS, NULL, NULL);
-}
diff --git a/sway/old/commands/workspace_auto_back_and_forth.c b/sway/old/commands/workspace_auto_back_and_forth.c
deleted file mode 100644
index d58ae5c8..00000000
--- a/sway/old/commands/workspace_auto_back_and_forth.c
+++ /dev/null
@@ -1,18 +0,0 @@
-#include <string.h>
-#include <strings.h>
-#include "sway/commands.h"
-
-struct cmd_results *cmd_ws_auto_back_and_forth(int argc, char **argv) {
- struct cmd_results *error = NULL;
- if ((error = checkarg(argc, "workspace_auto_back_and_forth", EXPECTED_EQUAL_TO, 1))) {
- return error;
- }
- if (strcasecmp(argv[0], "yes") == 0) {
- config->auto_back_and_forth = true;
- } else if (strcasecmp(argv[0], "no") == 0) {
- config->auto_back_and_forth = false;
- } else {
- return cmd_results_new(CMD_INVALID, "workspace_auto_back_and_forth", "Expected 'workspace_auto_back_and_forth <yes|no>'");
- }
- return cmd_results_new(CMD_SUCCESS, NULL, NULL);
-}
diff --git a/sway/old/commands/workspace_layout.c b/sway/old/commands/workspace_layout.c
deleted file mode 100644
index 9ac84be2..00000000
--- a/sway/old/commands/workspace_layout.c
+++ /dev/null
@@ -1,40 +0,0 @@
-#include <string.h>
-#include <strings.h>
-#include "sway/commands.h"
-
-struct cmd_results *cmd_workspace_layout(int argc, char **argv) {
- struct cmd_results *error = NULL;
- if ((error = checkarg(argc, "workspace_layout", EXPECTED_AT_LEAST, 1))) {
- return error;
- }
-
- if (strcasecmp(argv[0], "default") == 0) {
- config->default_layout = L_NONE;
- } else if (strcasecmp(argv[0], "stacking") == 0) {
- config->default_layout = L_STACKED;
- } else if (strcasecmp(argv[0], "tabbed") == 0) {
- config->default_layout = L_TABBED;
- } else if (strcasecmp(argv[0], "auto") == 0) {
- if (argc == 1) {
- config->default_layout = L_AUTO_FIRST;
- } else {
- if ((error = checkarg(argc, "workspace_layout auto", EXPECTED_EQUAL_TO, 2))) {
- return error;
- }
- if (strcasecmp(argv[1], "left") == 0) {
- config->default_layout = L_AUTO_LEFT;
- } else if (strcasecmp(argv[1], "right") == 0) {
- config->default_layout = L_AUTO_RIGHT;
- } else if (strcasecmp(argv[1], "top") == 0) {
- config->default_layout = L_AUTO_TOP;
- } else if (strcasecmp(argv[1], "bottom") == 0) {
- config->default_layout = L_AUTO_BOTTOM;
- } else {
- return cmd_results_new(CMD_INVALID, "workspace_layout auto", "Expected 'workspace_layout auto <left|right|top|bottom>'");
- }
- }
- } else {
- return cmd_results_new(CMD_INVALID, "workspace_layout", "Expected 'workspace_layout <default|stacking|tabbed|auto|auto left|auto right|auto top|auto bottom>'");
- }
- return cmd_results_new(CMD_SUCCESS, NULL, NULL);
-}
diff --git a/sway/old/config.c b/sway/old/config.c
deleted file mode 100644
index d14653e3..00000000
--- a/sway/old/config.c
+++ /dev/null
@@ -1,1313 +0,0 @@
-#define _POSIX_C_SOURCE 200809L
-#define _XOPEN_SOURCE 700
-#include <stdio.h>
-#include <stdbool.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <libgen.h>
-#include <wordexp.h>
-#include <sys/types.h>
-#include <sys/wait.h>
-#include <sys/stat.h>
-#include <signal.h>
-#include <libinput.h>
-#include <limits.h>
-#include <float.h>
-#include <dirent.h>
-#include <strings.h>
-#include <wlr/types/wlr_output.h>
-#include "wayland-desktop-shell-server-protocol.h"
-#include "sway/commands.h"
-#include "sway/config.h"
-#include "sway/layout.h"
-#include "sway/input_state.h"
-#include "sway/criteria.h"
-#include "sway/input.h"
-#include "sway/border.h"
-#include "readline.h"
-#include "stringop.h"
-#include "list.h"
-#include "log.h"
-
-struct sway_config *config = NULL;
-
-static void terminate_swaybar(pid_t pid);
-
-static void free_variable(struct sway_variable *var) {
- if (!var) {
- return;
- }
- free(var->name);
- free(var->value);
- free(var);
-}
-
-static void free_binding(struct sway_binding *bind) {
- if (!bind) {
- return;
- }
- free_flat_list(bind->keys);
- free(bind->command);
- free(bind);
-}
-
-static void free_mode(struct sway_mode *mode) {
- if (!mode) {
- return;
- }
- free(mode->name);
- int i;
- for (i = 0; mode->bindings && i < mode->bindings->length; ++i) {
- free_binding(mode->bindings->items[i]);
- }
- list_free(mode->bindings);
- free(mode);
-}
-
-static void free_bar(struct bar_config *bar) {
- if (!bar) {
- return;
- }
- free(bar->mode);
- free(bar->hidden_state);
-#ifdef ENABLE_TRAY
- free(bar->tray_output);
- free(bar->icon_theme);
-#endif
- free(bar->status_command);
- free(bar->font);
- free(bar->separator_symbol);
- int i;
- for (i = 0; bar->bindings && i < bar->bindings->length; ++i) {
- free_sway_mouse_binding(bar->bindings->items[i]);
- }
- list_free(bar->bindings);
-
- if (bar->outputs) {
- free_flat_list(bar->outputs);
- }
-
- if (bar->pid != 0) {
- terminate_swaybar(bar->pid);
- }
-
- free(bar->colors.background);
- free(bar->colors.statusline);
- free(bar->colors.separator);
- free(bar->colors.focused_background);
- free(bar->colors.focused_statusline);
- free(bar->colors.focused_separator);
- free(bar->colors.focused_workspace_border);
- free(bar->colors.focused_workspace_bg);
- free(bar->colors.focused_workspace_text);
- free(bar->colors.active_workspace_border);
- free(bar->colors.active_workspace_bg);
- free(bar->colors.active_workspace_text);
- free(bar->colors.inactive_workspace_border);
- free(bar->colors.inactive_workspace_bg);
- free(bar->colors.inactive_workspace_text);
- free(bar->colors.urgent_workspace_border);
- free(bar->colors.urgent_workspace_bg);
- free(bar->colors.urgent_workspace_text);
- free(bar->colors.binding_mode_border);
- free(bar->colors.binding_mode_bg);
- free(bar->colors.binding_mode_text);
-
- free(bar);
-}
-
-void free_input_config(struct input_config *ic) {
- if (!ic) {
- return;
- }
- free(ic->identifier);
- free(ic);
-}
-
-void free_output_config(struct output_config *oc) {
- if (!oc) {
- return;
- }
- free(oc->name);
- free(oc->background);
- free(oc->background_option);
- free(oc);
-}
-
-static void free_workspace_output(struct workspace_output *wo) {
- if (!wo) {
- return;
- }
- free(wo->output);
- free(wo->workspace);
- free(wo);
-}
-
-static void pid_workspace_cleanup() {
- struct timespec ts;
- struct pid_workspace *pw = NULL;
-
- clock_gettime(CLOCK_MONOTONIC, &ts);
-
- // work backwards through list and remove any entries
- // older than PID_WORKSPACE_TIMEOUT
- for (int i = config->pid_workspaces->length - 1; i > -1; i--) {
- pw = config->pid_workspaces->items[i];
-
- if (difftime(ts.tv_sec, *pw->time_added) >= PID_WORKSPACE_TIMEOUT) {
- free_pid_workspace(config->pid_workspaces->items[i]);
- list_del(config->pid_workspaces, i);
- }
- }
-}
-
-// de-dupe pid_workspaces to ensure pid uniqueness
-void pid_workspace_add(struct pid_workspace *pw) {
- struct pid_workspace *list_pw = NULL;
- struct timespec ts;
- time_t *now = malloc(sizeof(time_t));
- if (!now) {
- sway_log(L_ERROR, "Allocating time for pid_workspace failed");
- return;
- }
-
- pid_workspace_cleanup();
-
- // add current time to pw
- clock_gettime(CLOCK_MONOTONIC, &ts);
- *now = ts.tv_sec;
-
- pw->time_added = now;
-
- // work backwards through list and delete any entries that
- // have the same pid as that in our new pid_workspace
- for (int i = config->pid_workspaces->length - 1; i > -1; i--) {
- list_pw = config->pid_workspaces->items[i];
-
- if (pw->pid == list_pw->pid) {
- free_pid_workspace(config->pid_workspaces->items[i]);
- list_del(config->pid_workspaces, i);
- }
- }
-
- list_add(config->pid_workspaces, pw);
-}
-
-void free_pid_workspace(struct pid_workspace *pw) {
- if (!pw) {
- return;
- }
- free(pw->pid);
- free(pw->workspace);
- free(pw->time_added);
- free(pw);
-}
-
-void free_command_policy(struct command_policy *policy) {
- if (!policy) {
- return;
- }
- free(policy->command);
- free(policy);
-}
-
-void free_feature_policy(struct feature_policy *policy) {
- if (!policy) {
- return;
- }
- free(policy->program);
- free(policy);
-}
-
-void free_config(struct sway_config *config) {
- if (!config) {
- return;
- }
- int i;
- for (i = 0; config->symbols && i < config->symbols->length; ++i) {
- free_variable(config->symbols->items[i]);
- }
- list_free(config->symbols);
-
- for (i = 0; config->modes && i < config->modes->length; ++i) {
- free_mode(config->modes->items[i]);
- }
- list_free(config->modes);
-
- for (i = 0; config->bars && i < config->bars->length; ++i) {
- free_bar(config->bars->items[i]);
- }
- list_free(config->bars);
-
- free_flat_list(config->cmd_queue);
-
- for (i = 0; config->workspace_outputs && i < config->workspace_outputs->length; ++i) {
- free_workspace_output(config->workspace_outputs->items[i]);
- }
- list_free(config->workspace_outputs);
-
- for (i = 0; config->pid_workspaces && i < config->pid_workspaces->length; ++i) {
- free_pid_workspace(config->pid_workspaces->items[i]);
- }
- list_free(config->pid_workspaces);
-
- for (i = 0; config->criteria && i < config->criteria->length; ++i) {
- free_criteria(config->criteria->items[i]);
- }
- list_free(config->criteria);
-
- for (i = 0; config->no_focus && i < config->no_focus->length; ++i) {
- free_criteria(config->no_focus->items[i]);
- }
- list_free(config->no_focus);
-
- for (i = 0; config->input_configs && i < config->input_configs->length; ++i) {
- free_input_config(config->input_configs->items[i]);
- }
- list_free(config->input_configs);
-
- for (i = 0; config->output_configs && i < config->output_configs->length; ++i) {
- free_output_config(config->output_configs->items[i]);
- }
- list_free(config->output_configs);
-
- for (i = 0; config->command_policies && i < config->command_policies->length; ++i) {
- free_command_policy(config->command_policies->items[i]);
- }
- list_free(config->command_policies);
-
- for (i = 0; config->feature_policies && i < config->feature_policies->length; ++i) {
- free_feature_policy(config->feature_policies->items[i]);
- }
- list_free(config->feature_policies);
-
- list_free(config->active_bar_modifiers);
- free_flat_list(config->config_chain);
- free(config->font);
- free(config->floating_scroll_up_cmd);
- free(config->floating_scroll_down_cmd);
- free(config->floating_scroll_left_cmd);
- free(config->floating_scroll_right_cmd);
- free(config);
-}
-
-
-static bool file_exists(const char *path) {
- return path && access(path, R_OK) != -1;
-}
-
-static void config_defaults(struct sway_config *config) {
- if (!(config->symbols = create_list())) goto cleanup;
- if (!(config->modes = create_list())) goto cleanup;
- if (!(config->bars = create_list())) goto cleanup;
- if (!(config->workspace_outputs = create_list())) goto cleanup;
- if (!(config->pid_workspaces = create_list())) goto cleanup;
- if (!(config->criteria = create_list())) goto cleanup;
- if (!(config->no_focus = create_list())) goto cleanup;
- if (!(config->input_configs = create_list())) goto cleanup;
- if (!(config->output_configs = create_list())) goto cleanup;
-
- if (!(config->cmd_queue = create_list())) goto cleanup;
-
- if (!(config->current_mode = malloc(sizeof(struct sway_mode)))) goto cleanup;
- if (!(config->current_mode->name = malloc(sizeof("default")))) goto cleanup;
- strcpy(config->current_mode->name, "default");
- if (!(config->current_mode->bindings = create_list())) goto cleanup;
- list_add(config->modes, config->current_mode);
-
- config->floating_mod = 0;
- config->dragging_key = M_LEFT_CLICK;
- config->resizing_key = M_RIGHT_CLICK;
- if (!(config->floating_scroll_up_cmd = strdup(""))) goto cleanup;
- if (!(config->floating_scroll_down_cmd = strdup(""))) goto cleanup;
- if (!(config->floating_scroll_left_cmd = strdup(""))) goto cleanup;
- if (!(config->floating_scroll_right_cmd = strdup(""))) goto cleanup;
- config->default_layout = L_NONE;
- config->default_orientation = L_NONE;
- if (!(config->font = strdup("monospace 10"))) goto cleanup;
- config->font_height = get_font_text_height(config->font);
-
- // floating view
- config->floating_maximum_width = 0;
- config->floating_maximum_height = 0;
- config->floating_minimum_width = 75;
- config->floating_minimum_height = 50;
-
- // Flags
- config->focus_follows_mouse = true;
- config->mouse_warping = true;
- config->reloading = false;
- config->active = false;
- config->failed = false;
- config->auto_back_and_forth = false;
- config->seamless_mouse = true;
- config->reading = false;
- config->show_marks = true;
-
- config->edge_gaps = true;
- config->smart_gaps = false;
- config->gaps_inner = 0;
- config->gaps_outer = 0;
-
- if (!(config->active_bar_modifiers = create_list())) goto cleanup;
-
- if (!(config->config_chain = create_list())) goto cleanup;
- config->current_config = NULL;
-
- // borders
- config->border = B_NORMAL;
- config->floating_border = B_NORMAL;
- config->border_thickness = 2;
- config->floating_border_thickness = 2;
- config->hide_edge_borders = E_NONE;
-
- // border colors
- config->border_colors.focused.border = 0x4C7899FF;
- config->border_colors.focused.background = 0x285577FF;
- config->border_colors.focused.text = 0xFFFFFFFF;
- config->border_colors.focused.indicator = 0x2E9EF4FF;
- config->border_colors.focused.child_border = 0x285577FF;
-
- config->border_colors.focused_inactive.border = 0x333333FF;
- config->border_colors.focused_inactive.background = 0x5F676AFF;
- config->border_colors.focused_inactive.text = 0xFFFFFFFF;
- config->border_colors.focused_inactive.indicator = 0x484E50FF;
- config->border_colors.focused_inactive.child_border = 0x5F676AFF;
-
- config->border_colors.unfocused.border = 0x333333FF;
- config->border_colors.unfocused.background = 0x222222FF;
- config->border_colors.unfocused.text = 0x888888FF;
- config->border_colors.unfocused.indicator = 0x292D2EFF;
- config->border_colors.unfocused.child_border = 0x222222FF;
-
- config->border_colors.urgent.border = 0x2F343AFF;
- config->border_colors.urgent.background = 0x900000FF;
- config->border_colors.urgent.text = 0xFFFFFFFF;
- config->border_colors.urgent.indicator = 0x900000FF;
- config->border_colors.urgent.child_border = 0x900000FF;
-
- config->border_colors.placeholder.border = 0x000000FF;
- config->border_colors.placeholder.background = 0x0C0C0CFF;
- config->border_colors.placeholder.text = 0xFFFFFFFF;
- config->border_colors.placeholder.indicator = 0x000000FF;
- config->border_colors.placeholder.child_border = 0x0C0C0CFF;
-
- config->border_colors.background = 0xFFFFFFFF;
-
- // Security
- if (!(config->command_policies = create_list())) goto cleanup;
- if (!(config->feature_policies = create_list())) goto cleanup;
- if (!(config->ipc_policies = create_list())) goto cleanup;
-
- return;
-cleanup:
- sway_abort("Unable to allocate config structures");
-}
-
-static int compare_modifiers(const void *left, const void *right) {
- uint32_t a = *(uint32_t *)left;
- uint32_t b = *(uint32_t *)right;
-
- return a - b;
-}
-
-void update_active_bar_modifiers() {
- if (config->active_bar_modifiers->length > 0) {
- list_free(config->active_bar_modifiers);
- config->active_bar_modifiers = create_list();
- }
-
- struct bar_config *bar;
- int i;
- for (i = 0; i < config->bars->length; ++i) {
- bar = config->bars->items[i];
- if (strcmp(bar->mode, "hide") == 0 && strcmp(bar->hidden_state, "hide") == 0) {
- if (list_seq_find(config->active_bar_modifiers, compare_modifiers, &bar->modifier) < 0) {
- list_add(config->active_bar_modifiers, &bar->modifier);
- }
- }
- }
-}
-
-static char *get_config_path(void) {
- static const char *config_paths[] = {
- "$HOME/.sway/config",
- "$XDG_CONFIG_HOME/sway/config",
- "$HOME/.i3/config",
- "$XDG_CONFIG_HOME/i3/config",
- SYSCONFDIR "/sway/config",
- SYSCONFDIR "/i3/config",
- };
-
- if (!getenv("XDG_CONFIG_HOME")) {
- char *home = getenv("HOME");
- char *config_home = malloc(strlen(home) + strlen("/.config") + 1);
- if (!config_home) {
- sway_log(L_ERROR, "Unable to allocate $HOME/.config");
- } else {
- strcpy(config_home, home);
- strcat(config_home, "/.config");
- setenv("XDG_CONFIG_HOME", config_home, 1);
- sway_log(L_DEBUG, "Set XDG_CONFIG_HOME to %s", config_home);
- free(config_home);
- }
- }
-
- wordexp_t p;
- char *path;
-
- int i;
- for (i = 0; i < (int)(sizeof(config_paths) / sizeof(char *)); ++i) {
- if (wordexp(config_paths[i], &p, 0) == 0) {
- path = strdup(p.we_wordv[0]);
- wordfree(&p);
- if (file_exists(path)) {
- return path;
- }
- }
- }
-
- return NULL; // Not reached
-}
-
-const char *current_config_path;
-
-static bool load_config(const char *path, struct sway_config *config) {
- sway_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) {
- sway_log(L_ERROR, "Unable to find a config file!");
- return false;
- }
-
- FILE *f = fopen(path, "r");
- if (!f) {
- sway_log(L_ERROR, "Unable to open %s for reading", path);
- return false;
- }
-
- bool config_load_success = read_config(f, config);
- fclose(f);
-
- if (!config_load_success) {
- sway_log(L_ERROR, "Error(s) loading config!");
- }
-
- current_config_path = NULL;
- return true;
-}
-
-static int qstrcmp(const void* a, const void* b) {
- return strcmp(*((char**) a), *((char**) b));
-}
-
-bool load_main_config(const char *file, bool is_active) {
- input_init();
-
- char *path;
- if (file != NULL) {
- path = strdup(file);
- } else {
- path = get_config_path();
- }
-
- struct sway_config *old_config = config;
- config = calloc(1, sizeof(struct sway_config));
- if (!config) {
- sway_abort("Unable to allocate config");
- }
-
- config_defaults(config);
- if (is_active) {
- sway_log(L_DEBUG, "Performing configuration file reload");
- config->reloading = true;
- config->active = true;
- }
-
- config->current_config = path;
- list_add(config->config_chain, path);
-
- config->reading = true;
-
- // Read security configs
- bool success = true;
- DIR *dir = opendir(SYSCONFDIR "/sway/security.d");
- if (!dir) {
- sway_log(L_ERROR, "%s does not exist, sway will have no security configuration"
- " and will probably be broken", SYSCONFDIR "/sway/security.d");
- } else {
- list_t *secconfigs = create_list();
- char *base = SYSCONFDIR "/sway/security.d/";
- struct dirent *ent = readdir(dir);
- struct stat s;
- while (ent != NULL) {
- char *_path = malloc(strlen(ent->d_name) + strlen(base) + 1);
- strcpy(_path, base);
- strcat(_path, ent->d_name);
- lstat(_path, &s);
- if (S_ISREG(s.st_mode) && ent->d_name[0] != '.') {
- list_add(secconfigs, _path);
- }
- else {
- free(_path);
- }
- ent = readdir(dir);
- }
- closedir(dir);
-
- list_qsort(secconfigs, qstrcmp);
- for (int i = 0; i < secconfigs->length; ++i) {
- char *_path = secconfigs->items[i];
- if (stat(_path, &s) || s.st_uid != 0 || s.st_gid != 0 || (((s.st_mode & 0777) != 0644) && (s.st_mode & 0777) != 0444)) {
- sway_log(L_ERROR, "Refusing to load %s - it must be owned by root and mode 644 or 444", _path);
- success = false;
- } else {
- success = success && load_config(_path, config);
- }
- }
-
- free_flat_list(secconfigs);
- }
-
- success = success && load_config(path, config);
-
- if (is_active) {
- config->reloading = false;
- }
-
- if (old_config) {
- free_config(old_config);
- }
- config->reading = false;
-
- if (success) {
- update_active_bar_modifiers();
- }
-
- return success;
-}
-
-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;
-
- 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) {
- sway_log(L_ERROR, "Unable to allocate full path to included config");
- return false;
- }
- snprintf(full_path, len, "%s/%s", parent_dir, path);
- }
-
- char *real_path = realpath(full_path, NULL);
- free(full_path);
-
- if (real_path == NULL) {
- sway_log(L_DEBUG, "%s not found.", path);
- return false;
- }
-
- // check if config has already been included
- int j;
- for (j = 0; j < config->config_chain->length; ++j) {
- char *old_path = config->config_chain->items[j];
- if (strcmp(real_path, old_path) == 0) {
- sway_log(L_DEBUG, "%s already included once, won't be included again.", real_path);
- free(real_path);
- return false;
- }
- }
-
- 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 = parent_config;
- list_del(config->config_chain, index);
- return false;
- }
-
- // 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);
- const char *parent_dir = dirname(parent_path);
-
- if (chdir(parent_dir) < 0) {
- free(parent_path);
- free(wd);
- return false;
- }
-
- wordexp_t p;
-
- if (wordexp(path, &p, 0) < 0) {
- free(parent_path);
- free(wd);
- return false;
- }
-
- char **w = p.we_wordv;
- size_t i;
- for (i = 0; i < p.we_wordc; ++i) {
- load_include_config(w[i], parent_dir, config);
- }
- free(parent_path);
- wordfree(&p);
-
- // restore wd
- if (chdir(wd) < 0) {
- free(wd);
- sway_log(L_ERROR, "failed to restore working directory");
- return false;
- }
-
- free(wd);
- return true;
-}
-
-struct cmd_results *check_security_config() {
- if (!current_config_path || strncmp(SYSCONFDIR "/sway/security.d/", current_config_path,
- strlen(SYSCONFDIR "/sway/security.d/")) != 0) {
- return cmd_results_new(CMD_INVALID, "permit",
- "This command is only permitted to run from " SYSCONFDIR "/sway/security.d/*");
- }
- return NULL;
-}
-
-bool read_config(FILE *file, struct sway_config *config) {
- bool success = true;
- enum cmd_status block = CMD_BLOCK_END;
-
- int line_number = 0;
- char *line;
- while (!feof(file)) {
- line = read_line(file);
- if (!line) {
- continue;
- }
- line_number++;
- line = strip_whitespace(line);
- if (line[0] == '#') {
- free(line);
- continue;
- }
- struct cmd_results *res;
- if (block == CMD_BLOCK_COMMANDS) {
- // Special case
- res = config_commands_command(line);
- } else {
- res = config_command(line, block);
- }
- switch(res->status) {
- case CMD_FAILURE:
- case CMD_INVALID:
- sway_log(L_ERROR, "Error on line %i '%s': %s (%s)", line_number, line,
- res->error, config->current_config);
- success = false;
- break;
-
- case CMD_DEFER:
- sway_log(L_DEBUG, "Defferring command `%s'", line);
- list_add(config->cmd_queue, strdup(line));
- break;
-
- case CMD_BLOCK_MODE:
- if (block == CMD_BLOCK_END) {
- block = CMD_BLOCK_MODE;
- } else {
- sway_log(L_ERROR, "Invalid block '%s'", line);
- }
- break;
-
- case CMD_BLOCK_INPUT:
- if (block == CMD_BLOCK_END) {
- block = CMD_BLOCK_INPUT;
- } else {
- sway_log(L_ERROR, "Invalid block '%s'", line);
- }
- break;
-
- case CMD_BLOCK_BAR:
- if (block == CMD_BLOCK_END) {
- block = CMD_BLOCK_BAR;
- } else {
- sway_log(L_ERROR, "Invalid block '%s'", line);
- }
- break;
-
- case CMD_BLOCK_BAR_COLORS:
- if (block == CMD_BLOCK_BAR) {
- block = CMD_BLOCK_BAR_COLORS;
- } else {
- sway_log(L_ERROR, "Invalid block '%s'", line);
- }
- break;
-
- case CMD_BLOCK_COMMANDS:
- if (block == CMD_BLOCK_END) {
- block = CMD_BLOCK_COMMANDS;
- } else {
- sway_log(L_ERROR, "Invalid block '%s'", line);
- }
- break;
-
- case CMD_BLOCK_IPC:
- if (block == CMD_BLOCK_END) {
- block = CMD_BLOCK_IPC;
- } else {
- sway_log(L_ERROR, "Invalid block '%s'", line);
- }
- break;
-
- case CMD_BLOCK_IPC_EVENTS:
- if (block == CMD_BLOCK_IPC) {
- block = CMD_BLOCK_IPC_EVENTS;
- } else {
- sway_log(L_ERROR, "Invalid block '%s'", line);
- }
- break;
-
- case CMD_BLOCK_END:
- switch(block) {
- case CMD_BLOCK_MODE:
- sway_log(L_DEBUG, "End of mode block");
- config->current_mode = config->modes->items[0];
- block = CMD_BLOCK_END;
- break;
-
- case CMD_BLOCK_INPUT:
- sway_log(L_DEBUG, "End of input block");
- current_input_config = NULL;
- block = CMD_BLOCK_END;
- break;
-
- case CMD_BLOCK_BAR:
- sway_log(L_DEBUG, "End of bar block");
- config->current_bar = NULL;
- block = CMD_BLOCK_END;
- break;
-
- case CMD_BLOCK_BAR_COLORS:
- sway_log(L_DEBUG, "End of bar colors block");
- block = CMD_BLOCK_BAR;
- break;
-
- case CMD_BLOCK_COMMANDS:
- sway_log(L_DEBUG, "End of commands block");
- block = CMD_BLOCK_END;
- break;
-
- case CMD_BLOCK_IPC:
- sway_log(L_DEBUG, "End of IPC block");
- block = CMD_BLOCK_END;
- break;
-
- case CMD_BLOCK_IPC_EVENTS:
- sway_log(L_DEBUG, "End of IPC events block");
- block = CMD_BLOCK_IPC;
- break;
-
- case CMD_BLOCK_END:
- sway_log(L_ERROR, "Unmatched }");
- break;
-
- default:;
- }
- default:;
- }
- free(line);
- free_cmd_results(res);
- }
-
- return success;
-}
-
-int input_identifier_cmp(const void *item, const void *data) {
- const struct input_config *ic = item;
- const char *identifier = data;
- return strcmp(ic->identifier, identifier);
-}
-
-int output_name_cmp(const void *item, const void *data) {
- const struct output_config *output = item;
- const char *name = data;
-
- return strcmp(output->name, name);
-}
-
-void merge_input_config(struct input_config *dst, struct input_config *src) {
- if (src->identifier) {
- if (dst->identifier) {
- free(dst->identifier);
- }
- dst->identifier = strdup(src->identifier);
- }
- if (src->accel_profile != INT_MIN) {
- dst->accel_profile = src->accel_profile;
- }
- if (src->click_method != INT_MIN) {
- dst->click_method = src->click_method;
- }
- if (src->drag_lock != INT_MIN) {
- dst->drag_lock = src->drag_lock;
- }
- if (src->dwt != INT_MIN) {
- dst->dwt = src->dwt;
- }
- if (src->middle_emulation != INT_MIN) {
- dst->middle_emulation = src->middle_emulation;
- }
- if (src->natural_scroll != INT_MIN) {
- dst->natural_scroll = src->natural_scroll;
- }
- if (src->pointer_accel != FLT_MIN) {
- dst->pointer_accel = src->pointer_accel;
- }
- if (src->scroll_method != INT_MIN) {
- dst->scroll_method = src->scroll_method;
- }
- if (src->send_events != INT_MIN) {
- dst->send_events = src->send_events;
- }
- if (src->tap != INT_MIN) {
- dst->tap = src->tap;
- }
-}
-
-void merge_output_config(struct output_config *dst, struct output_config *src) {
- if (src->name) {
- if (dst->name) {
- free(dst->name);
- }
- dst->name = strdup(src->name);
- }
- if (src->enabled != -1) {
- dst->enabled = src->enabled;
- }
- if (src->width != -1) {
- dst->width = src->width;
- }
- if (src->height != -1) {
- dst->height = src->height;
- }
- if (src->x != -1) {
- dst->x = src->x;
- }
- if (src->y != -1) {
- dst->y = src->y;
- }
- if (src->scale != -1) {
- dst->scale = src->scale;
- }
- if (src->background) {
- if (dst->background) {
- free(dst->background);
- }
- dst->background = strdup(src->background);
- }
- if (src->background_option) {
- if (dst->background_option) {
- free(dst->background_option);
- }
- dst->background_option = strdup(src->background_option);
- }
-}
-
-static void invoke_swaybar(struct bar_config *bar) {
- return; // TODO WLR
- sway_log(L_DEBUG, "Invoking swaybar for bar id '%s'", bar->id);
- // Pipe to communicate errors
- int filedes[2];
- if (pipe(filedes) == -1) {
- sway_log(L_ERROR, "Pipe setup failed! Cannot fork into bar");
- return;
- }
-
- bar->pid = fork();
- if (bar->pid == 0) {
- close(filedes[0]);
- if (!bar->swaybar_command) {
- char *const cmd[] = {
- "swaybar",
- "-b",
- bar->id,
- NULL,
- };
-
- close(filedes[1]);
- execvp(cmd[0], cmd);
- _exit(EXIT_SUCCESS);
- } else {
- // run custom swaybar
- int len = strlen(bar->swaybar_command) + strlen(bar->id) + 5;
- char *command = malloc(len * sizeof(char));
- if (!command) {
- const char msg[] = "Unable to allocate swaybar command string";
- int len = sizeof(msg);
- if (write(filedes[1], &len, sizeof(int))) {};
- if (write(filedes[1], msg, len)) {};
- close(filedes[1]);
- _exit(EXIT_FAILURE);
- }
- snprintf(command, len, "%s -b %s", bar->swaybar_command, bar->id);
-
- char *const cmd[] = {
- "sh",
- "-c",
- command,
- NULL,
- };
-
- close(filedes[1]);
- execvp(cmd[0], cmd);
- free(command);
- _exit(EXIT_SUCCESS);
- }
- }
- close(filedes[0]);
- int len;
- if(read(filedes[1], &len, sizeof(int)) == sizeof(int)) {
- char *buf = malloc(len);
- if(!buf) {
- sway_log(L_ERROR, "Cannot allocate error string");
- return;
- }
- if(read(filedes[1], buf, len)) {
- sway_log(L_ERROR, "%s", buf);
- }
- free(buf);
- }
- close(filedes[1]);
-}
-
-static void terminate_swaybar(pid_t pid) {
- return; // TODO WLR
- int ret = kill(pid, SIGTERM);
- if (ret != 0) {
- sway_log(L_ERROR, "Unable to terminate swaybar [pid: %d]", pid);
- } else {
- int status;
- waitpid(pid, &status, 0);
- }
-}
-
-void terminate_swaybg(pid_t pid) {
- int ret = kill(pid, SIGTERM);
- if (ret != 0) {
- sway_log(L_ERROR, "Unable to terminate swaybg [pid: %d]", pid);
- } else {
- int status;
- waitpid(pid, &status, 0);
- }
-}
-
-static bool active_output(const char *name) {
- int i;
- swayc_t *cont = NULL;
- for (i = 0; i < root_container.children->length; ++i) {
- cont = root_container.children->items[i];
- if (cont->type == C_OUTPUT && strcasecmp(name, cont->name) == 0) {
- return true;
- }
- }
-
- return false;
-}
-
-void load_swaybars() {
- // Check for bars
- list_t *bars = create_list();
- struct bar_config *bar = NULL;
- int i;
- for (i = 0; i < config->bars->length; ++i) {
- bar = config->bars->items[i];
- bool apply = false;
- if (bar->outputs) {
- int j;
- for (j = 0; j < bar->outputs->length; ++j) {
- char *o = bar->outputs->items[j];
- if (!strcmp(o, "*") || active_output(o)) {
- apply = true;
- break;
- }
- }
- } else {
- apply = true;
- }
- if (apply) {
- list_add(bars, bar);
- }
- }
-
- for (i = 0; i < bars->length; ++i) {
- bar = bars->items[i];
- if (bar->pid != 0) {
- terminate_swaybar(bar->pid);
- }
- invoke_swaybar(bar);
- }
-
- list_free(bars);
-}
-
-char *do_var_replacement(char *str) {
- int i;
- char *find = str;
- while ((find = strchr(find, '$'))) {
- // Skip if escaped.
- if (find > str && find[-1] == '\\') {
- if (find == str + 1 || !(find > str + 1 && find[-2] == '\\')) {
- ++find;
- continue;
- }
- }
- // Find matching variable
- for (i = 0; i < config->symbols->length; ++i) {
- struct sway_variable *var = config->symbols->items[i];
- int vnlen = strlen(var->name);
- if (strncmp(find, var->name, vnlen) == 0) {
- int vvlen = strlen(var->value);
- char *newstr = malloc(strlen(str) - vnlen + vvlen + 1);
- if (!newstr) {
- sway_log(L_ERROR,
- "Unable to allocate replacement during variable expansion");
- break;
- }
- char *newptr = newstr;
- int offset = find - str;
- strncpy(newptr, str, offset);
- newptr += offset;
- strncpy(newptr, var->value, vvlen);
- newptr += vvlen;
- strcpy(newptr, find + vnlen);
- free(str);
- str = newstr;
- find = str + offset + vvlen;
- break;
- }
- }
- if (i == config->symbols->length) {
- ++find;
- }
- }
- return str;
-}
-
-// the naming is intentional (albeit long): a workspace_output_cmp function
-// would compare two structs in full, while this method only compares the
-// workspace.
-int workspace_output_cmp_workspace(const void *a, const void *b) {
- const struct workspace_output *wsa = a, *wsb = b;
- return lenient_strcmp(wsa->workspace, wsb->workspace);
-}
-
-int sway_binding_cmp_keys(const void *a, const void *b) {
- const struct sway_binding *binda = a, *bindb = b;
-
- // Count keys pressed for this binding. important so we check long before
- // short ones. for example mod+a+b before mod+a
- unsigned int moda = 0, modb = 0, i;
-
- // Count how any modifiers are pressed
- for (i = 0; i < 8 * sizeof(binda->modifiers); ++i) {
- moda += (binda->modifiers & 1 << i) != 0;
- modb += (bindb->modifiers & 1 << i) != 0;
- }
- if (bindb->keys->length + modb != binda->keys->length + moda) {
- return (bindb->keys->length + modb) - (binda->keys->length + moda);
- }
-
- // Otherwise compare keys
- if (binda->modifiers > bindb->modifiers) {
- return 1;
- } else if (binda->modifiers < bindb->modifiers) {
- return -1;
- }
- struct wlc_modifiers no_mods = { 0, 0 };
- for (int i = 0; i < binda->keys->length; i++) {
- xkb_keysym_t ka = *(xkb_keysym_t *)binda->keys->items[i],
- kb = *(xkb_keysym_t *)bindb->keys->items[i];
- if (binda->bindcode) {
- uint32_t *keycode = binda->keys->items[i];
- ka = wlc_keyboard_get_keysym_for_key(*keycode, &no_mods);
- }
-
- if (bindb->bindcode) {
- uint32_t *keycode = bindb->keys->items[i];
- kb = wlc_keyboard_get_keysym_for_key(*keycode, &no_mods);
- }
-
- if (ka > kb) {
- return 1;
- } else if (ka < kb) {
- return -1;
- }
- }
-
- return 0;
-}
-
-int sway_binding_cmp(const void *a, const void *b) {
- int cmp = 0;
- if ((cmp = sway_binding_cmp_keys(a, b)) != 0) {
- return cmp;
- }
- const struct sway_binding *binda = a, *bindb = b;
- return lenient_strcmp(binda->command, bindb->command);
-}
-
-int sway_binding_cmp_qsort(const void *a, const void *b) {
- return sway_binding_cmp(*(void **)a, *(void **)b);
-}
-
-void free_sway_binding(struct sway_binding *binding) {
- if (binding->keys) {
- for (int i = 0; i < binding->keys->length; i++) {
- free(binding->keys->items[i]);
- }
- list_free(binding->keys);
- }
- if (binding->command) {
- free(binding->command);
- }
- free(binding);
-}
-
-int sway_mouse_binding_cmp_buttons(const void *a, const void *b) {
- const struct sway_mouse_binding *binda = a, *bindb = b;
- if (binda->button > bindb->button) {
- return 1;
- }
- if (binda->button < bindb->button) {
- return -1;
- }
- return 0;
-}
-
-int sway_mouse_binding_cmp(const void *a, const void *b) {
- int cmp = 0;
- if ((cmp = sway_binding_cmp_keys(a, b)) != 0) {
- return cmp;
- }
- const struct sway_mouse_binding *binda = a, *bindb = b;
- return lenient_strcmp(binda->command, bindb->command);
-}
-
-int sway_mouse_binding_cmp_qsort(const void *a, const void *b) {
- return sway_mouse_binding_cmp(*(void **)a, *(void **)b);
-}
-
-void free_sway_mouse_binding(struct sway_mouse_binding *binding) {
- if (binding->command) {
- free(binding->command);
- }
- free(binding);
-}
-
-struct sway_binding *sway_binding_dup(struct sway_binding *sb) {
- struct sway_binding *new_sb = malloc(sizeof(struct sway_binding));
- if (!new_sb) {
- return NULL;
- }
-
- new_sb->order = sb->order;
- new_sb->modifiers = sb->modifiers;
- new_sb->command = strdup(sb->command);
-
- new_sb->keys = create_list();
- int i;
- for (i = 0; i < sb->keys->length; ++i) {
- xkb_keysym_t *key = malloc(sizeof(xkb_keysym_t));
- if (!key) {
- free_sway_binding(new_sb);
- return NULL;
- }
- *key = *(xkb_keysym_t *)sb->keys->items[i];
- list_add(new_sb->keys, key);
- }
-
- return new_sb;
-}
-
-struct bar_config *default_bar_config(void) {
- struct bar_config *bar = NULL;
- 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->modifier = WLC_BIT_MOD_LOGO;
- bar->outputs = NULL;
- bar->position = DESKTOP_SHELL_PANEL_POSITION_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;
- bar->height = -1;
- bar->workspace_buttons = true;
- bar->wrap_scroll = false;
- bar->separator_symbol = NULL;
- bar->strip_workspace_numbers = false;
- bar->binding_mode_indicator = true;
-#ifdef ENABLE_TRAY
- bar->tray_output = NULL;
- bar->icon_theme = NULL;
- bar->tray_padding = 2;
- bar->activate_button = 0x110; /* BTN_LEFT */
- bar->context_button = 0x111; /* BTN_RIGHT */
- bar->secondary_button = 0x112; /* BTN_MIDDLE */
-#endif
- bar->verbose = false;
- bar->pid = 0;
- // set default colors
- if (!(bar->colors.background = strndup("#000000ff", 9))) goto cleanup;
- if (!(bar->colors.statusline = strndup("#ffffffff", 9))) goto cleanup;
- if (!(bar->colors.separator = strndup("#666666ff", 9))) goto cleanup;
- if (!(bar->colors.focused_workspace_border = strndup("#4c7899ff", 9))) goto cleanup;
- if (!(bar->colors.focused_workspace_bg = strndup("#285577ff", 9))) goto cleanup;
- if (!(bar->colors.focused_workspace_text = strndup("#ffffffff", 9))) goto cleanup;
- if (!(bar->colors.active_workspace_border = strndup("#333333ff", 9))) goto cleanup;
- if (!(bar->colors.active_workspace_bg = strndup("#5f676aff", 9))) goto cleanup;
- if (!(bar->colors.active_workspace_text = strndup("#ffffffff", 9))) goto cleanup;
- if (!(bar->colors.inactive_workspace_border = strndup("#333333ff", 9))) goto cleanup;
- if (!(bar->colors.inactive_workspace_bg = strndup("#222222ff", 9))) goto cleanup;
- if (!(bar->colors.inactive_workspace_text = strndup("#888888ff", 9))) goto cleanup;
- if (!(bar->colors.urgent_workspace_border = strndup("#2f343aff", 9))) goto cleanup;
- if (!(bar->colors.urgent_workspace_bg = strndup("#900000ff", 9))) goto cleanup;
- if (!(bar->colors.urgent_workspace_text = strndup("#ffffffff", 9))) goto cleanup;
- // if the following colors stay undefined, they fall back to background,
- // statusline, separator and urgent_workspace_*.
- bar->colors.focused_background = NULL;
- bar->colors.focused_statusline = NULL;
- bar->colors.focused_separator = NULL;
- bar->colors.binding_mode_border = NULL;
- bar->colors.binding_mode_bg = NULL;
- bar->colors.binding_mode_text = NULL;
-
- list_add(config->bars, bar);
-
- return bar;
-
-cleanup:
- free_bar(bar);
- return NULL;
-}
diff --git a/sway/old/container.c b/sway/old/container.c
deleted file mode 100644
index 82c0d877..00000000
--- a/sway/old/container.c
+++ /dev/null
@@ -1,1024 +0,0 @@
-#define _XOPEN_SOURCE 500
-#include <ctype.h>
-#include <stdlib.h>
-#include <stdbool.h>
-#include <strings.h>
-#include <string.h>
-#include <wlr/types/wlr_box.h>
-#include <wlr/types/wlr_output.h>
-#include "sway/config.h"
-#include "sway/container.h"
-#include "sway/workspace.h"
-#include "sway/focus.h"
-#include "sway/border.h"
-#include "sway/layout.h"
-#include "sway/input_state.h"
-#include "sway/ipc-server.h"
-#include "sway/output.h"
-#include "sway/view.h"
-#include "log.h"
-#include "stringop.h"
-
-#define ASSERT_NONNULL(PTR) \
- sway_assert (PTR, #PTR "must be non-null")
-
-static swayc_t *new_swayc(enum swayc_types type) {
- // next id starts at 1 because 0 is assigned to root_container in layout.c
- static size_t next_id = 1;
- swayc_t *c = calloc(1, sizeof(swayc_t));
- if (!c) {
- return NULL;
- }
- c->id = next_id++;
- c->handle = -1;
- c->gaps = -1;
- c->layout = L_NONE;
- c->workspace_layout = L_NONE;
- c->type = type;
- c->nb_master = 1;
- c->nb_slave_groups = 1;
- if (type != C_VIEW) {
- c->children = create_list();
- }
- return c;
-}
-
-static void free_swayc(swayc_t *cont) {
- if (!ASSERT_NONNULL(cont)) {
- return;
- }
- if (cont->children) {
- // remove children until there are no more, free_swayc calls
- // remove_child, which removes child from this container
- while (cont->children->length) {
- free_swayc(cont->children->items[0]);
- }
- list_free(cont->children);
- }
- if (cont->unmanaged) {
- list_free(cont->unmanaged);
- }
- if (cont->floating) {
- while (cont->floating->length) {
- free_swayc(cont->floating->items[0]);
- }
- list_free(cont->floating);
- }
- if (cont->marks) {
- list_foreach(cont->marks, free);
- list_free(cont->marks);
- }
- if (cont->parent) {
- remove_child(cont);
- }
- if (cont->name) {
- free(cont->name);
- }
- if (cont->class) {
- free(cont->class);
- }
- if (cont->instance) {
- free(cont->instance);
- }
- if (cont->app_id) {
- free(cont->app_id);
- }
- if (cont->bg_pid != 0) {
- terminate_swaybg(cont->bg_pid);
- }
- if (cont->border) {
- if (cont->border->buffer) {
- free(cont->border->buffer);
- }
- free(cont->border);
- }
- free(cont);
-}
-
-static void update_root_geometry() {
- int width = 0;
- int height = 0;
- swayc_t *child;
- int child_width;
- int child_height;
-
- for (int i = 0; i < root_container.children->length; ++i) {
- child = root_container.children->items[i];
- child_width = child->width + child->x;
- child_height = child->height + child->y;
- if (child_width > width) {
- width = child_width;
- }
-
- if (child_height > height) {
- height = child_height;
- }
- }
-
- root_container.width = width;
- root_container.height = height;
-}
-
-// New containers
-
-swayc_t *new_output(struct sway_output *sway_output) {
- struct wlr_box size;
- wlr_output_effective_resolution(sway_output->wlr_output,
- &size.width, &size.height);
- const char *name = sway_output->wlr_output->name;
- // Find current outputs to see if this already exists
- {
- int i, len = root_container.children->length;
- for (i = 0; i < len; ++i) {
- swayc_t *op = root_container.children->items[i];
- const char *op_name = op->name;
- if (op_name && name && strcmp(op_name, name) == 0) {
- sway_log(L_DEBUG, "restoring output %p: %s",
- sway_output, op_name);
- return op;
- }
- }
- }
-
- struct output_config *oc = NULL, *all = NULL;
- int i;
- for (i = 0; i < config->output_configs->length; ++i) {
- struct output_config *cur = config->output_configs->items[i];
- if (strcasecmp(name, cur->name) == 0) {
- sway_log(L_DEBUG, "Matched output config for %s", name);
- oc = cur;
- }
- if (strcasecmp("*", cur->name) == 0) {
- sway_log(L_DEBUG, "Matched wildcard output config for %s", name);
- all = cur;
- }
-
- if (oc && all) {
- break;
- }
- }
-
- if (!oc) {
- oc = all;
- }
-
- if (oc && !oc->enabled) {
- return NULL;
- }
-
- swayc_t *output = new_swayc(C_OUTPUT);
- output->_handle.output = sway_output;
- output->name = name ? strdup(name) : NULL;
- output->width = size.width;
- output->height = size.width;
- output->unmanaged = create_list();
- output->bg_pid = 0;
-
- apply_output_config(oc, output);
- add_child(&root_container, output);
- load_swaybars();
-
- // Create workspace
- char *ws_name = NULL;
- swayc_t *ws = NULL;
-
- if (name) {
- for (i = 0; i < config->workspace_outputs->length; ++i) {
- struct workspace_output *wso = config->workspace_outputs->items[i];
- if (strcasecmp(wso->output, name) == 0) {
- sway_log(L_DEBUG, "Matched workspace to output: %s for %s", wso->workspace, wso->output);
- // Check if any other workspaces are using this name
- if ((ws = workspace_by_name(wso->workspace))) {
- // if yes, move those to this output, because they should be here
- move_workspace_to(ws, output);
- } else if (!ws_name) {
- // set a workspace name in case we need to create a default one
- ws_name = strdup(wso->workspace);
- }
- }
- }
- }
-
- if (output->children->length == 0) {
- if (!ws_name) {
- ws_name = workspace_next_name(output->name);
- }
- // create and initialize default workspace
- sway_log(L_DEBUG, "Creating default workspace %s", ws_name);
- ws = new_workspace(output, ws_name);
- ws->is_focused = true;
- } else {
- sort_workspaces(output);
- set_focused_container(output->children->items[0]);
- }
-
- free(ws_name);
- update_root_geometry();
- return output;
-}
-
-swayc_t *new_workspace(swayc_t *output, const char *name) {
- if (!ASSERT_NONNULL(output)) {
- return NULL;
- }
- sway_log(L_DEBUG, "Added workspace %s for output %u", name, (unsigned int)output->handle);
- swayc_t *workspace = new_swayc(C_WORKSPACE);
-
- workspace->prev_layout = L_NONE;
- workspace->layout = default_layout(output);
- workspace->workspace_layout = default_layout(output);
-
- workspace->x = output->x;
- workspace->y = output->y;
- workspace->width = output->width;
- workspace->height = output->height;
- workspace->name = !name ? NULL : strdup(name);
- workspace->visible = false;
- workspace->floating = create_list();
-
- add_child(output, workspace);
- sort_workspaces(output);
-
- return workspace;
-}
-
-swayc_t *new_container(swayc_t *child, enum swayc_layouts layout) {
- if (!ASSERT_NONNULL(child)
- && !sway_assert(!child->is_floating, "cannot create container around floating window")) {
- return NULL;
- }
- swayc_t *cont = new_swayc(C_CONTAINER);
-
- sway_log(L_DEBUG, "creating container %p around %p", cont, child);
-
- cont->prev_layout = L_NONE;
- cont->layout = layout;
- cont->width = child->width;
- cont->height = child->height;
- cont->x = child->x;
- cont->y = child->y;
- cont->visible = child->visible;
- cont->cached_geometry = child->cached_geometry;
- cont->gaps = child->gaps;
-
- /* Container inherits all of workspaces children, layout and whatnot */
- if (child->type == C_WORKSPACE) {
- swayc_t *workspace = child;
- // reorder focus
- cont->focused = workspace->focused;
- workspace->focused = cont;
- // set all children focu to container
- int i;
- for (i = 0; i < workspace->children->length; ++i) {
- ((swayc_t *)workspace->children->items[i])->parent = cont;
- }
- // Swap children
- list_t *tmp_list = workspace->children;
- workspace->children = cont->children;
- cont->children = tmp_list;
- // add container to workspace chidren
- add_child(workspace, cont);
- // give them proper layouts
- cont->layout = workspace->workspace_layout;
- cont->prev_layout = workspace->prev_layout;
- /* TODO: might break shit in move_container!!! workspace->layout = layout; */
- set_focused_container_for(workspace, get_focused_view(workspace));
- } else { // Or is built around container
- swayc_t *parent = replace_child(child, cont);
- if (parent) {
- add_child(cont, child);
- }
- }
- return cont;
-}
-
-swayc_t *new_view(swayc_t *sibling, struct sway_view *view) {
- if (!ASSERT_NONNULL(sibling)) {
- return NULL;
- }
- const char *title = view->iface.get_prop(view, VIEW_PROP_TITLE);
- swayc_t *swayc = new_swayc(C_VIEW);
- sway_log(L_DEBUG, "Adding new view %p:%s to container %p %d",
- swayc, title, sibling, sibling ? sibling->type : 0);
- // Setup values
- swayc->_handle.view = view;
-
- swayc->name = title ? strdup(title) : NULL;
-
- const char *class = view->iface.get_prop(view, VIEW_PROP_CLASS);
- swayc->class = class ? strdup(class) : NULL;
-
- const char *instance = view->iface.get_prop(view, VIEW_PROP_INSTANCE);
- swayc->instance = instance ? strdup(instance) : NULL;
-
- const char *app_id = view->iface.get_prop(view, VIEW_PROP_APP_ID);
- swayc->app_id = app_id ? strdup(app_id) : NULL;
-
- swayc->visible = true;
- swayc->is_focused = true;
- swayc->sticky = false;
- swayc->width = 0;
- swayc->height = 0;
- swayc->desired_width = -1;
- swayc->desired_height = -1;
- // setup border
- swayc->border_type = config->border;
- swayc->border_thickness = config->border_thickness;
-
- swayc->is_floating = false;
-
- if (sibling->type == C_WORKSPACE) {
- // Case of focused workspace, just create as child of it
- add_child(sibling, swayc);
- } else {
- // Regular case, create as sibling of current container
- add_sibling(sibling, swayc);
- }
- return swayc;
-}
-
-swayc_t *new_floating_view(wlc_handle handle) {
- if (swayc_active_workspace() == NULL) {
- return NULL;
- }
- const char *title = wlc_view_get_title(handle);
- swayc_t *view = new_swayc(C_VIEW);
- sway_log(L_DEBUG, "Adding new view %" PRIuPTR ":%x:%s as a floating view",
- handle, wlc_view_get_type(handle), title);
- // Setup values
- view->handle = handle;
- view->name = title ? strdup(title) : NULL;
- const char *class = wlc_view_get_class(handle);
- view->class = class ? strdup(class) : NULL;
- const char *instance = wlc_view_get_instance(handle);
- view->instance = instance ? strdup(instance) : NULL;
- const char *app_id = wlc_view_get_app_id(handle);
- view->app_id = app_id ? strdup(app_id) : NULL;
- view->visible = true;
- view->sticky = false;
-
- // Set the geometry of the floating view
- const struct wlc_geometry *geometry = wlc_view_get_geometry(handle);
-
- // give it requested geometry, but place in center if possible
- // in top left otherwise
- if (geometry->size.w != 0) {
- view->x = (swayc_active_workspace()->width - geometry->size.w) / 2;
- } else {
- view->x = 0;
- }
- if (geometry->size.h != 0) {
- view->y = (swayc_active_workspace()->height - geometry->size.h) / 2;
- } else {
- view->y = 0;
- }
-
- view->width = geometry->size.w;
- view->height = geometry->size.h;
-
- view->desired_width = view->width;
- view->desired_height = view->height;
-
- // setup border
- view->border_type = config->floating_border;
- view->border_thickness = config->floating_border_thickness;
-
- view->is_floating = true;
-
- // Case of focused workspace, just create as child of it
- list_add(swayc_active_workspace()->floating, view);
- view->parent = swayc_active_workspace();
- if (swayc_active_workspace()->focused == NULL) {
- set_focused_container_for(swayc_active_workspace(), view);
- }
- return view;
-}
-
-void floating_view_sane_size(swayc_t *view) {
- // floating_minimum is used as sane value.
- // floating_maximum has priority in case of conflict
- // TODO: implement total_outputs_dimensions()
- if (config->floating_minimum_height != -1 &&
- view->desired_height < config->floating_minimum_height) {
- view->desired_height = config->floating_minimum_height;
- }
- if (config->floating_minimum_width != -1 &&
- view->desired_width < config->floating_minimum_width) {
- view->desired_width = config->floating_minimum_width;
- }
-
- // if 0 do not resize, only enforce max value
- if (config->floating_maximum_height == 0) {
- // Missing total_outputs_dimensions() using swayc_active_workspace()
- config->floating_maximum_height = swayc_active_workspace()->height;
-
- } else if (config->floating_maximum_height != -1 &&
- view->desired_height > config->floating_maximum_height) {
- view->desired_height = config->floating_maximum_height;
- }
-
- // if 0 do not resize, only enforce max value
- if (config->floating_maximum_width == 0) {
- // Missing total_outputs_dimensions() using swayc_active_workspace()
- config->floating_maximum_width = swayc_active_workspace()->width;
-
- } else if (config->floating_maximum_width != -1 &&
- view->desired_width > config->floating_maximum_width) {
- view->desired_width = config->floating_maximum_width;
- }
-
- sway_log(L_DEBUG, "Sane values for view to %d x %d @ %.f, %.f",
- view->desired_width, view->desired_height, view->x, view->y);
-
- return;
-}
-
-
-// Destroy container
-
-swayc_t *destroy_output(swayc_t *output) {
- if (!ASSERT_NONNULL(output)) {
- return NULL;
- }
- if (output->children->length > 0) {
- // TODO save workspaces when there are no outputs.
- // TODO also check if there will ever be no outputs except for exiting
- // program
- if (root_container.children->length > 1) {
- int p = root_container.children->items[0] == output;
- // Move workspace from this output to another output
- while (output->children->length) {
- swayc_t *child = output->children->items[0];
- remove_child(child);
- add_child(root_container.children->items[p], child);
- }
- sort_workspaces(root_container.children->items[p]);
- update_visibility(root_container.children->items[p]);
- arrange_windows(root_container.children->items[p], -1, -1);
- }
- }
- sway_log(L_DEBUG, "OUTPUT: Destroying output '%" PRIuPTR "'", output->handle);
- free_swayc(output);
- update_root_geometry();
- return &root_container;
-}
-
-swayc_t *destroy_workspace(swayc_t *workspace) {
- if (!ASSERT_NONNULL(workspace)) {
- return NULL;
- }
-
- // Do not destroy this if it's the last workspace on this output
- swayc_t *output = swayc_parent_by_type(workspace, C_OUTPUT);
- if (output && output->children->length == 1) {
- return NULL;
- }
-
- swayc_t *parent = workspace->parent;
- // destroy the WS if there are no children
- if (workspace->children->length == 0 && workspace->floating->length == 0) {
- sway_log(L_DEBUG, "destroying workspace '%s'", workspace->name);
- ipc_event_workspace(workspace, NULL, "empty");
- } else {
- // Move children to a different workspace on this output
- swayc_t *new_workspace = NULL;
- int i;
- for(i = 0; i < output->children->length; i++) {
- if(output->children->items[i] != workspace) {
- break;
- }
- }
- new_workspace = output->children->items[i];
-
- sway_log(L_DEBUG, "moving children to different workspace '%s' -> '%s'",
- workspace->name, new_workspace->name);
-
- for(i = 0; i < workspace->children->length; i++) {
- move_container_to(workspace->children->items[i], new_workspace);
- }
-
- for(i = 0; i < workspace->floating->length; i++) {
- move_container_to(workspace->floating->items[i], new_workspace);
- }
- }
-
- free_swayc(workspace);
- return parent;
-}
-
-swayc_t *destroy_container(swayc_t *container) {
- if (!ASSERT_NONNULL(container)) {
- return NULL;
- }
- while (container->children->length == 0 && container->type == C_CONTAINER) {
- sway_log(L_DEBUG, "Container: Destroying container '%p'", container);
- swayc_t *parent = container->parent;
- free_swayc(container);
- container = parent;
- }
- return container;
-}
-
-swayc_t *destroy_view(swayc_t *view) {
- if (!ASSERT_NONNULL(view)) {
- return NULL;
- }
- sway_log(L_DEBUG, "Destroying view '%p'", view);
- swayc_t *parent = view->parent;
- free_swayc(view);
-
- // Destroy empty containers
- if (parent && parent->type == C_CONTAINER) {
- return destroy_container(parent);
- }
- return parent;
-}
-
-// Container lookup
-
-
-swayc_t *swayc_by_test(swayc_t *container, bool (*test)(swayc_t *view, void *data), void *data) {
- if (!container->children) {
- return NULL;
- }
- // Special case for checking floating stuff
- int i;
- if (container->type == C_WORKSPACE) {
- for (i = 0; i < container->floating->length; ++i) {
- swayc_t *child = container->floating->items[i];
- if (test(child, data)) {
- return child;
- }
- }
- }
- for (i = 0; i < container->children->length; ++i) {
- swayc_t *child = container->children->items[i];
- if (test(child, data)) {
- return child;
- } else {
- swayc_t *res = swayc_by_test(child, test, data);
- if (res) {
- return res;
- }
- }
- }
- return NULL;
-}
-
-static bool test_name(swayc_t *view, void *data) {
- if (!view || !view->name) {
- return false;
- }
- return strcmp(view->name, data) == 0;
-}
-
-swayc_t *swayc_by_name(const char *name) {
- return swayc_by_test(&root_container, test_name, (void *)name);
-}
-
-swayc_t *swayc_parent_by_type(swayc_t *container, enum swayc_types type) {
- if (!ASSERT_NONNULL(container)) {
- return NULL;
- }
- if (!sway_assert(type < C_TYPES && type >= C_ROOT, "invalid type")) {
- return NULL;
- }
- do {
- container = container->parent;
- } while (container && container->type != type);
- return container;
-}
-
-swayc_t *swayc_parent_by_layout(swayc_t *container, enum swayc_layouts layout) {
- if (!ASSERT_NONNULL(container)) {
- return NULL;
- }
- if (!sway_assert(layout < L_LAYOUTS && layout >= L_NONE, "invalid layout")) {
- return NULL;
- }
- do {
- container = container->parent;
- } while (container && container->layout != layout);
- return container;
-}
-
-swayc_t *swayc_focus_by_type(swayc_t *container, enum swayc_types type) {
- if (!ASSERT_NONNULL(container)) {
- return NULL;
- }
- if (!sway_assert(type < C_TYPES && type >= C_ROOT, "invalid type")) {
- return NULL;
- }
- do {
- container = container->focused;
- } while (container && container->type != type);
- return container;
-}
-
-swayc_t *swayc_focus_by_layout(swayc_t *container, enum swayc_layouts layout) {
- if (!ASSERT_NONNULL(container)) {
- return NULL;
- }
- if (!sway_assert(layout < L_LAYOUTS && layout >= L_NONE, "invalid layout")) {
- return NULL;
- }
- do {
- container = container->focused;
- } while (container && container->layout != layout);
- return container;
-}
-
-
-static swayc_t *_swayc_by_handle_helper(wlc_handle handle, swayc_t *parent) {
- if (!parent || !parent->children) {
- return NULL;
- }
- int i, len;
- swayc_t **child;
- if (parent->type == C_WORKSPACE) {
- len = parent->floating->length;
- child = (swayc_t **)parent->floating->items;
- for (i = 0; i < len; ++i, ++child) {
- if ((*child)->handle == handle) {
- return *child;
- }
- }
- }
-
- len = parent->children->length;
- child = (swayc_t**)parent->children->items;
- for (i = 0; i < len; ++i, ++child) {
- if ((*child)->handle == handle) {
- return *child;
- } else {
- swayc_t *res;
- if ((res = _swayc_by_handle_helper(handle, *child))) {
- return res;
- }
- }
- }
- return NULL;
-}
-
-swayc_t *swayc_by_handle(wlc_handle handle) {
- return _swayc_by_handle_helper(handle, &root_container);
-}
-
-swayc_t *swayc_active_output(void) {
- return root_container.focused;
-}
-
-swayc_t *swayc_active_workspace(void) {
- return root_container.focused ? root_container.focused->focused : NULL;
-}
-
-swayc_t *swayc_active_workspace_for(swayc_t *cont) {
- if (!cont) {
- return NULL;
- }
- switch (cont->type) {
- case C_ROOT:
- cont = cont->focused;
- /* Fallthrough */
-
- case C_OUTPUT:
- cont = cont ? cont->focused : NULL;
- /* Fallthrough */
-
- case C_WORKSPACE:
- return cont;
-
- default:
- return swayc_parent_by_type(cont, C_WORKSPACE);
- }
-}
-
-static bool pointer_test(swayc_t *view, void *_origin) {
- const struct wlc_point *origin = _origin;
- // Determine the output that the view is under
- swayc_t *parent = swayc_parent_by_type(view, C_OUTPUT);
- if (origin->x >= view->x && origin->y >= view->y
- && origin->x < view->x + view->width && origin->y < view->y + view->height
- && view->visible && parent == root_container.focused) {
- return true;
- }
- return false;
-}
-
-swayc_t *container_under_pointer(void) {
- // root.output->workspace
- if (!root_container.focused) {
- return NULL;
- }
- swayc_t *lookup = root_container.focused;
- // Case of empty workspace
- if (lookup->children && !lookup->unmanaged) {
- return NULL;
- }
- double x, y;
- wlc_pointer_get_position_v2(&x, &y);
- struct wlc_point origin = { .x = x, .y = y };
-
- while (lookup && lookup->type != C_VIEW) {
- int i;
- int len;
- for (int _i = 0; lookup->unmanaged && _i < lookup->unmanaged->length; ++_i) {
- wlc_handle *handle = lookup->unmanaged->items[_i];
- const struct wlc_geometry *geo = wlc_view_get_geometry(*handle);
- if (origin.x >= geo->origin.x && origin.y >= geo->origin.y
- && origin.x < geo->origin.x + (int)geo->size.w
- && origin.y < geo->origin.y + (int)geo->size.h) {
- // Hack: we force focus upon unmanaged views here
- wlc_view_focus(*handle);
- return NULL;
- }
- }
- // if tabbed/stacked go directly to focused container, otherwise search
- // children
- if (lookup->layout == L_TABBED || lookup->layout == L_STACKED) {
- lookup = lookup->focused;
- continue;
- }
- // if workspace, search floating
- if (lookup->type == C_WORKSPACE) {
- i = len = lookup->floating->length;
- bool got_floating = false;
- while (--i > -1) {
- if (pointer_test(lookup->floating->items[i], &origin)) {
- lookup = lookup->floating->items[i];
- got_floating = true;
- break;
- }
- }
- if (got_floating) {
- continue;
- }
- }
- // search children
- len = lookup->children->length;
- for (i = 0; i < len; ++i) {
- if (pointer_test(lookup->children->items[i], &origin)) {
- lookup = lookup->children->items[i];
- break;
- }
- }
- // when border and titles are done, this could happen
- if (i == len) {
- break;
- }
- }
- return lookup;
-}
-
-swayc_t *container_find(swayc_t *container, bool (*f)(swayc_t *, const void *), const void *data) {
- if (container->children == NULL || container->children->length == 0) {
- return NULL;
- }
-
- swayc_t *con;
- if (container->type == C_WORKSPACE) {
- for (int i = 0; i < container->floating->length; ++i) {
- con = container->floating->items[i];
- if (f(con, data)) {
- return con;
- }
- con = container_find(con, f, data);
- if (con != NULL) {
- return con;
- }
- }
- }
-
- for (int i = 0; i < container->children->length; ++i) {
- con = container->children->items[i];
- if (f(con, data)) {
- return con;
- }
-
- con = container_find(con, f, data);
- if (con != NULL) {
- return con;
- }
- }
-
- return NULL;
-}
-
-// Container information
-
-bool swayc_is_fullscreen(swayc_t *view) {
- return view && view->type == C_VIEW && (wlc_view_get_state(view->handle) & WLC_BIT_FULLSCREEN);
-}
-
-bool swayc_is_active(swayc_t *view) {
- return view && view->type == C_VIEW && (wlc_view_get_state(view->handle) & WLC_BIT_ACTIVATED);
-}
-
-bool swayc_is_parent_of(swayc_t *parent, swayc_t *child) {
- while (child != &root_container) {
- child = child->parent;
- if (child == parent) {
- return true;
- }
- }
- return false;
-}
-
-bool swayc_is_child_of(swayc_t *child, swayc_t *parent) {
- return swayc_is_parent_of(parent, child);
-}
-
-bool swayc_is_empty_workspace(swayc_t *container) {
- return container->type == C_WORKSPACE && container->children->length == 0;
-}
-
-int swayc_gap(swayc_t *container) {
- if (container->type == C_VIEW || container->type == C_CONTAINER) {
- return container->gaps >= 0 ? container->gaps : config->gaps_inner;
- } else if (container->type == C_WORKSPACE) {
- int base = container->gaps >= 0 ? container->gaps : config->gaps_outer;
- if (config->edge_gaps && !(config->smart_gaps && container->children->length == 1)) {
- // the inner gap is created via a margin around each window which
- // is half the gap size, so the workspace also needs half a gap
- // size to make the outermost gap the same size (excluding the
- // actual "outer gap" size which is handled independently)
- return base + config->gaps_inner / 2;
- } else if (config->smart_gaps && container->children->length == 1) {
- return 0;
- } else {
- return base;
- }
- } else {
- return 0;
- }
-}
-
-// Mapping
-
-void container_map(swayc_t *container, void (*f)(swayc_t *view, void *data), void *data) {
- if (container) {
- int i;
- if (container->children) {
- for (i = 0; i < container->children->length; ++i) {
- swayc_t *child = container->children->items[i];
- container_map(child, f, data);
- }
- }
- if (container->floating) {
- for (i = 0; i < container->floating->length; ++i) {
- swayc_t *child = container->floating->items[i];
- container_map(child, f, data);
- }
- }
- f(container, data);
- }
-}
-
-void update_visibility_output(swayc_t *container, wlc_handle output) {
- // Inherit visibility
- swayc_t *parent = container->parent;
- container->visible = parent->visible;
- // special cases where visibility depends on focus
- if (parent->type == C_OUTPUT || parent->layout == L_TABBED ||
- parent->layout == L_STACKED) {
- container->visible = parent->focused == container && parent->visible;
- }
- // Set visibility and output for view
- if (container->type == C_VIEW) {
- wlc_view_set_output(container->handle, output);
- wlc_view_set_mask(container->handle, container->visible ? VISIBLE : 0);
- }
- // Update visibility for children
- else {
- if (container->children) {
- int i, len = container->children->length;
- for (i = 0; i < len; ++i) {
- update_visibility_output(container->children->items[i], output);
- }
- }
- if (container->floating) {
- int i, len = container->floating->length;
- for (i = 0; i < len; ++i) {
- update_visibility_output(container->floating->items[i], output);
- }
- }
- }
-}
-
-void update_visibility(swayc_t *container) {
- if (!container) return;
- switch (container->type) {
- case C_ROOT:
- container->visible = true;
- if (container->children) {
- int i, len = container->children->length;
- for (i = 0; i < len; ++i) {
- update_visibility(container->children->items[i]);
- }
- }
- return;
-
- case C_OUTPUT:
- container->visible = true;
- if (container->children) {
- int i, len = container->children->length;
- for (i = 0; i < len; ++i) {
- update_visibility_output(container->children->items[i], container->handle);
- }
- }
- return;
-
- default:
- {
- swayc_t *op = swayc_parent_by_type(container, C_OUTPUT);
- update_visibility_output(container, op->handle);
- }
- }
-}
-
-void set_gaps(swayc_t *view, void *_data) {
- int *data = _data;
- if (!ASSERT_NONNULL(view)) {
- return;
- }
- if (view->type == C_WORKSPACE || view->type == C_VIEW) {
- view->gaps = *data;
- }
-}
-
-void add_gaps(swayc_t *view, void *_data) {
- int *data = _data;
- if (!ASSERT_NONNULL(view)) {
- return;
- }
- if (view->type == C_WORKSPACE || view->type == C_VIEW) {
- if ((view->gaps += *data) < 0) {
- view->gaps = 0;
- }
- }
-}
-
-static void close_view(swayc_t *container, void *data) {
- if (container->type == C_VIEW) {
- wlc_view_close(container->handle);
- }
-}
-
-void close_views(swayc_t *container) {
- container_map(container, close_view, NULL);
-}
-
-swayc_t *swayc_tabbed_stacked_ancestor(swayc_t *view) {
- swayc_t *parent = NULL;
- if (!ASSERT_NONNULL(view)) {
- return NULL;
- }
- while (view->type != C_WORKSPACE && view->parent && view->parent->type != C_WORKSPACE) {
- view = view->parent;
- if (view->layout == L_TABBED || view->layout == L_STACKED) {
- parent = view;
- }
- }
-
- return parent;
-}
-
-swayc_t *swayc_tabbed_stacked_parent(swayc_t *con) {
- if (!ASSERT_NONNULL(con)) {
- return NULL;
- }
- if (con->parent && (con->parent->layout == L_TABBED || con->parent->layout == L_STACKED)) {
- return con->parent;
- }
- return NULL;
-}
-
-swayc_t *swayc_change_layout(swayc_t *container, enum swayc_layouts layout) {
- // if layout change modifies the auto layout's major axis, swap width and height
- // to preserve current ratios.
- if (is_auto_layout(layout) && is_auto_layout(container->layout)) {
- enum swayc_layouts prev_major =
- container->layout == L_AUTO_LEFT || container->layout == L_AUTO_RIGHT
- ? L_HORIZ : L_VERT;
- enum swayc_layouts new_major =
- layout == L_AUTO_LEFT || layout == L_AUTO_RIGHT
- ? L_HORIZ : L_VERT;
- if (new_major != prev_major) {
- for (int i = 0; i < container->children->length; ++i) {
- swayc_t *child = container->children->items[i];
- double h = child->height;
- child->height = child->width;
- child->width = h;
- }
- }
- }
- if (container->type == C_WORKSPACE) {
- container->workspace_layout = layout;
- if (layout == L_HORIZ || layout == L_VERT || is_auto_layout(layout)) {
- container->layout = layout;
- }
- } else {
- container->layout = layout;
- }
- return container;
-}
diff --git a/sway/old/criteria.c b/sway/old/criteria.c
deleted file mode 100644
index e8978ebe..00000000
--- a/sway/old/criteria.c
+++ /dev/null
@@ -1,451 +0,0 @@
-#define _XOPEN_SOURCE 700
-#include <stdlib.h>
-#include <stdio.h>
-#include <stdbool.h>
-#include <pcre.h>
-#include "sway/criteria.h"
-#include "sway/container.h"
-#include "sway/config.h"
-#include "stringop.h"
-#include "list.h"
-#include "log.h"
-
-enum criteria_type { // *must* keep in sync with criteria_strings[]
- CRIT_CLASS,
- CRIT_CON_ID,
- CRIT_CON_MARK,
- CRIT_FLOATING,
- CRIT_ID,
- CRIT_INSTANCE,
- CRIT_TILING,
- CRIT_TITLE,
- CRIT_URGENT,
- CRIT_WINDOW_ROLE,
- CRIT_WINDOW_TYPE,
- CRIT_WORKSPACE,
- CRIT_LAST
-};
-
-static const char * const criteria_strings[CRIT_LAST] = {
- [CRIT_CLASS] = "class",
- [CRIT_CON_ID] = "con_id",
- [CRIT_CON_MARK] = "con_mark",
- [CRIT_FLOATING] = "floating",
- [CRIT_ID] = "id",
- [CRIT_INSTANCE] = "instance",
- [CRIT_TILING] = "tiling",
- [CRIT_TITLE] = "title",
- [CRIT_URGENT] = "urgent", // either "latest" or "oldest" ...
- [CRIT_WINDOW_ROLE] = "window_role",
- [CRIT_WINDOW_TYPE] = "window_type",
- [CRIT_WORKSPACE] = "workspace"
-};
-
-/**
- * A single criteria token (ie. value/regex pair),
- * e.g. 'class="some class regex"'.
- */
-struct crit_token {
- enum criteria_type type;
- pcre *regex;
- char *raw;
-};
-
-static void free_crit_token(struct crit_token *crit) {
- pcre_free(crit->regex);
- free(crit->raw);
- free(crit);
-}
-
-static void free_crit_tokens(list_t *crit_tokens) {
- for (int i = 0; i < crit_tokens->length; i++) {
- free_crit_token(crit_tokens->items[i]);
- }
- list_free(crit_tokens);
-}
-
-// Extracts criteria string from its brackets. Returns new (duplicate)
-// substring.
-static char *criteria_from(const char *arg) {
- char *criteria = NULL;
- if (*arg == '[') {
- criteria = strdup(arg + 1);
- } else {
- criteria = strdup(arg);
- }
-
- int last = strlen(criteria) - 1;
- if (criteria[last] == ']') {
- criteria[last] = '\0';
- }
- return criteria;
-}
-
-// Return instances of c found in str.
-static int countchr(char *str, char c) {
- int found = 0;
- for (int i = 0; str[i]; i++) {
- if (str[i] == c) {
- ++found;
- }
- }
- return found;
-}
-
-// criteria_str is e.g. '[class="some class regex" instance="instance name"]'.
-//
-// Will create array of pointers in buf, where first is duplicate of given
-// string (must be freed) and the rest are pointers to names and values in the
-// base string (every other, naturally). argc will be populated with the length
-// of buf.
-//
-// Returns error string or NULL if successful.
-static char *crit_tokens(int *argc, char ***buf, const char * const criteria_str) {
- sway_log(L_DEBUG, "Parsing criteria: '%s'", criteria_str);
- char *base = criteria_from(criteria_str);
- char *head = base;
- char *namep = head; // start of criteria name
- char *valp = NULL; // start of value
-
- // We're going to place EOS markers where we need to and fill up an array
- // of pointers to the start of each token (either name or value).
- int pairs = countchr(base, '=');
- int max_tokens = pairs * 2 + 1; // this gives us at least enough slots
-
- char **argv = *buf = calloc(max_tokens, sizeof(char*));
- argv[0] = base; // this needs to be freed by caller
- bool quoted = true;
-
- *argc = 1; // uneven = name, even = value
- while (*head && *argc < max_tokens) {
- if (namep != head && *(head - 1) == '\\') {
- // escaped character: don't try to parse this
- } else if (*head == '=' && namep != head) {
- if (*argc % 2 != 1) {
- // we're not expecting a name
- return strdup("Unable to parse criteria: "
- "Found out of place equal sign");
- } else {
- // name ends here
- char *end = head; // don't want to rewind the head
- while (*(end - 1) == ' ') {
- --end;
- }
- *end = '\0';
- if (*(namep) == ' ') {
- namep = strrchr(namep, ' ') + 1;
- }
- argv[*argc] = namep;
- *argc += 1;
- }
- } else if (*head == '"') {
- if (*argc % 2 != 0) {
- // we're not expecting a value
- return strdup("Unable to parse criteria: "
- "Found quoted value where it was not expected");
- } else if (!valp) { // value starts here
- valp = head + 1;
- quoted = true;
- } else {
- // value ends here
- argv[*argc] = valp;
- *argc += 1;
- *head = '\0';
- valp = NULL;
- namep = head + 1;
- }
- } else if (*argc % 2 == 0 && *head != ' ') {
- // parse unquoted values
- if (!valp) {
- quoted = false;
- valp = head; // value starts here
- }
- } else if (valp && !quoted && *head == ' ') {
- // value ends here
- argv[*argc] = valp;
- *argc += 1;
- *head = '\0';
- valp = NULL;
- namep = head + 1;
- }
- head++;
- }
-
- // catch last unquoted value if needed
- if (valp && !quoted && !*head) {
- argv[*argc] = valp;
- *argc += 1;
- }
-
- return NULL;
-}
-
-// Returns error string on failure or NULL otherwise.
-static char *parse_criteria_name(enum criteria_type *type, char *name) {
- *type = CRIT_LAST;
- for (int i = 0; i < CRIT_LAST; i++) {
- if (strcmp(criteria_strings[i], name) == 0) {
- *type = (enum criteria_type) i;
- break;
- }
- }
- if (*type == CRIT_LAST) {
- const char *fmt = "Criteria type '%s' is invalid or unsupported.";
- int len = strlen(name) + strlen(fmt) - 1;
- char *error = malloc(len);
- snprintf(error, len, fmt, name);
- return error;
- } else if (*type == CRIT_URGENT || *type == CRIT_WINDOW_ROLE ||
- *type == CRIT_WINDOW_TYPE) {
- // (we're just being helpful here)
- const char *fmt = "\"%s\" criteria currently unsupported, "
- "no window will match this";
- int len = strlen(fmt) + strlen(name) - 1;
- char *error = malloc(len);
- snprintf(error, len, fmt, name);
- return error;
- }
- return NULL;
-}
-
-// Returns error string on failure or NULL otherwise.
-static char *generate_regex(pcre **regex, char *value) {
- const char *reg_err;
- int offset;
-
- *regex = pcre_compile(value, PCRE_UTF8 | PCRE_UCP, &reg_err, &offset, NULL);
-
- if (!*regex) {
- const char *fmt = "Regex compilation (for '%s') failed: %s";
- int len = strlen(fmt) + strlen(value) + strlen(reg_err) - 3;
- char *error = malloc(len);
- snprintf(error, len, fmt, value, reg_err);
- return error;
- }
- return NULL;
-}
-
-// Test whether the criterion corresponds to the currently focused window
-static bool crit_is_focused(const char *value) {
- return !strcmp(value, "focused") || !strcmp(value, "__focused__");
-}
-
-// Populate list with crit_tokens extracted from criteria string, returns error
-// string or NULL if successful.
-char *extract_crit_tokens(list_t *tokens, const char * const criteria) {
- int argc;
- char **argv = NULL, *error = NULL;
- if ((error = crit_tokens(&argc, &argv, criteria))) {
- goto ect_cleanup;
- }
- for (int i = 1; i + 1 < argc; i += 2) {
- char* name = argv[i], *value = argv[i + 1];
- struct crit_token *token = calloc(1, sizeof(struct crit_token));
- token->raw = strdup(value);
-
- if ((error = parse_criteria_name(&token->type, name))) {
- free_crit_token(token);
- goto ect_cleanup;
- } else if (token->type == CRIT_URGENT || crit_is_focused(value)) {
- sway_log(L_DEBUG, "%s -> \"%s\"", name, value);
- list_add(tokens, token);
- } else if((error = generate_regex(&token->regex, value))) {
- free_crit_token(token);
- goto ect_cleanup;
- } else {
- sway_log(L_DEBUG, "%s -> /%s/", name, value);
- list_add(tokens, token);
- }
- }
-ect_cleanup:
- free(argv[0]); // base string
- free(argv);
- return error;
-}
-
-static int regex_cmp(const char *item, const pcre *regex) {
- return pcre_exec(regex, NULL, item, strlen(item), 0, 0, NULL, 0);
-}
-
-// test a single view if it matches list of criteria tokens (all of them).
-static bool criteria_test(swayc_t *cont, list_t *tokens) {
- if (cont->type != C_VIEW) {
- return false;
- }
- int matches = 0;
- for (int i = 0; i < tokens->length; i++) {
- struct crit_token *crit = tokens->items[i];
- switch (crit->type) {
- case CRIT_CLASS:
- if (!cont->class) {
- // ignore
- } else if (crit_is_focused(crit->raw)) {
- swayc_t *focused = get_focused_view(&root_container);
- if (focused->class && strcmp(cont->class, focused->class) == 0) {
- matches++;
- }
- } else if (crit->regex && regex_cmp(cont->class, crit->regex) == 0) {
- matches++;
- }
- break;
- case CRIT_CON_ID: {
- char *endptr;
- size_t crit_id = strtoul(crit->raw, &endptr, 10);
-
- if (*endptr == 0 && cont->id == crit_id) {
- ++matches;
- }
- break;
- }
- case CRIT_CON_MARK:
- if (crit->regex && cont->marks && (list_seq_find(cont->marks, (int (*)(const void *, const void *))regex_cmp, crit->regex) != -1)) {
- // Make sure it isn't matching the NUL string
- if ((strcmp(crit->raw, "") == 0) == (list_seq_find(cont->marks, (int (*)(const void *, const void *))strcmp, "") != -1)) {
- ++matches;
- }
- }
- break;
- case CRIT_FLOATING:
- if (cont->is_floating) {
- matches++;
- }
- break;
- case CRIT_ID:
- if (!cont->app_id) {
- // ignore
- } else if (crit->regex && regex_cmp(cont->app_id, crit->regex) == 0) {
- matches++;
- }
- break;
- case CRIT_INSTANCE:
- if (!cont->instance) {
- // ignore
- } else if (crit_is_focused(crit->raw)) {
- swayc_t *focused = get_focused_view(&root_container);
- if (focused->instance && strcmp(cont->instance, focused->instance) == 0) {
- matches++;
- }
- } else if (crit->regex && regex_cmp(cont->instance, crit->regex) == 0) {
- matches++;
- }
- break;
- case CRIT_TILING:
- if (!cont->is_floating) {
- matches++;
- }
- break;
- case CRIT_TITLE:
- if (!cont->name) {
- // ignore
- } else if (crit_is_focused(crit->raw)) {
- swayc_t *focused = get_focused_view(&root_container);
- if (focused->name && strcmp(cont->name, focused->name) == 0) {
- matches++;
- }
- } else if (crit->regex && regex_cmp(cont->name, crit->regex) == 0) {
- matches++;
- }
- break;
- case CRIT_URGENT: // "latest" or "oldest"
- break;
- case CRIT_WINDOW_ROLE:
- break;
- case CRIT_WINDOW_TYPE:
- // TODO wlc indeed exposes this information
- break;
- case CRIT_WORKSPACE: ;
- swayc_t *cont_ws = swayc_parent_by_type(cont, C_WORKSPACE);
- if (!cont_ws || !cont_ws->name) {
- // ignore
- } else if (crit_is_focused(crit->raw)) {
- swayc_t *focused_ws = swayc_active_workspace();
- if (focused_ws->name && strcmp(cont_ws->name, focused_ws->name) == 0) {
- matches++;
- }
- } else if (crit->regex && regex_cmp(cont_ws->name, crit->regex) == 0) {
- matches++;
- }
- break;
- default:
- sway_abort("Invalid criteria type (%i)", crit->type);
- break;
- }
- }
- return matches == tokens->length;
-}
-
-int criteria_cmp(const void *a, const void *b) {
- if (a == b) {
- return 0;
- } else if (!a) {
- return -1;
- } else if (!b) {
- return 1;
- }
- const struct criteria *crit_a = a, *crit_b = b;
- int cmp = lenient_strcmp(crit_a->cmdlist, crit_b->cmdlist);
- if (cmp != 0) {
- return cmp;
- }
- return lenient_strcmp(crit_a->crit_raw, crit_b->crit_raw);
-}
-
-void free_criteria(struct criteria *crit) {
- if (crit->tokens) {
- free_crit_tokens(crit->tokens);
- }
- if (crit->cmdlist) {
- free(crit->cmdlist);
- }
- if (crit->crit_raw) {
- free(crit->crit_raw);
- }
- free(crit);
-}
-
-bool criteria_any(swayc_t *cont, list_t *criteria) {
- for (int i = 0; i < criteria->length; i++) {
- struct criteria *bc = criteria->items[i];
- if (criteria_test(cont, bc->tokens)) {
- return true;
- }
- }
- return false;
-}
-
-list_t *criteria_for(swayc_t *cont) {
- list_t *criteria = config->criteria, *matches = create_list();
- for (int i = 0; i < criteria->length; i++) {
- struct criteria *bc = criteria->items[i];
- if (criteria_test(cont, bc->tokens)) {
- list_add(matches, bc);
- }
- }
- return matches;
-}
-
-struct list_tokens {
- list_t *list;
- list_t *tokens;
-};
-
-static void container_match_add(swayc_t *container, struct list_tokens *list_tokens) {
- if (criteria_test(container, list_tokens->tokens)) {
- list_add(list_tokens->list, container);
- }
-}
-
-list_t *container_for(list_t *tokens) {
- struct list_tokens list_tokens = (struct list_tokens){create_list(), tokens};
-
- container_map(&root_container, (void (*)(swayc_t *, void *))container_match_add, &list_tokens);
-
- for (int i = 0; i < scratchpad->length; ++i) {
- swayc_t *c = scratchpad->items[i];
- if (criteria_test(c, tokens)) {
- list_add(list_tokens.list, c);
- }
- }
-
- return list_tokens.list;
-}
diff --git a/sway/old/focus.c b/sway/old/focus.c
deleted file mode 100644
index 66f7ee17..00000000
--- a/sway/old/focus.c
+++ /dev/null
@@ -1,278 +0,0 @@
-#include "stdbool.h"
-#include <wlc/wlc.h>
-#include "sway/focus.h"
-#include "sway/workspace.h"
-#include "sway/layout.h"
-#include "sway/config.h"
-#include "sway/input_state.h"
-#include "sway/ipc-server.h"
-#include "sway/border.h"
-#include "log.h"
-
-bool locked_container_focus = false;
-bool suspend_workspace_cleanup = false;
-
-// switches parent focus to c. will switch it accordingly
-static void update_focus(swayc_t *c) {
- // Handle if focus switches
- swayc_t *parent = c->parent;
- if (!parent) return;
- if (parent->focused != c) {
- // Get previous focus
- swayc_t *prev = parent->focused;
- // Set new focus
- parent->focused = c;
-
- switch (c->type) {
- // Shouldn't happen
- case C_ROOT: return;
-
- // Case where output changes
- case C_OUTPUT:
- wlc_output_focus(c->handle);
- break;
-
- // Case where workspace changes
- case C_WORKSPACE:
- if (prev) {
- ipc_event_workspace(prev, c, "focus");
-
- // if the old workspace has no children, destroy it
- if(prev->children->length == 0 && prev->floating->length == 0 && !suspend_workspace_cleanup) {
- destroy_workspace(prev);
- } else {
- // update visibility of old workspace
- update_visibility(prev);
- }
- }
- // Update visibility of newly focused workspace
- update_visibility(c);
- break;
-
- default:
- case C_VIEW:
- case C_CONTAINER:
- break;
- }
- }
-}
-
-bool move_focus(enum movement_direction direction) {
- swayc_t *old_view = get_focused_container(&root_container);
- swayc_t *new_view = get_swayc_in_direction(old_view, direction);
- if (!new_view) {
- return false;
- } else if (new_view->type == C_ROOT) {
- sway_log(L_DEBUG, "Not setting focus above the workspace level");
- return false;
- } else if (new_view->type == C_OUTPUT) {
- return set_focused_container(swayc_active_workspace_for(new_view));
- } else if (direction == MOVE_PARENT || direction == MOVE_CHILD) {
- return set_focused_container(new_view);
- } else if (config->mouse_warping) {
- swayc_t *old_op = old_view->type == C_OUTPUT ?
- old_view : swayc_parent_by_type(old_view, C_OUTPUT);
- swayc_t *focused = get_focused_view(new_view);
- if (set_focused_container(focused)) {
- if (old_op != swayc_active_output() && focused && focused->type == C_VIEW) {
- center_pointer_on(focused);
- }
- return true;
- }
- } else {
- return set_focused_container(get_focused_view(new_view));
- }
- return false;
-}
-
-swayc_t *get_focused_container(swayc_t *parent) {
- if (!parent) {
- return swayc_active_workspace();
- }
- while (!parent->is_focused && parent->focused) {
- parent = parent->focused;
- }
- return parent;
-}
-
-bool set_focused_container(swayc_t *c) {
- if (locked_container_focus || !c || !c->parent) {
- return false;
- }
-
- // current ("old") workspace for sending workspace change event later
- swayc_t *old_ws = swayc_active_workspace();
- // keep track of child count so we can determine if it gets destroyed
- int old_ws_child_count = 0;
- if (old_ws) {
- old_ws_child_count = old_ws->children->length + old_ws->floating->length;
- }
-
- // current ("old") focused container
- swayc_t *old_focus = get_focused_container(&root_container);
- // if old_focus is a workspace, then it's the same workspace as
- // old_ws, and we'll need to null its pointer too, since it will
- // be destroyed in the update_focus() call
- bool old_focus_was_ws = (old_focus->type == C_WORKSPACE);
-
- // workspace of new focused container
- swayc_t *workspace = swayc_active_workspace_for(c);
-
- if (swayc_is_fullscreen(get_focused_container(workspace))) {
- // if switching to a workspace with a fullscreen view,
- // focus on the fullscreen view
- c = get_focused_container(workspace);
- }
-
- swayc_log(L_DEBUG, c, "Setting focus to %p:%" PRIuPTR, c, c->handle);
-
- if (c->type == C_VIEW) {
- // dispatch a window event
- ipc_event_window(c, "focus");
- }
-
- // update the global pointer
- current_focus = c;
-
- // update container focus from here to root, making necessary changes along
- // the way
- swayc_t *p = c;
- if (p->type != C_OUTPUT && p->type != C_ROOT) {
- p->is_focused = true;
- }
- while (p != &root_container) {
- update_focus(p);
- p = p->parent;
- p->is_focused = false;
- }
-
- if (old_focus_was_ws && old_ws_child_count == 0) {
- // this workspace was destroyed in update_focus(), so null the pointers
- old_focus = NULL;
- old_ws = NULL;
- }
-
- if (!(wlc_view_get_type(p->handle) & WLC_BIT_POPUP)) {
- if (old_focus) {
- if (old_focus->type == C_VIEW) {
- wlc_view_set_state(old_focus->handle, WLC_BIT_ACTIVATED, false);
- }
- update_container_border(old_focus);
- }
- if (c->type == C_VIEW) {
- wlc_view_set_state(c->handle, WLC_BIT_ACTIVATED, true);
- }
- /* TODO WLR
- if (!desktop_shell.is_locked) {
- // If the system is locked, we do everything _but_ actually setting
- // focus. This includes making our internals think that this view is
- // focused.
- wlc_view_focus(c->handle);
- }
- */
- if (c->parent->layout != L_TABBED && c->parent->layout != L_STACKED) {
- update_container_border(c);
- }
-
- swayc_t *parent = swayc_tabbed_stacked_ancestor(c);
- if (parent != NULL) {
- arrange_backgrounds();
- arrange_windows(parent, -1, -1);
- }
- }
-
- if (old_ws != workspace) {
- // old_ws might be NULL here but that's ok
- ipc_event_workspace(old_ws, workspace, "focus");
- }
-
- return true;
-}
-
-bool set_focused_container_for(swayc_t *a, swayc_t *c) {
- if (locked_container_focus || !c) {
- return false;
- }
- swayc_t *find = c;
- while (find != a && (find = find->parent)) {
- if (find == &root_container) {
- return false;
- }
- }
-
- // Get workspace for c, get that workspaces current focused container.
- swayc_t *workspace = swayc_active_workspace_for(c);
- swayc_t *focused = get_focused_view(workspace);
- // if the workspace we are changing focus to has a fullscreen view return
- if (swayc_is_fullscreen(focused) && c != focused) {
- return false;
- }
-
- // Check if we are changing a parent container that will see change
- bool effective = true;
- while (find != &root_container) {
- if (find->parent->focused != find) {
- effective = false;
- }
- find = find->parent;
- }
- if (effective) {
- // Go to set_focused_container
- return set_focused_container(c);
- }
-
- sway_log(L_DEBUG, "Setting focus for %p:%" PRIuPTR " to %p:%" PRIuPTR,
- a, a->handle, c, c->handle);
-
- c->is_focused = true;
- swayc_t *p = c;
- while (p != a) {
- update_focus(p);
- p = p->parent;
- p->is_focused = false;
- }
- return true;
-}
-
-swayc_t *get_focused_view(swayc_t *parent) {
- swayc_t *c = parent;
- while (c && c->type != C_VIEW) {
- if (c->type == C_WORKSPACE && c->focused == NULL) {
- return c;
- }
- c = c->focused;
- }
- if (c == NULL) {
- c = swayc_active_workspace_for(parent);
- }
- return c;
-}
-
-swayc_t *get_focused_float(swayc_t *ws) {
- if(!sway_assert(ws->type == C_WORKSPACE, "must be of workspace type")) {
- ws = swayc_active_workspace();
- }
- if (ws->floating->length) {
- return ws->floating->items[ws->floating->length - 1];
- }
- return NULL;
-}
-
-swayc_t *get_focused_view_include_floating(swayc_t *parent) {
- swayc_t *c = parent;
- swayc_t *f = NULL;
-
- while (c && c->type != C_VIEW) {
- if (c->type == C_WORKSPACE && c->focused == NULL) {
- return ((f = get_focused_float(c))) ? f : c;
- }
-
- c = c->focused;
- }
-
- if (c == NULL) {
- c = swayc_active_workspace_for(parent);
- }
-
- return c;
-}
diff --git a/sway/old/handlers.c b/sway/old/handlers.c
deleted file mode 100644
index 33e75d6b..00000000
--- a/sway/old/handlers.c
+++ /dev/null
@@ -1,1143 +0,0 @@
-#define _XOPEN_SOURCE 500
-#include <xkbcommon/xkbcommon.h>
-#include <strings.h>
-#include <stdlib.h>
-#include <stdbool.h>
-#include <libinput.h>
-#include <math.h>
-#include <wlc/wlc.h>
-#include <wlc/wlc-render.h>
-#include <wlc/wlc-wayland.h>
-#include <ctype.h>
-#include "sway/handlers.h"
-#include "sway/border.h"
-#include "sway/layout.h"
-#include "sway/config.h"
-#include "sway/commands.h"
-#include "sway/workspace.h"
-#include "sway/container.h"
-#include "sway/output.h"
-#include "sway/focus.h"
-#include "sway/input_state.h"
-#include "sway/extensions.h"
-#include "sway/criteria.h"
-#include "sway/ipc-server.h"
-#include "sway/input.h"
-#include "sway/security.h"
-#include "list.h"
-#include "stringop.h"
-#include "log.h"
-
-// Event should be sent to client
-#define EVENT_PASSTHROUGH false
-
-// Event handled by sway and should not be sent to client
-#define EVENT_HANDLED true
-
-static struct panel_config *if_panel_find_config(struct wl_client *client) {
- int i;
- for (i = 0; i < desktop_shell.panels->length; i++) {
- struct panel_config *config = desktop_shell.panels->items[i];
- if (config->client == client) {
- return config;
- }
- }
- return NULL;
-}
-
-static struct background_config *if_background_find_config(struct wl_client *client) {
- int i;
- for (i = 0; i < desktop_shell.backgrounds->length; i++) {
- struct background_config *config = desktop_shell.backgrounds->items[i];
- if (config->client == client) {
- return config;
- }
- }
- return NULL;
-}
-
-static struct wlc_geometry compute_panel_geometry(struct panel_config *config) {
- struct wlc_size resolution;
- output_get_scaled_size(config->output, &resolution);
- const struct wlc_geometry *old = wlc_view_get_geometry(config->handle);
- struct wlc_geometry new;
-
- switch (config->panel_position) {
- case DESKTOP_SHELL_PANEL_POSITION_TOP:
- new.origin.x = 0;
- new.origin.y = 0;
- new.size.w = resolution.w;
- new.size.h = old->size.h;
- break;
- case DESKTOP_SHELL_PANEL_POSITION_BOTTOM:
- new.origin.x = 0;
- new.origin.y = resolution.h - old->size.h;
- new.size.w = resolution.w;
- new.size.h = old->size.h;
- break;
- case DESKTOP_SHELL_PANEL_POSITION_LEFT:
- new.origin.x = 0;
- new.origin.y = 0;
- new.size.w = old->size.w;
- new.size.h = resolution.h;
- break;
- case DESKTOP_SHELL_PANEL_POSITION_RIGHT:
- new.origin.x = resolution.w - old->size.w;
- new.origin.y = 0;
- new.size.w = old->size.w;
- new.size.h = resolution.h;
- break;
- }
-
- return new;
-}
-
-static void update_panel_geometry(struct panel_config *config) {
- struct wlc_geometry geometry = compute_panel_geometry(config);
- wlc_view_set_geometry(config->handle, 0, &geometry);
-}
-
-static void update_panel_geometries(wlc_handle output) {
- for (int i = 0; i < desktop_shell.panels->length; i++) {
- struct panel_config *config = desktop_shell.panels->items[i];
- if (config->output == output) {
- update_panel_geometry(config);
- }
- }
-}
-
-static void update_background_geometry(struct background_config *config) {
- struct wlc_geometry geometry = wlc_geometry_zero;
- output_get_scaled_size(config->output, &geometry.size);
- wlc_view_set_geometry(config->handle, 0, &geometry);
-}
-
-static void update_background_geometries(wlc_handle output) {
- for (int i = 0; i < desktop_shell.backgrounds->length; i++) {
- struct background_config *config = desktop_shell.backgrounds->items[i];
- if (config->output == output) {
- update_background_geometry(config);
- }
- }
-}
-
-/* Handles */
-
-static bool handle_input_created(struct libinput_device *device) {
- const char *identifier = libinput_dev_unique_id(device);
- if (!identifier) {
- sway_log(L_ERROR, "Unable to allocate unique name for input device %p",
- device);
- return true;
- }
- sway_log(L_INFO, "Found input device (%s)", identifier);
-
- list_add(input_devices, device);
-
- struct input_config *ic = NULL;
- int i;
- for (i = 0; i < config->input_configs->length; ++i) {
- struct input_config *cur = config->input_configs->items[i];
- if (strcasecmp(identifier, cur->identifier) == 0) {
- sway_log(L_DEBUG, "Matched input config for %s",
- identifier);
- ic = cur;
- break;
- }
- if (strcasecmp("*", cur->identifier) == 0) {
- sway_log(L_DEBUG, "Matched wildcard input config for %s",
- identifier);
- ic = cur;
- break;
- }
- }
-
- apply_input_config(ic, device);
- return true;
-}
-
-static void handle_input_destroyed(struct libinput_device *device) {
- int i;
- list_t *list = input_devices;
- for (i = 0; i < list->length; ++i) {
- if(((struct libinput_device *)list->items[i]) == device) {
- list_del(list, i);
- break;
- }
- }
-}
-
-static bool handle_output_created(wlc_handle output) {
- swayc_t *op = new_output(output);
-
- // Visibility mask to be able to make view invisible
- wlc_output_set_mask(output, VISIBLE);
-
- if (!op) {
- return false;
- }
-
- // Switch to workspace if we need to
- if (swayc_active_workspace() == NULL) {
- swayc_t *ws = op->children->items[0];
- workspace_switch(ws);
- }
-
- // Fixes issues with backgrounds and wlc
- wlc_handle prev = wlc_get_focused_output();
- wlc_output_focus(output);
- wlc_output_focus(prev);
- return true;
-}
-
-static void handle_output_destroyed(wlc_handle output) {
- int i;
- list_t *list = root_container.children;
- for (i = 0; i < list->length; ++i) {
- if (((swayc_t *)list->items[i])->handle == output) {
- break;
- }
- }
- if (i < list->length) {
- destroy_output(list->items[i]);
- } else {
- return;
- }
- if (list->length > 0) {
- // switch to other outputs active workspace
- workspace_switch(((swayc_t *)root_container.children->items[0])->focused);
- }
-}
-
-static void handle_output_post_render(wlc_handle output) {
- ipc_get_pixels(output);
-}
-
-static void handle_view_pre_render(wlc_handle view) {
- render_view_borders(view);
-}
-
-static void handle_output_resolution_change(wlc_handle output, const struct wlc_size *from, const struct wlc_size *to) {
- sway_log(L_DEBUG, "Output %u resolution changed to %d x %d", (unsigned int)output, to->w, to->h);
-
- swayc_t *c = swayc_by_handle(output);
- if (!c) {
- return;
- }
- c->width = to->w;
- c->height = to->h;
-
- update_panel_geometries(output);
- update_background_geometries(output);
-
- arrange_windows(&root_container, -1, -1);
-}
-
-static void handle_output_focused(wlc_handle output, bool focus) {
- swayc_t *c = swayc_by_handle(output);
- // if for some reason this output doesn't exist, create it.
- if (!c) {
- handle_output_created(output);
- }
- if (focus) {
- set_focused_container(get_focused_container(c));
- }
-}
-
-static void ws_cleanup() {
- swayc_t *op, *ws;
- int i = 0, j;
- if (!root_container.children)
- return;
- while (i < root_container.children->length) {
- op = root_container.children->items[i++];
- if (!op->children)
- continue;
- j = 0;
- while (j < op->children->length) {
- ws = op->children->items[j++];
- if (ws->children->length == 0 && ws->floating->length == 0 && ws != op->focused) {
- if (destroy_workspace(ws)) {
- j--;
- }
- }
- }
- }
-}
-
-static void positioner_place_window(wlc_handle handle) {
- const struct wlc_geometry *anchor = wlc_view_positioner_get_anchor_rect(handle);
- const struct wlc_size *sr = wlc_view_positioner_get_size(handle);
- // a positioner is required to have a non-null anchor and a non-negative size
- if (!anchor || !sr ||
- sr->w <= 0 || sr->h <= 0 ||
- anchor->size.w <= 0 || anchor->size.h <= 0) {
- return;
- }
- const struct wlc_point offset = *wlc_view_positioner_get_offset(handle);
- enum wlc_positioner_anchor_bit anchors = wlc_view_positioner_get_anchor(handle);
- enum wlc_positioner_gravity_bit gravity = wlc_view_positioner_get_gravity(handle);
- struct wlc_geometry geo = {
- .origin = offset,
- .size = *sr
- };
-
- if (anchors & WLC_BIT_ANCHOR_TOP) {
- geo.origin.y += anchor->origin.y;
- } else if (anchors & WLC_BIT_ANCHOR_BOTTOM) {
- geo.origin.y += anchor->origin.y + anchor->size.h;
- } else {
- geo.origin.y += anchor->origin.y + anchor->size.h / 2;
- }
- if (anchors & WLC_BIT_ANCHOR_LEFT) {
- geo.origin.x += anchor->origin.x;
- } else if (anchors & WLC_BIT_ANCHOR_RIGHT) {
- geo.origin.x += anchor->origin.x + anchor->size.w;
- } else {
- geo.origin.x += anchor->origin.x + anchor->size.w / 2;
- }
-
- if (gravity & WLC_BIT_GRAVITY_TOP) {
- geo.origin.y -= geo.size.h;
- } else if (gravity & WLC_BIT_GRAVITY_BOTTOM) {
- /* default */
- } else {
- geo.origin.y -= geo.size.h / 2;
- }
- if (gravity & WLC_BIT_GRAVITY_LEFT) {
- geo.origin.x -= geo.size.w;
- } else if (gravity & WLC_BIT_GRAVITY_RIGHT) {
- /* default */
- } else {
- geo.origin.x -= geo.size.w / 2;
- }
-
- sway_log(L_DEBUG, "xdg-positioner: placing window %" PRIuPTR " "
- "sized (%u,%u) offset by (%d,%d), "
- "anchor rectangle sized (%u,%u) at (%d,%d), "
- "anchor edges: %s %s, gravity: %s %s",
- handle,
- sr->w, sr->h, offset.x, offset.y,
- anchor->size.w, anchor->size.h, anchor->origin.x, anchor->origin.y,
- anchors & WLC_BIT_ANCHOR_TOP ? "top" :
- (anchors & WLC_BIT_ANCHOR_BOTTOM ? "bottom" : "middle"),
- anchors & WLC_BIT_ANCHOR_LEFT ? "left" :
- (anchors & WLC_BIT_ANCHOR_RIGHT ? "right" : "center"),
- gravity & WLC_BIT_GRAVITY_TOP ? "top" :
- (gravity & WLC_BIT_GRAVITY_BOTTOM ? "bottom" : "middle"),
- gravity & WLC_BIT_GRAVITY_LEFT ? "left" :
- (gravity & WLC_BIT_GRAVITY_RIGHT ? "right" : "center"));
-
- wlc_handle parent = wlc_view_get_parent(handle);
- if (parent) {
- const struct wlc_geometry *pg = wlc_view_get_geometry(parent);
- geo.origin.x += pg->origin.x;
- geo.origin.y += pg->origin.y;
- }
- wlc_view_set_geometry(handle, 0, &geo);
-}
-
-static bool handle_view_created(wlc_handle handle) {
- // if view is child of another view, the use that as focused container
- wlc_handle parent = wlc_view_get_parent(handle);
- swayc_t *focused = NULL;
- swayc_t *newview = NULL;
- swayc_t *current_ws = swayc_active_workspace();
- bool return_to_workspace = false;
- struct wl_client *client = wlc_view_get_wl_client(handle);
- struct wl_resource *resource = wlc_surface_get_wl_resource(
- wlc_view_get_surface(handle));
- pid_t pid;
- struct panel_config *panel_config = NULL;
- struct background_config *background_config = NULL;
-
- panel_config = if_panel_find_config(client);
- if (panel_config) {
- panel_config->handle = handle;
- update_panel_geometry(panel_config);
- wlc_view_set_mask(handle, VISIBLE);
- wlc_view_set_output(handle, panel_config->output);
- wlc_view_bring_to_front(handle);
- arrange_windows(&root_container, -1, -1);
- return true;
- }
-
- background_config = if_background_find_config(client);
- if (background_config) {
- background_config->handle = handle;
- update_background_geometry(background_config);
- wlc_view_set_mask(handle, VISIBLE);
- wlc_view_set_output(handle, background_config->output);
- wlc_view_send_to_back(handle);
- return true;
- }
-
- // Get parent container, to add view in
- if (parent) {
- focused = swayc_by_handle(parent);
- }
-
- if (client) {
- pid = wlc_view_get_pid(handle);
-
- if (pid) {
- // using newview as a temp storage location here,
- // rather than adding yet another workspace var
- newview = workspace_for_pid(pid);
- if (newview) {
- focused = get_focused_container(newview);
- return_to_workspace = true;
- }
- newview = NULL;
- }
- }
-
- swayc_t *prev_focus = get_focused_container(&root_container);
-
- if (!focused || focused->type == C_OUTPUT) {
- focused = prev_focus;
- // Move focus from floating view
- if (focused->is_floating) {
- // To workspace if there are no children
- if (focused->parent->children->length == 0) {
- focused = focused->parent;
- }
- // TODO find a better way of doing this
- // Or to focused container
- else {
- focused = get_focused_container(focused->parent->children->items[0]);
- }
- }
- }
-
- positioner_place_window(handle);
-
- sway_log(L_DEBUG, "handle:%" PRIuPTR " type:%x state:%x parent:%" PRIuPTR " "
- "mask:%d (x:%d y:%d w:%d h:%d) title:%s "
- "class:%s appid:%s",
- handle, wlc_view_get_type(handle), wlc_view_get_state(handle), parent,
- wlc_view_get_mask(handle), wlc_view_get_geometry(handle)->origin.x,
- wlc_view_get_geometry(handle)->origin.y,wlc_view_get_geometry(handle)->size.w,
- wlc_view_get_geometry(handle)->size.h, wlc_view_get_title(handle),
- wlc_view_get_class(handle), wlc_view_get_app_id(handle));
-
- // TODO properly figure out how each window should be handled.
- switch (wlc_view_get_type(handle)) {
- // regular view created regularly
- case 0:
- if (parent) {
- newview = new_floating_view(handle);
- } else {
- newview = new_view(focused, handle);
- wlc_view_set_state(handle, WLC_BIT_MAXIMIZED, true);
- }
- break;
-
- // Dmenu keeps viewfocus, but others with this flag don't, for now simulate
- // dmenu
- case WLC_BIT_OVERRIDE_REDIRECT:
- wlc_view_focus(handle);
- wlc_view_set_state(handle, WLC_BIT_ACTIVATED, true);
- wlc_view_bring_to_front(handle);
- break;
-
- // Firefox popups have this flag set.
- case WLC_BIT_OVERRIDE_REDIRECT|WLC_BIT_UNMANAGED:
- wlc_view_bring_to_front(handle);
- locked_container_focus = true;
- break;
-
- // Modals, get focus, popups do not
- case WLC_BIT_MODAL:
- wlc_view_focus(handle);
- wlc_view_bring_to_front(handle);
- newview = new_floating_view(handle);
- /* fallthrough */
- case WLC_BIT_POPUP:
- wlc_view_bring_to_front(handle);
- break;
- }
-
- // Prevent current ws from being destroyed, if empty
- suspend_workspace_cleanup = true;
-
- if (newview) {
- ipc_event_window(newview, "new");
- set_focused_container(newview);
- wlc_view_set_mask(handle, VISIBLE);
- swayc_t *output = swayc_parent_by_type(newview, C_OUTPUT);
- arrange_windows(output, -1, -1);
- // check if it matches for_window in config and execute if so
- list_t *criteria = criteria_for(newview);
- for (int i = 0; i < criteria->length; i++) {
- struct criteria *crit = criteria->items[i];
- sway_log(L_DEBUG, "for_window '%s' matches new view %p, cmd: '%s'",
- crit->crit_raw, newview, crit->cmdlist);
- struct cmd_results *res = handle_command(crit->cmdlist, CONTEXT_CRITERIA);
- if (res->status != CMD_SUCCESS) {
- sway_log(L_ERROR, "Command '%s' failed: %s", res->input, res->error);
- }
- free_cmd_results(res);
- // view must be focused for commands to affect it, so always
- // refocus in-between command lists
- set_focused_container(newview);
- }
- swayc_t *workspace = swayc_parent_by_type(focused, C_WORKSPACE);
- if (workspace && workspace->fullscreen) {
- set_focused_container(workspace->fullscreen);
- }
- for (int i = 0; i < decoration_state.csd_resources->length; ++i) {
- struct wl_resource *res = decoration_state.csd_resources->items[i];
- if (res == resource) {
- list_del(decoration_state.csd_resources, i);
- server_decoration_enable_csd(handle);
- break;
- }
- }
- } else {
- swayc_t *output = swayc_parent_by_type(focused, C_OUTPUT);
- wlc_handle *h = malloc(sizeof(wlc_handle));
- if (!h) {
- sway_log(L_ERROR, "Unable to allocate window handle, view handler bailing out");
- return true;
- }
- *h = handle;
- sway_log(L_DEBUG, "Adding unmanaged window %p to %p", h, output->unmanaged);
- list_add(output->unmanaged, h);
- wlc_view_set_mask(handle, VISIBLE);
- }
-
- if (return_to_workspace && current_ws != swayc_active_workspace()) {
- // we were on one workspace, switched to another to add this view,
- // now let's return to where we were
- workspace_switch(current_ws);
- set_focused_container(get_focused_container(current_ws));
- }
- if (prev_focus && prev_focus->type == C_VIEW
- && newview && criteria_any(newview, config->no_focus)) {
- // Restore focus
- swayc_t *ws = swayc_parent_by_type(newview, C_WORKSPACE);
- if (!ws || ws != newview->parent
- || ws->children->length + ws->floating->length != 1) {
- sway_log(L_DEBUG, "no_focus: restoring focus to %s", prev_focus->name);
- set_focused_container(prev_focus);
- }
- }
-
- suspend_workspace_cleanup = false;
- ws_cleanup();
- return true;
-}
-
-static void handle_view_destroyed(wlc_handle handle) {
- sway_log(L_DEBUG, "Destroying window %" PRIuPTR, handle);
- swayc_t *view = swayc_by_handle(handle);
-
- // destroy views by type
- switch (wlc_view_get_type(handle)) {
- // regular view created regularly
- case 0:
- case WLC_BIT_MODAL:
- case WLC_BIT_POPUP:
- break;
- // DMENU has this flag, and takes view_focus, but other things with this
- // flag don't
- case WLC_BIT_OVERRIDE_REDIRECT:
- break;
- case WLC_BIT_OVERRIDE_REDIRECT|WLC_BIT_UNMANAGED:
- locked_container_focus = false;
- break;
- }
-
- if (view) {
- bool fullscreen = swayc_is_fullscreen(view);
- remove_view_from_scratchpad(view);
- swayc_t *parent = destroy_view(view), *iter = NULL;
- if (parent) {
- ipc_event_window(parent, "close");
-
- // Destroy empty workspaces
- if (parent->type == C_WORKSPACE &&
- parent->children->length == 0 &&
- parent->floating->length == 0 &&
- swayc_active_workspace() != parent &&
- !parent->visible) {
- parent = destroy_workspace(parent);
- }
-
- if (fullscreen) {
- iter = parent;
- while (iter) {
- if (iter->fullscreen) {
- iter->fullscreen = NULL;
- break;
- }
- iter = iter->parent;
- }
- }
-
-
- arrange_windows(iter ? iter : parent, -1, -1);
- }
- } else {
- // Is it unmanaged?
- int i;
- for (i = 0; i < root_container.children->length; ++i) {
- swayc_t *output = root_container.children->items[i];
- int j;
- for (j = 0; j < output->unmanaged->length; ++j) {
- wlc_handle *_handle = output->unmanaged->items[j];
- if (*_handle == handle) {
- list_del(output->unmanaged, j);
- free(_handle);
- break;
- }
- }
- }
- // Is it in the scratchpad?
- for (i = 0; i < scratchpad->length; ++i) {
- swayc_t *item = scratchpad->items[i];
- if (item->handle == handle) {
- list_del(scratchpad, i);
- destroy_view(item);
- break;
- }
- }
- }
- set_focused_container(get_focused_view(&root_container));
-}
-
-static void handle_view_focus(wlc_handle view, bool focus) {
- return;
-}
-
-static void handle_view_geometry_request(wlc_handle handle, const struct wlc_geometry *geometry) {
- sway_log(L_DEBUG, "geometry request for %" PRIuPTR " %dx%d @ %d,%d", handle,
- geometry->size.w, geometry->size.h, geometry->origin.x, geometry->origin.y);
- // If the view is floating, then apply the geometry.
- // Otherwise save the desired width/height for the view.
- // This will not do anything for the time being as WLC improperly sends geometry requests
- swayc_t *view = swayc_by_handle(handle);
- if (view) {
- view->desired_width = geometry->size.w;
- view->desired_height = geometry->size.h;
-
- if (view->is_floating) {
- floating_view_sane_size(view);
- view->width = view->desired_width;
- view->height = view->desired_height;
- view->x = geometry->origin.x;
- view->y = geometry->origin.y;
- update_geometry(view);
- }
- } else {
- wlc_view_set_geometry(handle, 0, geometry);
- }
-}
-
-static void handle_view_state_request(wlc_handle view, enum wlc_view_state_bit state, bool toggle) {
- swayc_t *c = swayc_by_handle(view);
- pid_t pid = wlc_view_get_pid(view);
- switch (state) {
- case WLC_BIT_FULLSCREEN:
- if (!(get_feature_policy_mask(pid) & FEATURE_FULLSCREEN)) {
- sway_log(L_INFO, "Denying fullscreen to %d (%s)", pid, c->name);
- break;
- }
- // i3 just lets it become fullscreen
- wlc_view_set_state(view, state, toggle);
- if (c) {
- sway_log(L_DEBUG, "setting view %" PRIuPTR " %s, fullscreen %d", view, c->name, toggle);
- arrange_windows(c->parent, -1, -1);
- // Set it as focused window for that workspace if its going fullscreen
- swayc_t *ws = swayc_parent_by_type(c, C_WORKSPACE);
- if (toggle) {
- // Set ws focus to c
- set_focused_container_for(ws, c);
- ws->fullscreen = c;
- } else {
- ws->fullscreen = NULL;
- }
- }
- break;
- case WLC_BIT_MAXIMIZED:
- case WLC_BIT_RESIZING:
- case WLC_BIT_MOVING:
- break;
- case WLC_BIT_ACTIVATED:
- sway_log(L_DEBUG, "View %p requested to be activated", c);
- break;
- }
- return;
-}
-
-static void handle_view_properties_updated(wlc_handle view, uint32_t mask) {
- if (mask == WLC_BIT_PROPERTY_TITLE) {
- swayc_t *c = swayc_by_handle(view);
- if (!c) {
- return;
- }
-
- // update window title
- const char *new_name = wlc_view_get_title(view);
-
- if (new_name) {
- if (!c->name || strcmp(c->name, new_name) != 0) {
- free(c->name);
- c->name = strdup(new_name);
- swayc_t *p = swayc_tabbed_stacked_ancestor(c);
- if (p) {
- // TODO: we only got the topmost tabbed/stacked container, update borders of all containers on the path
- update_container_border(get_focused_view(p));
- } else if (c->border_type == B_NORMAL) {
- update_container_border(c);
- }
- ipc_event_window(c, "title");
- }
- }
- }
-}
-
-static void handle_binding_command(struct sway_binding *binding) {
- struct sway_binding *binding_copy = binding;
- bool reload = false;
- // if this is a reload command we need to make a duplicate of the
- // binding since it will be gone after the reload has completed.
- if (strcasecmp(binding->command, "reload") == 0) {
- binding_copy = sway_binding_dup(binding);
- if (!binding_copy) {
- sway_log(L_ERROR, "Unable to duplicate binding during reload");
- return;
- }
- reload = true;
- }
-
- struct cmd_results *res = handle_command(binding->command, CONTEXT_BINDING);
- if (res->status != CMD_SUCCESS) {
- sway_log(L_ERROR, "Command '%s' failed: %s", res->input, res->error);
- }
- ipc_event_binding_keyboard(binding_copy);
-
- if (reload) { // free the binding if we made a copy
- free_sway_binding(binding_copy);
- }
-
- free_cmd_results(res);
-}
-
-static bool handle_bindsym(struct sway_binding *binding, uint32_t keysym, uint32_t keycode) {
- int i;
- for (i = 0; i < binding->keys->length; ++i) {
- if (binding->bindcode) {
- xkb_keycode_t *key = binding->keys->items[i];
- if (keycode == *key) {
- handle_binding_command(binding);
- return true;
- }
- } else {
- xkb_keysym_t *key = binding->keys->items[i];
- if (keysym == *key) {
- handle_binding_command(binding);
- return true;
- }
- }
- }
-
- return false;
-}
-
-static bool valid_bindsym(struct sway_binding *binding) {
- bool match = false;
- int i;
- for (i = 0; i < binding->keys->length; ++i) {
- if (binding->bindcode) {
- xkb_keycode_t *key = binding->keys->items[i];
- if ((match = check_key(0, *key)) == false) {
- break;
- }
- } else {
- xkb_keysym_t *key = binding->keys->items[i];
- if ((match = check_key(*key, 0)) == false) {
- break;
- }
- }
- }
-
- return match;
-}
-
-static bool handle_bindsym_release(struct sway_binding *binding) {
- if (binding->keys->length == 1) {
- xkb_keysym_t *key = binding->keys->items[0];
- if (check_released_key(*key)) {
- handle_binding_command(binding);
- return true;
- }
- }
-
- return false;
-}
-
-static bool handle_key(wlc_handle view, uint32_t time, const struct wlc_modifiers *modifiers,
- uint32_t key, enum wlc_key_state state) {
-
- if (desktop_shell.is_locked) {
- return EVENT_PASSTHROUGH;
- }
-
- // reset pointer mode on keypress
- if (state == WLC_KEY_STATE_PRESSED && pointer_state.mode) {
- pointer_mode_reset();
- }
-
- struct sway_mode *mode = config->current_mode;
-
- struct wlc_modifiers no_mods = { 0, 0 };
- uint32_t sym = tolower(wlc_keyboard_get_keysym_for_key(key, &no_mods));
-
- int i;
-
- if (state == WLC_KEY_STATE_PRESSED) {
- press_key(sym, key);
- } else { // WLC_KEY_STATE_RELEASED
- release_key(sym, key);
- }
-
- // handle bar modifiers pressed/released
- uint32_t modifier;
- for (i = 0; i < config->active_bar_modifiers->length; ++i) {
- modifier = *(uint32_t *)config->active_bar_modifiers->items[i];
-
- switch (modifier_state_changed(modifiers->mods, modifier)) {
- case MOD_STATE_PRESSED:
- ipc_event_modifier(modifier, "pressed");
- break;
- case MOD_STATE_RELEASED:
- ipc_event_modifier(modifier, "released");
- break;
- }
- }
- // update modifiers state
- modifiers_state_update(modifiers->mods);
-
- // handle bindings
- list_t *candidates = create_list();
- for (i = 0; i < mode->bindings->length; ++i) {
- struct sway_binding *binding = mode->bindings->items[i];
- if ((modifiers->mods ^ binding->modifiers) == 0) {
- switch (state) {
- case WLC_KEY_STATE_PRESSED:
- if (!binding->release && valid_bindsym(binding)) {
- list_add(candidates, binding);
- }
- break;
- case WLC_KEY_STATE_RELEASED:
- if (binding->release && handle_bindsym_release(binding)) {
- list_free(candidates);
- return EVENT_HANDLED;
- }
- break;
- }
- }
- }
-
- for (i = 0; i < candidates->length; ++i) {
- struct sway_binding *binding = candidates->items[i];
- if (state == WLC_KEY_STATE_PRESSED) {
- if (!binding->release && handle_bindsym(binding, sym, key)) {
- list_free(candidates);
- return EVENT_HANDLED;
- }
- }
- }
-
- list_free(candidates);
-
- swayc_t *focused = get_focused_container(&root_container);
- if (focused->type == C_VIEW) {
- pid_t pid = wlc_view_get_pid(focused->handle);
- if (!(get_feature_policy_mask(pid) & FEATURE_KEYBOARD)) {
- return EVENT_HANDLED;
- }
- }
- return EVENT_PASSTHROUGH;
-}
-
-static bool handle_pointer_motion(wlc_handle handle, uint32_t time, double x, double y) {
- if (desktop_shell.is_locked) {
- return EVENT_PASSTHROUGH;
- }
-
- double new_x = x;
- double new_y = y;
- // Switch to adjacent output if touching output edge.
- //
- // Since this doesn't currently support moving windows between outputs we
- // don't do the switch if the pointer is in a mode.
- if (config->seamless_mouse && !pointer_state.mode &&
- !pointer_state.left.held && !pointer_state.right.held && !pointer_state.scroll.held) {
-
- swayc_t *output = swayc_active_output(), *adjacent = NULL;
- struct wlc_point abs_pos = { .x = x + output->x, .y = y + output->y };
- if (x <= 0) { // Left edge
- if ((adjacent = swayc_adjacent_output(output, MOVE_LEFT, &abs_pos, false))) {
- if (workspace_switch(swayc_active_workspace_for(adjacent))) {
- new_x = adjacent->width;
- // adjust for differently aligned outputs (well, this is
- // only correct when the two outputs have the same
- // resolution or the same dpi I guess, it should take
- // physical attributes into account)
- new_y += (output->y - adjacent->y);
- }
- }
- } else if (x >= output->width) { // Right edge
- if ((adjacent = swayc_adjacent_output(output, MOVE_RIGHT, &abs_pos, false))) {
- if (workspace_switch(swayc_active_workspace_for(adjacent))) {
- new_x = 0;
- new_y += (output->y - adjacent->y);
- }
- }
- } else if (y <= 0) { // Top edge
- if ((adjacent = swayc_adjacent_output(output, MOVE_UP, &abs_pos, false))) {
- if (workspace_switch(swayc_active_workspace_for(adjacent))) {
- new_y = adjacent->height;
- new_x += (output->x - adjacent->x);
- }
- }
- } else if (y >= output->height) { // Bottom edge
- if ((adjacent = swayc_adjacent_output(output, MOVE_DOWN, &abs_pos, false))) {
- if (workspace_switch(swayc_active_workspace_for(adjacent))) {
- new_y = 0;
- new_x += (output->x - adjacent->x);
- }
- }
- }
- }
-
- pointer_position_set(new_x, new_y, false);
-
- swayc_t *focused = get_focused_container(&root_container);
- if (focused->type == C_VIEW) {
- pid_t pid = wlc_view_get_pid(focused->handle);
- if (!(get_feature_policy_mask(pid) & FEATURE_MOUSE)) {
- return EVENT_HANDLED;
- }
- }
-
- return EVENT_PASSTHROUGH;
-}
-
-static bool swayc_border_check(swayc_t *c, const void *_origin) {
- const struct wlc_point *origin = _origin;
- const struct wlc_geometry title_bar = c->title_bar_geometry;
-
- if (c->border_type != B_NORMAL) {
- return false;
- }
-
- if (origin->x >= title_bar.origin.x && origin->y >= title_bar.origin.y
- && origin->x < title_bar.origin.x + (int32_t)title_bar.size.w
- && origin->y < title_bar.origin.y + (int32_t)title_bar.size.h) {
- return true;
- }
- return false;
-}
-
-static bool handle_pointer_button(wlc_handle view, uint32_t time, const struct wlc_modifiers *modifiers,
- uint32_t button, enum wlc_button_state state, const struct wlc_point *origin) {
-
- // Update view pointer is on
- pointer_state.view = container_under_pointer();
-
- struct sway_mode *mode = config->current_mode;
- // handle bindings
- for (int i = 0; i < mode->bindings->length; ++i) {
- struct sway_binding *binding = mode->bindings->items[i];
- if ((modifiers->mods ^ binding->modifiers) == 0) {
- switch (state) {
- case WLC_BUTTON_STATE_PRESSED:
- if (!binding->release && handle_bindsym(binding, button, 0)) {
- return EVENT_HANDLED;
- }
- break;
- case WLC_BUTTON_STATE_RELEASED:
- if (binding->release && handle_bindsym(binding, button, 0)) {
- return EVENT_HANDLED;
- }
- break;
- }
- }
- }
-
- // Update pointer_state
- switch (button) {
- case M_LEFT_CLICK:
- if (state == WLC_BUTTON_STATE_PRESSED) {
- pointer_state.left.held = true;
- pointer_state.left.x = origin->x;
- pointer_state.left.y = origin->y;
- pointer_state.left.view = pointer_state.view;
- } else {
- pointer_state.left.held = false;
- }
- break;
-
- case M_RIGHT_CLICK:
- if (state == WLC_BUTTON_STATE_PRESSED) {
- pointer_state.right.held = true;
- pointer_state.right.x = origin->x;
- pointer_state.right.y = origin->y;
- pointer_state.right.view = pointer_state.view;
- } else {
- pointer_state.right.held = false;
- }
- break;
-
- case M_SCROLL_CLICK:
- if (state == WLC_BUTTON_STATE_PRESSED) {
- pointer_state.scroll.held = true;
- pointer_state.scroll.x = origin->x;
- pointer_state.scroll.y = origin->y;
- pointer_state.scroll.view = pointer_state.view;
- } else {
- pointer_state.scroll.held = false;
- }
- break;
-
- //TODO scrolling behavior
- case M_SCROLL_UP:
- case M_SCROLL_DOWN:
- break;
- }
-
- // get focused window and check if to change focus on mouse click
- swayc_t *focused = get_focused_container(&root_container);
-
- // don't change focus or mode if fullscreen
- if (swayc_is_fullscreen(focused)) {
- if (focused->type == C_VIEW) {
- pid_t pid = wlc_view_get_pid(focused->handle);
- if (!(get_feature_policy_mask(pid) & FEATURE_MOUSE)) {
- return EVENT_HANDLED;
- }
- }
- return EVENT_PASSTHROUGH;
- }
-
- // set pointer mode only if floating mod has been set
- if (config->floating_mod) {
- pointer_mode_set(button, !(modifiers->mods ^ config->floating_mod));
- }
-
- // Check whether to change focus
- swayc_t *pointer = pointer_state.view;
- if (pointer) {
- swayc_t *ws = swayc_parent_by_type(focused, C_WORKSPACE);
- if (ws != NULL) {
- swayc_t *find = container_find(ws, &swayc_border_check, origin);
- if (find != NULL) {
- set_focused_container(find);
- return EVENT_HANDLED;
- }
- }
-
- if (focused != pointer) {
- set_focused_container(pointer_state.view);
- }
- // Send to front if floating
- if (pointer->is_floating) {
- int i;
- for (i = 0; i < pointer->parent->floating->length; i++) {
- if (pointer->parent->floating->items[i] == pointer) {
- list_del(pointer->parent->floating, i);
- list_add(pointer->parent->floating, pointer);
- break;
- }
- }
- wlc_view_bring_to_front(pointer->handle);
- }
- }
-
- // Return if mode has been set
- if (pointer_state.mode) {
- return EVENT_HANDLED;
- }
-
- if (focused->type == C_VIEW) {
- pid_t pid = wlc_view_get_pid(focused->handle);
- if (!(get_feature_policy_mask(pid) & FEATURE_MOUSE)) {
- return EVENT_HANDLED;
- }
- }
-
- // Always send mouse release
- if (state == WLC_BUTTON_STATE_RELEASED) {
- return EVENT_PASSTHROUGH;
- }
-
- // Finally send click
- return EVENT_PASSTHROUGH;
-}
-
-bool handle_pointer_scroll(wlc_handle view, uint32_t time, const struct wlc_modifiers* modifiers,
- uint8_t axis_bits, double _amount[2]) {
- if (!(modifiers->mods ^ config->floating_mod)) {
- int x_amount = (int)_amount[0];
- int y_amount = (int)_amount[1];
-
- if (x_amount > 0 && strcmp(config->floating_scroll_up_cmd, "")) {
- handle_command(config->floating_scroll_up_cmd, CONTEXT_BINDING);
- return EVENT_HANDLED;
- } else if (x_amount < 0 && strcmp(config->floating_scroll_down_cmd, "")) {
- handle_command(config->floating_scroll_down_cmd, CONTEXT_BINDING);
- return EVENT_HANDLED;
- }
-
- if (y_amount > 0 && strcmp(config->floating_scroll_right_cmd, "")) {
- handle_command(config->floating_scroll_right_cmd, CONTEXT_BINDING);
- return EVENT_HANDLED;
- } else if (y_amount < 0 && strcmp(config->floating_scroll_left_cmd, "")) {
- handle_command(config->floating_scroll_left_cmd, CONTEXT_BINDING);
- return EVENT_HANDLED;
- }
- }
- return EVENT_PASSTHROUGH;
-}
-
-static void handle_wlc_ready(void) {
- sway_log(L_DEBUG, "Compositor is ready, executing cmds in queue");
- // Execute commands until there are none left
- config->active = true;
- while (config->cmd_queue->length) {
- char *line = config->cmd_queue->items[0];
- struct cmd_results *res = handle_command(line, CONTEXT_CONFIG);
- if (res->status != CMD_SUCCESS) {
- sway_log(L_ERROR, "Error on line '%s': %s", line, res->error);
- }
- free_cmd_results(res);
- free(line);
- list_del(config->cmd_queue, 0);
- }
-}
-
-void register_wlc_handlers() {
- wlc_set_output_created_cb(handle_output_created);
- wlc_set_output_destroyed_cb(handle_output_destroyed);
- wlc_set_output_resolution_cb(handle_output_resolution_change);
- wlc_set_output_focus_cb(handle_output_focused);
- wlc_set_output_render_post_cb(handle_output_post_render);
- wlc_set_view_created_cb(handle_view_created);
- wlc_set_view_destroyed_cb(handle_view_destroyed);
- wlc_set_view_focus_cb(handle_view_focus);
- wlc_set_view_render_pre_cb(handle_view_pre_render);
- wlc_set_view_request_geometry_cb(handle_view_geometry_request);
- wlc_set_view_request_state_cb(handle_view_state_request);
- wlc_set_view_properties_updated_cb(handle_view_properties_updated);
- wlc_set_keyboard_key_cb(handle_key);
- wlc_set_pointer_motion_cb_v2(handle_pointer_motion);
- wlc_set_pointer_button_cb(handle_pointer_button);
- wlc_set_pointer_scroll_cb(handle_pointer_scroll);
- wlc_set_compositor_ready_cb(handle_wlc_ready);
- wlc_set_input_created_cb(handle_input_created);
- wlc_set_input_destroyed_cb(handle_input_destroyed);
-}
diff --git a/sway/old/input_state.c b/sway/old/input_state.c
deleted file mode 100644
index 04aafd37..00000000
--- a/sway/old/input_state.c
+++ /dev/null
@@ -1,490 +0,0 @@
-#include <string.h>
-#include <stdbool.h>
-#include <ctype.h>
-#include "sway/input_state.h"
-#include "sway/config.h"
-#include "log.h"
-
-#define KEY_STATE_MAX_LENGTH 64
-
-struct key_state {
- /*
- * Aims to store state regardless of modifiers.
- * If you press a key, then hold shift, then release the key, we'll
- * get two different key syms, but the same key code. This handles
- * that scenario and makes sure we can use the right bindings.
- */
- uint32_t key_sym;
- uint32_t alt_sym;
- uint32_t key_code;
-};
-
-static struct key_state key_state_array[KEY_STATE_MAX_LENGTH];
-
-static struct key_state last_released;
-
-static uint32_t modifiers_state;
-
-void input_init(void) {
- int i;
- for (i = 0; i < KEY_STATE_MAX_LENGTH; ++i) {
- struct key_state none = { 0, 0, 0 };
- key_state_array[i] = none;
- }
-
- struct key_state none = { 0, 0, 0 };
- last_released = none;
-
- modifiers_state = 0;
-}
-
-uint32_t modifier_state_changed(uint32_t new_state, uint32_t mod) {
- if ((new_state & mod) != 0) { // pressed
- if ((modifiers_state & mod) != 0) { // already pressed
- return MOD_STATE_UNCHANGED;
- } else { // pressed
- return MOD_STATE_PRESSED;
- }
- } else { // not pressed
- if ((modifiers_state & mod) != 0) { // released
- return MOD_STATE_RELEASED;
- } else { // already released
- return MOD_STATE_UNCHANGED;
- }
- }
-}
-
-void modifiers_state_update(uint32_t new_state) {
- modifiers_state = new_state;
-}
-
-static uint8_t find_key(uint32_t key_sym, uint32_t key_code, bool update) {
- int i;
- for (i = 0; i < KEY_STATE_MAX_LENGTH; ++i) {
- if (0 == key_sym && 0 == key_code && key_state_array[i].key_sym == 0) {
- break;
- }
- if (key_sym != 0 && (key_state_array[i].key_sym == key_sym
- || key_state_array[i].alt_sym == key_sym)) {
- break;
- }
- if (update && key_state_array[i].key_code == key_code) {
- key_state_array[i].alt_sym = key_sym;
- break;
- }
- if (key_sym == 0 && key_code != 0 && key_state_array[i].key_code == key_code) {
- break;
- }
- }
- return i;
-}
-
-bool check_key(uint32_t key_sym, uint32_t key_code) {
- return find_key(key_sym, key_code, false) < KEY_STATE_MAX_LENGTH;
-}
-
-bool check_released_key(uint32_t key_sym) {
- return (key_sym != 0
- && (last_released.key_sym == key_sym
- || last_released.alt_sym == key_sym));
-}
-
-void press_key(uint32_t key_sym, uint32_t key_code) {
- if (key_code == 0) {
- return;
- }
- // Check if key exists
- if (!check_key(key_sym, key_code)) {
- // Check that we don't exceed buffer length
- int insert = find_key(0, 0, true);
- if (insert < KEY_STATE_MAX_LENGTH) {
- key_state_array[insert].key_sym = key_sym;
- key_state_array[insert].key_code = key_code;
- }
- }
-}
-
-void release_key(uint32_t key_sym, uint32_t key_code) {
- uint8_t index = find_key(key_sym, key_code, true);
- if (index < KEY_STATE_MAX_LENGTH) {
- last_released.key_sym = key_state_array[index].key_sym;
- last_released.alt_sym = key_state_array[index].alt_sym;
- last_released.key_code = key_state_array[index].key_code;
- struct key_state none = { 0, 0, 0 };
- key_state_array[index] = none;
- }
-}
-
-// Pointer state and mode
-
-struct pointer_state pointer_state;
-
-static struct mode_state {
- // initial view state
- double x, y, w, h;
- swayc_t *ptr;
- // Containers used for resizing horizontally
- struct {
- double w;
- swayc_t *ptr;
- struct {
- double w;
- swayc_t *ptr;
- } parent;
- } horiz;
- // Containers used for resizing vertically
- struct {
- double h;
- swayc_t *ptr;
- struct {
- double h;
- swayc_t *ptr;
- } parent;
- } vert;
-} initial;
-
-static struct {
- bool left;
- bool top;
-} lock;
-
-// initial set/unset
-
-static void set_initial_view(swayc_t *view) {
- initial.ptr = view;
- initial.x = view->x;
- initial.y = view->y;
- initial.w = view->width;
- initial.h = view->height;
-}
-
-static void set_initial_sibling(void) {
- bool reset = true;
- swayc_t *ws = swayc_active_workspace_for(initial.ptr);
- if ((initial.horiz.ptr = get_swayc_in_direction_under(initial.ptr,
- lock.left ? MOVE_RIGHT: MOVE_LEFT, ws))) {
- initial.horiz.w = initial.horiz.ptr->width;
- initial.horiz.parent.ptr = get_swayc_in_direction_under(initial.horiz.ptr,
- lock.left ? MOVE_LEFT : MOVE_RIGHT, ws);
- initial.horiz.parent.w = initial.horiz.parent.ptr->width;
- reset = false;
- }
- if ((initial.vert.ptr = get_swayc_in_direction_under(initial.ptr,
- lock.top ? MOVE_DOWN: MOVE_UP, ws))) {
- initial.vert.h = initial.vert.ptr->height;
- initial.vert.parent.ptr = get_swayc_in_direction_under(initial.vert.ptr,
- lock.top ? MOVE_UP : MOVE_DOWN, ws);
- initial.vert.parent.h = initial.vert.parent.ptr->height;
- reset = false;
- }
- // If nothing will change just undo the mode
- if (reset) {
- pointer_state.mode = 0;
- }
-}
-
-static void reset_initial_view(void) {
- initial.ptr->x = initial.x;
- initial.ptr->y = initial.y;
- initial.ptr->width = initial.w;
- initial.ptr->height = initial.h;
- arrange_windows(initial.ptr, -1, -1);
- pointer_state.mode = 0;
-}
-
-static void reset_initial_sibling(void) {
- initial.horiz.ptr->width = initial.horiz.w;
- initial.horiz.parent.ptr->width = initial.horiz.parent.w;
- initial.vert.ptr->height = initial.vert.h;
- initial.vert.parent.ptr->height = initial.vert.parent.h;
- arrange_windows(initial.horiz.ptr->parent, -1, -1);
- arrange_windows(initial.vert.ptr->parent, -1, -1);
- pointer_state.mode = 0;
-}
-
-void pointer_position_set(double new_x, double new_y, bool force_focus) {
- double x, y;
- wlc_pointer_get_position_v2(&x, &y);
- pointer_state.delta.x = new_x - x;
- pointer_state.delta.y = new_y - y;
-
- wlc_pointer_set_position_v2(new_x, new_y);
-
- // Update view under pointer
- swayc_t *prev_view = pointer_state.view;
- pointer_state.view = container_under_pointer();
-
- // If pointer is in a mode, update it
- if (pointer_state.mode) {
- pointer_mode_update();
- // Otherwise change focus if config is set
- } else if (force_focus || (prev_view != pointer_state.view && config->focus_follows_mouse)) {
- if (pointer_state.view && pointer_state.view->type == C_VIEW) {
- set_focused_container(pointer_state.view);
- }
- }
-}
-
-void center_pointer_on(swayc_t *view) {
- pointer_position_set(view->x + view->width/2, view->y + view->height/2, true);
-}
-
-// Mode set left/right click
-
-static void pointer_mode_set_dragging(void) {
- switch (config->dragging_key) {
- case M_LEFT_CLICK:
- set_initial_view(pointer_state.left.view);
- break;
- case M_RIGHT_CLICK:
- set_initial_view(pointer_state.right.view);
- break;
- }
-
- if (initial.ptr->is_floating) {
- pointer_state.mode = M_DRAGGING | M_FLOATING;
- } else {
- pointer_state.mode = M_DRAGGING | M_TILING;
- // unset mode if we can't drag tile
- if (initial.ptr->parent->type == C_WORKSPACE &&
- initial.ptr->parent->children->length == 1) {
- pointer_state.mode = 0;
- }
- }
-}
-
-static void pointer_mode_set_resizing(void) {
- switch (config->resizing_key) {
- case M_LEFT_CLICK:
- set_initial_view(pointer_state.left.view);
- break;
- case M_RIGHT_CLICK:
- set_initial_view(pointer_state.right.view);
- break;
- }
- // Setup locking information
- int midway_x = initial.ptr->x + initial.ptr->width/2;
- int midway_y = initial.ptr->y + initial.ptr->height/2;
-
- double x, y;
- wlc_pointer_get_position_v2(&x, &y);
- lock.left = x > midway_x;
- lock.top = y > midway_y;
-
- if (initial.ptr->is_floating) {
- pointer_state.mode = M_RESIZING | M_FLOATING;
- } else {
- pointer_state.mode = M_RESIZING | M_TILING;
- set_initial_sibling();
- }
-}
-
-// Mode set/update/reset
-
-void pointer_mode_set(uint32_t button, bool condition) {
- // switch on drag/resize mode
- switch (pointer_state.mode & (M_DRAGGING | M_RESIZING)) {
- case M_DRAGGING:
- // end drag mode when 'dragging' click is unpressed
- if (config->dragging_key == M_LEFT_CLICK && !pointer_state.left.held) {
- pointer_state.mode = 0;
- } else if (config->dragging_key == M_RIGHT_CLICK && !pointer_state.right.held) {
- pointer_state.mode = 0;
- }
- break;
-
- case M_RESIZING:
- // end resize mode when 'resizing' click is unpressed
- if (config->resizing_key == M_LEFT_CLICK && !pointer_state.left.held) {
- pointer_state.mode = 0;
- } else if (config->resizing_key == M_RIGHT_CLICK && !pointer_state.right.held) {
- pointer_state.mode = 0;
- }
- break;
-
- // No mode case
- default:
- // return if failed condition, or no view
- if (!condition || !pointer_state.view) {
- break;
- }
-
- // Set mode depending on current button press
- switch (button) {
- // Start left-click mode
- case M_LEFT_CLICK:
- // if button release don't do anything
- if (pointer_state.left.held) {
- if (config->dragging_key == M_LEFT_CLICK) {
- pointer_mode_set_dragging();
- } else if (config->resizing_key == M_LEFT_CLICK) {
- pointer_mode_set_resizing();
- }
- }
- break;
-
- // Start right-click mode
- case M_RIGHT_CLICK:
- // if button release don't do anyhting
- if (pointer_state.right.held) {
- if (config->dragging_key == M_RIGHT_CLICK) {
- pointer_mode_set_dragging();
- } else if (config->resizing_key == M_RIGHT_CLICK) {
- pointer_mode_set_resizing();
- }
- }
- break;
- }
- }
-}
-
-void pointer_mode_update(void) {
- if (initial.ptr->type != C_VIEW) {
- pointer_state.mode = 0;
- return;
- }
- double x, y;
- wlc_pointer_get_position_v2(&x, &y);
- int dx = x;
- int dy = y;
-
- switch (pointer_state.mode) {
- case M_FLOATING | M_DRAGGING:
- // Update position
- switch (config->dragging_key) {
- case M_LEFT_CLICK:
- dx -= pointer_state.left.x;
- dy -= pointer_state.left.y;
- break;
- case M_RIGHT_CLICK:
- dx -= pointer_state.right.x;
- dy -= pointer_state.right.y;
- break;
- }
-
- if (initial.x + dx != initial.ptr->x) {
- initial.ptr->x = initial.x + dx;
- }
- if (initial.y + dy != initial.ptr->y) {
- initial.ptr->y = initial.y + dy;
- }
- update_geometry(initial.ptr);
- break;
-
- case M_FLOATING | M_RESIZING:
- switch (config->resizing_key) {
- case M_LEFT_CLICK:
- dx -= pointer_state.left.x;
- dy -= pointer_state.left.y;
- initial.ptr = pointer_state.left.view;
- break;
- case M_RIGHT_CLICK:
- dx -= pointer_state.right.x;
- dy -= pointer_state.right.y;
- initial.ptr = pointer_state.right.view;
- break;
- }
-
- if (lock.left) {
- if (initial.w + dx > min_sane_w) {
- initial.ptr->width = initial.w + dx;
- }
- } else { // lock.right
- if (initial.w - dx > min_sane_w) {
- initial.ptr->width = initial.w - dx;
- initial.ptr->x = initial.x + dx;
- }
- }
- if (lock.top) {
- if (initial.h + dy > min_sane_h) {
- initial.ptr->height = initial.h + dy;
- }
- } else { // lock.bottom
- if (initial.h - dy > min_sane_h) {
- initial.ptr->height = initial.h - dy;
- initial.ptr->y = initial.y + dy;
- }
- }
- update_geometry(initial.ptr);
- break;
-
- case M_TILING | M_DRAGGING:
- // swap current view under pointer with dragged view
- if (pointer_state.view && pointer_state.view->type == C_VIEW
- && pointer_state.view != initial.ptr
- && !pointer_state.view->is_floating) {
- // Swap them around
- swap_container(pointer_state.view, initial.ptr);
- swap_geometry(pointer_state.view, initial.ptr);
- update_geometry(pointer_state.view);
- update_geometry(initial.ptr);
- // Set focus back to initial view
- set_focused_container(initial.ptr);
- // Arrange the windows
- arrange_windows(&root_container, -1, -1);
- }
- break;
-
- case M_TILING | M_RESIZING:
- switch (config->resizing_key) {
- case M_LEFT_CLICK:
- dx -= pointer_state.left.x;
- dy -= pointer_state.left.y;
- break;
- case M_RIGHT_CLICK:
- dx -= pointer_state.right.x;
- dy -= pointer_state.right.y;
- break;
- }
-
- // resize if we can
- if (initial.horiz.ptr) {
- if (lock.left) {
- // Check whether its fine to resize
- if (initial.w + dx > min_sane_w && initial.horiz.w - dx > min_sane_w) {
- initial.horiz.ptr->width = initial.horiz.w - dx;
- initial.horiz.parent.ptr->width = initial.horiz.parent.w + dx;
- }
- } else { // lock.right
- if (initial.w - dx > min_sane_w && initial.horiz.w + dx > min_sane_w) {
- initial.horiz.ptr->width = initial.horiz.w + dx;
- initial.horiz.parent.ptr->width = initial.horiz.parent.w - dx;
- }
- }
- arrange_windows(initial.horiz.ptr->parent, -1, -1);
- }
- if (initial.vert.ptr) {
- if (lock.top) {
- if (initial.h + dy > min_sane_h && initial.vert.h - dy > min_sane_h) {
- initial.vert.ptr->height = initial.vert.h - dy;
- initial.vert.parent.ptr->height = initial.vert.parent.h + dy;
- }
- } else { // lock.bottom
- if (initial.h - dy > min_sane_h && initial.vert.h + dy > min_sane_h) {
- initial.vert.ptr->height = initial.vert.h + dy;
- initial.vert.parent.ptr->height = initial.vert.parent.h - dy;
- }
- }
- arrange_windows(initial.vert.ptr->parent, -1, -1);
- }
- default:
- return;
- }
-}
-
-void pointer_mode_reset(void) {
- switch (pointer_state.mode) {
- case M_FLOATING | M_RESIZING:
- case M_FLOATING | M_DRAGGING:
- reset_initial_view();
- break;
-
- case M_TILING | M_RESIZING:
- (void) reset_initial_sibling;
- break;
-
- case M_TILING | M_DRAGGING:
- default:
- break;
- }
-}
diff --git a/sway/old/ipc-json.c b/sway/old/ipc-json.c
deleted file mode 100644
index 1579a2d9..00000000
--- a/sway/old/ipc-json.c
+++ /dev/null
@@ -1,521 +0,0 @@
-#define _POSIX_C_SOURCE 200809L
-#include <json-c/json.h>
-#include <ctype.h>
-#include <string.h>
-#include <stdint.h>
-#include <libinput.h>
-#include <wlr/types/wlr_box.h>
-#include <wlr/types/wlr_output.h>
-#include "sway/output.h"
-#include "sway/container.h"
-#include "sway/input.h"
-#include "sway/ipc-json.h"
-#include "util.h"
-
-static json_object *ipc_json_create_rect(swayc_t *c) {
- json_object *rect = json_object_new_object();
-
- json_object_object_add(rect, "x", json_object_new_int((int32_t)c->x));
- json_object_object_add(rect, "y", json_object_new_int((int32_t)c->y));
-
- struct wlr_box box;
- if (c->type == C_OUTPUT) {
- wlr_output_effective_resolution(c->_handle.output->wlr_output,
- &box.width, &box.height);
- } else {
- box.width = c->width;
- box.width = c->height;
- }
-
- json_object_object_add(rect, "width",
- json_object_new_int((int32_t)box.width));
- json_object_object_add(rect, "height",
- json_object_new_int((int32_t)box.height));
-
- return rect;
-}
-
-static json_object *ipc_json_create_rect_from_geometry(struct wlc_geometry g) {
- json_object *rect = json_object_new_object();
-
- json_object_object_add(rect, "x", json_object_new_int(g.origin.x));
- json_object_object_add(rect, "y", json_object_new_int(g.origin.y));
- json_object_object_add(rect, "width", json_object_new_int(g.size.w));
- json_object_object_add(rect, "height", json_object_new_int(g.size.h));
-
- return rect;
-}
-
-static const char *ipc_json_border_description(swayc_t *c) {
- const char *border;
-
- switch (c->border_type) {
- case B_PIXEL:
- border = "1pixel";
- break;
-
- case B_NORMAL:
- border = "normal";
- break;
-
- case B_NONE: // fallthrough
- default:
- border = "none";
- break;
- }
-
- return border;
-}
-
-static const char *ipc_json_layout_description(enum swayc_layouts l) {
- const char *layout;
-
- switch (l) {
- case L_VERT:
- layout = "splitv";
- break;
-
- case L_HORIZ:
- layout = "splith";
- break;
-
- case L_TABBED:
- layout = "tabbed";
- break;
-
- case L_STACKED:
- layout = "stacked";
- break;
-
- case L_FLOATING:
- layout = "floating";
- break;
-
- case L_NONE: // fallthrough
- case L_LAYOUTS: // fallthrough; this should never happen, I'm just trying to silence compiler warnings
- default:
- layout = "null";
- break;
- }
-
- return layout;
-}
-
-static float ipc_json_child_percentage(swayc_t *c) {
- float percent = 0;
- swayc_t *parent = c->parent;
-
- if (parent) {
- switch (parent->layout) {
- case L_VERT:
- percent = c->height / parent->height;
- break;
-
- case L_HORIZ:
- percent = c->width / parent->width;
- break;
-
- case L_STACKED: // fallthrough
- case L_TABBED: // fallthrough
- percent = 1.0;
- break;
-
- default:
- break;
- }
- }
-
- return percent;
-}
-
-static void ipc_json_describe_output(swayc_t *output, json_object *object) {
- uint32_t scale = wlc_output_get_scale(output->handle);
- json_object_object_add(object, "active", json_object_new_boolean(true));
- json_object_object_add(object, "primary", json_object_new_boolean(false));
- json_object_object_add(object, "layout", json_object_new_string("output"));
- json_object_object_add(object, "type", json_object_new_string("output"));
- json_object_object_add(object, "current_workspace",
- (output->focused) ? json_object_new_string(output->focused->name) : NULL);
- json_object_object_add(object, "scale", json_object_new_int(scale));
-}
-
-static void ipc_json_describe_workspace(swayc_t *workspace, json_object *object) {
- int num = (isdigit(workspace->name[0])) ? atoi(workspace->name) : -1;
- const char *layout = ipc_json_layout_description(workspace->workspace_layout);
-
- json_object_object_add(object, "num", json_object_new_int(num));
- json_object_object_add(object, "output", (workspace->parent) ? json_object_new_string(workspace->parent->name) : NULL);
- json_object_object_add(object, "type", json_object_new_string("workspace"));
- json_object_object_add(object, "layout", (strcmp(layout, "null") == 0) ? NULL : json_object_new_string(layout));
-}
-
-// window is in the scratchpad ? changed : none
-static const char *ipc_json_get_scratchpad_state(swayc_t *c) {
- int i;
- for (i = 0; i < scratchpad->length; i++) {
- if (scratchpad->items[i] == c) {
- return "changed";
- }
- }
- return "none"; // we ignore the fresh value
-}
-
-static void ipc_json_describe_view(swayc_t *c, json_object *object) {
- json_object *props = json_object_new_object();
- json_object_object_add(object, "type", json_object_new_string((c->is_floating) ? "floating_con" : "con"));
-
- wlc_handle parent = wlc_view_get_parent(c->handle);
- json_object_object_add(object, "scratchpad_state",
- json_object_new_string(ipc_json_get_scratchpad_state(c)));
-
- json_object_object_add(object, "name", (c->name) ? json_object_new_string(c->name) : NULL);
-
- json_object_object_add(props, "class", c->class ? json_object_new_string(c->class) :
- c->app_id ? json_object_new_string(c->app_id) : NULL);
- json_object_object_add(props, "instance", c->instance ? json_object_new_string(c->instance) :
- c->app_id ? json_object_new_string(c->app_id) : NULL);
- json_object_object_add(props, "title", (c->name) ? json_object_new_string(c->name) : NULL);
- json_object_object_add(props, "transient_for", parent ? json_object_new_int(parent) : NULL);
- json_object_object_add(object, "window_properties", props);
-
- json_object_object_add(object, "fullscreen_mode",
- json_object_new_int(swayc_is_fullscreen(c) ? 1 : 0));
- json_object_object_add(object, "sticky", json_object_new_boolean(c->sticky));
- json_object_object_add(object, "floating", json_object_new_string(
- c->is_floating ? "auto_on" : "auto_off")); // we can't state the cause
-
- json_object_object_add(object, "app_id", c->app_id ? json_object_new_string(c->app_id) : NULL);
-
- if (c->parent) {
- const char *layout = (c->parent->type == C_CONTAINER) ?
- ipc_json_layout_description(c->parent->layout) : "none";
- const char *last_layout = (c->parent->type == C_CONTAINER) ?
- ipc_json_layout_description(c->parent->prev_layout) : "none";
- json_object_object_add(object, "layout",
- (strcmp(layout, "null") == 0) ? NULL : json_object_new_string(layout));
- json_object_object_add(object, "last_split_layout",
- (strcmp(last_layout, "null") == 0) ? NULL : json_object_new_string(last_layout));
- json_object_object_add(object, "workspace_layout",
- json_object_new_string(ipc_json_layout_description(swayc_parent_by_type(c, C_WORKSPACE)->workspace_layout)));
- }
-}
-
-static void ipc_json_describe_root(swayc_t *c, json_object *object) {
- json_object_object_add(object, "type", json_object_new_string("root"));
- json_object_object_add(object, "layout", json_object_new_string("splith"));
-}
-
-json_object *ipc_json_describe_container(swayc_t *c) {
- float percent = ipc_json_child_percentage(c);
-
- if (!(sway_assert(c, "Container must not be null."))) {
- return NULL;
- }
-
- json_object *object = json_object_new_object();
-
- json_object_object_add(object, "id", json_object_new_int((int)c->id));
- json_object_object_add(object, "name", (c->name) ? json_object_new_string(c->name) : NULL);
- json_object_object_add(object, "rect", ipc_json_create_rect(c));
- json_object_object_add(object, "visible", json_object_new_boolean(c->visible));
- json_object_object_add(object, "focused", json_object_new_boolean(c == current_focus));
-
- json_object_object_add(object, "border", json_object_new_string(ipc_json_border_description(c)));
- json_object_object_add(object, "window_rect", ipc_json_create_rect_from_geometry(c->actual_geometry));
- json_object_object_add(object, "deco_rect", ipc_json_create_rect_from_geometry(c->title_bar_geometry));
- json_object_object_add(object, "geometry", ipc_json_create_rect_from_geometry(c->cached_geometry));
- json_object_object_add(object, "percent", (percent > 0) ? json_object_new_double(percent) : NULL);
- json_object_object_add(object, "window", json_object_new_int(c->handle)); // for the sake of i3 compat
- // TODO: make urgency actually work once Sway supports it
- json_object_object_add(object, "urgent", json_object_new_boolean(false));
- json_object_object_add(object, "current_border_width", json_object_new_int(c->border_thickness));
-
- switch (c->type) {
- case C_ROOT:
- ipc_json_describe_root(c, object);
- break;
-
- case C_OUTPUT:
- ipc_json_describe_output(c, object);
- break;
-
- case C_CONTAINER: // fallthrough
- case C_VIEW:
- ipc_json_describe_view(c, object);
- break;
-
- case C_WORKSPACE:
- ipc_json_describe_workspace(c, object);
- break;
-
- case C_TYPES: // fallthrough; this should never happen, I'm just trying to silence compiler warnings
- default:
- break;
- }
-
- return object;
-}
-
-json_object *ipc_json_describe_input(struct libinput_device *device) {
- char* identifier = libinput_dev_unique_id(device);
- int vendor = libinput_device_get_id_vendor(device);
- int product = libinput_device_get_id_product(device);
- const char *name = libinput_device_get_name(device);
- double width = -1, height = -1;
- int has_size = libinput_device_get_size(device, &width, &height);
-
- json_object *device_object = json_object_new_object();
- json_object_object_add(device_object,"identifier",
- identifier ? json_object_new_string(identifier) : NULL);
- json_object_object_add(device_object,
- "vendor", json_object_new_int(vendor));
- json_object_object_add(device_object,
- "product", json_object_new_int(product));
- json_object_object_add(device_object,
- "name", json_object_new_string(name));
- if (has_size == 0) {
- json_object *size_object = json_object_new_object();
- json_object_object_add(size_object,
- "width", json_object_new_double(width));
- json_object_object_add(size_object,
- "height", json_object_new_double(height));
- } else {
- json_object_object_add(device_object, "size", NULL);
- }
-
- struct {
- enum libinput_device_capability cap;
- const char *name;
- // If anyone feels like implementing device-specific IPC output,
- // be my guest
- json_object *(*describe)(struct libinput_device *);
- } caps[] = {
- { LIBINPUT_DEVICE_CAP_KEYBOARD, "keyboard", NULL },
- { LIBINPUT_DEVICE_CAP_POINTER, "pointer", NULL },
- { LIBINPUT_DEVICE_CAP_TOUCH, "touch", NULL },
- { LIBINPUT_DEVICE_CAP_TABLET_TOOL, "tablet_tool", NULL },
- { LIBINPUT_DEVICE_CAP_TABLET_PAD, "tablet_pad", NULL },
- { LIBINPUT_DEVICE_CAP_GESTURE, "gesture", NULL },
-#ifdef LIBINPUT_DEVICE_CAP_SWITCH // libinput 1.7.0+
- { LIBINPUT_DEVICE_CAP_SWITCH, "switch", NULL },
-#endif
- };
-
- json_object *_caps = json_object_new_array();
- for (size_t i = 0; i < sizeof(caps) / sizeof(caps[0]); ++i) {
- if (libinput_device_has_capability(device, caps[i].cap)) {
- json_object_array_add(_caps, json_object_new_string(caps[i].name));
- if (caps[i].describe) {
- json_object *desc = caps[i].describe(device);
- json_object_object_add(device_object, caps[i].name, desc);
- }
- }
- }
- json_object_object_add(device_object, "capabilities", _caps);
-
- free(identifier);
- return device_object;
-}
-
-json_object *ipc_json_get_version() {
- int major = 0, minor = 0, patch = 0;
- json_object *version = json_object_new_object();
-
- sscanf(SWAY_VERSION, "%u.%u.%u", &major, &minor, &patch);
-
- json_object_object_add(version, "human_readable", json_object_new_string(SWAY_VERSION));
- json_object_object_add(version, "variant", json_object_new_string("sway"));
- 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));
-
- return version;
-}
-
-json_object *ipc_json_describe_bar_config(struct bar_config *bar) {
- if (!sway_assert(bar, "Bar must not be NULL")) {
- return NULL;
- }
-
- json_object *json = json_object_new_object();
- json_object_object_add(json, "id", json_object_new_string(bar->id));
-#ifdef ENABLE_TRAY
- if (bar->tray_output) {
- json_object_object_add(json, "tray_output", json_object_new_string(bar->tray_output));
- } else {
- json_object_object_add(json, "tray_output", NULL);
- }
- if (bar->icon_theme) {
- json_object_object_add(json, "icon_theme", json_object_new_string(bar->icon_theme));
- } else {
- json_object_object_add(json, "icon_theme", NULL);
- }
- json_object_object_add(json, "tray_padding", json_object_new_int(bar->tray_padding));
- json_object_object_add(json, "activate_button", json_object_new_int(bar->activate_button));
- json_object_object_add(json, "context_button", json_object_new_int(bar->context_button));
- json_object_object_add(json, "secondary_button", json_object_new_int(bar->secondary_button));
-#endif
- json_object_object_add(json, "mode", json_object_new_string(bar->mode));
- json_object_object_add(json, "hidden_state", json_object_new_string(bar->hidden_state));
- json_object_object_add(json, "modifier", json_object_new_string(get_modifier_name_by_mask(bar->modifier)));
- switch (bar->position) {
- case DESKTOP_SHELL_PANEL_POSITION_TOP:
- json_object_object_add(json, "position", json_object_new_string("top"));
- break;
- case DESKTOP_SHELL_PANEL_POSITION_BOTTOM:
- json_object_object_add(json, "position", json_object_new_string("bottom"));
- break;
- case DESKTOP_SHELL_PANEL_POSITION_LEFT:
- json_object_object_add(json, "position", json_object_new_string("left"));
- break;
- case DESKTOP_SHELL_PANEL_POSITION_RIGHT:
- json_object_object_add(json, "position", json_object_new_string("right"));
- break;
- }
- json_object_object_add(json, "status_command", json_object_new_string(bar->status_command));
- json_object_object_add(json, "font", json_object_new_string((bar->font) ? bar->font : config->font));
- if (bar->separator_symbol) {
- json_object_object_add(json, "separator_symbol", json_object_new_string(bar->separator_symbol));
- }
- json_object_object_add(json, "bar_height", json_object_new_int(bar->height));
- json_object_object_add(json, "wrap_scroll", json_object_new_boolean(bar->wrap_scroll));
- json_object_object_add(json, "workspace_buttons", json_object_new_boolean(bar->workspace_buttons));
- json_object_object_add(json, "strip_workspace_numbers", json_object_new_boolean(bar->strip_workspace_numbers));
- json_object_object_add(json, "binding_mode_indicator", json_object_new_boolean(bar->binding_mode_indicator));
- json_object_object_add(json, "verbose", json_object_new_boolean(bar->verbose));
- json_object_object_add(json, "pango_markup", json_object_new_boolean(bar->pango_markup));
-
- json_object *colors = json_object_new_object();
- json_object_object_add(colors, "background", json_object_new_string(bar->colors.background));
- json_object_object_add(colors, "statusline", json_object_new_string(bar->colors.statusline));
- json_object_object_add(colors, "separator", json_object_new_string(bar->colors.separator));
-
- if (bar->colors.focused_background) {
- json_object_object_add(colors, "focused_background", json_object_new_string(bar->colors.focused_background));
- } else {
- json_object_object_add(colors, "focused_background", json_object_new_string(bar->colors.background));
- }
-
- if (bar->colors.focused_statusline) {
- json_object_object_add(colors, "focused_statusline", json_object_new_string(bar->colors.focused_statusline));
- } else {
- json_object_object_add(colors, "focused_statusline", json_object_new_string(bar->colors.statusline));
- }
-
- if (bar->colors.focused_separator) {
- json_object_object_add(colors, "focused_separator", json_object_new_string(bar->colors.focused_separator));
- } else {
- json_object_object_add(colors, "focused_separator", json_object_new_string(bar->colors.separator));
- }
-
- json_object_object_add(colors, "focused_workspace_border", json_object_new_string(bar->colors.focused_workspace_border));
- json_object_object_add(colors, "focused_workspace_bg", json_object_new_string(bar->colors.focused_workspace_bg));
- json_object_object_add(colors, "focused_workspace_text", json_object_new_string(bar->colors.focused_workspace_text));
-
- json_object_object_add(colors, "inactive_workspace_border", json_object_new_string(bar->colors.inactive_workspace_border));
- json_object_object_add(colors, "inactive_workspace_bg", json_object_new_string(bar->colors.inactive_workspace_bg));
- json_object_object_add(colors, "inactive_workspace_text", json_object_new_string(bar->colors.inactive_workspace_text));
-
- json_object_object_add(colors, "active_workspace_border", json_object_new_string(bar->colors.active_workspace_border));
- json_object_object_add(colors, "active_workspace_bg", json_object_new_string(bar->colors.active_workspace_bg));
- json_object_object_add(colors, "active_workspace_text", json_object_new_string(bar->colors.active_workspace_text));
-
- json_object_object_add(colors, "urgent_workspace_border", json_object_new_string(bar->colors.urgent_workspace_border));
- json_object_object_add(colors, "urgent_workspace_bg", json_object_new_string(bar->colors.urgent_workspace_bg));
- json_object_object_add(colors, "urgent_workspace_text", json_object_new_string(bar->colors.urgent_workspace_text));
-
- if (bar->colors.binding_mode_border) {
- json_object_object_add(colors, "binding_mode_border", json_object_new_string(bar->colors.binding_mode_border));
- } else {
- json_object_object_add(colors, "binding_mode_border", json_object_new_string(bar->colors.urgent_workspace_border));
- }
-
- if (bar->colors.binding_mode_bg) {
- json_object_object_add(colors, "binding_mode_bg", json_object_new_string(bar->colors.binding_mode_bg));
- } else {
- json_object_object_add(colors, "binding_mode_bg", json_object_new_string(bar->colors.urgent_workspace_bg));
- }
-
- if (bar->colors.binding_mode_text) {
- json_object_object_add(colors, "binding_mode_text", json_object_new_string(bar->colors.binding_mode_text));
- } else {
- json_object_object_add(colors, "binding_mode_text", json_object_new_string(bar->colors.urgent_workspace_text));
- }
-
- json_object_object_add(json, "colors", colors);
-
- // Add outputs if defined
- if (bar->outputs && bar->outputs->length > 0) {
- json_object *outputs = json_object_new_array();
- int i;
- for (i = 0; i < bar->outputs->length; ++i) {
- const char *name = bar->outputs->items[i];
- json_object_array_add(outputs, json_object_new_string(name));
- }
- json_object_object_add(json, "outputs", outputs);
- }
-
- return json;
-}
-
-json_object *ipc_json_describe_container_recursive(swayc_t *c) {
- json_object *object = ipc_json_describe_container(c);
- int i;
-
- json_object *floating = json_object_new_array();
- if (c->type != C_VIEW && c->floating) {
- for (i = 0; i < c->floating->length; ++i) {
- swayc_t *item = c->floating->items[i];
- json_object_array_add(floating, ipc_json_describe_container_recursive(item));
- }
- }
- json_object_object_add(object, "floating_nodes", floating);
-
- json_object *children = json_object_new_array();
- if (c->type != C_VIEW && c->children) {
- for (i = 0; i < c->children->length; ++i) {
- json_object_array_add(children, ipc_json_describe_container_recursive(c->children->items[i]));
- }
- }
- json_object_object_add(object, "nodes", children);
-
- json_object *focus = json_object_new_array();
- if (c->type != C_VIEW) {
- if (c->focused) {
- json_object_array_add(focus, json_object_new_double(c->focused->id));
- }
- if (c->floating) {
- for (i = 0; i < c->floating->length; ++i) {
- swayc_t *item = c->floating->items[i];
- if (item == c->focused) {
- continue;
- }
-
- json_object_array_add(focus, json_object_new_double(item->id));
- }
- }
- if (c->children) {
- for (i = 0; i < c->children->length; ++i) {
- swayc_t *item = c->children->items[i];
- if (item == c->focused) {
- continue;
- }
-
- json_object_array_add(focus, json_object_new_double(item->id));
- }
- }
- }
- json_object_object_add(object, "focus", focus);
-
- if (c->type == C_ROOT) {
- json_object *scratchpad_json = json_object_new_array();
- if (scratchpad->length > 0) {
- for (i = 0; i < scratchpad->length; ++i) {
- json_object_array_add(scratchpad_json, ipc_json_describe_container_recursive(scratchpad->items[i]));
- }
- }
- json_object_object_add(object, "scratchpad", scratchpad_json);
- }
-
- return object;
-}
diff --git a/sway/old/ipc-server.c b/sway/old/ipc-server.c
deleted file mode 100644
index fd64e81b..00000000
--- a/sway/old/ipc-server.c
+++ /dev/null
@@ -1,840 +0,0 @@
-// See https://i3wm.org/docs/ipc.html for protocol information
-#ifndef __FreeBSD__
-// Any value will hide SOCK_CLOEXEC on FreeBSD (__BSD_VISIBLE=0)
-#define _XOPEN_SOURCE 700
-#endif
-#include <errno.h>
-#include <string.h>
-#include <sys/socket.h>
-#include <sys/un.h>
-#include <stdbool.h>
-#include <unistd.h>
-#include <stdlib.h>
-#include <sys/ioctl.h>
-#include <fcntl.h>
-#include <json-c/json.h>
-#include <list.h>
-#include <libinput.h>
-#ifdef __linux__
-struct ucred {
- pid_t pid;
- uid_t uid;
- gid_t gid;
-};
-#endif
-#include "sway/ipc-json.h"
-#include "sway/ipc-server.h"
-#include "sway/security.h"
-#include "sway/config.h"
-#include "sway/commands.h"
-#include "sway/input.h"
-#include "sway/server.h"
-#include "stringop.h"
-#include "log.h"
-#include "list.h"
-#include "util.h"
-
-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 const char ipc_magic[] = {'i', '3', '-', 'i', 'p', 'c'};
-
-struct ipc_client {
- struct wl_event_source *event_source;
- struct wl_event_source *writable_event_source;
- int fd;
- uint32_t payload_length;
- uint32_t security_policy;
- enum ipc_command_type current_command;
- enum ipc_command_type subscribed_events;
- size_t write_buffer_len;
- size_t write_buffer_size;
- char *write_buffer;
-};
-
-struct sockaddr_un *ipc_user_sockaddr(void);
-int ipc_handle_connection(int fd, uint32_t mask, void *data);
-int ipc_client_handle_readable(int client_fd, uint32_t mask, void *data);
-int ipc_client_handle_writable(int client_fd, uint32_t mask, void *data);
-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);
-void ipc_get_workspaces_callback(swayc_t *workspace, void *data);
-void ipc_get_outputs_callback(swayc_t *container, void *data);
-static void ipc_get_marks_callback(swayc_t *container, void *data);
-
-void ipc_init(void) {
- ipc_socket = socket(AF_UNIX, SOCK_STREAM | SOCK_NONBLOCK | SOCK_CLOEXEC, 0);
- if (ipc_socket == -1) {
- sway_abort("Unable to create IPC socket");
- }
-
- ipc_sockaddr = ipc_user_sockaddr();
-
- // We want to use socket name set by user, not existing socket from another sway instance.
- if (getenv("SWAYSOCK") != NULL && access(getenv("SWAYSOCK"), F_OK) == -1) {
- strncpy(ipc_sockaddr->sun_path, getenv("SWAYSOCK"), sizeof(ipc_sockaddr->sun_path));
- ipc_sockaddr->sun_path[sizeof(ipc_sockaddr->sun_path) - 1] = 0;
- }
-
- unlink(ipc_sockaddr->sun_path);
- if (bind(ipc_socket, (struct sockaddr *)ipc_sockaddr, sizeof(*ipc_sockaddr)) == -1) {
- sway_abort("Unable to bind IPC socket");
- }
-
- if (listen(ipc_socket, 3) == -1) {
- sway_abort("Unable to listen on IPC socket");
- }
-
- // Set i3 IPC socket path so that i3-msg works out of the box
- setenv("I3SOCK", ipc_sockaddr->sun_path, 1);
- setenv("SWAYSOCK", ipc_sockaddr->sun_path, 1);
-
- ipc_client_list = create_list();
-
- ipc_event_source = wl_event_loop_add_fd(server.wl_event_loop, ipc_socket,
- WL_EVENT_READABLE, ipc_handle_connection, NULL);
-}
-
-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) {
- sway_abort("Can't allocate ipc_sockaddr");
- }
-
- ipc_sockaddr->sun_family = AF_UNIX;
- int path_size = sizeof(ipc_sockaddr->sun_path);
-
- // Env var typically set by logind, e.g. "/run/user/<user-id>"
- const char *dir = getenv("XDG_RUNTIME_DIR");
- if (!dir) {
- dir = "/tmp";
- }
- if (path_size <= snprintf(ipc_sockaddr->sun_path, path_size,
- "%s/sway-ipc.%i.%i.sock", dir, getuid(), getpid())) {
- sway_abort("Socket path won't fit into ipc_sockaddr->sun_path");
- }
-
- return ipc_sockaddr;
-}
-
-static pid_t get_client_pid(int client_fd) {
-// FreeBSD supports getting uid/gid, but not pid
-#ifdef __linux__
- struct ucred ucred;
- socklen_t len = sizeof(struct ucred);
-
- if (getsockopt(client_fd, SOL_SOCKET, SO_PEERCRED, &ucred, &len) == -1) {
- return -1;
- }
-
- return ucred.pid;
-#else
- return -1;
-#endif
-}
-
-int ipc_handle_connection(int fd, uint32_t mask, void *data) {
- (void) fd; (void) data;
- sway_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) {
- sway_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) {
- sway_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) {
- sway_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) {
- sway_log(L_ERROR, "Unable to allocate ipc client");
- close(client_fd);
- return 0;
- }
- client->payload_length = 0;
- client->fd = client_fd;
- client->subscribed_events = 0;
- client->event_source = wl_event_loop_add_fd(server.wl_event_loop, client_fd,
- WL_EVENT_READABLE, ipc_client_handle_readable, client);
- client->writable_event_source = NULL;
-
- client->write_buffer_size = 128;
- client->write_buffer_len = 0;
- client->write_buffer = malloc(client->write_buffer_size);
- if (!client->write_buffer) {
- sway_log(L_ERROR, "Unable to allocate ipc client write buffer");
- close(client_fd);
- return 0;
- }
-
- pid_t pid = get_client_pid(client->fd);
- client->security_policy = get_ipc_policy_mask(pid);
-
- sway_log(L_DEBUG, "New client: fd %d, pid %d", client_fd, pid);
-
- list_add(ipc_client_list, client);
-
- return 0;
-}
-
-static const int ipc_header_size = sizeof(ipc_magic)+8;
-
-int ipc_client_handle_readable(int client_fd, uint32_t mask, void *data) {
- struct ipc_client *client = data;
-
- if (mask & WL_EVENT_ERROR) {
- sway_log(L_ERROR, "IPC Client socket error, removing client");
- ipc_client_disconnect(client);
- return 0;
- }
-
- if (mask & WL_EVENT_HANGUP) {
- sway_log(L_DEBUG, "Client %d hung up", client->fd);
- ipc_client_disconnect(client);
- return 0;
- }
-
- sway_log(L_DEBUG, "Client %d readable", client->fd);
-
- int read_available;
- if (ioctl(client_fd, FIONREAD, &read_available) == -1) {
- sway_log_errno(L_INFO, "Unable to read IPC socket buffer size");
- ipc_client_disconnect(client);
- return 0;
- }
-
- // Wait for the rest of the command payload in case the header has already been read
- if (client->payload_length > 0) {
- if ((uint32_t)read_available >= client->payload_length) {
- ipc_client_handle_command(client);
- }
- return 0;
- }
-
- if (read_available < ipc_header_size) {
- return 0;
- }
-
- uint8_t buf[ipc_header_size];
- uint32_t *buf32 = (uint32_t*)(buf + sizeof(ipc_magic));
- // Should be fully available, because read_available >= ipc_header_size
- ssize_t received = recv(client_fd, buf, ipc_header_size, 0);
- if (received == -1) {
- sway_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) {
- sway_log(L_DEBUG, "IPC header check failed");
- ipc_client_disconnect(client);
- return 0;
- }
-
- client->payload_length = buf32[0];
- client->current_command = (enum ipc_command_type)buf32[1];
-
- if (read_available - received >= (long)client->payload_length) {
- ipc_client_handle_command(client);
- }
-
- return 0;
-}
-
-int ipc_client_handle_writable(int client_fd, uint32_t mask, void *data) {
- struct ipc_client *client = data;
-
- if (mask & WL_EVENT_ERROR) {
- sway_log(L_ERROR, "IPC Client socket error, removing client");
- ipc_client_disconnect(client);
- return 0;
- }
-
- if (mask & WL_EVENT_HANGUP) {
- sway_log(L_DEBUG, "Client %d hung up", client->fd);
- ipc_client_disconnect(client);
- return 0;
- }
-
- if (client->write_buffer_len <= 0) {
- return 0;
- }
-
- sway_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) {
- sway_log_errno(L_INFO, "Unable to send data from queue to IPC client");
- ipc_client_disconnect(client);
- return 0;
- }
-
- memmove(client->write_buffer, client->write_buffer + written, client->write_buffer_len - written);
- client->write_buffer_len -= written;
-
- if (client->write_buffer_len == 0 && client->writable_event_source) {
- wl_event_source_remove(client->writable_event_source);
- client->writable_event_source = NULL;
- }
-
- return 0;
-}
-
-void ipc_client_disconnect(struct ipc_client *client) {
- if (!sway_assert(client != NULL, "client != NULL")) {
- return;
- }
-
- if (client->fd != -1) {
- shutdown(client->fd, SHUT_RDWR);
- }
-
- sway_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);
- }
- int i = 0;
- while (i < ipc_client_list->length && ipc_client_list->items[i] != client) i++;
- list_del(ipc_client_list, i);
- free(client->write_buffer);
- close(client->fd);
- free(client);
-}
-
-bool output_by_name_test(swayc_t *view, void *data) {
- char *name = (char *)data;
- if (view->type != C_OUTPUT) {
- return false;
- }
- return !strcmp(name, view->name);
-}
-
-// greedy wildcard (only "*") matching
-bool mime_type_matches(const char *mime_type, const char *pattern) {
- const char *wildcard = NULL;
- while (*mime_type && *pattern) {
- if (*pattern == '*' && !wildcard) {
- wildcard = pattern;
- ++pattern;
- }
-
- if (*mime_type != *pattern) {
- if (!wildcard)
- return false;
-
- pattern = wildcard;
- ++mime_type;
- continue;
- }
-
- ++mime_type;
- ++pattern;
- }
-
- while (*pattern == '*') {
- ++pattern;
- }
-
- return (*mime_type == *pattern);
-}
-
-void ipc_client_handle_command(struct ipc_client *client) {
- if (!sway_assert(client != NULL, "client != NULL")) {
- return;
- }
-
- char *buf = malloc(client->payload_length + 1);
- if (!buf) {
- sway_log_errno(L_INFO, "Unable to allocate IPC payload");
- ipc_client_disconnect(client);
- return;
- }
- if (client->payload_length > 0) {
- // Payload should be fully available
- ssize_t received = recv(client->fd, buf, client->payload_length, 0);
- if (received == -1)
- {
- sway_log_errno(L_INFO, "Unable to receive payload from IPC client");
- ipc_client_disconnect(client);
- free(buf);
- return;
- }
- }
- buf[client->payload_length] = '\0';
-
- const char *error_denied = "{ \"success\": false, \"error\": \"Permission denied\" }";
-
- switch (client->current_command) {
- case IPC_COMMAND:
- {
- if (!(client->security_policy & IPC_FEATURE_COMMAND)) {
- goto exit_denied;
- }
- struct cmd_results *results = handle_command(buf, CONTEXT_IPC);
- 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;
- }
-
- case IPC_SUBSCRIBE:
- {
- // TODO: Check if they're permitted to use these events
- struct json_object *request = json_tokener_parse(buf);
- if (request == NULL) {
- ipc_send_reply(client, "{\"success\": false}", 18);
- sway_log_errno(L_INFO, "Failed to read request");
- goto exit_cleanup;
- }
-
- // parse requested event types
- for (int i = 0; i < json_object_array_length(request); i++) {
- const char *event_type = json_object_get_string(json_object_array_get_idx(request, i));
- if (strcmp(event_type, "workspace") == 0) {
- client->subscribed_events |= event_mask(IPC_EVENT_WORKSPACE);
- } else if (strcmp(event_type, "barconfig_update") == 0) {
- client->subscribed_events |= event_mask(IPC_EVENT_BARCONFIG_UPDATE);
- } else if (strcmp(event_type, "mode") == 0) {
- client->subscribed_events |= event_mask(IPC_EVENT_MODE);
- } else if (strcmp(event_type, "window") == 0) {
- client->subscribed_events |= event_mask(IPC_EVENT_WINDOW);
- } else if (strcmp(event_type, "modifier") == 0) {
- client->subscribed_events |= event_mask(IPC_EVENT_MODIFIER);
- } else if (strcmp(event_type, "binding") == 0) {
- client->subscribed_events |= event_mask(IPC_EVENT_BINDING);
- } else {
- ipc_send_reply(client, "{\"success\": false}", 18);
- json_object_put(request);
- sway_log_errno(L_INFO, "Failed to parse request");
- goto exit_cleanup;
- }
- }
-
- json_object_put(request);
-
- ipc_send_reply(client, "{\"success\": true}", 17);
- goto exit_cleanup;
- }
-
- case IPC_GET_WORKSPACES:
- {
- if (!(client->security_policy & IPC_FEATURE_GET_WORKSPACES)) {
- goto exit_denied;
- }
- json_object *workspaces = json_object_new_array();
- container_map(&root_container, ipc_get_workspaces_callback, workspaces);
- const char *json_string = json_object_to_json_string(workspaces);
- ipc_send_reply(client, json_string, (uint32_t) strlen(json_string));
- json_object_put(workspaces); // free
- goto exit_cleanup;
- }
-
- case IPC_GET_INPUTS:
- {
- if (!(client->security_policy & IPC_FEATURE_GET_INPUTS)) {
- goto exit_denied;
- }
- json_object *inputs = json_object_new_array();
- /* TODO WLR
- if (input_devices) {
- for(int i = 0; i<input_devices->length; i++) {
- struct libinput_device *device = input_devices->items[i];
- json_object_array_add(inputs, ipc_json_describe_input(device));
- }
- }
- */
- const char *json_string = json_object_to_json_string(inputs);
- ipc_send_reply(client, json_string, (uint32_t) strlen(json_string));
- json_object_put(inputs);
- goto exit_cleanup;
- }
-
- case IPC_GET_OUTPUTS:
- {
- if (!(client->security_policy & IPC_FEATURE_GET_OUTPUTS)) {
- goto exit_denied;
- }
- json_object *outputs = json_object_new_array();
- container_map(&root_container, ipc_get_outputs_callback, outputs);
- const char *json_string = json_object_to_json_string(outputs);
- ipc_send_reply(client, json_string, (uint32_t) strlen(json_string));
- json_object_put(outputs); // free
- goto exit_cleanup;
- }
-
- case IPC_GET_TREE:
- {
- if (!(client->security_policy & IPC_FEATURE_GET_TREE)) {
- goto exit_denied;
- }
- json_object *tree = ipc_json_describe_container_recursive(&root_container);
- const char *json_string = json_object_to_json_string(tree);
- ipc_send_reply(client, json_string, (uint32_t) strlen(json_string));
- json_object_put(tree);
- goto exit_cleanup;
- }
-
- case IPC_GET_MARKS:
- {
- if (!(client->security_policy & IPC_FEATURE_GET_MARKS)) {
- goto exit_denied;
- }
- json_object *marks = json_object_new_array();
- container_map(&root_container, ipc_get_marks_callback, marks);
- const char *json_string = json_object_to_json_string(marks);
- ipc_send_reply(client, json_string, (uint32_t) strlen(json_string));
- json_object_put(marks);
- goto exit_cleanup;
- }
-
- case IPC_GET_VERSION:
- {
- json_object *version = ipc_json_get_version();
- const char *json_string = json_object_to_json_string(version);
- ipc_send_reply(client, json_string, (uint32_t)strlen(json_string));
- json_object_put(version); // free
- goto exit_cleanup;
- }
-
- case IPC_GET_BAR_CONFIG:
- {
- if (!(client->security_policy & IPC_FEATURE_GET_BAR_CONFIG)) {
- goto exit_denied;
- }
- if (!buf[0]) {
- // Send list of configured bar IDs
- json_object *bars = json_object_new_array();
- int i;
- for (i = 0; i < config->bars->length; ++i) {
- struct bar_config *bar = config->bars->items[i];
- json_object_array_add(bars, json_object_new_string(bar->id));
- }
- const char *json_string = json_object_to_json_string(bars);
- ipc_send_reply(client, json_string, (uint32_t)strlen(json_string));
- json_object_put(bars); // free
- } else {
- // Send particular bar's details
- struct bar_config *bar = NULL;
- int i;
- for (i = 0; i < config->bars->length; ++i) {
- bar = config->bars->items[i];
- if (strcmp(buf, bar->id) == 0) {
- break;
- }
- bar = NULL;
- }
- if (!bar) {
- const char *error = "{ \"success\": false, \"error\": \"No bar with that ID\" }";
- 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);
- ipc_send_reply(client, json_string, (uint32_t)strlen(json_string));
- json_object_put(json); // free
- }
- goto exit_cleanup;
- }
-
- case IPC_GET_CLIPBOARD:
- // TODO WLR
- break;
-
- default:
- sway_log(L_INFO, "Unknown IPC command type %i", client->current_command);
- goto exit_cleanup;
- }
-
-exit_denied:
- ipc_send_reply(client, error_denied, (uint32_t)strlen(error_denied));
- sway_log(L_DEBUG, "Denied IPC client access to %i", client->current_command);
-
-exit_cleanup:
- client->payload_length = 0;
- free(buf);
- return;
-}
-
-bool ipc_send_reply(struct ipc_client *client, const char *payload, uint32_t payload_length) {
- assert(payload);
-
- char data[ipc_header_size];
- uint32_t *data32 = (uint32_t*)(data + sizeof(ipc_magic));
-
- memcpy(data, ipc_magic, sizeof(ipc_magic));
- data32[0] = payload_length;
- data32[1] = client->current_command;
-
- while (client->write_buffer_len + ipc_header_size + payload_length >=
- client->write_buffer_size) {
- client->write_buffer_size *= 2;
- }
-
- // TODO: reduce the limit back to 4 MB when screenshooter is implemented
- if (client->write_buffer_size > (1 << 28)) { // 256 MB
- sway_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) {
- sway_log(L_ERROR, "Unable to reallocate ipc client write buffer");
- ipc_client_disconnect(client);
- return false;
- }
- client->write_buffer = new_buffer;
-
- memcpy(client->write_buffer + client->write_buffer_len, data, ipc_header_size);
- client->write_buffer_len += ipc_header_size;
- memcpy(client->write_buffer + client->write_buffer_len, payload, payload_length);
- client->write_buffer_len += payload_length;
-
- if (!client->writable_event_source) {
- client->writable_event_source = wl_event_loop_add_fd(
- server.wl_event_loop, client->fd, WL_EVENT_WRITABLE,
- ipc_client_handle_writable, client);
- }
-
- sway_log(L_DEBUG, "Added IPC reply to client %d queue: %s", client->fd, payload);
-
- return true;
-}
-
-void ipc_get_workspaces_callback(swayc_t *workspace, void *data) {
- if (workspace->type == C_WORKSPACE) {
- json_object *workspace_json = ipc_json_describe_container(workspace);
- // override the default focused indicator because
- // it's set differently for the get_workspaces reply
- bool focused = root_container.focused == workspace->parent && workspace->parent->focused == workspace;
- json_object_object_del(workspace_json, "focused");
- json_object_object_add(workspace_json, "focused", json_object_new_boolean(focused));
- json_object_array_add((json_object *)data, workspace_json);
- }
-}
-
-void ipc_get_outputs_callback(swayc_t *container, void *data) {
- if (container->type == C_OUTPUT) {
- json_object_array_add((json_object *)data, ipc_json_describe_container(container));
- }
-}
-
-static void ipc_get_marks_callback(swayc_t *container, void *data) {
- json_object *object = (json_object *)data;
- if (container->marks) {
- for (int i = 0; i < container->marks->length; ++i) {
- char *mark = (char *)container->marks->items[i];
- json_object_array_add(object, json_object_new_string(mark));
- }
- }
-}
-
-void ipc_send_event(const char *json_string, enum ipc_command_type event) {
- static struct {
- enum ipc_command_type event;
- enum ipc_feature feature;
- } security_mappings[] = {
- { IPC_EVENT_WORKSPACE, IPC_FEATURE_EVENT_WORKSPACE },
- { IPC_EVENT_OUTPUT, IPC_FEATURE_EVENT_OUTPUT },
- { IPC_EVENT_MODE, IPC_FEATURE_EVENT_MODE },
- { IPC_EVENT_WINDOW, IPC_FEATURE_EVENT_WINDOW },
- { IPC_EVENT_BINDING, IPC_FEATURE_EVENT_BINDING },
- { IPC_EVENT_INPUT, IPC_FEATURE_EVENT_INPUT }
- };
-
- uint32_t security_mask = 0;
- for (size_t i = 0; i < sizeof(security_mappings) / sizeof(security_mappings[0]); ++i) {
- if (security_mappings[i].event == event) {
- security_mask = security_mappings[i].feature;
- break;
- }
- }
-
- int i;
- struct ipc_client *client;
- for (i = 0; i < ipc_client_list->length; i++) {
- client = ipc_client_list->items[i];
- if (!(client->security_policy & security_mask)) {
- continue;
- }
- if ((client->subscribed_events & event_mask(event)) == 0) {
- continue;
- }
- client->current_command = event;
- if (!ipc_send_reply(client, json_string, (uint32_t) strlen(json_string))) {
- sway_log_errno(L_INFO, "Unable to send reply to IPC client");
- ipc_client_disconnect(client);
- }
- }
-}
-
-void ipc_event_workspace(swayc_t *old, swayc_t *new, const char *change) {
- sway_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) {
- if (old) {
- json_object_object_add(obj, "old", ipc_json_describe_container_recursive(old));
- } else {
- json_object_object_add(obj, "old", NULL);
- }
- }
-
- if (new) {
- json_object_object_add(obj, "current", ipc_json_describe_container_recursive(new));
- } else {
- json_object_object_add(obj, "current", NULL);
- }
-
- const char *json_string = json_object_to_json_string(obj);
- ipc_send_event(json_string, IPC_EVENT_WORKSPACE);
-
- json_object_put(obj); // free
-}
-
-void ipc_event_window(swayc_t *window, const char *change) {
- sway_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));
-
- const char *json_string = json_object_to_json_string(obj);
- ipc_send_event(json_string, IPC_EVENT_WINDOW);
-
- json_object_put(obj); // free
-}
-
-void ipc_event_barconfig_update(struct bar_config *bar) {
- sway_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);
- ipc_send_event(json_string, IPC_EVENT_BARCONFIG_UPDATE);
-
- json_object_put(json); // free
-}
-
-void ipc_event_mode(const char *mode) {
- sway_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));
-
- const char *json_string = json_object_to_json_string(obj);
- ipc_send_event(json_string, IPC_EVENT_MODE);
-
- json_object_put(obj); // free
-}
-
-void ipc_event_modifier(uint32_t modifier, const char *state) {
- sway_log(L_DEBUG, "Sending modifier::%s event", state);
- json_object *obj = json_object_new_object();
- json_object_object_add(obj, "change", json_object_new_string(state));
-
- const char *modifier_name = get_modifier_name_by_mask(modifier);
- json_object_object_add(obj, "modifier", json_object_new_string(modifier_name));
-
- const char *json_string = json_object_to_json_string(obj);
- ipc_send_event(json_string, IPC_EVENT_MODIFIER);
-
- json_object_put(obj); // free
-}
-
-static void ipc_event_binding(json_object *sb_obj) {
- sway_log(L_DEBUG, "Sending binding::run event");
- json_object *obj = json_object_new_object();
- json_object_object_add(obj, "change", json_object_new_string("run"));
- json_object_object_add(obj, "binding", sb_obj);
-
- const char *json_string = json_object_to_json_string(obj);
- ipc_send_event(json_string, IPC_EVENT_BINDING);
-
- json_object_put(obj); // free
-}
-
-void ipc_event_binding_keyboard(struct sway_binding *sb) {
- json_object *sb_obj = json_object_new_object();
- json_object_object_add(sb_obj, "command", json_object_new_string(sb->command));
-
- const char *names[10];
-
- int len = get_modifier_names(names, sb->modifiers);
- int i;
- json_object *modifiers = json_object_new_array();
- for (i = 0; i < len; ++i) {
- json_object_array_add(modifiers, json_object_new_string(names[i]));
- }
-
- json_object_object_add(sb_obj, "event_state_mask", modifiers);
-
- json_object *input_codes = json_object_new_array();
- int input_code = 0;
- json_object *symbols = json_object_new_array();
- json_object *symbol = NULL;
-
- if (sb->bindcode) { // bindcode: populate input_codes
- uint32_t keycode;
- for (i = 0; i < sb->keys->length; ++i) {
- keycode = *(uint32_t *)sb->keys->items[i];
- json_object_array_add(input_codes, json_object_new_int(keycode));
- if (i == 0) {
- input_code = keycode;
- }
- }
- } else { // bindsym: populate symbols
- uint32_t keysym;
- char buffer[64];
- for (i = 0; i < sb->keys->length; ++i) {
- keysym = *(uint32_t *)sb->keys->items[i];
- if (xkb_keysym_get_name(keysym, buffer, 64) > 0) {
- json_object *str = json_object_new_string(buffer);
- json_object_array_add(symbols, str);
- if (i == 0) {
- symbol = str;
- }
- }
- }
- }
-
- json_object_object_add(sb_obj, "input_codes", input_codes);
- json_object_object_add(sb_obj, "input_code", json_object_new_int(input_code));
- json_object_object_add(sb_obj, "symbols", symbols);
- json_object_object_add(sb_obj, "symbol", symbol);
- json_object_object_add(sb_obj, "input_type", json_object_new_string("keyboard"));
-
- ipc_event_binding(sb_obj);
-}
diff --git a/sway/old/layout.c b/sway/old/layout.c
deleted file mode 100644
index 22f81688..00000000
--- a/sway/old/layout.c
+++ /dev/null
@@ -1,1773 +0,0 @@
-#define _XOPEN_SOURCE 500
-#include <stdlib.h>
-#include <stdbool.h>
-#include <math.h>
-#include <wlc/wlc.h>
-#include "sway/config.h"
-#include "sway/container.h"
-#include "sway/workspace.h"
-#include "sway/focus.h"
-#include "sway/output.h"
-#include "sway/ipc-server.h"
-#include "sway/border.h"
-#include "sway/layout.h"
-#include "list.h"
-#include "log.h"
-
-swayc_t root_container;
-swayc_t *current_focus;
-list_t *scratchpad;
-
-int min_sane_h = 60;
-int min_sane_w = 100;
-
-void init_layout(void) {
- root_container.id = 0; // normally assigned in new_swayc()
- root_container.type = C_ROOT;
- root_container.layout = L_NONE;
- root_container.name = strdup("root");
- root_container.children = create_list();
- root_container.handle = -1;
- root_container.visible = true;
- current_focus = &root_container;
- scratchpad = create_list();
-}
-
-int index_child(const swayc_t *child) {
- swayc_t *parent = child->parent;
- int i, len;
- if (!child->is_floating) {
- len = parent->children->length;
- for (i = 0; i < len; ++i) {
- if (parent->children->items[i] == child) {
- break;
- }
- }
- } else {
- len = parent->floating->length;
- for (i = 0; i < len; ++i) {
- if (parent->floating->items[i] == child) {
- break;
- }
- }
- }
- if (!sway_assert(i < len, "Stray container")) {
- return -1;
- }
- return i;
-}
-
-void add_child(swayc_t *parent, swayc_t *child) {
- sway_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);
- list_add(parent->children, child);
- child->parent = parent;
- // set focus for this container
- if (!parent->focused) {
- parent->focused = child;
- }
- if (parent->type == C_WORKSPACE && child->type == C_VIEW && (parent->workspace_layout == L_TABBED || parent->workspace_layout == L_STACKED)) {
- child = new_container(child, parent->workspace_layout);
- }
-}
-
-static double *get_height(swayc_t *cont) {
- return &cont->height;
-}
-
-static double *get_width(swayc_t *cont) {
- return &cont->width;
-}
-
-void insert_child(swayc_t *parent, swayc_t *child, int index) {
- if (index > parent->children->length) {
- index = parent->children->length;
- }
- if (index < 0) {
- index = 0;
- }
- list_insert(parent->children, index, child);
- child->parent = parent;
- if (!parent->focused) {
- parent->focused = child;
- }
- if (parent->type == C_WORKSPACE && child->type == C_VIEW && (parent->workspace_layout == L_TABBED || parent->workspace_layout == L_STACKED)) {
- child = new_container(child, parent->workspace_layout);
- }
- if (is_auto_layout(parent->layout)) {
- /* go through each group, adjust the size of the first child of each group */
- double *(*get_maj_dim)(swayc_t *cont);
- double *(*get_min_dim)(swayc_t *cont);
- if (parent->layout == L_AUTO_LEFT || parent->layout == L_AUTO_RIGHT) {
- get_maj_dim = get_width;
- get_min_dim = get_height;
- } else {
- get_maj_dim = get_height;
- get_min_dim = get_width;
- }
- for (int i = index; i < parent->children->length;) {
- int start = auto_group_start_index(parent, i);
- int end = auto_group_end_index(parent, i);
- swayc_t *first = parent->children->items[start];
- if (start + 1 < parent->children->length) {
- /* preserve the group's dimension along major axis */
- *get_maj_dim(first) = *get_maj_dim(parent->children->items[start + 1]);
- } else {
- /* new group, let the apply_layout handle it */
- first->height = first->width = 0;
- break;
- }
- double remaining = *get_min_dim(parent);
- for (int j = end - 1; j > start; --j) {
- swayc_t *sibling = parent->children->items[j];
- if (sibling == child) {
- /* the inserted child won't yet have its minor
- dimension set */
- remaining -= *get_min_dim(parent) / (end - start);
- } else {
- remaining -= *get_min_dim(sibling);
- }
- }
- *get_min_dim(first) = remaining;
- i = end;
- }
- }
-}
-
-void add_floating(swayc_t *ws, swayc_t *child) {
- sway_log(L_DEBUG, "Adding %p (%d, %fx%f) to %p (%d, %fx%f)", child, child->type,
- child->width, child->height, ws, ws->type, ws->width, ws->height);
- if (!sway_assert(ws->type == C_WORKSPACE, "Must be of workspace type")) {
- return;
- }
- list_add(ws->floating, child);
- child->parent = ws;
- child->is_floating = true;
- if (!ws->focused) {
- ws->focused = child;
- }
- ipc_event_window(child, "floating");
-}
-
-swayc_t *add_sibling(swayc_t *fixed, swayc_t *active) {
- swayc_t *parent = fixed->parent;
- if (fixed->is_floating) {
- if (active->is_floating) {
- int i = index_child(fixed);
- list_insert(parent->floating, i + 1, active);
- } else {
- list_add(parent->children, active);
- }
- } else {
- if (active->is_floating) {
- list_add(parent->floating, active);
- } else {
- int i = index_child(fixed);
- if (is_auto_layout(parent->layout)) {
- list_add(parent->children, active);
- } else {
- list_insert(parent->children, i + 1, active);
- }
- }
- }
- active->parent = parent;
- // focus new child
- parent->focused = active;
- return active->parent;
-}
-
-swayc_t *replace_child(swayc_t *child, swayc_t *new_child) {
- swayc_t *parent = child->parent;
- if (parent == NULL) {
- return NULL;
- }
- int i = index_child(child);
- if (child->is_floating) {
- parent->floating->items[i] = new_child;
- } else {
- parent->children->items[i] = new_child;
- }
- // Set parent and focus for new_child
- new_child->parent = child->parent;
- if (child->parent->focused == child) {
- child->parent->focused = new_child;
- }
- child->parent = NULL;
-
- // Set geometry for new child
- new_child->x = child->x;
- new_child->y = child->y;
- new_child->width = child->width;
- new_child->height = child->height;
-
- // reset geometry for child
- child->width = 0;
- child->height = 0;
-
- // deactivate child
- if (child->type == C_VIEW) {
- wlc_view_set_state(child->handle, WLC_BIT_ACTIVATED, false);
- }
- return parent;
-}
-
-swayc_t *remove_child(swayc_t *child) {
- int i;
- swayc_t *parent = child->parent;
- if (child->is_floating) {
- // Special case for floating views
- for (i = 0; i < parent->floating->length; ++i) {
- if (parent->floating->items[i] == child) {
- list_del(parent->floating, i);
- break;
- }
- }
- i = 0;
- } else {
- for (i = 0; i < parent->children->length; ++i) {
- if (parent->children->items[i] == child) {
- list_del(parent->children, i);
- break;
- }
- }
- if (is_auto_layout(parent->layout) && parent->children->length) {
- /* go through each group, adjust the size of the last child of each group */
- double *(*get_maj_dim)(swayc_t *cont);
- double *(*get_min_dim)(swayc_t *cont);
- if (parent->layout == L_AUTO_LEFT || parent->layout == L_AUTO_RIGHT) {
- get_maj_dim = get_width;
- get_min_dim = get_height;
- } else {
- get_maj_dim = get_height;
- get_min_dim = get_width;
- }
- for (int j = parent->children->length - 1; j >= i;) {
- int start = auto_group_start_index(parent, j);
- int end = auto_group_end_index(parent, j);
- swayc_t *first = parent->children->items[start];
- if (i == start) {
- /* removed element was first child in the current group,
- use its size along the major axis */
- *get_maj_dim(first) = *get_maj_dim(child);
- } else if (start > i) {
- /* preserve the group's dimension along major axis */
- *get_maj_dim(first) = *get_maj_dim(parent->children->items[start - 1]);
- }
- if (end != parent->children->length) {
- double remaining = *get_min_dim(parent);
- for (int k = start; k < end - 1; ++k) {
- swayc_t *sibling = parent->children->items[k];
- remaining -= *get_min_dim(sibling);
- }
- /* last element of the group gets remaining size, elements
- that don't change groups keep their ratio */
- *get_min_dim((swayc_t *) parent->children->items[end - 1]) = remaining;
- } /* else last group, let apply_layout handle it */
- j = start - 1;
- }
- }
- }
- // Set focused to new container
- if (parent->focused == child) {
- if (parent->children->length > 0) {
- parent->focused = parent->children->items[i ? i-1:0];
- } else if (parent->floating && parent->floating->length) {
- parent->focused = parent->floating->items[parent->floating->length - 1];
- } else {
- parent->focused = NULL;
- }
- }
- child->parent = NULL;
- // deactivate view
- if (child->type == C_VIEW) {
- wlc_view_set_state(child->handle, WLC_BIT_ACTIVATED, false);
- }
- return parent;
-}
-
-void swap_container(swayc_t *a, swayc_t *b) {
- if (!sway_assert(a&&b, "parameters must be non null") ||
- !sway_assert(a->parent && b->parent, "containers must have parents")) {
- return;
- }
- size_t a_index = index_child(a);
- size_t b_index = index_child(b);
- swayc_t *a_parent = a->parent;
- swayc_t *b_parent = b->parent;
- // Swap the pointers
- if (a->is_floating) {
- a_parent->floating->items[a_index] = b;
- } else {
- a_parent->children->items[a_index] = b;
- }
- if (b->is_floating) {
- b_parent->floating->items[b_index] = a;
- } else {
- b_parent->children->items[b_index] = a;
- }
- a->parent = b_parent;
- b->parent = a_parent;
- if (a_parent->focused == a) {
- a_parent->focused = b;
- }
- // don't want to double switch
- if (b_parent->focused == b && a_parent != b_parent) {
- b_parent->focused = a;
- }
-}
-
-void swap_geometry(swayc_t *a, swayc_t *b) {
- double x = a->x;
- double y = a->y;
- double w = a->width;
- double h = a->height;
- a->x = b->x;
- a->y = b->y;
- a->width = b->width;
- a->height = b->height;
- b->x = x;
- b->y = y;
- b->width = w;
- b->height = h;
-}
-
-static void swap_children(swayc_t *container, int a, int b) {
- if (a >= 0 && b >= 0 && a < container->children->length
- && b < container->children->length
- && a != b) {
- swayc_t *pa = (swayc_t *)container->children->items[a];
- swayc_t *pb = (swayc_t *)container->children->items[b];
- container->children->items[a] = container->children->items[b];
- container->children->items[b] = pa;
- if (is_auto_layout(container->layout)) {
- size_t ga = auto_group_index(container, a);
- size_t gb = auto_group_index(container, b);
- if (ga != gb) {
- swap_geometry(pa, pb);
- }
- }
- }
-}
-
-void move_container(swayc_t *container, enum movement_direction dir, int move_amt) {
- enum swayc_layouts layout = L_NONE;
- swayc_t *parent = container->parent;
- if (container->is_floating) {
- swayc_t *output = swayc_parent_by_type(container, C_OUTPUT);
- switch(dir) {
- case MOVE_LEFT:
- container->x = MAX(0, container->x - move_amt);
- break;
- case MOVE_RIGHT:
- container->x = MIN(output->width - container->width, container->x + move_amt);
- break;
- case MOVE_UP:
- container->y = MAX(0, container->y - move_amt);
- break;
- case MOVE_DOWN:
- container->y = MIN(output->height - container->height, container->y + move_amt);
- break;
- default:
- break;
- }
- update_geometry(container);
- return;
- }
- if (container->type != C_VIEW && container->type != C_CONTAINER) {
- return;
- }
- if (dir == MOVE_UP || dir == MOVE_DOWN) {
- layout = L_VERT;
- } else if (dir == MOVE_LEFT || dir == MOVE_RIGHT) {
- layout = L_HORIZ;
- } else if (dir == MOVE_FIRST) {
- // swap first child in auto layout with currently focused child
- if (is_auto_layout(parent->layout)) {
- int focused_idx = index_child(container);
- swayc_t *first = parent->children->items[0];
- if (focused_idx > 0) {
- list_swap(parent->children, 0, focused_idx);
- swap_geometry(first, container);
- }
- arrange_windows(parent->parent, -1, -1);
- ipc_event_window(container, "move");
- set_focused_container_for(parent->parent, container);
- }
- return;
- } else if (! (dir == MOVE_NEXT || dir == MOVE_PREV)) {
- return;
- }
- swayc_t *child = container;
- bool ascended = false;
-
- // View is wrapped in intermediate container which is needed for displaying
- // the titlebar. Moving only the view outside of its parent container would just
- // wrap it again under worspace. There would effectively be no movement,
- // just a change of wrapping container.
- if (child->type == C_VIEW &&
- parent->type == C_CONTAINER &&
- parent->children->length == 1 &&
- parent->parent->type == C_WORKSPACE) {
- child = parent;
- parent = parent->parent;
- }
-
- while (true) {
- sway_log(L_DEBUG, "container:%p, parent:%p, child %p,",
- container,parent,child);
- if (parent->layout == layout
- || (layout == L_NONE && (parent->type == C_CONTAINER || parent->type == C_WORKSPACE)) /* accept any layout for next/prev direction */
- || (parent->layout == L_TABBED && layout == L_HORIZ)
- || (parent->layout == L_STACKED && layout == L_VERT)
- || is_auto_layout(parent->layout)) {
- int diff;
- // If it has ascended (parent has moved up), no container is removed
- // so insert it at index, or index+1.
- // if it has not, the moved container is removed, so it needs to be
- // inserted at index-1, or index+1
- if (ascended) {
- diff = dir == MOVE_LEFT || dir == MOVE_UP || dir == MOVE_PREV ? 0 : 1;
- } else {
- diff = dir == MOVE_LEFT || dir == MOVE_UP || dir == MOVE_PREV ? -1 : 1;
- }
- int idx = index_child(child);
- int desired = idx + diff;
- if (dir == MOVE_NEXT || dir == MOVE_PREV) {
- // Next/Prev always wrap.
- if (desired < 0) {
- desired += parent->children->length;
- } else if (desired >= parent->children->length) {
- desired = 0;
- }
- }
- // when it has ascended, legal insertion position is 0:len
- // when it has not, legal insertion position is 0:len-1
- if (desired >= 0 && desired - ascended < parent->children->length) {
- if (!ascended) {
- child = parent->children->items[desired];
- // Move container into sibling container
- if (child->type == C_CONTAINER) {
- parent = child;
- // Insert it in first/last if matching layout, otherwise
- // insert it next to focused container
- if (parent->layout == layout
- || (parent->layout == L_TABBED && layout == L_HORIZ)
- || (parent->layout == L_STACKED && layout == L_VERT)
- || is_auto_layout(parent->layout)) {
- desired = (diff < 0) * parent->children->length;
- } else {
- desired = index_child(child->focused) + 1;
- }
- //reset geometry
- container->width = container->height = 0;
- }
- }
- if (container->parent == parent) {
- swap_children(parent, idx, desired);
- } else {
- swayc_t *old_parent = remove_child(container);
- insert_child(parent, container, desired);
- destroy_container(old_parent);
- sway_log(L_DEBUG,"Moving to %p %d", parent, desired);
- }
- break;
- }
- }
- // Change parent layout if we need to
- if (parent->children->length == 1 && parent->layout != layout && layout != L_NONE) {
- /* swayc_change_layout(parent, layout); */
- parent->layout = layout;
- continue;
- }
- if (parent->type == C_WORKSPACE) {
- // If moving to an adjacent output we need a starting position (since this
- // output might border to multiple outputs).
- struct wlc_point abs_pos;
- get_absolute_center_position(container, &abs_pos);
-
- swayc_t *output = swayc_adjacent_output(parent->parent, dir, &abs_pos, true);
-
- if (output) {
- sway_log(L_DEBUG, "Moving between outputs");
- swayc_t *old_parent = remove_child(container);
- destroy_container(old_parent);
-
- swayc_t *dest = output->focused;
- switch (dir) {
- case MOVE_LEFT:
- case MOVE_UP:
- // reset container geometry
- container->width = container->height = 0;
- add_child(dest, container);
- break;
- case MOVE_RIGHT:
- case MOVE_DOWN:
- // reset container geometry
- container->width = container->height = 0;
- insert_child(dest, container, 0);
- break;
- default:
- break;
- }
- // arrange new workspace
- arrange_windows(dest, -1, -1);
- set_focused_container(container);
- break;
- }
-
- // We simply cannot move any further.
- if (parent->layout == layout) {
- break;
- }
- // Create container around workspace to insert child into
- parent = new_container(parent, layout);
- // Previous line set the resulting container's layout to
- // workspace_layout. It should have been just layout.
- parent->layout = parent->parent->layout;
- }
- ascended = true;
- child = parent;
- parent = child->parent;
- }
- arrange_windows(parent->parent, -1, -1);
- ipc_event_window(container, "move");
- set_focused_container_for(parent->parent, container);
-}
-
-void move_container_to(swayc_t* container, swayc_t* destination) {
- if (container == destination || swayc_is_parent_of(container, destination)) {
- return;
- }
- swayc_t *parent = remove_child(container);
- // Send to new destination
- if (container->is_floating) {
- swayc_t *ws = swayc_active_workspace_for(destination);
- add_floating(ws, container);
-
- // If the workspace only has one child after adding one, it
- // means that the workspace was just initialized.
- if (ws->children->length + ws->floating->length == 1) {
- ipc_event_workspace(NULL, ws, "init");
- }
- } else if (destination->type == C_WORKSPACE) {
- // reset container geometry
- container->width = container->height = 0;
- add_child(destination, container);
-
- // If the workspace only has one child after adding one, it
- // means that the workspace was just initialized.
- if (destination->children->length + destination->floating->length == 1) {
- ipc_event_workspace(NULL, destination, "init");
- }
- } else {
- // reset container geometry
- container->width = container->height = 0;
- add_sibling(destination, container);
- }
- // Destroy old container if we need to
- parent = destroy_container(parent);
- // Refocus
- swayc_t *op1 = swayc_parent_by_type(destination, C_OUTPUT);
- swayc_t *op2 = swayc_parent_by_type(parent, C_OUTPUT);
- set_focused_container(get_focused_view(op1));
- arrange_windows(op1, -1, -1);
- update_visibility(op1);
- if (op1 != op2) {
- set_focused_container(get_focused_view(op2));
- arrange_windows(op2, -1, -1);
- update_visibility(op2);
- }
-}
-
-void move_workspace_to(swayc_t* workspace, swayc_t* destination) {
- if (workspace == destination || swayc_is_parent_of(workspace, destination)) {
- return;
- }
- swayc_t *src_op = remove_child(workspace);
- // reset container geometry
- workspace->width = workspace->height = 0;
- add_child(destination, workspace);
- sort_workspaces(destination);
- // Refocus destination (change to new workspace)
- set_focused_container(get_focused_view(workspace));
- arrange_windows(destination, -1, -1);
- update_visibility(destination);
-
- // make sure source output has a workspace
- if (src_op->children->length == 0) {
- char *ws_name = workspace_next_name(src_op->name);
- swayc_t *ws = new_workspace(src_op, ws_name);
- ws->is_focused = true;
- free(ws_name);
- }
- set_focused_container(get_focused_view(src_op));
- update_visibility(src_op);
-}
-
-static void adjust_border_geometry(swayc_t *c, struct wlc_geometry *g,
- const struct wlc_size *res, int left, int right, int top, int bottom) {
-
- g->size.w += left + right;
- if (g->origin.x - left < 0) {
- g->size.w += g->origin.x - left;
- } else if (g->origin.x + g->size.w - right > res->w) {
- g->size.w = res->w - g->origin.x + right;
- }
-
- g->size.h += top + bottom;
- if (g->origin.y - top < 0) {
- g->size.h += g->origin.y - top;
- } else if (g->origin.y + g->size.h - top > res->h) {
- g->size.h = res->h - g->origin.y + top;
- }
-
- g->origin.x = MIN((uint32_t)MAX(g->origin.x - left, 0), res->w);
- g->origin.y = MIN((uint32_t)MAX(g->origin.y - top, 0), res->h);
-
-}
-
-static void update_border_geometry_floating(swayc_t *c, struct wlc_geometry *geometry) {
- struct wlc_geometry g = *geometry;
- c->actual_geometry = g;
-
- swayc_t *output = swayc_parent_by_type(c, C_OUTPUT);
- struct wlc_size res;
- output_get_scaled_size(output->handle, &res);
-
- switch (c->border_type) {
- case B_NONE:
- break;
- case B_PIXEL:
- adjust_border_geometry(c, &g, &res, c->border_thickness,
- c->border_thickness, c->border_thickness, c->border_thickness);
- break;
- case B_NORMAL:
- {
- int title_bar_height = config->font_height + 4; // borders + padding
-
- adjust_border_geometry(c, &g, &res, c->border_thickness,
- c->border_thickness, title_bar_height, c->border_thickness);
-
- struct wlc_geometry title_bar = {
- .origin = {
- .x = c->actual_geometry.origin.x - c->border_thickness,
- .y = c->actual_geometry.origin.y - title_bar_height
- },
- .size = {
- .w = c->actual_geometry.size.w + (2 * c->border_thickness),
- .h = title_bar_height
- }
- };
- c->title_bar_geometry = title_bar;
- break;
- }
- }
-
- c->border_geometry = g;
- *geometry = c->actual_geometry;
-
- update_container_border(c);
-}
-
-void update_layout_geometry(swayc_t *parent, enum swayc_layouts prev_layout) {
- switch (parent->layout) {
- case L_TABBED:
- case L_STACKED:
- if (prev_layout != L_TABBED && prev_layout != L_STACKED) {
- // cache current geometry for all non-float children
- int i;
- for (i = 0; i < parent->children->length; ++i) {
- swayc_t *child = parent->children->items[i];
- child->cached_geometry.origin.x = child->x;
- child->cached_geometry.origin.y = child->y;
- child->cached_geometry.size.w = child->width;
- child->cached_geometry.size.h = child->height;
- }
- }
- break;
- default:
- if (prev_layout == L_TABBED || prev_layout == L_STACKED) {
- // recover cached geometry for all non-float children
- int i;
- for (i = 0; i < parent->children->length; ++i) {
- swayc_t *child = parent->children->items[i];
- // only recoverer cached geometry if non-zero
- if (!wlc_geometry_equals(&child->cached_geometry, &wlc_geometry_zero)) {
- child->x = child->cached_geometry.origin.x;
- child->y = child->cached_geometry.origin.y;
- child->width = child->cached_geometry.size.w;
- child->height = child->cached_geometry.size.h;
- }
- }
- }
- break;
- }
-}
-
-static int update_gap_geometry(swayc_t *container, struct wlc_geometry *g) {
- swayc_t *ws = swayc_parent_by_type(container, C_WORKSPACE);
- swayc_t *op = ws->parent;
- int gap = container->is_floating ? 0 : swayc_gap(container);
- if (gap % 2 != 0) {
- // because gaps are implemented as "half sized margins" it's currently
- // not possible to align views properly with odd sized gaps.
- gap -= 1;
- }
-
- g->origin.x = container->x + gap/2 < op->width ? container->x + gap/2 : op->width-1;
- g->origin.y = container->y + gap/2 < op->height ? container->y + gap/2 : op->height-1;
- g->size.w = container->width > gap ? container->width - gap : 1;
- g->size.h = container->height > gap ? container->height - gap : 1;
-
- if ((!config->edge_gaps && gap > 0) || (config->smart_gaps && ws->children->length == 1)) {
- // Remove gap against the workspace edges. Because a pixel is not
- // divisable, depending on gap size and the number of siblings our view
- // might be at the workspace edge without being exactly so (thus test
- // with gap, and align correctly).
- if (container->x - gap <= ws->x) {
- g->origin.x = ws->x;
- g->size.w = container->width - gap/2;
- }
- if (container->y - gap <= ws->y) {
- g->origin.y = ws->y;
- g->size.h = container->height - gap/2;
- }
- if (container->x + container->width + gap >= ws->x + ws->width) {
- g->size.w = ws->x + ws->width - g->origin.x;
- }
- if (container->y + container->height + gap >= ws->y + ws->height) {
- g->size.h = ws->y + ws->height - g->origin.y;
- }
- }
-
- return gap;
-}
-
-void update_geometry(swayc_t *container) {
- if (container->type != C_VIEW && container->type != C_CONTAINER) {
- return;
- }
-
- swayc_t *workspace = swayc_parent_by_type(container, C_WORKSPACE);
- swayc_t *op = workspace->parent;
- swayc_t *parent = container->parent;
-
- struct wlc_geometry geometry = {
- .origin = {
- .x = container->x < op->width ? container->x : op->width-1,
- .y = container->y < op->height ? container->y : op->height-1
- },
- .size = {
- .w = container->width,
- .h = container->height,
- }
- };
-
- int gap = 0;
-
- // apply inner gaps to non-tabbed/stacked containers
- swayc_t *p = swayc_tabbed_stacked_ancestor(container);
- if (p == NULL) {
- gap = update_gap_geometry(container, &geometry);
- }
-
- swayc_t *output = swayc_parent_by_type(container, C_OUTPUT);
- struct wlc_size size;
- output_get_scaled_size(output->handle, &size);
-
- if (swayc_is_fullscreen(container)) {
- geometry.origin.x = 0;
- geometry.origin.y = 0;
- geometry.size.w = size.w;
- geometry.size.h = size.h;
- if (op->focused == workspace) {
- wlc_view_bring_to_front(container->handle);
- }
-
- container->border_geometry = wlc_geometry_zero;
- container->title_bar_geometry = wlc_geometry_zero;
- border_clear(container->border);
- } else if (container->is_floating) { // allocate border for floating window
- update_border_geometry_floating(container, &geometry);
- } else if (!container->is_floating) { // allocate border for titled window
- container->border_geometry = geometry;
-
- int border_top = container->border_thickness;
- int border_bottom = container->border_thickness;
- int border_left = container->border_thickness;
- int border_right = container->border_thickness;
-
- // handle hide_edge_borders
- if (config->hide_edge_borders != E_NONE && (gap <= 0 || (config->smart_gaps && workspace->children->length == 1))) {
- if (config->hide_edge_borders == E_VERTICAL || config->hide_edge_borders == E_BOTH) {
- if (geometry.origin.x == workspace->x) {
- border_left = 0;
- }
-
- if (geometry.origin.x + geometry.size.w == workspace->x + workspace->width) {
- border_right = 0;
- }
- }
-
- if (config->hide_edge_borders == E_HORIZONTAL || config->hide_edge_borders == E_BOTH) {
- if (geometry.origin.y == workspace->y || should_hide_top_border(container, geometry.origin.y)) {
- border_top = 0;
- }
-
- if (geometry.origin.y + geometry.size.h == workspace->y + workspace->height) {
- border_bottom = 0;
- }
- }
-
- if (config->hide_edge_borders == E_SMART && workspace->children->length == 1) {
- border_top = 0;
- border_bottom = 0;
- border_left = 0;
- border_right = 0;
- }
- }
-
- int title_bar_height = config->font_height + 4; //borders + padding
-
- if (parent->layout == L_TABBED && parent->children->length > 1) {
- int i, x = 0, w, l, r;
- l = parent->children->length;
- w = geometry.size.w / l;
- r = geometry.size.w % l;
- for (i = 0; i < parent->children->length; ++i) {
- swayc_t *view = parent->children->items[i];
- if (view == container) {
- x = w * i;
- if (i == l - 1) {
- w += r;
- }
- break;
- }
- }
-
- struct wlc_geometry title_bar = {
- .origin = {
- .x = container->border_geometry.origin.x + x,
- .y = container->border_geometry.origin.y
- },
- .size = {
- .w = w,
- .h = title_bar_height
- }
- };
- geometry.origin.x += border_left;
- geometry.origin.y += title_bar.size.h;
- geometry.size.w -= (border_left + border_right);
- geometry.size.h -= (border_bottom + title_bar.size.h);
- container->title_bar_geometry = title_bar;
- } else if (parent->layout == L_STACKED && parent->children->length > 1) {
- int i, y = 0;
- for (i = 0; i < parent->children->length; ++i) {
- swayc_t *view = parent->children->items[i];
- if (view == container) {
- y = title_bar_height * i;
- }
- }
-
- struct wlc_geometry title_bar = {
- .origin = {
- .x = container->border_geometry.origin.x,
- .y = container->border_geometry.origin.y + y
- },
- .size = {
- .w = container->border_geometry.size.w,
- .h = title_bar_height
- }
- };
- title_bar_height = title_bar_height * parent->children->length;
- geometry.origin.x += border_left;
- geometry.origin.y += title_bar_height;
- geometry.size.w -= (border_left + border_right);
- geometry.size.h -= (border_bottom + title_bar_height);
- container->title_bar_geometry = title_bar;
- } else {
- switch (container->border_type) {
- case B_NONE:
- break;
- case B_PIXEL:
- geometry.origin.x += border_left;
- geometry.origin.y += border_top;
- geometry.size.w -= (border_left + border_right);
- geometry.size.h -= (border_top + border_bottom);
- break;
- case B_NORMAL:
- {
- struct wlc_geometry title_bar = {
- .origin = {
- .x = container->border_geometry.origin.x,
- .y = container->border_geometry.origin.y
- },
- .size = {
- .w = container->border_geometry.size.w,
- .h = title_bar_height
- }
- };
- geometry.origin.x += border_left;
- geometry.origin.y += title_bar.size.h;
- geometry.size.w -= (border_left + border_right);
- geometry.size.h -= (border_bottom + title_bar.size.h);
- container->title_bar_geometry = title_bar;
- break;
- }
- }
- }
-
- container->actual_geometry = geometry;
-
- if (container->type == C_VIEW) {
- update_container_border(container);
- }
- }
-
- if (container->type == C_VIEW) {
- wlc_view_set_geometry(container->handle, 0, &geometry);
- }
-}
-
-/**
- * Layout application prototypes
- */
-static void apply_horiz_layout(swayc_t *container, const double x,
- const double y, const double width,
- const double height, const int start,
- const int end);
-static void apply_vert_layout(swayc_t *container, const double x,
- const double y, const double width,
- const double height, const int start,
- const int end);
-static void apply_tabbed_or_stacked_layout(swayc_t *container, double x,
- double y, double width,
- double height);
-
-static void apply_auto_layout(swayc_t *container, const double x, const double y,
- const double width, const double height,
- enum swayc_layouts group_layout,
- bool master_first);
-
-static void arrange_windows_r(swayc_t *container, double width, double height) {
- int i;
- if (width == -1 || height == -1) {
- swayc_log(L_DEBUG, container, "Arranging layout for %p", container);
- width = container->width;
- height = container->height;
- }
- // pixels are indivisible. if we don't round the pixels, then the view
- // calculations will be off (e.g. 50.5 + 50.5 = 101, but in reality it's
- // 50 + 50 = 100). doing it here cascades properly to all width/height/x/y.
- width = floor(width);
- height = floor(height);
-
- sway_log(L_DEBUG, "Arranging layout for %p %s %fx%f+%f,%f", container,
- container->name, container->width, container->height, container->x,
- container->y);
-
- double x = 0, y = 0;
- switch (container->type) {
- case C_ROOT:
- for (i = 0; i < container->children->length; ++i) {
- swayc_t *output = container->children->items[i];
- sway_log(L_DEBUG, "Arranging output '%s' at %f,%f", output->name, output->x, output->y);
- arrange_windows_r(output, -1, -1);
- }
- return;
- case C_OUTPUT:
- {
- struct wlc_size resolution;
- output_get_scaled_size(container->handle, &resolution);
- width = resolution.w; height = resolution.h;
- // output must have correct size due to e.g. seamless mouse,
- // but a workspace might be smaller depending on panels.
- container->width = width;
- container->height = height;
- }
- // arrange all workspaces:
- for (i = 0; i < container->children->length; ++i) {
- swayc_t *child = container->children->items[i];
- arrange_windows_r(child, -1, -1);
- }
- // Bring all unmanaged views to the front
- for (i = 0; i < container->unmanaged->length; ++i) {
- wlc_handle *handle = container->unmanaged->items[i];
- wlc_view_bring_to_front(*handle);
- }
- return;
- case C_WORKSPACE:
- {
- swayc_t *output = swayc_parent_by_type(container, C_OUTPUT);
- width = output->width, height = output->height;
- /* TODO WLR
- for (i = 0; i < desktop_shell.panels->length; ++i) {
- struct panel_config *config = desktop_shell.panels->items[i];
- if (config->output == output->handle) {
- struct wlc_size size = *wlc_surface_get_size(config->surface);
- sway_log(L_DEBUG, "-> Found panel for this workspace: %ux%u, position: %u", size.w, size.h, config->panel_position);
- switch (config->panel_position) {
- case DESKTOP_SHELL_PANEL_POSITION_TOP:
- y += size.h; height -= size.h;
- break;
- case DESKTOP_SHELL_PANEL_POSITION_BOTTOM:
- height -= size.h;
- break;
- case DESKTOP_SHELL_PANEL_POSITION_LEFT:
- x += size.w; width -= size.w;
- break;
- case DESKTOP_SHELL_PANEL_POSITION_RIGHT:
- width -= size.w;
- break;
- }
- }
- }
- */
- int gap = swayc_gap(container);
- x = container->x = x + gap;
- y = container->y = y + gap;
- width = container->width = width - gap * 2;
- height = container->height = height - gap * 2;
- sway_log(L_DEBUG, "Arranging workspace '%s' at %f, %f", container->name, container->x, container->y);
- }
- // children are properly handled below
- break;
- case C_VIEW:
- {
- container->width = width;
- container->height = height;
- update_geometry(container);
- sway_log(L_DEBUG, "Set view to %.f x %.f @ %.f, %.f", container->width,
- container->height, container->x, container->y);
- }
- return;
- default:
- container->width = width;
- container->height = height;
- x = container->x;
- y = container->y;
-
- // add gaps to top level tapped/stacked container
- if (container->parent->type == C_WORKSPACE &&
- (container->layout == L_TABBED || container->layout == L_STACKED)) {
- update_geometry(container);
- width = container->border_geometry.size.w;
- height = container->border_geometry.size.h;
- x = container->border_geometry.origin.x;
- y = container->border_geometry.origin.y;
- }
-
- // update container size if it's a direct child in a tabbed/stacked layout
- // if parent is a workspace, its actual_geometry won't be initialized
- if (swayc_tabbed_stacked_parent(container) != NULL &&
- container->parent->type != C_WORKSPACE) {
- // Use parent actual_geometry as a base for calculating
- // container geometry
- container->width = container->parent->actual_geometry.size.w;
- container->height = container->parent->actual_geometry.size.h;
- container->x = container->parent->actual_geometry.origin.x;
- container->y = container->parent->actual_geometry.origin.y;
-
- update_geometry(container);
- width = container->width = container->actual_geometry.size.w;
- height = container->height = container->actual_geometry.size.h;
- x = container->x = container->actual_geometry.origin.x;
- y = container->y = container->actual_geometry.origin.y;
- }
-
- break;
- }
-
- switch (container->layout) {
- case L_HORIZ:
- default:
- apply_horiz_layout(container, x, y, width, height, 0,
- container->children->length);
- break;
- case L_VERT:
- apply_vert_layout(container, x, y, width, height, 0,
- container->children->length);
- break;
- case L_TABBED:
- case L_STACKED:
- apply_tabbed_or_stacked_layout(container, x, y, width, height);
- break;
- case L_AUTO_LEFT:
- apply_auto_layout(container, x, y, width, height, L_VERT, true);
- break;
- case L_AUTO_RIGHT:
- apply_auto_layout(container, x, y, width, height, L_VERT, false);
- break;
- case L_AUTO_TOP:
- apply_auto_layout(container, x, y, width, height, L_HORIZ, true);
- break;
- case L_AUTO_BOTTOM:
- apply_auto_layout(container, x, y, width, height, L_HORIZ, false);
- break;
- }
-
- // Arrage floating layouts for workspaces last
- if (container->type == C_WORKSPACE) {
- for (int i = 0; i < container->floating->length; ++i) {
- swayc_t *view = container->floating->items[i];
- if (view->type == C_VIEW) {
- update_geometry(view);
- sway_log(L_DEBUG, "Set floating view to %.f x %.f @ %.f, %.f",
- view->width, view->height, view->x, view->y);
- if (swayc_is_fullscreen(view)) {
- wlc_view_bring_to_front(view->handle);
- } else if (!container->focused ||
- !swayc_is_fullscreen(container->focused)) {
- wlc_view_bring_to_front(view->handle);
- }
- }
- }
- }
-}
-
-void apply_horiz_layout(swayc_t *container, const double x, const double y,
- const double width, const double height,
- const int start, const int end) {
- double scale = 0;
- // Calculate total width
- for (int i = start; i < end; ++i) {
- double *old_width = &((swayc_t *)container->children->items[i])->width;
- if (*old_width <= 0) {
- if (end - start > 1) {
- *old_width = width / (end - start - 1);
- } else {
- *old_width = width;
- }
- }
- scale += *old_width;
- }
- scale = width / scale;
-
- // Resize windows
- double child_x = x;
- if (scale > 0.1) {
- sway_log(L_DEBUG, "Arranging %p horizontally", container);
- swayc_t *focused = NULL;
- for (int i = start; i < end; ++i) {
- swayc_t *child = container->children->items[i];
- sway_log(L_DEBUG,
- "Calculating arrangement for %p:%d (will scale %f by %f)", child,
- child->type, width, scale);
- child->x = child_x;
- child->y = y;
-
- if (child == container->focused) {
- focused = child;
- }
-
- if (i == end - 1) {
- double remaining_width = x + width - child_x;
- arrange_windows_r(child, remaining_width, height);
- } else {
- arrange_windows_r(child, child->width * scale, height);
- }
- child_x += child->width;
- }
-
- // update focused view border last because it may
- // depend on the title bar geometry of its siblings.
- if (focused && container->children->length > 1) {
- update_container_border(focused);
- }
- }
-}
-
-void apply_vert_layout(swayc_t *container, const double x, const double y,
- const double width, const double height, const int start,
- const int end) {
- int i;
- double scale = 0;
- // Calculate total height
- for (i = start; i < end; ++i) {
- double *old_height = &((swayc_t *)container->children->items[i])->height;
- if (*old_height <= 0) {
- if (end - start > 1) {
- *old_height = height / (end - start - 1);
- } else {
- *old_height = height;
- }
- }
- scale += *old_height;
- }
- scale = height / scale;
-
- // Resize
- double child_y = y;
- if (scale > 0.1) {
- sway_log(L_DEBUG, "Arranging %p vertically", container);
- swayc_t *focused = NULL;
- for (i = start; i < end; ++i) {
- swayc_t *child = container->children->items[i];
- sway_log(L_DEBUG,
- "Calculating arrangement for %p:%d (will scale %f by %f)", child,
- child->type, height, scale);
- child->x = x;
- child->y = child_y;
-
- if (child == container->focused) {
- focused = child;
- }
-
- if (i == end - 1) {
- double remaining_height = y + height - child_y;
- arrange_windows_r(child, width, remaining_height);
- } else {
- arrange_windows_r(child, width, child->height * scale);
- }
- child_y += child->height;
- }
-
- // update focused view border last because it may
- // depend on the title bar geometry of its siblings.
- if (focused && container->children->length > 1) {
- update_container_border(focused);
- }
- }
-}
-
-void apply_tabbed_or_stacked_layout(swayc_t *container, double x, double y,
- double width, double height) {
- int i;
- swayc_t *focused = NULL;
- for (i = 0; i < container->children->length; ++i) {
- swayc_t *child = container->children->items[i];
- child->x = x;
- child->y = y;
- if (child == container->focused) {
- focused = child;
- } else {
- arrange_windows_r(child, width, height);
- }
- }
-
- if (focused) {
- arrange_windows_r(focused, width, height);
- }
-}
-
-void apply_auto_layout(swayc_t *container, const double x, const double y,
- const double width, const double height,
- enum swayc_layouts group_layout,
- bool master_first) {
- // Auto layout "container" in width x height @ x, y
- // using "group_layout" for each of the groups in the container.
- // There is one "master" group, plus container->nb_slave_groups.
- // Each group is layed out side by side following the "major" axis.
- // The direction of the layout used for groups is the "minor" axis.
- // Example:
- //
- // ---- major axis -->
- // +---------+-----------+
- // | | | |
- // | master | slave 1 | |
- // | +-----------+ | minor axis (direction of group_layout)
- // | | | |
- // | | slave 2 | V
- // +---------+-----------+
- //
- // container with three children (one master and two slaves) and
- // a single slave group (containing slave 1 and 2). The master
- // group and slave group are layed out using L_VERT.
-
- size_t nb_groups = auto_group_count(container);
-
- // the target dimension of the container along the "major" axis, each
- // group in the container will be layed out using "group_layout" along
- // the "minor" axis.
- double dim_maj;
- double pos_maj;
-
- // x and y coords for the next group to be laid out.
- const double *group_x, *group_y;
-
- // pos of the next group to layout along the major axis
- double pos;
-
- // size of the next group along the major axis.
- double group_dim;
-
- // height and width of next group to be laid out.
- const double *group_h, *group_w;
-
- switch (group_layout) {
- default:
- sway_log(L_DEBUG, "Unknown layout type (%d) used in %s()",
- group_layout, __func__);
- /* fall through */
- case L_VERT:
- dim_maj = width;
- pos_maj = x;
-
- group_x = &pos;
- group_y = &y;
- group_w = &group_dim;
- group_h = &height;
- break;
- case L_HORIZ:
- dim_maj = height;
- pos_maj = y;
-
- group_x = &x;
- group_y = &pos;
- group_w = &width;
- group_h = &group_dim;
- break;
- }
-
- /* Determine the dimension of each of the groups in the layout.
- * Dimension will be width for a VERT layout and height for a HORIZ
- * layout. */
- double old_group_dim[nb_groups];
- double old_dim = 0;
- for (size_t group = 0; group < nb_groups; ++group) {
- int idx;
- if (auto_group_bounds(container, group, &idx, NULL)) {
- swayc_t *child = container->children->items[idx];
- double *dim = group_layout == L_HORIZ ? &child->height : &child->width;
- if (*dim <= 0) {
- // New child with uninitialized dimension
- *dim = dim_maj;
- if (nb_groups > 1) {
- // child gets a dimension proportional to existing groups,
- // it will be later scaled based on to the available size
- // in the major axis.
- *dim /= (nb_groups - 1);
- }
- }
- old_dim += *dim;
- old_group_dim[group] = *dim;
- }
- }
- double scale = dim_maj / old_dim;
-
- /* Apply layout to each group */
- pos = pos_maj;
-
- for (size_t group = 0; group < nb_groups; ++group) {
- int start, end; // index of first (inclusive) and last (exclusive) child in the group
- if (auto_group_bounds(container, group, &start, &end)) {
- // adjusted size of the group
- group_dim = old_group_dim[group] * scale;
- if (group == nb_groups - 1) {
- group_dim = pos_maj + dim_maj - pos; // remaining width
- }
- sway_log(L_DEBUG, "Arranging container %p column %zu, children [%d,%d[ (%fx%f+%f,%f)",
- container, group, start, end, *group_w, *group_h, *group_x, *group_y);
- switch (group_layout) {
- default:
- case L_VERT:
- apply_vert_layout(container, *group_x, *group_y, *group_w, *group_h, start, end);
- break;
- case L_HORIZ:
- apply_horiz_layout(container, *group_x, *group_y, *group_w, *group_h, start, end);
- break;
- }
-
- /* update position for next group */
- pos += group_dim;
- }
- }
-}
-
-void arrange_windows(swayc_t *container, double width, double height) {
- update_visibility(container);
- arrange_windows_r(container, width, height);
- layout_log(&root_container, 0);
-}
-
-void arrange_backgrounds(void) {
- /* TODO WLR
- struct background_config *bg;
- for (int i = 0; i < desktop_shell.backgrounds->length; ++i) {
- bg = desktop_shell.backgrounds->items[i];
- wlc_view_send_to_back(bg->handle);
- }
- */
-}
-
-/**
- * Get swayc in the direction of newly entered output.
- */
-static swayc_t *get_swayc_in_output_direction(swayc_t *output, enum movement_direction dir) {
- if (!output) {
- return NULL;
- }
-
- swayc_t *ws = swayc_focus_by_type(output, C_WORKSPACE);
- if (ws && ws->children->length > 0) {
- switch (dir) {
- case MOVE_LEFT:
- // get most right child of new output
- return ws->children->items[ws->children->length-1];
- case MOVE_RIGHT:
- // get most left child of new output
- return ws->children->items[0];
- case MOVE_UP:
- case MOVE_DOWN:
- {
- swayc_t *focused_view = swayc_focus_by_type(ws, C_VIEW);
- if (focused_view && focused_view->parent) {
- swayc_t *parent = focused_view->parent;
- if (parent->layout == L_VERT) {
- if (dir == MOVE_UP) {
- // get child furthest down on new output
- return parent->children->items[parent->children->length-1];
- } else if (dir == MOVE_DOWN) {
- // get child furthest up on new output
- return parent->children->items[0];
- }
- }
- return focused_view;
- }
- break;
- }
- default:
- break;
- }
- }
-
- return output;
-}
-
-swayc_t *get_swayc_in_direction_under(swayc_t *container, enum movement_direction dir, swayc_t *limit) {
- if (dir == MOVE_CHILD) {
- return container->focused;
- }
-
- swayc_t *parent = container->parent;
- if (dir == MOVE_PARENT) {
- if (parent->type == C_OUTPUT) {
- return NULL;
- } else {
- return parent;
- }
- }
-
- if (dir == MOVE_PREV || dir == MOVE_NEXT) {
- int focused_idx = index_child(container);
- if (focused_idx == -1) {
- return NULL;
- } else {
- int desired = (focused_idx + (dir == MOVE_NEXT ? 1 : -1)) %
- parent->children->length;
- if (desired < 0) {
- desired += parent->children->length;
- }
- return parent->children->items[desired];
- }
- }
-
- // If moving to an adjacent output we need a starting position (since this
- // output might border to multiple outputs).
- struct wlc_point abs_pos;
- get_absolute_center_position(container, &abs_pos);
-
- if (container->type == C_VIEW && swayc_is_fullscreen(container)) {
- sway_log(L_DEBUG, "Moving from fullscreen view, skipping to output");
- container = swayc_parent_by_type(container, C_OUTPUT);
- get_absolute_center_position(container, &abs_pos);
- swayc_t *output = swayc_adjacent_output(container, dir, &abs_pos, true);
- return get_swayc_in_output_direction(output, dir);
- }
-
- if (container->type == C_WORKSPACE && container->fullscreen) {
- sway_log(L_DEBUG, "Moving to fullscreen view");
- return container->fullscreen;
- }
-
- swayc_t *wrap_candidate = NULL;
- while (true) {
- // Test if we can even make a difference here
- bool can_move = false;
- int desired;
- int idx = index_child(container);
- if (parent->type == C_ROOT) {
- swayc_t *output = swayc_adjacent_output(container, dir, &abs_pos, true);
- if (!output || output == container) {
- return wrap_candidate;
- }
- sway_log(L_DEBUG, "Moving between outputs");
- return get_swayc_in_output_direction(output, dir);
- } else {
- if (is_auto_layout(parent->layout)) {
- bool is_major = parent->layout == L_AUTO_LEFT || parent->layout == L_AUTO_RIGHT
- ? dir == MOVE_LEFT || dir == MOVE_RIGHT
- : dir == MOVE_DOWN || dir == MOVE_UP;
- size_t gidx = auto_group_index(parent, idx);
- if (is_major) {
- size_t desired_grp = gidx + (dir == MOVE_RIGHT || dir == MOVE_DOWN ? 1 : -1);
- can_move = auto_group_bounds(parent, desired_grp, &desired, NULL);
- } else {
- desired = idx + (dir == MOVE_RIGHT || dir == MOVE_DOWN ? 1 : -1);
- int start, end;
- can_move = auto_group_bounds(parent, gidx, &start, &end)
- && desired >= start && desired < end;
- }
- } else {
- if (dir == MOVE_LEFT || dir == MOVE_RIGHT) {
- if (parent->layout == L_HORIZ || parent->layout == L_TABBED) {
- can_move = true;
- desired = idx + (dir == MOVE_LEFT ? -1 : 1);
- }
- } else {
- if (parent->layout == L_VERT || parent->layout == L_STACKED) {
- can_move = true;
- desired = idx + (dir == MOVE_UP ? -1 : 1);
- }
- }
- }
- }
-
- if (can_move) {
- if (container->is_floating) {
- if (desired < 0) {
- wrap_candidate = parent->floating->items[parent->floating->length-1];
- } else if (desired >= parent->floating->length){
- wrap_candidate = parent->floating->items[0];
- } else {
- wrap_candidate = parent->floating->items[desired];
- }
- if (wrap_candidate) {
- wlc_view_bring_to_front(wrap_candidate->handle);
- }
- return wrap_candidate;
- } else if (desired < 0 || desired >= parent->children->length) {
- can_move = false;
- int len = parent->children->length;
- if (!wrap_candidate && len > 1) {
- if (desired < 0) {
- wrap_candidate = parent->children->items[len-1];
- } else {
- wrap_candidate = parent->children->items[0];
- }
- if (config->force_focus_wrapping) {
- return wrap_candidate;
- }
- }
- } else {
- sway_log(L_DEBUG, "%s cont %d-%p dir %i sibling %d: %p", __func__,
- idx, container, dir, desired, parent->children->items[desired]);
- return parent->children->items[desired];
- }
- }
- if (!can_move) {
- container = parent;
- parent = parent->parent;
- if (!parent || container == limit) {
- // wrapping is the last chance
- return wrap_candidate;
- }
- }
- }
-}
-
-swayc_t *get_swayc_in_direction(swayc_t *container, enum movement_direction dir) {
- return get_swayc_in_direction_under(container, dir, NULL);
-}
-
-void recursive_resize(swayc_t *container, double amount, enum wlc_resize_edge edge) {
- int i;
- bool layout_match = true;
- sway_log(L_DEBUG, "Resizing %p with amount: %f", container, amount);
- if (edge == WLC_RESIZE_EDGE_LEFT || edge == WLC_RESIZE_EDGE_RIGHT) {
- container->width += amount;
- layout_match = container->layout == L_HORIZ;
- } else if (edge == WLC_RESIZE_EDGE_TOP || edge == WLC_RESIZE_EDGE_BOTTOM) {
- container->height += amount;
- layout_match = container->layout == L_VERT;
- }
- if (container->type == C_VIEW) {
- update_geometry(container);
- return;
- }
- if (layout_match) {
- for (i = 0; i < container->children->length; i++) {
- recursive_resize(container->children->items[i], amount/container->children->length, edge);
- }
- } else {
- for (i = 0; i < container->children->length; i++) {
- recursive_resize(container->children->items[i], amount, edge);
- }
- }
-}
-
-enum swayc_layouts default_layout(swayc_t *output) {
- if (config->default_layout != L_NONE) {
- return config->default_layout;
- } else if (config->default_orientation != L_NONE) {
- return config->default_orientation;
- } else if (output->width >= output->height) {
- return L_HORIZ;
- } else {
- return L_VERT;
- }
-}
-
-bool is_auto_layout(enum swayc_layouts layout) {
- return (layout >= L_AUTO_FIRST) && (layout <= L_AUTO_LAST);
-}
-
-/**
- * Return the number of master elements in a container
- */
-static inline size_t auto_master_count(const swayc_t *container) {
- sway_assert(container->children->length >= 0, "Container %p has (negative) children %d",
- container, container->children->length);
- return MIN(container->nb_master, (size_t)container->children->length);
-}
-
-/**
- * Return the number of children in the slave groups. This corresponds to the children
- * that are not members of the master group.
- */
-static inline size_t auto_slave_count(const swayc_t *container) {
- return container->children->length - auto_master_count(container);
-}
-
-/**
- * Return the number of slave groups in the container.
- */
-size_t auto_slave_group_count(const swayc_t *container) {
- return MIN(container->nb_slave_groups, auto_slave_count(container));
-}
-
-/**
- * Return the combined number of master and slave groups in the container.
- */
-size_t auto_group_count(const swayc_t *container) {
- return auto_slave_group_count(container)
- + (container->children->length && container->nb_master ? 1 : 0);
-}
-
-/**
- * given the index of a container's child, return the index of the first child of the group
- * which index is a member of.
- */
-int auto_group_start_index(const swayc_t *container, int index) {
- if (index < 0 || ! is_auto_layout(container->layout)
- || (size_t)index < container->nb_master) {
- return 0;
- } else {
- size_t nb_slaves = auto_slave_count(container);
- size_t nb_slave_grp = auto_slave_group_count(container);
- size_t grp_sz = nb_slaves / nb_slave_grp;
- size_t remainder = nb_slaves % nb_slave_grp;
- int idx2 = (nb_slave_grp - remainder) * grp_sz + container->nb_master;
- int start_idx;
- if (index < idx2) {
- start_idx = ((index - container->nb_master) / grp_sz) * grp_sz + container->nb_master;
- } else {
- start_idx = idx2 + ((index - idx2) / (grp_sz + 1)) * (grp_sz + 1);
- }
- return MIN(start_idx, container->children->length);
- }
-}
-
-/**
- * given the index of a container's child, return the index of the first child of the group
- * that follows the one which index is a member of.
- * This makes the function usable to walk through the groups in a container.
- */
-int auto_group_end_index(const swayc_t *container, int index) {
- if (index < 0 || ! is_auto_layout(container->layout)) {
- return container->children->length;
- } else {
- int nxt_idx;
- if ((size_t)index < container->nb_master) {
- nxt_idx = auto_master_count(container);
- } else {
- size_t nb_slaves = auto_slave_count(container);
- size_t nb_slave_grp = auto_slave_group_count(container);
- size_t grp_sz = nb_slaves / nb_slave_grp;
- size_t remainder = nb_slaves % nb_slave_grp;
- int idx2 = (nb_slave_grp - remainder) * grp_sz + container->nb_master;
- if (index < idx2) {
- nxt_idx = ((index - container->nb_master) / grp_sz + 1) * grp_sz + container->nb_master;
- } else {
- nxt_idx = idx2 + ((index - idx2) / (grp_sz + 1) + 1) * (grp_sz + 1);
- }
- }
- return MIN(nxt_idx, container->children->length);
- }
-}
-
-/**
- * return the index of the Group containing <index>th child of <container>.
- * The index is the order of the group along the container's major axis (starting at 0).
- */
-size_t auto_group_index(const swayc_t *container, int index) {
- if (index < 0) {
- return 0;
- }
- bool master_first = (container->layout == L_AUTO_LEFT || container->layout == L_AUTO_TOP);
- size_t nb_slaves = auto_slave_count(container);
- if ((size_t)index < container->nb_master) {
- if (master_first || nb_slaves <= 0) {
- return 0;
- } else {
- return auto_slave_group_count(container);
- }
- } else {
- size_t nb_slave_grp = auto_slave_group_count(container);
- size_t grp_sz = nb_slaves / nb_slave_grp;
- size_t remainder = nb_slaves % nb_slave_grp;
- int idx2 = (nb_slave_grp - remainder) * grp_sz + container->nb_master;
- size_t grp_idx;
- if (index < idx2) {
- grp_idx = (index - container->nb_master) / grp_sz;
- } else {
- grp_idx = (nb_slave_grp - remainder) + (index - idx2) / (grp_sz + 1) ;
- }
- return grp_idx + (master_first && container-> nb_master ? 1 : 0);
- }
-}
-
-/**
- * Return the first index (inclusive) and last index (exclusive) of the elements of a group in
- * an auto layout.
- * If the bounds of the given group can be calculated, they are returned in the start/end
- * parameters (int pointers) and the return value will be true.
- * The indexes are passed by reference and can be NULL.
- */
-bool auto_group_bounds(const swayc_t *container, size_t group_index, int *start, int *end) {
- size_t nb_grp = auto_group_count(container);
- if (group_index >= nb_grp) {
- return false;
- }
- bool master_first = (container->layout == L_AUTO_LEFT || container->layout == L_AUTO_TOP);
- size_t nb_master = auto_master_count(container);
- size_t nb_slave_grp = auto_slave_group_count(container);
- int g_start, g_end;
- if (nb_master && (master_first ? group_index == 0 : group_index == nb_grp - 1)) {
- g_start = 0;
- g_end = nb_master;
- } else {
- size_t nb_slaves = auto_slave_count(container);
- size_t grp_sz = nb_slaves / nb_slave_grp;
- size_t remainder = nb_slaves % nb_slave_grp;
- size_t g0 = master_first && container->nb_master ? 1 : 0;
- size_t g1 = g0 + nb_slave_grp - remainder;
- if (group_index < g1) {
- g_start = container->nb_master + (group_index - g0) * grp_sz;
- g_end = g_start + grp_sz;
- } else {
- size_t g2 = group_index - g1;
- g_start = container->nb_master
- + (nb_slave_grp - remainder) * grp_sz
- + g2 * (grp_sz + 1);
- g_end = g_start + grp_sz + 1;
- }
- }
- if (start) {
- *start = g_start;
- }
- if (end) {
- *end = g_end;
- }
- return true;
-}
diff --git a/sway/old/output.c b/sway/old/output.c
deleted file mode 100644
index edfcac98..00000000
--- a/sway/old/output.c
+++ /dev/null
@@ -1,278 +0,0 @@
-#define _POSIX_C_SOURCE 200809L
-#include <strings.h>
-#include <ctype.h>
-#include <stdlib.h>
-#include "sway/output.h"
-#include "log.h"
-#include "list.h"
-
-void output_get_scaled_size(wlc_handle handle, struct wlc_size *size) {
- *size = *wlc_output_get_resolution(handle);
- uint32_t scale = wlc_output_get_scale(handle);
- size->w /= scale;
- size->h /= scale;
-}
-
-swayc_t *output_by_name(const char* name, const struct wlc_point *abs_pos) {
- swayc_t *output = NULL;
- // If there is no output directly next to the current one, use
- // swayc_opposite_output to wrap.
- if (strcasecmp(name, "left") == 0) {
- output = swayc_adjacent_output(NULL, MOVE_LEFT, abs_pos, true);
- if (!output) {
- output = swayc_opposite_output(MOVE_RIGHT, abs_pos);
- }
- } else if (strcasecmp(name, "right") == 0) {
- output = swayc_adjacent_output(NULL, MOVE_RIGHT, abs_pos, true);
- if (!output) {
- output = swayc_opposite_output(MOVE_LEFT, abs_pos);
- }
- } else if (strcasecmp(name, "up") == 0) {
- output = swayc_adjacent_output(NULL, MOVE_UP, abs_pos, true);
- if (!output) {
- output = swayc_opposite_output(MOVE_DOWN, abs_pos);
- }
- } else if (strcasecmp(name, "down") == 0) {
- output = swayc_adjacent_output(NULL, MOVE_DOWN, abs_pos, true);
- if (!output) {
- output = swayc_opposite_output(MOVE_UP, abs_pos);
- }
- } else {
- for(int i = 0; i < root_container.children->length; ++i) {
- swayc_t *c = root_container.children->items[i];
- if (c->type == C_OUTPUT && strcasecmp(c->name, name) == 0) {
- return c;
- }
- }
- }
- return output;
-}
-
-swayc_t *swayc_opposite_output(enum movement_direction dir,
- const struct wlc_point *abs_pos) {
-
- // Search through all the outputs and pick the output whose edge covers the
- // given position, and is at leftmost/rightmost/upmost/downmost side of the
- // screen (decided by the direction given).
- swayc_t *opposite = NULL;
- char *dir_text = NULL;
- switch(dir) {
- case MOVE_LEFT:
- case MOVE_RIGHT: ;
- for (int i = 0; i < root_container.children->length; ++i) {
- swayc_t *c = root_container.children->items[i];
- if (abs_pos->y >= c->y && abs_pos->y <= c->y + c->height) {
- if (!opposite) {
- opposite = c;
- } else if ((dir == MOVE_LEFT && c->x < opposite->x)
- || (dir == MOVE_RIGHT && c->x > opposite->x)) {
- opposite = c;
- }
- }
- }
- dir_text = dir == MOVE_LEFT ? "leftmost" : "rightmost";
- break;
- case MOVE_UP:
- case MOVE_DOWN: ;
- for (int i = 0; i < root_container.children->length; ++i) {
- swayc_t *c = root_container.children->items[i];
- if (abs_pos->x >= c->x && abs_pos->x <= c->x + c->width) {
- if (!opposite) {
- opposite = c;
- } else if ((dir == MOVE_UP && c->y < opposite->y)
- || (dir == MOVE_DOWN && c->y > opposite->y)) {
- opposite = c;
- }
- }
- }
- dir_text = dir == MOVE_UP ? "upmost" : "downmost";
- break;
- default:
- sway_abort("Function called with invalid argument.");
- break;
- }
- if (opposite) {
- sway_log(L_DEBUG, "%s (%.0fx%.0f+%.0f+%.0f) is %s from y-position %i",
- opposite->name, opposite->width, opposite->height, opposite->x, opposite->y,
- dir_text, abs_pos->y);
- }
- return opposite;
-}
-
-// Position is where on the edge (as absolute position) the adjacent output should be searched for.
-swayc_t *swayc_adjacent_output(swayc_t *output, enum movement_direction dir,
- const struct wlc_point *abs_pos, bool pick_closest) {
-
- if (!output) {
- output = swayc_active_output();
- }
- // In order to find adjacent outputs we need to test that the outputs are
- // aligned on one axis (decided by the direction given) and that the given
- // position is within the edge of the adjacent output. If no such output
- // exists we pick the adjacent output within the edge that is closest to
- // the given position, if any.
- swayc_t *adjacent = NULL;
- char *dir_text = NULL;
- switch(dir) {
- case MOVE_LEFT:
- case MOVE_RIGHT: ;
- double delta_y = 0;
- for(int i = 0; i < root_container.children->length; ++i) {
- swayc_t *c = root_container.children->items[i];
- if (c == output || c->type != C_OUTPUT) {
- continue;
- }
- bool x_aligned = dir == MOVE_LEFT ?
- c->x + c->width == output->x :
- c->x == output->x + output->width;
- if (!x_aligned) {
- continue;
- }
- if (abs_pos->y >= c->y && abs_pos->y <= c->y + c->height) {
- delta_y = 0;
- adjacent = c;
- break;
- } else if (pick_closest) {
- // track closest adjacent output
- double top_y = c->y, bottom_y = c->y + c->height;
- if (top_y >= output->y && top_y <= output->y + output->height) {
- double delta = top_y - abs_pos->y;
- if (delta < 0) delta = -delta;
- if (delta < delta_y || !adjacent) {
- delta_y = delta;
- adjacent = c;
- }
- }
- // we check both points and pick the closest
- if (bottom_y >= output->y && bottom_y <= output->y + output->height) {
- double delta = bottom_y - abs_pos->y;
- if (delta < 0) delta = -delta;
- if (delta < delta_y || !adjacent) {
- delta_y = delta;
- adjacent = c;
- }
- }
- }
- }
- dir_text = dir == MOVE_LEFT ? "left of" : "right of";
- if (adjacent && delta_y == 0) {
- sway_log(L_DEBUG, "%s (%.0fx%.0f+%.0f+%.0f) is %s current output %s (y-position %i)",
- adjacent->name, adjacent->width, adjacent->height, adjacent->x, adjacent->y,
- dir_text, output->name, abs_pos->y);
- } else if (adjacent) {
- // so we end up picking the closest adjacent output because
- // there is no directly adjacent to the given position
- sway_log(L_DEBUG, "%s (%.0fx%.0f+%.0f+%.0f) is %s current output %s (y-position %i, delta: %.0f)",
- adjacent->name, adjacent->width, adjacent->height, adjacent->x, adjacent->y,
- dir_text, output->name, abs_pos->y, delta_y);
- }
- break;
- case MOVE_UP:
- case MOVE_DOWN: ;
- double delta_x = 0;
- for(int i = 0; i < root_container.children->length; ++i) {
- swayc_t *c = root_container.children->items[i];
- if (c == output || c->type != C_OUTPUT) {
- continue;
- }
- bool y_aligned = dir == MOVE_UP ?
- c->y + c->height == output->y :
- c->y == output->y + output->height;
- if (!y_aligned) {
- continue;
- }
- if (abs_pos->x >= c->x && abs_pos->x <= c->x + c->width) {
- delta_x = 0;
- adjacent = c;
- break;
- } else if (pick_closest) {
- // track closest adjacent output
- double left_x = c->x, right_x = c->x + c->width;
- if (left_x >= output->x && left_x <= output->x + output->width) {
- double delta = left_x - abs_pos->x;
- if (delta < 0) delta = -delta;
- if (delta < delta_x || !adjacent) {
- delta_x = delta;
- adjacent = c;
- }
- }
- // we check both points and pick the closest
- if (right_x >= output->x && right_x <= output->x + output->width) {
- double delta = right_x - abs_pos->x;
- if (delta < 0) delta = -delta;
- if (delta < delta_x || !adjacent) {
- delta_x = delta;
- adjacent = c;
- }
- }
- }
- }
- dir_text = dir == MOVE_UP ? "above" : "below";
- if (adjacent && delta_x == 0) {
- sway_log(L_DEBUG, "%s (%.0fx%.0f+%.0f+%.0f) is %s current output %s (x-position %i)",
- adjacent->name, adjacent->width, adjacent->height, adjacent->x, adjacent->y,
- dir_text, output->name, abs_pos->x);
- } else if (adjacent) {
- // so we end up picking the closest adjacent output because
- // there is no directly adjacent to the given position
- sway_log(L_DEBUG, "%s (%.0fx%.0f+%.0f+%.0f) is %s current output %s (x-position %i, delta: %.0f)",
- adjacent->name, adjacent->width, adjacent->height, adjacent->x, adjacent->y,
- dir_text, output->name, abs_pos->x, delta_x);
- }
- break;
- default:
- sway_abort("Function called with invalid argument.");
- break;
- }
- return adjacent;
-}
-
-void get_absolute_position(swayc_t *container, struct wlc_point *point) {
- if (!container || !point)
- sway_abort("Need container and wlc_point (was %p, %p).", container, point);
-
- if (container->type == C_OUTPUT) {
- // Coordinates are already absolute.
- point->x = container->x;
- point->y = container->y;
- } else {
- swayc_t *output = swayc_parent_by_type(container, C_OUTPUT);
- if (container->type == C_WORKSPACE) {
- // Workspace coordinates are actually wrong/arbitrary, but should
- // be same as output.
- point->x = output->x;
- point->y = output->y;
- } else {
- point->x = output->x + container->x;
- point->y = output->y + container->y;
- }
- }
-}
-
-void get_absolute_center_position(swayc_t *container, struct wlc_point *point) {
- get_absolute_position(container, point);
- point->x += container->width/2;
- point->y += container->height/2;
-}
-
-static int sort_workspace_cmp_qsort(const void *_a, const void *_b) {
- swayc_t *a = *(void **)_a;
- swayc_t *b = *(void **)_b;
- int retval = 0;
-
- if (isdigit(a->name[0]) && isdigit(b->name[0])) {
- int a_num = strtol(a->name, NULL, 10);
- int b_num = strtol(b->name, NULL, 10);
- retval = (a_num < b_num) ? -1 : (a_num > b_num);
- } else if (isdigit(a->name[0])) {
- retval = -1;
- } else if (isdigit(b->name[0])) {
- retval = 1;
- }
-
- return retval;
-}
-
-void sort_workspaces(swayc_t *output) {
- list_stable_sort(output->children, sort_workspace_cmp_qsort);
-}
diff --git a/sway/old/security.c b/sway/old/security.c
deleted file mode 100644
index fcd70f9d..00000000
--- a/sway/old/security.c
+++ /dev/null
@@ -1,228 +0,0 @@
-#define _XOPEN_SOURCE 700
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <string.h>
-#include <unistd.h>
-#include <stdio.h>
-#include "sway/config.h"
-#include "sway/security.h"
-#include "log.h"
-
-static bool validate_ipc_target(const char *program) {
- struct stat sb;
-
- sway_log(L_DEBUG, "Validating IPC target '%s'", program);
-
- if (!strcmp(program, "*")) {
- return true;
- }
- if (lstat(program, &sb) == -1) {
- return false;
- }
- if (!S_ISREG(sb.st_mode)) {
- sway_log(L_ERROR,
- "IPC target '%s' MUST be/point at an existing regular file",
- program);
- return false;
- }
- if (sb.st_uid != 0) {
-#ifdef NDEBUG
- sway_log(L_ERROR, "IPC target '%s' MUST be owned by root", program);
- return false;
-#else
- sway_log(L_INFO, "IPC target '%s' MUST be owned by root (waived for debug build)", program);
- return true;
-#endif
- }
- if (sb.st_mode & S_IWOTH) {
- sway_log(L_ERROR, "IPC target '%s' MUST NOT be world writable", program);
- return false;
- }
-
- return true;
-}
-
-struct feature_policy *alloc_feature_policy(const char *program) {
- uint32_t default_policy = 0;
-
- if (!validate_ipc_target(program)) {
- return NULL;
- }
- for (int i = 0; i < config->feature_policies->length; ++i) {
- struct feature_policy *policy = config->feature_policies->items[i];
- if (strcmp(policy->program, "*") == 0) {
- default_policy = policy->features;
- break;
- }
- }
-
- struct feature_policy *policy = malloc(sizeof(struct feature_policy));
- if (!policy) {
- return NULL;
- }
- policy->program = strdup(program);
- if (!policy->program) {
- free(policy);
- return NULL;
- }
- policy->features = default_policy;
-
- return policy;
-}
-
-struct ipc_policy *alloc_ipc_policy(const char *program) {
- uint32_t default_policy = 0;
-
- if (!validate_ipc_target(program)) {
- return NULL;
- }
- for (int i = 0; i < config->ipc_policies->length; ++i) {
- struct ipc_policy *policy = config->ipc_policies->items[i];
- if (strcmp(policy->program, "*") == 0) {
- default_policy = policy->features;
- break;
- }
- }
-
- struct ipc_policy *policy = malloc(sizeof(struct ipc_policy));
- if (!policy) {
- return NULL;
- }
- policy->program = strdup(program);
- if (!policy->program) {
- free(policy);
- return NULL;
- }
- policy->features = default_policy;
-
- return policy;
-}
-
-struct command_policy *alloc_command_policy(const char *command) {
- struct command_policy *policy = malloc(sizeof(struct command_policy));
- if (!policy) {
- return NULL;
- }
- policy->command = strdup(command);
- if (!policy->command) {
- free(policy);
- return NULL;
- }
- policy->context = 0;
- return policy;
-}
-
-static const char *get_pid_exe(pid_t pid) {
-#ifdef __FreeBSD__
- const char *fmt = "/proc/%d/file";
-#else
- const char *fmt = "/proc/%d/exe";
-#endif
- int pathlen = snprintf(NULL, 0, fmt, pid);
- char *path = malloc(pathlen + 1);
- if (path) {
- snprintf(path, pathlen + 1, fmt, pid);
- }
-
- static char link[2048];
-
- ssize_t len = !path ? -1 : readlink(path, link, sizeof(link));
- if (len < 0) {
- sway_log(L_INFO,
- "WARNING: unable to read %s for security check. Using default policy.",
- path);
- strcpy(link, "*");
- } else {
- link[len] = '\0';
- }
- free(path);
-
- return link;
-}
-
-struct feature_policy *get_feature_policy(const char *name) {
- struct feature_policy *policy = NULL;
-
- for (int i = 0; i < config->feature_policies->length; ++i) {
- struct feature_policy *p = config->feature_policies->items[i];
- if (strcmp(p->program, name) == 0) {
- policy = p;
- break;
- }
- }
- if (!policy) {
- policy = alloc_feature_policy(name);
- sway_assert(policy, "Unable to allocate security policy");
- if (policy) {
- list_add(config->feature_policies, policy);
- }
- }
- return policy;
-}
-
-uint32_t get_feature_policy_mask(pid_t pid) {
- uint32_t default_policy = 0;
- const char *link = get_pid_exe(pid);
-
- for (int i = 0; i < config->feature_policies->length; ++i) {
- struct feature_policy *policy = config->feature_policies->items[i];
- if (strcmp(policy->program, "*") == 0) {
- default_policy = policy->features;
- }
- if (strcmp(policy->program, link) == 0) {
- return policy->features;
- }
- }
-
- return default_policy;
-}
-
-uint32_t get_ipc_policy_mask(pid_t pid) {
- uint32_t default_policy = 0;
- const char *link = get_pid_exe(pid);
-
- for (int i = 0; i < config->ipc_policies->length; ++i) {
- struct ipc_policy *policy = config->ipc_policies->items[i];
- if (strcmp(policy->program, "*") == 0) {
- default_policy = policy->features;
- }
- if (strcmp(policy->program, link) == 0) {
- return policy->features;
- }
- }
-
- return default_policy;
-}
-
-uint32_t get_command_policy_mask(const char *cmd) {
- uint32_t default_policy = 0;
-
- for (int i = 0; i < config->command_policies->length; ++i) {
- struct command_policy *policy = config->command_policies->items[i];
- if (strcmp(policy->command, "*") == 0) {
- default_policy = policy->context;
- }
- if (strcmp(policy->command, cmd) == 0) {
- return policy->context;
- }
- }
-
- return default_policy;
-}
-
-const char *command_policy_str(enum command_context context) {
- switch (context) {
- case CONTEXT_ALL:
- return "all";
- case CONTEXT_CONFIG:
- return "config";
- case CONTEXT_BINDING:
- return "binding";
- case CONTEXT_IPC:
- return "IPC";
- case CONTEXT_CRITERIA:
- return "criteria";
- default:
- return "unknown";
- }
-}
diff --git a/sway/old/workspace.c b/sway/old/workspace.c
deleted file mode 100644
index 14cde146..00000000
--- a/sway/old/workspace.c
+++ /dev/null
@@ -1,373 +0,0 @@
-#define _XOPEN_SOURCE 500
-#include <stdlib.h>
-#include <stdbool.h>
-#include <limits.h>
-#include <ctype.h>
-#include <wlc/wlc.h>
-#include <string.h>
-#include <strings.h>
-#include <sys/types.h>
-#include "sway/ipc-server.h"
-#include "sway/workspace.h"
-#include "sway/layout.h"
-#include "sway/container.h"
-#include "sway/handlers.h"
-#include "sway/config.h"
-#include "sway/focus.h"
-#include "stringop.h"
-#include "util.h"
-#include "list.h"
-#include "log.h"
-#include "ipc.h"
-
-char *prev_workspace_name = NULL;
-struct workspace_by_number_data {
- int len;
- const char *cset;
- const char *name;
-};
-
-static bool workspace_valid_on_output(const char *output_name, const char *ws_name) {
- int i;
- for (i = 0; i < config->workspace_outputs->length; ++i) {
- struct workspace_output *wso = config->workspace_outputs->items[i];
- if (strcasecmp(wso->workspace, ws_name) == 0) {
- if (strcasecmp(wso->output, output_name) != 0) {
- return false;
- }
- }
- }
-
- return true;
-}
-
-char *workspace_next_name(const char *output_name) {
- sway_log(L_DEBUG, "Workspace: Generating new workspace name for output %s", output_name);
- int i;
- 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;
-
- int order = INT_MAX;
- char *target = NULL;
- for (i = 0; i < mode->bindings->length; ++i) {
- struct sway_binding *binding = mode->bindings->items[i];
- char *cmdlist = strdup(binding->command);
- char *dup = cmdlist;
- char *name = NULL;
-
- // workspace n
- char *cmd = argsep(&cmdlist, " ");
- if (cmdlist) {
- name = argsep(&cmdlist, ",;");
- }
-
- if (strcmp("workspace", cmd) == 0 && name) {
- sway_log(L_DEBUG, "Got valid workspace command for target: '%s'", name);
- char *_target = strdup(name);
- strip_quotes(_target);
- while (isspace(*_target))
- _target++;
-
- // Make sure that the command references an actual workspace
- // not a command about workspaces
- if (strcmp(_target, "next") == 0 ||
- strcmp(_target, "prev") == 0 ||
- strcmp(_target, "next_on_output") == 0 ||
- strcmp(_target, "prev_on_output") == 0 ||
- strcmp(_target, "number") == 0 ||
- strcmp(_target, "back_and_forth") == 0 ||
- strcmp(_target, "current") == 0)
- {
- free(_target);
- free(dup);
- continue;
- }
-
- // Make sure that the workspace doesn't already exist
- if (workspace_by_name(_target)) {
- free(_target);
- free(dup);
- continue;
- }
-
- // make sure that the workspace can appear on the given
- // output
- if (!workspace_valid_on_output(output_name, _target)) {
- free(_target);
- free(dup);
- continue;
- }
-
- if (binding->order < order) {
- order = binding->order;
- free(target);
- target = _target;
- sway_log(L_DEBUG, "Workspace: Found free name %s", _target);
- }
- }
- free(dup);
- }
- if (target != NULL) {
- return target;
- }
- // 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;
- if (ws_num >= 10) {
- l = 2;
- } else if (ws_num >= 100) {
- l = 3;
- }
- char *name = malloc(l + 1);
- if (!name) {
- sway_log(L_ERROR, "Could not allocate workspace name");
- return NULL;
- }
- sprintf(name, "%d", ws_num++);
- return name;
-}
-
-swayc_t *workspace_create(const char* name) {
- swayc_t *parent;
- // Search for workspace<->output pair
- int i, e = config->workspace_outputs->length;
- for (i = 0; i < e; ++i) {
- struct workspace_output *wso = config->workspace_outputs->items[i];
- if (strcasecmp(wso->workspace, name) == 0)
- {
- // Find output to use if it exists
- e = root_container.children->length;
- for (i = 0; i < e; ++i) {
- parent = root_container.children->items[i];
- if (strcmp(parent->name, wso->output) == 0) {
- return new_workspace(parent, name);
- }
- }
- break;
- }
- }
- // Otherwise create a new one
- parent = get_focused_container(&root_container);
- parent = swayc_parent_by_type(parent, C_OUTPUT);
- return new_workspace(parent, name);
-}
-
-static bool _workspace_by_name(swayc_t *view, void *data) {
- return (view->type == C_WORKSPACE) &&
- (strcasecmp(view->name, (char *) data) == 0);
-}
-
-swayc_t *workspace_by_name(const char* name) {
- if (strcmp(name, "prev") == 0) {
- return workspace_prev();
- }
- else if (strcmp(name, "prev_on_output") == 0) {
- return workspace_output_prev();
- }
- else if (strcmp(name, "next") == 0) {
- return workspace_next();
- }
- else if (strcmp(name, "next_on_output") == 0) {
- return workspace_output_next();
- }
- else if (strcmp(name, "current") == 0) {
- return swayc_active_workspace();
- }
- else {
- return swayc_by_test(&root_container, _workspace_by_name, (void *) name);
- }
-}
-
-static bool _workspace_by_number(swayc_t *view, void *data) {
- if (view->type != C_WORKSPACE) {
- return false;
- }
- struct workspace_by_number_data *wbnd = data;
- int a = strspn(view->name, wbnd->cset);
- return a == wbnd->len && strncmp(view->name, wbnd->name, a) == 0;
-}
-swayc_t *workspace_by_number(const char* name) {
- struct workspace_by_number_data wbnd = {0, "1234567890", name};
- wbnd.len = strspn(name, wbnd.cset);
- if (wbnd.len <= 0) {
- return NULL;
- }
- return swayc_by_test(&root_container, _workspace_by_number, (void *) &wbnd);
-}
-
-/**
- * Get the previous or next workspace on the specified output.
- * Wraps around at the end and beginning.
- * If next is false, the previous workspace is returned, otherwise the next one is returned.
- */
-swayc_t *workspace_output_prev_next_impl(swayc_t *output, bool next) {
- if (!sway_assert(output->type == C_OUTPUT, "Argument must be an output, is %d", output->type)) {
- return NULL;
- }
-
- int i;
- for (i = 0; i < output->children->length; i++) {
- if (output->children->items[i] == output->focused) {
- return output->children->items[wrap(i + (next ? 1 : -1), output->children->length)];
- }
- }
-
- // Doesn't happen, at worst the for loop returns the previously active workspace
- return NULL;
-}
-
-/**
- * Get the previous or next workspace. If the first/last workspace on an output is active,
- * proceed to the previous/next output's previous/next workspace.
- * If next is false, the previous workspace is returned, otherwise the next one is returned.
- */
-swayc_t *workspace_prev_next_impl(swayc_t *workspace, bool next) {
- if (!sway_assert(workspace->type == C_WORKSPACE, "Argument must be a workspace, is %d", workspace->type)) {
- return NULL;
- }
-
- swayc_t *current_output = workspace->parent;
- int offset = next ? 1 : -1;
- int start = next ? 0 : 1;
- int end = next ? (current_output->children->length) - 1 : current_output->children->length;
- int i;
- for (i = start; i < end; i++) {
- if (current_output->children->items[i] == workspace) {
- return current_output->children->items[i + offset];
- }
- }
-
- // Given workspace is the first/last on the output, jump to the previous/next output
- int num_outputs = root_container.children->length;
- for (i = 0; i < num_outputs; i++) {
- if (root_container.children->items[i] == current_output) {
- swayc_t *next_output = root_container.children->items[wrap(i + offset, num_outputs)];
- return workspace_output_prev_next_impl(next_output, next);
- }
- }
-
- // Doesn't happen, at worst the for loop returns the previously active workspace on the active output
- return NULL;
-}
-
-swayc_t *workspace_output_next() {
- return workspace_output_prev_next_impl(swayc_active_output(), true);
-}
-
-swayc_t *workspace_next() {
- return workspace_prev_next_impl(swayc_active_workspace(), true);
-}
-
-swayc_t *workspace_output_prev() {
- return workspace_output_prev_next_impl(swayc_active_output(), false);
-}
-
-swayc_t *workspace_prev() {
- return workspace_prev_next_impl(swayc_active_workspace(), false);
-}
-
-bool workspace_switch(swayc_t *workspace) {
- if (!workspace) {
- return false;
- }
- swayc_t *active_ws = swayc_active_workspace();
- if (config->auto_back_and_forth && active_ws == workspace && prev_workspace_name) {
- swayc_t *new_ws = workspace_by_name(prev_workspace_name);
- workspace = new_ws ? new_ws : workspace_create(prev_workspace_name);
- }
-
- if (!prev_workspace_name
- || (strcmp(prev_workspace_name, active_ws->name)
- && active_ws != workspace)) {
- free(prev_workspace_name);
- prev_workspace_name = malloc(strlen(active_ws->name) + 1);
- if (!prev_workspace_name) {
- sway_log(L_ERROR, "Unable to allocate previous workspace name");
- return false;
- }
- strcpy(prev_workspace_name, active_ws->name);
- }
-
- // move sticky containers
- if (swayc_parent_by_type(active_ws, C_OUTPUT) == swayc_parent_by_type(workspace, C_OUTPUT)) {
- // don't change list while traversing it, use intermediate list instead
- list_t *stickies = create_list();
- for (int i = 0; i < active_ws->floating->length; i++) {
- swayc_t *cont = active_ws->floating->items[i];
- if (cont->sticky) {
- list_add(stickies, cont);
- }
- }
- for (int i = 0; i < stickies->length; i++) {
- swayc_t *cont = stickies->items[i];
- sway_log(L_DEBUG, "Moving sticky container %p to %p:%s",
- cont, workspace, workspace->name);
- swayc_t *parent = remove_child(cont);
- add_floating(workspace, cont);
- // Destroy old container if we need to
- destroy_container(parent);
- }
- list_free(stickies);
- }
- sway_log(L_DEBUG, "Switching to workspace %p:%s", workspace, workspace->name);
- if (!set_focused_container(get_focused_view(workspace))) {
- return false;
- }
- swayc_t *output = swayc_parent_by_type(workspace, C_OUTPUT);
- arrange_backgrounds();
- arrange_windows(output, -1, -1);
- return true;
-}
-
-swayc_t *workspace_for_pid(pid_t pid) {
- int i;
- swayc_t *ws = NULL;
- struct pid_workspace *pw = NULL;
-
- sway_log(L_DEBUG, "looking for workspace for pid %d", pid);
-
- // leaving this here as it's useful for debugging
- // sway_log(L_DEBUG, "all pid_workspaces");
- // for (int k = 0; k < config->pid_workspaces->length; k++) {
- // pw = config->pid_workspaces->items[k];
- // sway_log(L_DEBUG, "pid %d workspace %s time_added %li", *pw->pid, pw->workspace, *pw->time_added);
- // }
-
- do {
- for (i = 0; i < config->pid_workspaces->length; i++) {
- pw = config->pid_workspaces->items[i];
- pid_t *pw_pid = pw->pid;
-
- if (pid == *pw_pid) {
- sway_log(L_DEBUG, "found pid_workspace for pid %d, workspace %s", pid, pw->workspace);
- break; // out of for loop
- }
-
- pw = NULL;
- }
-
- if (pw) {
- break; // out of do-while loop
- }
-
- pid = get_parent_pid(pid);
- // no sense in looking for matches for pid 0.
- // also, if pid == getpid(), that is the compositor's
- // pid, which definitely isn't helpful
- } while (pid > 0 && pid != getpid());
-
- if (pw) {
- ws = workspace_by_name(pw->workspace);
-
- if (!ws) {
- sway_log(L_DEBUG, "Creating workspace %s for pid %d because it disappeared", pw->workspace, pid);
- ws = workspace_create(pw->workspace);
- }
-
- list_del(config->pid_workspaces, i);
- }
-
- return ws;
-}