diff options
36 files changed, 206 insertions, 212 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,  /**   * TODO: Move this function and its dependent functions to container.c.   */ -void container_resize_tiled(struct sway_container *parent, enum wlr_edges edge, +bool container_resize_tiled(struct sway_container *parent, enum wlr_edges edge,  		int amount);  sway_cmd cmd_assign; @@ -217,6 +217,7 @@ sway_cmd bar_colors_cmd_urgent_workspace;  sway_cmd input_cmd_seat;  sway_cmd input_cmd_accel_profile;  sway_cmd input_cmd_click_method; +sway_cmd input_cmd_drag;  sway_cmd input_cmd_drag_lock;  sway_cmd input_cmd_dwt;  sway_cmd input_cmd_events; diff --git a/include/sway/config.h b/include/sway/config.h index 82be26ca..eab48aed 100644 --- a/include/sway/config.h +++ b/include/sway/config.h @@ -93,6 +93,7 @@ struct input_config {  	int accel_profile;  	int click_method; +	int drag;  	int drag_lock;  	int dwt;  	int left_handed; @@ -451,8 +452,6 @@ void free_sway_variable(struct sway_variable *var);   */  char *do_var_replacement(char *str); -struct cmd_results *check_security_config(); -  int input_identifier_cmp(const void *item, const void *data);  struct input_config *new_input_config(const char* identifier); @@ -473,7 +472,7 @@ struct seat_config *copy_seat_config(struct seat_config *seat);  void free_seat_config(struct seat_config *ic); -struct seat_attachment_config *seat_attachment_config_new(); +struct seat_attachment_config *seat_attachment_config_new(void);  struct seat_attachment_config *seat_config_get_attachment(  		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 {  extern struct sway_debug debug; -void update_debug_tree(); +void update_debug_tree(void);  #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 @@  #include "sway/tree/container.h"  #include "sway/input/input-manager.h" -json_object *ipc_json_get_version(); +json_object *ipc_json_get_version(void);  json_object *ipc_json_describe_disabled_output(struct sway_output *o);  json_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 {  	enum wl_output_subpixel subpixel;  	struct pool_buffer buffers[2];  	struct pool_buffer *current_buffer; +	bool dirty; +	bool frame_scheduled;  };  struct 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 {  	} colors;  }; -struct swaybar_config *init_config(); +struct swaybar_config *init_config(void);  void free_config(struct swaybar_config *config);  uint32_t parse_position(const char *position); 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 @@  #ifndef _SWAYBAR_RENDER_H  #define _SWAYBAR_RENDER_H -struct swaybar;  struct swaybar_output; -struct swaybar_config; -void render_frame(struct swaybar *bar, struct swaybar_output *output); +void render_frame(struct swaybar_output *output);  #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 @@ -#ifndef _SWAYBAR_DBUS_H -#define _SWAYBAR_DBUS_H - -#include <stdbool.h> -#include <dbus/dbus.h> -extern DBusConnection *conn; - -/** - * Should be called in main loop to dispatch events - */ -void dispatch_dbus(); - -/** - * Initializes async dbus communication - */ -int dbus_init(); - -#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 @@ -#ifndef _SWAYBAR_SNI_WATCHER_H -#define _SWAYBAR_SNI_WATCHER_H - -/** - * Starts the sni_watcher, the watcher is practically a black box and should - * only be accessed though functions described in its spec - */ -int init_sni_watcher(); - -#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 @@ -#ifndef _SWAYBAR_TRAY_H -#define _SWAYBAR_TRAY_H - -#include <stdint.h> -#include <stdbool.h> -#include "swaybar/tray/dbus.h" -#include "swaybar/tray/sni.h" -#include "swaybar/bar.h" -#include "list.h" - -extern struct tray *tray; - -struct tray { -	list_t *items; -}; - -/** - * Processes a mouse event on the bar - */ -void tray_mouse_event(struct output *output, int x, int y, -		uint32_t button, uint32_t state); - -uint32_t tray_render(struct output *output, struct config *config); - -void tray_upkeep(struct bar *bar); - -/** - * Initializes the tray with D-Bus - */ -void init_tray(struct bar *bar); - -#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')  pangocairo     = dependency('pangocairo')  gdk_pixbuf     = dependency('gdk-pixbuf-2.0', required: false)  pixman         = dependency('pixman-1') -libcap         = dependency('libcap', required: false)  libinput       = dependency('libinput', version: '>=1.6.0')  libpam         = cc.find_library('pam', required: false)  systemd        = 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) {  	// Var replacement, for all but first argument of set  	// TODO commands  	for (i = handler->handle == cmd_set ? 2 : 1; i < argc; ++i) { +		if (*argv[i] == '\"' || *argv[i] == '\'') { +			strip_quotes(argv[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 { @@ -422,11 +420,6 @@ struct cmd_results *config_subcommand(char **argv, int argc,  		char *input = argv[0] ? argv[0] : "(empty)";  		return cmd_results_new(CMD_INVALID, input, "Unknown/invalid command");  	} -	// 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) {  		return handler->handle(argc - 1, argv + 1);  	} 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 @@  static struct cmd_handler input_handlers[] = {  	{ "accel_profile", input_cmd_accel_profile },  	{ "click_method", input_cmd_click_method }, +	{ "drag", input_cmd_drag },  	{ "drag_lock", input_cmd_drag_lock },  	{ "dwt", input_cmd_dwt },  	{ "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 @@ +#include <string.h> +#include <strings.h> +#include "sway/config.h" +#include "sway/commands.h" +#include "sway/input/input-manager.h" +#include "util.h" + +struct cmd_results *input_cmd_drag(int argc, char **argv) { +	struct cmd_results *error = NULL; +	if ((error = checkarg(argc, "drag", EXPECTED_AT_LEAST, 1))) { +		return error; +	} +	struct input_config *ic = config->handler_context.input_config; +	if (!ic) { +		return cmd_results_new(CMD_FAILURE, +			"drag", "No input device defined."); +	} + +	if (parse_boolean(argv[0], true)) { +		ic->drag = LIBINPUT_CONFIG_DRAG_ENABLED; +	} else { +		ic->drag = LIBINPUT_CONFIG_DRAG_DISABLED; +	} + +	return cmd_results_new(CMD_SUCCESS, NULL, NULL); +} 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) {  			}  			free(src);  		} else { -			// Escape spaces and quotes in the final path for swaybg +			// Escape double quotes in the final path for swaybg  			for (size_t i = 0; i < strlen(src); i++) { -				switch (src[i]) { -					case ' ': -					case '\'': -					case '\"': -						src = realloc(src, strlen(src) + 2); -						memmove(src + i + 1, src + i, strlen(src + i) + 1); -						*(src + i) = '\\'; -						i++; -						break; -					default: -						break; +				if (src[i] == '"') { +					src = realloc(src, strlen(src) + 2); +					memmove(src + i + 1, src + i, strlen(src + i) + 1); +					*(src + i) = '\\'; +					i++;  				}  			} 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,  	}  } -static void resize_tiled(struct sway_container *parent, int amount, +static bool resize_tiled(struct sway_container *parent, int amount,  		enum resize_axis axis) {  	struct sway_container *focused = parent;  	if (!parent) { -		return; +		return false;  	}  	enum sway_container_layout parallel_layout = @@ -216,7 +216,7 @@ static void resize_tiled(struct sway_container *parent, int amount,  	}  	if (!parent) {  		// Can't resize in this direction -		return; +		return false;  	}  	// 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,  			if (sibling_pos < parent_pos && minor_weight) {  				double pixels = -amount / minor_weight;  				if (major_weight && (sibling_size + pixels / 2) < min_sane) { -					return; // Too small +					return false; // Too small  				} else if (!major_weight && sibling_size + pixels < min_sane) { -					return; // Too small +					return false; // Too small  				}  			} else if (sibling_pos > parent_pos && major_weight) {  				double pixels = -amount / major_weight;  				if (minor_weight && (sibling_size + pixels / 2) < min_sane) { -					return; // Too small +					return false; // Too small  				} else if (!minor_weight && sibling_size + pixels < min_sane) { -					return; // Too small +					return false; // Too small  				}  			}  		} else {  			double pixels = amount;  			if (parent_size + pixels < min_sane) { -				return; // Too small +				return false; // Too small  			}  		}  	} @@ -317,9 +317,10 @@ static void resize_tiled(struct sway_container *parent, int amount,  	} else {  		arrange_workspace(parent->workspace);  	} +	return true;  } -void container_resize_tiled(struct sway_container *parent, +bool container_resize_tiled(struct sway_container *parent,  		enum wlr_edges edge, int amount) {  	enum resize_axis axis = RESIZE_AXIS_INVALID;  	switch (edge) { @@ -338,7 +339,7 @@ void container_resize_tiled(struct sway_container *parent,  	case WLR_EDGE_NONE:  		break;  	} -	resize_tiled(parent, amount, axis); +	return resize_tiled(parent, amount, axis);  }  /** @@ -395,6 +396,10 @@ static struct cmd_results *resize_adjust_floating(enum resize_axis axis,  	case RESIZE_AXIS_INVALID:  		return cmd_results_new(CMD_INVALID, "resize", "Invalid axis/direction");  	} +	if (grow_x == 0 && grow_y == 0) { +		return cmd_results_new(CMD_INVALID, "resize", +				"Cannot resize any further"); +	}  	con->x += grow_x;  	con->y += grow_y;  	con->width += grow_width; @@ -442,7 +447,10 @@ static struct cmd_results *resize_adjust_tiled(enum resize_axis axis,  		}  	} -	resize_tiled(current, amount->amount, axis); +	if (!resize_tiled(current, amount->amount, axis)) { +		return cmd_results_new(CMD_INVALID, "resize", +				"Cannot resize any further"); +	}  	return cmd_results_new(CMD_SUCCESS, NULL, NULL);  } 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) {  	input->tap = INT_MIN;  	input->tap_button_map = INT_MIN; +	input->drag = INT_MIN;  	input->drag_lock = INT_MIN;  	input->dwt = INT_MIN;  	input->send_events = INT_MIN; @@ -46,6 +47,9 @@ void merge_input_config(struct input_config *dst, struct input_config *src) {  	if (src->click_method != INT_MIN) {  		dst->click_method = src->click_method;  	} +	if (src->drag != INT_MIN) { +		dst->drag = src->drag; +	}  	if (src->drag_lock != INT_MIN) {  		dst->drag_lock = src->drag_lock;  	} 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) {  		wlr_log(WLR_DEBUG, "Setting background for output %d to %s",  				output_i, oc->background); -		size_t len = snprintf(NULL, 0, "%s %d %s %s %s", +		size_t len = snprintf(NULL, 0, "%s %d \"%s\" %s %s",  				config->swaybg_command ? config->swaybg_command : "swaybg",  				output_i, oc->background, oc->background_option,  				oc->background_fallback ? oc->background_fallback : ""); @@ -246,7 +246,7 @@ void apply_output_config(struct output_config *oc, struct sway_output *output) {  			wlr_log(WLR_DEBUG, "Unable to allocate swaybg command");  			return;  		} -		snprintf(command, len + 1, "%s %d %s %s %s", +		snprintf(command, len + 1, "%s %d \"%s\" %s %s",  				config->swaybg_command ? config->swaybg_command : "swaybg",  				output_i, oc->background, oc->background_option,  				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) {  	return seat;  } -struct seat_attachment_config *seat_attachment_config_new() { +struct seat_attachment_config *seat_attachment_config_new(void) {  	struct seat_attachment_config *attachment =  		calloc(1, sizeof(struct seat_attachment_config));  	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,  	return height;  } -void update_debug_tree() { +void update_debug_tree(void) {  	if (!debug.render_tree) {  		return;  	} 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 @@  // when dragging to the edge of a layout container.  #define DROP_LAYOUT_BORDER 30 -static uint32_t get_current_time_msec() { +static uint32_t get_current_time_msec(void) {  	struct timespec now;  	clock_gettime(CLOCK_MONOTONIC, &now);  	return now.tv_nsec / 1000; @@ -1006,8 +1006,7 @@ static void handle_touch_down(struct wl_listener *listener, void *data) {  	if (seat_is_input_allowed(seat, surface)) {  		wlr_seat_touch_notify_down(wlr_seat, surface, event->time_msec,  				event->touch_id, sx, sy); -		cursor->image_client = NULL; -		wlr_cursor_set_image(cursor->cursor, NULL, 0, 0, 0, 0, 0, 0); +		cursor_set_image(cursor, NULL, NULL);  	}  } @@ -1175,11 +1174,13 @@ static void handle_request_set_cursor(struct wl_listener *listener,  void cursor_set_image(struct sway_cursor *cursor, const char *image,  		struct wl_client *client) { -	if (!cursor->image || strcmp(cursor->image, image) != 0) { +	if (!image) { +		wlr_cursor_set_image(cursor->cursor, NULL, 0, 0, 0, 0, 0, 0); +	} else if (!cursor->image || strcmp(cursor->image, image) != 0) {  		wlr_xcursor_manager_set_cursor_image(cursor->xcursor_manager, image,  				cursor->cursor); -		cursor->image = image;  	} +	cursor->image = image;  	cursor->image_client = client;  } 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(  		libinput_device_config_click_set_method(libinput_device,  			ic->click_method);  	} +	if (ic->drag != INT_MIN) { +		wlr_log(WLR_DEBUG, +			"libinput_config_pointer(%s) tap_set_drag_enabled(%d)", +			ic->identifier, ic->click_method); +		libinput_device_config_tap_set_drag_enabled(libinput_device, +			ic->drag); +	}  	if (ic->drag_lock != INT_MIN) {  		wlr_log(WLR_DEBUG,  			"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) {  			caps |= WL_SEAT_CAPABILITY_TOUCH;  			break;  		case WLR_INPUT_DEVICE_TABLET_TOOL: +			caps |= WL_SEAT_CAPABILITY_POINTER; +			break;  		case WLR_INPUT_DEVICE_TABLET_PAD:  			break;  		}  	}  	wlr_seat_set_capabilities(seat->wlr_seat, caps); + +	// Hide cursor if seat doesn't have pointer capability +	if ((caps & WL_SEAT_CAPABILITY_POINTER) == 0) { +		cursor_set_image(seat->cursor, NULL, NULL); +	} else { +		cursor_set_image(seat->cursor, "left_ptr", NULL); +	}  }  static void seat_apply_input_config(struct sway_seat *seat, @@ -552,8 +561,7 @@ void seat_configure_xcursor(struct sway_seat *seat) {  			output->name, (double)output->scale);  	} -	wlr_xcursor_manager_set_cursor_image(seat->cursor->xcursor_manager, -		"left_ptr", seat->cursor->cursor); +	cursor_set_image(seat->cursor, "left_ptr", NULL);  	wlr_cursor_warp(seat->cursor->cursor, NULL, seat->cursor->cursor->x,  		seat->cursor->cursor->y);  } 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  	return "none";  } -json_object *ipc_json_get_version() { +json_object *ipc_json_get_version(void) {  	int major = 0, minor = 0, patch = 0;  	json_object *version = json_object_new_object(); 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 @@  #include <sys/wait.h>  #include <sys/un.h>  #include <unistd.h> -#ifdef __linux__ -#include <sys/capability.h> -#include <sys/prctl.h> -#endif  #include <wlr/util/log.h>  #include "sway/commands.h"  #include "sway/config.h" @@ -45,7 +41,7 @@ void sig_handler(int signal) {  	sway_terminate(EXIT_SUCCESS);  } -void detect_raspi() { +void detect_raspi(void) {  	bool raspi = false;  	FILE *f = fopen("/sys/firmware/devicetree/base/model", "r");  	if (!f) { @@ -85,7 +81,7 @@ void detect_raspi() {  	}  } -void detect_proprietary() { +void detect_proprietary(void) {  	FILE *f = fopen("/proc/modules", "r");  	if (!f) {  		return; @@ -120,7 +116,7 @@ void run_as_ipc_client(char *command, char *socket_path) {  	close(socketfd);  } -static void log_env() { +static void log_env(void) {  	const char *log_vars[] = {  		"PATH",  		"LD_LIBRARY_PATH", @@ -135,7 +131,7 @@ static void log_env() {  	}  } -static void log_distro() { +static void log_distro(void) {  	const char *paths[] = {  		"/etc/lsb-release",  		"/etc/os-release", @@ -162,7 +158,7 @@ static void log_distro() {  	}  } -static void log_kernel() { +static void log_kernel(void) {  	FILE *f = popen("uname -a", "r");  	if (!f) {  		wlr_log(WLR_INFO, "Unable to determine kernel version"); @@ -181,28 +177,8 @@ static void log_kernel() {  	pclose(f);  } -static void executable_sanity_check() { -#ifdef __linux__ -		struct stat sb; -		char *exe = realpath("/proc/self/exe", NULL); -		stat(exe, &sb); -		// We assume that cap_get_file returning NULL implies ENODATA -		if (sb.st_mode & (S_ISUID|S_ISGID) && cap_get_file(exe)) { -			wlr_log(WLR_ERROR, -				"sway executable has both the s(g)uid bit AND file caps set."); -			wlr_log(WLR_ERROR, -				"This is strongly discouraged (and completely broken)."); -			wlr_log(WLR_ERROR, -				"Please clear one of them (either the suid bit, or the file caps)."); -			wlr_log(WLR_ERROR, -				"If unsure, strip the file caps."); -			exit(EXIT_FAILURE); -		} -		free(exe); -#endif -} -static void drop_permissions(bool keep_caps) { +static void drop_permissions(void) {  	if (getuid() != geteuid() || getgid() != getegid()) {  		if (setgid(getgid()) != 0) {  			wlr_log(WLR_ERROR, "Unable to drop root"); @@ -217,20 +193,6 @@ static void drop_permissions(bool keep_caps) {  		wlr_log(WLR_ERROR, "Root privileges can be restored.");  		exit(EXIT_FAILURE);  	} -#ifdef __linux__ -	if (keep_caps) { -		// Drop every cap except CAP_SYS_PTRACE -		cap_t caps = cap_init(); -		cap_value_t keep = CAP_SYS_PTRACE; -		wlr_log(WLR_INFO, "Dropping extra capabilities"); -		if (cap_set_flag(caps, CAP_PERMITTED, 1, &keep, CAP_SET) || -			cap_set_flag(caps, CAP_EFFECTIVE, 1, &keep, CAP_SET) || -			cap_set_proc(caps)) { -			wlr_log(WLR_ERROR, "Failed to drop extra capabilities"); -			exit(EXIT_FAILURE); -		} -	} -#endif  }  void enable_debug_flag(const char *flag) { @@ -347,7 +309,7 @@ int main(int argc, char **argv) {  			wlr_log(WLR_ERROR, "Don't use options with the IPC client");  			exit(EXIT_FAILURE);  		} -		drop_permissions(false); +		drop_permissions();  		char *socket_path = getenv("SWAYSOCK");  		if (!socket_path) {  			wlr_log(WLR_ERROR, "Unable to retrieve socket path"); @@ -358,34 +320,17 @@ int main(int argc, char **argv) {  		return 0;  	} -	executable_sanity_check(); -	bool suid = false; -  	if (!server_privileged_prepare(&server)) {  		return 1;  	} -#if defined(__linux__) || defined(__FreeBSD__) -	if (getuid() != geteuid() || getgid() != getegid()) { -#ifdef __linux__ -		// Retain capabilities after setuid() -		if (prctl(PR_SET_KEEPCAPS, 1, 0, 0, 0)) { -			wlr_log(WLR_ERROR, "Cannot keep caps after setuid()"); -			exit(EXIT_FAILURE); -		} -#endif -		suid = true; -	} -#endif -  	log_kernel();  	log_distro();  	detect_proprietary();  	detect_raspi(); -#if defined(__linux__) || defined(__FreeBSD__) -	drop_permissions(suid); -#endif +	drop_permissions(); +  	// handle SIGTERM signals  	signal(SIGTERM, sig_handler); 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(  	'commands/input/accel_profile.c',  	'commands/input/click_method.c', +	'commands/input/drag.c',  	'commands/input/drag_lock.c',  	'commands/input/dwt.c',  	'commands/input/events.c', @@ -164,7 +165,6 @@ sway_deps = [  	cairo,  	gdk_pixbuf,  	jsonc, -	libcap,  	libinput,  	math,  	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.  *input* <identifier> click\_method none|button\_areas|clickfinger  	Changes the click method for the specified device. +*input* <identifier> drag enabled|disabled +	Enables or disables tap-and-drag for specified input device. +  *input* <identifier> drag\_lock enabled|disabled  	Enables or disables drag lock for specified input device. diff --git a/sway/tree/container.c b/sway/tree/container.c index e329f835..788300cc 100644 --- a/sway/tree/container.c +++ b/sway/tree/container.c @@ -593,7 +593,7 @@ void container_update_representation(struct sway_container *con) {  	}  } -size_t container_titlebar_height() { +size_t container_titlebar_height(void) {  	return config->font_height + TITLEBAR_V_PADDING * 2;  } @@ -823,9 +823,16 @@ void container_floating_move_to_center(struct sway_container *con) {  		return;  	}  	struct sway_workspace *ws = con->workspace; +	bool full = con->is_fullscreen; +	if (full) { +		container_set_fullscreen(con, false); +	}  	double new_lx = ws->x + (ws->width - con->width) / 2;  	double new_ly = ws->y + (ws->height - con->height) / 2;  	container_floating_translate(con, new_lx - con->x, new_ly - con->y); +	if (full) { +		container_set_fullscreen(con, true); +	}  }  static bool find_urgent_iterator(struct sway_container *con, void *data) { diff --git a/sway/tree/output.c b/sway/tree/output.c index 06933dc4..c3176325 100644 --- a/sway/tree/output.c +++ b/sway/tree/output.c @@ -113,6 +113,20 @@ void output_enable(struct sway_output *output, struct output_config *oc) {  	arrange_root();  } +static void evacuate_sticky(struct sway_workspace *old_ws, +		struct sway_output *new_output) { +	struct sway_workspace *new_ws = output_get_active_workspace(new_output); +	while (old_ws->floating->length) { +		struct sway_container *sticky = old_ws->floating->items[0]; +		container_detach(sticky); +		workspace_add_floating(new_ws, sticky); +		container_handle_fullscreen_reparent(sticky); +		container_floating_move_to_center(sticky); +		ipc_event_window(sticky, "move"); +	} +	workspace_detect_urgent(new_ws); +} +  static void output_evacuate(struct sway_output *output) {  	if (!output->workspaces->length) {  		return; @@ -130,17 +144,21 @@ static void output_evacuate(struct sway_output *output) {  		workspace_detach(workspace); -		if (workspace_is_empty(workspace)) { -			workspace_begin_destroy(workspace); -			continue; -		} -  		struct sway_output *new_output =  			workspace_output_get_highest_available(workspace, output);  		if (!new_output) {  			new_output = fallback_output;  		} +		if (workspace_is_empty(workspace)) { +			// If floating is not empty, there are sticky containers to move +			if (workspace->floating->length) { +				evacuate_sticky(workspace, new_output); +			} +			workspace_begin_destroy(workspace); +			continue; +		} +  		if (new_output) {  			workspace_output_add_priority(workspace, new_output);  			output_add_workspace(new_output, workspace); 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),  			container_for_each_child(container, f, data);  		}  	} + +	// Saved workspaces +	for (int i = 0; i < root->saved_workspaces->length; ++i) { +		struct sway_workspace *ws = root->saved_workspaces->items[i]; +		workspace_for_each_container(ws, f, data); +	}  }  struct sway_output *root_find_output( @@ -320,6 +326,15 @@ struct sway_container *root_find_container(  			}  		}  	} + +	// Saved workspaces +	for (int i = 0; i < root->saved_workspaces->length; ++i) { +		struct sway_workspace *ws = root->saved_workspaces->items[i]; +		if ((result = workspace_find_container(ws, test, data))) { +			return result; +		} +	} +  	return NULL;  } 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) {  	free(output);  } +static void set_output_dirty(struct swaybar_output *output) { +	if (output->frame_scheduled) { +		output->dirty = true; +		return; +	} +	if (output->surface) { +		render_frame(output); +	} +} +  static void layer_surface_configure(void *data,  		struct zwlr_layer_surface_v1 *surface,  		uint32_t serial, uint32_t width, uint32_t height) { @@ -79,7 +89,7 @@ static void layer_surface_configure(void *data,  	output->width = width;  	output->height = height;  	zwlr_layer_surface_v1_ack_configure(surface, serial); -	render_frame(output->bar, output); +	set_output_dirty(output);  }  static void layer_surface_closed(void *_output, @@ -325,27 +335,22 @@ static void output_geometry(void *data, struct wl_output *wl_output, int32_t x,  		const char *make, const char *model, int32_t transform) {  	struct swaybar_output *output = data;  	output->subpixel = subpixel; -	if (output->surface) { -		render_frame(output->bar, output); -	}  } -static void output_mode(void *data, struct wl_output *output, uint32_t flags, +static void output_mode(void *data, struct wl_output *wl_output, uint32_t flags,  		int32_t width, int32_t height, int32_t refresh) {  	// Who cares  } -static void output_done(void *data, struct wl_output *output) { -	// Who cares +static void output_done(void *data, struct wl_output *wl_output) { +	struct swaybar_output *output = data; +	set_output_dirty(output);  }  static void output_scale(void *data, struct wl_output *wl_output,  		int32_t factor) {  	struct swaybar_output *output = data;  	output->scale = factor; -	if (output->surface) { -		render_frame(output->bar, output); -	}  }  struct wl_output_listener output_listener = { @@ -381,7 +386,7 @@ static void xdg_output_handle_done(void *data,  		wl_list_insert(&bar->outputs, &output->link);  		add_layer_surface(output); -		render_frame(bar, output); +		set_output_dirty(output);  	}  } @@ -470,12 +475,10 @@ static const struct wl_registry_listener registry_listener = {  	.global_remove = handle_global_remove,  }; -static void render_all_frames(struct swaybar *bar) { +static void set_bar_dirty(struct swaybar *bar) {  	struct swaybar_output *output;  	wl_list_for_each(output, &bar->outputs, link) { -		if (output->surface != NULL) { -			render_frame(bar, output); -		} +		set_output_dirty(output);  	}  } @@ -528,7 +531,7 @@ bool bar_setup(struct swaybar *bar,  	assert(pointer->cursor_surface);  	ipc_get_workspaces(bar); -	render_all_frames(bar); +	set_bar_dirty(bar);  	return true;  } @@ -543,7 +546,7 @@ static void display_in(int fd, short mask, void *data) {  static void ipc_in(int fd, short mask, void *data) {  	struct swaybar *bar = data;  	if (handle_ipc_readable(bar)) { -		render_all_frames(bar); +		set_bar_dirty(bar);  	}  } @@ -551,10 +554,10 @@ static void status_in(int fd, short mask, void *data) {  	struct swaybar *bar = data;  	if (mask & (POLLHUP | POLLERR)) {  		status_error(bar->status, "[error reading from status command]"); -		render_all_frames(bar); +		set_bar_dirty(bar);  		remove_event(fd);  	} else if (status_handle_readable(bar->status)) { -		render_all_frames(bar); +		set_bar_dirty(bar);  	}  } 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) {  	}  } -struct swaybar_config *init_config() { +struct swaybar_config *init_config(void) {  	struct swaybar_config *config = calloc(1, sizeof(struct swaybar_config));  	config->status_command = NULL;  	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) {  	return max_height > output->height ? max_height : output->height;  } -void render_frame(struct swaybar *bar, struct swaybar_output *output) { +static void output_frame_handle_done(void *data, struct wl_callback *callback, +		uint32_t time) { +	wl_callback_destroy(callback); +	struct swaybar_output *output = data; +	output->frame_scheduled = false; +	if (output->dirty) { +		render_frame(output); +		output->dirty = false; +	} +} + +static const struct wl_callback_listener output_frame_listener = { +	.done = output_frame_handle_done +}; + +void render_frame(struct swaybar_output *output) {  	assert(output->surface != NULL);  	struct swaybar_hotspot *hotspot, *tmp; @@ -518,6 +533,8 @@ void render_frame(struct swaybar *bar, struct swaybar_output *output) {  				output->width * output->scale,  				output->height * output->scale);  		if (!output->current_buffer) { +			cairo_surface_destroy(recorder); +			cairo_destroy(cairo);  			return;  		}  		cairo_t *shm = output->current_buffer->cairo; @@ -535,6 +552,11 @@ void render_frame(struct swaybar *bar, struct swaybar_output *output) {  				output->current_buffer->buffer, 0, 0);  		wl_surface_damage(output->surface, 0, 0,  				output->width, output->height); + +		struct wl_callback *frame_callback = wl_surface_frame(output->surface); +		wl_callback_add_listener(frame_callback, &output_frame_listener, output); +		output->frame_scheduled = true; +  		wl_surface_commit(output->surface);  	}  	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) {  	return 0;  } -void acquire_sleep_lock() { +void acquire_sleep_lock(void) {  	sd_bus_message *msg = NULL;  	sd_bus_error error = SD_BUS_ERROR_NULL;  	struct sd_bus *bus; @@ -161,7 +161,7 @@ static int dbus_event(int fd, uint32_t mask, void *data) {  	return 1;  } -void setup_sleep_listener() { +void setup_sleep_listener(void) {  	struct sd_bus *bus;  	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) {  	exit(exit_code);  } -static void daemonize() { +static void daemonize(void) {  	int fds[2];  	if (pipe(fds) != 0) {  		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 @@  #include "util.h"  #include "wlr-layer-shell-unstable-v1-client-protocol.h" -static char *read_from_stdin() { +static char *read_from_stdin(void) {  	char *buffer = NULL;  	while (!feof(stdin)) {  		char *line = read_line(stdin); | 
