From 05d218113c1209f58b0dcdd415f1e095d4ff2b46 Mon Sep 17 00:00:00 2001 From: Ivan Molodetskikh Date: Sat, 2 Nov 2024 09:33:44 +0300 Subject: Add gradient support for the insert hint Implement it via FocusRing which already handles SolidColor vs. Border render element. --- src/layout/insert_hint_element.rs | 61 +++++++++++++++++++++++++++++++++++++++ src/layout/mod.rs | 1 + src/layout/workspace.rs | 37 ++++++++++++++---------- 3 files changed, 83 insertions(+), 16 deletions(-) create mode 100644 src/layout/insert_hint_element.rs (limited to 'src') diff --git a/src/layout/insert_hint_element.rs b/src/layout/insert_hint_element.rs new file mode 100644 index 00000000..5f70295c --- /dev/null +++ b/src/layout/insert_hint_element.rs @@ -0,0 +1,61 @@ +use niri_config::{CornerRadius, FloatOrInt}; +use smithay::utils::{Logical, Point, Rectangle, Size}; + +use super::focus_ring::{FocusRing, FocusRingRenderElement}; +use crate::render_helpers::renderer::NiriRenderer; + +#[derive(Debug)] +pub struct InsertHintElement { + inner: FocusRing, +} + +pub type InsertHintRenderElement = FocusRingRenderElement; + +impl InsertHintElement { + pub fn new(config: niri_config::InsertHint) -> Self { + Self { + inner: FocusRing::new(niri_config::FocusRing { + off: config.off, + width: FloatOrInt(0.), + active_color: config.color, + inactive_color: config.color, + active_gradient: config.gradient, + inactive_gradient: config.gradient, + }), + } + } + + pub fn update_config(&mut self, config: niri_config::InsertHint) { + self.inner.update_config(niri_config::FocusRing { + off: config.off, + width: FloatOrInt(0.), + active_color: config.color, + inactive_color: config.color, + active_gradient: config.gradient, + inactive_gradient: config.gradient, + }); + } + + pub fn update_shaders(&mut self) { + self.inner.update_shaders(); + } + + pub fn update_render_elements( + &mut self, + size: Size, + view_rect: Rectangle, + radius: CornerRadius, + scale: f64, + ) { + self.inner + .update_render_elements(size, true, false, view_rect, radius, scale); + } + + pub fn render( + &self, + renderer: &mut impl NiriRenderer, + location: Point, + ) -> impl Iterator { + self.inner.render(renderer, location) + } +} diff --git a/src/layout/mod.rs b/src/layout/mod.rs index 1493152f..1c531b51 100644 --- a/src/layout/mod.rs +++ b/src/layout/mod.rs @@ -64,6 +64,7 @@ use crate::window::ResolvedWindowRules; pub mod closing_window; pub mod focus_ring; +pub mod insert_hint_element; pub mod monitor; pub mod opening_window; pub mod tile; diff --git a/src/layout/workspace.rs b/src/layout/workspace.rs index 0f378abc..c8b3d5ee 100644 --- a/src/layout/workspace.rs +++ b/src/layout/workspace.rs @@ -8,7 +8,6 @@ use niri_config::{ }; use niri_ipc::SizeChange; use ordered_float::NotNan; -use smithay::backend::renderer::element::Kind; use smithay::backend::renderer::gles::GlesRenderer; use smithay::desktop::{layer_map_for_output, Window}; use smithay::output::Output; @@ -17,13 +16,13 @@ use smithay::reexports::wayland_server::protocol::wl_surface::WlSurface; use smithay::utils::{Logical, Point, Rectangle, Scale, Serial, Size, Transform}; use super::closing_window::{ClosingWindow, ClosingWindowRenderElement}; +use super::insert_hint_element::{InsertHintElement, InsertHintRenderElement}; use super::tile::{Tile, TileRenderElement, TileRenderSnapshot}; use super::{ConfigureIntent, InteractiveResizeData, LayoutElement, Options, RemovedTile}; use crate::animation::Animation; use crate::input::swipe_tracker::SwipeTracker; use crate::niri_render_elements; use crate::render_helpers::renderer::NiriRenderer; -use crate::render_helpers::solid_color::{SolidColorBuffer, SolidColorRenderElement}; use crate::render_helpers::RenderTarget; use crate::utils::id::IdCounter; use crate::utils::transaction::{Transaction, TransactionBlocker}; @@ -111,8 +110,8 @@ pub struct Workspace { /// Indication where an interactively-moved window is about to be placed. insert_hint: Option, - /// Buffer for the insert hint. - insert_hint_buffer: SolidColorBuffer, + /// Insert hint element for rendering. + insert_hint_element: InsertHintElement, /// Configurable properties of the layout as received from the parent monitor. pub(super) base_options: Rc, @@ -173,6 +172,7 @@ niri_render_elements! { WorkspaceRenderElement => { Tile = TileRenderElement, ClosingWindow = ClosingWindowRenderElement, + InsertHint = InsertHintRenderElement, } } @@ -440,7 +440,7 @@ impl Workspace { view_offset_before_fullscreen: None, closing_windows: vec![], insert_hint: None, - insert_hint_buffer: SolidColorBuffer::new((0., 0.), [0., 0., 0., 1.]), + insert_hint_element: InsertHintElement::new(options.insert_hint), base_options, options, name: config.map(|c| c.name.0), @@ -480,7 +480,7 @@ impl Workspace { view_offset_before_fullscreen: None, closing_windows: vec![], insert_hint: None, - insert_hint_buffer: SolidColorBuffer::new((0., 0.), [0., 0., 0., 1.]), + insert_hint_element: InsertHintElement::new(options.insert_hint), base_options, options, name: config.map(|c| c.name.0), @@ -562,8 +562,13 @@ impl Workspace { if let Some(insert_hint) = &self.insert_hint { if let Some(area) = self.insert_hint_area(insert_hint) { - self.insert_hint_buffer - .update(area.size, self.options.insert_hint.color.to_array_premul()); + let view_rect = Rectangle::from_loc_and_size(area.loc.upscale(-1.), view_size); + self.insert_hint_element.update_render_elements( + area.size, + view_rect, + Default::default(), + self.scale.fractional_scale(), + ); } } } @@ -577,6 +582,8 @@ impl Workspace { data.update(column); } + self.insert_hint_element.update_config(options.insert_hint); + self.base_options = base_options; self.options = options; } @@ -587,6 +594,8 @@ impl Workspace { tile.update_shaders(); } } + + self.insert_hint_element.update_shaders(); } pub fn windows(&self) -> impl Iterator + '_ { @@ -2672,14 +2681,10 @@ impl Workspace { // Draw the insert hint. if let Some(insert_hint) = &self.insert_hint { if let Some(area) = self.insert_hint_area(insert_hint) { - rv.push( - TileRenderElement::SolidColor(SolidColorRenderElement::from_buffer( - &self.insert_hint_buffer, - area.loc, - 1., - Kind::Unspecified, - )) - .into(), + rv.extend( + self.insert_hint_element + .render(renderer, area.loc) + .map(WorkspaceRenderElement::InsertHint), ); } } -- cgit