#include "dwm.h" /* local callbacks */ static void scroll(struct wl_listener *ev, void *arg); static void frame(struct wl_listener *ev, void *arg); static void click(struct wl_listener *ev, void *arg); static void relmove(struct wl_listener *ev, void *arg); static void absmove(struct wl_listener *ev, void *arg); static void setcursor(struct wl_listener *ev, void *arg); static void setsel(struct wl_listener *ev, void *arg); static void setpsel(struct wl_listener *ev, void *arg); static void keypress(struct wl_listener *ev, void *arg); static void modifier(struct wl_listener *ev, void *arg); /* global variables */ Mouse mouse = { .mode = 0, .manager = nil, .cursor = nil, .ev = { .axis = {.notify=scroll}, .button = {.notify=click}, .frame = {.notify=frame}, .motion = {.notify=relmove}, .absmotion = {.notify=absmove}, .cursor = {.notify=setcursor}, .sel = {.notify=setsel}, .psel = {.notify=setpsel}, }, }; Grab grab = { 0 }; // ----------------------------------------------------------------------- // callback function implementations /* input devices */ static void newkeyboard(struct wlr_input_device *dev) { Keyboard *kb; struct xkb_context *ctx; struct xkb_keymap *map; kb = dev->data = calloc(1, sizeof(*kb)); kb->dev = dev; ctx = xkb_context_new(XKB_CONTEXT_NO_FLAGS); map = xkb_map_new_from_names(ctx, &xkb_rules, XKB_KEYMAP_COMPILE_NO_FLAGS); wlr_keyboard_set_keymap(dev->keyboard, map); xkb_keymap_unref(map); xkb_context_unref(ctx); wlr_keyboard_set_repeat_info(dev->keyboard, 25, 600); /* install callbacks */ kb->ev.modifier.notify = modifier; kb->ev.keypress.notify = keypress; wl_signal_add(&dev->keyboard->events.modifiers, &kb->ev.modifier); wl_signal_add(&dev->keyboard->events.key, &kb->ev.keypress); /* NOTE: we only look at the last keyboard given right now */ wlr_seat_set_keyboard(dwm.seat, dev); wl_list_insert(&dwm.keyboards, &kb->link); } static void newmouse(struct wlr_input_device *dev) { /* NOTE: we only look at one mouse right now */ wlr_cursor_attach_input_device(mouse.cursor, dev); } void ev·newinput(struct wl_listener *ev, void *arg) { uint32 c; struct wlr_input_device *dev; dev = arg; switch (dev->type) { case WLR_INPUT_DEVICE_KEYBOARD: newkeyboard(dev); break; case WLR_INPUT_DEVICE_POINTER: newmouse(dev); break; default: ; } c = WL_SEAT_CAPABILITY_POINTER; if (!wl_list_empty(&dwm.keyboards)) c |= WL_SEAT_CAPABILITY_KEYBOARD; wlr_seat_set_capabilities(dwm.seat, c); } /* mouse input */ static void scroll(struct wl_listener *ev, void *arg) { struct wlr_event_pointer_axis *axis; axis = arg; wlr_seat_pointer_notify_axis(dwm.seat, axis->time_msec, axis->orientation, axis->delta, axis->delta_discrete, axis->source); } void click(struct wl_listener *ev, void *arg) { uint32 mods; Client *c; const Button *b; struct wlr_surface *surf; struct wlr_keyboard *keyb; struct wlr_event_pointer_button *button; button = arg; switch (button->state) { case WLR_BUTTON_PRESSED: if ((c = clientat(mouse.cursor->x, mouse.cursor->y))) { surf = wlr_xdg_surface_surface_at(c->surf, mouse.cursor->x - c->dim.x - c->bw, mouse.cursor->y - c->dim.y - c->bw, nil, nil ); setfocus(c, surf, 1); } keyb = wlr_seat_get_keyboard(dwm.seat); mods = wlr_keyboard_get_modifiers(keyb); for (b = buttons; b < arrend(buttons); b++) { if (CLEANMASK(mods) == CLEANMASK(b->mod) && button->button == b->kind && b->func) { b->func(&b->arg); return; } } break; case WLR_BUTTON_RELEASED: if (mouse.mode != MouseNormal) { wlr_xcursor_manager_set_cursor_image(mouse.manager, "left_ptr", mouse.cursor); mouse.mode = MouseNormal; monitor = monitorat(mouse.cursor->x, mouse.cursor->y); setmonitor(grab.c, monitor, 0); } } wlr_seat_pointer_notify_button(dwm.seat, button->time_msec, button->button, button->state); } static void frame(struct wl_listener *ev, void *arg) { wlr_seat_pointer_notify_frame(dwm.seat); } static void notify(uint32 time) { Client *c; double sx, sy; struct wlr_surface *surf; if (sloppyfocus) monitor = monitorat(mouse.cursor->x, mouse.cursor->y); switch (mouse.mode) { case MouseMove: resize(grab.c, mouse.cursor->x - grab.x, mouse.cursor->y - grab.y, grab.c->dim.width, grab.c->dim.height, 1); return; case MouseResize: resize(grab.c, grab.c->dim.x, grab.c->dim.y, mouse.cursor->x - grab.c->dim.x, mouse.cursor->y - grab.c->dim.y, 1); return; case MouseNormal: default: ; } surf = nil; if ((c = clientat(mouse.cursor->x, mouse.cursor->y))) surf = wlr_xdg_surface_surface_at(c->surf, mouse.cursor->x - c->dim.x - c->bw, mouse.cursor->y - c->dim.y - c->bw, &sx, &sy); if (!surf) wlr_xcursor_manager_set_cursor_image(mouse.manager, "left_ptr", mouse.cursor); pointerfocus(c, surf, sx, sy, time); } static void relmove(struct wl_listener *ev, void *arg) { struct wlr_event_pointer_motion *mv; mv = arg; wlr_cursor_move(mouse.cursor, mv->device, mv->delta_x, mv->delta_y); notify(mv->time_msec); } static void absmove(struct wl_listener *ev, void *arg) { struct wlr_event_pointer_motion_absolute *mv; mv = arg; wlr_cursor_warp_absolute(mouse.cursor, mv->device, mv->x, mv->y); notify(mv->time_msec); } /* cursor images */ static void setcursor(struct wl_listener *ev, void *arg) { struct wlr_seat_pointer_request_set_cursor_event *cur; cur = arg; if (mouse.mode != MouseNormal) return; if (cur->seat_client == dwm.seat->pointer_state.focused_client) wlr_cursor_set_surface(mouse.cursor, cur->surface, cur->hotspot_x, cur->hotspot_y); } static void setpsel(struct wl_listener *ev, void *arg) { struct wlr_seat_request_set_primary_selection_event *psel; psel = arg; wlr_seat_set_primary_selection(dwm.seat, psel->source, psel->serial); } static void setsel(struct wl_listener *ev, void *arg) { struct wlr_seat_request_set_selection_event *sel; sel = arg; wlr_seat_set_selection(dwm.seat, sel->source, sel->serial); } /* keyboards */ static int dokey(uint32 mods, xkb_keysym_t sym) { int h; const Key *k, *e; h = 0; for (k = keys, e = arrend(keys); k < e; k++) if (CLEANMASK(mods) == CLEANMASK(k->mod) && sym == k->sym && k->func) { k->func(&k->arg); h = 1; } return h; } static void modifier(struct wl_listener *ev, void *arg) { Keyboard *kb; kb = wl_container_of(ev, kb, ev.modifier); wlr_seat_set_keyboard(dwm.seat, kb->dev); wlr_seat_keyboard_notify_modifiers(dwm.seat, &kb->dev->keyboard->modifiers); } static void keypress(struct wl_listener *ev, void *arg) { Keyboard *kb; int i, n, hit; uint32 code, mods; const xkb_keysym_t *syms; struct wlr_event_keyboard_key *key; key = arg; kb = wl_container_of(ev, kb, ev.keypress); code = key->keycode + 8; n = xkb_state_key_get_syms(kb->dev->keyboard->xkb_state, code, &syms); mods = wlr_keyboard_get_modifiers(kb->dev->keyboard); hit = 0; if (key->state == WLR_KEY_PRESSED) for (i = 0; i < n; i++) hit += dokey(mods, syms[i]); /* if no binding found, pass the event to the client */ if (!hit) { wlr_seat_set_keyboard(dwm.seat, kb->dev); wlr_seat_keyboard_notify_key(dwm.seat, key->time_msec, key->keycode, key->state); } }