mirror of
https://github.com/Cloudef/bemenu
synced 2024-11-22 17:02:05 +01:00
Reapply "implement wayland fractional scaling"
This reverts commit 943d74600eb3791f3fe8344a844e5bc6d17899bb. This fix the BEMENU_SCALE that was left unused when fractionnal scale support was detected. This is rebased over origin/master.
This commit is contained in:
parent
3156dac7d4
commit
877ca82cc1
20
GNUmakefile
20
GNUmakefile
@ -85,15 +85,33 @@ lib/renderers/wayland/wlr-layer-shell-unstable-v1.h: lib/renderers/wayland/wlr-l
|
|||||||
lib/renderers/wayland/wlr-layer-shell-unstable-v1.c: lib/renderers/wayland/wlr-layer-shell-unstable-v1.xml
|
lib/renderers/wayland/wlr-layer-shell-unstable-v1.c: lib/renderers/wayland/wlr-layer-shell-unstable-v1.xml
|
||||||
wayland-scanner private-code < $^ > $@
|
wayland-scanner private-code < $^ > $@
|
||||||
|
|
||||||
|
lib/renderers/wayland/fractional-scale-v1.h: lib/renderers/wayland/fractional-scale-v1.xml
|
||||||
|
wayland-scanner client-header < $^ > $@
|
||||||
|
|
||||||
|
lib/renderers/wayland/fractional-scale-v1.c: lib/renderers/wayland/fractional-scale-v1.xml
|
||||||
|
wayland-scanner private-code < $^ > $@
|
||||||
|
|
||||||
|
lib/renderers/wayland/viewporter.h: lib/renderers/wayland/viewporter.xml
|
||||||
|
wayland-scanner client-header < $^ > $@
|
||||||
|
|
||||||
|
lib/renderers/wayland/viewporter.c: lib/renderers/wayland/viewporter.xml
|
||||||
|
wayland-scanner private-code < $^ > $@
|
||||||
|
|
||||||
xdg-shell.a: private override LDFLAGS += -fPIC
|
xdg-shell.a: private override LDFLAGS += -fPIC
|
||||||
xdg-shell.a: private override CPPFLAGS += $(shell $(PKG_CONFIG) --cflags-only-I wayland-client)
|
xdg-shell.a: private override CPPFLAGS += $(shell $(PKG_CONFIG) --cflags-only-I wayland-client)
|
||||||
xdg-shell.a: lib/renderers/wayland/xdg-shell.c
|
xdg-shell.a: lib/renderers/wayland/xdg-shell.c
|
||||||
wlr-layer-shell.a: private override LDFLAGS += -fPIC
|
wlr-layer-shell.a: private override LDFLAGS += -fPIC
|
||||||
wlr-layer-shell.a: private override CPPFLAGS += $(shell $(PKG_CONFIG) --cflags-only-I wayland-client)
|
wlr-layer-shell.a: private override CPPFLAGS += $(shell $(PKG_CONFIG) --cflags-only-I wayland-client)
|
||||||
wlr-layer-shell.a: lib/renderers/wayland/wlr-layer-shell-unstable-v1.c lib/renderers/wayland/wlr-layer-shell-unstable-v1.h
|
wlr-layer-shell.a: lib/renderers/wayland/wlr-layer-shell-unstable-v1.c lib/renderers/wayland/wlr-layer-shell-unstable-v1.h
|
||||||
|
fractional-scale.a: private override LDFLAGS += -fPIC
|
||||||
|
fractional-scale.a: private override CPPFLAGS += $(shell $(PKG_CONFIG) --cflags-only-I wayland-client)
|
||||||
|
fractional-scale.a: lib/renderers/wayland/fractional-scale-v1.c lib/renderers/wayland/fractional-scale-v1.h
|
||||||
|
viewporter.a: private override LDFLAGS += -fPIC
|
||||||
|
viewporter.a: private override CPPFLAGS += $(shell $(PKG_CONFIG) --cflags-only-I wayland-client)
|
||||||
|
viewporter.a: lib/renderers/wayland/viewporter.c lib/renderers/wayland/viewporter.h
|
||||||
bemenu-renderer-wayland.so: private override LDLIBS += $(shell $(PKG_CONFIG) --libs wayland-client cairo pango pangocairo xkbcommon)
|
bemenu-renderer-wayland.so: private override LDLIBS += $(shell $(PKG_CONFIG) --libs wayland-client cairo pango pangocairo xkbcommon)
|
||||||
bemenu-renderer-wayland.so: private override CPPFLAGS += $(shell $(PKG_CONFIG) --cflags-only-I wayland-client cairo pango pangocairo xkbcommon)
|
bemenu-renderer-wayland.so: private override CPPFLAGS += $(shell $(PKG_CONFIG) --cflags-only-I wayland-client cairo pango pangocairo xkbcommon)
|
||||||
bemenu-renderer-wayland.so: lib/renderers/cairo_renderer.h lib/renderers/wayland/wayland.c lib/renderers/wayland/wayland.h lib/renderers/wayland/registry.c lib/renderers/wayland/window.c xdg-shell.a wlr-layer-shell.a util.a
|
bemenu-renderer-wayland.so: lib/renderers/cairo_renderer.h lib/renderers/wayland/wayland.c lib/renderers/wayland/wayland.h lib/renderers/wayland/registry.c lib/renderers/wayland/window.c xdg-shell.a wlr-layer-shell.a fractional-scale.a viewporter.a util.a
|
||||||
|
|
||||||
common.a: client/common/common.c client/common/common.h
|
common.a: client/common/common.c client/common/common.h
|
||||||
bemenu: common.a client/bemenu.c
|
bemenu: common.a client/bemenu.c
|
||||||
|
@ -12,7 +12,7 @@ struct cairo {
|
|||||||
cairo_t *cr;
|
cairo_t *cr;
|
||||||
cairo_surface_t *surface;
|
cairo_surface_t *surface;
|
||||||
PangoContext *pango;
|
PangoContext *pango;
|
||||||
int scale;
|
double scale;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct cairo_color {
|
struct cairo_color {
|
||||||
@ -67,6 +67,8 @@ bm_cairo_create_for_surface(struct cairo *cairo, cairo_surface_t *surface)
|
|||||||
if (!(cairo->pango = pango_cairo_create_context(cairo->cr)))
|
if (!(cairo->pango = pango_cairo_create_context(cairo->cr)))
|
||||||
goto fail;
|
goto fail;
|
||||||
|
|
||||||
|
cairo_set_antialias(cairo->cr, CAIRO_ANTIALIAS_NONE);
|
||||||
|
|
||||||
cairo->surface = surface;
|
cairo->surface = surface;
|
||||||
assert(cairo->scale > 0);
|
assert(cairo->scale > 0);
|
||||||
cairo_surface_set_device_scale(surface, cairo->scale, cairo->scale);
|
cairo_surface_set_device_scale(surface, cairo->scale, cairo->scale);
|
||||||
|
102
lib/renderers/wayland/fractional-scale-v1.xml
Normal file
102
lib/renderers/wayland/fractional-scale-v1.xml
Normal file
@ -0,0 +1,102 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<protocol name="fractional_scale_v1">
|
||||||
|
<copyright>
|
||||||
|
Copyright © 2022 Kenny Levinsen
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
|
copy of this software and associated documentation files (the "Software"),
|
||||||
|
to deal in the Software without restriction, including without limitation
|
||||||
|
the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||||
|
and/or sell copies of the Software, and to permit persons to whom the
|
||||||
|
Software is furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice (including the next
|
||||||
|
paragraph) shall be included in all copies or substantial portions of the
|
||||||
|
Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||||
|
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||||
|
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||||
|
DEALINGS IN THE SOFTWARE.
|
||||||
|
</copyright>
|
||||||
|
|
||||||
|
<description summary="Protocol for requesting fractional surface scales">
|
||||||
|
This protocol allows a compositor to suggest for surfaces to render at
|
||||||
|
fractional scales.
|
||||||
|
|
||||||
|
A client can submit scaled content by utilizing wp_viewport. This is done by
|
||||||
|
creating a wp_viewport object for the surface and setting the destination
|
||||||
|
rectangle to the surface size before the scale factor is applied.
|
||||||
|
|
||||||
|
The buffer size is calculated by multiplying the surface size by the
|
||||||
|
intended scale.
|
||||||
|
|
||||||
|
The wl_surface buffer scale should remain set to 1.
|
||||||
|
|
||||||
|
If a surface has a surface-local size of 100 px by 50 px and wishes to
|
||||||
|
submit buffers with a scale of 1.5, then a buffer of 150px by 75 px should
|
||||||
|
be used and the wp_viewport destination rectangle should be 100 px by 50 px.
|
||||||
|
|
||||||
|
For toplevel surfaces, the size is rounded halfway away from zero. The
|
||||||
|
rounding algorithm for subsurface position and size is not defined.
|
||||||
|
</description>
|
||||||
|
|
||||||
|
<interface name="wp_fractional_scale_manager_v1" version="1">
|
||||||
|
<description summary="fractional surface scale information">
|
||||||
|
A global interface for requesting surfaces to use fractional scales.
|
||||||
|
</description>
|
||||||
|
|
||||||
|
<request name="destroy" type="destructor">
|
||||||
|
<description summary="unbind the fractional surface scale interface">
|
||||||
|
Informs the server that the client will not be using this protocol
|
||||||
|
object anymore. This does not affect any other objects,
|
||||||
|
wp_fractional_scale_v1 objects included.
|
||||||
|
</description>
|
||||||
|
</request>
|
||||||
|
|
||||||
|
<enum name="error">
|
||||||
|
<entry name="fractional_scale_exists" value="0"
|
||||||
|
summary="the surface already has a fractional_scale object associated"/>
|
||||||
|
</enum>
|
||||||
|
|
||||||
|
<request name="get_fractional_scale">
|
||||||
|
<description summary="extend surface interface for scale information">
|
||||||
|
Create an add-on object for the the wl_surface to let the compositor
|
||||||
|
request fractional scales. If the given wl_surface already has a
|
||||||
|
wp_fractional_scale_v1 object associated, the fractional_scale_exists
|
||||||
|
protocol error is raised.
|
||||||
|
</description>
|
||||||
|
<arg name="id" type="new_id" interface="wp_fractional_scale_v1"
|
||||||
|
summary="the new surface scale info interface id"/>
|
||||||
|
<arg name="surface" type="object" interface="wl_surface"
|
||||||
|
summary="the surface"/>
|
||||||
|
</request>
|
||||||
|
</interface>
|
||||||
|
|
||||||
|
<interface name="wp_fractional_scale_v1" version="1">
|
||||||
|
<description summary="fractional scale interface to a wl_surface">
|
||||||
|
An additional interface to a wl_surface object which allows the compositor
|
||||||
|
to inform the client of the preferred scale.
|
||||||
|
</description>
|
||||||
|
|
||||||
|
<request name="destroy" type="destructor">
|
||||||
|
<description summary="remove surface scale information for surface">
|
||||||
|
Destroy the fractional scale object. When this object is destroyed,
|
||||||
|
preferred_scale events will no longer be sent.
|
||||||
|
</description>
|
||||||
|
</request>
|
||||||
|
|
||||||
|
<event name="preferred_scale">
|
||||||
|
<description summary="notify of new preferred scale">
|
||||||
|
Notification of a new preferred scale for this surface that the
|
||||||
|
compositor suggests that the client should use.
|
||||||
|
|
||||||
|
The sent scale is the numerator of a fraction with a denominator of 120.
|
||||||
|
</description>
|
||||||
|
<arg name="scale" type="uint" summary="the new preferred scale"/>
|
||||||
|
</event>
|
||||||
|
</interface>
|
||||||
|
</protocol>
|
@ -595,6 +595,10 @@ registry_handle_global(void *data, struct wl_registry *registry, uint32_t id, co
|
|||||||
output->output = wl_output;
|
output->output = wl_output;
|
||||||
wl_list_insert(&wayland->outputs, &output->link);
|
wl_list_insert(&wayland->outputs, &output->link);
|
||||||
wl_output_add_listener(wl_output, &output_listener, output);
|
wl_output_add_listener(wl_output, &output_listener, output);
|
||||||
|
} else if (strcmp(interface, "wp_fractional_scale_manager_v1") == 0) {
|
||||||
|
wayland->wfs_mgr = wl_registry_bind(registry, id, &wp_fractional_scale_manager_v1_interface, 1);
|
||||||
|
} else if (strcmp(interface, "wp_viewporter") == 0) {
|
||||||
|
wayland->viewporter = wl_registry_bind(registry, id, &wp_viewporter_interface, 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -660,6 +664,9 @@ bm_wl_registry_register(struct wayland *wayland)
|
|||||||
if (!wayland->input.keyboard || !(wayland->formats & (1 << WL_SHM_FORMAT_ARGB8888)))
|
if (!wayland->input.keyboard || !(wayland->formats & (1 << WL_SHM_FORMAT_ARGB8888)))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
if (wayland->wfs_mgr && wayland->viewporter)
|
||||||
|
wayland->fractional_scaling = true;
|
||||||
|
|
||||||
set_repeat_info(&wayland->input, 40, 400);
|
set_repeat_info(&wayland->input, 40, 400);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
180
lib/renderers/wayland/viewporter.xml
Normal file
180
lib/renderers/wayland/viewporter.xml
Normal file
@ -0,0 +1,180 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<protocol name="viewporter">
|
||||||
|
|
||||||
|
<copyright>
|
||||||
|
Copyright © 2013-2016 Collabora, Ltd.
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
|
copy of this software and associated documentation files (the "Software"),
|
||||||
|
to deal in the Software without restriction, including without limitation
|
||||||
|
the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||||
|
and/or sell copies of the Software, and to permit persons to whom the
|
||||||
|
Software is furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice (including the next
|
||||||
|
paragraph) shall be included in all copies or substantial portions of the
|
||||||
|
Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||||
|
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||||
|
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||||
|
DEALINGS IN THE SOFTWARE.
|
||||||
|
</copyright>
|
||||||
|
|
||||||
|
<interface name="wp_viewporter" version="1">
|
||||||
|
<description summary="surface cropping and scaling">
|
||||||
|
The global interface exposing surface cropping and scaling
|
||||||
|
capabilities is used to instantiate an interface extension for a
|
||||||
|
wl_surface object. This extended interface will then allow
|
||||||
|
cropping and scaling the surface contents, effectively
|
||||||
|
disconnecting the direct relationship between the buffer and the
|
||||||
|
surface size.
|
||||||
|
</description>
|
||||||
|
|
||||||
|
<request name="destroy" type="destructor">
|
||||||
|
<description summary="unbind from the cropping and scaling interface">
|
||||||
|
Informs the server that the client will not be using this
|
||||||
|
protocol object anymore. This does not affect any other objects,
|
||||||
|
wp_viewport objects included.
|
||||||
|
</description>
|
||||||
|
</request>
|
||||||
|
|
||||||
|
<enum name="error">
|
||||||
|
<entry name="viewport_exists" value="0"
|
||||||
|
summary="the surface already has a viewport object associated"/>
|
||||||
|
</enum>
|
||||||
|
|
||||||
|
<request name="get_viewport">
|
||||||
|
<description summary="extend surface interface for crop and scale">
|
||||||
|
Instantiate an interface extension for the given wl_surface to
|
||||||
|
crop and scale its content. If the given wl_surface already has
|
||||||
|
a wp_viewport object associated, the viewport_exists
|
||||||
|
protocol error is raised.
|
||||||
|
</description>
|
||||||
|
<arg name="id" type="new_id" interface="wp_viewport"
|
||||||
|
summary="the new viewport interface id"/>
|
||||||
|
<arg name="surface" type="object" interface="wl_surface"
|
||||||
|
summary="the surface"/>
|
||||||
|
</request>
|
||||||
|
</interface>
|
||||||
|
|
||||||
|
<interface name="wp_viewport" version="1">
|
||||||
|
<description summary="crop and scale interface to a wl_surface">
|
||||||
|
An additional interface to a wl_surface object, which allows the
|
||||||
|
client to specify the cropping and scaling of the surface
|
||||||
|
contents.
|
||||||
|
|
||||||
|
This interface works with two concepts: the source rectangle (src_x,
|
||||||
|
src_y, src_width, src_height), and the destination size (dst_width,
|
||||||
|
dst_height). The contents of the source rectangle are scaled to the
|
||||||
|
destination size, and content outside the source rectangle is ignored.
|
||||||
|
This state is double-buffered, and is applied on the next
|
||||||
|
wl_surface.commit.
|
||||||
|
|
||||||
|
The two parts of crop and scale state are independent: the source
|
||||||
|
rectangle, and the destination size. Initially both are unset, that
|
||||||
|
is, no scaling is applied. The whole of the current wl_buffer is
|
||||||
|
used as the source, and the surface size is as defined in
|
||||||
|
wl_surface.attach.
|
||||||
|
|
||||||
|
If the destination size is set, it causes the surface size to become
|
||||||
|
dst_width, dst_height. The source (rectangle) is scaled to exactly
|
||||||
|
this size. This overrides whatever the attached wl_buffer size is,
|
||||||
|
unless the wl_buffer is NULL. If the wl_buffer is NULL, the surface
|
||||||
|
has no content and therefore no size. Otherwise, the size is always
|
||||||
|
at least 1x1 in surface local coordinates.
|
||||||
|
|
||||||
|
If the source rectangle is set, it defines what area of the wl_buffer is
|
||||||
|
taken as the source. If the source rectangle is set and the destination
|
||||||
|
size is not set, then src_width and src_height must be integers, and the
|
||||||
|
surface size becomes the source rectangle size. This results in cropping
|
||||||
|
without scaling. If src_width or src_height are not integers and
|
||||||
|
destination size is not set, the bad_size protocol error is raised when
|
||||||
|
the surface state is applied.
|
||||||
|
|
||||||
|
The coordinate transformations from buffer pixel coordinates up to
|
||||||
|
the surface-local coordinates happen in the following order:
|
||||||
|
1. buffer_transform (wl_surface.set_buffer_transform)
|
||||||
|
2. buffer_scale (wl_surface.set_buffer_scale)
|
||||||
|
3. crop and scale (wp_viewport.set*)
|
||||||
|
This means, that the source rectangle coordinates of crop and scale
|
||||||
|
are given in the coordinates after the buffer transform and scale,
|
||||||
|
i.e. in the coordinates that would be the surface-local coordinates
|
||||||
|
if the crop and scale was not applied.
|
||||||
|
|
||||||
|
If src_x or src_y are negative, the bad_value protocol error is raised.
|
||||||
|
Otherwise, if the source rectangle is partially or completely outside of
|
||||||
|
the non-NULL wl_buffer, then the out_of_buffer protocol error is raised
|
||||||
|
when the surface state is applied. A NULL wl_buffer does not raise the
|
||||||
|
out_of_buffer error.
|
||||||
|
|
||||||
|
If the wl_surface associated with the wp_viewport is destroyed,
|
||||||
|
all wp_viewport requests except 'destroy' raise the protocol error
|
||||||
|
no_surface.
|
||||||
|
|
||||||
|
If the wp_viewport object is destroyed, the crop and scale
|
||||||
|
state is removed from the wl_surface. The change will be applied
|
||||||
|
on the next wl_surface.commit.
|
||||||
|
</description>
|
||||||
|
|
||||||
|
<request name="destroy" type="destructor">
|
||||||
|
<description summary="remove scaling and cropping from the surface">
|
||||||
|
The associated wl_surface's crop and scale state is removed.
|
||||||
|
The change is applied on the next wl_surface.commit.
|
||||||
|
</description>
|
||||||
|
</request>
|
||||||
|
|
||||||
|
<enum name="error">
|
||||||
|
<entry name="bad_value" value="0"
|
||||||
|
summary="negative or zero values in width or height"/>
|
||||||
|
<entry name="bad_size" value="1"
|
||||||
|
summary="destination size is not integer"/>
|
||||||
|
<entry name="out_of_buffer" value="2"
|
||||||
|
summary="source rectangle extends outside of the content area"/>
|
||||||
|
<entry name="no_surface" value="3"
|
||||||
|
summary="the wl_surface was destroyed"/>
|
||||||
|
</enum>
|
||||||
|
|
||||||
|
<request name="set_source">
|
||||||
|
<description summary="set the source rectangle for cropping">
|
||||||
|
Set the source rectangle of the associated wl_surface. See
|
||||||
|
wp_viewport for the description, and relation to the wl_buffer
|
||||||
|
size.
|
||||||
|
|
||||||
|
If all of x, y, width and height are -1.0, the source rectangle is
|
||||||
|
unset instead. Any other set of values where width or height are zero
|
||||||
|
or negative, or x or y are negative, raise the bad_value protocol
|
||||||
|
error.
|
||||||
|
|
||||||
|
The crop and scale state is double-buffered state, and will be
|
||||||
|
applied on the next wl_surface.commit.
|
||||||
|
</description>
|
||||||
|
<arg name="x" type="fixed" summary="source rectangle x"/>
|
||||||
|
<arg name="y" type="fixed" summary="source rectangle y"/>
|
||||||
|
<arg name="width" type="fixed" summary="source rectangle width"/>
|
||||||
|
<arg name="height" type="fixed" summary="source rectangle height"/>
|
||||||
|
</request>
|
||||||
|
|
||||||
|
<request name="set_destination">
|
||||||
|
<description summary="set the surface size for scaling">
|
||||||
|
Set the destination size of the associated wl_surface. See
|
||||||
|
wp_viewport for the description, and relation to the wl_buffer
|
||||||
|
size.
|
||||||
|
|
||||||
|
If width is -1 and height is -1, the destination size is unset
|
||||||
|
instead. Any other pair of values for width and height that
|
||||||
|
contains zero or negative values raises the bad_value protocol
|
||||||
|
error.
|
||||||
|
|
||||||
|
The crop and scale state is double-buffered state, and will be
|
||||||
|
applied on the next wl_surface.commit.
|
||||||
|
</description>
|
||||||
|
<arg name="width" type="int" summary="surface width"/>
|
||||||
|
<arg name="height" type="int" summary="surface height"/>
|
||||||
|
</request>
|
||||||
|
</interface>
|
||||||
|
|
||||||
|
</protocol>
|
@ -8,6 +8,8 @@
|
|||||||
#include <linux/input-event-codes.h>
|
#include <linux/input-event-codes.h>
|
||||||
|
|
||||||
#include "wlr-layer-shell-unstable-v1.h"
|
#include "wlr-layer-shell-unstable-v1.h"
|
||||||
|
#include "fractional-scale-v1.h"
|
||||||
|
#include "viewporter.h"
|
||||||
#include "renderers/cairo_renderer.h"
|
#include "renderers/cairo_renderer.h"
|
||||||
|
|
||||||
struct bm_menu;
|
struct bm_menu;
|
||||||
@ -119,12 +121,13 @@ struct window {
|
|||||||
struct wl_surface *surface;
|
struct wl_surface *surface;
|
||||||
struct wl_callback *frame_cb;
|
struct wl_callback *frame_cb;
|
||||||
struct zwlr_layer_surface_v1 *layer_surface;
|
struct zwlr_layer_surface_v1 *layer_surface;
|
||||||
|
struct wp_viewport *viewport_surface;
|
||||||
struct wl_shm *shm;
|
struct wl_shm *shm;
|
||||||
struct buffer buffers[2];
|
struct buffer buffers[2];
|
||||||
uint32_t width, height, max_height;
|
uint32_t width, height, max_height;
|
||||||
uint32_t hmargin_size;
|
uint32_t hmargin_size;
|
||||||
float width_factor;
|
float width_factor;
|
||||||
int32_t scale;
|
double scale;
|
||||||
uint32_t displayed;
|
uint32_t displayed;
|
||||||
struct wl_list link;
|
struct wl_list link;
|
||||||
enum bm_align align;
|
enum bm_align align;
|
||||||
@ -167,6 +170,9 @@ struct wayland {
|
|||||||
struct input input;
|
struct input input;
|
||||||
struct wl_list windows;
|
struct wl_list windows;
|
||||||
uint32_t formats;
|
uint32_t formats;
|
||||||
|
struct wp_fractional_scale_manager_v1 *wfs_mgr;
|
||||||
|
struct wp_viewporter *viewporter;
|
||||||
|
bool fractional_scaling;
|
||||||
};
|
};
|
||||||
|
|
||||||
void bm_wl_repeat(struct wayland *wayland);
|
void bm_wl_repeat(struct wayland *wayland);
|
||||||
|
@ -6,6 +6,7 @@
|
|||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <sys/mman.h>
|
#include <sys/mman.h>
|
||||||
|
#include <math.h>
|
||||||
|
|
||||||
static int
|
static int
|
||||||
set_cloexec_or_close(int fd)
|
set_cloexec_or_close(int fd)
|
||||||
@ -107,7 +108,7 @@ destroy_buffer(struct buffer *buffer)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
create_buffer(struct wl_shm *shm, struct buffer *buffer, int32_t width, int32_t height, uint32_t format, int32_t scale)
|
create_buffer(struct wl_shm *shm, struct buffer *buffer, int32_t width, int32_t height, uint32_t format, double scale)
|
||||||
{
|
{
|
||||||
int fd = -1;
|
int fd = -1;
|
||||||
struct wl_shm_pool *pool = NULL;
|
struct wl_shm_pool *pool = NULL;
|
||||||
@ -188,10 +189,10 @@ next_buffer(struct window *window)
|
|||||||
if (!buffer)
|
if (!buffer)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
if (window->width * window->scale != buffer->width || window->height * window->scale != buffer->height)
|
if ((uint32_t) ceil(window->width * window->scale) != buffer->width || (uint32_t) ceil(window->height * window->scale) != buffer->height)
|
||||||
destroy_buffer(buffer);
|
destroy_buffer(buffer);
|
||||||
|
|
||||||
if (!buffer->buffer && !create_buffer(window->shm, buffer, window->width * window->scale, window->height * window->scale, WL_SHM_FORMAT_ARGB8888, window->scale))
|
if (!buffer->buffer && !create_buffer(window->shm, buffer, ceil(window->width * window->scale), ceil(window->height * window->scale), WL_SHM_FORMAT_ARGB8888, window->scale))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
return buffer;
|
return buffer;
|
||||||
@ -258,17 +259,24 @@ bm_wl_window_render(struct window *window, struct wl_display *display, struct bm
|
|||||||
window->notify.render(&buffer->cairo, buffer->width, window->max_height, menu, &result);
|
window->notify.render(&buffer->cairo, buffer->width, window->max_height, menu, &result);
|
||||||
window->displayed = result.displayed;
|
window->displayed = result.displayed;
|
||||||
|
|
||||||
if (window->height == result.height / window->scale)
|
if (window->height == (uint32_t) ceil(result.height / window->scale))
|
||||||
break;
|
break;
|
||||||
|
|
||||||
window->height = result.height / window->scale;
|
window->height = ceil(result.height / window->scale);
|
||||||
zwlr_layer_surface_v1_set_size(window->layer_surface, window->width, window->height);
|
zwlr_layer_surface_v1_set_size(window->layer_surface, window->width, window->height);
|
||||||
destroy_buffer(buffer);
|
destroy_buffer(buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
assert(window->width * window->scale == buffer->width);
|
assert(ceil(window->width * window->scale) == buffer->width);
|
||||||
assert(window->height * window->scale == buffer->height);
|
assert(ceil(window->height * window->scale) == buffer->height);
|
||||||
wl_surface_set_buffer_scale(window->surface, window->scale);
|
|
||||||
|
if (window->wayland->fractional_scaling) {
|
||||||
|
assert(window->viewport_surface);
|
||||||
|
wp_viewport_set_destination(window->viewport_surface, window->width, window->height);
|
||||||
|
} else {
|
||||||
|
wl_surface_set_buffer_scale(window->surface, window->scale);
|
||||||
|
}
|
||||||
|
|
||||||
wl_surface_damage_buffer(window->surface, 0, 0, buffer->width, buffer->height);
|
wl_surface_damage_buffer(window->surface, 0, 0, buffer->width, buffer->height);
|
||||||
wl_surface_attach(window->surface, buffer->buffer, 0, 0);
|
wl_surface_attach(window->surface, buffer->buffer, 0, 0);
|
||||||
wl_surface_commit(window->surface);
|
wl_surface_commit(window->surface);
|
||||||
@ -323,6 +331,21 @@ get_window_width(struct window *window)
|
|||||||
return width;
|
return width;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
fractional_scale_preferred_scale(
|
||||||
|
void *data, struct wp_fractional_scale_v1 *wp_fractional_scale_v1,
|
||||||
|
uint32_t scale)
|
||||||
|
{
|
||||||
|
(void)wp_fractional_scale_v1;
|
||||||
|
struct window *window = data;
|
||||||
|
|
||||||
|
window->scale = (double)scale / 120;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const struct wp_fractional_scale_v1_listener fractional_scale_listener = {
|
||||||
|
.preferred_scale = fractional_scale_preferred_scale,
|
||||||
|
};
|
||||||
|
|
||||||
static const struct zwlr_layer_surface_v1_listener layer_surface_listener = {
|
static const struct zwlr_layer_surface_v1_listener layer_surface_listener = {
|
||||||
.configure = layer_surface_configure,
|
.configure = layer_surface_configure,
|
||||||
.closed = layer_surface_closed,
|
.closed = layer_surface_closed,
|
||||||
@ -393,6 +416,17 @@ bm_wl_window_create(struct window *window, struct wl_display *display, struct wl
|
|||||||
{
|
{
|
||||||
assert(window);
|
assert(window);
|
||||||
|
|
||||||
|
struct wayland *wayland = window->wayland;
|
||||||
|
|
||||||
|
if (wayland->fractional_scaling) {
|
||||||
|
assert(wayland->wfs_mgr && wayland->viewporter);
|
||||||
|
|
||||||
|
struct wp_fractional_scale_v1 *wfs_surf = wp_fractional_scale_manager_v1_get_fractional_scale(wayland->wfs_mgr, surface);
|
||||||
|
wp_fractional_scale_v1_add_listener(
|
||||||
|
wfs_surf, &fractional_scale_listener, window);
|
||||||
|
window->viewport_surface = wp_viewporter_get_viewport(wayland->viewporter, surface);
|
||||||
|
}
|
||||||
|
|
||||||
enum zwlr_layer_shell_v1_layer layer = ZWLR_LAYER_SHELL_V1_LAYER_OVERLAY;
|
enum zwlr_layer_shell_v1_layer layer = ZWLR_LAYER_SHELL_V1_LAYER_OVERLAY;
|
||||||
if (layer_shell && (window->layer_surface = zwlr_layer_shell_v1_get_layer_surface(layer_shell, surface, output, layer, "menu"))) {
|
if (layer_shell && (window->layer_surface = zwlr_layer_shell_v1_get_layer_surface(layer_shell, surface, output, layer, "menu"))) {
|
||||||
zwlr_layer_surface_v1_add_listener(window->layer_surface, &layer_surface_listener, window);
|
zwlr_layer_surface_v1_add_listener(window->layer_surface, &layer_surface_listener, window);
|
||||||
|
Loading…
Reference in New Issue
Block a user