mirror of
https://github.com/niri-wm/niri.git
synced 2026-06-21 02:01:55 +07:00
Add a push version of render()
Will be useful for screencasting.
This commit is contained in:
+50
-50
@@ -4283,8 +4283,29 @@ impl Niri {
|
||||
renderer: &mut R,
|
||||
output: &Output,
|
||||
include_pointer: bool,
|
||||
mut target: RenderTarget,
|
||||
target: RenderTarget,
|
||||
) -> Vec<OutputRenderElements<R>> {
|
||||
let mut elements = Vec::new();
|
||||
self.render_inner(renderer, output, include_pointer, target, &mut |elem| {
|
||||
elements.push(elem)
|
||||
});
|
||||
|
||||
if self.debug_draw_opaque_regions {
|
||||
let output_scale = Scale::from(output.current_scale().fractional_scale());
|
||||
draw_opaque_regions(&mut elements, output_scale);
|
||||
}
|
||||
|
||||
elements
|
||||
}
|
||||
|
||||
pub fn render_inner<R: NiriRenderer>(
|
||||
&self,
|
||||
renderer: &mut R,
|
||||
output: &Output,
|
||||
include_pointer: bool,
|
||||
mut target: RenderTarget,
|
||||
push: &mut dyn FnMut(OutputRenderElements<R>),
|
||||
) {
|
||||
let _span = tracy_client::span!("Niri::render");
|
||||
|
||||
if target == RenderTarget::Output {
|
||||
@@ -4299,26 +4320,25 @@ impl Niri {
|
||||
let output_scale = Scale::from(output.current_scale().fractional_scale());
|
||||
|
||||
// The pointer goes on the top.
|
||||
let mut elements = vec![];
|
||||
if include_pointer && self.pointer_visibility.is_visible() {
|
||||
self.render_pointer(renderer, output, &mut |elem| elements.push(elem.into()));
|
||||
self.render_pointer(renderer, output, &mut |elem| push(elem.into()));
|
||||
}
|
||||
|
||||
// Next, the screen transition texture.
|
||||
{
|
||||
let state = self.output_state.get(output).unwrap();
|
||||
if let Some(transition) = &state.screen_transition {
|
||||
elements.push(transition.render(target).into());
|
||||
push(transition.render(target).into());
|
||||
}
|
||||
}
|
||||
|
||||
// Next, the exit confirm dialog.
|
||||
self.exit_confirm_dialog
|
||||
.render(renderer, output, &mut |elem| elements.push(elem.into()));
|
||||
.render(renderer, output, &mut |elem| push(elem.into()));
|
||||
|
||||
// Next, the config error notification too.
|
||||
if let Some(element) = self.config_error_notification.render(renderer, output) {
|
||||
elements.push(element.into());
|
||||
push(element.into());
|
||||
}
|
||||
|
||||
// If the session is locked, draw the lock surface.
|
||||
@@ -4332,12 +4352,12 @@ impl Niri {
|
||||
output_scale,
|
||||
1.,
|
||||
Kind::ScanoutCandidate,
|
||||
&mut |elem| elements.push(elem.into()),
|
||||
&mut |elem| push(elem.into()),
|
||||
);
|
||||
}
|
||||
|
||||
// Draw the solid color background.
|
||||
elements.push(
|
||||
push(
|
||||
SolidColorRenderElement::from_buffer(
|
||||
&state.lock_color_buffer,
|
||||
(0., 0.),
|
||||
@@ -4347,10 +4367,7 @@ impl Niri {
|
||||
.into(),
|
||||
);
|
||||
|
||||
if self.debug_draw_opaque_regions {
|
||||
draw_opaque_regions(&mut elements, output_scale);
|
||||
}
|
||||
return elements;
|
||||
return;
|
||||
}
|
||||
|
||||
// Prepare the background elements.
|
||||
@@ -4366,26 +4383,23 @@ impl Niri {
|
||||
// If the screenshot UI is open, draw it.
|
||||
if self.screenshot_ui.is_open() {
|
||||
self.screenshot_ui
|
||||
.render_output(output, target, &mut |elem| elements.push(elem.into()));
|
||||
.render_output(output, target, &mut |elem| push(elem.into()));
|
||||
|
||||
// Add the backdrop for outputs that were connected while the screenshot UI was open.
|
||||
elements.push(backdrop);
|
||||
push(backdrop);
|
||||
|
||||
if self.debug_draw_opaque_regions {
|
||||
draw_opaque_regions(&mut elements, output_scale);
|
||||
}
|
||||
return elements;
|
||||
return;
|
||||
}
|
||||
|
||||
// Draw the hotkey overlay on top.
|
||||
if let Some(element) = self.hotkey_overlay.render(renderer, output) {
|
||||
elements.push(element.into());
|
||||
push(element.into());
|
||||
}
|
||||
|
||||
// Then, the Alt-Tab switcher.
|
||||
self.window_mru_ui
|
||||
.render_output(self, output, renderer, target, &mut |elem| {
|
||||
elements.push(elem.into())
|
||||
push(elem.into())
|
||||
});
|
||||
|
||||
// Don't draw the focus ring on the workspaces while interactively moving above those
|
||||
@@ -4399,20 +4413,20 @@ impl Niri {
|
||||
// Get layer-shell elements.
|
||||
let layer_map = layer_map_for_output(output);
|
||||
|
||||
// We use macros instead of closures to avoid borrowing issues (renderer and elements go
|
||||
// We use macros instead of closures to avoid borrowing issues (renderer and push() go
|
||||
// into different functions).
|
||||
macro_rules! push_popups_from_layer {
|
||||
($layer:expr, $backdrop:expr, $push:expr) => {{
|
||||
self.render_layer_popups(renderer, target, &layer_map, $layer, $backdrop, $push);
|
||||
}};
|
||||
($layer:expr, true) => {{
|
||||
push_popups_from_layer!($layer, true, &mut |elem| elements.push(elem.into()));
|
||||
push_popups_from_layer!($layer, true, &mut |elem| push(elem.into()));
|
||||
}};
|
||||
($layer:expr, $push:expr) => {{
|
||||
push_popups_from_layer!($layer, false, $push);
|
||||
}};
|
||||
($layer:expr) => {{
|
||||
push_popups_from_layer!($layer, false, &mut |elem| elements.push(elem.into()));
|
||||
push_popups_from_layer!($layer, false, &mut |elem| push(elem.into()));
|
||||
}};
|
||||
}
|
||||
macro_rules! push_normal_from_layer {
|
||||
@@ -4420,13 +4434,13 @@ impl Niri {
|
||||
self.render_layer_normal(renderer, target, &layer_map, $layer, $backdrop, $push);
|
||||
}};
|
||||
($layer:expr, true) => {{
|
||||
push_normal_from_layer!($layer, true, &mut |elem| elements.push(elem.into()));
|
||||
push_normal_from_layer!($layer, true, &mut |elem| push(elem.into()));
|
||||
}};
|
||||
($layer:expr, $push:expr) => {{
|
||||
push_normal_from_layer!($layer, false, $push);
|
||||
}};
|
||||
($layer:expr) => {{
|
||||
push_normal_from_layer!($layer, false, &mut |elem| elements.push(elem.into()));
|
||||
push_normal_from_layer!($layer, false, &mut |elem| push(elem.into()));
|
||||
}};
|
||||
}
|
||||
|
||||
@@ -4439,16 +4453,12 @@ impl Niri {
|
||||
if mon.render_above_top_layer() {
|
||||
self.layout
|
||||
.render_interactive_move_for_output(renderer, output, target, &mut |elem| {
|
||||
elements.push(elem.into())
|
||||
push(elem.into())
|
||||
});
|
||||
|
||||
mon.render_insert_hint_between_workspaces(renderer, &mut |elem| {
|
||||
elements.push(elem.into())
|
||||
});
|
||||
mon.render_insert_hint_between_workspaces(renderer, &mut |elem| push(elem.into()));
|
||||
|
||||
mon.render_workspaces(renderer, target, focus_ring, &mut |elem| {
|
||||
elements.push(elem.into())
|
||||
});
|
||||
mon.render_workspaces(renderer, target, focus_ring, &mut |elem| push(elem.into()));
|
||||
|
||||
push_popups_from_layer!(Layer::Top);
|
||||
push_normal_from_layer!(Layer::Top);
|
||||
@@ -4460,7 +4470,7 @@ impl Niri {
|
||||
|
||||
// We don't expect more than one workspace when render_above_top_layer().
|
||||
if let Some((ws, _geo)) = mon.workspaces_with_render_geo().next() {
|
||||
elements.push(ws.render_background().into());
|
||||
push(ws.render_background().into());
|
||||
}
|
||||
} else {
|
||||
push_popups_from_layer!(Layer::Top);
|
||||
@@ -4468,19 +4478,17 @@ impl Niri {
|
||||
|
||||
self.layout
|
||||
.render_interactive_move_for_output(renderer, output, target, &mut |elem| {
|
||||
elements.push(elem.into())
|
||||
push(elem.into())
|
||||
});
|
||||
|
||||
mon.render_insert_hint_between_workspaces(renderer, &mut |elem| {
|
||||
elements.push(elem.into())
|
||||
});
|
||||
mon.render_insert_hint_between_workspaces(renderer, &mut |elem| push(elem.into()));
|
||||
|
||||
// Macro instead of closure to avoid borrowing elements.
|
||||
// Macro instead of closure to avoid borrowing push().
|
||||
macro_rules! process {
|
||||
($geo:expr) => {{
|
||||
&mut |elem| {
|
||||
if let Some(elem) = scale_relocate_crop(elem, output_scale, zoom, $geo) {
|
||||
elements.push(elem.into());
|
||||
push(elem.into());
|
||||
}
|
||||
}
|
||||
}};
|
||||
@@ -4491,9 +4499,7 @@ impl Niri {
|
||||
push_popups_from_layer!(Layer::Background, process!(geo));
|
||||
}
|
||||
|
||||
mon.render_workspaces(renderer, target, focus_ring, &mut |elem| {
|
||||
elements.push(elem.into())
|
||||
});
|
||||
mon.render_workspaces(renderer, target, focus_ring, &mut |elem| push(elem.into()));
|
||||
|
||||
for (ws, geo) in mon.workspaces_with_render_geo() {
|
||||
push_normal_from_layer!(Layer::Bottom, process!(geo));
|
||||
@@ -4503,19 +4509,13 @@ impl Niri {
|
||||
}
|
||||
}
|
||||
|
||||
mon.render_workspace_shadows(renderer, &mut |elem| elements.push(elem.into()));
|
||||
mon.render_workspace_shadows(renderer, &mut |elem| push(elem.into()));
|
||||
|
||||
// Then the backdrop.
|
||||
push_popups_from_layer!(Layer::Background, true);
|
||||
push_normal_from_layer!(Layer::Background, true);
|
||||
|
||||
elements.push(backdrop);
|
||||
|
||||
if self.debug_draw_opaque_regions {
|
||||
draw_opaque_regions(&mut elements, output_scale);
|
||||
}
|
||||
|
||||
elements
|
||||
push(backdrop);
|
||||
}
|
||||
|
||||
fn layers_in_render_order<'a>(
|
||||
|
||||
Reference in New Issue
Block a user