mirror of
https://github.com/niri-wm/niri.git
synced 2026-06-24 02:01:18 +07:00
Workspace back and forth (#253)
* implement workspace back and forth * Make our own ID counter instead of SerialCounter, use a newtype * Rename FocusWorkspaceBackAndForth to FocusWorkspacePrevious * Add focus-workspace-previous to tests * Don't special case in switch_workspace_previous * Minor clean up * Add switch_workspace_auto_back_and_forth to tests * Skip animation on switch_workspace_previous * Preserve previous_workspace_id on workspace movement * Make Workspace::id private with a getter Reduce the chance it gets overwritten. * Add test for workspace ID uniqueness * Update previous workspace ID upon moving workspace across monitors --------- Co-authored-by: Ivan Molodetskikh <yalterz@gmail.com>
This commit is contained in:
@@ -73,6 +73,8 @@ pub struct Input {
|
|||||||
pub warp_mouse_to_focus: bool,
|
pub warp_mouse_to_focus: bool,
|
||||||
#[knuffel(child)]
|
#[knuffel(child)]
|
||||||
pub focus_follows_mouse: bool,
|
pub focus_follows_mouse: bool,
|
||||||
|
#[knuffel(child)]
|
||||||
|
pub workspace_auto_back_and_forth: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(knuffel::Decode, Debug, Default, PartialEq, Eq)]
|
#[derive(knuffel::Decode, Debug, Default, PartialEq, Eq)]
|
||||||
@@ -766,6 +768,7 @@ pub enum Action {
|
|||||||
FocusWorkspaceDown,
|
FocusWorkspaceDown,
|
||||||
FocusWorkspaceUp,
|
FocusWorkspaceUp,
|
||||||
FocusWorkspace(#[knuffel(argument)] u8),
|
FocusWorkspace(#[knuffel(argument)] u8),
|
||||||
|
FocusWorkspacePrevious,
|
||||||
MoveWindowToWorkspaceDown,
|
MoveWindowToWorkspaceDown,
|
||||||
MoveWindowToWorkspaceUp,
|
MoveWindowToWorkspaceUp,
|
||||||
MoveWindowToWorkspace(#[knuffel(argument)] u8),
|
MoveWindowToWorkspace(#[knuffel(argument)] u8),
|
||||||
@@ -835,6 +838,7 @@ impl From<niri_ipc::Action> for Action {
|
|||||||
niri_ipc::Action::FocusWorkspaceDown => Self::FocusWorkspaceDown,
|
niri_ipc::Action::FocusWorkspaceDown => Self::FocusWorkspaceDown,
|
||||||
niri_ipc::Action::FocusWorkspaceUp => Self::FocusWorkspaceUp,
|
niri_ipc::Action::FocusWorkspaceUp => Self::FocusWorkspaceUp,
|
||||||
niri_ipc::Action::FocusWorkspace { index } => Self::FocusWorkspace(index),
|
niri_ipc::Action::FocusWorkspace { index } => Self::FocusWorkspace(index),
|
||||||
|
niri_ipc::Action::FocusWorkspacePrevious => Self::FocusWorkspacePrevious,
|
||||||
niri_ipc::Action::MoveWindowToWorkspaceDown => Self::MoveWindowToWorkspaceDown,
|
niri_ipc::Action::MoveWindowToWorkspaceDown => Self::MoveWindowToWorkspaceDown,
|
||||||
niri_ipc::Action::MoveWindowToWorkspaceUp => Self::MoveWindowToWorkspaceUp,
|
niri_ipc::Action::MoveWindowToWorkspaceUp => Self::MoveWindowToWorkspaceUp,
|
||||||
niri_ipc::Action::MoveWindowToWorkspace { index } => Self::MoveWindowToWorkspace(index),
|
niri_ipc::Action::MoveWindowToWorkspace { index } => Self::MoveWindowToWorkspace(index),
|
||||||
@@ -1599,6 +1603,7 @@ mod tests {
|
|||||||
|
|
||||||
warp-mouse-to-focus
|
warp-mouse-to-focus
|
||||||
focus-follows-mouse
|
focus-follows-mouse
|
||||||
|
workspace-auto-back-and-forth
|
||||||
}
|
}
|
||||||
|
|
||||||
output "eDP-1" {
|
output "eDP-1" {
|
||||||
@@ -1740,6 +1745,7 @@ mod tests {
|
|||||||
disable_power_key_handling: true,
|
disable_power_key_handling: true,
|
||||||
warp_mouse_to_focus: true,
|
warp_mouse_to_focus: true,
|
||||||
focus_follows_mouse: true,
|
focus_follows_mouse: true,
|
||||||
|
workspace_auto_back_and_forth: true,
|
||||||
},
|
},
|
||||||
outputs: vec![Output {
|
outputs: vec![Output {
|
||||||
off: false,
|
off: false,
|
||||||
|
|||||||
@@ -123,6 +123,8 @@ pub enum Action {
|
|||||||
#[cfg_attr(feature = "clap", arg())]
|
#[cfg_attr(feature = "clap", arg())]
|
||||||
index: u8,
|
index: u8,
|
||||||
},
|
},
|
||||||
|
/// Focus the previous workspace.
|
||||||
|
FocusWorkspacePrevious,
|
||||||
/// Move the focused window to the workspace below.
|
/// Move the focused window to the workspace below.
|
||||||
MoveWindowToWorkspaceDown,
|
MoveWindowToWorkspaceDown,
|
||||||
/// Move the focused window to the workspace above.
|
/// Move the focused window to the workspace above.
|
||||||
|
|||||||
@@ -73,6 +73,11 @@ input {
|
|||||||
|
|
||||||
// Focus windows and outputs automatically when moving the mouse into them.
|
// Focus windows and outputs automatically when moving the mouse into them.
|
||||||
// focus-follows-mouse
|
// focus-follows-mouse
|
||||||
|
|
||||||
|
// Uncomment this to enable workspace auto-back-and-forth.
|
||||||
|
// If enabled, switching to the same workspace by index twice will switch back to the
|
||||||
|
// previous workspace.
|
||||||
|
// workspace-auto-back-and-forth
|
||||||
}
|
}
|
||||||
|
|
||||||
// You can configure outputs by their name, which you can find
|
// You can configure outputs by their name, which you can find
|
||||||
@@ -518,6 +523,9 @@ binds {
|
|||||||
// Alternatively, there are commands to move just a single window:
|
// Alternatively, there are commands to move just a single window:
|
||||||
// Mod+Ctrl+1 { move-window-to-workspace 1; }
|
// Mod+Ctrl+1 { move-window-to-workspace 1; }
|
||||||
|
|
||||||
|
// Switches focus between the current and the previous workspace.
|
||||||
|
// Mod+Tab { focus-workspace-previous; }
|
||||||
|
|
||||||
Mod+Comma { consume-window-into-column; }
|
Mod+Comma { consume-window-into-column; }
|
||||||
Mod+Period { expel-window-from-column; }
|
Mod+Period { expel-window-from-column; }
|
||||||
|
|
||||||
|
|||||||
@@ -569,11 +569,23 @@ impl State {
|
|||||||
}
|
}
|
||||||
Action::FocusWorkspace(idx) => {
|
Action::FocusWorkspace(idx) => {
|
||||||
let idx = idx.saturating_sub(1) as usize;
|
let idx = idx.saturating_sub(1) as usize;
|
||||||
|
|
||||||
|
let config = &self.niri.config;
|
||||||
|
if config.borrow().input.workspace_auto_back_and_forth {
|
||||||
|
self.niri.layout.switch_workspace_auto_back_and_forth(idx);
|
||||||
|
} else {
|
||||||
self.niri.layout.switch_workspace(idx);
|
self.niri.layout.switch_workspace(idx);
|
||||||
|
}
|
||||||
|
|
||||||
self.maybe_warp_cursor_to_focus();
|
self.maybe_warp_cursor_to_focus();
|
||||||
// FIXME: granular
|
// FIXME: granular
|
||||||
self.niri.queue_redraw_all();
|
self.niri.queue_redraw_all();
|
||||||
}
|
}
|
||||||
|
Action::FocusWorkspacePrevious => {
|
||||||
|
self.niri.layout.switch_workspace_previous();
|
||||||
|
// FIXME: granular
|
||||||
|
self.niri.queue_redraw_all();
|
||||||
|
}
|
||||||
Action::MoveWorkspaceDown => {
|
Action::MoveWorkspaceDown => {
|
||||||
self.niri.layout.move_workspace_down();
|
self.niri.layout.move_workspace_down();
|
||||||
// FIXME: granular
|
// FIXME: granular
|
||||||
|
|||||||
@@ -1165,6 +1165,20 @@ impl<W: LayoutElement> Layout<W> {
|
|||||||
monitor.switch_workspace(idx);
|
monitor.switch_workspace(idx);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn switch_workspace_auto_back_and_forth(&mut self, idx: usize) {
|
||||||
|
let Some(monitor) = self.active_monitor() else {
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
monitor.switch_workspace_auto_back_and_forth(idx);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn switch_workspace_previous(&mut self) {
|
||||||
|
let Some(monitor) = self.active_monitor() else {
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
monitor.switch_workspace_previous();
|
||||||
|
}
|
||||||
|
|
||||||
pub fn consume_into_column(&mut self) {
|
pub fn consume_into_column(&mut self) {
|
||||||
let Some(monitor) = self.active_monitor() else {
|
let Some(monitor) = self.active_monitor() else {
|
||||||
return;
|
return;
|
||||||
@@ -1221,8 +1235,12 @@ impl<W: LayoutElement> Layout<W> {
|
|||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
fn verify_invariants(&self) {
|
fn verify_invariants(&self) {
|
||||||
|
use std::collections::HashSet;
|
||||||
|
|
||||||
use crate::layout::monitor::WorkspaceSwitch;
|
use crate::layout::monitor::WorkspaceSwitch;
|
||||||
|
|
||||||
|
let mut seen_workspace_id = HashSet::new();
|
||||||
|
|
||||||
let (monitors, &primary_idx, &active_monitor_idx) = match &self.monitor_set {
|
let (monitors, &primary_idx, &active_monitor_idx) = match &self.monitor_set {
|
||||||
MonitorSet::Normal {
|
MonitorSet::Normal {
|
||||||
monitors,
|
monitors,
|
||||||
@@ -1241,6 +1259,11 @@ impl<W: LayoutElement> Layout<W> {
|
|||||||
"workspace options must be synchronized with layout"
|
"workspace options must be synchronized with layout"
|
||||||
);
|
);
|
||||||
|
|
||||||
|
assert!(
|
||||||
|
seen_workspace_id.insert(workspace.id()),
|
||||||
|
"workspace id must be unique"
|
||||||
|
);
|
||||||
|
|
||||||
workspace.verify_invariants();
|
workspace.verify_invariants();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1325,6 +1348,11 @@ impl<W: LayoutElement> Layout<W> {
|
|||||||
"workspace options must be synchronized with layout"
|
"workspace options must be synchronized with layout"
|
||||||
);
|
);
|
||||||
|
|
||||||
|
assert!(
|
||||||
|
seen_workspace_id.insert(workspace.id()),
|
||||||
|
"workspace id must be unique"
|
||||||
|
);
|
||||||
|
|
||||||
workspace.verify_invariants();
|
workspace.verify_invariants();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1529,6 +1557,8 @@ impl<W: LayoutElement> Layout<W> {
|
|||||||
.unwrap();
|
.unwrap();
|
||||||
let target = &mut monitors[target_idx];
|
let target = &mut monitors[target_idx];
|
||||||
|
|
||||||
|
target.previous_workspace_id = Some(target.workspaces[target.active_workspace_idx].id());
|
||||||
|
|
||||||
// Insert the workspace after the currently active one. Unless the currently active one is
|
// Insert the workspace after the currently active one. Unless the currently active one is
|
||||||
// the last empty workspace, then insert before.
|
// the last empty workspace, then insert before.
|
||||||
let target_ws_idx = min(target.active_workspace_idx + 1, target.workspaces.len() - 1);
|
let target_ws_idx = min(target.active_workspace_idx + 1, target.workspaces.len() - 1);
|
||||||
@@ -2017,6 +2047,8 @@ mod tests {
|
|||||||
FocusWorkspaceDown,
|
FocusWorkspaceDown,
|
||||||
FocusWorkspaceUp,
|
FocusWorkspaceUp,
|
||||||
FocusWorkspace(#[proptest(strategy = "0..=4usize")] usize),
|
FocusWorkspace(#[proptest(strategy = "0..=4usize")] usize),
|
||||||
|
FocusWorkspaceAutoBackAndForth(#[proptest(strategy = "0..=4usize")] usize),
|
||||||
|
FocusWorkspacePrevious,
|
||||||
MoveWindowToWorkspaceDown,
|
MoveWindowToWorkspaceDown,
|
||||||
MoveWindowToWorkspaceUp,
|
MoveWindowToWorkspaceUp,
|
||||||
MoveWindowToWorkspace(#[proptest(strategy = "0..=4usize")] usize),
|
MoveWindowToWorkspace(#[proptest(strategy = "0..=4usize")] usize),
|
||||||
@@ -2219,6 +2251,10 @@ mod tests {
|
|||||||
Op::FocusWorkspaceDown => layout.switch_workspace_down(),
|
Op::FocusWorkspaceDown => layout.switch_workspace_down(),
|
||||||
Op::FocusWorkspaceUp => layout.switch_workspace_up(),
|
Op::FocusWorkspaceUp => layout.switch_workspace_up(),
|
||||||
Op::FocusWorkspace(idx) => layout.switch_workspace(idx),
|
Op::FocusWorkspace(idx) => layout.switch_workspace(idx),
|
||||||
|
Op::FocusWorkspaceAutoBackAndForth(idx) => {
|
||||||
|
layout.switch_workspace_auto_back_and_forth(idx)
|
||||||
|
}
|
||||||
|
Op::FocusWorkspacePrevious => layout.switch_workspace_previous(),
|
||||||
Op::MoveWindowToWorkspaceDown => layout.move_to_workspace_down(),
|
Op::MoveWindowToWorkspaceDown => layout.move_to_workspace_down(),
|
||||||
Op::MoveWindowToWorkspaceUp => layout.move_to_workspace_up(),
|
Op::MoveWindowToWorkspaceUp => layout.move_to_workspace_up(),
|
||||||
Op::MoveWindowToWorkspace(idx) => layout.move_to_workspace(idx),
|
Op::MoveWindowToWorkspace(idx) => layout.move_to_workspace(idx),
|
||||||
|
|||||||
+36
-1
@@ -10,7 +10,8 @@ use smithay::output::Output;
|
|||||||
use smithay::utils::{Logical, Point, Rectangle, Scale};
|
use smithay::utils::{Logical, Point, Rectangle, Scale};
|
||||||
|
|
||||||
use super::workspace::{
|
use super::workspace::{
|
||||||
compute_working_area, Column, ColumnWidth, OutputId, Workspace, WorkspaceRenderElement,
|
compute_working_area, Column, ColumnWidth, OutputId, Workspace, WorkspaceId,
|
||||||
|
WorkspaceRenderElement,
|
||||||
};
|
};
|
||||||
use super::{LayoutElement, Options};
|
use super::{LayoutElement, Options};
|
||||||
use crate::animation::Animation;
|
use crate::animation::Animation;
|
||||||
@@ -35,6 +36,8 @@ pub struct Monitor<W: LayoutElement> {
|
|||||||
pub workspaces: Vec<Workspace<W>>,
|
pub workspaces: Vec<Workspace<W>>,
|
||||||
/// Index of the currently active workspace.
|
/// Index of the currently active workspace.
|
||||||
pub active_workspace_idx: usize,
|
pub active_workspace_idx: usize,
|
||||||
|
/// ID of the previously active workspace.
|
||||||
|
pub previous_workspace_id: Option<WorkspaceId>,
|
||||||
/// In-progress switch between workspaces.
|
/// In-progress switch between workspaces.
|
||||||
pub workspace_switch: Option<WorkspaceSwitch>,
|
pub workspace_switch: Option<WorkspaceSwitch>,
|
||||||
/// Configurable properties of the layout.
|
/// Configurable properties of the layout.
|
||||||
@@ -89,6 +92,7 @@ impl<W: LayoutElement> Monitor<W> {
|
|||||||
output,
|
output,
|
||||||
workspaces,
|
workspaces,
|
||||||
active_workspace_idx: 0,
|
active_workspace_idx: 0,
|
||||||
|
previous_workspace_id: None,
|
||||||
workspace_switch: None,
|
workspace_switch: None,
|
||||||
options,
|
options,
|
||||||
}
|
}
|
||||||
@@ -114,6 +118,8 @@ impl<W: LayoutElement> Monitor<W> {
|
|||||||
.map(|s| s.current_idx())
|
.map(|s| s.current_idx())
|
||||||
.unwrap_or(self.active_workspace_idx as f64);
|
.unwrap_or(self.active_workspace_idx as f64);
|
||||||
|
|
||||||
|
self.previous_workspace_id = Some(self.workspaces[self.active_workspace_idx].id());
|
||||||
|
|
||||||
self.active_workspace_idx = idx;
|
self.active_workspace_idx = idx;
|
||||||
|
|
||||||
self.workspace_switch = Some(WorkspaceSwitch::Animation(Animation::new(
|
self.workspace_switch = Some(WorkspaceSwitch::Animation(Animation::new(
|
||||||
@@ -461,6 +467,11 @@ impl<W: LayoutElement> Monitor<W> {
|
|||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn previous_workspace_idx(&self) -> Option<usize> {
|
||||||
|
let id = self.previous_workspace_id?;
|
||||||
|
self.workspaces.iter().position(|w| w.id() == id)
|
||||||
|
}
|
||||||
|
|
||||||
pub fn switch_workspace(&mut self, idx: usize) {
|
pub fn switch_workspace(&mut self, idx: usize) {
|
||||||
self.activate_workspace(min(idx, self.workspaces.len() - 1));
|
self.activate_workspace(min(idx, self.workspaces.len() - 1));
|
||||||
// Don't animate this action.
|
// Don't animate this action.
|
||||||
@@ -469,6 +480,24 @@ impl<W: LayoutElement> Monitor<W> {
|
|||||||
self.clean_up_workspaces();
|
self.clean_up_workspaces();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn switch_workspace_auto_back_and_forth(&mut self, idx: usize) {
|
||||||
|
let idx = min(idx, self.workspaces.len() - 1);
|
||||||
|
|
||||||
|
if idx == self.active_workspace_idx {
|
||||||
|
if let Some(prev_idx) = self.previous_workspace_idx() {
|
||||||
|
self.switch_workspace(prev_idx);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
self.switch_workspace(idx);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn switch_workspace_previous(&mut self) {
|
||||||
|
if let Some(idx) = self.previous_workspace_idx() {
|
||||||
|
self.switch_workspace(idx);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn consume_into_column(&mut self) {
|
pub fn consume_into_column(&mut self) {
|
||||||
self.active_workspace().consume_into_column();
|
self.active_workspace().consume_into_column();
|
||||||
}
|
}
|
||||||
@@ -564,8 +593,10 @@ impl<W: LayoutElement> Monitor<W> {
|
|||||||
self.workspaces.push(ws);
|
self.workspaces.push(ws);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let previous_workspace_id = self.previous_workspace_id;
|
||||||
self.activate_workspace(new_idx);
|
self.activate_workspace(new_idx);
|
||||||
self.workspace_switch = None;
|
self.workspace_switch = None;
|
||||||
|
self.previous_workspace_id = previous_workspace_id;
|
||||||
|
|
||||||
self.clean_up_workspaces();
|
self.clean_up_workspaces();
|
||||||
}
|
}
|
||||||
@@ -584,8 +615,10 @@ impl<W: LayoutElement> Monitor<W> {
|
|||||||
self.workspaces.push(ws);
|
self.workspaces.push(ws);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let previous_workspace_id = self.previous_workspace_id;
|
||||||
self.activate_workspace(new_idx);
|
self.activate_workspace(new_idx);
|
||||||
self.workspace_switch = None;
|
self.workspace_switch = None;
|
||||||
|
self.previous_workspace_id = previous_workspace_id;
|
||||||
|
|
||||||
self.clean_up_workspaces();
|
self.clean_up_workspaces();
|
||||||
}
|
}
|
||||||
@@ -833,6 +866,8 @@ impl<W: LayoutElement> Monitor<W> {
|
|||||||
gesture.center_idx as f64 + current_pos,
|
gesture.center_idx as f64 + current_pos,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
self.previous_workspace_id = Some(self.workspaces[self.active_workspace_idx].id());
|
||||||
|
|
||||||
self.active_workspace_idx = new_idx;
|
self.active_workspace_idx = new_idx;
|
||||||
self.workspace_switch = Some(WorkspaceSwitch::Animation(Animation::new(
|
self.workspace_switch = Some(WorkspaceSwitch::Animation(Animation::new(
|
||||||
gesture.current_idx,
|
gesture.current_idx,
|
||||||
|
|||||||
@@ -18,6 +18,7 @@ use crate::animation::Animation;
|
|||||||
use crate::niri_render_elements;
|
use crate::niri_render_elements;
|
||||||
use crate::render_helpers::renderer::NiriRenderer;
|
use crate::render_helpers::renderer::NiriRenderer;
|
||||||
use crate::swipe_tracker::SwipeTracker;
|
use crate::swipe_tracker::SwipeTracker;
|
||||||
|
use crate::utils::id::IdCounter;
|
||||||
use crate::utils::output_size;
|
use crate::utils::output_size;
|
||||||
|
|
||||||
/// Amount of touchpad movement to scroll the view for the width of one working area.
|
/// Amount of touchpad movement to scroll the view for the width of one working area.
|
||||||
@@ -76,11 +77,25 @@ pub struct Workspace<W: LayoutElement> {
|
|||||||
|
|
||||||
/// Configurable properties of the layout.
|
/// Configurable properties of the layout.
|
||||||
pub options: Rc<Options>,
|
pub options: Rc<Options>,
|
||||||
|
|
||||||
|
/// Unique ID of this workspace.
|
||||||
|
id: WorkspaceId,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||||
pub struct OutputId(String);
|
pub struct OutputId(String);
|
||||||
|
|
||||||
|
static WORKSPACE_ID_COUNTER: IdCounter = IdCounter::new();
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
|
||||||
|
pub struct WorkspaceId(u32);
|
||||||
|
|
||||||
|
impl WorkspaceId {
|
||||||
|
fn next() -> WorkspaceId {
|
||||||
|
WorkspaceId(WORKSPACE_ID_COUNTER.next())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
niri_render_elements! {
|
niri_render_elements! {
|
||||||
WorkspaceRenderElement<R> => {
|
WorkspaceRenderElement<R> => {
|
||||||
Tile = TileRenderElement<R>,
|
Tile = TileRenderElement<R>,
|
||||||
@@ -225,6 +240,7 @@ impl<W: LayoutElement> Workspace<W> {
|
|||||||
view_offset_adj: None,
|
view_offset_adj: None,
|
||||||
activate_prev_column_on_removal: None,
|
activate_prev_column_on_removal: None,
|
||||||
options,
|
options,
|
||||||
|
id: WorkspaceId::next(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -240,9 +256,14 @@ impl<W: LayoutElement> Workspace<W> {
|
|||||||
view_offset_adj: None,
|
view_offset_adj: None,
|
||||||
activate_prev_column_on_removal: None,
|
activate_prev_column_on_removal: None,
|
||||||
options,
|
options,
|
||||||
|
id: WorkspaceId::next(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn id(&self) -> WorkspaceId {
|
||||||
|
self.id
|
||||||
|
}
|
||||||
|
|
||||||
pub fn advance_animations(&mut self, current_time: Duration, is_active: bool) {
|
pub fn advance_animations(&mut self, current_time: Duration, is_active: bool) {
|
||||||
if let Some(ViewOffsetAdjustment::Animation(anim)) = &mut self.view_offset_adj {
|
if let Some(ViewOffsetAdjustment::Animation(anim)) = &mut self.view_offset_adj {
|
||||||
anim.set_current_time(current_time);
|
anim.set_current_time(current_time);
|
||||||
|
|||||||
@@ -0,0 +1,27 @@
|
|||||||
|
use std::sync::atomic::{AtomicU32, Ordering};
|
||||||
|
|
||||||
|
/// Counter that returns unique IDs.
|
||||||
|
///
|
||||||
|
/// Under the hood it uses a `u32` that will eventually wrap around. When incrementing it once a
|
||||||
|
/// second, it will wrap around after about 136 years.
|
||||||
|
pub struct IdCounter {
|
||||||
|
value: AtomicU32,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl IdCounter {
|
||||||
|
pub const fn new() -> Self {
|
||||||
|
Self {
|
||||||
|
value: AtomicU32::new(0),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn next(&self) -> u32 {
|
||||||
|
self.value.fetch_add(1, Ordering::SeqCst)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Default for IdCounter {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self::new()
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -14,6 +14,7 @@ use smithay::output::Output;
|
|||||||
use smithay::reexports::rustix::time::{clock_gettime, ClockId};
|
use smithay::reexports::rustix::time::{clock_gettime, ClockId};
|
||||||
use smithay::utils::{Logical, Point, Rectangle, Size};
|
use smithay::utils::{Logical, Point, Rectangle, Size};
|
||||||
|
|
||||||
|
pub mod id;
|
||||||
pub mod spawning;
|
pub mod spawning;
|
||||||
pub mod watcher;
|
pub mod watcher;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user