feat: propagate nested output scale
This commit is contained in:
1 parent
4f5f88b06f
commit
59ad6d40b2
2 files changed
+75
-7
No files matched your search
@@ -9,7 +9,7 @@ use smithay::{
|
|||||||
},
|
},
|
||||||
reexports::wayland_server::{Resource, protocol::wl_surface::WlSurface},
|
reexports::wayland_server::{Resource, protocol::wl_surface::WlSurface},
|
||||||
wayland::{
|
wayland::{
|
||||||
compositor::with_states,
|
compositor::{TraversalAction, with_states, with_surface_tree_downward},
|
||||||
fractional_scale::{FractionalScaleHandler, with_fractional_scale},
|
fractional_scale::{FractionalScaleHandler, with_fractional_scale},
|
||||||
output::OutputHandler,
|
output::OutputHandler,
|
||||||
pointer_constraints::{
|
pointer_constraints::{
|
||||||
@@ -52,9 +52,40 @@ impl OutputHandler for Ferese {}
|
|||||||
|
|
||||||
impl FractionalScaleHandler for Ferese {
|
impl FractionalScaleHandler for Ferese {
|
||||||
fn new_fractional_scale(&mut self, surface: WlSurface) {
|
fn new_fractional_scale(&mut self, surface: WlSurface) {
|
||||||
|
let scale = self
|
||||||
|
.space
|
||||||
|
.outputs()
|
||||||
|
.next()
|
||||||
|
.map(|output| output.current_scale().fractional_scale())
|
||||||
|
.unwrap_or(1.0);
|
||||||
|
|
||||||
with_states(&surface, |states| {
|
with_states(&surface, |states| {
|
||||||
with_fractional_scale(states, |scale| scale.set_preferred_scale(1.0));
|
with_fractional_scale(states, |surface_scale| {
|
||||||
|
surface_scale.set_preferred_scale(scale);
|
||||||
});
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Ferese {
|
||||||
|
pub fn update_fractional_scale(&self, scale: f64) {
|
||||||
|
for window in self.space.elements() {
|
||||||
|
let Some(toplevel) = window.toplevel() else {
|
||||||
|
continue;
|
||||||
|
};
|
||||||
|
|
||||||
|
with_surface_tree_downward(
|
||||||
|
toplevel.wl_surface(),
|
||||||
|
(),
|
||||||
|
|_, _, &()| TraversalAction::DoChildren(()),
|
||||||
|
|_, states, &()| {
|
||||||
|
with_fractional_scale(states, |surface_scale| {
|
||||||
|
surface_scale.set_preferred_scale(scale);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|_, _, &()| true,
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+42
-5
@@ -9,7 +9,7 @@ use smithay::{
|
|||||||
winit::{self, WinitEvent},
|
winit::{self, WinitEvent},
|
||||||
},
|
},
|
||||||
desktop::utils::OutputPresentationFeedback,
|
desktop::utils::OutputPresentationFeedback,
|
||||||
output::{Mode, Output, PhysicalProperties, Subpixel},
|
output::{Mode, Output, PhysicalProperties, Scale, Subpixel},
|
||||||
reexports::calloop::EventLoop,
|
reexports::calloop::EventLoop,
|
||||||
reexports::wayland_protocols::wp::presentation_time::server::wp_presentation_feedback::Kind,
|
reexports::wayland_protocols::wp::presentation_time::server::wp_presentation_feedback::Kind,
|
||||||
utils::{Clock, Monotonic, Rectangle, Transform},
|
utils::{Clock, Monotonic, Rectangle, Transform},
|
||||||
@@ -20,6 +20,7 @@ use crate::Ferese;
|
|||||||
|
|
||||||
pub fn init(event_loop: &mut EventLoop<Ferese>, state: &mut Ferese) -> Result<(), Box<dyn Error>> {
|
pub fn init(event_loop: &mut EventLoop<Ferese>, state: &mut Ferese) -> Result<(), Box<dyn Error>> {
|
||||||
let (mut backend, event_source) = winit::init()?;
|
let (mut backend, event_source) = winit::init()?;
|
||||||
|
let initial_scale = normalized_scale(backend.scale_factor());
|
||||||
let mode = Mode {
|
let mode = Mode {
|
||||||
size: backend.window_size(),
|
size: backend.window_size(),
|
||||||
refresh: 60_000,
|
refresh: 60_000,
|
||||||
@@ -37,7 +38,7 @@ pub fn init(event_loop: &mut EventLoop<Ferese>, state: &mut Ferese) -> Result<()
|
|||||||
output.change_current_state(
|
output.change_current_state(
|
||||||
Some(mode),
|
Some(mode),
|
||||||
Some(Transform::Flipped180),
|
Some(Transform::Flipped180),
|
||||||
None,
|
Some(Scale::Fractional(initial_scale)),
|
||||||
Some((0, 0).into()),
|
Some((0, 0).into()),
|
||||||
);
|
);
|
||||||
output.set_preferred(mode);
|
output.set_preferred(mode);
|
||||||
@@ -46,18 +47,29 @@ pub fn init(event_loop: &mut EventLoop<Ferese>, state: &mut Ferese) -> Result<()
|
|||||||
let mut damage_tracker = OutputDamageTracker::from_output(&output);
|
let mut damage_tracker = OutputDamageTracker::from_output(&output);
|
||||||
let clock = Clock::<Monotonic>::new();
|
let clock = Clock::<Monotonic>::new();
|
||||||
let mut sequence = 0_u64;
|
let mut sequence = 0_u64;
|
||||||
|
let mut output_scale = initial_scale;
|
||||||
|
|
||||||
event_loop
|
event_loop
|
||||||
.handle()
|
.handle()
|
||||||
.insert_source(event_source, move |event, _, state| match event {
|
.insert_source(event_source, move |event, _, state| match event {
|
||||||
WinitEvent::Resized { size, .. } => output.change_current_state(
|
WinitEvent::Resized { size, scale_factor } => {
|
||||||
|
let scale = normalized_scale(scale_factor);
|
||||||
|
|
||||||
|
output.change_current_state(
|
||||||
Some(Mode {
|
Some(Mode {
|
||||||
size,
|
size,
|
||||||
refresh: 60_000,
|
refresh: 60_000,
|
||||||
}),
|
}),
|
||||||
None,
|
None,
|
||||||
|
Some(Scale::Fractional(scale)),
|
||||||
None,
|
None,
|
||||||
None,
|
);
|
||||||
),
|
|
||||||
|
if scale != output_scale {
|
||||||
|
output_scale = scale;
|
||||||
|
state.update_fractional_scale(scale);
|
||||||
|
}
|
||||||
|
}
|
||||||
WinitEvent::Input(event) => state.process_input_event(event),
|
WinitEvent::Input(event) => state.process_input_event(event),
|
||||||
WinitEvent::Redraw => {
|
WinitEvent::Redraw => {
|
||||||
let damage = Rectangle::from_size(backend.window_size());
|
let damage = Rectangle::from_size(backend.window_size());
|
||||||
@@ -124,3 +136,28 @@ pub fn init(event_loop: &mut EventLoop<Ferese>, state: &mut Ferese) -> Result<()
|
|||||||
})?;
|
})?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn normalized_scale(scale: f64) -> f64 {
|
||||||
|
if scale.is_finite() && scale > 0.0 {
|
||||||
|
scale
|
||||||
|
} else {
|
||||||
|
1.0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::normalized_scale;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn accepts_positive_finite_scale() {
|
||||||
|
assert_eq!(normalized_scale(1.25), 1.25);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn rejects_invalid_scale() {
|
||||||
|
assert_eq!(normalized_scale(0.0), 1.0);
|
||||||
|
assert_eq!(normalized_scale(f64::NAN), 1.0);
|
||||||
|
assert_eq!(normalized_scale(f64::INFINITY), 1.0);
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in new issue
Block a user