mirror of
https://github.com/niri-wm/niri.git
synced 2026-06-24 02:01:18 +07:00
Make interactively moved window semitransparent
This commit is contained in:
+64
-1
@@ -93,6 +93,9 @@ pub const RESIZE_ANIMATION_THRESHOLD: f64 = 10.;
|
|||||||
/// Pointer needs to move this far to pull a window from the layout.
|
/// Pointer needs to move this far to pull a window from the layout.
|
||||||
const INTERACTIVE_MOVE_START_THRESHOLD: f64 = 256. * 256.;
|
const INTERACTIVE_MOVE_START_THRESHOLD: f64 = 256. * 256.;
|
||||||
|
|
||||||
|
/// Opacity of interactively moved tiles targeting the scrolling layout.
|
||||||
|
const INTERACTIVE_MOVE_ALPHA: f64 = 0.75;
|
||||||
|
|
||||||
/// Size-relative units.
|
/// Size-relative units.
|
||||||
pub struct SizeFrac;
|
pub struct SizeFrac;
|
||||||
|
|
||||||
@@ -2334,6 +2337,34 @@ impl<W: LayoutElement> Layout<W> {
|
|||||||
// Tile position must be rounded to physical pixels.
|
// Tile position must be rounded to physical pixels.
|
||||||
assert_abs_diff_eq!(tile_pos.x, rounded_pos.x, epsilon = 1e-5);
|
assert_abs_diff_eq!(tile_pos.x, rounded_pos.x, epsilon = 1e-5);
|
||||||
assert_abs_diff_eq!(tile_pos.y, rounded_pos.y, epsilon = 1e-5);
|
assert_abs_diff_eq!(tile_pos.y, rounded_pos.y, epsilon = 1e-5);
|
||||||
|
|
||||||
|
if let Some(alpha) = &move_.tile.alpha_animation {
|
||||||
|
if move_.is_floating {
|
||||||
|
assert_eq!(
|
||||||
|
alpha.anim.to(),
|
||||||
|
1.,
|
||||||
|
"interactively moved floating tile can animate alpha only to 1"
|
||||||
|
);
|
||||||
|
|
||||||
|
assert!(
|
||||||
|
!alpha.hold_after_done,
|
||||||
|
"interactively moved floating tile \
|
||||||
|
cannot have held alpha animation"
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
assert_ne!(
|
||||||
|
alpha.anim.to(),
|
||||||
|
1.,
|
||||||
|
"interactively moved scrolling tile must animate alpha to not 1"
|
||||||
|
);
|
||||||
|
|
||||||
|
assert!(
|
||||||
|
alpha.hold_after_done,
|
||||||
|
"interactively moved scrolling tile \
|
||||||
|
must have held alpha animation"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -3005,6 +3036,21 @@ impl<W: LayoutElement> Layout<W> {
|
|||||||
size.h = ensure_min_max_size_maybe_zero(size.h, min_size.h, max_size.h);
|
size.h = ensure_min_max_size_maybe_zero(size.h, min_size.h, max_size.h);
|
||||||
|
|
||||||
win.request_size_once(size, true);
|
win.request_size_once(size, true);
|
||||||
|
|
||||||
|
// Animate the tile back to opaque.
|
||||||
|
move_.tile.animate_alpha(
|
||||||
|
INTERACTIVE_MOVE_ALPHA,
|
||||||
|
1.,
|
||||||
|
self.options.animations.window_movement.0,
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
// Animate the tile back to semitransparent.
|
||||||
|
move_.tile.animate_alpha(
|
||||||
|
1.,
|
||||||
|
INTERACTIVE_MOVE_ALPHA,
|
||||||
|
self.options.animations.window_movement.0,
|
||||||
|
);
|
||||||
|
move_.tile.hold_alpha_animation_after_done();
|
||||||
}
|
}
|
||||||
|
|
||||||
return;
|
return;
|
||||||
@@ -3773,6 +3819,16 @@ impl<W: LayoutElement> Layout<W> {
|
|||||||
is_floating = unfullscreen_to_floating;
|
is_floating = unfullscreen_to_floating;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Animate to semitransparent.
|
||||||
|
if !is_floating {
|
||||||
|
tile.animate_alpha(
|
||||||
|
1.,
|
||||||
|
INTERACTIVE_MOVE_ALPHA,
|
||||||
|
self.options.animations.window_movement.0,
|
||||||
|
);
|
||||||
|
tile.hold_alpha_animation_after_done();
|
||||||
|
}
|
||||||
|
|
||||||
let mut data = InteractiveMoveData {
|
let mut data = InteractiveMoveData {
|
||||||
tile,
|
tile,
|
||||||
output,
|
output,
|
||||||
@@ -3869,7 +3925,7 @@ impl<W: LayoutElement> Layout<W> {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
let Some(InteractiveMoveState::Moving(move_)) = self.interactive_move.take() else {
|
let Some(InteractiveMoveState::Moving(mut move_)) = self.interactive_move.take() else {
|
||||||
unreachable!()
|
unreachable!()
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -3878,6 +3934,13 @@ impl<W: LayoutElement> Layout<W> {
|
|||||||
for ws in self.workspaces_mut() {
|
for ws in self.workspaces_mut() {
|
||||||
ws.dnd_scroll_gesture_end();
|
ws.dnd_scroll_gesture_end();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Also animate the tile back to opaque.
|
||||||
|
move_.tile.animate_alpha(
|
||||||
|
INTERACTIVE_MOVE_ALPHA,
|
||||||
|
1.,
|
||||||
|
self.options.animations.window_movement.0,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
match &mut self.monitor_set {
|
match &mut self.monitor_set {
|
||||||
|
|||||||
+18
-2
@@ -148,6 +148,12 @@ struct MoveAnimation {
|
|||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub(super) struct AlphaAnimation {
|
pub(super) struct AlphaAnimation {
|
||||||
pub(super) anim: Animation,
|
pub(super) anim: Animation,
|
||||||
|
/// Whether the animation should persist after it's done.
|
||||||
|
///
|
||||||
|
/// This is used by things like interactive move which need to animate alpha to
|
||||||
|
/// semitransparent, then hold it at semitransparent for a while, until the operation
|
||||||
|
/// completes.
|
||||||
|
pub(super) hold_after_done: bool,
|
||||||
offscreen: OffscreenBuffer,
|
offscreen: OffscreenBuffer,
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -319,7 +325,7 @@ impl<W: LayoutElement> Tile<W> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if let Some(alpha) = &mut self.alpha_animation {
|
if let Some(alpha) = &mut self.alpha_animation {
|
||||||
if alpha.anim.is_done() {
|
if !alpha.hold_after_done && alpha.anim.is_done() {
|
||||||
self.alpha_animation = None;
|
self.alpha_animation = None;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -334,7 +340,10 @@ impl<W: LayoutElement> Tile<W> {
|
|||||||
|| self.resize_animation.is_some()
|
|| self.resize_animation.is_some()
|
||||||
|| self.move_x_animation.is_some()
|
|| self.move_x_animation.is_some()
|
||||||
|| self.move_y_animation.is_some()
|
|| self.move_y_animation.is_some()
|
||||||
|| self.alpha_animation.is_some()
|
|| self
|
||||||
|
.alpha_animation
|
||||||
|
.as_ref()
|
||||||
|
.is_some_and(|alpha| !alpha.anim.is_done())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn update_render_elements(&mut self, is_active: bool, view_rect: Rectangle<f64, Logical>) {
|
pub fn update_render_elements(&mut self, is_active: bool, view_rect: Rectangle<f64, Logical>) {
|
||||||
@@ -491,6 +500,7 @@ impl<W: LayoutElement> Tile<W> {
|
|||||||
|
|
||||||
self.alpha_animation = Some(AlphaAnimation {
|
self.alpha_animation = Some(AlphaAnimation {
|
||||||
anim: Animation::new(self.clock.clone(), current, to, 0., config),
|
anim: Animation::new(self.clock.clone(), current, to, 0., config),
|
||||||
|
hold_after_done: false,
|
||||||
offscreen,
|
offscreen,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -505,6 +515,12 @@ impl<W: LayoutElement> Tile<W> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn hold_alpha_animation_after_done(&mut self) {
|
||||||
|
if let Some(alpha) = &mut self.alpha_animation {
|
||||||
|
alpha.hold_after_done = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn window(&self) -> &W {
|
pub fn window(&self) -> &W {
|
||||||
&self.window
|
&self.window
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1757,6 +1757,11 @@ impl<W: LayoutElement> Workspace<W> {
|
|||||||
if visible {
|
if visible {
|
||||||
assert_eq!(anim.to(), 1., "visible tiles can animate alpha only to 1");
|
assert_eq!(anim.to(), 1., "visible tiles can animate alpha only to 1");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
assert!(
|
||||||
|
!alpha.hold_after_done,
|
||||||
|
"tiles in the layout cannot have held alpha animation"
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user