~ruther/dwl

22336612ae75954c68a7d4cd3f30fbebf94f441f — Leonardo Hernández Hernández 2 years ago 38bd003
improve type safety of toplevel_from_wlr_surface()
2 files changed, 56 insertions(+), 40 deletions(-)

M client.h
M dwl.c
M client.h => client.h +32 -15
@@ 51,29 51,38 @@ client_surface(Client *c)
	return c->surface.xdg->surface;
}

static inline void *
toplevel_from_wlr_surface(struct wlr_surface *s)
static inline int
toplevel_from_wlr_surface(struct wlr_surface *s, Client **pc, LayerSurface **pl)
{
	struct wlr_xdg_surface *xdg_surface;
	struct wlr_surface *root_surface;
	struct wlr_layer_surface_v1 *layer_surface;
	Client *c = NULL;
	LayerSurface *l = NULL;
	int type = -1;
#ifdef XWAYLAND
	struct wlr_xwayland_surface *xsurface;
#endif

	if (!s)
		return NULL;
		return type;
	root_surface = wlr_surface_get_root_surface(s);

#ifdef XWAYLAND
	if (wlr_surface_is_xwayland_surface(root_surface)
			&& (xsurface = wlr_xwayland_surface_from_wlr_surface(root_surface)))
		return xsurface->data;
			&& (xsurface = wlr_xwayland_surface_from_wlr_surface(root_surface))) {
		c = xsurface->data;
		type = c->type;
		goto end;
	}
#endif

	if (wlr_surface_is_layer_surface(root_surface)
			&& (layer_surface = wlr_layer_surface_v1_from_wlr_surface(root_surface)))
		return layer_surface->data;
			&& (layer_surface = wlr_layer_surface_v1_from_wlr_surface(root_surface))) {
		l = layer_surface->data;
		type = LayerShell;
		goto end;
	}

	if (wlr_surface_is_xdg_surface(root_surface)
			&& (xdg_surface = wlr_xdg_surface_from_wlr_surface(root_surface))) {


@@ 81,21 90,28 @@ toplevel_from_wlr_surface(struct wlr_surface *s)
			switch (xdg_surface->role) {
			case WLR_XDG_SURFACE_ROLE_POPUP:
				if (!xdg_surface->popup->parent)
					return NULL;
					return -1;
				else if (!wlr_surface_is_xdg_surface(xdg_surface->popup->parent))
					return toplevel_from_wlr_surface(xdg_surface->popup->parent);
					return toplevel_from_wlr_surface(xdg_surface->popup->parent, pc, pl);

				xdg_surface = wlr_xdg_surface_from_wlr_surface(xdg_surface->popup->parent);
				break;
			case WLR_XDG_SURFACE_ROLE_TOPLEVEL:
					return xdg_surface->data;
				c = xdg_surface->data;
				type = c->type;
				goto end;
			case WLR_XDG_SURFACE_ROLE_NONE:
				return NULL;
				return -1;
			}
		}
	}

	return NULL;
end:
	if (pl)
		*pl = l;
	if (pc)
		*pc = c;
	return type;
}

/* The others */


@@ 169,14 185,15 @@ client_get_geometry(Client *c, struct wlr_box *geom)
static inline Client *
client_get_parent(Client *c)
{
	Client *p = NULL;
#ifdef XWAYLAND
	if (client_is_x11(c) && c->surface.xwayland->parent)
		return toplevel_from_wlr_surface(c->surface.xwayland->parent->surface);
		toplevel_from_wlr_surface(c->surface.xwayland->parent->surface, &p, NULL);
#endif
	if (c->surface.xdg->toplevel->parent)
		return toplevel_from_wlr_surface(c->surface.xdg->toplevel->parent->base->surface);
		toplevel_from_wlr_surface(c->surface.xdg->toplevel->parent->base->surface, &p, NULL);

	return NULL;
	return p;
}

static inline const char *

M dwl.c => dwl.c +24 -25
@@ 904,22 904,21 @@ createnotify(struct wl_listener *listener, void *data)
	 * If you want to do something tricky with popups you should check if
	 * its parent is wlr_xdg_shell or wlr_layer_shell */
	struct wlr_xdg_surface *xdg_surface = data;
	Client *c;
	Client *c = NULL;
	LayerSurface *l = NULL;

	if (xdg_surface->role == WLR_XDG_SURFACE_ROLE_POPUP) {
		struct wlr_box box;
		LayerSurface *l = toplevel_from_wlr_surface(xdg_surface->surface);
		int type = toplevel_from_wlr_surface(xdg_surface->surface, &c, &l);
		if (!xdg_surface->popup->parent)
			return;
		xdg_surface->surface->data = wlr_scene_xdg_surface_create(
				xdg_surface->popup->parent->data, xdg_surface);
		/* Probably the check of `l` is useless, the only thing that can be NULL
		 * is its monitor */
		if (!l || !l->mon)
		if ((!l || !l->mon) || (!c || !c->mon))
			return;
		box = l->type == LayerShell ? l->mon->m : l->mon->w;
		box.x -= l->geom.x;
		box.y -= l->geom.y;
		box = type == LayerShell ? l->mon->m : c->mon->w;
		box.x -= (type == LayerShell ? l->geom.x : c->geom.x);
		box.y -= (type == LayerShell ? l->geom.y : c->geom.y);
		wlr_xdg_popup_unconstrain_from_box(xdg_surface->popup, &box);
		return;
	} else if (xdg_surface->role == WLR_XDG_SURFACE_ROLE_NONE)


@@ 1096,15 1095,12 @@ focusclient(Client *c, int lift)
		/* If an overlay is focused, don't focus or activate the client,
		 * but only update its position in fstack to render its border with focuscolor
		 * and focus it after the overlay is closed. */
		Client *w = toplevel_from_wlr_surface(old);
		if (wlr_surface_is_layer_surface(old)) {
			struct wlr_layer_surface_v1 *wlr_layer_surface =
				wlr_layer_surface_v1_from_wlr_surface(old);

			if (wlr_layer_surface && ((LayerSurface *)wlr_layer_surface->data)->mapped
					&& (wlr_layer_surface->current.layer == ZWLR_LAYER_SHELL_V1_LAYER_TOP
					|| wlr_layer_surface->current.layer == ZWLR_LAYER_SHELL_V1_LAYER_OVERLAY))
				return;
		Client *w = NULL;
		LayerSurface *l = NULL;
		int type = toplevel_from_wlr_surface(old, &w, &l);
		if (type == LayerShell && l->scene->node.enabled
				&& l->layer_surface->current.layer >= ZWLR_LAYER_SHELL_V1_LAYER_TOP) {
			return;
		} else if (w && w == exclusive_focus && client_wants_focus(w)) {
			return;
		/* Don't deactivate old client if the new one wants focus, as this causes issues with winecfg


@@ 1438,8 1434,9 @@ void
motionnotify(uint32_t time)
{
	double sx = 0, sy = 0;
	Client *c = NULL;
	LayerSurface *l;
	Client *c = NULL, *w = NULL;
	LayerSurface *l = NULL;
	int type;
	struct wlr_surface *surface = NULL;
	struct wlr_drag_icon *icon;



@@ 1472,11 1469,12 @@ motionnotify(uint32_t time)
	xytonode(cursor->x, cursor->y, &surface, &c, NULL, &sx, &sy);

	if (cursor_mode == CurPressed && !seat->drag) {
		if ((l = toplevel_from_wlr_surface(
				 seat->pointer_state.focused_surface))) {
		if ((type = toplevel_from_wlr_surface(
				 seat->pointer_state.focused_surface, &w, &l)) >= 0) {
			c = w;
			surface = seat->pointer_state.focused_surface;
			sx = cursor->x - l->geom.x;
			sy = cursor->y - l->geom.y;
			sx = cursor->x - (type == LayerShell ? l->geom.x : w->geom.x);
			sy = cursor->y - (type == LayerShell ? l->geom.y : w->geom.y);
		}
	}



@@ 2357,8 2355,9 @@ void
urgent(struct wl_listener *listener, void *data)
{
	struct wlr_xdg_activation_v1_request_activate_event *event = data;
	Client *c = toplevel_from_wlr_surface(event->surface);
	if (c && c->type != LayerShell && c != selclient()) {
	Client *c = NULL;
	int type = toplevel_from_wlr_surface(event->surface, &c, NULL);
	if (type >= 0 && type != LayerShell && c != selclient()) {
		c->isurgent = 1;
		printstatus();
	}

Do not follow this link