Add live-reload of output scales

This commit is contained in:
Ivan Molodetskikh 2024-01-16 09:45:47 +04:00
parent 6ca3b6ddb5
commit 69907f123d
4 changed files with 56 additions and 10 deletions

View File

@ -637,6 +637,8 @@ impl<W: LayoutElement> Layout<W> {
}
pub fn update_output_size(&mut self, output: &Output) {
let _span = tracy_client::span!("Layout::update_output_size");
let MonitorSet::Normal { monitors, .. } = &mut self.monitor_set else {
panic!()
};
@ -648,6 +650,7 @@ impl<W: LayoutElement> Layout<W> {
for ws in &mut mon.workspaces {
ws.set_view_size(view_size, working_area);
ws.update_output_scale_transform();
}
break;

View File

@ -308,7 +308,7 @@ impl<W: LayoutElement> Workspace<W> {
fn enter_output_for_window(&self, window: &W) {
if let Some(output) = &self.output {
prepare_for_output(window, output);
set_preferred_scale_transform(window, output);
window.output_enter(output);
}
}
@ -330,6 +330,15 @@ impl<W: LayoutElement> Workspace<W> {
}
}
pub fn update_output_scale_transform(&mut self) {
let Some(output) = self.output.as_ref() else {
return;
};
for window in self.windows() {
set_preferred_scale_transform(window, output);
}
}
fn toplevel_bounds(&self) -> Size<i32, Logical> {
let mut border = 0;
if !self.options.border.off {
@ -363,7 +372,7 @@ impl<W: LayoutElement> Workspace<W> {
let bounds = self.toplevel_bounds();
if let Some(output) = self.output.as_ref() {
prepare_for_output(window, output);
set_preferred_scale_transform(window, output);
}
window.toplevel().with_pending_state(|state| {
@ -1626,7 +1635,8 @@ fn compute_new_view_offset(
}
}
fn prepare_for_output(window: &impl LayoutElement, output: &Output) {
fn set_preferred_scale_transform(window: &impl LayoutElement, output: &Output) {
// FIXME: cache this on the workspace.
let scale = output.current_scale().integer_scale();
let transform = output.current_transform();
window.set_preferred_scale_transform(scale, transform);

View File

@ -41,7 +41,7 @@ use smithay::desktop::{
use smithay::input::keyboard::{Layout as KeyboardLayout, XkbContextHandler};
use smithay::input::pointer::{CursorIcon, CursorImageAttributes, CursorImageStatus, MotionEvent};
use smithay::input::{Seat, SeatState};
use smithay::output::Output;
use smithay::output::{self, Output};
use smithay::reexports::calloop::generic::Generic;
use smithay::reexports::calloop::timer::{TimeoutAction, Timer};
use smithay::reexports::calloop::{
@ -587,11 +587,37 @@ impl State {
}
if output_config_changed {
let mut resized_outputs = vec![];
for output in self.niri.global_space.outputs() {
let name = output.name();
let scale = self
.niri
.config
.borrow()
.outputs
.iter()
.find(|o| o.name == name)
.map(|c| c.scale)
.unwrap_or(1.);
let scale = scale.clamp(1., 10.).ceil() as i32;
if output.current_scale().integer_scale() != scale {
output.change_current_state(
None,
None,
Some(output::Scale::Integer(scale)),
None,
);
resized_outputs.push(output.clone());
}
}
for output in resized_outputs {
self.niri.output_resized(output);
}
self.niri.reposition_outputs(None);
}
self.niri.queue_redraw_all();
// FIXME: apply output scale and whatnot.
// FIXME: apply libinput device settings.
// FIXME: apply xdg decoration settings.
}
@ -1168,11 +1194,14 @@ impl Niri {
}
// If the output size changed with an open screenshot UI, close the screenshot UI.
if let Some(old_size) = self.screenshot_ui.output_size(&output) {
if let Some((old_size, old_scale)) = self.screenshot_ui.output_size(&output) {
let output_transform = output.current_transform();
let output_mode = output.current_mode().unwrap();
let size = output_transform.transform_size(output_mode.size);
if old_size != size {
let scale = output.current_scale().integer_scale();
// FIXME: scale changes shouldn't matter but they currently do since I haven't quite
// figured out how to draw the screenshot textures in physical coordinates.
if old_size != size || old_scale != scale {
self.screenshot_ui.close();
self.cursor_manager
.set_cursor_image(CursorImageStatus::default_named());

View File

@ -41,6 +41,7 @@ pub enum ScreenshotUi {
pub struct OutputData {
size: Size<i32, Physical>,
scale: i32,
texture: GlesTexture,
texture_buffer: TextureBuffer<GlesTexture>,
buffers: [SolidColorBuffer; 8],
@ -106,10 +107,11 @@ impl ScreenshotUi {
let output_transform = output.current_transform();
let output_mode = output.current_mode().unwrap();
let size = output_transform.transform_size(output_mode.size);
let scale = output.current_scale().integer_scale();
let texture_buffer = TextureBuffer::from_texture(
renderer,
texture.clone(),
output.current_scale().integer_scale(),
scale,
Transform::Normal,
None,
);
@ -126,6 +128,7 @@ impl ScreenshotUi {
let locations = [Default::default(); 8];
let data = OutputData {
size,
scale,
texture,
texture_buffer,
buffers,
@ -330,9 +333,10 @@ impl ScreenshotUi {
}
}
pub fn output_size(&self, output: &Output) -> Option<Size<i32, Physical>> {
pub fn output_size(&self, output: &Output) -> Option<(Size<i32, Physical>, i32)> {
if let Self::Open { output_data, .. } = self {
Some(output_data.get(output)?.size)
let data = output_data.get(output)?;
Some((data.size, data.scale))
} else {
None
}