Wayland fractional scaling (#7961)

This PR adds support for fractional scaling on Wayland.

Release Notes:

- N/A
This commit is contained in:
Roman 2024-02-19 08:22:03 +03:00 committed by GitHub
parent 4e1e26b696
commit bd137b01ad
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 91 additions and 21 deletions

View file

@ -11,6 +11,7 @@ use raw_window_handle::{
DisplayHandle, HandleError, HasDisplayHandle, HasWindowHandle, WindowHandle,
};
use wayland_client::{protocol::wl_surface, Proxy};
use wayland_protocols::wp::viewporter::client::wp_viewport;
use wayland_protocols::xdg::shell::client::xdg_toplevel;
use crate::platform::blade::BladeRenderer;
@ -38,6 +39,7 @@ pub(crate) struct Callbacks {
struct WaylandWindowInner {
renderer: BladeRenderer,
bounds: Bounds<i32>,
scale: f32,
input_handler: Option<PlatformInputHandler>,
}
@ -92,6 +94,7 @@ impl WaylandWindowInner {
Self {
renderer: BladeRenderer::new(gpu, extent),
bounds,
scale: 1.0,
input_handler: None,
}
}
@ -103,12 +106,14 @@ pub(crate) struct WaylandWindowState {
pub(crate) callbacks: Mutex<Callbacks>,
pub(crate) surface: Arc<wl_surface::WlSurface>,
pub(crate) toplevel: Arc<xdg_toplevel::XdgToplevel>,
viewport: Option<wp_viewport::WpViewport>,
}
impl WaylandWindowState {
pub(crate) fn new(
conn: &Arc<wayland_client::Connection>,
wl_surf: Arc<wl_surface::WlSurface>,
viewport: Option<wp_viewport::WpViewport>,
toplevel: Arc<xdg_toplevel::XdgToplevel>,
options: WindowOptions,
) -> Self {
@ -135,6 +140,7 @@ impl WaylandWindowState {
inner: Mutex::new(WaylandWindowInner::new(&Arc::clone(conn), &wl_surf, bounds)),
callbacks: Mutex::new(Callbacks::default()),
toplevel,
viewport,
}
}
@ -147,30 +153,40 @@ impl WaylandWindowState {
}
}
pub fn resize(&self, width: i32, height: i32) {
{
let mut inner = self.inner.lock();
inner.bounds.size.width = width;
inner.bounds.size.height = height;
inner
.renderer
.update_drawable_size(size(width as f64, height as f64));
}
let mut callbacks = self.callbacks.lock();
if let Some(ref mut fun) = callbacks.resize {
pub fn set_size_and_scale(&self, width: i32, height: i32, scale: f32) {
self.inner.lock().scale = scale;
self.inner.lock().bounds.size.width = width;
self.inner.lock().bounds.size.height = height;
self.inner.lock().renderer.update_drawable_size(size(
width as f64 * scale as f64,
height as f64 * scale as f64,
));
if let Some(ref mut fun) = self.callbacks.lock().resize {
fun(
Size {
width: px(width as f32),
height: px(height as f32),
},
1.0,
scale,
);
}
if let Some(ref mut fun) = callbacks.moved {
fun()
if let Some(viewport) = &self.viewport {
viewport.set_destination(width, height);
}
}
pub fn resize(&self, width: i32, height: i32) {
let scale = self.inner.lock().scale;
self.set_size_and_scale(width, height, scale);
}
pub fn rescale(&self, scale: f32) {
let bounds = self.inner.lock().bounds;
self.set_size_and_scale(bounds.size.width, bounds.size.height, scale)
}
pub fn close(&self) {
let mut callbacks = self.callbacks.lock();
if let Some(fun) = callbacks.close.take() {
@ -215,7 +231,6 @@ impl PlatformWindow for WaylandWindow {
WindowBounds::Maximized
}
// todo!(linux)
fn content_size(&self) -> Size<Pixels> {
let inner = self.0.inner.lock();
Size {
@ -224,9 +239,8 @@ impl PlatformWindow for WaylandWindow {
}
}
// todo!(linux)
fn scale_factor(&self) -> f32 {
1f32
self.0.inner.lock().scale
}
//todo!(linux)
@ -263,7 +277,6 @@ impl PlatformWindow for WaylandWindow {
self.0.inner.lock().input_handler = Some(input_handler);
}
//todo!(linux)
fn take_input_handler(&mut self) -> Option<PlatformInputHandler> {
self.0.inner.lock().input_handler.take()
}