aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorIvan Molodetskikh <yalterz@gmail.com>2024-06-09 09:47:31 +0300
committerIvan Molodetskikh <yalterz@gmail.com>2024-06-10 18:08:00 +0300
commitbe62bd123ae44d92b2d74ca714a7f029faccc921 (patch)
treef653e7d76cd1a20454cd6581cb186e5955df3b78 /src
parent3c63be6261f3420008366b41b3df6d57b3ec3867 (diff)
downloadniri-be62bd123ae44d92b2d74ca714a7f029faccc921.tar.gz
niri-be62bd123ae44d92b2d74ca714a7f029faccc921.tar.bz2
niri-be62bd123ae44d92b2d74ca714a7f029faccc921.zip
ui/hotkey_overlay: Make fractional-scaling aware
Diffstat (limited to 'src')
-rw-r--r--src/ui/hotkey_overlay.rs104
1 files changed, 47 insertions, 57 deletions
diff --git a/src/ui/hotkey_overlay.rs b/src/ui/hotkey_overlay.rs
index 3db3879a..ac61e562 100644
--- a/src/ui/hotkey_overlay.rs
+++ b/src/ui/hotkey_overlay.rs
@@ -7,21 +7,21 @@ use std::rc::Rc;
use niri_config::{Action, Config, Key, Modifiers, Trigger};
use pangocairo::cairo::{self, ImageSurface};
use pangocairo::pango::{AttrColor, AttrInt, AttrList, AttrString, FontDescription, Weight};
-use smithay::backend::renderer::element::memory::{
- MemoryRenderBuffer, MemoryRenderBufferRenderElement,
-};
-use smithay::backend::renderer::element::utils::{Relocate, RelocateRenderElement};
use smithay::backend::renderer::element::Kind;
+use smithay::backend::renderer::gles::{GlesRenderer, GlesTexture};
use smithay::input::keyboard::xkb::keysym_get_name;
use smithay::output::{Output, WeakOutput};
use smithay::reexports::gbm::Format as Fourcc;
-use smithay::utils::{Physical, Size, Transform};
+use smithay::utils::{Scale, Transform};
use crate::input::CompositorMod;
+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 PADDING: i32 = 8;
-const MARGIN: i32 = PADDING * 2;
+// const MARGIN: i32 = PADDING * 2;
const FONT: &str = "sans 14px";
const BORDER: i32 = 4;
const LINE_INTERVAL: i32 = 2;
@@ -35,13 +35,9 @@ pub struct HotkeyOverlay {
}
pub struct RenderedOverlay {
- buffer: Option<MemoryRenderBuffer>,
- size: Size<i32, Physical>,
- scale: i32,
+ buffer: Option<TextureBuffer<GlesTexture>>,
}
-pub type HotkeyOverlayRenderElement<R> = RelocateRenderElement<MemoryRenderBufferRenderElement<R>>;
-
impl HotkeyOverlay {
pub fn new(config: Rc<RefCell<Config>>, comp_mod: CompositorMod) -> Self {
Self {
@@ -82,17 +78,13 @@ impl HotkeyOverlay {
&self,
renderer: &mut R,
output: &Output,
- ) -> Option<HotkeyOverlayRenderElement<R>> {
+ ) -> Option<PrimaryGpuTextureRenderElement> {
if !self.is_open {
return None;
}
- let scale = output.current_scale().integer_scale();
- let margin = MARGIN * scale;
-
- let output_transform = output.current_transform();
- let output_mode = output.current_mode().unwrap();
- let output_size = output_transform.transform_size(output_mode.size);
+ let scale = output.current_scale().fractional_scale();
+ let output_size = output_size(output);
let mut buffers = self.buffers.borrow_mut();
buffers.retain(|output, _| output.upgrade().is_some());
@@ -100,51 +92,52 @@ impl HotkeyOverlay {
// FIXME: should probably use the working area rather than view size.
let weak = output.downgrade();
if let Some(rendered) = buffers.get(&weak) {
- if rendered.scale != scale {
- buffers.remove(&weak);
+ if let Some(buffer) = &rendered.buffer {
+ if buffer.texture_scale() != Scale::from(scale) {
+ buffers.remove(&weak);
+ }
}
}
let rendered = buffers.entry(weak).or_insert_with(|| {
- render(&self.config.borrow(), self.comp_mod, scale).unwrap_or_else(|_| {
- // This can go negative but whatever, as long as there's no rerender loop.
- let mut size = output_size;
- size.w -= margin * 2;
- size.h -= margin * 2;
- RenderedOverlay {
- buffer: None,
- size,
- scale,
- }
- })
+ let renderer = renderer.as_gles_renderer();
+ render(renderer, &self.config.borrow(), self.comp_mod, scale)
+ .unwrap_or_else(|_| RenderedOverlay { buffer: None })
});
let buffer = rendered.buffer.as_ref()?;
- let elem = MemoryRenderBufferRenderElement::from_buffer(
- renderer,
- (0., 0.),
- buffer,
- Some(0.9),
+ let size = buffer.logical_size();
+ let location = (output_size.to_f64().to_point() - size.to_point()).downscale(2.);
+ let mut location = location.to_physical_precise_round(scale).to_logical(scale);
+ location.x = f64::max(0., location.x);
+ location.y = f64::max(0., location.y);
+
+ let elem = TextureRenderElement::from_texture_buffer(
+ buffer.clone(),
+ location,
+ 0.9,
None,
None,
Kind::Unspecified,
- )
- .ok()?;
-
- let x = (output_size.w / 2 - rendered.size.w / 2).max(0);
- let y = (output_size.h / 2 - rendered.size.h / 2).max(0);
- let elem = RelocateRenderElement::from_element(elem, (x, y), Relocate::Absolute);
+ );
- Some(elem)
+ Some(PrimaryGpuTextureRenderElement(elem))
}
}
-fn render(config: &Config, comp_mod: CompositorMod, scale: i32) -> anyhow::Result<RenderedOverlay> {
+fn render(
+ renderer: &mut GlesRenderer,
+ config: &Config,
+ comp_mod: CompositorMod,
+ scale: f64,
+) -> anyhow::Result<RenderedOverlay> {
let _span = tracy_client::span!("hotkey_overlay::render");
+ let apply_scale = |val: i32| (f64::from(val) * scale).round() as i32;
+
// let margin = MARGIN * scale;
- let padding = PADDING * scale;
- let line_interval = LINE_INTERVAL * scale;
+ let padding = apply_scale(PADDING);
+ let line_interval = apply_scale(LINE_INTERVAL);
// FIXME: if it doesn't fit, try splitting in two columns or something.
// let mut target_size = output_size;
@@ -254,7 +247,7 @@ fn render(config: &Config, comp_mod: CompositorMod, scale: i32) -> anyhow::Resul
.collect::<Vec<_>>();
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)?;
@@ -303,10 +296,6 @@ fn render(config: &Config, comp_mod: CompositorMod, scale: i32) -> anyhow::Resul
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);
@@ -348,24 +337,25 @@ fn render(config: &Config, comp_mod: CompositorMod, scale: i32) -> anyhow::Resul
cr.line_to(0., height.into());
cr.line_to(0., 0.);
cr.set_source_rgb(0.5, 0.8, 1.0);
- 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(
+ let buffer = TextureBuffer::from_memory(
+ renderer,
&data,
Fourcc::Argb8888,
(width, height),
+ false,
scale,
Transform::Normal,
- None,
- );
+ Vec::new(),
+ )?;
Ok(RenderedOverlay {
buffer: Some(buffer),
- size: Size::from((width, height)),
- scale,
})
}