diff options
| author | Ivan Molodetskikh <yalterz@gmail.com> | 2024-05-10 16:58:53 +0400 |
|---|---|---|
| committer | Ivan Molodetskikh <yalterz@gmail.com> | 2024-05-10 20:23:08 +0400 |
| commit | 9dfa121b8e31082314d1c9347a60ef2e596494cb (patch) | |
| tree | 6e9b90f2f1d54213444fb89b4739e0c8948ed1e9 /src/window | |
| parent | c4ebb9f58e7ea1d2e688d3ee9483a7a1b3dd52b4 (diff) | |
| download | niri-9dfa121b8e31082314d1c9347a60ef2e596494cb.tar.gz niri-9dfa121b8e31082314d1c9347a60ef2e596494cb.tar.bz2 niri-9dfa121b8e31082314d1c9347a60ef2e596494cb.zip | |
Implement interactive mouse resizing
Diffstat (limited to 'src/window')
| -rw-r--r-- | src/window/mapped.rs | 78 |
1 files changed, 77 insertions, 1 deletions
diff --git a/src/window/mapped.rs b/src/window/mapped.rs index 3fd0a259..e863e2ca 100644 --- a/src/window/mapped.rs +++ b/src/window/mapped.rs @@ -19,7 +19,9 @@ use smithay::wayland::compositor::{ use smithay::wayland::shell::xdg::{SurfaceCachedState, ToplevelSurface}; use super::{ResolvedWindowRules, WindowRef}; -use crate::layout::{LayoutElement, LayoutElementRenderElement, LayoutElementRenderSnapshot}; +use crate::layout::{ + InteractiveResizeData, LayoutElement, LayoutElementRenderElement, LayoutElementRenderSnapshot, +}; use crate::niri::WindowOffscreenId; use crate::render_helpers::renderer::NiriRenderer; use crate::render_helpers::snapshot::RenderSnapshot; @@ -56,6 +58,23 @@ pub struct Mapped { /// Snapshot right before an animated commit. animation_snapshot: Option<LayoutElementRenderSnapshot>, + + /// State of an ongoing interactive resize. + interactive_resize: Option<InteractiveResize>, +} + +/// Interactive resize state. +#[derive(Debug)] +enum InteractiveResize { + /// The resize is ongoing. + Ongoing(InteractiveResizeData), + /// The resize has stopped and we're waiting to send the last configure. + WaitingForLastConfigure(InteractiveResizeData), + /// We had sent the last resize configure and are waiting for the corresponding commit. + WaitingForLastCommit { + data: InteractiveResizeData, + serial: Serial, + }, } impl Mapped { @@ -70,6 +89,7 @@ impl Mapped { animate_next_configure: false, animate_serials: Vec::new(), animation_snapshot: None, + interactive_resize: None, } } @@ -427,6 +447,20 @@ impl LayoutElement for Mapped { if self.animate_next_configure { self.animate_serials.push(serial); } + + self.interactive_resize = match self.interactive_resize.take() { + Some(InteractiveResize::WaitingForLastConfigure(data)) => { + Some(InteractiveResize::WaitingForLastCommit { data, serial }) + } + x => x, + } + } else { + self.interactive_resize = match self.interactive_resize.take() { + // We probably started and stopped resizing in the same loop cycle without anything + // changing. + Some(InteractiveResize::WaitingForLastConfigure { .. }) => None, + x => x, + } } self.animate_next_configure = false; @@ -459,4 +493,46 @@ impl LayoutElement for Mapped { fn take_animation_snapshot(&mut self) -> Option<LayoutElementRenderSnapshot> { self.animation_snapshot.take() } + + fn set_interactive_resize(&mut self, data: Option<InteractiveResizeData>) { + self.toplevel().with_pending_state(|state| { + if data.is_some() { + state.states.set(xdg_toplevel::State::Resizing); + } else { + state.states.unset(xdg_toplevel::State::Resizing); + } + }); + + if let Some(data) = data { + self.interactive_resize = Some(InteractiveResize::Ongoing(data)); + } else { + self.interactive_resize = match self.interactive_resize.take() { + Some(InteractiveResize::Ongoing(data)) => { + Some(InteractiveResize::WaitingForLastConfigure(data)) + } + x => x, + } + } + } + + fn cancel_interactive_resize(&mut self) { + self.set_interactive_resize(None); + self.interactive_resize = None; + } + + fn interactive_resize_data(&mut self, commit_serial: Serial) -> Option<InteractiveResizeData> { + let resize = self.interactive_resize.as_ref()?; + match resize { + InteractiveResize::Ongoing(data) | InteractiveResize::WaitingForLastConfigure(data) => { + Some(*data) + } + InteractiveResize::WaitingForLastCommit { data, serial } => { + let rv = Some(*data); + if commit_serial.is_no_older_than(serial) { + self.interactive_resize = None; + } + rv + } + } + } } |
