summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/config.c29
-rw-r--r--src/main.c75
-rw-r--r--src/tofi.h2
3 files changed, 81 insertions, 25 deletions
diff --git a/src/config.c b/src/config.c
index 23dbc7f..31db79d 100644
--- a/src/config.c
+++ b/src/config.c
@@ -775,14 +775,6 @@ void config_fixup_values(struct tofi *tofi)
base_height /= scale;
}
- tofi->window.width = fixup_percentage(
- tofi->window.width,
- base_width,
- tofi->window.width_is_percent);
- tofi->window.height = fixup_percentage(
- tofi->window.height,
- base_height,
- tofi->window.height_is_percent);
tofi->window.margin_top = fixup_percentage(
tofi->window.margin_top,
base_height,
@@ -816,6 +808,27 @@ void config_fixup_values(struct tofi *tofi)
base_width,
tofi->window.entry.padding_right_is_percent);
+ /*
+ * Window width and height are a little special. We're only going to be
+ * using them to specify sizes to Wayland, which always wants scaled
+ * pixels, so always scale them here (unless we've directly specified a
+ * scaled size).
+ */
+ tofi->window.width = fixup_percentage(
+ tofi->window.width,
+ tofi->output_width,
+ tofi->window.width_is_percent);
+ tofi->window.height = fixup_percentage(
+ tofi->window.height,
+ tofi->output_height,
+ tofi->window.height_is_percent);
+ if (tofi->window.width_is_percent || !tofi->use_scale) {
+ tofi->window.width /= scale;
+ }
+ if (tofi->window.height_is_percent || !tofi->use_scale) {
+ tofi->window.height /= scale;
+ }
+
/* Don't attempt percentage handling if exclusive_zone is set to -1. */
if (tofi->window.exclusive_zone > 0) {
/* Exclusive zone base depends on anchor. */
diff --git a/src/main.c b/src/main.c
index 04e8529..aa0e2f3 100644
--- a/src/main.c
+++ b/src/main.c
@@ -27,6 +27,7 @@
#include "string_vec.h"
#include "string_vec.h"
#include "unicode.h"
+#include "viewporter.h"
#include "xmalloc.h"
#undef MAX
@@ -104,9 +105,6 @@ static void zwlr_layer_surface_configure(
* We want actual pixel width / height, so we have to scale the
* values provided by Wayland.
*/
- tofi->window.width = width;
- tofi->window.height = height;
-
tofi->window.surface.width = width * tofi->window.scale;
tofi->window.surface.height = height * tofi->window.scale;
@@ -697,6 +695,13 @@ static void registry_global(
&zwlr_layer_shell_v1_interface,
version);
log_debug("Bound to zwlr_layer_shell_v1 %u.\n", name);
+ } else if (!strcmp(interface, wp_viewporter_interface.name)) {
+ tofi->wp_viewporter = wl_registry_bind(
+ wl_registry,
+ name,
+ &wp_viewporter_interface,
+ 1);
+ log_debug("Bound to wp_viewporter %u.\n", name);
}
}
@@ -1430,9 +1435,30 @@ int main(int argc, char *argv[])
tofi.window.surface.wl_surface,
&wl_surface_listener,
&tofi);
- wl_surface_set_buffer_scale(
- tofi.window.surface.wl_surface,
- tofi.window.scale);
+ if (tofi.window.width == 0 || tofi.window.height == 0) {
+ /*
+ * Workaround for compatibility with legacy behaviour.
+ *
+ * Before the fractional_scale protocol was released, there was
+ * no way for a client to know whether a fractional scale
+ * factor had been set, meaning percentage-based dimensions
+ * were incorrect. As a workaround for full-size windows, we
+ * allowed specifying 0 for the width / height, which caused
+ * zwlr_layer_shell to tell us the correct size to use.
+ *
+ * To make fractional scaling work, we have to use
+ * wp_viewporter, and no longer need to set the buffer scale.
+ * However, viewporter doesn't allow specifying 0 for
+ * destination width or height. As a workaround, if 0 size is
+ * set, don't use viewporter, warn the user and set the buffer
+ * scale here.
+ */
+ 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");
+ wl_surface_set_buffer_scale(
+ tofi.window.surface.wl_surface,
+ tofi.window.scale);
+ }
/* Grab the first (and only remaining) output from our list. */
struct wl_output *wl_output;
@@ -1450,8 +1476,7 @@ int main(int argc, char *argv[])
"launcher");
zwlr_layer_surface_v1_set_keyboard_interactivity(
tofi.window.zwlr_layer_surface,
- ZWLR_LAYER_SURFACE_V1_KEYBOARD_INTERACTIVITY_EXCLUSIVE
- );
+ ZWLR_LAYER_SURFACE_V1_KEYBOARD_INTERACTIVITY_EXCLUSIVE);
zwlr_layer_surface_v1_add_listener(
tofi.window.zwlr_layer_surface,
&zwlr_layer_surface_listener,
@@ -1462,6 +1487,12 @@ int main(int argc, char *argv[])
zwlr_layer_surface_v1_set_exclusive_zone(
tofi.window.zwlr_layer_surface,
tofi.window.exclusive_zone);
+ zwlr_layer_surface_v1_set_margin(
+ tofi.window.zwlr_layer_surface,
+ tofi.window.margin_top,
+ tofi.window.margin_right,
+ tofi.window.margin_bottom,
+ tofi.window.margin_left);
/*
* No matter whether we're scaling via Cairo or not, we're presenting a
* scaled buffer to Wayland, so scale the window size here if we
@@ -1469,14 +1500,23 @@ int main(int argc, char *argv[])
*/
zwlr_layer_surface_v1_set_size(
tofi.window.zwlr_layer_surface,
- tofi.window.width / (tofi.use_scale ? 1 : tofi.window.scale),
- tofi.window.height / (tofi.use_scale ? 1 : tofi.window.scale));
- zwlr_layer_surface_v1_set_margin(
- tofi.window.zwlr_layer_surface,
- tofi.window.margin_top,
- tofi.window.margin_right,
- tofi.window.margin_bottom,
- tofi.window.margin_left);
+ tofi.window.width,
+ tofi.window.height);
+
+ /*
+ * Set up a viewport for our surface, necessary for fractional scaling.
+ */
+ tofi.window.wp_viewport = wp_viewporter_get_viewport(
+ tofi.wp_viewporter,
+ tofi.window.surface.wl_surface);
+ if (tofi.window.width > 0 && tofi.window.height > 0) {
+ wp_viewport_set_destination(
+ tofi.window.wp_viewport,
+ tofi.window.width,
+ tofi.window.height);
+ }
+
+ /* Commit the surface to finalise setup. */
wl_surface_commit(tofi.window.surface.wl_surface);
/*
@@ -1491,7 +1531,6 @@ int main(int argc, char *argv[])
&wl_data_device_listener,
&tofi.clipboard);
-
/*
* Now that we've done all our Wayland-related setup, we do another
* roundtrip. This should cause the layer surface window to be
@@ -1700,6 +1739,7 @@ int main(int argc, char *argv[])
*/
surface_destroy(&tofi.window.surface);
entry_destroy(&tofi.window.entry);
+ wp_viewport_destroy(tofi.window.wp_viewport);
zwlr_layer_surface_v1_destroy(tofi.window.zwlr_layer_surface);
wl_surface_destroy(tofi.window.surface.wl_surface);
if (tofi.wl_keyboard != NULL) {
@@ -1727,6 +1767,7 @@ int main(int argc, char *argv[])
}
wl_shm_destroy(tofi.wl_shm);
zwlr_layer_shell_v1_destroy(tofi.zwlr_layer_shell);
+ wp_viewporter_destroy(tofi.wp_viewporter);
xkb_state_unref(tofi.xkb_state);
xkb_keymap_unref(tofi.xkb_keymap);
xkb_context_unref(tofi.xkb_context);
diff --git a/src/tofi.h b/src/tofi.h
index 547b4ed..1ae05d6 100644
--- a/src/tofi.h
+++ b/src/tofi.h
@@ -35,6 +35,7 @@ struct tofi {
struct wl_shm *wl_shm;
struct wl_data_device_manager *wl_data_device_manager;
struct wl_data_device *wl_data_device;
+ struct wp_viewporter *wp_viewporter;
struct zwlr_layer_shell_v1 *zwlr_layer_shell;
struct wl_list output_list;
struct output_list_element *default_output;
@@ -57,6 +58,7 @@ struct tofi {
struct clipboard clipboard;
struct {
struct surface surface;
+ struct wp_viewport *wp_viewport;
struct zwlr_layer_surface_v1 *zwlr_layer_surface;
struct entry entry;
uint32_t width;