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
+3
View File
@@ -637,6 +637,8 @@ impl<W: LayoutElement> Layout<W> {
} }
pub fn update_output_size(&mut self, output: &Output) { 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 { let MonitorSet::Normal { monitors, .. } = &mut self.monitor_set else {
panic!() panic!()
}; };
@@ -648,6 +650,7 @@ impl<W: LayoutElement> Layout<W> {
for ws in &mut mon.workspaces { for ws in &mut mon.workspaces {
ws.set_view_size(view_size, working_area); ws.set_view_size(view_size, working_area);
ws.update_output_scale_transform();
} }
break; break;
+13 -3
View File
@@ -308,7 +308,7 @@ impl<W: LayoutElement> Workspace<W> {
fn enter_output_for_window(&self, window: &W) { fn enter_output_for_window(&self, window: &W) {
if let Some(output) = &self.output { if let Some(output) = &self.output {
prepare_for_output(window, output); set_preferred_scale_transform(window, output);
window.output_enter(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> { fn toplevel_bounds(&self) -> Size<i32, Logical> {
let mut border = 0; let mut border = 0;
if !self.options.border.off { if !self.options.border.off {
@@ -363,7 +372,7 @@ impl<W: LayoutElement> Workspace<W> {
let bounds = self.toplevel_bounds(); let bounds = self.toplevel_bounds();
if let Some(output) = self.output.as_ref() { 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| { 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 scale = output.current_scale().integer_scale();
let transform = output.current_transform(); let transform = output.current_transform();
window.set_preferred_scale_transform(scale, transform); window.set_preferred_scale_transform(scale, transform);
+33 -4
View File
@@ -41,7 +41,7 @@ use smithay::desktop::{
use smithay::input::keyboard::{Layout as KeyboardLayout, XkbContextHandler}; use smithay::input::keyboard::{Layout as KeyboardLayout, XkbContextHandler};
use smithay::input::pointer::{CursorIcon, CursorImageAttributes, CursorImageStatus, MotionEvent}; use smithay::input::pointer::{CursorIcon, CursorImageAttributes, CursorImageStatus, MotionEvent};
use smithay::input::{Seat, SeatState}; use smithay::input::{Seat, SeatState};
use smithay::output::Output; use smithay::output::{self, Output};
use smithay::reexports::calloop::generic::Generic; use smithay::reexports::calloop::generic::Generic;
use smithay::reexports::calloop::timer::{TimeoutAction, Timer}; use smithay::reexports::calloop::timer::{TimeoutAction, Timer};
use smithay::reexports::calloop::{ use smithay::reexports::calloop::{
@@ -587,11 +587,37 @@ impl State {
} }
if output_config_changed { 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.reposition_outputs(None);
} }
self.niri.queue_redraw_all(); self.niri.queue_redraw_all();
// FIXME: apply output scale and whatnot.
// FIXME: apply libinput device settings. // FIXME: apply libinput device settings.
// FIXME: apply xdg decoration 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 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_transform = output.current_transform();
let output_mode = output.current_mode().unwrap(); let output_mode = output.current_mode().unwrap();
let size = output_transform.transform_size(output_mode.size); 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.screenshot_ui.close();
self.cursor_manager self.cursor_manager
.set_cursor_image(CursorImageStatus::default_named()); .set_cursor_image(CursorImageStatus::default_named());
+7 -3
View File
@@ -41,6 +41,7 @@ pub enum ScreenshotUi {
pub struct OutputData { pub struct OutputData {
size: Size<i32, Physical>, size: Size<i32, Physical>,
scale: i32,
texture: GlesTexture, texture: GlesTexture,
texture_buffer: TextureBuffer<GlesTexture>, texture_buffer: TextureBuffer<GlesTexture>,
buffers: [SolidColorBuffer; 8], buffers: [SolidColorBuffer; 8],
@@ -106,10 +107,11 @@ impl ScreenshotUi {
let output_transform = output.current_transform(); let output_transform = output.current_transform();
let output_mode = output.current_mode().unwrap(); let output_mode = output.current_mode().unwrap();
let size = output_transform.transform_size(output_mode.size); let size = output_transform.transform_size(output_mode.size);
let scale = output.current_scale().integer_scale();
let texture_buffer = TextureBuffer::from_texture( let texture_buffer = TextureBuffer::from_texture(
renderer, renderer,
texture.clone(), texture.clone(),
output.current_scale().integer_scale(), scale,
Transform::Normal, Transform::Normal,
None, None,
); );
@@ -126,6 +128,7 @@ impl ScreenshotUi {
let locations = [Default::default(); 8]; let locations = [Default::default(); 8];
let data = OutputData { let data = OutputData {
size, size,
scale,
texture, texture,
texture_buffer, texture_buffer,
buffers, 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 { 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 { } else {
None None
} }