From 88b8c199e3524b7c4e2667db3683c77d70f34a26 Mon Sep 17 00:00:00 2001 From: Nicholas Noll Date: Wed, 29 Sep 2021 10:53:41 -0700 Subject: feat(wm): working prototype --- sys/cmd/rules.mk | 3 ++ sys/cmd/wm/client.c | 45 +++++++++------- sys/cmd/wm/input.c | 72 +++++++++++++------------ sys/cmd/wm/main.c | 61 ++++++++++++++++++--- sys/cmd/wm/output.c | 153 ++++++++++++++++++++++++++++++++++++---------------- sys/cmd/wm/rules.mk | 21 +++++++- sys/cmd/wm/wm.h | 123 ++++++++++++++++++++++++++++++++++++++---- sys/cmd/wm/xdg.c | 41 +++++++++++--- 8 files changed, 393 insertions(+), 126 deletions(-) (limited to 'sys') diff --git a/sys/cmd/rules.mk b/sys/cmd/rules.mk index 01edd92..50d9274 100644 --- a/sys/cmd/rules.mk +++ b/sys/cmd/rules.mk @@ -8,6 +8,9 @@ include share/push.mk DIR := $(d)/dwm include $(DIR)/rules.mk +DIR := $(d)/tinywl +include $(DIR)/rules.mk + DIR := $(d)/wm include $(DIR)/rules.mk diff --git a/sys/cmd/wm/client.c b/sys/cmd/wm/client.c index 7d828a0..33dfcb1 100644 --- a/sys/cmd/wm/client.c +++ b/sys/cmd/wm/client.c @@ -8,12 +8,15 @@ focus(Client *client, struct wlr_surface *new) struct wlr_xdg_surface *xdg; struct wlr_keyboard *keyboard; - if(!client) - return; + if(client) { + wl_list_remove(&client->link); + wl_list_insert(&server.clients, &client->link); + } seat = server.input.seat; old = seat->keyboard_state.focused_surface; - if(old == new) + + if(old==new) return; if(old) { @@ -21,20 +24,26 @@ focus(Client *client, struct wlr_surface *new) wlr_xdg_toplevel_set_activated(xdg, false); } + if(!client) { + wlr_seat_keyboard_notify_clear_focus(seat); + return; + } + keyboard = wlr_seat_get_keyboard(seat); - wl_list_remove(&client->link); - wl_list_insert(&server.clients, &client->link); + wlr_seat_keyboard_notify_enter(seat, client->xdg->surface, + keyboard->keycodes, + keyboard->num_keycodes, + &keyboard->modifiers + ); wlr_xdg_toplevel_set_activated(client->xdg, true); - wlr_seat_keyboard_notify_enter(seat, client->xdg->surface, - keyboard->keycodes, keyboard->num_keycodes, &keyboard->modifiers); } int -clienthas(Client *client, double lx, double ly, struct wlr_surface **surface, double *sx, double *sy) +client_has(Client *client, double lx, double ly, struct wlr_surface **surface, double *sx, double *sy) { - double x, y, vsx = lx - client->x, vsy = ly - client->y; + double x, y, vsx = lx - client->geo.x, vsy = ly - client->geo.y; struct wlr_surface *find = nil; find = wlr_xdg_surface_surface_at(client->xdg, vsx, vsy, &x, &y); @@ -49,11 +58,11 @@ clienthas(Client *client, double lx, double ly, struct wlr_surface **surface, do } Client* -clientat(double lx, double ly, struct wlr_surface **surface, double *sx, double *sy) +client_at(double lx, double ly, struct wlr_surface **surface, double *sx, double *sy) { Client *it; wl_list_for_each(it, &server.clients, link) { - if(clienthas(it, lx, ly, surface, sx, sy)) + if(client_has(it, lx, ly, surface, sx, sy)) return it; } @@ -73,23 +82,21 @@ setinteractive(Client *client, int mode, uint32 edges) { server.cursor.mode = mode; if(mode == CursorMove) { - server.grab.x = server.cursor.dot->x - client->x; - server.grab.y = server.cursor.dot->y - client->y; + server.grab.x = server.cursor.dot->x - client->geo.x; + server.grab.y = server.cursor.dot->y - client->geo.y; } else { wlr_xdg_surface_get_geometry(client->xdg, &box); - bx = (client->x + box.x) + ((edges & WLR_EDGE_RIGHT) ? box.width : 0); - by = (client->y + box.y) + ((edges & WLR_EDGE_BOTTOM) ? box.height : 0); + bx = (client->geo.x + box.x) + ((edges & WLR_EDGE_RIGHT) ? box.width : 0); + by = (client->geo.y + box.y) + ((edges & WLR_EDGE_BOTTOM) ? box.height : 0); server.grab.x = server.cursor.dot->x - bx; server.grab.y = server.cursor.dot->y - by; server.grab.box = box; - server.grab.box.x += client->x; - server.grab.box.y += client->y; + server.grab.box.x += client->geo.x; + server.grab.box.y += client->geo.y; server.resize = edges; } } - - diff --git a/sys/cmd/wm/input.c b/sys/cmd/wm/input.c index e155024..295f861 100644 --- a/sys/cmd/wm/input.c +++ b/sys/cmd/wm/input.c @@ -15,31 +15,16 @@ keymodifier(struct wl_listener *l, void *data) static int -keybinding(xkb_keysym_t sym) +keybinding(uint32 modifier, xkb_keysym_t sym) { - Client *current, *next; - - switch(sym) { - case XKB_KEY_Escape: - wl_display_terminate(server.display); - break; - case XKB_KEY_F1: - /* cycle to the next client */ - if(wl_list_length(&server.clients) < 2) break; - - current = wl_container_of(server.clients.next, current, link); - next = wl_container_of(current->link.next, next, link); - - focus(next, next->xdg->surface); - - /* move previous client to the end of the list */ - wl_list_remove(¤t->link); - wl_list_insert(server.clients.prev, ¤t->link); - break; - default: - return false; + Key *key; + for(key=cfg·binding; key!=cfg·endbinding; ++key) { + if(modifier == key->modifier && sym == key->sym && key->action){ + key->action(&key->arg); + return 1; + } } - return true; + return 0; } static @@ -51,7 +36,6 @@ keypress(struct wl_listener *l, void *data) const xkb_keysym_t *syms; struct Keyboard *keyboard = wl_container_of(l, keyboard, event.press); struct wlr_event_keyboard_key *event = data; - struct wlr_seat *seat = server.input.seat; keycode = event->keycode + 8; @@ -59,18 +43,33 @@ keypress(struct wl_listener *l, void *data) n = xkb_state_key_get_syms(keyboard->device->keyboard->xkb_state, keycode, &syms); modifier = wlr_keyboard_get_modifiers(keyboard->device->keyboard); - if((modifier & WLR_MODIFIER_ALT) && event->state == WL_KEYBOARD_KEY_STATE_PRESSED) { + if(event->state == WL_KEYBOARD_KEY_STATE_PRESSED) { for(i=0; idevice); - wlr_seat_keyboard_notify_key(seat, event->time_msec, - event->keycode, event->state); + wlr_seat_set_keyboard(server.input.seat, keyboard->device); + wlr_seat_keyboard_notify_key(server.input.seat, event->time_msec, event->keycode, event->state); } } +static +void +free_keyboard(struct wl_listener *l, void *data) +{ + struct wlr_input_device *device = data; + Keyboard *keyboard = device->data; + + /* + wl_list_remove(&keyboard->link); + wl_list_remove(&keyboard->event.modify.link); + wl_list_remove(&keyboard->event.press.link); + wl_list_remove(&keyboard->event.destroy.link); + free(keyboard); + */ +} + static void make_keyboard(struct wlr_input_device *device) @@ -82,22 +81,25 @@ make_keyboard(struct wlr_input_device *device) context = xkb_context_new(XKB_CONTEXT_NO_FLAGS); keymap = xkb_keymap_new_from_names(context, nil, XKB_KEYMAP_COMPILE_NO_FLAGS); - wlr_keyboard_set_keymap(device->keyboard, keymap); wlr_keyboard_set_keymap(device->keyboard, keymap); xkb_keymap_unref(keymap); xkb_context_unref(context); - wlr_keyboard_set_repeat_info(device->keyboard, 25, 600); + wlr_keyboard_set_repeat_info(device->keyboard, cfg·repeat_rate, cfg·repeat_delay); keyboard = calloc(1, sizeof(*keyboard)); keyboard->device = device; keyboard->event.modify.notify = keymodifier; wl_signal_add(&device->keyboard->events.modifiers, &keyboard->event.modify); + keyboard->event.press.notify = keypress; wl_signal_add(&device->keyboard->events.key, &keyboard->event.press); + keyboard->event.destroy.notify = free_keyboard; + wl_signal_add(&device->keyboard->events.destroy, &keyboard->event.destroy); + wlr_seat_set_keyboard(server.input.seat, device); wl_list_insert(&server.input.keyboards, &keyboard->link); } @@ -147,8 +149,8 @@ cursorresize(uint32 time) } wlr_xdg_surface_get_geometry(client->xdg, &box); - client->x = new_left - box.x; - client->y = new_top - box.y; + client->geo.x = new_left - box.x; + client->geo.y = new_top - box.y; new_width = new_right - new_left; new_height = new_bottom - new_top; @@ -172,7 +174,7 @@ docursor(uint32 time) /* Otherwise, find the client under the pointer and send the event along. */ seat = server.input.seat; surface = nil; - client = clientat(server.cursor.dot->x, server.cursor.dot->y, &surface, &sx, &sy); + client = client_at(server.cursor.dot->x, server.cursor.dot->y, &surface, &sx, &sy); if(!client) wlr_xcursor_manager_set_cursor_image(server.cursor.manager, "left_ptr", server.cursor.dot); @@ -211,7 +213,7 @@ cursor_button(struct wl_listener *l, void *data) wlr_seat_pointer_notify_button(server.input.seat, event->time_msec, event->button, event->state); - client = clientat(server.cursor.dot->x, server.cursor.dot->y, &surface, &sx, &sy); + 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 diff --git a/sys/cmd/wm/main.c b/sys/cmd/wm/main.c index dac0aa3..3dd9903 100644 --- a/sys/cmd/wm/main.c +++ b/sys/cmd/wm/main.c @@ -3,7 +3,7 @@ Server server = { .event = { .make_input = { .notify = make_input }, - .make_output = { .notify = make_output }, + .make_monitor = { .notify = make_monitor }, .make_xdg_surface = { .notify = make_xdg_surface }, .cursor_move = { .notify = cursor_move }, @@ -27,26 +27,42 @@ init_compositor(void) server.display = wl_display_create(); server.backend = wlr_backend_autocreate(server.display); server.renderer = wlr_backend_get_renderer(server.backend); + server.present = wlr_presentation_create(server.display, server.backend); wlr_renderer_init_wl_display(server.renderer, server.display); wlr_compositor_create(server.display, server.renderer); + wlr_export_dmabuf_manager_v1_create(server.display); + wlr_screencopy_manager_v1_create(server.display); + wlr_data_control_manager_v1_create(server.display); wlr_data_device_manager_create(server.display); + wlr_gamma_control_manager_v1_create(server.display); + wlr_primary_selection_v1_device_manager_create(server.display); + wlr_viewporter_create(server.display); - server.output.layout = wlr_output_layout_create(); + wlr_data_device_manager_create(server.display); + + server.monitor.layout = wlr_output_layout_create(); - wl_list_init(&server.output.list); - wl_signal_add(&server.backend->events.new_output, &server.event.make_output); + wl_list_init(&server.monitor.list); + wl_signal_add(&server.backend->events.new_output, &server.event.make_monitor); } static inline void -init_desktop(void) +init_shells(void) { wl_list_init(&server.clients); + wl_list_init(&server.stack); server.shell.xdg = wlr_xdg_shell_create(server.display); wl_signal_add(&server.shell.xdg->events.new_surface, &server.event.make_xdg_surface); + + wlr_server_decoration_manager_set_default_mode( + wlr_server_decoration_manager_create(server.display), + WLR_SERVER_DECORATION_MANAGER_MODE_SERVER + ); + wlr_xdg_decoration_manager_v1_create(server.display); } static inline @@ -54,7 +70,7 @@ void init_inputs(void) { server.cursor.dot = wlr_cursor_create(); - wlr_cursor_attach_output_layout(server.cursor.dot, server.output.layout); + wlr_cursor_attach_output_layout(server.cursor.dot, server.monitor.layout); server.cursor.manager = wlr_xcursor_manager_create(nil, 24); wlr_xcursor_manager_load(server.cursor.manager, 1); @@ -79,21 +95,46 @@ void cleanup(void) { wl_display_destroy_clients(server.display); + + wlr_backend_destroy(server.backend); + wlr_xcursor_manager_destroy(server.cursor.manager); + wlr_output_layout_destroy(server.monitor.layout); + wlr_seat_destroy(server.input.seat); + wl_display_destroy(server.display); } // ----------------------------------------------------------------------- // main point of entry +int +usage(void) +{ + fprintf(stderr, "usage: %s [-s startup command]\n", argv0); + return 1; +} + + int main(int argc, char *argv[]) { - char *socket; + char *socket, *cmd=nil; + + ARGBEGIN { + case 's': + cmd = ARGF(); + break; + default: + return usage(); + } ARGEND + + if(argc != 0) + return usage(); wlr_log_init(WLR_DEBUG, nil); init_compositor(); - init_desktop(); + init_shells(); init_inputs(); if(!(socket=(char*)wl_display_add_socket_auto(server.display))) { @@ -108,6 +149,10 @@ main(int argc, char *argv[]) } setenv("WAYLAND_DISPLAY", socket, true); + if(cmd) { + if(fork()==0) + execl("/bin/sh", "/bin/sh", "-c", cmd, nil); + } wlr_log(WLR_INFO, "Running Wayland compositor on WAYLAND_DISPLAY=%s", socket); wl_display_run(server.display); /* event loop */ diff --git a/sys/cmd/wm/output.c b/sys/cmd/wm/output.c index 3283c41..46e702f 100644 --- a/sys/cmd/wm/output.c +++ b/sys/cmd/wm/output.c @@ -1,23 +1,23 @@ #include "wm.h" -typedef struct Payload Payload; struct Payload { - Client *client; - struct wlr_output *output; - struct wlr_renderer *renderer; - struct timespec *when; + Client *client; + struct wlr_output *output; + struct timespec *when; + int x, y; }; static void -draw(struct wlr_surface *surface, int sx, int sy, void *data) +render(struct wlr_surface *surface, int sx, int sy, void *data) { float matrix[9]; - double ox, oy; + double x, y; Client *client; - Payload *payload; + struct Payload *payload; + struct wlr_box box; struct wlr_output *output; struct wlr_texture *texture; @@ -31,70 +31,134 @@ draw(struct wlr_surface *surface, int sx, int sy, void *data) if(!texture) return; - ox = 0, oy = 0; - wlr_output_layout_output_coords(server.output.layout, output, &ox, &oy); - ox += client->x + sx, oy += client->y + sy; + x = 0, y = 0; + wlr_output_layout_output_coords(server.monitor.layout, output, &x, &y); - box = (struct wlr_box){ - .x = ox * output->scale, - .y = oy * output->scale, - .width = surface->current.width * output->scale, - .height = surface->current.height * output->scale, + 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(payload->renderer, texture, matrix, 1); + 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(struct wl_listener *l, void *data) +render_clients(Monitor *monitor, struct timespec *now) { - int width, height; - 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.clients, link) { + if(!client->ismapped) + continue; + + surface = client->xdg->surface; + + x = client->geo.x, y = client->geo.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->geo.x + client->border, + .y = client->geo.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; Monitor *monitor; - struct wlr_renderer *renderer; - float color[4] = {0.3, 0.3, 0.3, 1.0}; + struct timespec now; monitor = wl_container_of(l, monitor, event.render); - renderer = server.renderer; clock_gettime(CLOCK_MONOTONIC, &now); if(!wlr_output_attach_render(monitor->output, nil)) return; - wlr_output_effective_resolution(monitor->output, &width, &height); + wlr_output_effective_resolution(monitor->output, &w, &h); /* start of rendering kernel */ - wlr_renderer_begin(renderer, width, height); - wlr_renderer_clear(renderer, color); + wlr_renderer_begin(server.renderer, w, h); + wlr_renderer_clear(server.renderer, cfg·rootcolor); - wl_list_for_each_reverse(client, &server.clients, link) { - if(!client->mapped) - continue; - - Payload payload = { - .output = monitor->output, - .client = client, - .renderer = renderer, - .when = &now, - }; - - wlr_xdg_surface_for_each_surface(client->xdg, draw, &payload); - } + render_clients(monitor, &now); wlr_output_render_software_cursors(monitor->output, nil); - wlr_renderer_end(renderer); + 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_output(struct wl_listener *l, void *data) +make_monitor(struct wl_listener *l, void *data) { struct wlr_output_mode *mode; struct Monitor *monitor; @@ -112,10 +176,9 @@ make_output(struct wl_listener *l, void *data) monitor = calloc(1, sizeof(*monitor)); monitor->output = output; - monitor->event.render.notify = render; + monitor->event.render.notify = render_monitor; wl_signal_add(&output->events.frame, &monitor->event.render); - wl_list_insert(&server.output.list, &monitor->link); + wl_list_insert(&server.monitor.list, &monitor->link); - wlr_output_layout_add_auto(server.output.layout, output); + wlr_output_layout_add_auto(server.monitor.layout, output); } - diff --git a/sys/cmd/wm/rules.mk b/sys/cmd/wm/rules.mk index b1ab9c3..8714aec 100644 --- a/sys/cmd/wm/rules.mk +++ b/sys/cmd/wm/rules.mk @@ -3,6 +3,9 @@ include share/push.mk # Local sources SRCS_$(d) := \ + $(d)/xdg-shell-protocol.c \ + $(d)/util.c \ + $(d)/arg.c \ $(d)/input.c \ $(d)/output.c \ $(d)/xdg.c \ @@ -14,15 +17,29 @@ include share/paths.mk # Local rules include share/dynamic.mk + +$(d)/xdg-shell-protocol.h: + @echo "MK xdg-shell-protocol.h";\ + $(WL_SCAN) server-header $(WL_PROTO)/stable/xdg-shell/xdg-shell.xml $@ + +$(d)/xdg-shell-protocol.c: $(d)/xdg-shell-protocol.h + @echo "MK xdg-shell-protocol.c";\ + $(WL_SCAN) private-code $(WL_PROTO)/stable/xdg-shell/xdg-shell.xml $@ + +GENS += $(d)/xdg-shell-protocol.h $(d)/xdg-shell-protocol.c + +$(BINS_$(d)): TCINCS = \ + -I sys/cmd/wm + $(BINS_$(d)): TCFLAGS = \ - `$(PKG) --cflags wlroots ` \ + `$(PKG) --cflags wlroots` \ `$(PKG) --cflags wayland-server` \ `$(PKG) --cflags xkbcommon` $(BINS_$(d)): TCLIBS = \ `$(PKG) --libs wlroots` \ `$(PKG) --libs wayland-server` \ - `$(PKG) --libs xkbcommon` + `$(PKG) --libs xkbcommon` \ $(BINS_$(d)): $(OBJS_$(d)) $(OBJ_DIR)/sys/libn/libn.a $(COMPLINK) diff --git a/sys/cmd/wm/wm.h b/sys/cmd/wm/wm.h index b9731e9..e1d3670 100644 --- a/sys/cmd/wm/wm.h +++ b/sys/cmd/wm/wm.h @@ -10,21 +10,39 @@ #include #include +#include #include +#include +#include #include #include #include #include #include +#include +#include +#include #include +#include +#include +#include #include +#include #include +#include +#include +#include #include #include #include +// ----------------------------------------------------------------------- +// macros + +#define ROUND(x) ((int)((x)+0.5)) + // ----------------------------------------------------------------------- // types @@ -35,11 +53,45 @@ enum CursorResize, }; +typedef union Arg Arg; +typedef struct Button Button; +typedef struct Key Key; typedef struct Keyboard Keyboard; typedef struct Client Client; +typedef struct Layout Layout; typedef struct Monitor Monitor; typedef struct Server Server; +struct Rectangle +{ + int x, y; + int w, h; +}; + +union Arg +{ + int i; + uint ui; + float f; + void *v; +}; + +struct Key +{ + uint modifier; + xkb_keysym_t sym; + void (*action)(Arg *); + Arg arg; +}; + +struct Button +{ + uint mod; + uint button; + void (*func)(const Arg *); + const Arg arg; +}; + struct Keyboard { struct wl_list link; @@ -47,21 +99,41 @@ struct Keyboard struct { struct wl_listener press; struct wl_listener modify; + struct wl_listener destroy; } event; }; struct Client { struct wl_list link; + struct wl_list stack; + struct wlr_xdg_surface *xdg; + struct { struct wl_listener map; struct wl_listener unmap; struct wl_listener destroy; struct wl_listener request_move; + struct wl_listener request_title; struct wl_listener request_resize; + struct wl_listener request_fullscreen; } event; - int x, y, mapped; + + struct wlr_box geo, oldgeo; + + uint tags; + int border : 4; + int ismapped : 1; + int isfloating : 1; + int isurgent : 1; + int isfullscreen : 1; +}; + +struct Layout +{ + char *symbol; + void (*arrange)(Monitor *); }; struct Monitor @@ -70,20 +142,45 @@ struct Monitor struct wlr_output *output; struct { struct wl_listener render; + struct wl_listener destroy; } event; }; +struct MonitorRule +{ + char *name; + float mfact; + int nmaster; + float scale; + const Layout *lt; + enum wl_output_transform rr; + int x; + int y; +}; + +struct Rule +{ + char *id; + char *title; + uint tags; + int floating; + int monitor; +}; + struct Server { - struct wl_display *display; - struct wlr_backend *backend; - struct wlr_renderer *renderer; + struct wl_display *display; + struct wlr_backend *backend; + struct wlr_renderer *renderer; + struct wlr_presentation *present; struct { struct wlr_xdg_shell *xdg; } shell; struct wl_list clients; + struct wl_list stack; + Client *selected; struct { Client *client; @@ -95,7 +192,7 @@ struct Server struct { struct wlr_output_layout *layout; struct wl_list list; - } output; + } monitor; struct { struct wlr_cursor *dot; @@ -109,9 +206,10 @@ struct Server } input; struct { - struct wl_listener make_output; struct wl_listener make_input; + struct wl_listener make_monitor; struct wl_listener make_xdg_surface; + struct wl_listener make_layer_surface; struct wl_listener cursor_move; struct wl_listener cursor_move_abs; @@ -129,8 +227,11 @@ extern struct Server server; // ----------------------------------------------------------------------- // functions +/* util.c */ +void scale_box(struct wlr_box *, float); + /* output.c */ -void make_output(struct wl_listener *, void *); +void make_monitor(struct wl_listener *, void *); /* xdg.c */ void make_xdg_surface(struct wl_listener *, void *); @@ -149,6 +250,10 @@ void request_set_selection(struct wl_listener *, void *); /* client.c */ void focus(Client *client, struct wlr_surface *new); -Client* clientat(double, double, struct wlr_surface **, double *, double *); -int clienthas(Client *, double, double, struct wlr_surface **, double *, double *); +Client* client_at(double, double, struct wlr_surface **, double *, double *); +int client_has(Client *, double, double, struct wlr_surface **, double *, double *); void setinteractive(Client *client, int mode, uint32 edges); + +#define CONFIG(a,b,...) extern a cfg·##b +#include "config.h" +#undef CONFIG diff --git a/sys/cmd/wm/xdg.c b/sys/cmd/wm/xdg.c index 3978cbf..0ff7c0a 100644 --- a/sys/cmd/wm/xdg.c +++ b/sys/cmd/wm/xdg.c @@ -5,7 +5,14 @@ void map(struct wl_listener *l, void *data) { Client *client = wl_container_of(l, client, event.map); - client->mapped = true; + client->ismapped = true; + + wl_list_insert(&server.clients, &client->link); + wl_list_insert(&server.stack, &client->stack); + + wlr_xdg_surface_get_geometry(client->xdg, &client->geo); + client->geo.width += 2 * client->border; + client->geo.height += 2 * client->border; focus(client, client->xdg->surface); } @@ -15,7 +22,10 @@ void unmap(struct wl_listener *l, void *data) { Client *client = wl_container_of(l, client, event.unmap); - client->mapped = false; + client->ismapped = false; + + wl_list_remove(&client->link); + wl_list_remove(&client->stack); } static @@ -23,7 +33,6 @@ void destroy(struct wl_listener *l, void *data) { Client *client = wl_container_of(l, client, event.destroy); - wl_list_remove(&client->link); free(client); } @@ -35,6 +44,13 @@ request_move(struct wl_listener *l, void *data) setinteractive(client, CursorMove, 0); } +static +void +request_title(struct wl_listener *l, void *data) +{ + Client *client = wl_container_of(l, client, event.request_title); +} + static void request_resize(struct wl_listener *l, void *data) @@ -44,6 +60,14 @@ request_resize(struct wl_listener *l, void *data) setinteractive(client, CursorResize, event->edges); } +static +void +request_fullscreen(struct wl_listener *l, void *data) +{ + Client *client = wl_container_of(l, client, event.request_fullscreen); + client->isfullscreen = 1; +} + void make_xdg_surface(struct wl_listener *l, void *data) { @@ -54,8 +78,9 @@ make_xdg_surface(struct wl_listener *l, void *data) if(xdg->role != WLR_XDG_SURFACE_ROLE_TOPLEVEL) return; - client = calloc(1, sizeof(*client)); + client = xdg->surface->data = calloc(1, sizeof(*client)); client->xdg = xdg; + client->border = cfg·borderpixel; client->event.map.notify = map; wl_signal_add(&xdg->events.map, &client->event.map); @@ -64,13 +89,13 @@ make_xdg_surface(struct wl_listener *l, void *data) client->event.destroy.notify = destroy; wl_signal_add(&xdg->events.destroy, &client->event.destroy); - /* cotd */ toplevel = xdg->toplevel; client->event.request_move.notify = request_move; wl_signal_add(&toplevel->events.request_move, &client->event.request_move); + client->event.request_title.notify = request_title; + wl_signal_add(&toplevel->events.set_title, &client->event.request_title); client->event.request_resize.notify = request_resize; wl_signal_add(&toplevel->events.request_resize, &client->event.request_resize); - - /* Add it to the list of client. */ - wl_list_insert(&server.clients, &client->link); + client->event.request_fullscreen.notify = request_fullscreen; + wl_signal_add(&toplevel->events.request_fullscreen, &client->event.request_fullscreen); } -- cgit v1.2.1