summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--dwl.c105
1 files changed, 53 insertions, 52 deletions
diff --git a/dwl.c b/dwl.c
index 10d5a5b..ec2b1c1 100644
--- a/dwl.c
+++ b/dwl.c
@@ -253,6 +253,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 destroydecoration(struct wl_listener *listener, void *data);
static void destroydragicon(struct wl_listener *listener, void *data);
@@ -640,7 +641,6 @@ cleanup(void)
waitpid(child_pid, NULL, 0);
}
wlr_xcursor_manager_destroy(cursor_mgr);
- wlr_output_layout_destroy(output_layout);
/* Remove event source that use the dpy event loop before destroying dpy */
wl_event_source_remove(kb_group.key_repeat_source);
@@ -710,6 +710,17 @@ commitlayersurfacenotify(struct wl_listener *listener, void *data)
LayerSurface *l = wl_container_of(listener, l, surface_commit);
struct wlr_layer_surface_v1 *layer_surface = l->layer_surface;
struct wlr_scene_tree *scene_layer = layers[layermap[layer_surface->current.layer]];
+ struct wlr_layer_surface_v1_state old_state;
+
+ if (l->layer_surface->initial_commit) {
+ /* Temporarily set the layer's current state to pending
+ * so that we can easily arrange it */
+ old_state = l->layer_surface->current;
+ l->layer_surface->current = l->layer_surface->pending;
+ arrangelayers(l->mon);
+ l->layer_surface->current = old_state;
+ return;
+ }
if (layer_surface->current.committed == 0 && l->mapped == layer_surface->surface->mapped)
return;
@@ -731,6 +742,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));
@@ -779,7 +793,6 @@ createlayersurface(struct wl_listener *listener, void *data)
LayerSurface *l;
struct wlr_surface *surface = layer_surface->surface;
struct wlr_scene_tree *scene_layer = layers[layermap[layer_surface->pending.layer]];
- struct wlr_layer_surface_v1_state old_state;
if (!layer_surface->output
&& !(layer_surface->output = selmon ? selmon->wlr_output : NULL)) {
@@ -804,15 +817,6 @@ createlayersurface(struct wl_listener *listener, void *data)
wl_list_insert(&l->mon->layers[layer_surface->pending.layer],&l->link);
wlr_surface_send_enter(surface, layer_surface->output);
-
- /* Temporarily set the layer's current state to pending
- * so that we can easily arrange it
- */
- old_state = layer_surface->current;
- layer_surface->current = layer_surface->pending;
- l->mapped = 1;
- arrangelayers(l->mon);
- layer_surface->current = old_state;
}
void
@@ -917,49 +921,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_xdg_popup *popup = xdg_surface->popup;
- struct wlr_box box;
- if (toplevel_from_wlr_surface(popup->base->surface, &c, &l) < 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 = l ? l->mon->m : c->mon->w;
- box.x -= (l ? l->geom.x : c->geom.x);
- box.y -= (l ? l->geom.y : c->geom.y);
- wlr_xdg_popup_unconstrain_from_box(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->events.destroy, &c->destroy, destroynotify);
- 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->toplevel->events.request_fullscreen, &c->fullscreen,
- fullscreennotify);
- LISTEN(&xdg_surface->toplevel->events.request_maximize, &c->maximize,
- maximizenotify);
- LISTEN(&xdg_surface->toplevel->events.set_title, &c->set_title, updatetitle);
+ 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
@@ -1007,6 +984,30 @@ createpointer(struct wlr_pointer *pointer)
}
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)
{
/* This event is forwarded by the cursor when a pointer emits an frame
@@ -1481,7 +1482,6 @@ locksession(struct wl_listener *listener, void *data)
void
maplayersurfacenotify(struct wl_listener *listener, void *data)
{
- LayerSurface *l = wl_container_of(listener, l, map);
motionnotify(0);
}
@@ -2241,7 +2241,7 @@ setup(void)
/* Creates an output layout, which a wlroots utility for working with an
* arrangement of screens in a physical layout. */
- output_layout = wlr_output_layout_create();
+ output_layout = wlr_output_layout_create(dpy);
LISTEN_STATIC(&output_layout->events.change, updatemons);
wlr_xdg_output_manager_v1_create(dpy, output_layout);
@@ -2260,7 +2260,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);