Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Terminal window stops updating after resuming from sleep on Windows 10, 11 #475

Closed
yndx-melkov opened this issue Mar 27, 2023 · 0 comments
Closed

Comments

@yndx-melkov
Copy link
Contributor

yndx-melkov commented Mar 27, 2023

I have a relatively new laptop with Windows 11 (that's important because this combination can use Modern Standby in Windows).

When setting the laptop to sleep and waking it up, existing KiTTY windows stop displaying any changes, although the connection works and commands on the server are executed (I just can't see that).

Doing full screen refresh, such as bringing the window out of focus and back, using scrolling and so on, reveals the changed content, but normal keypress and/or mouse activity does not.

After waiting a few minutes, terminal operation usually comes to normal, so the hard patience here can be a workaround :)

I've investigated this bug and found that this problem is in Putty code (so I'll be cross-posting this to Putty authors too). Putty does not restore connections, but if the connection is not dropped at all during the sleep, Putty gets the symptoms described above.

  • Windows delays WM_TIMER messages that were scheduled to arrive during the time the computer went to sleep for the period of sleep. However, GetTickCount() continues to advance when that sleep mode is actually Modern StandBy.
  • That message (of TIMING_TIMER_ID) was supposed to invoke the run_timers() function that pops and executes the callbacks at the front of timers priority queue (whose execution time has come).
  • Most of the time, the front of timers is an event scheduled approximately 2 minutes ahead.
  • Now the computer wakes up and we have the front element of timers pointing to the past (in terms of GetTickCount()), but respective WM_TIMER will arrive in another one or two minutes.
  • Because of that, schedule_timer() would normally not call timer_change_notify() that schedules the new WM_TIMER message, so no one would call run_timers() and execute what we've just scheduled.
  • Now, look at term_update_callback() that is actually responsible for the terminal window update. There's a protection against its repetitive calling that sets term->window_update_cooldown and schedules its reset after 20ms using schedule_timer().
  • Whoosh! window_update_cooldown was set, but the schedule_timer() does not work any more, so cooldown is not reset back, and term_update_callback() does not work.

To solve the problem for me, I first tried to reschedule the WM_TIMER message from WM_POWERBROADCAST. Surprise! Windows does not send WM_POWERBROADCAST when it enters or leaves Modern Standby. Nothing can be done here.

So my solution is to look at the front element of timers. Should its due time be too much (like 10 seconds) in the past, we can generally think that something bad has happened with timers and reschedule WM_TIMER .

--- orig\timing.c	2023-03-06 21:40:49 +0300
+++ KiTTY-0.76.1.5\0.76b_My_PuTTY\timing.c	2023-03-27 05:49:49 +0300
@@ -137,10 +137,12 @@
     }
 
     first = (struct timer *)index234(timers, 0);
-    if (first == t) {
+    if (first == t || first != NULL && first->now + 10 * (TICKSPERSEC) < now) {
 	/*
 	 * This timer is the very first on the list, so we must
 	 * notify the front end.
+	 * Also notify if the first timer has seriously missed its run time,
+	 * most likely due to a system sleep event.
 	 */
 	timer_change_notify(first->now);
     }
@cyd01 cyd01 closed this as completed in b2b8df2 May 9, 2023
cyd01 added a commit that referenced this issue May 9, 2023
Resolves #475 Terminal window stops updating after resuming from sleep
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant