|
|
@ -34,11 +34,15 @@ struct wlr_cursor_device {
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
struct wlr_cursor_state {
|
|
|
|
struct wlr_cursor_state {
|
|
|
|
|
|
|
|
struct wlr_cursor *cursor;
|
|
|
|
struct wl_list devices;
|
|
|
|
struct wl_list devices;
|
|
|
|
struct wlr_output_layout *layout;
|
|
|
|
struct wlr_output_layout *layout;
|
|
|
|
struct wlr_xcursor *xcursor;
|
|
|
|
struct wlr_xcursor *xcursor;
|
|
|
|
struct wlr_output *mapped_output;
|
|
|
|
struct wlr_output *mapped_output;
|
|
|
|
struct wlr_box *mapped_box;
|
|
|
|
struct wlr_box *mapped_box;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
struct wl_listener layout_change;
|
|
|
|
|
|
|
|
struct wl_listener layout_destroy;
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
struct wlr_cursor *wlr_cursor_create() {
|
|
|
|
struct wlr_cursor *wlr_cursor_create() {
|
|
|
@ -55,6 +59,7 @@ struct wlr_cursor *wlr_cursor_create() {
|
|
|
|
return NULL;
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
cur->state->cursor = cur;
|
|
|
|
cur->state->mapped_output = NULL;
|
|
|
|
cur->state->mapped_output = NULL;
|
|
|
|
|
|
|
|
|
|
|
|
wl_list_init(&cur->state->devices);
|
|
|
|
wl_list_init(&cur->state->devices);
|
|
|
@ -83,7 +88,20 @@ struct wlr_cursor *wlr_cursor_create() {
|
|
|
|
return cur;
|
|
|
|
return cur;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static void wlr_cursor_detach_output_layout(struct wlr_cursor *cur) {
|
|
|
|
|
|
|
|
if (!cur->state->layout) {
|
|
|
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
wl_list_remove(&cur->state->layout_destroy.link);
|
|
|
|
|
|
|
|
wl_list_remove(&cur->state->layout_change.link);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
cur->state->layout = NULL;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void wlr_cursor_destroy(struct wlr_cursor *cur) {
|
|
|
|
void wlr_cursor_destroy(struct wlr_cursor *cur) {
|
|
|
|
|
|
|
|
wlr_cursor_detach_output_layout(cur);
|
|
|
|
|
|
|
|
|
|
|
|
struct wlr_cursor_device *device, *device_tmp = NULL;
|
|
|
|
struct wlr_cursor_device *device, *device_tmp = NULL;
|
|
|
|
wl_list_for_each_safe(device, device_tmp, &cur->state->devices, link) {
|
|
|
|
wl_list_for_each_safe(device, device_tmp, &cur->state->devices, link) {
|
|
|
|
wl_list_remove(&device->link);
|
|
|
|
wl_list_remove(&device->link);
|
|
|
@ -430,8 +448,42 @@ void wlr_cursor_detach_input_device(struct wlr_cursor *cur,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static void handle_layout_destroy(struct wl_listener *listener, void *data) {
|
|
|
|
|
|
|
|
struct wlr_cursor_state *state =
|
|
|
|
|
|
|
|
wl_container_of(listener, state, layout_change);
|
|
|
|
|
|
|
|
wlr_cursor_detach_output_layout(state->cursor);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static void handle_layout_change(struct wl_listener *listener, void *data) {
|
|
|
|
|
|
|
|
struct wlr_cursor_state *state =
|
|
|
|
|
|
|
|
wl_container_of(listener, state, layout_change);
|
|
|
|
|
|
|
|
struct wlr_output_layout *layout = data;
|
|
|
|
|
|
|
|
if (!wlr_output_layout_contains_point(layout, NULL, state->cursor->x,
|
|
|
|
|
|
|
|
state->cursor->y)) {
|
|
|
|
|
|
|
|
// the output we were on has gone away so go to the closest boundary
|
|
|
|
|
|
|
|
// point
|
|
|
|
|
|
|
|
double x, y;
|
|
|
|
|
|
|
|
wlr_output_layout_closest_point(layout, NULL, state->cursor->x,
|
|
|
|
|
|
|
|
state->cursor->y, &x, &y);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
wlr_cursor_warp_unchecked(state->cursor, x, y);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void wlr_cursor_attach_output_layout(struct wlr_cursor *cur,
|
|
|
|
void wlr_cursor_attach_output_layout(struct wlr_cursor *cur,
|
|
|
|
struct wlr_output_layout *l) {
|
|
|
|
struct wlr_output_layout *l) {
|
|
|
|
|
|
|
|
wlr_cursor_detach_output_layout(cur);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (l == NULL) {
|
|
|
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
wl_signal_add(&l->events.change, &cur->state->layout_change);
|
|
|
|
|
|
|
|
cur->state->layout_change.notify = handle_layout_change;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
wl_signal_add(&l->events.destroy, &cur->state->layout_destroy);
|
|
|
|
|
|
|
|
cur->state->layout_destroy.notify = handle_layout_destroy;
|
|
|
|
|
|
|
|
|
|
|
|
cur->state->layout = l;
|
|
|
|
cur->state->layout = l;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|