From 8e40c83799ba2a153f6b74079a1acfa1d3e22834 Mon Sep 17 00:00:00 2001 From: Simon Ser Date: Thu, 6 Apr 2023 12:33:12 +0200 Subject: [PATCH] cursor: add outputs_update event This is necessary for supporting e.g. fractional-scale-v1 for cursor surfaces. --- include/wlr/types/wlr_cursor.h | 7 ++++++ types/wlr_cursor.c | 40 ++++++++++++++++++++++++++++++++++ 2 files changed, 47 insertions(+) diff --git a/include/wlr/types/wlr_cursor.h b/include/wlr/types/wlr_cursor.h index 06ae2f1f0..88aa203fe 100644 --- a/include/wlr/types/wlr_cursor.h +++ b/include/wlr/types/wlr_cursor.h @@ -29,6 +29,11 @@ struct wlr_input_device; struct wlr_box; struct wlr_cursor_state; +struct wlr_cursor_outputs_update_event { + struct wlr_output *const *outputs; + size_t outputs_len; +}; + struct wlr_cursor { struct wlr_cursor_state *state; double x, y; @@ -72,6 +77,8 @@ struct wlr_cursor { struct wl_signal tablet_tool_proximity; struct wl_signal tablet_tool_tip; struct wl_signal tablet_tool_button; + + struct wl_signal outputs_update; // struct wlr_cursor_outputs_update_event } events; void *data; diff --git a/types/wlr_cursor.c b/types/wlr_cursor.c index 46a196df3..de77ad349 100644 --- a/types/wlr_cursor.c +++ b/types/wlr_cursor.c @@ -67,6 +67,9 @@ struct wlr_cursor_state { struct wl_listener layout_add; struct wl_listener layout_change; struct wl_listener layout_destroy; + + struct wl_array outputs; + uint64_t prev_output_mask; }; struct wlr_cursor *wlr_cursor_create(void) { @@ -117,6 +120,8 @@ struct wlr_cursor *wlr_cursor_create(void) { wl_signal_init(&cur->events.tablet_tool_button); wl_signal_init(&cur->events.tablet_tool_proximity); + wl_signal_init(&cur->events.outputs_update); + cur->x = 100; cur->y = 100; @@ -128,6 +133,7 @@ static void output_cursor_destroy( wl_list_remove(&output_cursor->layout_output_destroy.link); wl_list_remove(&output_cursor->link); wlr_output_cursor_destroy(output_cursor->output_cursor); + output_cursor->cursor->state->prev_output_mask = 0; free(output_cursor); } @@ -191,6 +197,7 @@ void wlr_cursor_destroy(struct wlr_cursor *cur) { cursor_device_destroy(device); } + wl_array_release(&cur->state->outputs); free(cur->state); free(cur); } @@ -216,6 +223,10 @@ static void cursor_warp_unchecked(struct wlr_cursor *cur, return; } + assert(cur->state->outputs.size == 0); + + size_t i = 0; + uint64_t output_mask = 0; struct wlr_cursor_output_cursor *output_cursor; wl_list_for_each(output_cursor, &cur->state->output_cursors, link) { double output_x = lx, output_y = ly; @@ -223,8 +234,36 @@ static void cursor_warp_unchecked(struct wlr_cursor *cur, output_cursor->output_cursor->output, &output_x, &output_y); wlr_output_cursor_move(output_cursor->output_cursor, output_x, output_y); + + assert(i < 64); + uint64_t output_bit = 1 << i; + i++; + + if (!output_cursor->output_cursor->visible) { + continue; + } + + output_mask |= output_bit; + + struct wlr_output **output_ptr = + wl_array_add(&cur->state->outputs, sizeof(struct wlr_output *)); + if (output_ptr == NULL) { + wlr_log_errno(WLR_ERROR, "Allocation failed"); + break; + } + *output_ptr = output_cursor->output_cursor->output; } + if (output_mask != cur->state->prev_output_mask) { + struct wlr_cursor_outputs_update_event event = { + .outputs = cur->state->outputs.data, + .outputs_len = cur->state->outputs.size / sizeof(struct wlr_output *), + }; + wl_signal_emit_mutable(&cur->events.outputs_update, &event); + cur->state->prev_output_mask = output_mask; + } + cur->state->outputs.size = 0; + cur->x = lx; cur->y = ly; } @@ -814,6 +853,7 @@ static void layout_add(struct wlr_cursor_state *state, &output_cursor->layout_output_destroy); wl_list_insert(&state->output_cursors, &output_cursor->link); + state->prev_output_mask = 0; } static void handle_layout_add(struct wl_listener *listener, void *data) {