From 36174e35185c34733a84055cd30dda5f7d947397 Mon Sep 17 00:00:00 2001 From: Nicholas Noll Date: Mon, 4 Oct 2021 13:40:18 -0700 Subject: feat(wm): mouse input --- sys/cmd/wm/client.c | 69 +++++++++++++++++++++++++++++++++++++++++++++++------ sys/cmd/wm/config.h | 4 ++-- sys/cmd/wm/input.c | 22 ++++++++++------- sys/cmd/wm/wm.h | 8 ++++--- 4 files changed, 82 insertions(+), 21 deletions(-) (limited to 'sys') diff --git a/sys/cmd/wm/client.c b/sys/cmd/wm/client.c index 3139367..abd5054 100644 --- a/sys/cmd/wm/client.c +++ b/sys/cmd/wm/client.c @@ -5,22 +5,60 @@ static char broken[] = "broken"; // ----------------------------------------------------------------------- // scripts -void * +static inline +void +grab_client(void) +{ + if(server.cursor.mode != CursorNormal) + return; + if(!(server.grab.client = client_at(server.cursor.dot->x, server.cursor.dot->y))) + return; + + floating(server.grab.client, 1); +} + +void move_client(Arg *arg) { - return nil; + grab_client(); + server.cursor.mode = CursorMove; + + server.grab.x = server.cursor.dot->x - server.grab.client->geometry.x; + server.grab.y = server.cursor.dot->y - server.grab.client->geometry.y; + wlr_xcursor_manager_set_cursor_image(server.cursor.manager, "fleur", server.cursor.dot); } -void * +void float_client(Arg *arg) { - return nil; + Client *client = selected_client(); + wlr_log(WLR_DEBUG, "client selected = %lx", (uintptr)client); + if(!client) + return; + + floating(client, client->isfloating ? 0 : 1); } -void * +void resize_client(Arg *arg) { - return nil; + double x, y; + struct wlr_box geometry; + + grab_client(); + server.cursor.mode = CursorResize; + + wlr_xdg_surface_get_geometry(server.grab.client->xdg, &geometry); + + x = server.grab.client->geometry.x + geometry.x + geometry.width; + y = server.grab.client->geometry.y + geometry.y + geometry.height; + + server.grab.x = server.cursor.dot->x - x; + server.grab.y = server.cursor.dot->y - y; + + server.grab.box = geometry; + server.grab.box.x += server.grab.client->geometry.x; + server.grab.box.y += server.grab.client->geometry.y; } // ----------------------------------------------------------------------- @@ -75,7 +113,7 @@ Client* client_at(double x, double y) { Client *client; - wl_list_for_each(client, &server.client.list, link) + wl_list_for_each(client, &server.client.stack, stack) if(VISIBLE_ON(client, client->monitor) && wlr_box_contains_point(&client->geometry, x, y)) return client; return nil; @@ -196,3 +234,20 @@ rules(Client *client) attach(client, monitor, tags); } + +void +floating(Client *client, int state) +{ + wlr_log(WLR_DEBUG, "client %lx, floating = %d", (uintptr)client, state); + client->isfloating = state; + arrange(client->monitor); +} + +Client * +selected_client(void) +{ + Client *client = wl_container_of(server.client.focus.next, client, focus); + if(wl_list_empty(&server.client.focus) || !VISIBLE_ON(client, server.monitor.selected)) + return nil; + return client; +} diff --git a/sys/cmd/wm/config.h b/sys/cmd/wm/config.h index d44b45f..752c6b7 100644 --- a/sys/cmd/wm/config.h +++ b/sys/cmd/wm/config.h @@ -59,9 +59,9 @@ CONFIG(Key*, endbinding, arrend(cfg·binding)); /* mouse buttons */ CONFIG(Button, button[], { - { MODKEY, BTN_LEFT, move_client, {.ui = CursorMove} }, + { MODKEY, BTN_LEFT, move_client, {0} }, { MODKEY, BTN_MIDDLE, float_client, {0} }, - { MODKEY, BTN_RIGHT, resize_client, {.ui = CursorResize} }, + { MODKEY, BTN_RIGHT, resize_client, {0} }, }); CONFIG(Button*, endbutton, arrend(cfg·button)); diff --git a/sys/cmd/wm/input.c b/sys/cmd/wm/input.c index eb5fdd1..93bdc50 100644 --- a/sys/cmd/wm/input.c +++ b/sys/cmd/wm/input.c @@ -61,11 +61,12 @@ free_keyboard(struct wl_listener *l, void *data) struct wlr_input_device *device = data; Keyboard *keyboard = device->data; - /* + /* XXX: debug 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); */ } @@ -78,6 +79,9 @@ make_keyboard(struct wlr_input_device *device) struct xkb_context *context; struct xkb_keymap *keymap; + keyboard = device->data = calloc(1, sizeof(*keyboard)); + keyboard->device = device; + context = xkb_context_new(XKB_CONTEXT_NO_FLAGS); keymap = xkb_keymap_new_from_names(context, nil, XKB_KEYMAP_COMPILE_NO_FLAGS); @@ -88,9 +92,6 @@ make_keyboard(struct wlr_input_device *device) 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); @@ -101,6 +102,7 @@ make_keyboard(struct wlr_input_device *device) 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); } @@ -144,6 +146,7 @@ move(uint32 time) { double sx, sy; Client *client; + struct wlr_box box; struct wlr_surface *surface; if(time) { @@ -164,17 +167,18 @@ move(uint32 time) } if(server.cursor.mode == CursorResize) { + wlr_xdg_surface_get_geometry(server.grab.client->xdg, &box); resize(server.grab.client, - server.cursor.dot->x, - server.cursor.dot->y, - server.grab.client->geometry.width, - server.grab.client->geometry.height, + server.grab.box.x - box.x, + server.grab.box.y - box.y, + server.cursor.dot->x - server.grab.x - server.grab.box.x, + server.cursor.dot->y - server.grab.y - server.grab.box.y, 1 ); return; } - /* Otherwise, find the client under the pointer and send the event along. */ + /* otherwise, find the client under the pointer and send the event along. */ client = client_at(server.cursor.dot->x, server.cursor.dot->y); if(!client) { wlr_xcursor_manager_set_cursor_image(server.cursor.manager, "left_ptr", server.cursor.dot); diff --git a/sys/cmd/wm/wm.h b/sys/cmd/wm/wm.h index 2e9ea9f..bc898b1 100644 --- a/sys/cmd/wm/wm.h +++ b/sys/cmd/wm/wm.h @@ -290,14 +290,16 @@ 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); +void floating(Client *, int); +Client *selected_client(void); Client *client_at(double x, double y); struct wlr_surface *client_surface_at(Client *, double cx, double cy, double *sx, double *sy); struct wlr_surface *top_surface(Client *); -void *move_client(Arg *arg); -void *float_client(Arg *arg); -void *resize_client(Arg *arg); +void move_client(Arg *arg); +void float_client(Arg *arg); +void resize_client(Arg *arg); /* monitor.c */ void tile(Monitor *); -- cgit v1.2.1