From d37572486b12bd28babba40b299cb2594a3635fa Mon Sep 17 00:00:00 2001 From: Alexander Orzechowski Date: Sat, 19 Nov 2022 22:38:50 -0500 Subject: [PATCH] backend/wayland: handle scale --- backend/wayland/output.c | 43 +++++++++++++++++++++++++++------------ backend/wayland/pointer.c | 5 +++-- backend/wayland/seat.c | 5 +++-- 3 files changed, 36 insertions(+), 17 deletions(-) diff --git a/backend/wayland/output.c b/backend/wayland/output.c index 88dca06be..db14a1d41 100644 --- a/backend/wayland/output.c +++ b/backend/wayland/output.c @@ -293,6 +293,12 @@ static bool output_commit(struct wlr_output *wlr_output, return false; } + bool needs_commit = false; + if (state->committed & WLR_OUTPUT_STATE_SCALE) { + wl_surface_set_buffer_scale(output->surface, ceil(state->scale)); + needs_commit = true; + } + if (state->committed & WLR_OUTPUT_STATE_BUFFER) { if (output->requested.needs_ack) { output->requested.needs_ack = false; @@ -340,7 +346,7 @@ static bool output_commit(struct wlr_output *wlr_output, } } - wl_surface_commit(output->surface); + needs_commit = true; if (wp_feedback != NULL) { struct wlr_wl_presentation_feedback *feedback = @@ -365,6 +371,10 @@ static bool output_commit(struct wlr_output *wlr_output, } } + if (needs_commit) { + wl_surface_commit(output->surface); + } + wl_display_flush(output->backend->remote_display); if (state->committed & WLR_OUTPUT_STATE_MODE) { @@ -463,22 +473,17 @@ void update_wl_output_cursor(struct wlr_wl_output *output) { return; } - struct wlr_wl_buffer *buffer = - get_or_create_wl_buffer(output->backend, output->cursor.buffer); - if (!buffer) { - return; - } - - wl_surface_attach(surface, buffer->wl_buffer, 0, 0); + int scale = ceil(output->wlr_output.scale); wl_surface_damage_buffer(surface, 0, 0, INT32_MAX, INT32_MAX); + wl_surface_set_buffer_scale(surface, scale); wl_surface_commit(surface); wl_display_flush(backend->remote_display); struct wlr_wl_seat *seat = pointer->seat; wl_pointer_set_cursor(seat->wl_pointer, output->enter_serial, - output->cursor.surface, output->cursor.hotspot_x, - output->cursor.hotspot_y); + output->cursor.surface, output->cursor.hotspot_x / scale, + output->cursor.hotspot_y / scale); } static bool output_move_cursor(struct wlr_output *_output, int x, int y) { @@ -505,16 +510,28 @@ void surface_update(struct wlr_wl_output *output) { return; } + uint32_t scale = 1; + + struct wlr_wl_active_remote_output *active; + wl_list_for_each(active, &output->active_remote_outputs, link) { + struct wlr_wl_remote_output *output = active->remote_output; + if (scale < output->scale) { + scale = output->scale; + } + } + struct wlr_output_state state = { - .committed = WLR_OUTPUT_STATE_MODE, + .committed = WLR_OUTPUT_STATE_MODE | WLR_OUTPUT_STATE_SCALE, .mode_type = WLR_OUTPUT_STATE_MODE_CUSTOM, + .scale = scale, .custom_mode = { - .width = output->requested.width, - .height = output->requested.height + .width = output->requested.width * scale, + .height = output->requested.height * scale }, }; wlr_output_send_request_state(&output->wlr_output, &state); + update_wl_output_cursor(output); } static void xdg_surface_handle_configure(void *data, diff --git a/backend/wayland/pointer.c b/backend/wayland/pointer.c index 4ce233e52..f50f6600f 100644 --- a/backend/wayland/pointer.c +++ b/backend/wayland/pointer.c @@ -87,11 +87,12 @@ static void pointer_handle_motion(void *data, struct wl_pointer *wl_pointer, } struct wlr_output *wlr_output = &pointer->output->wlr_output; + int scale = ceil(wlr_output->scale); struct wlr_pointer_motion_absolute_event event = { .pointer = &pointer->wlr_pointer, .time_msec = time, - .x = wl_fixed_to_double(sx) / wlr_output->width, - .y = wl_fixed_to_double(sy) / wlr_output->height, + .x = wl_fixed_to_double(sx) * scale / wlr_output->width, + .y = wl_fixed_to_double(sy) * scale / wlr_output->height, }; wl_signal_emit_mutable(&pointer->wlr_pointer.events.motion_absolute, &event); } diff --git a/backend/wayland/seat.c b/backend/wayland/seat.c index a64795a8c..ff28c2f61 100644 --- a/backend/wayland/seat.c +++ b/backend/wayland/seat.c @@ -127,8 +127,9 @@ static void touch_coordinates_to_absolute(struct wlr_wl_seat *seat, */ struct wlr_wl_output *output, *tmp; wl_list_for_each_safe(output, tmp, &seat->backend->outputs, link) { - *sx = wl_fixed_to_double(x) / output->wlr_output.width; - *sy = wl_fixed_to_double(y) / output->wlr_output.height; + int scale = ceil(output->wlr_output.scale); + *sx = wl_fixed_to_double(x) * scale / output->wlr_output.width; + *sy = wl_fixed_to_double(y) * scale / output->wlr_output.height; return; // Choose the first output in the list }