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