diff options
| author | Ivan Molodetskikh <yalterz@gmail.com> | 2024-06-09 10:41:07 +0300 |
|---|---|---|
| committer | Ivan Molodetskikh <yalterz@gmail.com> | 2024-06-10 18:08:01 +0300 |
| commit | a1563b9132c3ba49ed80dbb9011846ea0c825caf (patch) | |
| tree | 86bb112d7600d212697b341bf09c93c91d09f3b7 /src | |
| parent | 98aea9579f371e85577aa0b04c11eed15686fc6f (diff) | |
| download | niri-a1563b9132c3ba49ed80dbb9011846ea0c825caf.tar.gz niri-a1563b9132c3ba49ed80dbb9011846ea0c825caf.tar.bz2 niri-a1563b9132c3ba49ed80dbb9011846ea0c825caf.zip | |
ui/config_error_notification: Make fractional-scaling aware
Diffstat (limited to 'src')
| -rw-r--r-- | src/ui/config_error_notification.rs | 91 |
1 files changed, 40 insertions, 51 deletions
diff --git a/src/ui/config_error_notification.rs b/src/ui/config_error_notification.rs index 1331b912..cdef5d6e 100644 --- a/src/ui/config_error_notification.rs +++ b/src/ui/config_error_notification.rs @@ -5,19 +5,20 @@ use std::rc::Rc; use std::time::Duration; use niri_config::Config; +use ordered_float::NotNan; use pangocairo::cairo::{self, ImageSurface}; use pangocairo::pango::FontDescription; -use smithay::backend::renderer::element::memory::{ - MemoryRenderBuffer, MemoryRenderBufferRenderElement, -}; -use smithay::backend::renderer::element::utils::{Relocate, RelocateRenderElement}; -use smithay::backend::renderer::element::{Element, Kind}; +use smithay::backend::renderer::element::Kind; use smithay::output::Output; use smithay::reexports::gbm::Format as Fourcc; -use smithay::utils::Transform; +use smithay::utils::{Point, Transform}; use crate::animation::Animation; +use crate::render_helpers::memory::MemoryBuffer; +use crate::render_helpers::primary_gpu_texture::PrimaryGpuTextureRenderElement; use crate::render_helpers::renderer::NiriRenderer; +use crate::render_helpers::texture::{TextureBuffer, TextureRenderElement}; +use crate::utils::output_size; const TEXT: &str = "Failed to parse the config file. \ Please run <span face='monospace' bgcolor='#000000'>niri validate</span> \ @@ -28,7 +29,7 @@ const BORDER: i32 = 4; pub struct ConfigErrorNotification { state: State, - buffers: RefCell<HashMap<i32, Option<MemoryRenderBuffer>>>, + buffers: RefCell<HashMap<NotNan<f64>, Option<MemoryBuffer>>>, // If set, this is a "Created config at {path}" notification. If unset, this is a config error // notification. @@ -44,9 +45,6 @@ enum State { Hiding(Animation), } -pub type ConfigErrorNotificationRenderElement<R> = - RelocateRenderElement<MemoryRenderBufferRenderElement<R>>; - impl ConfigErrorNotification { pub fn new(config: Rc<RefCell<Config>>) -> Self { Self { @@ -128,59 +126,54 @@ impl ConfigErrorNotification { &self, renderer: &mut R, output: &Output, - ) -> Option<ConfigErrorNotificationRenderElement<R>> { + ) -> Option<PrimaryGpuTextureRenderElement> { if matches!(self.state, State::Hidden) { return None; } - let scale = output.current_scale().integer_scale(); + let scale = output.current_scale().fractional_scale(); + let output_size = output_size(output); let path = self.created_path.as_deref(); let mut buffers = self.buffers.borrow_mut(); let buffer = buffers - .entry(scale) - .or_insert_with_key(move |&scale| render(scale, path).ok()); + .entry(NotNan::new(scale).unwrap()) + .or_insert_with(move || render(scale, path).ok()); let buffer = buffer.as_ref()?; - let elem = MemoryRenderBufferRenderElement::from_buffer( - renderer, - (0., 0.), - buffer, - Some(0.9), - None, - None, - Kind::Unspecified, - ) - .ok()?; - - let output_transform = output.current_transform(); - let output_mode = output.current_mode().unwrap(); - let output_size = output_transform.transform_size(output_mode.size); + let size = buffer.logical_size(); + let buffer = TextureBuffer::from_memory_buffer(renderer.as_gles_renderer(), buffer).ok()?; - let buffer_size = elem - .geometry(output.current_scale().fractional_scale().into()) - .size; + let y_range = size.h + f64::from(PADDING) * 2.; - let y_range = buffer_size.h + PADDING * 2 * scale; - - let x = (output_size.w / 2 - buffer_size.w / 2).max(0); + let x = (f64::from(output_size.w) - size.w).max(0.) / 2.; let y = match &self.state { State::Hidden => unreachable!(), - State::Showing(anim) | State::Hiding(anim) => { - (-buffer_size.h as f64 + anim.value() * y_range as f64).round() as i32 - } - State::Shown(_) => PADDING * 2 * scale, + State::Showing(anim) | State::Hiding(anim) => -size.h + anim.value() * y_range, + State::Shown(_) => f64::from(PADDING) * 2., }; - let elem = RelocateRenderElement::from_element(elem, (x, y), Relocate::Absolute); - Some(elem) + let location = Point::from((x, y)); + let location = location.to_physical_precise_round(scale).to_logical(scale); + + let elem = TextureRenderElement::from_texture_buffer( + buffer, + location, + 1., + None, + None, + Kind::Unspecified, + ); + Some(PrimaryGpuTextureRenderElement(elem)) } } -fn render(scale: i32, created_path: Option<&Path>) -> anyhow::Result<MemoryRenderBuffer> { +fn render(scale: f64, created_path: Option<&Path>) -> anyhow::Result<MemoryBuffer> { let _span = tracy_client::span!("config_error_notification::render"); - let padding = PADDING * scale; + let apply_scale = |val: i32| (f64::from(val) * scale).round() as i32; + + let padding = apply_scale(PADDING); let mut text = String::from(TEXT); let mut border_color = (1., 0.3, 0.3); @@ -194,7 +187,7 @@ fn render(scale: i32, created_path: Option<&Path>) -> anyhow::Result<MemoryRende }; let mut font = FontDescription::from_string(FONT); - font.set_absolute_size((font.size() * scale).into()); + font.set_absolute_size(apply_scale(font.size()).into()); let surface = ImageSurface::create(cairo::Format::ARgb32, 0, 0)?; let cr = cairo::Context::new(&surface)?; @@ -206,10 +199,6 @@ fn render(scale: i32, created_path: Option<&Path>) -> anyhow::Result<MemoryRende width += padding * 2; height += padding * 2; - // FIXME: fix bug in Smithay that rounds pixel sizes down to scale. - width = (width + scale - 1) / scale * scale; - height = (height + scale - 1) / scale * scale; - let surface = ImageSurface::create(cairo::Format::ARgb32, width, height)?; let cr = cairo::Context::new(&surface)?; cr.set_source_rgb(0.1, 0.1, 0.1); @@ -229,18 +218,18 @@ fn render(scale: i32, created_path: Option<&Path>) -> anyhow::Result<MemoryRende cr.line_to(0., height.into()); cr.line_to(0., 0.); cr.set_source_rgb(border_color.0, border_color.1, border_color.2); - cr.set_line_width((BORDER * scale).into()); + // Keep the border width even to avoid blurry edges. + cr.set_line_width((f64::from(BORDER) / 2. * scale).round() * 2.); cr.stroke()?; drop(cr); let data = surface.take_data().unwrap(); - let buffer = MemoryRenderBuffer::from_slice( - &data, + let buffer = MemoryBuffer::new( + data.to_vec(), Fourcc::Argb8888, (width, height), scale, Transform::Normal, - None, ); Ok(buffer) |
