diff options
| author | Ivan Molodetskikh <yalterz@gmail.com> | 2024-11-02 09:33:44 +0300 |
|---|---|---|
| committer | Ivan Molodetskikh <yalterz@gmail.com> | 2024-11-02 10:53:55 +0300 |
| commit | 05d218113c1209f58b0dcdd415f1e095d4ff2b46 (patch) | |
| tree | 57a10521ada23b1974e67f144a02fd92ad6a2c40 | |
| parent | ef6af6adc1094db05d1df3953a18f6550816f71e (diff) | |
| download | niri-05d218113c1209f58b0dcdd415f1e095d4ff2b46.tar.gz niri-05d218113c1209f58b0dcdd415f1e095d4ff2b46.tar.bz2 niri-05d218113c1209f58b0dcdd415f1e095d4ff2b46.zip | |
Add gradient support for the insert hint
Implement it via FocusRing which already handles SolidColor vs. Border
render element.
| -rw-r--r-- | niri-config/src/lib.rs | 14 | ||||
| -rw-r--r-- | src/layout/insert_hint_element.rs | 61 | ||||
| -rw-r--r-- | src/layout/mod.rs | 1 | ||||
| -rw-r--r-- | src/layout/workspace.rs | 37 | ||||
| -rw-r--r-- | wiki/Configuration:-Layout.md | 4 |
5 files changed, 100 insertions, 17 deletions
diff --git a/niri-config/src/lib.rs b/niri-config/src/lib.rs index d8613def..042cf6ba 100644 --- a/niri-config/src/lib.rs +++ b/niri-config/src/lib.rs @@ -597,6 +597,8 @@ pub struct InsertHint { pub off: bool, #[knuffel(child, default = Self::default().color)] pub color: Color, + #[knuffel(child)] + pub gradient: Option<Gradient>, } impl Default for InsertHint { @@ -604,6 +606,7 @@ impl Default for InsertHint { Self { off: false, color: Color::from_rgba8_unpremul(127, 200, 255, 128), + gradient: None, } } } @@ -3051,6 +3054,7 @@ mod tests { insert-hint { color "rgb(255, 200, 127)" + gradient from="rgba(10, 20, 30, 1.0)" to="#0080ffff" relative-to="workspace-view" } } @@ -3253,6 +3257,16 @@ mod tests { insert_hint: InsertHint { off: false, color: Color::from_rgba8_unpremul(255, 200, 127, 255), + gradient: Some(Gradient { + from: Color::from_rgba8_unpremul(10, 20, 30, 255), + to: Color::from_rgba8_unpremul(0, 128, 255, 255), + angle: 180, + relative_to: GradientRelativeTo::WorkspaceView, + in_: GradientInterpolation { + color_space: GradientColorSpace::Srgb, + hue_interpolation: HueInterpolation::Shorter, + }, + }), }, preset_column_widths: vec![ PresetSize::Proportion(0.25), 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<f64, Logical>, + view_rect: Rectangle<f64, Logical>, + 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<f64, Logical>, + ) -> impl Iterator<Item = FocusRingRenderElement> { + 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<W: LayoutElement> { /// Indication where an interactively-moved window is about to be placed. insert_hint: Option<InsertHint>, - /// 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<Options>, @@ -173,6 +172,7 @@ niri_render_elements! { WorkspaceRenderElement<R> => { Tile = TileRenderElement<R>, ClosingWindow = ClosingWindowRenderElement, + InsertHint = InsertHintRenderElement, } } @@ -440,7 +440,7 @@ impl<W: LayoutElement> Workspace<W> { 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<W: LayoutElement> Workspace<W> { 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<W: LayoutElement> Workspace<W> { 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<W: LayoutElement> Workspace<W> { 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<W: LayoutElement> Workspace<W> { tile.update_shaders(); } } + + self.insert_hint_element.update_shaders(); } pub fn windows(&self) -> impl Iterator<Item = &W> + '_ { @@ -2672,14 +2681,10 @@ impl<W: LayoutElement> Workspace<W> { // 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), ); } } diff --git a/wiki/Configuration:-Layout.md b/wiki/Configuration:-Layout.md index 02921b48..c7a68835 100644 --- a/wiki/Configuration:-Layout.md +++ b/wiki/Configuration:-Layout.md @@ -45,6 +45,7 @@ layout { insert-hint { // off color "#ffc87f80" + // gradient from="#ffbb6680" to="#ffc88080" angle=45 relative-to="workspace-view" } struts { @@ -316,13 +317,14 @@ Settings for the window insert position hint during an interactive window move. `off` disables the insert hint altogether. -`color` lets you change the color of the hint and has the same syntax as colors in border and focus ring. +`color` and `gradient` let you change the color of the hint and have the same syntax as colors and gradients in border and focus ring. ```kdl layout { insert-hint { // off color "#ffc87f80" + gradient from="#ffbb6680" to="#ffc88080" angle=45 relative-to="workspace-view" } } ``` |
