aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile2
-rw-r--r--client.h15
-rw-r--r--dwl.c297
3 files changed, 108 insertions, 206 deletions
diff --git a/Makefile b/Makefile
index 0c2b78d..8635093 100644
--- a/Makefile
+++ b/Makefile
@@ -5,7 +5,7 @@ CFLAGS += -I. -DWLR_USE_UNSTABLE -std=c99 -pedantic -DVERSION=\"$(VERSION)\"
WAYLAND_PROTOCOLS=$(shell pkg-config --variable=pkgdatadir wayland-protocols)
WAYLAND_SCANNER=$(shell pkg-config --variable=wayland_scanner wayland-scanner)
-PKGS = wlroots wayland-server xcb xkbcommon libinput
+PKGS = wlroots wayland-server xcb xcb-icccm xkbcommon libinput
CFLAGS += $(foreach p,$(PKGS),$(shell pkg-config --cflags $(p)))
LDLIBS += $(foreach p,$(PKGS),$(shell pkg-config --libs $(p)))
diff --git a/client.h b/client.h
index e0964da..6648c59 100644
--- a/client.h
+++ b/client.h
@@ -42,7 +42,7 @@ client_activate_surface(struct wlr_surface *s, int activated)
if (wlr_surface_is_xdg_surface(s)
&& (surface = wlr_xdg_surface_from_wlr_surface(s))
&& surface->role == WLR_XDG_SURFACE_ROLE_TOPLEVEL)
- wlr_xdg_toplevel_set_activated(surface, activated);
+ wlr_xdg_toplevel_set_activated(surface->toplevel, activated);
}
static inline void
@@ -100,7 +100,7 @@ client_is_float_type(Client *c)
#ifdef XWAYLAND
if (client_is_x11(c)) {
struct wlr_xwayland_surface *surface = c->surface.xwayland;
- struct wlr_xwayland_surface_size_hints *size_hints;
+ xcb_size_hints_t *size_hints;
if (surface->modal)
return 1;
@@ -157,7 +157,7 @@ client_send_close(Client *c)
return;
}
#endif
- wlr_xdg_toplevel_send_close(c->surface.xdg);
+ wlr_xdg_toplevel_send_close(c->surface.xdg->toplevel);
}
static inline void
@@ -169,7 +169,7 @@ client_set_fullscreen(Client *c, int fullscreen)
return;
}
#endif
- wlr_xdg_toplevel_set_fullscreen(c->surface.xdg, fullscreen);
+ wlr_xdg_toplevel_set_fullscreen(c->surface.xdg->toplevel, fullscreen);
}
static inline uint32_t
@@ -182,7 +182,7 @@ client_set_size(Client *c, uint32_t width, uint32_t height)
return 0;
}
#endif
- return wlr_xdg_toplevel_set_size(c->surface.xdg, width, height);
+ return wlr_xdg_toplevel_set_size(c->surface.xdg->toplevel, width, height);
}
static inline void
@@ -192,7 +192,7 @@ client_set_tiled(Client *c, uint32_t edges)
if (client_is_x11(c))
return;
#endif
- wlr_xdg_toplevel_set_tiled(c->surface.xdg, edges);
+ wlr_xdg_toplevel_set_tiled(c->surface.xdg->toplevel, edges);
}
static inline struct wlr_surface *
@@ -213,8 +213,7 @@ client_min_size(Client *c, int *width, int *height)
struct wlr_xdg_toplevel_state *state;
#ifdef XWAYLAND
if (client_is_x11(c)) {
- struct wlr_xwayland_surface_size_hints *size_hints;
- size_hints = c->surface.xwayland->size_hints;
+ xcb_size_hints_t *size_hints = c->surface.xwayland->size_hints;
if (size_hints) {
*width = size_hints->min_width;
*height = size_hints->min_height;
diff --git a/dwl.c b/dwl.c
index 90a2789..84e5f2e 100644
--- a/dwl.c
+++ b/dwl.c
@@ -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>
@@ -49,8 +50,9 @@
#include <wlr/util/log.h>
#include <xkbcommon/xkbcommon.h>
#ifdef XWAYLAND
-#include <X11/Xlib.h>
#include <wlr/xwayland.h>
+#include <X11/Xlib.h>
+#include <xcb/xcb_icccm.h>
#endif
#include "util.h"
@@ -103,6 +105,7 @@ typedef struct {
} surface;
struct wl_listener commit;
struct wl_listener map;
+ struct wl_listener maximize;
struct wl_listener unmap;
struct wl_listener destroy;
struct wl_listener set_title;
@@ -122,14 +125,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 *);
@@ -138,7 +133,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;
@@ -150,6 +145,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;
@@ -157,8 +153,6 @@ typedef struct {
struct wl_listener map;
struct wl_listener unmap;
struct wl_listener surface_commit;
-
- struct wlr_box geo;
} LayerSurface;
typedef struct {
@@ -203,9 +197,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,
@@ -221,11 +212,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);
@@ -245,6 +236,7 @@ static void keypressmod(struct wl_listener *listener, void *data);
static void killclient(const Arg *arg);
static void maplayersurfacenotify(struct wl_listener *listener, void *data);
static void mapnotify(struct wl_listener *listener, void *data);
+static void maximizenotify(struct wl_listener *listener, void *data);
static void monocle(Monitor *m);
static void motionabsolute(struct wl_listener *listener, void *data);
static void motionnotify(uint32_t time);
@@ -272,7 +264,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);
@@ -360,6 +351,7 @@ 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 sethints(struct wl_listener *listener, void *data);
+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};
@@ -395,61 +387,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 */
@@ -500,72 +437,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);
}
}
@@ -618,7 +494,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,
@@ -629,7 +505,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;
@@ -700,7 +576,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);
@@ -796,29 +672,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);
@@ -851,9 +727,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],
@@ -971,15 +849,17 @@ createnotify(struct wl_listener *listener, void *data)
LISTEN(&xdg_surface->toplevel->events.set_title, &c->set_title, updatetitle);
LISTEN(&xdg_surface->toplevel->events.request_fullscreen, &c->fullscreen,
fullscreennotify);
+ LISTEN(&xdg_surface->toplevel->events.request_maximize, &c->maximize,
+ maximizenotify);
c->isfullscreen = 0;
}
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);
@@ -992,7 +872,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
@@ -1238,10 +1118,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 */
@@ -1284,17 +1164,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);
@@ -1307,7 +1187,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);
}
@@ -1325,10 +1205,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
@@ -1399,6 +1279,18 @@ mapnotify(struct wl_listener *listener, void *data)
}
void
+maximizenotify(struct wl_listener *listener, void *data)
+{
+ /* This event is raised when a client would like to maximize itself,
+ * typically because the user clicked on the maximize button on
+ * client-side decorations. dwl doesn't support maximization, but
+ * to conform to xdg-shell protocol we still must send a configure.
+ * wlr_xdg_surface_schedule_configure() is used to send an empty reply. */
+ Client *c = wl_container_of(listener, c, maximize);
+ wlr_xdg_surface_schedule_configure(c->surface.xdg);
+}
+
+void
monocle(Monitor *m)
{
Client *c;
@@ -1420,8 +1312,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);
}
@@ -1475,13 +1367,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);
}
@@ -1686,18 +1578,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;
@@ -1726,6 +1606,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;
@@ -1923,7 +1815,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);
@@ -1971,6 +1867,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);
@@ -2004,7 +1901,7 @@ setup(void)
layer_shell = wlr_layer_shell_v1_create(dpy);
wl_signal_add(&layer_shell->events.new_surface, &new_layer_shell_surface);
- xdg_shell = wlr_xdg_shell_create(dpy);
+ xdg_shell = wlr_xdg_shell_create(dpy, 2);
wl_signal_add(&xdg_shell->events.new_surface, &new_xdg_surface);
input_inhibit_mgr = wlr_input_inhibit_manager_create(dpy);
@@ -2088,20 +1985,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) {
@@ -2280,7 +2163,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);
@@ -2289,7 +2172,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);
@@ -2345,8 +2229,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 *
@@ -2488,12 +2372,31 @@ sethints(struct wl_listener *listener, void *data)
{
Client *c = wl_container_of(listener, c, set_hints);
if (c != selclient()) {
- c->isurgent = c->surface.xwayland->hints_urgency;
+ c->isurgent = xcb_icccm_wm_hints_get_urgency(c->surface.xwayland->hints);
printstatus();
}
}
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)
+ die("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;