improve type safety of toplevel_from_wlr_surface()
This commit is contained in:
parent
38bd00351a
commit
22336612ae
2 changed files with 56 additions and 40 deletions
47
client.h
47
client.h
|
@ -51,29 +51,38 @@ client_surface(Client *c)
|
||||||
return c->surface.xdg->surface;
|
return c->surface.xdg->surface;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void *
|
static inline int
|
||||||
toplevel_from_wlr_surface(struct wlr_surface *s)
|
toplevel_from_wlr_surface(struct wlr_surface *s, Client **pc, LayerSurface **pl)
|
||||||
{
|
{
|
||||||
struct wlr_xdg_surface *xdg_surface;
|
struct wlr_xdg_surface *xdg_surface;
|
||||||
struct wlr_surface *root_surface;
|
struct wlr_surface *root_surface;
|
||||||
struct wlr_layer_surface_v1 *layer_surface;
|
struct wlr_layer_surface_v1 *layer_surface;
|
||||||
|
Client *c = NULL;
|
||||||
|
LayerSurface *l = NULL;
|
||||||
|
int type = -1;
|
||||||
#ifdef XWAYLAND
|
#ifdef XWAYLAND
|
||||||
struct wlr_xwayland_surface *xsurface;
|
struct wlr_xwayland_surface *xsurface;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (!s)
|
if (!s)
|
||||||
return NULL;
|
return type;
|
||||||
root_surface = wlr_surface_get_root_surface(s);
|
root_surface = wlr_surface_get_root_surface(s);
|
||||||
|
|
||||||
#ifdef XWAYLAND
|
#ifdef XWAYLAND
|
||||||
if (wlr_surface_is_xwayland_surface(root_surface)
|
if (wlr_surface_is_xwayland_surface(root_surface)
|
||||||
&& (xsurface = wlr_xwayland_surface_from_wlr_surface(root_surface)))
|
&& (xsurface = wlr_xwayland_surface_from_wlr_surface(root_surface))) {
|
||||||
return xsurface->data;
|
c = xsurface->data;
|
||||||
|
type = c->type;
|
||||||
|
goto end;
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (wlr_surface_is_layer_surface(root_surface)
|
if (wlr_surface_is_layer_surface(root_surface)
|
||||||
&& (layer_surface = wlr_layer_surface_v1_from_wlr_surface(root_surface)))
|
&& (layer_surface = wlr_layer_surface_v1_from_wlr_surface(root_surface))) {
|
||||||
return layer_surface->data;
|
l = layer_surface->data;
|
||||||
|
type = LayerShell;
|
||||||
|
goto end;
|
||||||
|
}
|
||||||
|
|
||||||
if (wlr_surface_is_xdg_surface(root_surface)
|
if (wlr_surface_is_xdg_surface(root_surface)
|
||||||
&& (xdg_surface = wlr_xdg_surface_from_wlr_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) {
|
switch (xdg_surface->role) {
|
||||||
case WLR_XDG_SURFACE_ROLE_POPUP:
|
case WLR_XDG_SURFACE_ROLE_POPUP:
|
||||||
if (!xdg_surface->popup->parent)
|
if (!xdg_surface->popup->parent)
|
||||||
return NULL;
|
return -1;
|
||||||
else if (!wlr_surface_is_xdg_surface(xdg_surface->popup->parent))
|
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);
|
xdg_surface = wlr_xdg_surface_from_wlr_surface(xdg_surface->popup->parent);
|
||||||
break;
|
break;
|
||||||
case WLR_XDG_SURFACE_ROLE_TOPLEVEL:
|
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:
|
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 */
|
/* The others */
|
||||||
|
@ -169,14 +185,15 @@ client_get_geometry(Client *c, struct wlr_box *geom)
|
||||||
static inline Client *
|
static inline Client *
|
||||||
client_get_parent(Client *c)
|
client_get_parent(Client *c)
|
||||||
{
|
{
|
||||||
|
Client *p = NULL;
|
||||||
#ifdef XWAYLAND
|
#ifdef XWAYLAND
|
||||||
if (client_is_x11(c) && c->surface.xwayland->parent)
|
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
|
#endif
|
||||||
if (c->surface.xdg->toplevel->parent)
|
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 *
|
static inline const char *
|
||||||
|
|
49
dwl.c
49
dwl.c
|
@ -904,22 +904,21 @@ createnotify(struct wl_listener *listener, void *data)
|
||||||
* If you want to do something tricky with popups you should check if
|
* If you want to do something tricky with popups you should check if
|
||||||
* its parent is wlr_xdg_shell or wlr_layer_shell */
|
* its parent is wlr_xdg_shell or wlr_layer_shell */
|
||||||
struct wlr_xdg_surface *xdg_surface = data;
|
struct wlr_xdg_surface *xdg_surface = data;
|
||||||
Client *c;
|
Client *c = NULL;
|
||||||
|
LayerSurface *l = NULL;
|
||||||
|
|
||||||
if (xdg_surface->role == WLR_XDG_SURFACE_ROLE_POPUP) {
|
if (xdg_surface->role == WLR_XDG_SURFACE_ROLE_POPUP) {
|
||||||
struct wlr_box box;
|
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)
|
if (!xdg_surface->popup->parent)
|
||||||
return;
|
return;
|
||||||
xdg_surface->surface->data = wlr_scene_xdg_surface_create(
|
xdg_surface->surface->data = wlr_scene_xdg_surface_create(
|
||||||
xdg_surface->popup->parent->data, xdg_surface);
|
xdg_surface->popup->parent->data, xdg_surface);
|
||||||
/* Probably the check of `l` is useless, the only thing that can be NULL
|
if ((!l || !l->mon) || (!c || !c->mon))
|
||||||
* is its monitor */
|
|
||||||
if (!l || !l->mon)
|
|
||||||
return;
|
return;
|
||||||
box = l->type == LayerShell ? l->mon->m : l->mon->w;
|
box = type == LayerShell ? l->mon->m : c->mon->w;
|
||||||
box.x -= l->geom.x;
|
box.x -= (type == LayerShell ? l->geom.x : c->geom.x);
|
||||||
box.y -= l->geom.y;
|
box.y -= (type == LayerShell ? l->geom.y : c->geom.y);
|
||||||
wlr_xdg_popup_unconstrain_from_box(xdg_surface->popup, &box);
|
wlr_xdg_popup_unconstrain_from_box(xdg_surface->popup, &box);
|
||||||
return;
|
return;
|
||||||
} else if (xdg_surface->role == WLR_XDG_SURFACE_ROLE_NONE)
|
} 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,
|
/* 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
|
* but only update its position in fstack to render its border with focuscolor
|
||||||
* and focus it after the overlay is closed. */
|
* and focus it after the overlay is closed. */
|
||||||
Client *w = toplevel_from_wlr_surface(old);
|
Client *w = NULL;
|
||||||
if (wlr_surface_is_layer_surface(old)) {
|
LayerSurface *l = NULL;
|
||||||
struct wlr_layer_surface_v1 *wlr_layer_surface =
|
int type = toplevel_from_wlr_surface(old, &w, &l);
|
||||||
wlr_layer_surface_v1_from_wlr_surface(old);
|
if (type == LayerShell && l->scene->node.enabled
|
||||||
|
&& l->layer_surface->current.layer >= ZWLR_LAYER_SHELL_V1_LAYER_TOP) {
|
||||||
if (wlr_layer_surface && ((LayerSurface *)wlr_layer_surface->data)->mapped
|
return;
|
||||||
&& (wlr_layer_surface->current.layer == ZWLR_LAYER_SHELL_V1_LAYER_TOP
|
|
||||||
|| wlr_layer_surface->current.layer == ZWLR_LAYER_SHELL_V1_LAYER_OVERLAY))
|
|
||||||
return;
|
|
||||||
} else if (w && w == exclusive_focus && client_wants_focus(w)) {
|
} else if (w && w == exclusive_focus && client_wants_focus(w)) {
|
||||||
return;
|
return;
|
||||||
/* Don't deactivate old client if the new one wants focus, as this causes issues with winecfg
|
/* 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)
|
motionnotify(uint32_t time)
|
||||||
{
|
{
|
||||||
double sx = 0, sy = 0;
|
double sx = 0, sy = 0;
|
||||||
Client *c = NULL;
|
Client *c = NULL, *w = NULL;
|
||||||
LayerSurface *l;
|
LayerSurface *l = NULL;
|
||||||
|
int type;
|
||||||
struct wlr_surface *surface = NULL;
|
struct wlr_surface *surface = NULL;
|
||||||
struct wlr_drag_icon *icon;
|
struct wlr_drag_icon *icon;
|
||||||
|
|
||||||
|
@ -1472,11 +1469,12 @@ motionnotify(uint32_t time)
|
||||||
xytonode(cursor->x, cursor->y, &surface, &c, NULL, &sx, &sy);
|
xytonode(cursor->x, cursor->y, &surface, &c, NULL, &sx, &sy);
|
||||||
|
|
||||||
if (cursor_mode == CurPressed && !seat->drag) {
|
if (cursor_mode == CurPressed && !seat->drag) {
|
||||||
if ((l = toplevel_from_wlr_surface(
|
if ((type = toplevel_from_wlr_surface(
|
||||||
seat->pointer_state.focused_surface))) {
|
seat->pointer_state.focused_surface, &w, &l)) >= 0) {
|
||||||
|
c = w;
|
||||||
surface = seat->pointer_state.focused_surface;
|
surface = seat->pointer_state.focused_surface;
|
||||||
sx = cursor->x - l->geom.x;
|
sx = cursor->x - (type == LayerShell ? l->geom.x : w->geom.x);
|
||||||
sy = cursor->y - l->geom.y;
|
sy = cursor->y - (type == LayerShell ? l->geom.y : w->geom.y);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2357,8 +2355,9 @@ void
|
||||||
urgent(struct wl_listener *listener, void *data)
|
urgent(struct wl_listener *listener, void *data)
|
||||||
{
|
{
|
||||||
struct wlr_xdg_activation_v1_request_activate_event *event = data;
|
struct wlr_xdg_activation_v1_request_activate_event *event = data;
|
||||||
Client *c = toplevel_from_wlr_surface(event->surface);
|
Client *c = NULL;
|
||||||
if (c && c->type != LayerShell && c != selclient()) {
|
int type = toplevel_from_wlr_surface(event->surface, &c, NULL);
|
||||||
|
if (type >= 0 && type != LayerShell && c != selclient()) {
|
||||||
c->isurgent = 1;
|
c->isurgent = 1;
|
||||||
printstatus();
|
printstatus();
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue