wayland: Wire up wp_fractional_scale

This commit is contained in:
Victoria Brekenfeld 2023-06-14 14:44:36 +02:00
parent c282c5c08e
commit 8dbdd4a13e
3 changed files with 86 additions and 3 deletions

View file

@ -53,6 +53,7 @@ use smithay::{
compositor::{CompositorClientState, CompositorState},
data_device::DataDeviceState,
dmabuf::{DmabufFeedback, DmabufState},
fractional_scale::{with_fractional_scale, FractionalScaleManagerState},
keyboard_shortcuts_inhibit::KeyboardShortcutsInhibitState,
output::OutputManagerState,
presentation::PresentationState,
@ -113,6 +114,7 @@ pub struct Common {
pub compositor_state: CompositorState,
pub data_device_state: DataDeviceState,
pub dmabuf_state: DmabufState,
pub fractional_scale_state: FractionalScaleManagerState,
pub keyboard_shortcuts_inhibit_state: KeyboardShortcutsInhibitState,
pub output_state: OutputManagerState,
pub output_configuration_state: OutputConfigurationState<State>,
@ -244,6 +246,7 @@ impl State {
let compositor_state = CompositorState::new::<Self>(dh);
let data_device_state = DataDeviceState::new::<Self>(dh);
let dmabuf_state = DmabufState::new();
let fractional_scale_state = FractionalScaleManagerState::new::<State>(dh);
let keyboard_shortcuts_inhibit_state = KeyboardShortcutsInhibitState::new::<Self>(dh);
let output_state = OutputManagerState::new_with_xdg_output::<Self>(dh);
let output_configuration_state = OutputConfigurationState::new(dh, |_| true);
@ -292,6 +295,7 @@ impl State {
compositor_state,
data_device_state,
dmabuf_state,
fractional_scale_state,
screencopy_state,
shm_state,
seat_state,
@ -450,7 +454,7 @@ impl Common {
if outputs_for_element.contains(&output) {
let window = mapped.active_window();
window.with_surfaces(|surface, states| {
update_surface_primary_scanout_output(
let primary_scanout_output = update_surface_primary_scanout_output(
surface,
output,
states,
@ -468,6 +472,12 @@ impl Common {
}
},
);
if let Some(output) = primary_scanout_output {
with_fractional_scale(states, |fraction_scale| {
fraction_scale
.set_preferred_scale(output.current_scale().fractional_scale());
});
}
});
window.send_frame(output, time, throttle, surface_primary_scanout_output);
if let Some(feedback) = window
@ -504,13 +514,19 @@ impl Common {
self.shell.override_redirect_windows.iter().for_each(|or| {
if let Some(wl_surface) = or.wl_surface() {
with_surfaces_surface_tree(&wl_surface, |surface, states| {
update_surface_primary_scanout_output(
let primary_scanout_output = update_surface_primary_scanout_output(
surface,
output,
states,
render_element_states,
default_primary_scanout_output_compare,
);
if let Some(output) = primary_scanout_output {
with_fractional_scale(states, |fraction_scale| {
fraction_scale
.set_preferred_scale(output.current_scale().fractional_scale());
});
}
});
send_frames_surface_tree(
&wl_surface,
@ -542,13 +558,19 @@ impl Common {
let map = smithay::desktop::layer_map_for_output(output);
for layer_surface in map.layers() {
layer_surface.with_surfaces(|surface, states| {
update_surface_primary_scanout_output(
let primary_scanout_output = update_surface_primary_scanout_output(
surface,
output,
states,
render_element_states,
default_primary_scanout_output_compare,
);
if let Some(output) = primary_scanout_output {
with_fractional_scale(states, |fraction_scale| {
fraction_scale
.set_preferred_scale(output.current_scale().fractional_scale());
});
}
});
layer_surface.send_frame(output, time, throttle, surface_primary_scanout_output);
if let Some(feedback) =

View file

@ -0,0 +1,60 @@
use crate::{state::State, utils::prelude::SeatExt};
use smithay::{
delegate_fractional_scale,
desktop::utils::surface_primary_scanout_output,
reexports::wayland_server::protocol::wl_surface::WlSurface,
wayland::{
compositor::{get_parent, with_states},
fractional_scale::{with_fractional_scale, FractionalScaleHandler},
},
};
impl FractionalScaleHandler for State {
fn new_fractional_scale(&mut self, surface: WlSurface) {
// Here we can set the initial fractional scale
//
// First we look if the surface already has a primary scan-out output, if not
// we test if the surface is a subsurface and try to use the primary scan-out output
// of the root surface. If the root also has no primary scan-out output we just try
// to use the first output of the toplevel.
// If the surface is the root we also try to use the first output of the toplevel.
//
// If all the above tests do not lead to a output we just use the active output
// of the last active seat (which will also be the output a toplevel will
// initially be placed on)
let mut root = surface.clone();
while let Some(parent) = get_parent(&root) {
root = parent;
}
with_states(&surface, |states| {
let output = surface_primary_scanout_output(&surface, states)
.or_else(|| {
if root != surface {
with_states(&root, |states| {
surface_primary_scanout_output(&root, states).or_else(|| {
self.common
.shell
.visible_outputs_for_surface(&surface)
.next()
})
})
} else {
self.common
.shell
.visible_outputs_for_surface(&surface)
.next()
}
})
.unwrap_or_else(|| {
let seat = self.common.last_active_seat();
seat.active_output()
});
with_fractional_scale(states, |fractional_scale| {
fractional_scale.set_preferred_scale(output.current_scale().fractional_scale());
});
});
}
}
delegate_fractional_scale!(State);

View file

@ -5,6 +5,7 @@ pub mod compositor;
pub mod data_device;
pub mod decoration;
pub mod dmabuf;
pub mod fractional_scale;
pub mod keyboard_shortcuts_inhibit;
pub mod layer_shell;
pub mod output;