summaryrefslogtreecommitdiff
path: root/src/main.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/main.c')
-rw-r--r--src/main.c129
1 files changed, 112 insertions, 17 deletions
diff --git a/src/main.c b/src/main.c
index 10818c1..2a56c22 100644
--- a/src/main.c
+++ b/src/main.c
@@ -22,6 +22,7 @@
#include "log.h"
#include "nelem.h"
#include "lock.h"
+#include "scale.h"
#include "shm.h"
#include "string_vec.h"
#include "string_vec.h"
@@ -104,8 +105,13 @@ static void zwlr_layer_surface_configure(
* We want actual pixel width / height, so we have to scale the
* values provided by Wayland.
*/
- tofi->window.surface.width = width * tofi->window.scale;
- tofi->window.surface.height = height * tofi->window.scale;
+ if (tofi->window.fractional_scale != 0) {
+ tofi->window.surface.width = scale_apply(width, tofi->window.fractional_scale);
+ tofi->window.surface.height = scale_apply(height, tofi->window.fractional_scale);
+ } else {
+ tofi->window.surface.width = width * tofi->window.scale;
+ tofi->window.surface.height = height * tofi->window.scale;
+ }
zwlr_layer_surface_v1_ack_configure(
tofi->window.zwlr_layer_surface,
@@ -701,6 +707,13 @@ static void registry_global(
&wp_viewporter_interface,
1);
log_debug("Bound to wp_viewporter %u.\n", name);
+ } else if (!strcmp(interface, wp_fractional_scale_manager_v1_interface.name)) {
+ tofi->wp_fractional_scale_manager = wl_registry_bind(
+ wl_registry,
+ name,
+ &wp_fractional_scale_manager_v1_interface,
+ 1);
+ log_debug("Bound to wp_fractional_scale_manager_v1 %u.\n", name);
}
}
@@ -765,6 +778,19 @@ static const struct zwlr_layer_surface_v1_listener dummy_layer_surface_listener
.closed = dummy_layer_surface_close
};
+static void dummy_fractional_scale_preferred_scale(
+ void *data,
+ struct wp_fractional_scale_v1 *wp_fractional_scale,
+ uint32_t scale)
+{
+ struct tofi *tofi = data;
+ tofi->window.fractional_scale = scale;
+}
+
+static const struct wp_fractional_scale_v1_listener dummy_fractional_scale_listener = {
+ .preferred_scale = dummy_fractional_scale_preferred_scale
+};
+
static void dummy_surface_enter(
void *data,
struct wl_surface *wl_surface,
@@ -1228,20 +1254,28 @@ int main(int argc, char *argv[])
log_unindent();
log_debug("Second roundtrip done.\n");
- /* If there's more than one output, we need to select one. */
- if (wl_list_length(&tofi.output_list) > 1) {
+ {
/*
- * Determine the default output
+ * Determine the output we're going to appear on, and get its
+ * fractional scale if supported.
*
* This seems like an ugly solution, but as far as I know
* there's no way to determine the default output other than to
* call get_layer_surface with NULL as the output and see which
* output our surface turns up on.
*
+ * Additionally, determining fractional scale factors can
+ * currently only be done by attaching a wp_fractional_scale to
+ * a surface and displaying it.
+ *
* Here we set up a single pixel surface, perform the required
* two roundtrips, then tear it down. tofi.default_output
- * should then contain the output our surface was assigned to.
+ * should then contain the output our surface was assigned to,
+ * and tofi.window.fractional_scale should have the scale
+ * factor.
*/
+ log_debug("Determining output.\n");
+ log_indent();
struct surface surface = {
.width = 1,
.height = 1
@@ -1253,11 +1287,38 @@ int main(int argc, char *argv[])
&dummy_surface_listener,
&tofi);
+ struct wp_fractional_scale_v1 *wp_fractional_scale = NULL;
+ if (tofi.wp_fractional_scale_manager != NULL) {
+ wp_fractional_scale =
+ wp_fractional_scale_manager_v1_get_fractional_scale(
+ tofi.wp_fractional_scale_manager,
+ surface.wl_surface);
+ wp_fractional_scale_v1_add_listener(
+ wp_fractional_scale,
+ &dummy_fractional_scale_listener,
+ &tofi);
+ }
+
+ /*
+ * If we have a desired output, make sure we appear on it so we
+ * can determine the correct fractional scale.
+ */
+ struct wl_output *wl_output = NULL;
+ if (tofi.target_output_name[0] != '\0') {
+ struct output_list_element *el;
+ wl_list_for_each(el, &tofi.output_list, link) {
+ if (!strcmp(tofi.target_output_name, el->name)) {
+ wl_output = el->wl_output;
+ break;
+ }
+ }
+ }
+
struct zwlr_layer_surface_v1 *zwlr_layer_surface =
zwlr_layer_shell_v1_get_layer_surface(
tofi.zwlr_layer_shell,
surface.wl_surface,
- NULL,
+ wl_output,
ZWLR_LAYER_SHELL_V1_LAYER_BACKGROUND,
"dummy");
/*
@@ -1277,12 +1338,27 @@ int main(int argc, char *argv[])
1,
1);
wl_surface_commit(surface.wl_surface);
+ log_debug("First dummy roundtrip start.\n");
+ log_indent();
wl_display_roundtrip(tofi.wl_display);
+ log_unindent();
+ log_debug("First dummy roundtrip done.\n");
+ log_debug("Initialising dummy surface.\n");
+ log_indent();
surface_init(&surface, tofi.wl_shm);
surface_draw(&surface);
+ log_unindent();
+ log_debug("Dummy surface initialised.\n");
+ log_debug("Second dummy roundtrip start.\n");
+ log_indent();
wl_display_roundtrip(tofi.wl_display);
+ log_unindent();
+ log_debug("Second dummy roundtrip done.\n");
surface_destroy(&surface);
zwlr_layer_surface_v1_destroy(zwlr_layer_surface);
+ if (wp_fractional_scale != NULL) {
+ wp_fractional_scale_v1_destroy(wp_fractional_scale);
+ }
wl_surface_destroy(surface.wl_surface);
/*
@@ -1324,13 +1400,11 @@ int main(int argc, char *argv[])
free(el);
}
}
- }
- {
+
/*
* The only output left should either be the one we want, or
* the first that was advertised.
*/
- struct output_list_element *el;
el = wl_container_of(tofi.output_list.next, el, link);
/*
@@ -1351,6 +1425,7 @@ int main(int argc, char *argv[])
}
tofi.window.scale = el->scale;
tofi.window.transform = el->transform;
+ log_unindent();
log_debug("Selected output %s.\n", el->name);
}
@@ -1454,6 +1529,7 @@ int main(int argc, char *argv[])
*/
log_warning("Width or height set to 0, disabling fractional scaling support.\n");
log_warning("If your compositor supports the fractional scale protocol, percentages are preferred.\n");
+ tofi.window.fractional_scale = 0;
wl_surface_set_buffer_scale(
tofi.window.surface.wl_surface,
tofi.window.scale);
@@ -1564,12 +1640,28 @@ int main(int argc, char *argv[])
*/
log_debug("Initialising renderer.\n");
log_indent();
- entry_init(
- &tofi.window.entry,
- tofi.window.surface.shm_pool_data,
- tofi.window.surface.width,
- tofi.window.surface.height,
- tofi.use_scale ? tofi.window.scale : 1);
+ {
+ /*
+ * No matter how we're scaling (with fractions, integers or not
+ * at all), we pass a fractional scale factor (the numerator of
+ * a fraction with denominator 120) to our setup function for
+ * ease.
+ */
+ uint32_t scale = 120;
+ if (tofi.use_scale) {
+ if (tofi.window.fractional_scale != 0) {
+ scale = tofi.window.fractional_scale;
+ } else {
+ scale = tofi.window.scale * 120;
+ }
+ }
+ entry_init(
+ &tofi.window.entry,
+ tofi.window.surface.shm_pool_data,
+ tofi.window.surface.width,
+ tofi.window.surface.height,
+ scale);
+ }
log_unindent();
log_debug("Renderer initialised.\n");
@@ -1765,8 +1857,11 @@ int main(int argc, char *argv[])
}
}
wl_shm_destroy(tofi.wl_shm);
- zwlr_layer_shell_v1_destroy(tofi.zwlr_layer_shell);
+ if (tofi.wp_fractional_scale_manager != NULL) {
+ wp_fractional_scale_manager_v1_destroy(tofi.wp_fractional_scale_manager);
+ }
wp_viewporter_destroy(tofi.wp_viewporter);
+ zwlr_layer_shell_v1_destroy(tofi.zwlr_layer_shell);
xkb_state_unref(tofi.xkb_state);
xkb_keymap_unref(tofi.xkb_keymap);
xkb_context_unref(tofi.xkb_context);