aboutsummaryrefslogtreecommitdiff
path: root/sys/cmd/wm/client.c
blob: 7d828a0260a126a7eff690018f3a3e1eddac017d (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
#include "wm.h"

void
focus(Client *client, struct wlr_surface *new)
{
    struct wlr_seat        *seat;
    struct wlr_surface     *old;
    struct wlr_xdg_surface *xdg;
    struct wlr_keyboard    *keyboard;

    if(!client)
        return;

    seat = server.input.seat;
    old  = seat->keyboard_state.focused_surface;
    if(old == new)
        return;

    if(old) {
        xdg = wlr_xdg_surface_from_wlr_surface(seat->keyboard_state.focused_surface);
        wlr_xdg_toplevel_set_activated(xdg, false);
    }

    keyboard = wlr_seat_get_keyboard(seat);

    wl_list_remove(&client->link);
    wl_list_insert(&server.clients, &client->link);

    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)
{
    double x, y, vsx = lx - client->x, vsy = ly - client->y;
    struct wlr_surface *find = nil;

    find = wlr_xdg_surface_surface_at(client->xdg, vsx, vsy, &x, &y);
    if(find) {
        *sx = x;
        *sy = y;
        *surface = find;
        return true;
    }

    return false;
}

Client*
clientat(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))
            return it;
    }

    return nil;
}

void
setinteractive(Client *client, int mode, uint32 edges) {
    double bx, by;
    struct wlr_box box;
    struct wlr_surface *focused = server.input.seat->pointer_state.focused_surface;

    if(client->xdg->surface != focused)
        return;

    server.grab.client = client;
    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;
    } 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);

        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.resize = edges;
    }
}