aboutsummaryrefslogtreecommitdiff
path: root/sys/cmd/wm/monitor.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/cmd/wm/monitor.c')
-rw-r--r--sys/cmd/wm/monitor.c386
1 files changed, 0 insertions, 386 deletions
diff --git a/sys/cmd/wm/monitor.c b/sys/cmd/wm/monitor.c
deleted file mode 100644
index 93073f3..0000000
--- a/sys/cmd/wm/monitor.c
+++ /dev/null
@@ -1,386 +0,0 @@
-#include "wm.h"
-
-/* callbacks */
-void
-monitor_change(struct wl_listener *l, void *data)
-{
- Monitor *monitor;
- struct wlr_output_configuration_v1 *config;
-
- config = wlr_output_configuration_v1_create();
- server.monitor.geometry = *wlr_output_layout_get_box(server.monitor.layout, nil);
-
- wl_list_for_each(monitor, &server.monitor.list, link) {
- struct wlr_output_configuration_head_v1 *head =
- wlr_output_configuration_head_v1_create(config, monitor->output);
-
- monitor->geometry = monitor->window = *wlr_output_layout_get_box(server.monitor.layout, monitor->output);
-
- stratify(monitor);
- arrange(monitor);
-
- head->state.enabled = monitor->output->enabled;
- head->state.mode = monitor->output->current_mode;
- head->state.x = monitor->geometry.x;
- head->state.y = monitor->geometry.y;
- }
-
- wlr_output_manager_v1_set_configuration(server.monitor.manager, config);
-}
-
-static
-void
-trylayout(struct wlr_output_configuration_v1 *config, int force)
-{
- int ok;
- struct wlr_output_configuration_head_v1 *head;
-
- ok = 1;
- wl_list_for_each(head, &config->heads, link) {
- struct wlr_output *output= head->state.output;
- wlr_output_enable(output, head->state.enabled);
- if (head->state.enabled) {
- if (head->state.mode)
- wlr_output_set_mode(output, head->state.mode);
- else
- wlr_output_set_custom_mode(
- output,
- head->state.custom_mode.width,
- head->state.custom_mode.height,
- head->state.custom_mode.refresh
- );
-
- wlr_output_layout_move(server.monitor.layout, output,
- head->state.x, head->state.y);
- wlr_output_set_transform(output, head->state.transform);
- }
-
- if(!(ok=wlr_output_test(output)))
- break;
- }
-
- wl_list_for_each(head, &config->heads, link) {
- if(ok && force)
- wlr_output_commit(head->state.output);
- else
- wlr_output_rollback(head->state.output);
- }
-
- if(ok)
- wlr_output_configuration_v1_send_succeeded(config);
- else
- wlr_output_configuration_v1_send_failed(config);
-
- wlr_output_configuration_v1_destroy(config);
-}
-
-void
-monitor_apply(struct wl_listener *l, void *data)
-{
- struct wlr_output_configuration_v1 *config = data;
- trylayout(config, 1);
-}
-
-void
-monitor_test(struct wl_listener *l, void *data)
-{
- struct wlr_output_configuration_v1 *config = data;
- trylayout(config, 0);
-}
-
-void
-make_monitor(struct wl_listener *l, void *data)
-{
- int i;
- Client *client;
- Monitor *monitor;
- MonitorRule *rule;
- struct wlr_output_mode *mode;
- struct wlr_output *output = data;
-
- /*
- * XXX: needed?
- if (wl_list_empty(&output->modes))
- return;
- */
-
- monitor = output->data = calloc(1, sizeof(*monitor));
- monitor->output = output;
-
- for(i=0; i < arrlen(monitor->layer); i++)
- wl_list_init(&monitor->layer[i]);
- monitor->tag.set[0] = monitor->tag.set[1] = 1;
-
- for(rule=cfg·monitorrule; rule != cfg·endmonitorrule; ++rule) {
- if(!rule->name || strstr(output->name, rule->name)) {
- monitor->master.len = rule->master.len;
- monitor->master.frac = rule->master.frac;
-
- wlr_output_set_scale(output, rule->scale);
- wlr_xcursor_manager_load(server.cursor.manager, rule->scale);
- monitor->layouts[0] = monitor->layouts[1] = monitor->layout = rule->layout;
-
- wlr_output_set_transform(output, rule->transform);
- break;
- }
- }
-
- mode = wlr_output_preferred_mode(output);
- wlr_output_set_mode(output, mode);
- wlr_output_enable_adaptive_sync(output, true);
-
- monitor->event.render.notify = render_monitor;
- wl_signal_add(&output->events.frame, &monitor->event.render);
- monitor->event.destroy.notify = free_monitor;
- wl_signal_add(&output->events.destroy, &monitor->event.destroy);
-
- wlr_output_enable(output, true);
- if(!wlr_output_commit(output))
- return;
-
- wl_list_insert(&server.monitor.list, &monitor->link);
-
- wlr_output_layout_add(server.monitor.layout, output, rule->x, rule->y);
- server.monitor.geometry = *wlr_output_layout_get_box(server.monitor.layout, nil);
-
- /* update the geometries of all monitors */
- wl_list_for_each(monitor, &server.monitor.list, link) {
- /* first monitor in the list = most recently added */
- wl_list_for_each(client, &server.client.list, link) {
- if(client->isfloating)
- resize(client, client->geometry.x+monitor->window.width, client->geometry.y,
- client->geometry.width, client->geometry.height, 0);
- }
- return;
- }
-}
-
-void
-free_monitor(struct wl_listener *l, void *data)
-{
- int i, len;
- Client *client;
- struct wlr_output *output = data;
- Monitor *monitor = output->data;
-
- wl_list_remove(&monitor->event.destroy.link);
- wl_list_remove(&monitor->event.render.link);
- wl_list_remove(&monitor->link);
-
- wlr_output_layout_remove(server.monitor.layout, monitor->output);
-
- for(i=0, len=wl_list_length(&server.monitor.list); i < len; i++) {
- server.monitor.selected = wl_container_of(server.monitor.list.prev, server.monitor.selected, link);
- if(server.monitor.selected->output->enabled)
- break;
- }
-
- focus(focused_client(server.monitor.selected), 1);
-
- /* move closed monitor's clients to newly selected one */
- wl_list_for_each(client, &server.client.list, link) {
- if(client->isfloating && client->geometry.x > monitor->geometry.width)
- resize(client,
- client->geometry.x - monitor->window.width,
- client->geometry.y,
- client->geometry.width,
- client->geometry.height,
- 0
- );
- if(client->monitor == monitor)
- attach(client, monitor, client->tags);
- }
-
- free(monitor);
-}
-
-/* methods */
-void
-arrange(Monitor *monitor)
-{
- if(monitor->layout->arrange)
- monitor->layout->arrange(monitor);
-}
-
-void
-stratum(Monitor *monitor, struct wl_list *list, struct wlr_box *area, int exclusive)
-{
- Layer *layer;
- struct wlr_box full = monitor->geometry;
-
- wl_list_for_each(layer, list, link) {
- struct wlr_layer_surface_v1 *surface = layer->surface;
- struct wlr_layer_surface_v1_state *state = &surface->current;
- struct wlr_box bounds;
- struct wlr_box box = {
- .width = state->desired_width,
- .height = state->desired_height
- };
- const uint32 horizontal = ZWLR_LAYER_SURFACE_V1_ANCHOR_LEFT
- | ZWLR_LAYER_SURFACE_V1_ANCHOR_RIGHT;
- const uint32 vertical = ZWLR_LAYER_SURFACE_V1_ANCHOR_TOP
- | ZWLR_LAYER_SURFACE_V1_ANCHOR_BOTTOM;
-
- if (exclusive != (state->exclusive_zone > 0))
- continue;
-
- bounds = state->exclusive_zone == -1 ? full : *area;
-
- // horizontal axis
- if((state->anchor & horizontal) && box.width == 0) {
- box.x = bounds.x;
- box.width = bounds.width;
- } else if((state->anchor & ZWLR_LAYER_SURFACE_V1_ANCHOR_LEFT)) {
- box.x = bounds.x;
- } else if((state->anchor & ZWLR_LAYER_SURFACE_V1_ANCHOR_RIGHT)) {
- box.x = bounds.x + (bounds.width - box.width);
- } else {
- box.x = bounds.x + ((bounds.width / 2) - (box.width / 2));
- }
-
- // vertical axis
- if((state->anchor & vertical) && box.height == 0) {
- box.y = bounds.y;
- box.height = bounds.height;
- } else if((state->anchor & ZWLR_LAYER_SURFACE_V1_ANCHOR_TOP)) {
- box.y = bounds.y;
- } else if((state->anchor & ZWLR_LAYER_SURFACE_V1_ANCHOR_BOTTOM)) {
- box.y = bounds.y + (bounds.height - box.height);
- } else {
- box.y = bounds.y + ((bounds.height / 2) - (box.height / 2));
- }
-
- // margin
- if((state->anchor & horizontal) == horizontal) {
- box.x += state->margin.left;
- box.width -= state->margin.left + state->margin.right;
- } else if((state->anchor & ZWLR_LAYER_SURFACE_V1_ANCHOR_LEFT)) {
- box.x += state->margin.left;
- } else if((state->anchor & ZWLR_LAYER_SURFACE_V1_ANCHOR_RIGHT)) {
- box.x -= state->margin.right;
- }
-
- if((state->anchor & vertical) == vertical) {
- box.y += state->margin.top;
- box.height -= state->margin.top + state->margin.bottom;
- } else if((state->anchor & ZWLR_LAYER_SURFACE_V1_ANCHOR_TOP)) {
- box.y += state->margin.top;
- } else if((state->anchor & ZWLR_LAYER_SURFACE_V1_ANCHOR_BOTTOM)) {
- box.y -= state->margin.bottom;
- }
- if(box.width < 0 || box.height < 0) {
- wlr_layer_surface_v1_close(surface);
- continue;
- }
- layer->geometry = box;
-
- if (state->exclusive_zone > 0)
- exclude(area,
- state->anchor, state->exclusive_zone,
- state->margin.top, state->margin.right,
- state->margin.bottom, state->margin.left);
- wlr_layer_surface_v1_configure(surface, box.width, box.height);
- }
-}
-
-void
-stratify(Monitor *monitor)
-{
- int i;
- Layer *layer;
- struct wlr_box area = monitor->geometry;
- uint32_t overlays[] = {
- ZWLR_LAYER_SHELL_V1_LAYER_OVERLAY,
- ZWLR_LAYER_SHELL_V1_LAYER_TOP,
- };
- struct wlr_keyboard *keyboard = wlr_seat_get_keyboard(server.input.seat);
-
- // arrange exclusive surfaces from top->bottom
- stratum(monitor, &monitor->layer[ZWLR_LAYER_SHELL_V1_LAYER_OVERLAY], &area, 1);
- stratum(monitor, &monitor->layer[ZWLR_LAYER_SHELL_V1_LAYER_TOP], &area, 1);
- stratum(monitor, &monitor->layer[ZWLR_LAYER_SHELL_V1_LAYER_BOTTOM], &area, 1);
- stratum(monitor, &monitor->layer[ZWLR_LAYER_SHELL_V1_LAYER_BACKGROUND], &area, 1);
-
- if(memcmp(&area, &monitor->window, sizeof(area))) {
- monitor->window = area;
- arrange(monitor);
- }
-
- // arrange non-exlusive surfaces from top->bottom
- stratum(monitor, &monitor->layer[ZWLR_LAYER_SHELL_V1_LAYER_OVERLAY], &area, 0);
- stratum(monitor, &monitor->layer[ZWLR_LAYER_SHELL_V1_LAYER_TOP], &area, 0);
- stratum(monitor, &monitor->layer[ZWLR_LAYER_SHELL_V1_LAYER_BOTTOM], &area, 0);
- stratum(monitor, &monitor->layer[ZWLR_LAYER_SHELL_V1_LAYER_BACKGROUND], &area, 0);
-
- // find topmost keyboard interactive layer, if such a layer exists
- for(i = 0; i < arrlen(overlays); i++) {
- wl_list_for_each_reverse(layer, &monitor->layer[overlays[i]], link) {
- if (layer->surface->current.keyboard_interactive && layer->surface->mapped) {
- // Deactivate the focused client.
- focus(nil, 0);
- wlr_seat_keyboard_notify_enter(
- server.input.seat,
- layer->surface->surface,
- keyboard->keycodes,
- keyboard->num_keycodes,
- &keyboard->modifiers
- );
- return;
- }
- }
- }
-}
-
-Client *
-focused_client(Monitor *monitor)
-{
- Client *client;
- wl_list_for_each(client, &server.client.focus, focus) {
- if(VISIBLE_ON(client, monitor))
- return client;
- }
-
- return nil;
-}
-
-void
-tile(Monitor *monitor)
-{
- Client *client;
- uint i, n, h, mw, my, ty;
-
- n = 0;
- wl_list_for_each(client, &server.client.list, link) {
- if(VISIBLE_ON(client, monitor) && !client->isfloating)
- n++;
- }
- if(!n) return;
-
- if(n > monitor->master.len)
- mw = monitor->master.len ? monitor->window.width * monitor->master.frac : 0;
- else
- mw = monitor->window.width;
-
- i = my = ty = 0;
- wl_list_for_each(client, &server.client.list, link) {
- if(!VISIBLE_ON(client,monitor) || client->isfloating || client->isfullscreen)
- continue;
- if(i < monitor->master.len) {
- h = (monitor->window.height - my) / (MIN(n, monitor->master.len) - i);
- resize(client, monitor->window.x, monitor->window.y + my, mw, h, 0);
- my += client->geometry.height;
- } else {
- h = (monitor->window.height - ty) / (n - i);
- resize(client, monitor->window.x + mw, monitor->window.y + ty, monitor->window.width - mw, h, 0);
- ty += client->geometry.height;
- }
- i++;
- }
-}
-
-Monitor *
-monitor_at(double x, double y)
-{
- struct wlr_output *output = wlr_output_layout_output_at(server.monitor.layout, x, y);
- return output ? output->data : nil;
-}