swaybar: process hotspots on touch tap
This commit is contained in:
parent
512619a9a1
commit
4599907de7
|
@ -34,6 +34,7 @@ struct swaybar {
|
||||||
|
|
||||||
struct swaybar_config *config;
|
struct swaybar_config *config;
|
||||||
struct swaybar_pointer pointer;
|
struct swaybar_pointer pointer;
|
||||||
|
struct swaybar_touch touch;
|
||||||
struct status_line *status;
|
struct status_line *status;
|
||||||
|
|
||||||
struct loop *eventloop;
|
struct loop *eventloop;
|
||||||
|
|
|
@ -22,6 +22,19 @@ struct swaybar_pointer {
|
||||||
uint32_t serial;
|
uint32_t serial;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct touch_slot {
|
||||||
|
int32_t id;
|
||||||
|
uint32_t time;
|
||||||
|
struct swaybar_output *output;
|
||||||
|
double start_x, start_y;
|
||||||
|
double x, y;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct swaybar_touch {
|
||||||
|
struct wl_touch *touch;
|
||||||
|
struct touch_slot slots[16];
|
||||||
|
};
|
||||||
|
|
||||||
enum hotspot_event_handling {
|
enum hotspot_event_handling {
|
||||||
HOTSPOT_IGNORE,
|
HOTSPOT_IGNORE,
|
||||||
HOTSPOT_PROCESS,
|
HOTSPOT_PROCESS,
|
||||||
|
|
139
swaybar/input.c
139
swaybar/input.c
|
@ -123,6 +123,23 @@ static bool check_bindings(struct swaybar *bar, uint32_t button,
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void process_hotspots(struct swaybar_output *output,
|
||||||
|
double x, double y, uint32_t button) {
|
||||||
|
x *= output->scale;
|
||||||
|
y *= output->scale;
|
||||||
|
struct swaybar_hotspot *hotspot;
|
||||||
|
wl_list_for_each(hotspot, &output->hotspots, link) {
|
||||||
|
if (x >= hotspot->x && y >= hotspot->y
|
||||||
|
&& x < hotspot->x + hotspot->width
|
||||||
|
&& y < hotspot->y + hotspot->height) {
|
||||||
|
if (HOTSPOT_IGNORE == hotspot->callback(output, hotspot,
|
||||||
|
x / output->scale, y / output->scale, button, hotspot->data)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void wl_pointer_button(void *data, struct wl_pointer *wl_pointer,
|
static void wl_pointer_button(void *data, struct wl_pointer *wl_pointer,
|
||||||
uint32_t serial, uint32_t time, uint32_t button, uint32_t state) {
|
uint32_t serial, uint32_t time, uint32_t button, uint32_t state) {
|
||||||
struct swaybar *bar = data;
|
struct swaybar *bar = data;
|
||||||
|
@ -139,20 +156,7 @@ static void wl_pointer_button(void *data, struct wl_pointer *wl_pointer,
|
||||||
if (state != WL_POINTER_BUTTON_STATE_PRESSED) {
|
if (state != WL_POINTER_BUTTON_STATE_PRESSED) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
struct swaybar_hotspot *hotspot;
|
process_hotspots(output, pointer->x, pointer->y, button);
|
||||||
wl_list_for_each(hotspot, &output->hotspots, link) {
|
|
||||||
double x = pointer->x * output->scale;
|
|
||||||
double y = pointer->y * output->scale;
|
|
||||||
if (x >= hotspot->x
|
|
||||||
&& y >= hotspot->y
|
|
||||||
&& x < hotspot->x + hotspot->width
|
|
||||||
&& y < hotspot->y + hotspot->height) {
|
|
||||||
if (HOTSPOT_IGNORE == hotspot->callback(output, hotspot,
|
|
||||||
pointer->x, pointer->y, button, hotspot->data)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void wl_pointer_axis(void *data, struct wl_pointer *wl_pointer,
|
static void wl_pointer_axis(void *data, struct wl_pointer *wl_pointer,
|
||||||
|
@ -255,7 +259,7 @@ static void wl_pointer_axis_discrete(void *data, struct wl_pointer *wl_pointer,
|
||||||
// Who cares
|
// Who cares
|
||||||
}
|
}
|
||||||
|
|
||||||
struct wl_pointer_listener pointer_listener = {
|
static struct wl_pointer_listener pointer_listener = {
|
||||||
.enter = wl_pointer_enter,
|
.enter = wl_pointer_enter,
|
||||||
.leave = wl_pointer_leave,
|
.leave = wl_pointer_leave,
|
||||||
.motion = wl_pointer_motion,
|
.motion = wl_pointer_motion,
|
||||||
|
@ -267,6 +271,107 @@ struct wl_pointer_listener pointer_listener = {
|
||||||
.axis_discrete = wl_pointer_axis_discrete,
|
.axis_discrete = wl_pointer_axis_discrete,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static struct touch_slot *get_touch_slot(struct swaybar_touch *touch, int32_t id) {
|
||||||
|
int next = -1;
|
||||||
|
for (size_t i = 0; i < sizeof(touch->slots) / sizeof(*touch->slots); ++i) {
|
||||||
|
if (touch->slots[i].id == id) {
|
||||||
|
return &touch->slots[i];
|
||||||
|
}
|
||||||
|
if (next == -1 && !touch->slots[i].output) {
|
||||||
|
next = i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (next == -1) {
|
||||||
|
sway_log(SWAY_ERROR, "Ran out of touch slots");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
return &touch->slots[next];
|
||||||
|
}
|
||||||
|
|
||||||
|
static void wl_touch_down(void *data, struct wl_touch *wl_touch,
|
||||||
|
uint32_t serial, uint32_t time, struct wl_surface *surface,
|
||||||
|
int32_t id, wl_fixed_t _x, wl_fixed_t _y) {
|
||||||
|
struct swaybar *bar = data;
|
||||||
|
struct swaybar_output *_output, *output;
|
||||||
|
wl_list_for_each(_output, &bar->outputs, link) {
|
||||||
|
if (_output->surface == surface) {
|
||||||
|
output = _output;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!output) {
|
||||||
|
sway_log(SWAY_DEBUG, "Got touch event for unknown surface");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
struct touch_slot *slot = get_touch_slot(&bar->touch, id);
|
||||||
|
if (!slot) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
slot->id = id;
|
||||||
|
slot->output = output;
|
||||||
|
slot->x = slot->start_x = wl_fixed_to_double(_x);
|
||||||
|
slot->y = slot->start_y = wl_fixed_to_double(_y);
|
||||||
|
slot->time = time;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void wl_touch_up(void *data, struct wl_touch *wl_touch,
|
||||||
|
uint32_t serial, uint32_t time, int32_t id) {
|
||||||
|
struct swaybar *bar = data;
|
||||||
|
struct touch_slot *slot = get_touch_slot(&bar->touch, id);
|
||||||
|
if (!slot) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (time - slot->time < 500) {
|
||||||
|
// Tap, treat it like a pointer click
|
||||||
|
process_hotspots(slot->output, slot->x, slot->y, BTN_LEFT);
|
||||||
|
}
|
||||||
|
slot->output = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void wl_touch_motion(void *data, struct wl_touch *wl_touch,
|
||||||
|
uint32_t time, int32_t id, wl_fixed_t x, wl_fixed_t y) {
|
||||||
|
struct swaybar *bar = data;
|
||||||
|
struct touch_slot *slot = get_touch_slot(&bar->touch, id);
|
||||||
|
if (!slot) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
slot->x = wl_fixed_to_double(x);
|
||||||
|
slot->y = wl_fixed_to_double(y);
|
||||||
|
// TODO: Slide gestures
|
||||||
|
}
|
||||||
|
|
||||||
|
static void wl_touch_frame(void *data, struct wl_touch *wl_touch) {
|
||||||
|
// Who cares
|
||||||
|
}
|
||||||
|
|
||||||
|
static void wl_touch_cancel(void *data, struct wl_touch *wl_touch) {
|
||||||
|
struct swaybar *bar = data;
|
||||||
|
struct swaybar_touch *touch = &bar->touch;
|
||||||
|
for (size_t i = 0; i < sizeof(touch->slots) / sizeof(*touch->slots); ++i) {
|
||||||
|
touch->slots[i].output = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void wl_touch_shape(void *data, struct wl_touch *wl_touch, int32_t id,
|
||||||
|
wl_fixed_t major, wl_fixed_t minor) {
|
||||||
|
// Who cares
|
||||||
|
}
|
||||||
|
|
||||||
|
static void wl_touch_orientation(void *data, struct wl_touch *wl_touch,
|
||||||
|
int32_t id, wl_fixed_t orientation) {
|
||||||
|
// Who cares
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct wl_touch_listener touch_listener = {
|
||||||
|
.down = wl_touch_down,
|
||||||
|
.up = wl_touch_up,
|
||||||
|
.motion = wl_touch_motion,
|
||||||
|
.frame = wl_touch_frame,
|
||||||
|
.cancel = wl_touch_cancel,
|
||||||
|
.shape = wl_touch_shape,
|
||||||
|
.orientation = wl_touch_orientation,
|
||||||
|
};
|
||||||
|
|
||||||
static void seat_handle_capabilities(void *data, struct wl_seat *wl_seat,
|
static void seat_handle_capabilities(void *data, struct wl_seat *wl_seat,
|
||||||
enum wl_seat_capability caps) {
|
enum wl_seat_capability caps) {
|
||||||
struct swaybar *bar = data;
|
struct swaybar *bar = data;
|
||||||
|
@ -278,6 +383,10 @@ static void seat_handle_capabilities(void *data, struct wl_seat *wl_seat,
|
||||||
bar->pointer.pointer = wl_seat_get_pointer(wl_seat);
|
bar->pointer.pointer = wl_seat_get_pointer(wl_seat);
|
||||||
wl_pointer_add_listener(bar->pointer.pointer, &pointer_listener, bar);
|
wl_pointer_add_listener(bar->pointer.pointer, &pointer_listener, bar);
|
||||||
}
|
}
|
||||||
|
if ((caps & WL_SEAT_CAPABILITY_TOUCH)) {
|
||||||
|
bar->touch.touch = wl_seat_get_touch(wl_seat);
|
||||||
|
wl_touch_add_listener(bar->touch.touch, &touch_listener, bar);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void seat_handle_name(void *data, struct wl_seat *wl_seat,
|
static void seat_handle_name(void *data, struct wl_seat *wl_seat,
|
||||||
|
|
Loading…
Reference in a new issue