Skip to content

Commit

Permalink
Remove window flicker from open command
Browse files Browse the repository at this point in the history
This solves a problem that had been already solved in
0d1b5e0 but was reintroduced in
a9a35c1. Basically before this, the
window has been closed and reopened if it existed, which results in
flickering due to the animations.

In addition to remove the window flicker the timer (if started with
--duration) will also be renewed. This fixes elkowar#892.
  • Loading branch information
BeneSim committed Jun 18, 2024
1 parent d1fde92 commit eac4e0f
Showing 1 changed file with 35 additions and 27 deletions.
62 changes: 35 additions & 27 deletions crates/eww/src/app.rs
Original file line number Diff line number Diff line change
Expand Up @@ -362,14 +362,46 @@ impl<B: DisplayBackend> App<B> {
Ok(())
}

fn setup_close_timer(&mut self, instance_id: &str, duration: Duration) {
let app_evt_sender = self.app_evt_send.clone();

let (abort_send, abort_recv) = futures::channel::oneshot::channel();

glib::MainContext::default().spawn_local({
let instance_id = instance_id.to_string();
async move {
tokio::select! {
_ = glib::timeout_future(duration) => {
let (response_sender, mut response_recv) = daemon_response::create_pair();
let command = DaemonCommand::CloseWindows { windows: vec![instance_id.clone()], sender: response_sender };
if let Err(err) = app_evt_sender.send(command) {
log::error!("Error sending close window command to daemon after gtk window destroy event: {}", err);
}
_ = response_recv.recv().await;
}
_ = abort_recv => {}
}
}
});

if let Some(old_abort_send) = self.window_close_timer_abort_senders.insert(instance_id.to_string(), abort_send) {
_ = old_abort_send.send(());
}
}

fn open_window(&mut self, window_args: &WindowArguments) -> Result<()> {
let instance_id = &window_args.instance_id;
self.failed_windows.remove(instance_id);
log::info!("Opening window {} as '{}'", window_args.window_name, instance_id);

// if an instance of this is already running, close it
// if an instance of this is already running, do nothing, but if a
// duration has been supplied refresh the window close timer
let duration = window_args.duration;
if self.open_windows.contains_key(instance_id) {
self.close_window(instance_id)?;
if let Some(duration) = duration {
self.setup_close_timer(instance_id, duration);
}
return Ok(());
}

self.instance_id_to_args.insert(instance_id.to_string(), window_args.clone());
Expand Down Expand Up @@ -431,32 +463,8 @@ impl<B: DisplayBackend> App<B> {
}
}));

let duration = window_args.duration;
if let Some(duration) = duration {
let app_evt_sender = self.app_evt_send.clone();

let (abort_send, abort_recv) = futures::channel::oneshot::channel();

glib::MainContext::default().spawn_local({
let instance_id = instance_id.to_string();
async move {
tokio::select! {
_ = glib::timeout_future(duration) => {
let (response_sender, mut response_recv) = daemon_response::create_pair();
let command = DaemonCommand::CloseWindows { windows: vec![instance_id.clone()], sender: response_sender };
if let Err(err) = app_evt_sender.send(command) {
log::error!("Error sending close window command to daemon after gtk window destroy event: {}", err);
}
_ = response_recv.recv().await;
}
_ = abort_recv => {}
}
}
});

if let Some(old_abort_send) = self.window_close_timer_abort_senders.insert(instance_id.to_string(), abort_send) {
_ = old_abort_send.send(());
}
self.setup_close_timer(instance_id, duration);
}

self.open_windows.insert(instance_id.to_string(), eww_window);
Expand Down

0 comments on commit eac4e0f

Please sign in to comment.