diff options
| author | Ivan Molodetskikh <yalterz@gmail.com> | 2024-03-24 09:03:59 +0400 |
|---|---|---|
| committer | Ivan Molodetskikh <yalterz@gmail.com> | 2024-03-24 10:22:56 +0400 |
| commit | 493c8dc89072a746795d4e7b94363cfef3e0ee89 (patch) | |
| tree | 31a384a6272a876d95e271e186e08a92ed88092c /src/window | |
| parent | 8b4a9d68e0ba8093e88d20f3a003f78ef27cac0e (diff) | |
| download | niri-493c8dc89072a746795d4e7b94363cfef3e0ee89.tar.gz niri-493c8dc89072a746795d4e7b94363cfef3e0ee89.tar.bz2 niri-493c8dc89072a746795d4e7b94363cfef3e0ee89.zip | |
Implement block-out-from window rule, fix alpha on window screenshots
Diffstat (limited to 'src/window')
| -rw-r--r-- | src/window/mapped.rs | 45 | ||||
| -rw-r--r-- | src/window/mod.rs | 9 |
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()); |
