mirror of
https://github.com/YaLTeR/niri.git
synced 2025-10-06 00:23:14 +02:00
Move background rendering to Workspace
Per-output background-color doesn't work yet.
This commit is contained in:
@@ -272,7 +272,7 @@ impl TestCase for Layout {
|
|||||||
.monitor_for_output(&self.output)
|
.monitor_for_output(&self.output)
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.render_elements(renderer, RenderTarget::Output, true)
|
.render_elements(renderer, RenderTarget::Output, true)
|
||||||
.flat_map(|(_, iter)| iter)
|
.flat_map(|(_, _, iter)| iter)
|
||||||
.map(|elem| Box::new(elem) as _)
|
.map(|elem| Box::new(elem) as _)
|
||||||
.collect()
|
.collect()
|
||||||
}
|
}
|
||||||
|
@@ -23,6 +23,7 @@ use crate::input::swipe_tracker::SwipeTracker;
|
|||||||
use crate::niri_render_elements;
|
use crate::niri_render_elements;
|
||||||
use crate::render_helpers::renderer::NiriRenderer;
|
use crate::render_helpers::renderer::NiriRenderer;
|
||||||
use crate::render_helpers::shadow::ShadowRenderElement;
|
use crate::render_helpers::shadow::ShadowRenderElement;
|
||||||
|
use crate::render_helpers::solid_color::SolidColorRenderElement;
|
||||||
use crate::render_helpers::RenderTarget;
|
use crate::render_helpers::RenderTarget;
|
||||||
use crate::rubber_band::RubberBand;
|
use crate::rubber_band::RubberBand;
|
||||||
use crate::utils::transaction::Transaction;
|
use crate::utils::transaction::Transaction;
|
||||||
@@ -175,6 +176,7 @@ niri_render_elements! {
|
|||||||
InsertHint = CropRenderElement<InsertHintRenderElement>,
|
InsertHint = CropRenderElement<InsertHintRenderElement>,
|
||||||
UncroppedInsertHint = InsertHintRenderElement,
|
UncroppedInsertHint = InsertHintRenderElement,
|
||||||
Shadow = ShadowRenderElement,
|
Shadow = ShadowRenderElement,
|
||||||
|
SolidColor = SolidColorRenderElement,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1619,6 +1621,7 @@ impl<W: LayoutElement> Monitor<W> {
|
|||||||
) -> impl Iterator<
|
) -> impl Iterator<
|
||||||
Item = (
|
Item = (
|
||||||
Rectangle<f64, Logical>,
|
Rectangle<f64, Logical>,
|
||||||
|
MonitorRenderElement<R>,
|
||||||
impl Iterator<Item = MonitorRenderElement<R>> + 'a,
|
impl Iterator<Item = MonitorRenderElement<R>> + 'a,
|
||||||
),
|
),
|
||||||
> {
|
> {
|
||||||
@@ -1692,7 +1695,7 @@ impl<W: LayoutElement> Monitor<W> {
|
|||||||
|
|
||||||
let iter = floating.chain(hint).chain(scrolling);
|
let iter = floating.chain(hint).chain(scrolling);
|
||||||
|
|
||||||
let iter = iter.map(move |elem| {
|
let scale_relocate = move |elem| {
|
||||||
let elem = RescaleRenderElement::from_element(elem, Point::from((0, 0)), zoom);
|
let elem = RescaleRenderElement::from_element(elem, Point::from((0, 0)), zoom);
|
||||||
RelocateRenderElement::from_element(
|
RelocateRenderElement::from_element(
|
||||||
elem,
|
elem,
|
||||||
@@ -1702,9 +1705,14 @@ impl<W: LayoutElement> Monitor<W> {
|
|||||||
geo.loc.to_physical_precise_round(scale),
|
geo.loc.to_physical_precise_round(scale),
|
||||||
Relocate::Relative,
|
Relocate::Relative,
|
||||||
)
|
)
|
||||||
});
|
};
|
||||||
|
|
||||||
(geo, iter)
|
let iter = iter.map(scale_relocate);
|
||||||
|
|
||||||
|
let background = ws.render_background();
|
||||||
|
let background = scale_relocate(MonitorInnerRenderElement::SolidColor(background));
|
||||||
|
|
||||||
|
(geo, background, iter)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -6,6 +6,7 @@ use niri_config::{
|
|||||||
CenterFocusedColumn, CornerRadius, OutputName, PresetSize, Workspace as WorkspaceConfig,
|
CenterFocusedColumn, CornerRadius, OutputName, PresetSize, Workspace as WorkspaceConfig,
|
||||||
};
|
};
|
||||||
use niri_ipc::{ColumnDisplay, PositionChange, SizeChange, WindowLayout};
|
use niri_ipc::{ColumnDisplay, PositionChange, SizeChange, WindowLayout};
|
||||||
|
use smithay::backend::renderer::element::Kind;
|
||||||
use smithay::backend::renderer::gles::GlesRenderer;
|
use smithay::backend::renderer::gles::GlesRenderer;
|
||||||
use smithay::desktop::{layer_map_for_output, Window};
|
use smithay::desktop::{layer_map_for_output, Window};
|
||||||
use smithay::output::Output;
|
use smithay::output::Output;
|
||||||
@@ -29,6 +30,7 @@ use crate::animation::Clock;
|
|||||||
use crate::niri_render_elements;
|
use crate::niri_render_elements;
|
||||||
use crate::render_helpers::renderer::NiriRenderer;
|
use crate::render_helpers::renderer::NiriRenderer;
|
||||||
use crate::render_helpers::shadow::ShadowRenderElement;
|
use crate::render_helpers::shadow::ShadowRenderElement;
|
||||||
|
use crate::render_helpers::solid_color::{SolidColorBuffer, SolidColorRenderElement};
|
||||||
use crate::render_helpers::RenderTarget;
|
use crate::render_helpers::RenderTarget;
|
||||||
use crate::utils::id::IdCounter;
|
use crate::utils::id::IdCounter;
|
||||||
use crate::utils::transaction::{Transaction, TransactionBlocker};
|
use crate::utils::transaction::{Transaction, TransactionBlocker};
|
||||||
@@ -87,6 +89,9 @@ pub struct Workspace<W: LayoutElement> {
|
|||||||
/// This workspace's shadow in the overview.
|
/// This workspace's shadow in the overview.
|
||||||
shadow: Shadow,
|
shadow: Shadow,
|
||||||
|
|
||||||
|
/// This workspace's background.
|
||||||
|
background_buffer: SolidColorBuffer,
|
||||||
|
|
||||||
/// Clock for driving animations.
|
/// Clock for driving animations.
|
||||||
pub(super) clock: Clock,
|
pub(super) clock: Clock,
|
||||||
|
|
||||||
@@ -246,6 +251,8 @@ impl<W: LayoutElement> Workspace<W> {
|
|||||||
let shadow_config =
|
let shadow_config =
|
||||||
compute_workspace_shadow_config(options.overview.workspace_shadow, view_size);
|
compute_workspace_shadow_config(options.overview.workspace_shadow, view_size);
|
||||||
|
|
||||||
|
let background_color = options.layout.background_color.to_array_unpremul();
|
||||||
|
|
||||||
Self {
|
Self {
|
||||||
scrolling,
|
scrolling,
|
||||||
floating,
|
floating,
|
||||||
@@ -256,6 +263,7 @@ impl<W: LayoutElement> Workspace<W> {
|
|||||||
view_size,
|
view_size,
|
||||||
working_area,
|
working_area,
|
||||||
shadow: Shadow::new(shadow_config),
|
shadow: Shadow::new(shadow_config),
|
||||||
|
background_buffer: SolidColorBuffer::new(view_size, background_color),
|
||||||
output: Some(output),
|
output: Some(output),
|
||||||
clock,
|
clock,
|
||||||
base_options,
|
base_options,
|
||||||
@@ -309,6 +317,8 @@ impl<W: LayoutElement> Workspace<W> {
|
|||||||
let shadow_config =
|
let shadow_config =
|
||||||
compute_workspace_shadow_config(options.overview.workspace_shadow, view_size);
|
compute_workspace_shadow_config(options.overview.workspace_shadow, view_size);
|
||||||
|
|
||||||
|
let background_color = options.layout.background_color.to_array_unpremul();
|
||||||
|
|
||||||
Self {
|
Self {
|
||||||
scrolling,
|
scrolling,
|
||||||
floating,
|
floating,
|
||||||
@@ -320,6 +330,7 @@ impl<W: LayoutElement> Workspace<W> {
|
|||||||
view_size,
|
view_size,
|
||||||
working_area,
|
working_area,
|
||||||
shadow: Shadow::new(shadow_config),
|
shadow: Shadow::new(shadow_config),
|
||||||
|
background_buffer: SolidColorBuffer::new(view_size, background_color),
|
||||||
clock,
|
clock,
|
||||||
base_options,
|
base_options,
|
||||||
options,
|
options,
|
||||||
@@ -409,6 +420,9 @@ impl<W: LayoutElement> Workspace<W> {
|
|||||||
compute_workspace_shadow_config(options.overview.workspace_shadow, self.view_size);
|
compute_workspace_shadow_config(options.overview.workspace_shadow, self.view_size);
|
||||||
self.shadow.update_config(shadow_config);
|
self.shadow.update_config(shadow_config);
|
||||||
|
|
||||||
|
let background_color = options.layout.background_color.to_array_unpremul();
|
||||||
|
self.background_buffer.set_color(background_color);
|
||||||
|
|
||||||
self.base_options = base_options;
|
self.base_options = base_options;
|
||||||
self.options = options;
|
self.options = options;
|
||||||
}
|
}
|
||||||
@@ -563,6 +577,8 @@ impl<W: LayoutElement> Workspace<W> {
|
|||||||
self.shadow.update_config(shadow_config);
|
self.shadow.update_config(shadow_config);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
self.background_buffer.resize(size);
|
||||||
|
|
||||||
if scale_transform_changed {
|
if scale_transform_changed {
|
||||||
for window in self.windows() {
|
for window in self.windows() {
|
||||||
window.set_preferred_scale_transform(self.scale, self.transform);
|
window.set_preferred_scale_transform(self.scale, self.transform);
|
||||||
@@ -1513,6 +1529,15 @@ impl<W: LayoutElement> Workspace<W> {
|
|||||||
self.shadow.render(renderer, Point::from((0., 0.)))
|
self.shadow.render(renderer, Point::from((0., 0.)))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn render_background(&self) -> SolidColorRenderElement {
|
||||||
|
SolidColorRenderElement::from_buffer(
|
||||||
|
&self.background_buffer,
|
||||||
|
Point::new(0., 0.),
|
||||||
|
1.,
|
||||||
|
Kind::Unspecified,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
pub fn render_above_top_layer(&self) -> bool {
|
pub fn render_above_top_layer(&self) -> bool {
|
||||||
self.scrolling.render_above_top_layer()
|
self.scrolling.render_above_top_layer()
|
||||||
}
|
}
|
||||||
@@ -1831,6 +1856,12 @@ impl<W: LayoutElement> Workspace<W> {
|
|||||||
assert!(self.view_size.w > 0.);
|
assert!(self.view_size.w > 0.);
|
||||||
assert!(self.view_size.h > 0.);
|
assert!(self.view_size.h > 0.);
|
||||||
|
|
||||||
|
assert_eq!(self.background_buffer.size(), self.view_size);
|
||||||
|
assert_eq!(
|
||||||
|
self.background_buffer.color().components(),
|
||||||
|
options.layout.background_color.to_array_unpremul(),
|
||||||
|
);
|
||||||
|
|
||||||
assert_eq!(self.view_size, self.scrolling.view_size());
|
assert_eq!(self.view_size, self.scrolling.view_size());
|
||||||
assert_eq!(self.working_area, self.scrolling.parent_area());
|
assert_eq!(self.working_area, self.scrolling.parent_area());
|
||||||
assert_eq!(&self.clock, self.scrolling.clock());
|
assert_eq!(&self.clock, self.scrolling.clock());
|
||||||
|
51
src/niri.rs
51
src/niri.rs
@@ -474,9 +474,8 @@ pub struct OutputState {
|
|||||||
/// would occur, based on the last presentation time and output refresh interval. Sequence
|
/// would occur, based on the last presentation time and output refresh interval. Sequence
|
||||||
/// is incremented in that timer, before attempting a redraw or sending frame callbacks.
|
/// is incremented in that timer, before attempting a redraw or sending frame callbacks.
|
||||||
pub frame_callback_sequence: u32,
|
pub frame_callback_sequence: u32,
|
||||||
/// Solid color buffer for the background that we use instead of clearing to avoid damage
|
/// Solid color buffer for the backdrop that we use instead of clearing to avoid damage
|
||||||
/// tracking issues and make screenshots easier.
|
/// tracking issues and make screenshots easier.
|
||||||
pub background_buffer: SolidColorBuffer,
|
|
||||||
pub backdrop_buffer: SolidColorBuffer,
|
pub backdrop_buffer: SolidColorBuffer,
|
||||||
pub lock_render_state: LockRenderState,
|
pub lock_render_state: LockRenderState,
|
||||||
pub lock_surface: Option<LockSurface>,
|
pub lock_surface: Option<LockSurface>,
|
||||||
@@ -1655,12 +1654,6 @@ impl State {
|
|||||||
resized_outputs.push(output.clone());
|
resized_outputs.push(output.clone());
|
||||||
}
|
}
|
||||||
|
|
||||||
let background_color = config
|
|
||||||
.and_then(|c| c.background_color)
|
|
||||||
.unwrap_or_else(|| full_config.resolve_layout().background_color)
|
|
||||||
.to_array_unpremul();
|
|
||||||
let background_color = Color32F::from(background_color);
|
|
||||||
|
|
||||||
let mut backdrop_color = config
|
let mut backdrop_color = config
|
||||||
.and_then(|c| c.backdrop_color)
|
.and_then(|c| c.backdrop_color)
|
||||||
.unwrap_or(full_config.overview.backdrop_color)
|
.unwrap_or(full_config.overview.backdrop_color)
|
||||||
@@ -1669,10 +1662,6 @@ impl State {
|
|||||||
let backdrop_color = Color32F::from(backdrop_color);
|
let backdrop_color = Color32F::from(backdrop_color);
|
||||||
|
|
||||||
if let Some(state) = self.niri.output_state.get_mut(output) {
|
if let Some(state) = self.niri.output_state.get_mut(output) {
|
||||||
if state.background_buffer.color() != background_color {
|
|
||||||
state.background_buffer.set_color(background_color);
|
|
||||||
recolored_outputs.push(output.clone());
|
|
||||||
}
|
|
||||||
if state.backdrop_buffer.color() != backdrop_color {
|
if state.backdrop_buffer.color() != backdrop_color {
|
||||||
state.backdrop_buffer.set_color(backdrop_color);
|
state.backdrop_buffer.set_color(backdrop_color);
|
||||||
recolored_outputs.push(output.clone());
|
recolored_outputs.push(output.clone());
|
||||||
@@ -2904,11 +2893,6 @@ impl Niri {
|
|||||||
.map(|c| ipc_transform_to_smithay(c.transform))
|
.map(|c| ipc_transform_to_smithay(c.transform))
|
||||||
.unwrap_or(Transform::Normal);
|
.unwrap_or(Transform::Normal);
|
||||||
|
|
||||||
let background_color = c
|
|
||||||
.and_then(|c| c.background_color)
|
|
||||||
.unwrap_or_else(|| config.resolve_layout().background_color)
|
|
||||||
.to_array_unpremul();
|
|
||||||
|
|
||||||
let mut backdrop_color = c
|
let mut backdrop_color = c
|
||||||
.and_then(|c| c.backdrop_color)
|
.and_then(|c| c.backdrop_color)
|
||||||
.unwrap_or(config.overview.backdrop_color)
|
.unwrap_or(config.overview.backdrop_color)
|
||||||
@@ -2947,7 +2931,6 @@ impl Niri {
|
|||||||
frame_clock: FrameClock::new(refresh_interval, vrr),
|
frame_clock: FrameClock::new(refresh_interval, vrr),
|
||||||
last_drm_sequence: None,
|
last_drm_sequence: None,
|
||||||
frame_callback_sequence: 0,
|
frame_callback_sequence: 0,
|
||||||
background_buffer: SolidColorBuffer::new(size, background_color),
|
|
||||||
backdrop_buffer: SolidColorBuffer::new(size, backdrop_color),
|
backdrop_buffer: SolidColorBuffer::new(size, backdrop_color),
|
||||||
lock_render_state,
|
lock_render_state,
|
||||||
lock_surface: None,
|
lock_surface: None,
|
||||||
@@ -3056,7 +3039,6 @@ impl Niri {
|
|||||||
self.layout.update_output_size(output);
|
self.layout.update_output_size(output);
|
||||||
|
|
||||||
if let Some(state) = self.output_state.get_mut(output) {
|
if let Some(state) = self.output_state.get_mut(output) {
|
||||||
state.background_buffer.resize(output_size);
|
|
||||||
state.backdrop_buffer.resize(output_size);
|
state.backdrop_buffer.resize(output_size);
|
||||||
|
|
||||||
state.lock_color_buffer.resize(output_size);
|
state.lock_color_buffer.resize(output_size);
|
||||||
@@ -4239,13 +4221,6 @@ impl Niri {
|
|||||||
|
|
||||||
// Prepare the background elements.
|
// Prepare the background elements.
|
||||||
let state = self.output_state.get(output).unwrap();
|
let state = self.output_state.get(output).unwrap();
|
||||||
let background_buffer = state.background_buffer.clone();
|
|
||||||
let background = SolidColorRenderElement::from_buffer(
|
|
||||||
&background_buffer,
|
|
||||||
(0., 0.),
|
|
||||||
1.,
|
|
||||||
Kind::Unspecified,
|
|
||||||
);
|
|
||||||
let backdrop = SolidColorRenderElement::from_buffer(
|
let backdrop = SolidColorRenderElement::from_buffer(
|
||||||
&state.backdrop_buffer,
|
&state.backdrop_buffer,
|
||||||
(0., 0.),
|
(0., 0.),
|
||||||
@@ -4286,7 +4261,7 @@ impl Niri {
|
|||||||
let zoom = mon.overview_zoom();
|
let zoom = mon.overview_zoom();
|
||||||
let monitor_elements = Vec::from_iter(
|
let monitor_elements = Vec::from_iter(
|
||||||
mon.render_elements(renderer, target, focus_ring)
|
mon.render_elements(renderer, target, focus_ring)
|
||||||
.map(|(geo, iter)| (geo, Vec::from_iter(iter))),
|
.map(|(geo, bg, iter)| (geo, bg, Vec::from_iter(iter))),
|
||||||
);
|
);
|
||||||
let workspace_shadow_elements = Vec::from_iter(mon.render_workspace_shadows(renderer));
|
let workspace_shadow_elements = Vec::from_iter(mon.render_workspace_shadows(renderer));
|
||||||
let insert_hint_elements = mon.render_insert_hint_between_workspaces(renderer);
|
let insert_hint_elements = mon.render_insert_hint_between_workspaces(renderer);
|
||||||
@@ -4330,17 +4305,24 @@ impl Niri {
|
|||||||
.into_iter()
|
.into_iter()
|
||||||
.map(OutputRenderElements::from),
|
.map(OutputRenderElements::from),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
let mut ws_background = None;
|
||||||
elements.extend(
|
elements.extend(
|
||||||
monitor_elements
|
monitor_elements
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.flat_map(|(_ws_geo, iter)| iter)
|
.flat_map(|(_ws_geo, ws_bg, iter)| {
|
||||||
|
ws_background = Some(ws_bg);
|
||||||
|
iter
|
||||||
|
})
|
||||||
.map(OutputRenderElements::from),
|
.map(OutputRenderElements::from),
|
||||||
);
|
);
|
||||||
|
|
||||||
elements.extend(top_layer.into_iter().map(OutputRenderElements::from));
|
elements.extend(top_layer.into_iter().map(OutputRenderElements::from));
|
||||||
elements.extend(layer_elems.into_iter().map(OutputRenderElements::from));
|
elements.extend(layer_elems.into_iter().map(OutputRenderElements::from));
|
||||||
|
|
||||||
elements.push(OutputRenderElements::from(background));
|
if let Some(ws_background) = ws_background {
|
||||||
|
elements.push(OutputRenderElements::from(ws_background));
|
||||||
|
}
|
||||||
|
|
||||||
elements.extend(
|
elements.extend(
|
||||||
workspace_shadow_elements
|
workspace_shadow_elements
|
||||||
@@ -4362,7 +4344,7 @@ impl Niri {
|
|||||||
.map(OutputRenderElements::from),
|
.map(OutputRenderElements::from),
|
||||||
);
|
);
|
||||||
|
|
||||||
for (ws_geo, ws_elements) in monitor_elements {
|
for (ws_geo, ws_background, ws_elements) in monitor_elements {
|
||||||
// Collect all other layer-shell elements.
|
// Collect all other layer-shell elements.
|
||||||
let mut layer_elems = SplitElements::default();
|
let mut layer_elems = SplitElements::default();
|
||||||
extend_from_layer(&mut layer_elems, Layer::Bottom, false);
|
extend_from_layer(&mut layer_elems, Layer::Bottom, false);
|
||||||
@@ -4386,11 +4368,7 @@ impl Niri {
|
|||||||
.map(OutputRenderElements::from),
|
.map(OutputRenderElements::from),
|
||||||
);
|
);
|
||||||
|
|
||||||
if let Some(elem) =
|
elements.push(OutputRenderElements::from(ws_background));
|
||||||
scale_relocate_crop(background.clone(), output_scale, zoom, ws_geo)
|
|
||||||
{
|
|
||||||
elements.push(OutputRenderElements::from(elem));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
elements.extend(
|
elements.extend(
|
||||||
@@ -6351,9 +6329,6 @@ niri_render_elements! {
|
|||||||
Wayland = WaylandSurfaceRenderElement<R>,
|
Wayland = WaylandSurfaceRenderElement<R>,
|
||||||
NamedPointer = MemoryRenderBufferRenderElement<R>,
|
NamedPointer = MemoryRenderBufferRenderElement<R>,
|
||||||
SolidColor = SolidColorRenderElement,
|
SolidColor = SolidColorRenderElement,
|
||||||
RelocatedSolidColor = CropRenderElement<RelocateRenderElement<RescaleRenderElement<
|
|
||||||
SolidColorRenderElement
|
|
||||||
>>>,
|
|
||||||
ScreenshotUi = ScreenshotUiRenderElement,
|
ScreenshotUi = ScreenshotUiRenderElement,
|
||||||
ExitConfirmDialog = ExitConfirmDialogRenderElement,
|
ExitConfirmDialog = ExitConfirmDialogRenderElement,
|
||||||
Texture = PrimaryGpuTextureRenderElement,
|
Texture = PrimaryGpuTextureRenderElement,
|
||||||
|
Reference in New Issue
Block a user