nits
This commit is contained in:
1 parent
da60ecb719
commit
42f022fde5
4 files changed
+124
-120
No files matched your search
@@ -538,6 +538,7 @@ impl Ferese {
|
|||||||
if self.click_overview_workspace(position) {
|
if self.click_overview_workspace(position) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(window) = self.window_under_visual(position)
|
if let Some(window) = self.window_under_visual(position)
|
||||||
&& let Some(id) = self.windows.ids().get(&window).copied()
|
&& let Some(id) = self.windows.ids().get(&window).copied()
|
||||||
{
|
{
|
||||||
|
|||||||
+95
-92
@@ -742,14 +742,17 @@ impl Ferese {
|
|||||||
let Some(output) = self.overview_strip_at(point) else {
|
let Some(output) = self.overview_strip_at(point) else {
|
||||||
return false;
|
return false;
|
||||||
};
|
};
|
||||||
|
|
||||||
let card = self
|
let card = self
|
||||||
.overview_workspace_cards(&output)
|
.overview_workspace_cards(&output)
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.find(|card| contains(card.rect, point));
|
.find(|card| contains(card.rect, point));
|
||||||
|
|
||||||
if let Some(card) = card {
|
if let Some(card) = card {
|
||||||
let Some(output_id) = self.output_id(&output) else {
|
let Some(output_id) = self.output_id(&output) else {
|
||||||
return true;
|
return true;
|
||||||
};
|
};
|
||||||
|
|
||||||
if self
|
if self
|
||||||
.output_workspaces
|
.output_workspaces
|
||||||
.switch_workspace(output_id, card.workspace)
|
.switch_workspace(output_id, card.workspace)
|
||||||
@@ -950,6 +953,98 @@ fn directional_distance(direction: Direction, current: (f64, f64), candidate: (f
|
|||||||
Some(primary + secondary * 0.35)
|
Some(primary + secondary * 0.35)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Default for OverviewMotion {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self {
|
||||||
|
active: false,
|
||||||
|
presentations: HashMap::new(),
|
||||||
|
opacity: AnimatedValue::new(0.0),
|
||||||
|
exit_transition: None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl OverviewMotion {
|
||||||
|
pub(crate) fn is_animating(&self, spring: SpringConfig) -> bool {
|
||||||
|
self.exit_transition.is_some()
|
||||||
|
|| (self.opacity.current - self.opacity.target).abs() > 0.001
|
||||||
|
|| self.opacity.velocity.abs() > 0.005
|
||||||
|
|| self.presentations.values().any(|rect| !rect.is_settled(spring))
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn is_presenting(&self) -> bool {
|
||||||
|
self.active || !self.presentations.is_empty() || self.opacity.current > 0.001
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn opacity(&self) -> f32 {
|
||||||
|
self.opacity.current.clamp(0.0, 1.0) as f32
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn presented_rect(&self, id: WindowId, normal: Rect) -> Rect {
|
||||||
|
let preview = self.presentations.get(&id).map_or(normal, |p| p.current);
|
||||||
|
if let Some((elapsed, _)) = self.exit_transition {
|
||||||
|
let t = 1.0 - (1.0 - (elapsed / EXIT_DURATION).clamp(0.0, 1.0)).powi(3);
|
||||||
|
return Rect::new(
|
||||||
|
preview.x + (normal.x - preview.x) * t,
|
||||||
|
preview.y + (normal.y - preview.y) * t,
|
||||||
|
preview.width + (normal.width - preview.width) * t,
|
||||||
|
preview.height + (normal.height - preview.height) * t,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
preview
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn advance(&mut self, delta: Duration, spring: SpringConfig, animations_enabled: bool) -> bool {
|
||||||
|
if let Some((elapsed, initial_opacity)) = self.exit_transition {
|
||||||
|
let elapsed = if animations_enabled {
|
||||||
|
elapsed + delta.as_secs_f64()
|
||||||
|
} else {
|
||||||
|
EXIT_DURATION
|
||||||
|
};
|
||||||
|
let remaining = (1.0 - elapsed / EXIT_DURATION).clamp(0.0, 1.0);
|
||||||
|
self.opacity.current = initial_opacity * remaining.powi(3);
|
||||||
|
if elapsed >= EXIT_DURATION {
|
||||||
|
self.exit_transition = None;
|
||||||
|
self.presentations.clear();
|
||||||
|
self.opacity.snap();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
self.exit_transition = Some((elapsed, initial_opacity));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
let mut active_animation = false;
|
||||||
|
|
||||||
|
for presentation in self.presentations.values_mut() {
|
||||||
|
if animations_enabled {
|
||||||
|
active_animation |= presentation.advance(delta, spring);
|
||||||
|
} else {
|
||||||
|
presentation.snap();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if !self.active && !active_animation {
|
||||||
|
self.presentations.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
if animations_enabled {
|
||||||
|
// Geometry's 0.1-pixel tolerance is far too coarse for opacity:
|
||||||
|
// it would abruptly drop the last ten percent of the fade.
|
||||||
|
active_animation |= self.opacity.advance(
|
||||||
|
delta,
|
||||||
|
SpringConfig {
|
||||||
|
position_tolerance: 0.001,
|
||||||
|
velocity_tolerance: 0.005,
|
||||||
|
..spring
|
||||||
|
},
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
self.opacity.snap();
|
||||||
|
}
|
||||||
|
|
||||||
|
active_animation
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
@@ -1276,95 +1371,3 @@ mod tests {
|
|||||||
assert!(!overview.select_direction(Direction::Right));
|
assert!(!overview.select_direction(Direction::Right));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for OverviewMotion {
|
|
||||||
fn default() -> Self {
|
|
||||||
Self {
|
|
||||||
active: false,
|
|
||||||
presentations: HashMap::new(),
|
|
||||||
opacity: AnimatedValue::new(0.0),
|
|
||||||
exit_transition: None,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl OverviewMotion {
|
|
||||||
pub(crate) fn is_animating(&self, spring: SpringConfig) -> bool {
|
|
||||||
self.exit_transition.is_some()
|
|
||||||
|| (self.opacity.current - self.opacity.target).abs() > 0.001
|
|
||||||
|| self.opacity.velocity.abs() > 0.005
|
|
||||||
|| self.presentations.values().any(|rect| !rect.is_settled(spring))
|
|
||||||
}
|
|
||||||
|
|
||||||
pub(crate) fn is_presenting(&self) -> bool {
|
|
||||||
self.active || !self.presentations.is_empty() || self.opacity.current > 0.001
|
|
||||||
}
|
|
||||||
|
|
||||||
pub(crate) fn opacity(&self) -> f32 {
|
|
||||||
self.opacity.current.clamp(0.0, 1.0) as f32
|
|
||||||
}
|
|
||||||
|
|
||||||
pub(crate) fn presented_rect(&self, id: WindowId, normal: Rect) -> Rect {
|
|
||||||
let preview = self.presentations.get(&id).map_or(normal, |p| p.current);
|
|
||||||
if let Some((elapsed, _)) = self.exit_transition {
|
|
||||||
let t = 1.0 - (1.0 - (elapsed / EXIT_DURATION).clamp(0.0, 1.0)).powi(3);
|
|
||||||
return Rect::new(
|
|
||||||
preview.x + (normal.x - preview.x) * t,
|
|
||||||
preview.y + (normal.y - preview.y) * t,
|
|
||||||
preview.width + (normal.width - preview.width) * t,
|
|
||||||
preview.height + (normal.height - preview.height) * t,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
preview
|
|
||||||
}
|
|
||||||
|
|
||||||
pub(crate) fn advance(&mut self, delta: Duration, spring: SpringConfig, animations_enabled: bool) -> bool {
|
|
||||||
if let Some((elapsed, initial_opacity)) = self.exit_transition {
|
|
||||||
let elapsed = if animations_enabled {
|
|
||||||
elapsed + delta.as_secs_f64()
|
|
||||||
} else {
|
|
||||||
EXIT_DURATION
|
|
||||||
};
|
|
||||||
let remaining = (1.0 - elapsed / EXIT_DURATION).clamp(0.0, 1.0);
|
|
||||||
self.opacity.current = initial_opacity * remaining.powi(3);
|
|
||||||
if elapsed >= EXIT_DURATION {
|
|
||||||
self.exit_transition = None;
|
|
||||||
self.presentations.clear();
|
|
||||||
self.opacity.snap();
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
self.exit_transition = Some((elapsed, initial_opacity));
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
let mut active_animation = false;
|
|
||||||
|
|
||||||
for presentation in self.presentations.values_mut() {
|
|
||||||
if animations_enabled {
|
|
||||||
active_animation |= presentation.advance(delta, spring);
|
|
||||||
} else {
|
|
||||||
presentation.snap();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if !self.active && !active_animation {
|
|
||||||
self.presentations.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
if animations_enabled {
|
|
||||||
// Geometry's 0.1-pixel tolerance is far too coarse for opacity:
|
|
||||||
// it would abruptly drop the last ten percent of the fade.
|
|
||||||
active_animation |= self.opacity.advance(
|
|
||||||
delta,
|
|
||||||
SpringConfig {
|
|
||||||
position_tolerance: 0.001,
|
|
||||||
velocity_tolerance: 0.005,
|
|
||||||
..spring
|
|
||||||
},
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
self.opacity.snap();
|
|
||||||
}
|
|
||||||
|
|
||||||
active_animation
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -393,7 +393,7 @@ pub struct Ferese {
|
|||||||
pub(crate) shell_resources: Vec<Weak<FereseShellV1>>,
|
pub(crate) shell_resources: Vec<Weak<FereseShellV1>>,
|
||||||
pub(crate) shell_snapshot_serial: u32,
|
pub(crate) shell_snapshot_serial: u32,
|
||||||
pub(crate) last_shell_snapshot: Option<ShellSnapshot>,
|
pub(crate) last_shell_snapshot: Option<ShellSnapshot>,
|
||||||
pub(crate) overview: crate::overview::OverviewState,
|
pub(crate) overview: OverviewState,
|
||||||
next_output_id: u64,
|
next_output_id: u64,
|
||||||
last_animation_tick: Instant,
|
last_animation_tick: Instant,
|
||||||
pub popups: PopupManager,
|
pub popups: PopupManager,
|
||||||
|
|||||||
@@ -359,6 +359,33 @@ impl Default for WorkspaceSet {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl WorkspaceSet {
|
impl WorkspaceSet {
|
||||||
|
pub fn new(
|
||||||
|
default_layout_mode: LayoutMode,
|
||||||
|
default_column_width: ColumnWidth,
|
||||||
|
scrolling_focus_strategy: ViewportFocusStrategy,
|
||||||
|
) -> Self {
|
||||||
|
let active = WorkspaceId(1);
|
||||||
|
let workspace = Workspace {
|
||||||
|
id: active,
|
||||||
|
layout: WorkspaceLayout::new(default_layout_mode, default_column_width, scrolling_focus_strategy),
|
||||||
|
floating: Vec::new(),
|
||||||
|
last_focused: None,
|
||||||
|
fullscreen: None,
|
||||||
|
};
|
||||||
|
let workspaces = HashMap::from([(active, workspace)]);
|
||||||
|
|
||||||
|
Self {
|
||||||
|
active,
|
||||||
|
workspaces,
|
||||||
|
window_workspaces: HashMap::new(),
|
||||||
|
placements: HashMap::new(),
|
||||||
|
default_layout_mode,
|
||||||
|
default_column_width,
|
||||||
|
scrolling_focus_strategy,
|
||||||
|
next_id: 2,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn reconfigure_live(
|
pub fn reconfigure_live(
|
||||||
&mut self,
|
&mut self,
|
||||||
mode: LayoutMode,
|
mode: LayoutMode,
|
||||||
@@ -428,33 +455,6 @@ impl WorkspaceSet {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn new(
|
|
||||||
default_layout_mode: LayoutMode,
|
|
||||||
default_column_width: ColumnWidth,
|
|
||||||
scrolling_focus_strategy: ViewportFocusStrategy,
|
|
||||||
) -> Self {
|
|
||||||
let active = WorkspaceId(1);
|
|
||||||
let workspace = Workspace {
|
|
||||||
id: active,
|
|
||||||
layout: WorkspaceLayout::new(default_layout_mode, default_column_width, scrolling_focus_strategy),
|
|
||||||
floating: Vec::new(),
|
|
||||||
last_focused: None,
|
|
||||||
fullscreen: None,
|
|
||||||
};
|
|
||||||
let workspaces = HashMap::from([(active, workspace)]);
|
|
||||||
|
|
||||||
Self {
|
|
||||||
active,
|
|
||||||
workspaces,
|
|
||||||
window_workspaces: HashMap::new(),
|
|
||||||
placements: HashMap::new(),
|
|
||||||
default_layout_mode,
|
|
||||||
default_column_width,
|
|
||||||
scrolling_focus_strategy,
|
|
||||||
next_id: 2,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn active_id(&self) -> WorkspaceId {
|
pub fn active_id(&self) -> WorkspaceId {
|
||||||
self.active
|
self.active
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in new issue
Block a user