diff options
| author | Ivan Molodetskikh <yalterz@gmail.com> | 2025-03-01 09:45:57 +0300 |
|---|---|---|
| committer | Ivan Molodetskikh <yalterz@gmail.com> | 2025-03-10 07:59:14 +0300 |
| commit | b351f6ff220560d96a260d8dd3ad794000923481 (patch) | |
| tree | f2bd1a777fe9f932fea2cfeba3677cbb39b634eb /src/window | |
| parent | 12817a682d666e81e30b5a723d6419baf74cdb1c (diff) | |
| download | niri-b351f6ff220560d96a260d8dd3ad794000923481.tar.gz niri-b351f6ff220560d96a260d8dd3ad794000923481.tar.bz2 niri-b351f6ff220560d96a260d8dd3ad794000923481.zip | |
Keep track of RenderElementStates in offscreens
This both avoids sending frame callbacks to surfaces invisible on the offscreen
(fixing Firefox with subsurface compositing in the process), and fixes
searching for split popups during the resize animation.
Diffstat (limited to 'src/window')
| -rw-r--r-- | src/window/mapped.rs | 33 |
1 files changed, 25 insertions, 8 deletions
diff --git a/src/window/mapped.rs b/src/window/mapped.rs index 8263c078..6b539e46 100644 --- a/src/window/mapped.rs +++ b/src/window/mapped.rs @@ -3,7 +3,7 @@ use std::time::Duration; use niri_config::{Color, CornerRadius, GradientInterpolation, WindowRule}; use smithay::backend::renderer::element::surface::render_elements_from_surface_tree; -use smithay::backend::renderer::element::{Id, Kind}; +use smithay::backend::renderer::element::Kind; use smithay::backend::renderer::gles::GlesRenderer; use smithay::desktop::space::SpaceElement as _; use smithay::desktop::{PopupManager, Window}; @@ -26,6 +26,7 @@ use crate::layout::{ }; use crate::niri_render_elements; use crate::render_helpers::border::BorderRenderElement; +use crate::render_helpers::offscreen::OffscreenData; use crate::render_helpers::renderer::NiriRenderer; use crate::render_helpers::snapshot::RenderSnapshot; use crate::render_helpers::solid_color::{SolidColorBuffer, SolidColorRenderElement}; @@ -70,10 +71,10 @@ pub struct Mapped { /// resizes immediately, without waiting for a 1 second throttled callback. needs_frame_callback: bool, - /// Id of the offscreen element rendered in place of this window. + /// Data of the offscreen element rendered in place of this window. /// /// If `None`, then the window is not offscreened. - offscreen_element_id: RefCell<Option<Id>>, + offscreen_data: RefCell<Option<OffscreenData>>, /// Whether this window has the keyboard focus. is_focused: bool, @@ -192,7 +193,7 @@ impl Mapped { need_to_recompute_rules: false, needs_configure: false, needs_frame_callback: false, - offscreen_element_id: RefCell::new(None), + offscreen_data: RefCell::new(None), is_focused: false, is_active_in_column: true, is_floating: false, @@ -257,8 +258,8 @@ impl Mapped { self.credentials.as_ref() } - pub fn offscreen_element_id(&self) -> Ref<Option<Id>> { - self.offscreen_element_id.borrow() + pub fn offscreen_data(&self) -> Ref<Option<OffscreenData>> { + self.offscreen_data.borrow() } pub fn is_focused(&self) -> bool { @@ -751,8 +752,24 @@ impl LayoutElement for Mapped { self.window.output_leave(output) } - fn set_offscreen_element_id(&self, id: Option<Id>) { - self.offscreen_element_id.replace(id); + fn set_offscreen_data(&self, data: Option<OffscreenData>) { + let Some(data) = data else { + self.offscreen_data.replace(None); + return; + }; + + let mut offscreen_data = self.offscreen_data.borrow_mut(); + match &mut *offscreen_data { + None => { + *offscreen_data = Some(data); + } + Some(existing) => { + // Replace the id, amend existing element states. This is necessary to handle + // multiple layers of offscreen (e.g. resize animation + alpha animation). + existing.id = data.id; + existing.states.states.extend(data.states.states); + } + } } fn set_activated(&mut self, active: bool) { |
