aboutsummaryrefslogtreecommitdiff
path: root/src/window
diff options
context:
space:
mode:
Diffstat (limited to 'src/window')
-rw-r--r--src/window/mapped.rs45
-rw-r--r--src/window/mod.rs9
2 files changed, 44 insertions, 10 deletions
diff --git a/src/window/mapped.rs b/src/window/mapped.rs
index 52b9ac92..8a4b2473 100644
--- a/src/window/mapped.rs
+++ b/src/window/mapped.rs
@@ -1,7 +1,9 @@
+use std::cell::RefCell;
use std::cmp::{max, min};
-use niri_config::WindowRule;
-use smithay::backend::renderer::element::{AsRenderElements as _, Id};
+use niri_config::{BlockOutFrom, WindowRule};
+use smithay::backend::renderer::element::solid::{SolidColorBuffer, SolidColorRenderElement};
+use smithay::backend::renderer::element::{AsRenderElements as _, Id, Kind};
use smithay::desktop::space::SpaceElement as _;
use smithay::desktop::Window;
use smithay::output::Output;
@@ -16,6 +18,7 @@ use super::{ResolvedWindowRules, WindowRef};
use crate::layout::{LayoutElement, LayoutElementRenderElement};
use crate::niri::WindowOffscreenId;
use crate::render_helpers::renderer::NiriRenderer;
+use crate::render_helpers::RenderTarget;
#[derive(Debug)]
pub struct Mapped {
@@ -32,6 +35,9 @@ pub struct Mapped {
/// Whether this window has the keyboard focus.
is_focused: bool,
+
+ /// Buffer to draw instead of the window when it should be blocked out.
+ block_out_buffer: RefCell<SolidColorBuffer>,
}
impl Mapped {
@@ -41,6 +47,7 @@ impl Mapped {
rules,
need_to_recompute_rules: false,
is_focused: false,
+ block_out_buffer: RefCell::new(SolidColorBuffer::new((0, 0), [0., 0., 0., 1.])),
}
}
@@ -109,14 +116,34 @@ impl LayoutElement for Mapped {
location: Point<i32, Logical>,
scale: Scale<f64>,
alpha: f32,
+ target: RenderTarget,
) -> Vec<LayoutElementRenderElement<R>> {
- let buf_pos = location - self.window.geometry().loc;
- self.window.render_elements(
- renderer,
- buf_pos.to_physical_precise_round(scale),
- scale,
- alpha,
- )
+ let block_out = match self.rules.block_out_from {
+ None => false,
+ Some(BlockOutFrom::Screencast) => target == RenderTarget::Screencast,
+ Some(BlockOutFrom::ScreenCapture) => target != RenderTarget::Output,
+ };
+
+ if block_out {
+ let mut buffer = self.block_out_buffer.borrow_mut();
+ buffer.resize(self.window.geometry().size);
+ let elem = SolidColorRenderElement::from_buffer(
+ &buffer,
+ location.to_physical_precise_round(scale),
+ scale,
+ alpha,
+ Kind::Unspecified,
+ );
+ vec![elem.into()]
+ } else {
+ let buf_pos = location - self.window.geometry().loc;
+ self.window.render_elements(
+ renderer,
+ buf_pos.to_physical_precise_round(scale),
+ scale,
+ alpha,
+ )
+ }
}
fn request_size(&self, size: Size<i32, Logical>) {
diff --git a/src/window/mod.rs b/src/window/mod.rs
index ddf712b0..3c46e9e5 100644
--- a/src/window/mod.rs
+++ b/src/window/mod.rs
@@ -1,4 +1,4 @@
-use niri_config::{Match, WindowRule};
+use niri_config::{BlockOutFrom, Match, WindowRule};
use smithay::reexports::wayland_protocols::xdg::shell::server::xdg_toplevel;
use smithay::wayland::compositor::with_states;
use smithay::wayland::shell::xdg::{
@@ -55,6 +55,9 @@ pub struct ResolvedWindowRules {
/// Extra opacity to draw this window with.
pub opacity: Option<f32>,
+
+ /// Whether to block out this window from certain render targets.
+ pub block_out_from: Option<BlockOutFrom>,
}
impl<'a> WindowRef<'a> {
@@ -86,6 +89,7 @@ impl ResolvedWindowRules {
max_height: None,
draw_border_with_background: None,
opacity: None,
+ block_out_from: None,
}
}
@@ -160,6 +164,9 @@ impl ResolvedWindowRules {
if let Some(x) = rule.opacity {
resolved.opacity = Some(x);
}
+ if let Some(x) = rule.block_out_from {
+ resolved.block_out_from = Some(x);
+ }
}
resolved.open_on_output = open_on_output.map(|x| x.to_owned());