diff --git a/dwl.c b/dwl.c index 7b13087..aa3f1b9 100644 --- a/dwl.c +++ b/dwl.c @@ -251,6 +251,7 @@ static void createlocksurface(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_pointer *pointer); +static void createpopup(struct wl_listener *listener, void *data); static void cursorframe(struct wl_listener *listener, void *data); static void destroydragicon(struct wl_listener *listener, void *data); static void destroyidleinhibitor(struct wl_listener *listener, void *data); @@ -739,6 +740,9 @@ commitnotify(struct wl_listener *listener, void *data) { Client *c = wl_container_of(listener, c, commit); + if (c->surface.xdg->initial_commit) + wlr_xdg_toplevel_set_wm_capabilities(c->surface.xdg->toplevel, WLR_XDG_TOPLEVEL_WM_CAPABILITIES_FULLSCREEN); + if (client_surface(c)->mapped) resize(c, c->geom, (c->isfloating && !c->isfullscreen)); @@ -926,49 +930,22 @@ createmon(struct wl_listener *listener, void *data) void createnotify(struct wl_listener *listener, void *data) { - /* This event is raised when wlr_xdg_shell receives a new xdg surface from a - * client, either a toplevel (application window) or popup, - * or when wlr_layer_shell receives a new popup from a layer. - * 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; + /* This event is raised when a client creates a new toplevel (application window). */ + struct wlr_xdg_toplevel *toplevel = data; Client *c = NULL; - LayerSurface *l = NULL; - - if (xdg_surface->role == WLR_XDG_SURFACE_ROLE_POPUP) { - struct wlr_box box; - int type = toplevel_from_wlr_surface(xdg_surface->surface, &c, &l); - if (!xdg_surface->popup->parent || type < 0) - return; - xdg_surface->surface->data = wlr_scene_xdg_surface_create( - xdg_surface->popup->parent->data, xdg_surface); - if ((l && !l->mon) || (c && !c->mon)) - return; - 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) - return; /* Allocate a Client for this surface */ - c = xdg_surface->data = ecalloc(1, sizeof(*c)); - c->surface.xdg = xdg_surface; + c = toplevel->base->data = ecalloc(1, sizeof(*c)); + c->surface.xdg = toplevel->base; c->bw = borderpx; - wlr_xdg_toplevel_set_wm_capabilities(xdg_surface->toplevel, - WLR_XDG_TOPLEVEL_WM_CAPABILITIES_FULLSCREEN); - - LISTEN(&xdg_surface->surface->events.commit, &c->commit, commitnotify); - LISTEN(&xdg_surface->surface->events.map, &c->map, mapnotify); - LISTEN(&xdg_surface->surface->events.unmap, &c->unmap, unmapnotify); - LISTEN(&xdg_surface->events.destroy, &c->destroy, destroynotify); - 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); + LISTEN(&toplevel->base->surface->events.commit, &c->commit, commitnotify); + LISTEN(&toplevel->base->surface->events.map, &c->map, mapnotify); + LISTEN(&toplevel->base->surface->events.unmap, &c->unmap, unmapnotify); + LISTEN(&toplevel->events.destroy, &c->destroy, destroynotify); + LISTEN(&toplevel->events.request_fullscreen, &c->fullscreen, fullscreennotify); + LISTEN(&toplevel->events.request_maximize, &c->maximize, maximizenotify); + LISTEN(&toplevel->events.set_title, &c->set_title, updatetitle); } void @@ -1015,6 +992,30 @@ createpointer(struct wlr_pointer *pointer) wlr_cursor_attach_input_device(cursor, &pointer->base); } +void +createpopup(struct wl_listener *listener, void *data) +{ + /* This event is raised when a client (either xdg-shell or layer-shell) + * creates a new popup. */ + struct wlr_xdg_popup *popup = data; + LayerSurface *l = NULL; + Client *c = NULL; + struct wlr_box box; + + int type = toplevel_from_wlr_surface(popup->base->surface, &c, &l); + if (!popup->parent || type < 0) + return; + popup->base->surface->data = wlr_scene_xdg_surface_create( + popup->parent->data, popup->base); + if ((l && !l->mon) || (c && !c->mon)) + return; + 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); + /* FIXME: this send a configure event to a uninitialized wlr_xdg_surface */ + wlr_xdg_popup_unconstrain_from_box(popup, &box); +} + void cursorframe(struct wl_listener *listener, void *data) { @@ -2249,7 +2250,8 @@ setup(void) wl_list_init(&fstack); xdg_shell = wlr_xdg_shell_create(dpy, 6); - LISTEN_STATIC(&xdg_shell->events.new_surface, createnotify); + LISTEN_STATIC(&xdg_shell->events.new_toplevel, createnotify); + LISTEN_STATIC(&xdg_shell->events.new_popup, createpopup); layer_shell = wlr_layer_shell_v1_create(dpy, 3); LISTEN_STATIC(&layer_shell->events.new_surface, createlayersurface);