From 4d8e306b744cda1e47d5d7252003abba41a95d3b Mon Sep 17 00:00:00 2001 From: nevaforget Date: Sat, 28 Mar 2026 21:50:03 +0100 Subject: [PATCH] feat: add fade-out animation on dismiss for smooth visual exit MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Without this, app.quit() destroys windows instantly, creating a jarring pop-out. Now all windows fade out over 250ms (matching the fade-in) before the app exits. Uses the same CSS opacity transition — just removes the "visible" class and defers quit via glib timeout. --- CHANGELOG.md | 2 +- Cargo.lock | 2 +- src/panel.rs | 19 +++++++++++++++---- 3 files changed, 17 insertions(+), 6 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7f07561..8a22b75 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,7 +7,7 @@ Format based on [Keep a Changelog](https://keepachangelog.com/). ### Added -- Fade-in animation (250ms ease-in) for panel and wallpaper windows via CSS opacity transition +- Fade-in/fade-out animation (250ms ease-in) for panel and wallpaper windows via CSS opacity transition ### Fixed diff --git a/Cargo.lock b/Cargo.lock index 35f4d13..297a14d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -805,7 +805,7 @@ dependencies = [ [[package]] name = "moonset" -version = "0.4.0" +version = "0.4.1" dependencies = [ "dirs", "env_logger", diff --git a/src/panel.rs b/src/panel.rs index 2423d01..ed3e8f5 100644 --- a/src/panel.rs +++ b/src/panel.rs @@ -13,7 +13,7 @@ use std::io::Write; use std::os::unix::fs::OpenOptionsExt; use std::path::{Path, PathBuf}; use std::rc::Rc; -use std::time::SystemTime; +use std::time::{Duration, SystemTime}; use crate::i18n::{load_strings, Strings}; use crate::power::{self, PowerError}; @@ -247,6 +247,17 @@ fn apply_blur(texture: &gdk::Texture, sigma: f32) -> gdk::Texture { mem_texture.upcast() } +/// Fade out all windows and quit the app after the CSS transition completes. +fn fade_out_and_quit(app: >k::Application) { + for window in app.windows() { + window.remove_css_class("visible"); + } + let app = app.clone(); + glib::timeout_add_local_once(Duration::from_millis(250), move || { + app.quit(); + }); +} + /// Create a wallpaper-only window for secondary monitors. pub fn create_wallpaper_window(texture: &gdk::Texture, app: >k::Application) -> gtk::ApplicationWindow { let window = gtk::ApplicationWindow::builder() @@ -303,7 +314,7 @@ pub fn create_panel_window(texture: &gdk::Texture, app: >k::Application) -> gt #[weak] app, move |_, _, _, _| { - app.quit(); + fade_out_and_quit(&app); } )); background.add_controller(click_controller); @@ -373,7 +384,7 @@ pub fn create_panel_window(texture: &gdk::Texture, app: >k::Application) -> gt glib::Propagation::Proceed, move |_, keyval, _, _| { if keyval == gdk::Key::Escape { - app.quit(); + fade_out_and_quit(&app); glib::Propagation::Stop } else { glib::Propagation::Proceed @@ -593,7 +604,7 @@ fn execute_action( match result { Ok(Ok(())) => { if quit_after { - app.quit(); + fade_out_and_quit(&app); } } Ok(Err(e)) => {