diff options
Diffstat (limited to 'dwl.c')
| -rw-r--r-- | dwl.c | 274 | 
1 files changed, 80 insertions, 194 deletions
| @@ -39,6 +39,7 @@  #include <wlr/types/wlr_screencopy_v1.h>  #include <wlr/types/wlr_seat.h>  #include <wlr/types/wlr_server_decoration.h> +#include <wlr/types/wlr_subcompositor.h>  #include <wlr/types/wlr_viewporter.h>  #include <wlr/types/wlr_virtual_keyboard_v1.h>  #include <wlr/types/wlr_xcursor_manager.h> @@ -121,14 +122,6 @@ typedef struct {  } Client;  typedef struct { -	uint32_t singular_anchor; -	uint32_t anchor_triplet; -	int *positive_axis; -	int *negative_axis; -	int margin; -} Edge; - -typedef struct {  	uint32_t mod;  	xkb_keysym_t keysym;  	void (*func)(const Arg *); @@ -137,7 +130,7 @@ typedef struct {  typedef struct {  	struct wl_list link; -	struct wlr_input_device *device; +	struct wlr_keyboard *wlr_keyboard;  	struct wl_listener modifiers;  	struct wl_listener key; @@ -149,6 +142,7 @@ typedef struct {  	unsigned int type; /* LayerShell */  	int mapped;  	struct wlr_scene_node *scene; +	struct wlr_scene_layer_surface_v1 *scene_layer;  	struct wl_list link;  	struct wlr_layer_surface_v1 *layer_surface; @@ -156,8 +150,6 @@ typedef struct {  	struct wl_listener map;  	struct wl_listener unmap;  	struct wl_listener surface_commit; - -	struct wlr_box geo;  } LayerSurface;  typedef struct { @@ -202,9 +194,6 @@ typedef struct {  /* function declarations */  static void applybounds(Client *c, struct wlr_box *bbox); -static void applyexclusive(struct wlr_box *usable_area, uint32_t anchor, -		int32_t exclusive, int32_t margin_top, int32_t margin_right, -		int32_t margin_bottom, int32_t margin_left);  static void applyrules(Client *c);  static void arrange(Monitor *m);  static void arrangelayer(Monitor *m, struct wl_list *list, @@ -220,11 +209,11 @@ static void closemon(Monitor *m);  static void commitlayersurfacenotify(struct wl_listener *listener, void *data);  static void commitnotify(struct wl_listener *listener, void *data);  static void createidleinhibitor(struct wl_listener *listener, void *data); -static void createkeyboard(struct wlr_input_device *device); +static void createkeyboard(struct wlr_keyboard *keyboard);  static void createlayersurface(struct wl_listener *listener, void *data);  static void createmon(struct wl_listener *listener, void *data);  static void createnotify(struct wl_listener *listener, void *data); -static void createpointer(struct wlr_input_device *device); +static void createpointer(struct wlr_pointer *pointer);  static void cursorframe(struct wl_listener *listener, void *data);  static void destroyidleinhibitor(struct wl_listener *listener, void *data);  static void destroylayersurfacenotify(struct wl_listener *listener, void *data); @@ -271,7 +260,6 @@ static void setmon(Client *c, Monitor *m, unsigned int newtags);  static void setpsel(struct wl_listener *listener, void *data);  static void setsel(struct wl_listener *listener, void *data);  static void setup(void); -static void sigchld(int unused);  static void spawn(const Arg *arg);  static void startdrag(struct wl_listener *listener, void *data);  static void tag(const Arg *arg); @@ -358,6 +346,7 @@ static void activatex11(struct wl_listener *listener, void *data);  static void configurex11(struct wl_listener *listener, void *data);  static void createnotifyx11(struct wl_listener *listener, void *data);  static Atom getatom(xcb_connection_t *xc, const char *name); +static void sigchld(int unused);  static void xwaylandready(struct wl_listener *listener, void *data);  static struct wl_listener new_xwayland_surface = {.notify = createnotifyx11};  static struct wl_listener xwayland_ready = {.notify = xwaylandready}; @@ -393,61 +382,6 @@ applybounds(Client *c, struct wlr_box *bbox)  }  void -applyexclusive(struct wlr_box *usable_area, -		uint32_t anchor, int32_t exclusive, -		int32_t margin_top, int32_t margin_right, -		int32_t margin_bottom, int32_t margin_left) { -	Edge edges[] = { -		{ /* Top */ -			.singular_anchor = ZWLR_LAYER_SURFACE_V1_ANCHOR_TOP, -			.anchor_triplet = ZWLR_LAYER_SURFACE_V1_ANCHOR_LEFT | -				ZWLR_LAYER_SURFACE_V1_ANCHOR_RIGHT | -				ZWLR_LAYER_SURFACE_V1_ANCHOR_TOP, -			.positive_axis = &usable_area->y, -			.negative_axis = &usable_area->height, -			.margin = margin_top, -		}, -		{ /* Bottom */ -			.singular_anchor = ZWLR_LAYER_SURFACE_V1_ANCHOR_BOTTOM, -			.anchor_triplet = ZWLR_LAYER_SURFACE_V1_ANCHOR_LEFT | -				ZWLR_LAYER_SURFACE_V1_ANCHOR_RIGHT | -				ZWLR_LAYER_SURFACE_V1_ANCHOR_BOTTOM, -			.positive_axis = NULL, -			.negative_axis = &usable_area->height, -			.margin = margin_bottom, -		}, -		{ /* Left */ -			.singular_anchor = ZWLR_LAYER_SURFACE_V1_ANCHOR_LEFT, -			.anchor_triplet = ZWLR_LAYER_SURFACE_V1_ANCHOR_LEFT | -				ZWLR_LAYER_SURFACE_V1_ANCHOR_TOP | -				ZWLR_LAYER_SURFACE_V1_ANCHOR_BOTTOM, -			.positive_axis = &usable_area->x, -			.negative_axis = &usable_area->width, -			.margin = margin_left, -		}, -		{ /* Right */ -			.singular_anchor = ZWLR_LAYER_SURFACE_V1_ANCHOR_RIGHT, -			.anchor_triplet = ZWLR_LAYER_SURFACE_V1_ANCHOR_RIGHT | -				ZWLR_LAYER_SURFACE_V1_ANCHOR_TOP | -				ZWLR_LAYER_SURFACE_V1_ANCHOR_BOTTOM, -			.positive_axis = NULL, -			.negative_axis = &usable_area->width, -			.margin = margin_right, -		} -	}; -	for (size_t i = 0; i < LENGTH(edges); i++) { -		if ((anchor == edges[i].singular_anchor || anchor == edges[i].anchor_triplet) -				&& exclusive + edges[i].margin > 0) { -			if (edges[i].positive_axis) -				*edges[i].positive_axis += exclusive + edges[i].margin; -			if (edges[i].negative_axis) -				*edges[i].negative_axis -= exclusive + edges[i].margin; -			break; -		} -	} -} - -void  applyrules(Client *c)  {  	/* rule matching */ @@ -498,72 +432,11 @@ arrangelayer(Monitor *m, struct wl_list *list, struct wlr_box *usable_area, int  	wl_list_for_each(layersurface, list, link) {  		struct wlr_layer_surface_v1 *wlr_layer_surface = layersurface->layer_surface;  		struct wlr_layer_surface_v1_state *state = &wlr_layer_surface->current; -		struct wlr_box bounds; -		struct wlr_box box = { -			.width = state->desired_width, -			.height = state->desired_height -		}; -		const uint32_t both_horiz = ZWLR_LAYER_SURFACE_V1_ANCHOR_LEFT -			| ZWLR_LAYER_SURFACE_V1_ANCHOR_RIGHT; -		const uint32_t both_vert = ZWLR_LAYER_SURFACE_V1_ANCHOR_TOP -			| ZWLR_LAYER_SURFACE_V1_ANCHOR_BOTTOM;  		if (exclusive != (state->exclusive_zone > 0))  			continue; -		bounds = state->exclusive_zone == -1 ? full_area : *usable_area; - -		/* Horizontal axis */ -		if ((state->anchor & both_horiz) && box.width == 0) { -			box.x = bounds.x; -			box.width = bounds.width; -		} else if ((state->anchor & ZWLR_LAYER_SURFACE_V1_ANCHOR_LEFT)) { -			box.x = bounds.x; -		} else if ((state->anchor & ZWLR_LAYER_SURFACE_V1_ANCHOR_RIGHT)) { -			box.x = bounds.x + (bounds.width - box.width); -		} else { -			box.x = bounds.x + ((bounds.width / 2) - (box.width / 2)); -		} -		/* Vertical axis */ -		if ((state->anchor & both_vert) && box.height == 0) { -			box.y = bounds.y; -			box.height = bounds.height; -		} else if ((state->anchor & ZWLR_LAYER_SURFACE_V1_ANCHOR_TOP)) { -			box.y = bounds.y; -		} else if ((state->anchor & ZWLR_LAYER_SURFACE_V1_ANCHOR_BOTTOM)) { -			box.y = bounds.y + (bounds.height - box.height); -		} else { -			box.y = bounds.y + ((bounds.height / 2) - (box.height / 2)); -		} -		/* Margin */ -		if ((state->anchor & both_horiz) == both_horiz) { -			box.x += state->margin.left; -			box.width -= state->margin.left + state->margin.right; -		} else if ((state->anchor & ZWLR_LAYER_SURFACE_V1_ANCHOR_LEFT)) { -			box.x += state->margin.left; -		} else if ((state->anchor & ZWLR_LAYER_SURFACE_V1_ANCHOR_RIGHT)) { -			box.x -= state->margin.right; -		} -		if ((state->anchor & both_vert) == both_vert) { -			box.y += state->margin.top; -			box.height -= state->margin.top + state->margin.bottom; -		} else if ((state->anchor & ZWLR_LAYER_SURFACE_V1_ANCHOR_TOP)) { -			box.y += state->margin.top; -		} else if ((state->anchor & ZWLR_LAYER_SURFACE_V1_ANCHOR_BOTTOM)) { -			box.y -= state->margin.bottom; -		} -		if (box.width < 0 || box.height < 0) { -			wlr_layer_surface_v1_destroy(wlr_layer_surface); -			continue; -		} -		layersurface->geo = box; - -		if (state->exclusive_zone > 0) -			applyexclusive(usable_area, state->anchor, state->exclusive_zone, -					state->margin.top, state->margin.right, -					state->margin.bottom, state->margin.left); -		wlr_scene_node_set_position(layersurface->scene, box.x, box.y); -		wlr_layer_surface_v1_configure(wlr_layer_surface, box.width, box.height); +		wlr_scene_layer_surface_v1_configure(layersurface->scene_layer, &full_area, usable_area);  	}  } @@ -613,7 +486,7 @@ axisnotify(struct wl_listener *listener, void *data)  {  	/* This event is forwarded by the cursor when a pointer emits an axis event,  	 * for example when you move the scroll wheel. */ -	struct wlr_event_pointer_axis *event = data; +	struct wlr_pointer_axis_event *event = data;  	wlr_idle_notify_activity(idle, seat);  	/* Notify the client with pointer focus of the axis event. */  	wlr_seat_pointer_notify_axis(seat, @@ -624,7 +497,7 @@ axisnotify(struct wl_listener *listener, void *data)  void  buttonpress(struct wl_listener *listener, void *data)  { -	struct wlr_event_pointer_button *event = data; +	struct wlr_pointer_button_event *event = data;  	struct wlr_keyboard *keyboard;  	uint32_t mods;  	Client *c; @@ -695,7 +568,7 @@ void  cleanupkeyboard(struct wl_listener *listener, void *data)  {  	struct wlr_input_device *device = data; -	Keyboard *kb = device->data; +	Keyboard *kb = device->keyboard->data;  	wl_list_remove(&kb->link);  	wl_list_remove(&kb->modifiers.link); @@ -790,29 +663,29 @@ createidleinhibitor(struct wl_listener *listener, void *data)  }  void -createkeyboard(struct wlr_input_device *device) +createkeyboard(struct wlr_keyboard *keyboard)  {  	struct xkb_context *context;  	struct xkb_keymap *keymap; -	Keyboard *kb = device->data = ecalloc(1, sizeof(*kb)); -	kb->device = device; +	Keyboard *kb = keyboard->data = ecalloc(1, sizeof(*kb)); +	kb->wlr_keyboard = keyboard;  	/* Prepare an XKB keymap and assign it to the keyboard. */  	context = xkb_context_new(XKB_CONTEXT_NO_FLAGS);  	keymap = xkb_keymap_new_from_names(context, &xkb_rules,  		XKB_KEYMAP_COMPILE_NO_FLAGS); -	wlr_keyboard_set_keymap(device->keyboard, keymap); +	wlr_keyboard_set_keymap(keyboard, keymap);  	xkb_keymap_unref(keymap);  	xkb_context_unref(context); -	wlr_keyboard_set_repeat_info(device->keyboard, repeat_rate, repeat_delay); +	wlr_keyboard_set_repeat_info(keyboard, repeat_rate, repeat_delay);  	/* Here we set up listeners for keyboard events. */ -	LISTEN(&device->keyboard->events.modifiers, &kb->modifiers, keypressmod); -	LISTEN(&device->keyboard->events.key, &kb->key, keypress); -	LISTEN(&device->events.destroy, &kb->destroy, cleanupkeyboard); +	LISTEN(&keyboard->events.modifiers, &kb->modifiers, keypressmod); +	LISTEN(&keyboard->events.key, &kb->key, keypress); +	LISTEN(&keyboard->base.events.destroy, &kb->destroy, cleanupkeyboard); -	wlr_seat_set_keyboard(seat, device); +	wlr_seat_set_keyboard(seat, keyboard);  	/* And add the keyboard to our list of keyboards */  	wl_list_insert(&keyboards, &kb->link); @@ -845,9 +718,11 @@ createlayersurface(struct wl_listener *listener, void *data)  	wlr_layer_surface->data = layersurface;  	m = wlr_layer_surface->output->data; +	layersurface->scene_layer = wlr_scene_layer_surface_v1_create( +			layers[wlr_layer_surface->pending.layer], wlr_layer_surface);  	layersurface->scene = wlr_layer_surface->surface->data = -			wlr_scene_subsurface_tree_create(layers[wlr_layer_surface->pending.layer], -			wlr_layer_surface->surface); +			layersurface->scene_layer->node; +  	layersurface->scene->data = layersurface;  	wl_list_insert(&m->layers[wlr_layer_surface->pending.layer], @@ -969,11 +844,11 @@ createnotify(struct wl_listener *listener, void *data)  }  void -createpointer(struct wlr_input_device *device) +createpointer(struct wlr_pointer *pointer)  { -	if (wlr_input_device_is_libinput(device)) { +	if (wlr_input_device_is_libinput(&pointer->base)) {  		struct libinput_device *libinput_device =  (struct libinput_device*) -			wlr_libinput_get_device_handle(device); +			wlr_libinput_get_device_handle(&pointer->base);  		if (tap_to_click && libinput_device_config_tap_get_finger_count(libinput_device))  			libinput_device_config_tap_set_enabled(libinput_device, LIBINPUT_CONFIG_TAP_ENABLED); @@ -986,7 +861,7 @@ createpointer(struct wlr_input_device *device)  	 * is proxied through wlr_cursor. On another compositor, you might take this  	 * opportunity to do libinput configuration on the device to set  	 * acceleration, etc. */ -	wlr_cursor_attach_input_device(cursor, device); +	wlr_cursor_attach_input_device(cursor, &pointer->base);  }  void @@ -1219,10 +1094,10 @@ inputdevice(struct wl_listener *listener, void *data)  	switch (device->type) {  	case WLR_INPUT_DEVICE_KEYBOARD: -		createkeyboard(device); +		createkeyboard(device->keyboard);  		break;  	case WLR_INPUT_DEVICE_POINTER: -		createpointer(device); +		createpointer(device->pointer);  		break;  	default:  		/* TODO handle other input device types */ @@ -1265,17 +1140,17 @@ keypress(struct wl_listener *listener, void *data)  	int i;  	/* This event is raised when a key is pressed or released. */  	Keyboard *kb = wl_container_of(listener, kb, key); -	struct wlr_event_keyboard_key *event = data; +	struct wlr_keyboard_key_event *event = data;  	/* Translate libinput keycode -> xkbcommon */  	uint32_t keycode = event->keycode + 8;  	/* Get a list of keysyms based on the keymap for this keyboard */  	const xkb_keysym_t *syms;  	int nsyms = xkb_state_key_get_syms( -			kb->device->keyboard->xkb_state, keycode, &syms); +			kb->wlr_keyboard->xkb_state, keycode, &syms);  	int handled = 0; -	uint32_t mods = wlr_keyboard_get_modifiers(kb->device->keyboard); +	uint32_t mods = wlr_keyboard_get_modifiers(kb->wlr_keyboard);  	wlr_idle_notify_activity(idle, seat); @@ -1288,7 +1163,7 @@ keypress(struct wl_listener *listener, void *data)  	if (!handled) {  		/* Pass unhandled keycodes along to the client. */ -		wlr_seat_set_keyboard(seat, kb->device); +		wlr_seat_set_keyboard(seat, kb->wlr_keyboard);  		wlr_seat_keyboard_notify_key(seat, event->time_msec,  			event->keycode, event->state);  	} @@ -1306,10 +1181,10 @@ keypressmod(struct wl_listener *listener, void *data)  	 * same seat. You can swap out the underlying wlr_keyboard like this and  	 * wlr_seat handles this transparently.  	 */ -	wlr_seat_set_keyboard(seat, kb->device); +	wlr_seat_set_keyboard(seat, kb->wlr_keyboard);  	/* Send modifiers to the client. */  	wlr_seat_keyboard_notify_modifiers(seat, -		&kb->device->keyboard->modifiers); +		&kb->wlr_keyboard->modifiers);  }  void @@ -1400,8 +1275,8 @@ motionabsolute(struct wl_listener *listener, void *data)  	 * move the mouse over the window. You could enter the window from any edge,  	 * so we have to warp the mouse there. There is also some hardware which  	 * emits these events. */ -	struct wlr_event_pointer_motion_absolute *event = data; -	wlr_cursor_warp_absolute(cursor, event->device, event->x, event->y); +	struct wlr_pointer_motion_absolute_event *event = data; +	wlr_cursor_warp_absolute(cursor, &event->pointer->base, event->x, event->y);  	motionnotify(event->time_msec);  } @@ -1455,13 +1330,13 @@ motionrelative(struct wl_listener *listener, void *data)  {  	/* This event is forwarded by the cursor when a pointer emits a _relative_  	 * pointer motion event (i.e. a delta) */ -	struct wlr_event_pointer_motion *event = data; +	struct wlr_pointer_motion_event *event = data;  	/* The cursor doesn't move unless we tell it to. The cursor automatically  	 * handles constraining the motion to the output layout, as well as any  	 * special configuration applied for the specific input device which  	 * generated the event. You can pass NULL for the device if you want to move  	 * the cursor around without any input. */ -	wlr_cursor_move(cursor, event->device, event->delta_x, event->delta_y); +	wlr_cursor_move(cursor, &event->pointer->base, event->delta_x, event->delta_y);  	motionnotify(event->time_msec);  } @@ -1666,18 +1541,6 @@ rendermon(struct wl_listener *listener, void *data)  }  void -requeststartdrag(struct wl_listener *listener, void *data) -{ -	struct wlr_seat_request_start_drag_event *event = data; - -	if (wlr_seat_validate_pointer_grab_serial(seat, event->origin, -			event->serial)) -		wlr_seat_start_pointer_drag(seat, event->drag, event->serial); -	else -		wlr_data_source_destroy(event->drag->source); -} - -void  resize(Client *c, int x, int y, int w, int h, int interact)  {  	int min_width = 0, min_height = 0; @@ -1706,6 +1569,18 @@ resize(Client *c, int x, int y, int w, int h, int interact)  }  void +requeststartdrag(struct wl_listener *listener, void *data) +{ +	struct wlr_seat_request_start_drag_event *event = data; + +	if (wlr_seat_validate_pointer_grab_serial(seat, event->origin, +			event->serial)) +		wlr_seat_start_pointer_drag(seat, event->drag, event->serial); +	else +		wlr_data_source_destroy(event->drag->source); +} + +void  run(char *startup_cmd)  {  	pid_t startup_pid = -1; @@ -1903,7 +1778,11 @@ setup(void)  	dpy = wl_display_create();  	/* Set up signal handlers */ +#ifdef XWAYLAND  	sigchld(0); +#else +	signal(SIGCHLD, SIG_IGN); +#endif  	signal(SIGINT, quitsignal);  	signal(SIGTERM, quitsignal); @@ -1951,6 +1830,7 @@ setup(void)  	wlr_gamma_control_manager_v1_create(dpy);  	wlr_primary_selection_v1_device_manager_create(dpy);  	wlr_viewporter_create(dpy); +	wlr_subcompositor_create(dpy);  	/* Initializes the interface used to implement urgency hints */  	activation = wlr_xdg_activation_v1_create(dpy); @@ -2068,20 +1948,6 @@ setup(void)  }  void -sigchld(int unused) -{ -	/* We should be able to remove this function in favor of a simple -	 *     signal(SIGCHLD, SIG_IGN); -	 * but the Xwayland implementation in wlroots currently prevents us from -	 * setting our own disposition for SIGCHLD. -	 */ -	if (signal(SIGCHLD, sigchld) == SIG_ERR) -		die("can't install SIGCHLD handler:"); -	while (0 < waitpid(-1, NULL, WNOHANG)) -		; -} - -void  spawn(const Arg *arg)  {  	if (fork() == 0) { @@ -2260,7 +2126,7 @@ updatemons(struct wl_listener *listener, void *data)  	struct wlr_output_configuration_v1 *config =  		wlr_output_configuration_v1_create();  	Monitor *m; -	sgeom = *wlr_output_layout_get_box(output_layout, NULL); +	wlr_output_layout_get_box(output_layout, NULL, &sgeom);  	wl_list_for_each(m, &mons, link) {  		struct wlr_output_configuration_head_v1 *config_head =  			wlr_output_configuration_head_v1_create(config, m->wlr_output); @@ -2269,7 +2135,8 @@ updatemons(struct wl_listener *listener, void *data)  		/* TODO: move focus if selmon is disabled */  		/* Get the effective monitor geometry to use for surfaces */ -		m->m = m->w = *wlr_output_layout_get_box(output_layout, m->wlr_output); +		wlr_output_layout_get_box(output_layout, m->wlr_output, &(m->m)); +		wlr_output_layout_get_box(output_layout, m->wlr_output, &(m->w));  		wlr_scene_output_set_position(m->scene_output, m->m.x, m->m.y);  		/* Calculate the effective monitor geometry to use for clients */  		arrangelayers(m); @@ -2325,8 +2192,8 @@ void  virtualkeyboard(struct wl_listener *listener, void *data)  {  	struct wlr_virtual_keyboard_v1 *keyboard = data; -	struct wlr_input_device *device = &keyboard->input_device; -	createkeyboard(device); +	struct wlr_input_device *device = &keyboard->keyboard.base; +	createkeyboard(device->keyboard);  }  Monitor * @@ -2463,6 +2330,25 @@ getatom(xcb_connection_t *xc, const char *name)  }  void +sigchld(int unused) +{ +	siginfo_t in; +	/* We should be able to remove this function in favor of a simple +	 *     signal(SIGCHLD, SIG_IGN); +	 * but the Xwayland implementation in wlroots currently prevents us from +	 * setting our own disposition for SIGCHLD. +	 */ +	if (signal(SIGCHLD, sigchld) == SIG_ERR) +		EBARF("can't install SIGCHLD handler"); +	/* WNOWAIT leaves the child in a waitable state, in case this is the +	 * XWayland process +	 */ +	while (!waitid(P_ALL, 0, &in, WEXITED|WNOHANG|WNOWAIT) && in.si_pid +			&& in.si_pid != xwayland->server->pid) +		waitpid(in.si_pid, NULL, 0); +} + +void  xwaylandready(struct wl_listener *listener, void *data)  {  	struct wlr_xcursor *xcursor; | 
