diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/layout/mod.rs | 22 | ||||
| -rw-r--r-- | src/niri.rs | 28 |
2 files changed, 43 insertions, 7 deletions
diff --git a/src/layout/mod.rs b/src/layout/mod.rs index 0f6c0bef..e88182c0 100644 --- a/src/layout/mod.rs +++ b/src/layout/mod.rs @@ -211,6 +211,11 @@ pub trait LayoutElement { pub struct Layout<W: LayoutElement> { /// Monitors and workspaes in the layout. monitor_set: MonitorSet<W>, + /// Whether the layout should draw as active. + /// + /// This normally indicates that the layout has keyboard focus, but not always. E.g. when the + /// screenshot UI is open, it keeps the layout drawing as active. + is_active: bool, /// Configurable properties of the layout. options: Rc<Options>, } @@ -354,6 +359,7 @@ impl<W: LayoutElement> Layout<W> { pub fn with_options(options: Options) -> Self { Self { monitor_set: MonitorSet::NoOutputs { workspaces: vec![] }, + is_active: true, options: Rc::new(options), } } @@ -369,6 +375,7 @@ impl<W: LayoutElement> Layout<W> { Self { monitor_set: MonitorSet::NoOutputs { workspaces }, + is_active: true, options: opts, } } @@ -1899,7 +1906,8 @@ impl<W: LayoutElement> Layout<W> { for (idx, mon) in monitors.iter_mut().enumerate() { if output.map_or(true, |output| mon.output == *output) { - mon.update_render_elements(idx == *active_monitor_idx); + let is_active = self.is_active && idx == *active_monitor_idx; + mon.update_render_elements(is_active); } } } @@ -2590,9 +2598,11 @@ impl<W: LayoutElement> Layout<W> { } } - pub fn refresh(&mut self) { + pub fn refresh(&mut self, is_active: bool) { let _span = tracy_client::span!("Layout::refresh"); + self.is_active = is_active; + match &mut self.monitor_set { MonitorSet::Normal { monitors, @@ -2600,7 +2610,7 @@ impl<W: LayoutElement> Layout<W> { .. } => { for (idx, mon) in monitors.iter_mut().enumerate() { - let is_active = idx == *active_monitor_idx; + let is_active = self.is_active && idx == *active_monitor_idx; for (ws_idx, ws) in mon.workspaces.iter_mut().enumerate() { ws.refresh(is_active); @@ -3097,6 +3107,9 @@ mod tests { id: Option<usize>, }, Communicate(#[proptest(strategy = "1..=5usize")] usize), + Refresh { + is_active: bool, + }, MoveWorkspaceToOutput(#[proptest(strategy = "1..=5u8")] u8), ViewOffsetGestureBegin { #[proptest(strategy = "1..=5usize")] @@ -3547,6 +3560,9 @@ mod tests { layout.update_window(&id, None); } } + Op::Refresh { is_active } => { + layout.refresh(is_active); + } Op::MoveWorkspaceToOutput(id) => { let name = format!("output{id}"); let Some(output) = layout.outputs().find(|o| o.name() == name).cloned() else { diff --git a/src/niri.rs b/src/niri.rs index 4ae6d606..e553d971 100644 --- a/src/niri.rs +++ b/src/niri.rs @@ -541,14 +541,17 @@ impl State { self.notify_blocker_cleared(); // These should be called periodically, before flushing the clients. - self.niri.layout.refresh(); + self.niri.popups.cleanup(); + self.refresh_popup_grab(); + self.update_keyboard_focus(); + + // Needs to be called after updating the keyboard focus. + self.niri.refresh_layout(); + self.niri.cursor_manager.check_cursor_image_surface_alive(); self.niri.refresh_pointer_outputs(); - self.niri.popups.cleanup(); self.niri.global_space.refresh(); self.niri.refresh_idle_inhibit(); - self.refresh_popup_grab(); - self.update_keyboard_focus(); self.refresh_pointer_focus(); foreign_toplevel::refresh(self); self.niri.refresh_window_rules(); @@ -2825,6 +2828,23 @@ impl Niri { } } + pub fn refresh_layout(&mut self) { + let layout_is_active = match &self.keyboard_focus { + KeyboardFocus::Layout { .. } => true, + KeyboardFocus::LayerShell { .. } => false, + + // Draw layout as active in these cases to reduce unnecessary window animations. + // There's no confusion because these are both fullscreen modes. + // + // FIXME: when going into the screenshot UI from a layer-shell focus, and then back to + // layer-shell, the layout will briefly draw as active, despite never having focus. + KeyboardFocus::LockScreen { .. } => true, + KeyboardFocus::ScreenshotUi => true, + }; + + self.layout.refresh(layout_is_active); + } + pub fn refresh_idle_inhibit(&mut self) { let _span = tracy_client::span!("Niri::refresh_idle_inhibit"); |
