summaryrefslogtreecommitdiff
path: root/main.c
diff options
context:
space:
mode:
authorManuel Stoeckl <code@mstoeckl.com>2023-02-19 19:31:57 -0500
committerSimon Ser <contact@emersion.fr>2024-04-29 17:18:13 +0200
commitade567683ab84b814af07d1d5e2d19e69424a5da (patch)
tree1c5f846a095a2dc2157f2acbb1225a5861cca806 /main.c
parentcde38d5e876e2f6192e83073eedcca4348141a09 (diff)
downloadswaybg-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 '')
-rw-r--r--main.c39
1 files changed, 38 insertions, 1 deletions
diff --git a/main.c b/main.c
index af314f1..f15669e 100644
--- a/main.c
+++ b/main.c
@@ -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);
}
}