From 8f224149f176fb8de90a82b44f4dd1c6a1b89a4f Mon Sep 17 00:00:00 2001 From: Nicholas Noll Date: Mon, 4 Oct 2021 10:02:50 -0700 Subject: feat(wm): tiling prototype working --- sys/cmd/wm/client.c | 29 ++++--- sys/cmd/wm/input.c | 10 +-- sys/cmd/wm/main.c | 14 +++ sys/cmd/wm/monitor.c | 199 ++++++++++++++++++++++++++++++++++++++++++- sys/cmd/wm/output.c | 234 --------------------------------------------------- sys/cmd/wm/render.c | 140 ++++++++++++++++++++++++++++++ sys/cmd/wm/rules.mk | 2 +- sys/cmd/wm/wm.h | 55 +++++++----- sys/cmd/wm/xdg.c | 7 +- 9 files changed, 408 insertions(+), 282 deletions(-) delete mode 100644 sys/cmd/wm/output.c create mode 100644 sys/cmd/wm/render.c (limited to 'sys') diff --git a/sys/cmd/wm/client.c b/sys/cmd/wm/client.c index 4132468..f626cfa 100644 --- a/sys/cmd/wm/client.c +++ b/sys/cmd/wm/client.c @@ -3,13 +3,15 @@ static char broken[] = "broken"; void -focus(Client *client, struct wlr_surface *new, int lift) +focus(Client *client, int lift) { struct wlr_seat *seat; - struct wlr_surface *old; + struct wlr_surface *old, *new; struct wlr_xdg_surface *xdg; struct wlr_keyboard *keyboard; + new = server.input.seat->keyboard_state.focused_surface; + if(client && lift) { wl_list_remove(&client->stack); wl_list_insert(&server.client.stack, &client->stack); @@ -112,7 +114,7 @@ setinteractive(Client *client, int mode, uint32 edges) { static void -apply_bounds(Client *client, struct wlr_box *box) +constrain(Client *client, struct wlr_box *box) { client->geometry.width = MAX(1, client->geometry.width); client->geometry.height = MAX(1, client->geometry.height); @@ -137,7 +139,7 @@ resize(Client *client, int x, int y, int w, int h, int interact) client->geometry.width = w; client->geometry.height = h; - apply_bounds(client, box); + constrain(client, box); client->resize = wlr_xdg_toplevel_set_size(client->xdg, client->geometry.width - 2*client->border, @@ -146,13 +148,12 @@ resize(Client *client, int x, int y, int w, int h, int interact) } void -attach_to(Client *client, Monitor *monitor, uint tags) +attach(Client *client, Monitor *monitor, uint tags) { - struct wlr_surface *surface; Monitor *old = client->monitor; - if(old == monitor) return; + client->monitor = monitor; if(old) { @@ -162,23 +163,22 @@ attach_to(Client *client, Monitor *monitor, uint tags) if(monitor) { /* make sure window actually overlaps with the monitor */ - apply_bounds(client, &monitor->geometry); + constrain(client, &monitor->geometry); wlr_surface_send_enter(client->xdg->surface, monitor->output); client->tags = tags ? tags : monitor->tag.set[monitor->tag.selected]; arrange(monitor); } - surface = server.input.seat->keyboard_state.focused_surface; - focus(focused_client(server.monitor.selected), surface, 1); + focus(focused_client(server.monitor.selected), 1); } void -apply_rules(Client *client) +rules(Client *client) { /* rule matching */ - char *id, *title; - uint i, tags; Rule *rule; + uint i, tags; + char *id, *title; Monitor *monitor, *it; monitor = server.monitor.selected; @@ -199,5 +199,6 @@ apply_rules(Client *client) monitor = it; } } - attach_to(client, monitor, tags); + + attach(client, monitor, tags); } diff --git a/sys/cmd/wm/input.c b/sys/cmd/wm/input.c index b4ceba5..d9e6285 100644 --- a/sys/cmd/wm/input.c +++ b/sys/cmd/wm/input.c @@ -227,14 +227,12 @@ cursor_button(struct wl_listener *l, void *data) struct wlr_surface *surface; struct wlr_event_pointer_button *event = data; - wlr_seat_pointer_notify_button(server.input.seat, - event->time_msec, event->button, event->state); - + wlr_seat_pointer_notify_button(server.input.seat, event->time_msec, event->button, event->state); client = client_at(server.cursor.dot->x, server.cursor.dot->y, &surface, &sx, &sy); if (event->state == WLR_BUTTON_RELEASED) server.cursor.mode = CursorPassthrough; else - focus(client, surface, 1); + focus(client, 1); } void @@ -257,8 +255,8 @@ void request_cursor(struct wl_listener *l, void *data) { struct wlr_seat_pointer_request_set_cursor_event *event = data; - struct wlr_seat_client *focused_client = server.input.seat->pointer_state.focused_client; - if(focused_client == event->seat_client) + struct wlr_seat_client *focused = server.input.seat->pointer_state.focused_client; + if(focused == event->seat_client) wlr_cursor_set_surface(server.cursor.dot, event->surface, event->hotspot_x, event->hotspot_y); } diff --git a/sys/cmd/wm/main.c b/sys/cmd/wm/main.c index 7cc2f92..25981ca 100644 --- a/sys/cmd/wm/main.c +++ b/sys/cmd/wm/main.c @@ -6,6 +6,10 @@ Server server = { .make_monitor = { .notify = make_monitor }, .make_xdg_surface = { .notify = make_xdg_surface }, + .monitor_change = { .notify = monitor_change }, + .monitor_test = { .notify = monitor_test }, + .monitor_apply = { .notify = monitor_apply }, + .cursor_move = { .notify = cursor_move }, .cursor_move_abs = { .notify = cursor_move_abs }, .cursor_button = { .notify = cursor_button }, @@ -43,9 +47,15 @@ init_compositor(void) wlr_data_device_manager_create(server.display); server.monitor.layout = wlr_output_layout_create(); + wl_signal_add(&server.monitor.layout->events.change, &server.event.monitor_change); wl_list_init(&server.monitor.list); wl_signal_add(&server.backend->events.new_output, &server.event.make_monitor); + + /* rearrange monitor layouts */ + server.monitor.manager = wlr_output_manager_v1_create(server.display); + wl_signal_add(&server.monitor.manager->events.test, &server.event.monitor_test); + wl_signal_add(&server.monitor.manager->events.apply, &server.event.monitor_apply); } static inline @@ -156,6 +166,10 @@ main(int argc, char *argv[]) } wlr_log(WLR_INFO, "Running Wayland compositor on WAYLAND_DISPLAY=%s", socket); + server.monitor.selected = monitor_at(server.cursor.dot->x, server.cursor.dot->y); + wlr_cursor_warp_closest(server.cursor.dot, nil, server.cursor.dot->x, server.cursor.dot->y); + wlr_xcursor_manager_set_cursor_image(server.cursor.manager, "left_ptr", server.cursor.dot); + wl_display_run(server.display); /* event loop */ cleanup(); diff --git a/sys/cmd/wm/monitor.c b/sys/cmd/wm/monitor.c index 7fa4d57..9287bfc 100644 --- a/sys/cmd/wm/monitor.c +++ b/sys/cmd/wm/monitor.c @@ -1,5 +1,194 @@ #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); + 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) +{ + 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; + 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) { @@ -27,9 +216,8 @@ tile(Monitor *monitor) n = 0; wl_list_for_each(client, &server.client.list, link) { - if(VISIBLE_ON(client, monitor) && !client->isfloating) { + if(VISIBLE_ON(client, monitor) && !client->isfloating) n++; - } } if(!n) return; @@ -54,3 +242,10 @@ tile(Monitor *monitor) 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; +} diff --git a/sys/cmd/wm/output.c b/sys/cmd/wm/output.c deleted file mode 100644 index 1474a5f..0000000 --- a/sys/cmd/wm/output.c +++ /dev/null @@ -1,234 +0,0 @@ -#include "wm.h" - -struct Payload -{ - Client *client; - struct wlr_output *output; - struct timespec *when; - int x, y; -}; - - -static -void -render(struct wlr_surface *surface, int sx, int sy, void *data) -{ - float matrix[9]; - double x, y; - Client *client; - struct Payload *payload; - - struct wlr_box box; - struct wlr_output *output; - struct wlr_texture *texture; - enum wl_output_transform transform; - - payload = data; - client = payload->client; - output = payload->output; - - texture = wlr_surface_get_texture(surface); - if(!texture) - return; - - x = 0, y = 0; - wlr_output_layout_output_coords(server.monitor.layout, output, &x, &y); - - box = (struct wlr_box) { - .x = x + payload->x + sx, - .y = y + payload->y + sy, - .width = surface->current.width, - .height = surface->current.height, - }; - scale_box(&box, output->scale); - - transform = wlr_output_transform_invert(surface->current.transform); - wlr_matrix_project_box(matrix, &box, transform, 0, output->transform_matrix); - - wlr_render_texture_with_matrix(server.renderer, texture, matrix, 1); - wlr_surface_send_frame_done(surface, payload->when); - wlr_presentation_surface_sampled_on_output(server.present, surface, output); -} - -static -void -render_clients(Monitor *monitor, struct timespec *now) -{ - double x, y; - int i, w, h, bw; - float *color; - - Client *client; - struct wlr_output *output; - struct wlr_box *borders; - struct wlr_surface *surface; - - output = monitor->output; - wl_list_for_each_reverse(client, &server.client.stack, stack) { - if(!client->ismapped) - continue; - - surface = client->xdg->surface; - - x = client->geometry.x, y = client->geometry.y; - wlr_output_layout_output_coords(server.monitor.layout, output, &x, &y); - - if((bw=client->border)) { - w = surface->current.width; - h = surface->current.height; - borders = (struct wlr_box[4]) { - {x, y, w+2*bw, bw}, /* top */ - {x, y+bw, bw, h}, /* left */ - {x+bw+w, y+bw, bw, h}, /* right */ - {x, y+bw+h, w+2*bw, bw}, /* bottom */ - }; - - color = (client == server.selected) ? cfg·focuscolor : cfg·bordercolor; - for(i=0; i<4; i++) { - scale_box(&borders[i], output->scale); - wlr_render_rect(server.renderer, &borders[i], color, output->transform_matrix); - } - } - - struct Payload payload = { - .output = output, - .client = client, - .when = now, - - .x = client->geometry.x + client->border, - .y = client->geometry.y + client->border, - }; - - wlr_xdg_surface_for_each_surface(client->xdg, render, &payload); - } -} - -static -void -render_monitor(struct wl_listener *l, void *data) -{ - int w, h; - Client *client; - Monitor *monitor; - struct timespec now; - - clock_gettime(CLOCK_MONOTONIC, &now); - monitor = wl_container_of(l, monitor, event.render); - - wl_list_for_each(client, &server.client.list, link) { - if(client->resize) { - wlr_surface_send_frame_done(client->xdg->surface, &now); - } - } - - if(!wlr_output_attach_render(monitor->output, nil)) - return; - - wlr_output_effective_resolution(monitor->output, &w, &h); - - /* start of rendering kernel */ - wlr_renderer_begin(server.renderer, w, h); - wlr_renderer_clear(server.renderer, cfg·rootcolor); - - render_clients(monitor, &now); - - wlr_output_render_software_cursors(monitor->output, nil); - - wlr_renderer_end(server.renderer); - wlr_output_commit(monitor->output); -} - -static -void -free_monitor(struct wl_listener *l, void *data) -{ - /* - int len, i = 0; - 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); - - len = wl_list_length(&server.monitor.list); - */ - - /* - do // don't switch to disabled mons - selmon = wl_container_of(mons.prev, selmon, link); - while (!selmon->wlr_output->enabled && i++ < nmons); - focusclient(focustop(selmon), 1); - - closemon(m); - free(monitor); - */ -} - -void -make_monitor(struct wl_listener *l, void *data) -{ - 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 = calloc(1, sizeof(*monitor)); - monitor->output = output; - 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 -layout_change(struct wl_listener *l, void *data) -{ -} diff --git a/sys/cmd/wm/render.c b/sys/cmd/wm/render.c new file mode 100644 index 0000000..3732ec5 --- /dev/null +++ b/sys/cmd/wm/render.c @@ -0,0 +1,140 @@ +#include "wm.h" + +struct Payload +{ + Client *client; + struct wlr_output *output; + struct timespec *when; + int x, y; +}; + + +static +void +render(struct wlr_surface *surface, int sx, int sy, void *data) +{ + float matrix[9]; + double x, y; + Client *client; + struct Payload *payload; + + struct wlr_box box; + struct wlr_output *output; + struct wlr_texture *texture; + enum wl_output_transform transform; + + payload = data; + client = payload->client; + output = payload->output; + + texture = wlr_surface_get_texture(surface); + if(!texture) + return; + + x = 0, y = 0; + wlr_output_layout_output_coords(server.monitor.layout, output, &x, &y); + + box = (struct wlr_box) { + .x = x + payload->x + sx, + .y = y + payload->y + sy, + .width = surface->current.width, + .height = surface->current.height, + }; + scale_box(&box, output->scale); + + transform = wlr_output_transform_invert(surface->current.transform); + wlr_matrix_project_box(matrix, &box, transform, 0, output->transform_matrix); + + wlr_render_texture_with_matrix(server.renderer, texture, matrix, 1); + wlr_surface_send_frame_done(surface, payload->when); + wlr_presentation_surface_sampled_on_output(server.present, surface, output); +} + +static +void +render_clients(Monitor *monitor, struct timespec *now) +{ + double x, y; + int i, w, h, bw; + float *color; + + Client *client; + struct wlr_output *output; + struct wlr_box *borders; + struct wlr_surface *surface; + + output = monitor->output; + wl_list_for_each_reverse(client, &server.client.stack, stack) { + if(!VISIBLE_ON(client, client->monitor)) + continue; + if(!wlr_output_layout_intersects(server.monitor.layout, monitor->output, &client->geometry)) + continue; + + surface = client->xdg->surface; + + x = client->geometry.x, y = client->geometry.y; + wlr_output_layout_output_coords(server.monitor.layout, output, &x, &y); + + if((bw=client->border)) { + w = surface->current.width; + h = surface->current.height; + borders = (struct wlr_box[4]) { + {x, y, w+2*bw, bw}, /* top */ + {x, y+bw, bw, h}, /* left */ + {x+bw+w, y+bw, bw, h}, /* right */ + {x, y+bw+h, w+2*bw, bw}, /* bottom */ + }; + + color = (client == server.selected) ? cfg·focuscolor : cfg·bordercolor; + for(i=0; i<4; i++) { + scale_box(&borders[i], output->scale); + wlr_render_rect(server.renderer, &borders[i], color, output->transform_matrix); + } + } + + struct Payload payload = { + .output = output, + .client = client, + .when = now, + + .x = client->geometry.x + client->border, + .y = client->geometry.y + client->border, + }; + + wlr_xdg_surface_for_each_surface(client->xdg, render, &payload); + } +} + +void +render_monitor(struct wl_listener *l, void *data) +{ + int w, h; + Client *client; + Monitor *monitor; + struct timespec now; + + clock_gettime(CLOCK_MONOTONIC, &now); + monitor = wl_container_of(l, monitor, event.render); + + wl_list_for_each(client, &server.client.list, link) { + if(client->resize) { + wlr_surface_send_frame_done(client->xdg->surface, &now); + } + } + + if(!wlr_output_attach_render(monitor->output, nil)) + return; + + wlr_output_effective_resolution(monitor->output, &w, &h); + + /* start of rendering kernel */ + wlr_renderer_begin(server.renderer, w, h); + wlr_renderer_clear(server.renderer, cfg·rootcolor); + + render_clients(monitor, &now); + + wlr_output_render_software_cursors(monitor->output, nil); + + wlr_renderer_end(server.renderer); + wlr_output_commit(monitor->output); +} diff --git a/sys/cmd/wm/rules.mk b/sys/cmd/wm/rules.mk index d1217fc..e50257f 100644 --- a/sys/cmd/wm/rules.mk +++ b/sys/cmd/wm/rules.mk @@ -7,7 +7,7 @@ SRCS_$(d) := \ $(d)/util.c \ $(d)/arg.c \ $(d)/input.c \ - $(d)/output.c \ + $(d)/render.c \ $(d)/xdg.c \ $(d)/client.c \ $(d)/monitor.c \ diff --git a/sys/cmd/wm/wm.h b/sys/cmd/wm/wm.h index cd51e29..f6ff752 100644 --- a/sys/cmd/wm/wm.h +++ b/sys/cmd/wm/wm.h @@ -217,10 +217,11 @@ struct Server uint32 resize; struct { - struct wlr_output_layout *layout; - struct wl_list list; - struct wlr_box geometry; - Monitor *selected; + struct wlr_output_layout *layout; + struct wl_list list; + struct wlr_box geometry; + struct wlr_output_manager_v1 *manager; + Monitor *selected; } monitor; struct { @@ -240,7 +241,9 @@ struct Server struct wl_listener make_xdg_surface; struct wl_listener make_layer_surface; - struct wl_listener layout_change; + struct wl_listener monitor_test; + struct wl_listener monitor_apply; + struct wl_listener monitor_change; struct wl_listener cursor_move; struct wl_listener cursor_move_abs; @@ -259,41 +262,49 @@ extern struct Server server; // functions /* util.c */ -void scale_box(struct wlr_box *, float); +void scale_box(struct wlr_box *, float); -/* output.c */ -void make_monitor(struct wl_listener *, void *); -void layout_change(struct wl_listener *, void *); +/* render.c */ +void render_monitor(struct wl_listener *, void *); /* xdg.c */ -void make_xdg_surface(struct wl_listener *, void *); +void make_xdg_surface(struct wl_listener *, void *); /* input.c */ -void make_input(struct wl_listener *, void *); +void make_input(struct wl_listener *, void *); -void cursor_axis(struct wl_listener *, void *); -void cursor_frame(struct wl_listener *, void *); -void cursor_button(struct wl_listener *, void *); -void cursor_move(struct wl_listener *, void *); -void cursor_move_abs(struct wl_listener *, void *); +void cursor_axis(struct wl_listener *, void *); +void cursor_frame(struct wl_listener *, void *); +void cursor_button(struct wl_listener *, void *); +void cursor_move(struct wl_listener *, void *); +void cursor_move_abs(struct wl_listener *, void *); -void request_cursor(struct wl_listener *, void *); -void request_set_selection(struct wl_listener *, void *); +void request_cursor(struct wl_listener *, void *); +void request_set_selection(struct wl_listener *, void *); /* client.c */ -void focus(Client *, struct wlr_surface *, int lift); +void rules(Client *); +void focus(Client *, int lift); void resize(Client *, int x, int y, int w, int h, int interact); +void attach(Client *, Monitor *, uint tags); + Client* client_at(double, double, struct wlr_surface **, double *, double *); int client_has(Client *, double, double, struct wlr_surface **, double *, double *); -/* XXX: deprecate */ -void setinteractive(Client *client, int mode, uint32 edges); +void setinteractive(Client *client, int mode, uint32 edges); // XXX: deprecate /* monitor.c */ void tile(Monitor *); void arrange(Monitor *); -Client * focused_client(Monitor *); +Client *focused_client(Monitor *); +Monitor *monitor_at(double x, double y); + +void monitor_test(struct wl_listener *, void *); +void monitor_apply(struct wl_listener *, void *); +void monitor_change(struct wl_listener *, void *); +void free_monitor(struct wl_listener *, void *); +void make_monitor(struct wl_listener *, void *); #define CONFIG(a,b,...) extern a cfg·##b #include "config.h" diff --git a/sys/cmd/wm/xdg.c b/sys/cmd/wm/xdg.c index d49cfb6..1d5ae68 100644 --- a/sys/cmd/wm/xdg.c +++ b/sys/cmd/wm/xdg.c @@ -5,7 +5,6 @@ void map(struct wl_listener *l, void *data) { Client *client = wl_container_of(l, client, event.map); - client->ismapped = true; wl_list_insert(&server.client.list, &client->link); wl_list_insert(&server.client.stack, &client->stack); @@ -18,7 +17,8 @@ map(struct wl_listener *l, void *data) wlr_xdg_toplevel_set_tiled(client->xdg, WLR_EDGE_TOP|WLR_EDGE_BOTTOM|WLR_EDGE_LEFT|WLR_EDGE_RIGHT ); - focus(client, client->xdg->surface, 1); + + rules(client); } static @@ -26,9 +26,10 @@ void unmap(struct wl_listener *l, void *data) { Client *client = wl_container_of(l, client, event.unmap); - client->ismapped = false; wl_list_remove(&client->link); + attach(client, nil, 0); + wl_list_remove(&client->stack); wl_list_remove(&client->focus); } -- cgit v1.2.1