aboutsummaryrefslogtreecommitdiff
path: root/sys/cmd/wm/client.c
blob: 33dfcb146ed47017ed81181bd9834934ce3617ab (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
96
97
98
99
100
101
102
#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) {
        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)
        return;

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

    if(!client) {
        wlr_seat_keyboard_notify_clear_focus(seat);
        return;
    }

    keyboard = wlr_seat_get_keyboard(seat);

    wlr_seat_keyboard_notify_enter(seat, client->xdg->surface,
        keyboard->keycodes,
        keyboard->num_keycodes,
        &keyboard->modifiers
    );

    wlr_xdg_toplevel_set_activated(client->xdg, true);
}

int
client_has(Client *client, double lx, double ly, struct wlr_surface **surface, double *sx, double *sy)
{
    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);
    if(find) {
        *sx = x;
        *sy = y;
        *surface = find;
        return true;
    }

    return false;
}

Client*
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(client_has(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->geo.x;
        server.grab.y = server.cursor.dot->y - client->geo.y;
    } else {
        wlr_xdg_surface_get_geometry(client->xdg, &box);

        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->geo.x;
        server.grab.box.y += client->geo.y;

        server.resize = edges;
    }
}