diff options
author | Manuel Stoeckl <code@mstoeckl.com> | 2023-02-19 19:31:57 -0500 |
---|---|---|
committer | Simon Ser <contact@emersion.fr> | 2024-04-29 17:18:13 +0200 |
commit | ade567683ab84b814af07d1d5e2d19e69424a5da (patch) | |
tree | 1c5f846a095a2dc2157f2acbb1225a5861cca806 /main.c | |
parent | cde38d5e876e2f6192e83073eedcca4348141a09 (diff) | |
download | swaybg-ade567683ab84b814af07d1d5e2d19e69424a5da.tar.gz swaybg-ade567683ab84b814af07d1d5e2d19e69424a5da.tar.bz2 |
Estimate output size with wp-fractional-scale-v1
And if available, use wp-viewporter to submit buffers whose size
exactly matches the "physical" pixel dimensions of the output.
Diffstat (limited to 'main.c')
-rw-r--r-- | main.c | 39 |
1 files changed, 38 insertions, 1 deletions
@@ -14,6 +14,7 @@ #include "wlr-layer-shell-unstable-v1-client-protocol.h" #include "viewporter-client-protocol.h" #include "single-pixel-buffer-v1-client-protocol.h" +#include "fractional-scale-v1-client-protocol.h" /* * If `color` is a hexadecimal string of the form 'rrggbb' or '#rrggbb', @@ -47,6 +48,7 @@ struct swaybg_state { struct zwlr_layer_shell_v1 *layer_shell; struct wp_viewporter *viewporter; struct wp_single_pixel_buffer_manager_v1 *single_pixel_buffer_manager; + struct wp_fractional_scale_manager_v1 *fract_scale_manager; struct wl_list configs; // struct swaybg_output_config::link struct wl_list outputs; // struct swaybg_output::link struct wl_list images; // struct swaybg_image::link @@ -80,9 +82,11 @@ struct swaybg_output { struct wl_surface *surface; struct zwlr_layer_surface_v1 *layer_surface; struct wp_viewport *viewport; + struct wp_fractional_scale_v1 *fract_scale; uint32_t width, height; int32_t scale; + uint32_t pref_fract_scale; uint32_t configure_serial; bool dirty, needs_ack; @@ -146,6 +150,8 @@ static struct wl_buffer *draw_buffer(const struct swaybg_output *output, return wl_buf; } +#define FRACT_DENOM 120 + // Return the size of the buffer that should be attached to this output static void get_buffer_size(const struct swaybg_output *output, uint32_t *buffer_width, uint32_t *buffer_height) { @@ -153,6 +159,12 @@ static void get_buffer_size(const struct swaybg_output *output, output->state->viewporter) { *buffer_width = 1; *buffer_height = 1; + } else if (output->fract_scale && output->state->viewporter) { + // rounding mode is 'round half up' + *buffer_width = (output->width * output->pref_fract_scale + + FRACT_DENOM / 2) / FRACT_DENOM; + *buffer_height = (output->height * output->pref_fract_scale + + FRACT_DENOM / 2) / FRACT_DENOM; } else { *buffer_width = output->width * output->scale; *buffer_height = output->height * output->scale; @@ -223,6 +235,9 @@ static void destroy_swaybg_output(struct swaybg_output *output) { if (output->viewport != NULL) { wp_viewport_destroy(output->viewport); } + if (output->fract_scale != NULL) { + wp_fractional_scale_v1_destroy(output->fract_scale); + } wl_output_destroy(output->wl_output); free(output->name); free(output->identifier); @@ -253,6 +268,16 @@ static const struct zwlr_layer_surface_v1_listener layer_surface_listener = { .closed = layer_surface_closed, }; +static void fract_preferred_scale(void *data, struct wp_fractional_scale_v1 *f, + uint32_t scale) { + struct swaybg_output *output = data; + output->pref_fract_scale = scale; +} + +static const struct wp_fractional_scale_v1_listener fract_scale_listener = { + .preferred_scale = fract_preferred_scale +}; + static void output_geometry(void *data, struct wl_output *output, int32_t x, int32_t y, int32_t width_mm, int32_t height_mm, int32_t subpixel, const char *make, const char *model, int32_t transform) { @@ -275,8 +300,17 @@ static void create_layer_surface(struct swaybg_output *output) { wl_surface_set_input_region(output->surface, input_region); wl_region_destroy(input_region); + if (output->state->fract_scale_manager) { + output->fract_scale = wp_fractional_scale_manager_v1_get_fractional_scale( + output->state->fract_scale_manager, output->surface); + assert(output->fract_scale); + wp_fractional_scale_v1_add_listener(output->fract_scale, + &fract_scale_listener, output); + } + if (output->state->viewporter && - output->config->mode == BACKGROUND_MODE_SOLID_COLOR) { + (output->config->mode == BACKGROUND_MODE_SOLID_COLOR || + output->state->fract_scale_manager)) { output->viewport = wp_viewporter_get_viewport( output->state->viewporter, output->surface); } @@ -400,6 +434,9 @@ static void handle_global(void *data, struct wl_registry *registry, wp_single_pixel_buffer_manager_v1_interface.name) == 0) { state->single_pixel_buffer_manager = wl_registry_bind(registry, name, &wp_single_pixel_buffer_manager_v1_interface, 1); + } else if (strcmp(interface, wp_fractional_scale_manager_v1_interface.name) == 0) { + state->fract_scale_manager = wl_registry_bind(registry, name, + &wp_fractional_scale_manager_v1_interface, 1); } } |