aboutsummaryrefslogtreecommitdiff
path: root/src/cmd/wm/layer.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/cmd/wm/layer.c')
-rw-r--r--src/cmd/wm/layer.c107
1 files changed, 107 insertions, 0 deletions
diff --git a/src/cmd/wm/layer.c b/src/cmd/wm/layer.c
new file mode 100644
index 0000000..bfac744
--- /dev/null
+++ b/src/cmd/wm/layer.c
@@ -0,0 +1,107 @@
+#include "wm.h"
+
+static
+void
+map(struct wl_listener *l, void *data)
+{
+ Layer *layer = wl_container_of(l, layer, event.map);
+ wlr_surface_send_enter(layer->surface->surface, layer->surface->output);
+ notify_move(0);
+}
+
+static
+void
+finalize(Layer *layer)
+{
+ layer->surface->mapped = 0;
+ if (layer->surface->surface == server.input.seat->keyboard_state.focused_surface)
+ focus(selected_client(), 1);
+ notify_move(0);
+}
+
+static
+void
+unmap(struct wl_listener *l, void *data)
+{
+ Layer *layer = wl_container_of(l, layer, event.unmap);
+ finalize(layer);
+}
+
+static
+void
+destroy(struct wl_listener *l, void *data)
+{
+ Monitor *monitor;
+ Layer *layer = wl_container_of(l, layer, event.destroy);
+
+ if (layer->surface->mapped)
+ finalize(layer);
+
+ wl_list_remove(&layer->link);
+ wl_list_remove(&layer->event.destroy.link);
+ wl_list_remove(&layer->event.map.link);
+ wl_list_remove(&layer->event.unmap.link);
+ wl_list_remove(&layer->event.commit.link);
+
+ if(layer->surface->output) {
+ monitor = layer->surface->output->data;
+ if(monitor)
+ stratify(monitor);
+ layer->surface->output = nil;
+ }
+ free(layer);
+}
+
+static
+void
+commit(struct wl_listener *l, void *data)
+{
+ Monitor *monitor;
+ Layer *layer = wl_container_of(l, layer, event.commit);
+ struct wlr_layer_surface_v1 *surface = layer->surface;
+ struct wlr_output *output = surface->output;
+
+ if(!output)
+ return;
+
+ monitor = output->data;
+ stratify(monitor);
+
+ if (layer->type != surface->current.layer) {
+ wl_list_remove(&layer->link);
+ wl_list_insert(&monitor->layer[surface->current.layer], &layer->link);
+ layer->type = surface->current.layer;
+ }
+}
+
+void
+make_layer_surface(struct wl_listener *l, void *data)
+{
+ Layer *layer;
+ Monitor *monitor;
+ struct wlr_layer_surface_v1_state state;
+ struct wlr_layer_surface_v1 *surface = data;
+
+ if(!surface->output)
+ surface->output = server.monitor.selected->output;
+
+ layer = surface->data = calloc(1, sizeof(*layer));
+ layer->surface = surface;
+
+ layer->event.map.notify = map;
+ wl_signal_add(&surface->events.map, &layer->event.map);
+ layer->event.unmap.notify = unmap;
+ wl_signal_add(&surface->events.unmap, &layer->event.unmap);
+ layer->event.destroy.notify = destroy;
+ wl_signal_add(&surface->events.destroy, &layer->event.destroy);
+ layer->event.commit.notify = commit;
+ wl_signal_add(&surface->surface->events.commit, &layer->event.commit);
+
+ monitor = surface->output->data;
+ wl_list_insert(&monitor->layer[surface->client_pending.layer], &layer->link);
+
+ state = surface->current;
+ surface->current = surface->client_pending;
+ stratify(monitor);
+ surface->current = state;
+}