aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/sway/commands.h3
-rw-r--r--include/sway/config.h5
-rw-r--r--include/sway/debug.h2
-rw-r--r--include/sway/ipc-json.h2
-rw-r--r--include/swaybar/bar.h2
-rw-r--r--include/swaybar/config.h2
-rw-r--r--include/swaybar/render.h4
-rw-r--r--include/swaybar/tray/dbus.h18
-rw-r--r--include/swaybar/tray/sni_watcher.h10
-rw-r--r--include/swaybar/tray/tray.h32
-rw-r--r--meson.build1
-rw-r--r--sway/commands.c13
-rw-r--r--sway/commands/input.c1
-rw-r--r--sway/commands/input/drag.c26
-rw-r--r--sway/commands/output/background.c18
-rw-r--r--sway/commands/resize.c30
-rw-r--r--sway/config/input.c4
-rw-r--r--sway/config/output.c4
-rw-r--r--sway/config/seat.c2
-rw-r--r--sway/debug-tree.c2
-rw-r--r--sway/input/cursor.c11
-rw-r--r--sway/input/input-manager.c7
-rw-r--r--sway/input/seat.c12
-rw-r--r--sway/ipc-json.c2
-rw-r--r--sway/main.c73
-rw-r--r--sway/meson.build2
-rw-r--r--sway/sway-input.5.scd3
-rw-r--r--sway/tree/container.c2
-rw-r--r--sway/tree/root.c15
-rw-r--r--swaybar/bar.c41
-rw-r--r--swaybar/config.c2
-rw-r--r--swaybar/render.c24
-rw-r--r--swayidle/main.c4
-rw-r--r--swaylock/main.c2
-rw-r--r--swaynag/config.c2
35 files changed, 176 insertions, 207 deletions
diff --git a/include/sway/commands.h b/include/sway/commands.h
index 1654eb48..afa65340 100644
--- a/include/sway/commands.h
+++ b/include/sway/commands.h
@@ -95,7 +95,7 @@ struct cmd_results *add_color(const char *name,
95/** 95/**
96 * TODO: Move this function and its dependent functions to container.c. 96 * TODO: Move this function and its dependent functions to container.c.
97 */ 97 */
98void container_resize_tiled(struct sway_container *parent, enum wlr_edges edge, 98bool container_resize_tiled(struct sway_container *parent, enum wlr_edges edge,
99 int amount); 99 int amount);
100 100
101sway_cmd cmd_assign; 101sway_cmd cmd_assign;
@@ -217,6 +217,7 @@ sway_cmd bar_colors_cmd_urgent_workspace;
217sway_cmd input_cmd_seat; 217sway_cmd input_cmd_seat;
218sway_cmd input_cmd_accel_profile; 218sway_cmd input_cmd_accel_profile;
219sway_cmd input_cmd_click_method; 219sway_cmd input_cmd_click_method;
220sway_cmd input_cmd_drag;
220sway_cmd input_cmd_drag_lock; 221sway_cmd input_cmd_drag_lock;
221sway_cmd input_cmd_dwt; 222sway_cmd input_cmd_dwt;
222sway_cmd input_cmd_events; 223sway_cmd input_cmd_events;
diff --git a/include/sway/config.h b/include/sway/config.h
index af5c7a18..2395bc51 100644
--- a/include/sway/config.h
+++ b/include/sway/config.h
@@ -93,6 +93,7 @@ struct input_config {
93 93
94 int accel_profile; 94 int accel_profile;
95 int click_method; 95 int click_method;
96 int drag;
96 int drag_lock; 97 int drag_lock;
97 int dwt; 98 int dwt;
98 int left_handed; 99 int left_handed;
@@ -449,8 +450,6 @@ void free_sway_variable(struct sway_variable *var);
449 */ 450 */
450char *do_var_replacement(char *str); 451char *do_var_replacement(char *str);
451 452
452struct cmd_results *check_security_config();
453
454int input_identifier_cmp(const void *item, const void *data); 453int input_identifier_cmp(const void *item, const void *data);
455 454
456struct input_config *new_input_config(const char* identifier); 455struct input_config *new_input_config(const char* identifier);
@@ -471,7 +470,7 @@ struct seat_config *copy_seat_config(struct seat_config *seat);
471 470
472void free_seat_config(struct seat_config *ic); 471void free_seat_config(struct seat_config *ic);
473 472
474struct seat_attachment_config *seat_attachment_config_new(); 473struct seat_attachment_config *seat_attachment_config_new(void);
475 474
476struct seat_attachment_config *seat_config_get_attachment( 475struct seat_attachment_config *seat_config_get_attachment(
477 struct seat_config *seat_config, char *identifier); 476 struct seat_config *seat_config, char *identifier);
diff --git a/include/sway/debug.h b/include/sway/debug.h
index bf3a5f6d..0e9bb056 100644
--- a/include/sway/debug.h
+++ b/include/sway/debug.h
@@ -17,6 +17,6 @@ struct sway_debug {
17 17
18extern struct sway_debug debug; 18extern struct sway_debug debug;
19 19
20void update_debug_tree(); 20void update_debug_tree(void);
21 21
22#endif 22#endif
diff --git a/include/sway/ipc-json.h b/include/sway/ipc-json.h
index fef243e3..1cbfd15d 100644
--- a/include/sway/ipc-json.h
+++ b/include/sway/ipc-json.h
@@ -4,7 +4,7 @@
4#include "sway/tree/container.h" 4#include "sway/tree/container.h"
5#include "sway/input/input-manager.h" 5#include "sway/input/input-manager.h"
6 6
7json_object *ipc_json_get_version(); 7json_object *ipc_json_get_version(void);
8 8
9json_object *ipc_json_describe_disabled_output(struct sway_output *o); 9json_object *ipc_json_describe_disabled_output(struct sway_output *o);
10json_object *ipc_json_describe_node(struct sway_node *node); 10json_object *ipc_json_describe_node(struct sway_node *node);
diff --git a/include/swaybar/bar.h b/include/swaybar/bar.h
index 20992014..de234111 100644
--- a/include/swaybar/bar.h
+++ b/include/swaybar/bar.h
@@ -83,6 +83,8 @@ struct swaybar_output {
83 enum wl_output_subpixel subpixel; 83 enum wl_output_subpixel subpixel;
84 struct pool_buffer buffers[2]; 84 struct pool_buffer buffers[2];
85 struct pool_buffer *current_buffer; 85 struct pool_buffer *current_buffer;
86 bool dirty;
87 bool frame_scheduled;
86}; 88};
87 89
88struct swaybar_workspace { 90struct swaybar_workspace {
diff --git a/include/swaybar/config.h b/include/swaybar/config.h
index 6739c28a..5f5688cf 100644
--- a/include/swaybar/config.h
+++ b/include/swaybar/config.h
@@ -50,7 +50,7 @@ struct swaybar_config {
50 } colors; 50 } colors;
51}; 51};
52 52
53struct swaybar_config *init_config(); 53struct swaybar_config *init_config(void);
54void free_config(struct swaybar_config *config); 54void free_config(struct swaybar_config *config);
55uint32_t parse_position(const char *position); 55uint32_t parse_position(const char *position);
56 56
diff --git a/include/swaybar/render.h b/include/swaybar/render.h
index 071e2298..ebdc69e4 100644
--- a/include/swaybar/render.h
+++ b/include/swaybar/render.h
@@ -1,10 +1,8 @@
1#ifndef _SWAYBAR_RENDER_H 1#ifndef _SWAYBAR_RENDER_H
2#define _SWAYBAR_RENDER_H 2#define _SWAYBAR_RENDER_H
3 3
4struct swaybar;
5struct swaybar_output; 4struct swaybar_output;
6struct swaybar_config;
7 5
8void render_frame(struct swaybar *bar, struct swaybar_output *output); 6void render_frame(struct swaybar_output *output);
9 7
10#endif 8#endif
diff --git a/include/swaybar/tray/dbus.h b/include/swaybar/tray/dbus.h
deleted file mode 100644
index eb9cfea7..00000000
--- a/include/swaybar/tray/dbus.h
+++ /dev/null
@@ -1,18 +0,0 @@
1#ifndef _SWAYBAR_DBUS_H
2#define _SWAYBAR_DBUS_H
3
4#include <stdbool.h>
5#include <dbus/dbus.h>
6extern DBusConnection *conn;
7
8/**
9 * Should be called in main loop to dispatch events
10 */
11void dispatch_dbus();
12
13/**
14 * Initializes async dbus communication
15 */
16int dbus_init();
17
18#endif /* _SWAYBAR_DBUS_H */
diff --git a/include/swaybar/tray/sni_watcher.h b/include/swaybar/tray/sni_watcher.h
deleted file mode 100644
index 25ddfcd2..00000000
--- a/include/swaybar/tray/sni_watcher.h
+++ /dev/null
@@ -1,10 +0,0 @@
1#ifndef _SWAYBAR_SNI_WATCHER_H
2#define _SWAYBAR_SNI_WATCHER_H
3
4/**
5 * Starts the sni_watcher, the watcher is practically a black box and should
6 * only be accessed though functions described in its spec
7 */
8int init_sni_watcher();
9
10#endif /* _SWAYBAR_SNI_WATCHER_H */
diff --git a/include/swaybar/tray/tray.h b/include/swaybar/tray/tray.h
deleted file mode 100644
index 2d0662be..00000000
--- a/include/swaybar/tray/tray.h
+++ /dev/null
@@ -1,32 +0,0 @@
1#ifndef _SWAYBAR_TRAY_H
2#define _SWAYBAR_TRAY_H
3
4#include <stdint.h>
5#include <stdbool.h>
6#include "swaybar/tray/dbus.h"
7#include "swaybar/tray/sni.h"
8#include "swaybar/bar.h"
9#include "list.h"
10
11extern struct tray *tray;
12
13struct tray {
14 list_t *items;
15};
16
17/**
18 * Processes a mouse event on the bar
19 */
20void tray_mouse_event(struct output *output, int x, int y,
21 uint32_t button, uint32_t state);
22
23uint32_t tray_render(struct output *output, struct config *config);
24
25void tray_upkeep(struct bar *bar);
26
27/**
28 * Initializes the tray with D-Bus
29 */
30void init_tray(struct bar *bar);
31
32#endif /* _SWAYBAR_TRAY_H */
diff --git a/meson.build b/meson.build
index de6573ea..080709fa 100644
--- a/meson.build
+++ b/meson.build
@@ -42,7 +42,6 @@ pango = dependency('pango')
42pangocairo = dependency('pangocairo') 42pangocairo = dependency('pangocairo')
43gdk_pixbuf = dependency('gdk-pixbuf-2.0', required: false) 43gdk_pixbuf = dependency('gdk-pixbuf-2.0', required: false)
44pixman = dependency('pixman-1') 44pixman = dependency('pixman-1')
45libcap = dependency('libcap', required: false)
46libinput = dependency('libinput', version: '>=1.6.0') 45libinput = dependency('libinput', version: '>=1.6.0')
47libpam = cc.find_library('pam', required: false) 46libpam = cc.find_library('pam', required: false)
48systemd = dependency('libsystemd', required: false) 47systemd = dependency('libsystemd', required: false)
diff --git a/sway/commands.c b/sway/commands.c
index bff230f7..03761c52 100644
--- a/sway/commands.c
+++ b/sway/commands.c
@@ -391,14 +391,12 @@ struct cmd_results *config_command(char *exec) {
391 // Var replacement, for all but first argument of set 391 // Var replacement, for all but first argument of set
392 // TODO commands 392 // TODO commands
393 for (i = handler->handle == cmd_set ? 2 : 1; i < argc; ++i) { 393 for (i = handler->handle == cmd_set ? 2 : 1; i < argc; ++i) {
394 if (*argv[i] == '\"' || *argv[i] == '\'') {
395 strip_quotes(argv[i]);
396 }
394 argv[i] = do_var_replacement(argv[i]); 397 argv[i] = do_var_replacement(argv[i]);
395 unescape_string(argv[i]); 398 unescape_string(argv[i]);
396 } 399 }
397 // Strip quotes for first argument.
398 // TODO This part needs to be handled much better
399 if (argc>1 && (*argv[1] == '\"' || *argv[1] == '\'')) {
400 strip_quotes(argv[1]);
401 }
402 if (handler->handle) { 400 if (handler->handle) {
403 results = handler->handle(argc-1, argv+1); 401 results = handler->handle(argc-1, argv+1);
404 } else { 402 } else {
@@ -422,11 +420,6 @@ struct cmd_results *config_subcommand(char **argv, int argc,
422 char *input = argv[0] ? argv[0] : "(empty)"; 420 char *input = argv[0] ? argv[0] : "(empty)";
423 return cmd_results_new(CMD_INVALID, input, "Unknown/invalid command"); 421 return cmd_results_new(CMD_INVALID, input, "Unknown/invalid command");
424 } 422 }
425 // Strip quotes for first argument.
426 // TODO This part needs to be handled much better
427 if (argc > 1 && (*argv[1] == '\"' || *argv[1] == '\'')) {
428 strip_quotes(argv[1]);
429 }
430 if (handler->handle) { 423 if (handler->handle) {
431 return handler->handle(argc - 1, argv + 1); 424 return handler->handle(argc - 1, argv + 1);
432 } 425 }
diff --git a/sway/commands/input.c b/sway/commands/input.c
index 9091da2a..2889d47d 100644
--- a/sway/commands/input.c
+++ b/sway/commands/input.c
@@ -9,6 +9,7 @@
9static struct cmd_handler input_handlers[] = { 9static struct cmd_handler input_handlers[] = {
10 { "accel_profile", input_cmd_accel_profile }, 10 { "accel_profile", input_cmd_accel_profile },
11 { "click_method", input_cmd_click_method }, 11 { "click_method", input_cmd_click_method },
12 { "drag", input_cmd_drag },
12 { "drag_lock", input_cmd_drag_lock }, 13 { "drag_lock", input_cmd_drag_lock },
13 { "dwt", input_cmd_dwt }, 14 { "dwt", input_cmd_dwt },
14 { "events", input_cmd_events }, 15 { "events", input_cmd_events },
diff --git a/sway/commands/input/drag.c b/sway/commands/input/drag.c
new file mode 100644
index 00000000..e325df29
--- /dev/null
+++ b/sway/commands/input/drag.c
@@ -0,0 +1,26 @@
1#include <string.h>
2#include <strings.h>
3#include "sway/config.h"
4#include "sway/commands.h"
5#include "sway/input/input-manager.h"
6#include "util.h"
7
8struct cmd_results *input_cmd_drag(int argc, char **argv) {
9 struct cmd_results *error = NULL;
10 if ((error = checkarg(argc, "drag", EXPECTED_AT_LEAST, 1))) {
11 return error;
12 }
13 struct input_config *ic = config->handler_context.input_config;
14 if (!ic) {
15 return cmd_results_new(CMD_FAILURE,
16 "drag", "No input device defined.");
17 }
18
19 if (parse_boolean(argv[0], true)) {
20 ic->drag = LIBINPUT_CONFIG_DRAG_ENABLED;
21 } else {
22 ic->drag = LIBINPUT_CONFIG_DRAG_DISABLED;
23 }
24
25 return cmd_results_new(CMD_SUCCESS, NULL, NULL);
26}
diff --git a/sway/commands/output/background.c b/sway/commands/output/background.c
index 9e370d43..30fb47c4 100644
--- a/sway/commands/output/background.c
+++ b/sway/commands/output/background.c
@@ -123,19 +123,13 @@ struct cmd_results *output_cmd_background(int argc, char **argv) {
123 } 123 }
124 free(src); 124 free(src);
125 } else { 125 } else {
126 // Escape spaces and quotes in the final path for swaybg 126 // Escape double quotes in the final path for swaybg
127 for (size_t i = 0; i < strlen(src); i++) { 127 for (size_t i = 0; i < strlen(src); i++) {
128 switch (src[i]) { 128 if (src[i] == '"') {
129 case ' ': 129 src = realloc(src, strlen(src) + 2);
130 case '\'': 130 memmove(src + i + 1, src + i, strlen(src + i) + 1);
131 case '\"': 131 *(src + i) = '\\';
132 src = realloc(src, strlen(src) + 2); 132 i++;
133 memmove(src + i + 1, src + i, strlen(src + i) + 1);
134 *(src + i) = '\\';
135 i++;
136 break;
137 default:
138 break;
139 } 133 }
140 } 134 }
141 135
diff --git a/sway/commands/resize.c b/sway/commands/resize.c
index 99e9dbda..1343b165 100644
--- a/sway/commands/resize.c
+++ b/sway/commands/resize.c
@@ -179,11 +179,11 @@ static void container_recursive_resize(struct sway_container *container,
179 } 179 }
180} 180}
181 181
182static void resize_tiled(struct sway_container *parent, int amount, 182static bool resize_tiled(struct sway_container *parent, int amount,
183 enum resize_axis axis) { 183 enum resize_axis axis) {
184 struct sway_container *focused = parent; 184 struct sway_container *focused = parent;
185 if (!parent) { 185 if (!parent) {
186 return; 186 return false;
187 } 187 }
188 188
189 enum sway_container_layout parallel_layout = 189 enum sway_container_layout parallel_layout =
@@ -216,7 +216,7 @@ static void resize_tiled(struct sway_container *parent, int amount,
216 } 216 }
217 if (!parent) { 217 if (!parent) {
218 // Can't resize in this direction 218 // Can't resize in this direction
219 return; 219 return false;
220 } 220 }
221 221
222 // Implement up/down/left/right direction by zeroing one of the weights, 222 // Implement up/down/left/right direction by zeroing one of the weights,
@@ -248,22 +248,22 @@ static void resize_tiled(struct sway_container *parent, int amount,
248 if (sibling_pos < parent_pos && minor_weight) { 248 if (sibling_pos < parent_pos && minor_weight) {
249 double pixels = -amount / minor_weight; 249 double pixels = -amount / minor_weight;
250 if (major_weight && (sibling_size + pixels / 2) < min_sane) { 250 if (major_weight && (sibling_size + pixels / 2) < min_sane) {
251 return; // Too small 251 return false; // Too small
252 } else if (!major_weight && sibling_size + pixels < min_sane) { 252 } else if (!major_weight && sibling_size + pixels < min_sane) {
253 return; // Too small 253 return false; // Too small
254 } 254 }
255 } else if (sibling_pos > parent_pos && major_weight) { 255 } else if (sibling_pos > parent_pos && major_weight) {
256 double pixels = -amount / major_weight; 256 double pixels = -amount / major_weight;
257 if (minor_weight && (sibling_size + pixels / 2) < min_sane) { 257 if (minor_weight && (sibling_size + pixels / 2) < min_sane) {
258 return; // Too small 258 return false; // Too small
259 } else if (!minor_weight && sibling_size + pixels < min_sane) { 259 } else if (!minor_weight && sibling_size + pixels < min_sane) {
260 return; // Too small 260 return false; // Too small
261 } 261 }
262 } 262 }
263 } else { 263 } else {
264 double pixels = amount; 264 double pixels = amount;
265 if (parent_size + pixels < min_sane) { 265 if (parent_size + pixels < min_sane) {
266 return; // Too small 266 return false; // Too small
267 } 267 }
268 } 268 }
269 } 269 }
@@ -317,9 +317,10 @@ static void resize_tiled(struct sway_container *parent, int amount,
317 } else { 317 } else {
318 arrange_workspace(parent->workspace); 318 arrange_workspace(parent->workspace);
319 } 319 }
320 return true;
320} 321}
321 322
322void container_resize_tiled(struct sway_container *parent, 323bool container_resize_tiled(struct sway_container *parent,
323 enum wlr_edges edge, int amount) { 324 enum wlr_edges edge, int amount) {
324 enum resize_axis axis = RESIZE_AXIS_INVALID; 325 enum resize_axis axis = RESIZE_AXIS_INVALID;
325 switch (edge) { 326 switch (edge) {
@@ -338,7 +339,7 @@ void container_resize_tiled(struct sway_container *parent,
338 case WLR_EDGE_NONE: 339 case WLR_EDGE_NONE:
339 break; 340 break;
340 } 341 }
341 resize_tiled(parent, amount, axis); 342 return resize_tiled(parent, amount, axis);
342} 343}
343 344
344/** 345/**
@@ -395,6 +396,10 @@ static struct cmd_results *resize_adjust_floating(enum resize_axis axis,
395 case RESIZE_AXIS_INVALID: 396 case RESIZE_AXIS_INVALID:
396 return cmd_results_new(CMD_INVALID, "resize", "Invalid axis/direction"); 397 return cmd_results_new(CMD_INVALID, "resize", "Invalid axis/direction");
397 } 398 }
399 if (grow_x == 0 && grow_y == 0) {
400 return cmd_results_new(CMD_INVALID, "resize",
401 "Cannot resize any further");
402 }
398 con->x += grow_x; 403 con->x += grow_x;
399 con->y += grow_y; 404 con->y += grow_y;
400 con->width += grow_width; 405 con->width += grow_width;
@@ -442,7 +447,10 @@ static struct cmd_results *resize_adjust_tiled(enum resize_axis axis,
442 } 447 }
443 } 448 }
444 449
445 resize_tiled(current, amount->amount, axis); 450 if (!resize_tiled(current, amount->amount, axis)) {
451 return cmd_results_new(CMD_INVALID, "resize",
452 "Cannot resize any further");
453 }
446 return cmd_results_new(CMD_SUCCESS, NULL, NULL); 454 return cmd_results_new(CMD_SUCCESS, NULL, NULL);
447} 455}
448 456
diff --git a/sway/config/input.c b/sway/config/input.c
index 6b43a5b9..794d5194 100644
--- a/sway/config/input.c
+++ b/sway/config/input.c
@@ -20,6 +20,7 @@ struct input_config *new_input_config(const char* identifier) {
20 20
21 input->tap = INT_MIN; 21 input->tap = INT_MIN;
22 input->tap_button_map = INT_MIN; 22 input->tap_button_map = INT_MIN;
23 input->drag = INT_MIN;
23 input->drag_lock = INT_MIN; 24 input->drag_lock = INT_MIN;
24 input->dwt = INT_MIN; 25 input->dwt = INT_MIN;
25 input->send_events = INT_MIN; 26 input->send_events = INT_MIN;
@@ -46,6 +47,9 @@ void merge_input_config(struct input_config *dst, struct input_config *src) {
46 if (src->click_method != INT_MIN) { 47 if (src->click_method != INT_MIN) {
47 dst->click_method = src->click_method; 48 dst->click_method = src->click_method;
48 } 49 }
50 if (src->drag != INT_MIN) {
51 dst->drag = src->drag;
52 }
49 if (src->drag_lock != INT_MIN) { 53 if (src->drag_lock != INT_MIN) {
50 dst->drag_lock = src->drag_lock; 54 dst->drag_lock = src->drag_lock;
51 } 55 }
diff --git a/sway/config/output.c b/sway/config/output.c
index 74d79130..6f337b66 100644
--- a/sway/config/output.c
+++ b/sway/config/output.c
@@ -237,7 +237,7 @@ void apply_output_config(struct output_config *oc, struct sway_output *output) {
237 wlr_log(WLR_DEBUG, "Setting background for output %d to %s", 237 wlr_log(WLR_DEBUG, "Setting background for output %d to %s",
238 output_i, oc->background); 238 output_i, oc->background);
239 239
240 size_t len = snprintf(NULL, 0, "%s %d %s %s %s", 240 size_t len = snprintf(NULL, 0, "%s %d \"%s\" %s %s",
241 config->swaybg_command ? config->swaybg_command : "swaybg", 241 config->swaybg_command ? config->swaybg_command : "swaybg",
242 output_i, oc->background, oc->background_option, 242 output_i, oc->background, oc->background_option,
243 oc->background_fallback ? oc->background_fallback : ""); 243 oc->background_fallback ? oc->background_fallback : "");
@@ -246,7 +246,7 @@ void apply_output_config(struct output_config *oc, struct sway_output *output) {
246 wlr_log(WLR_DEBUG, "Unable to allocate swaybg command"); 246 wlr_log(WLR_DEBUG, "Unable to allocate swaybg command");
247 return; 247 return;
248 } 248 }
249 snprintf(command, len + 1, "%s %d %s %s %s", 249 snprintf(command, len + 1, "%s %d \"%s\" %s %s",
250 config->swaybg_command ? config->swaybg_command : "swaybg", 250 config->swaybg_command ? config->swaybg_command : "swaybg",
251 output_i, oc->background, oc->background_option, 251 output_i, oc->background, oc->background_option,
252 oc->background_fallback ? oc->background_fallback : ""); 252 oc->background_fallback ? oc->background_fallback : "");
diff --git a/sway/config/seat.c b/sway/config/seat.c
index 83dac4c0..46456caf 100644
--- a/sway/config/seat.c
+++ b/sway/config/seat.c
@@ -30,7 +30,7 @@ struct seat_config *new_seat_config(const char* name) {
30 return seat; 30 return seat;
31} 31}
32 32
33struct seat_attachment_config *seat_attachment_config_new() { 33struct seat_attachment_config *seat_attachment_config_new(void) {
34 struct seat_attachment_config *attachment = 34 struct seat_attachment_config *attachment =
35 calloc(1, sizeof(struct seat_attachment_config)); 35 calloc(1, sizeof(struct seat_attachment_config));
36 if (!attachment) { 36 if (!attachment) {
diff --git a/sway/debug-tree.c b/sway/debug-tree.c
index 9644f4e5..16b479f9 100644
--- a/sway/debug-tree.c
+++ b/sway/debug-tree.c
@@ -120,7 +120,7 @@ static int draw_node(cairo_t *cairo, struct sway_node *node,
120 return height; 120 return height;
121} 121}
122 122
123void update_debug_tree() { 123void update_debug_tree(void) {
124 if (!debug.render_tree) { 124 if (!debug.render_tree) {
125 return; 125 return;
126 } 126 }
diff --git a/sway/input/cursor.c b/sway/input/cursor.c
index aa0e07f5..3ddc27a0 100644
--- a/sway/input/cursor.c
+++ b/sway/input/cursor.c
@@ -30,7 +30,7 @@
30// when dragging to the edge of a layout container. 30// when dragging to the edge of a layout container.
31#define DROP_LAYOUT_BORDER 30 31#define DROP_LAYOUT_BORDER 30
32 32
33static uint32_t get_current_time_msec() { 33static uint32_t get_current_time_msec(void) {
34 struct timespec now; 34 struct timespec now;
35 clock_gettime(CLOCK_MONOTONIC, &now); 35 clock_gettime(CLOCK_MONOTONIC, &now);
36 return now.tv_nsec / 1000; 36 return now.tv_nsec / 1000;
@@ -1006,8 +1006,7 @@ static void handle_touch_down(struct wl_listener *listener, void *data) {
1006 if (seat_is_input_allowed(seat, surface)) { 1006 if (seat_is_input_allowed(seat, surface)) {
1007 wlr_seat_touch_notify_down(wlr_seat, surface, event->time_msec, 1007 wlr_seat_touch_notify_down(wlr_seat, surface, event->time_msec,
1008 event->touch_id, sx, sy); 1008 event->touch_id, sx, sy);
1009 cursor->image_client = NULL; 1009 cursor_set_image(cursor, NULL, NULL);
1010 wlr_cursor_set_image(cursor->cursor, NULL, 0, 0, 0, 0, 0, 0);
1011 } 1010 }
1012} 1011}
1013 1012
@@ -1175,11 +1174,13 @@ static void handle_request_set_cursor(struct wl_listener *listener,
1175 1174
1176void cursor_set_image(struct sway_cursor *cursor, const char *image, 1175void cursor_set_image(struct sway_cursor *cursor, const char *image,
1177 struct wl_client *client) { 1176 struct wl_client *client) {
1178 if (!cursor->image || strcmp(cursor->image, image) != 0) { 1177 if (!image) {
1178 wlr_cursor_set_image(cursor->cursor, NULL, 0, 0, 0, 0, 0, 0);
1179 } else if (!cursor->image || strcmp(cursor->image, image) != 0) {
1179 wlr_xcursor_manager_set_cursor_image(cursor->xcursor_manager, image, 1180 wlr_xcursor_manager_set_cursor_image(cursor->xcursor_manager, image,
1180 cursor->cursor); 1181 cursor->cursor);
1181 cursor->image = image;
1182 } 1182 }
1183 cursor->image = image;
1183 cursor->image_client = client; 1184 cursor->image_client = client;
1184} 1185}
1185 1186
diff --git a/sway/input/input-manager.c b/sway/input/input-manager.c
index f39fe29c..32f0355e 100644
--- a/sway/input/input-manager.c
+++ b/sway/input/input-manager.c
@@ -120,6 +120,13 @@ static void input_manager_libinput_config_pointer(
120 libinput_device_config_click_set_method(libinput_device, 120 libinput_device_config_click_set_method(libinput_device,
121 ic->click_method); 121 ic->click_method);
122 } 122 }
123 if (ic->drag != INT_MIN) {
124 wlr_log(WLR_DEBUG,
125 "libinput_config_pointer(%s) tap_set_drag_enabled(%d)",
126 ic->identifier, ic->click_method);
127 libinput_device_config_tap_set_drag_enabled(libinput_device,
128 ic->drag);
129 }
123 if (ic->drag_lock != INT_MIN) { 130 if (ic->drag_lock != INT_MIN) {
124 wlr_log(WLR_DEBUG, 131 wlr_log(WLR_DEBUG,
125 "libinput_config_pointer(%s) tap_set_drag_lock_enabled(%d)", 132 "libinput_config_pointer(%s) tap_set_drag_lock_enabled(%d)",
diff --git a/sway/input/seat.c b/sway/input/seat.c
index a9c564e7..4817eae7 100644
--- a/sway/input/seat.c
+++ b/sway/input/seat.c
@@ -368,11 +368,20 @@ static void seat_update_capabilities(struct sway_seat *seat) {
368 caps |= WL_SEAT_CAPABILITY_TOUCH; 368 caps |= WL_SEAT_CAPABILITY_TOUCH;
369 break; 369 break;
370 case WLR_INPUT_DEVICE_TABLET_TOOL: 370 case WLR_INPUT_DEVICE_TABLET_TOOL:
371 caps |= WL_SEAT_CAPABILITY_POINTER;
372 break;
371 case WLR_INPUT_DEVICE_TABLET_PAD: 373 case WLR_INPUT_DEVICE_TABLET_PAD:
372 break; 374 break;
373 } 375 }
374 } 376 }
375 wlr_seat_set_capabilities(seat->wlr_seat, caps); 377 wlr_seat_set_capabilities(seat->wlr_seat, caps);
378
379 // Hide cursor if seat doesn't have pointer capability
380 if ((caps & WL_SEAT_CAPABILITY_POINTER) == 0) {
381 cursor_set_image(seat->cursor, NULL, NULL);
382 } else {
383 cursor_set_image(seat->cursor, "left_ptr", NULL);
384 }
376} 385}
377 386
378static void seat_apply_input_config(struct sway_seat *seat, 387static void seat_apply_input_config(struct sway_seat *seat,
@@ -552,8 +561,7 @@ void seat_configure_xcursor(struct sway_seat *seat) {
552 output->name, (double)output->scale); 561 output->name, (double)output->scale);
553 } 562 }
554 563
555 wlr_xcursor_manager_set_cursor_image(seat->cursor->xcursor_manager, 564 cursor_set_image(seat->cursor, "left_ptr", NULL);
556 "left_ptr", seat->cursor->cursor);
557 wlr_cursor_warp(seat->cursor->cursor, NULL, seat->cursor->cursor->x, 565 wlr_cursor_warp(seat->cursor->cursor, NULL, seat->cursor->cursor->x,
558 seat->cursor->cursor->y); 566 seat->cursor->cursor->y);
559} 567}
diff --git a/sway/ipc-json.c b/sway/ipc-json.c
index f054ac9f..45915094 100644
--- a/sway/ipc-json.c
+++ b/sway/ipc-json.c
@@ -42,7 +42,7 @@ static const char *ipc_json_orientation_description(enum sway_container_layout l
42 return "none"; 42 return "none";
43} 43}
44 44
45json_object *ipc_json_get_version() { 45json_object *ipc_json_get_version(void) {
46 int major = 0, minor = 0, patch = 0; 46 int major = 0, minor = 0, patch = 0;
47 json_object *version = json_object_new_object(); 47 json_object *version = json_object_new_object();
48 48
diff --git a/sway/main.c b/sway/main.c
index 990f5f3a..50b05b21 100644
--- a/sway/main.c
+++ b/sway/main.c
@@ -12,10 +12,6 @@
12#include <sys/wait.h> 12#include <sys/wait.h>
13#include <sys/un.h> 13#include <sys/un.h>
14#include <unistd.h> 14#include <unistd.h>
15#ifdef __linux__
16#include <sys/capability.h>
17#include <sys/prctl.h>
18#endif
19#include <wlr/util/log.h> 15#include <wlr/util/log.h>
20#include "sway/commands.h" 16#include "sway/commands.h"
21#include "sway/config.h" 17#include "sway/config.h"
@@ -45,7 +41,7 @@ void sig_handler(int signal) {
45 sway_terminate(EXIT_SUCCESS); 41 sway_terminate(EXIT_SUCCESS);
46} 42}
47 43
48void detect_raspi() { 44void detect_raspi(void) {
49 bool raspi = false; 45 bool raspi = false;
50 FILE *f = fopen("/sys/firmware/devicetree/base/model", "r"); 46 FILE *f = fopen("/sys/firmware/devicetree/base/model", "r");
51 if (!f) { 47 if (!f) {
@@ -85,7 +81,7 @@ void detect_raspi() {
85 } 81 }
86} 82}
87 83
88void detect_proprietary() { 84void detect_proprietary(void) {
89 FILE *f = fopen("/proc/modules", "r"); 85 FILE *f = fopen("/proc/modules", "r");
90 if (!f) { 86 if (!f) {
91 return; 87 return;
@@ -120,7 +116,7 @@ void run_as_ipc_client(char *command, char *socket_path) {
120 close(socketfd); 116 close(socketfd);
121} 117}
122 118
123static void log_env() { 119static void log_env(void) {
124 const char *log_vars[] = { 120 const char *log_vars[] = {
125 "PATH", 121 "PATH",
126 "LD_LIBRARY_PATH", 122 "LD_LIBRARY_PATH",
@@ -135,7 +131,7 @@ static void log_env() {
135 } 131 }
136} 132}
137 133
138static void log_distro() { 134static void log_distro(void) {
139 const char *paths[] = { 135 const char *paths[] = {
140 "/etc/lsb-release", 136 "/etc/lsb-release",
141 "/etc/os-release", 137 "/etc/os-release",
@@ -162,7 +158,7 @@ static void log_distro() {
162 } 158 }
163} 159}
164 160
165static void log_kernel() { 161static void log_kernel(void) {
166 FILE *f = popen("uname -a", "r"); 162 FILE *f = popen("uname -a", "r");
167 if (!f) { 163 if (!f) {
168 wlr_log(WLR_INFO, "Unable to determine kernel version"); 164 wlr_log(WLR_INFO, "Unable to determine kernel version");
@@ -181,28 +177,8 @@ static void log_kernel() {
181 pclose(f); 177 pclose(f);
182} 178}
183 179
184static void executable_sanity_check() {
185#ifdef __linux__
186 struct stat sb;
187 char *exe = realpath("/proc/self/exe", NULL);
188 stat(exe, &sb);
189 // We assume that cap_get_file returning NULL implies ENODATA
190 if (sb.st_mode & (S_ISUID|S_ISGID) && cap_get_file(exe)) {
191 wlr_log(WLR_ERROR,
192 "sway executable has both the s(g)uid bit AND file caps set.");
193 wlr_log(WLR_ERROR,
194 "This is strongly discouraged (and completely broken).");
195 wlr_log(WLR_ERROR,
196 "Please clear one of them (either the suid bit, or the file caps).");
197 wlr_log(WLR_ERROR,
198 "If unsure, strip the file caps.");
199 exit(EXIT_FAILURE);
200 }
201 free(exe);
202#endif
203}
204 180
205static void drop_permissions(bool keep_caps) { 181static void drop_permissions(void) {
206 if (getuid() != geteuid() || getgid() != getegid()) { 182 if (getuid() != geteuid() || getgid() != getegid()) {
207 if (setgid(getgid()) != 0) { 183 if (setgid(getgid()) != 0) {
208 wlr_log(WLR_ERROR, "Unable to drop root"); 184 wlr_log(WLR_ERROR, "Unable to drop root");
@@ -217,20 +193,6 @@ static void drop_permissions(bool keep_caps) {
217 wlr_log(WLR_ERROR, "Root privileges can be restored."); 193 wlr_log(WLR_ERROR, "Root privileges can be restored.");
218 exit(EXIT_FAILURE); 194 exit(EXIT_FAILURE);
219 } 195 }
220#ifdef __linux__
221 if (keep_caps) {
222 // Drop every cap except CAP_SYS_PTRACE
223 cap_t caps = cap_init();
224 cap_value_t keep = CAP_SYS_PTRACE;
225 wlr_log(WLR_INFO, "Dropping extra capabilities");
226 if (cap_set_flag(caps, CAP_PERMITTED, 1, &keep, CAP_SET) ||
227 cap_set_flag(caps, CAP_EFFECTIVE, 1, &keep, CAP_SET) ||
228 cap_set_proc(caps)) {
229 wlr_log(WLR_ERROR, "Failed to drop extra capabilities");
230 exit(EXIT_FAILURE);
231 }
232 }
233#endif
234} 196}
235 197
236void enable_debug_flag(const char *flag) { 198void enable_debug_flag(const char *flag) {
@@ -347,7 +309,7 @@ int main(int argc, char **argv) {
347 wlr_log(WLR_ERROR, "Don't use options with the IPC client"); 309 wlr_log(WLR_ERROR, "Don't use options with the IPC client");
348 exit(EXIT_FAILURE); 310 exit(EXIT_FAILURE);
349 } 311 }
350 drop_permissions(false); 312 drop_permissions();
351 char *socket_path = getenv("SWAYSOCK"); 313 char *socket_path = getenv("SWAYSOCK");
352 if (!socket_path) { 314 if (!socket_path) {
353 wlr_log(WLR_ERROR, "Unable to retrieve socket path"); 315 wlr_log(WLR_ERROR, "Unable to retrieve socket path");
@@ -358,34 +320,17 @@ int main(int argc, char **argv) {
358 return 0; 320 return 0;
359 } 321 }
360 322
361 executable_sanity_check();
362 bool suid = false;
363
364 if (!server_privileged_prepare(&server)) { 323 if (!server_privileged_prepare(&server)) {
365 return 1; 324 return 1;
366 } 325 }
367 326
368#if defined(__linux__) || defined(__FreeBSD__)
369 if (getuid() != geteuid() || getgid() != getegid()) {
370#ifdef __linux__
371 // Retain capabilities after setuid()
372 if (prctl(PR_SET_KEEPCAPS, 1, 0, 0, 0)) {
373 wlr_log(WLR_ERROR, "Cannot keep caps after setuid()");
374 exit(EXIT_FAILURE);
375 }
376#endif
377 suid = true;
378 }
379#endif
380
381 log_kernel(); 327 log_kernel();
382 log_distro(); 328 log_distro();
383 detect_proprietary(); 329 detect_proprietary();
384 detect_raspi(); 330 detect_raspi();
385 331
386#if defined(__linux__) || defined(__FreeBSD__) 332 drop_permissions();
387 drop_permissions(suid); 333
388#endif
389 // handle SIGTERM signals 334 // handle SIGTERM signals
390 signal(SIGTERM, sig_handler); 335 signal(SIGTERM, sig_handler);
391 336
diff --git a/sway/meson.build b/sway/meson.build
index d67a4c64..b6394ecb 100644
--- a/sway/meson.build
+++ b/sway/meson.build
@@ -119,6 +119,7 @@ sway_sources = files(
119 119
120 'commands/input/accel_profile.c', 120 'commands/input/accel_profile.c',
121 'commands/input/click_method.c', 121 'commands/input/click_method.c',
122 'commands/input/drag.c',
122 'commands/input/drag_lock.c', 123 'commands/input/drag_lock.c',
123 'commands/input/dwt.c', 124 'commands/input/dwt.c',
124 'commands/input/events.c', 125 'commands/input/events.c',
@@ -164,7 +165,6 @@ sway_deps = [
164 cairo, 165 cairo,
165 gdk_pixbuf, 166 gdk_pixbuf,
166 jsonc, 167 jsonc,
167 libcap,
168 libinput, 168 libinput,
169 math, 169 math,
170 pango, 170 pango,
diff --git a/sway/sway-input.5.scd b/sway/sway-input.5.scd
index 5736d70a..14f2a007 100644
--- a/sway/sway-input.5.scd
+++ b/sway/sway-input.5.scd
@@ -67,6 +67,9 @@ The following commands may only be used in the configuration file.
67*input* <identifier> click\_method none|button\_areas|clickfinger 67*input* <identifier> click\_method none|button\_areas|clickfinger
68 Changes the click method for the specified device. 68 Changes the click method for the specified device.
69 69
70*input* <identifier> drag enabled|disabled
71 Enables or disables tap-and-drag for specified input device.
72
70*input* <identifier> drag\_lock enabled|disabled 73*input* <identifier> drag\_lock enabled|disabled
71 Enables or disables drag lock for specified input device. 74 Enables or disables drag lock for specified input device.
72 75
diff --git a/sway/tree/container.c b/sway/tree/container.c
index 01bd04c7..c30e7784 100644
--- a/sway/tree/container.c
+++ b/sway/tree/container.c
@@ -593,7 +593,7 @@ void container_update_representation(struct sway_container *con) {
593 } 593 }
594} 594}
595 595
596size_t container_titlebar_height() { 596size_t container_titlebar_height(void) {
597 return config->font_height + TITLEBAR_V_PADDING * 2; 597 return config->font_height + TITLEBAR_V_PADDING * 2;
598} 598}
599 599
diff --git a/sway/tree/root.c b/sway/tree/root.c
index d6f67bd7..6748e9c9 100644
--- a/sway/tree/root.c
+++ b/sway/tree/root.c
@@ -273,6 +273,12 @@ void root_for_each_container(void (*f)(struct sway_container *con, void *data),
273 container_for_each_child(container, f, data); 273 container_for_each_child(container, f, data);
274 } 274 }
275 } 275 }
276
277 // Saved workspaces
278 for (int i = 0; i < root->saved_workspaces->length; ++i) {
279 struct sway_workspace *ws = root->saved_workspaces->items[i];
280 workspace_for_each_container(ws, f, data);
281 }
276} 282}
277 283
278struct sway_output *root_find_output( 284struct sway_output *root_find_output(
@@ -320,6 +326,15 @@ struct sway_container *root_find_container(
320 } 326 }
321 } 327 }
322 } 328 }
329
330 // Saved workspaces
331 for (int i = 0; i < root->saved_workspaces->length; ++i) {
332 struct sway_workspace *ws = root->saved_workspaces->items[i];
333 if ((result = workspace_find_container(ws, test, data))) {
334 return result;
335 }
336 }
337
323 return NULL; 338 return NULL;
324} 339}
325 340
diff --git a/swaybar/bar.c b/swaybar/bar.c
index 15e81976..388c24c4 100644
--- a/swaybar/bar.c
+++ b/swaybar/bar.c
@@ -72,6 +72,16 @@ static void swaybar_output_free(struct swaybar_output *output) {
72 free(output); 72 free(output);
73} 73}
74 74
75static void set_output_dirty(struct swaybar_output *output) {
76 if (output->frame_scheduled) {
77 output->dirty = true;
78 return;
79 }
80 if (output->surface) {
81 render_frame(output);
82 }
83}
84
75static void layer_surface_configure(void *data, 85static void layer_surface_configure(void *data,
76 struct zwlr_layer_surface_v1 *surface, 86 struct zwlr_layer_surface_v1 *surface,
77 uint32_t serial, uint32_t width, uint32_t height) { 87 uint32_t serial, uint32_t width, uint32_t height) {
@@ -79,7 +89,7 @@ static void layer_surface_configure(void *data,
79 output->width = width; 89 output->width = width;
80 output->height = height; 90 output->height = height;
81 zwlr_layer_surface_v1_ack_configure(surface, serial); 91 zwlr_layer_surface_v1_ack_configure(surface, serial);
82 render_frame(output->bar, output); 92 set_output_dirty(output);
83} 93}
84 94
85static void layer_surface_closed(void *_output, 95static void layer_surface_closed(void *_output,
@@ -325,27 +335,22 @@ static void output_geometry(void *data, struct wl_output *wl_output, int32_t x,
325 const char *make, const char *model, int32_t transform) { 335 const char *make, const char *model, int32_t transform) {
326 struct swaybar_output *output = data; 336 struct swaybar_output *output = data;
327 output->subpixel = subpixel; 337 output->subpixel = subpixel;
328 if (output->surface) {
329 render_frame(output->bar, output);
330 }
331} 338}
332 339
333static void output_mode(void *data, struct wl_output *output, uint32_t flags, 340static void output_mode(void *data, struct wl_output *wl_output, uint32_t flags,
334 int32_t width, int32_t height, int32_t refresh) { 341 int32_t width, int32_t height, int32_t refresh) {
335 // Who cares 342 // Who cares
336} 343}
337 344
338static void output_done(void *data, struct wl_output *output) { 345static void output_done(void *data, struct wl_output *wl_output) {
339 // Who cares 346 struct swaybar_output *output = data;
347 set_output_dirty(output);
340} 348}
341 349
342static void output_scale(void *data, struct wl_output *wl_output, 350static void output_scale(void *data, struct wl_output *wl_output,
343 int32_t factor) { 351 int32_t factor) {
344 struct swaybar_output *output = data; 352 struct swaybar_output *output = data;
345 output->scale = factor; 353 output->scale = factor;
346 if (output->surface) {
347 render_frame(output->bar, output);
348 }
349} 354}
350 355
351struct wl_output_listener output_listener = { 356struct wl_output_listener output_listener = {
@@ -381,7 +386,7 @@ static void xdg_output_handle_done(void *data,
381 wl_list_insert(&bar->outputs, &output->link); 386 wl_list_insert(&bar->outputs, &output->link);
382 387
383 add_layer_surface(output); 388 add_layer_surface(output);
384 render_frame(bar, output); 389 set_output_dirty(output);
385 } 390 }
386} 391}
387 392
@@ -470,12 +475,10 @@ static const struct wl_registry_listener registry_listener = {
470 .global_remove = handle_global_remove, 475 .global_remove = handle_global_remove,
471}; 476};
472 477
473static void render_all_frames(struct swaybar *bar) { 478static void set_bar_dirty(struct swaybar *bar) {
474 struct swaybar_output *output; 479 struct swaybar_output *output;
475 wl_list_for_each(output, &bar->outputs, link) { 480 wl_list_for_each(output, &bar->outputs, link) {
476 if (output->surface != NULL) { 481 set_output_dirty(output);
477 render_frame(bar, output);
478 }
479 } 482 }
480} 483}
481 484
@@ -528,7 +531,7 @@ bool bar_setup(struct swaybar *bar,
528 assert(pointer->cursor_surface); 531 assert(pointer->cursor_surface);
529 532
530 ipc_get_workspaces(bar); 533 ipc_get_workspaces(bar);
531 render_all_frames(bar); 534 set_bar_dirty(bar);
532 return true; 535 return true;
533} 536}
534 537
@@ -543,7 +546,7 @@ static void display_in(int fd, short mask, void *data) {
543static void ipc_in(int fd, short mask, void *data) { 546static void ipc_in(int fd, short mask, void *data) {
544 struct swaybar *bar = data; 547 struct swaybar *bar = data;
545 if (handle_ipc_readable(bar)) { 548 if (handle_ipc_readable(bar)) {
546 render_all_frames(bar); 549 set_bar_dirty(bar);
547 } 550 }
548} 551}
549 552
@@ -551,10 +554,10 @@ static void status_in(int fd, short mask, void *data) {
551 struct swaybar *bar = data; 554 struct swaybar *bar = data;
552 if (mask & (POLLHUP | POLLERR)) { 555 if (mask & (POLLHUP | POLLERR)) {
553 status_error(bar->status, "[error reading from status command]"); 556 status_error(bar->status, "[error reading from status command]");
554 render_all_frames(bar); 557 set_bar_dirty(bar);
555 remove_event(fd); 558 remove_event(fd);
556 } else if (status_handle_readable(bar->status)) { 559 } else if (status_handle_readable(bar->status)) {
557 render_all_frames(bar); 560 set_bar_dirty(bar);
558 } 561 }
559} 562}
560 563
diff --git a/swaybar/config.c b/swaybar/config.c
index db7b0db6..4e851cca 100644
--- a/swaybar/config.c
+++ b/swaybar/config.c
@@ -22,7 +22,7 @@ uint32_t parse_position(const char *position) {
22 } 22 }
23} 23}
24 24
25struct swaybar_config *init_config() { 25struct swaybar_config *init_config(void) {
26 struct swaybar_config *config = calloc(1, sizeof(struct swaybar_config)); 26 struct swaybar_config *config = calloc(1, sizeof(struct swaybar_config));
27 config->status_command = NULL; 27 config->status_command = NULL;
28 config->pango_markup = false; 28 config->pango_markup = false;
diff --git a/swaybar/render.c b/swaybar/render.c
index 90e5bac7..dc31a5ea 100644
--- a/swaybar/render.c
+++ b/swaybar/render.c
@@ -473,7 +473,22 @@ static uint32_t render_to_cairo(cairo_t *cairo, struct swaybar_output *output) {
473 return max_height > output->height ? max_height : output->height; 473 return max_height > output->height ? max_height : output->height;
474} 474}
475 475
476void render_frame(struct swaybar *bar, struct swaybar_output *output) { 476static void output_frame_handle_done(void *data, struct wl_callback *callback,
477 uint32_t time) {
478 wl_callback_destroy(callback);
479 struct swaybar_output *output = data;
480 output->frame_scheduled = false;
481 if (output->dirty) {
482 render_frame(output);
483 output->dirty = false;
484 }
485}
486
487static const struct wl_callback_listener output_frame_listener = {
488 .done = output_frame_handle_done
489};
490
491void render_frame(struct swaybar_output *output) {
477 assert(output->surface != NULL); 492 assert(output->surface != NULL);
478 493
479 struct swaybar_hotspot *hotspot, *tmp; 494 struct swaybar_hotspot *hotspot, *tmp;
@@ -518,6 +533,8 @@ void render_frame(struct swaybar *bar, struct swaybar_output *output) {
518 output->width * output->scale, 533 output->width * output->scale,
519 output->height * output->scale); 534 output->height * output->scale);
520 if (!output->current_buffer) { 535 if (!output->current_buffer) {
536 cairo_surface_destroy(recorder);
537 cairo_destroy(cairo);
521 return; 538 return;
522 } 539 }
523 cairo_t *shm = output->current_buffer->cairo; 540 cairo_t *shm = output->current_buffer->cairo;
@@ -535,6 +552,11 @@ void render_frame(struct swaybar *bar, struct swaybar_output *output) {
535 output->current_buffer->buffer, 0, 0); 552 output->current_buffer->buffer, 0, 0);
536 wl_surface_damage(output->surface, 0, 0, 553 wl_surface_damage(output->surface, 0, 0,
537 output->width, output->height); 554 output->width, output->height);
555
556 struct wl_callback *frame_callback = wl_surface_frame(output->surface);
557 wl_callback_add_listener(frame_callback, &output_frame_listener, output);
558 output->frame_scheduled = true;
559
538 wl_surface_commit(output->surface); 560 wl_surface_commit(output->surface);
539 } 561 }
540 cairo_surface_destroy(recorder); 562 cairo_surface_destroy(recorder);
diff --git a/swayidle/main.c b/swayidle/main.c
index 678d622f..5b6c95a7 100644
--- a/swayidle/main.c
+++ b/swayidle/main.c
@@ -92,7 +92,7 @@ static int release_lock(void *data) {
92 return 0; 92 return 0;
93} 93}
94 94
95void acquire_sleep_lock() { 95void acquire_sleep_lock(void) {
96 sd_bus_message *msg = NULL; 96 sd_bus_message *msg = NULL;
97 sd_bus_error error = SD_BUS_ERROR_NULL; 97 sd_bus_error error = SD_BUS_ERROR_NULL;
98 struct sd_bus *bus; 98 struct sd_bus *bus;
@@ -161,7 +161,7 @@ static int dbus_event(int fd, uint32_t mask, void *data) {
161 return 1; 161 return 1;
162} 162}
163 163
164void setup_sleep_listener() { 164void setup_sleep_listener(void) {
165 struct sd_bus *bus; 165 struct sd_bus *bus;
166 166
167 int ret = sd_bus_default_system(&bus); 167 int ret = sd_bus_default_system(&bus);
diff --git a/swaylock/main.c b/swaylock/main.c
index 693cbc10..ed8c5607 100644
--- a/swaylock/main.c
+++ b/swaylock/main.c
@@ -32,7 +32,7 @@ void sway_terminate(int exit_code) {
32 exit(exit_code); 32 exit(exit_code);
33} 33}
34 34
35static void daemonize() { 35static void daemonize(void) {
36 int fds[2]; 36 int fds[2];
37 if (pipe(fds) != 0) { 37 if (pipe(fds) != 0) {
38 wlr_log(WLR_ERROR, "Failed to pipe"); 38 wlr_log(WLR_ERROR, "Failed to pipe");
diff --git a/swaynag/config.c b/swaynag/config.c
index 4d0824c9..cd34dcc2 100644
--- a/swaynag/config.c
+++ b/swaynag/config.c
@@ -11,7 +11,7 @@
11#include "util.h" 11#include "util.h"
12#include "wlr-layer-shell-unstable-v1-client-protocol.h" 12#include "wlr-layer-shell-unstable-v1-client-protocol.h"
13 13
14static char *read_from_stdin() { 14static char *read_from_stdin(void) {
15 char *buffer = NULL; 15 char *buffer = NULL;
16 while (!feof(stdin)) { 16 while (!feof(stdin)) {
17 char *line = read_line(stdin); 17 char *line = read_line(stdin);