Subject: bug#76805: closed (Re: bug#76805: 31.0.50; [PATH] Fix Emacs uses 100% CPU after switching graphic frame to inactive)

From: [email-masked] (GNU bug Tracking System)
Date: Fri, 14 Mar 2025 19:32:02 +0000

Your bug report

#76805: 31.0.50; [PATH] Fix Emacs uses 100% CPU after switching graphic frame to inactive

which was filed against the emacs package, has been closed.

The explanation is attached below, along with your original report.
If you require more details, please reply to [email-masked].

-- 
76805: https://debbugs.gnu.org/cgi/bugreport.cgi?bug=76805
GNU Bug Tracking System
Contact [email-masked] with problems

Subject: Re: bug#76805: 31.0.50; [PATH] Fix Emacs uses 100% CPU after switching graphic frame to inactive
From: Stefan Kangas <[email-masked]>
To: Lin Sun <[email-masked]>, Eli Zaretskii <[email-masked]>
Cc: [email-masked]
Date: Fri, 14 Mar 2025 12:31:12 -0700
List-Id: <debbugs-submit.debbugs.gnu.org>

Lin Sun <[email-masked]> writes:

> Thank you all of you. Please feel free to close the ticket.

Done.

Subject: 31.0.50; [PATH] Fix Emacs uses 100% CPU after switching graphic frame to inactive
From: Lin Sun <[email-masked]>
To: "[email-masked]" <[email-masked]>
Date: Fri, 7 Mar 2025 08:17:31 +0000
List-Id: <debbugs-submit.debbugs.gnu.org>

Hi, 
Emacs sometimes takes 100% CPU after I switch emacs graphic frame to inactive.
This patch will fix the issue.

Reproduce steps:
1. Build Emacs with gtk3 and xinput2 on Ubuntu 22.04.
2. (setq x-use-fast-mouse-position 'really-fast) in early-init.el.
3. On a windows-host start a X11 server, and ssh -XY ubuntu-host:emacs to Start emacs with X11 forwared-frame, and open emacs "src/eval.c", enable the show-paren-mode in emacs.
4. On the windows host, move the mouse out of emacs-graphic frame first, the move the mouse in emacs-graphic frame and click.
5. On the windows host, switch the emacs-graphic frame to inactive (switch a native windows app to active).
Repeat steps 4,5 sometimes the emacs will takes 100% CPU.

The issue won't happen if set the x-use-fast-mouse-position to `t` or `nil` instead of the 'really-fast.

According to my debugging and tracking the variables, I found that
1. the xterm.c:21710 will let "dpyinfo->last_mouse_motion_frame = NULL;", then 
2. later calls `x_fast_mouse_position` will no chance to let "XX->mouse_moved = false", then 
3. the function some_mouse_moved() in keyboard.c always return true; then
4. the function timer_start_idle() in keyboard.c will be called again and again, which leads 100% CPU usage.

As contrast when setting the x-use-fast-mouse-position to `t`, the "XX->mouse_moved = false;" always run, then the issue won't happen.

Please help review the patch. Thanks

Best Regards, Lin

From 4260ce23f260a58593bdbf02b251eb8077f0bedf Mon Sep 17 00:00:00 2001
From: Lin Sun <[email-masked]>
Date: Fri, 7 Mar 2025 06:50:03 +0000
Subject: [PATCH] * src/xterm.c: Mark mouse_moved to false in
 x_fast_mouse_position()

---
 src/xterm.c | 23 +++++++----------------
 1 file changed, 7 insertions(+), 16 deletions(-)

diff --git a/src/xterm.c b/src/xterm.c
index 2ccf267bbd3..3fd9cb54ccf 100644
--- a/src/xterm.c
+++ b/src/xterm.c
@@ -14878,6 +14878,13 @@ x_fast_mouse_position (struct frame **fp, int insist, Lisp_Object *bar_window,
       return;
     }
 
+  FOR_EACH_FRAME (tail, frame)
+    {
+      if (FRAME_X_P (XFRAME (frame))
+	  && (FRAME_DISPLAY_INFO (XFRAME (frame)) == dpyinfo))
+	XFRAME (frame)->mouse_moved = false;
+    }
+
   if (!EQ (Vx_use_fast_mouse_position, Qreally_fast))
     {
       /* This means that Emacs should select a frame and report the
@@ -14886,14 +14893,6 @@ x_fast_mouse_position (struct frame **fp, int insist, Lisp_Object *bar_window,
 	 window beneath the pointer, and was borrowed from
 	 haiku_mouse_position in haikuterm.c.  */
 
-      FOR_EACH_FRAME (tail, frame)
-	{
-	  if (FRAME_X_P (XFRAME (frame))
-	      && (FRAME_DISPLAY_INFO (XFRAME (frame))
-		  == dpyinfo))
-	    XFRAME (frame)->mouse_moved = false;
-	}
-
       if (gui_mouse_grabbed (dpyinfo)
 	  && !EQ (track_mouse, Qdropping)
 	  && !EQ (track_mouse, Qdrag_source))
@@ -14964,14 +14963,6 @@ x_fast_mouse_position (struct frame **fp, int insist, Lisp_Object *bar_window,
 	  *bar_window = Qnil;
 	  *part = scroll_bar_nowhere;
 
-	  FOR_EACH_FRAME (tail, frame)
-	    {
-	      if (FRAME_X_P (XFRAME (frame))
-		  && (FRAME_DISPLAY_INFO (XFRAME (frame))
-		      == dpyinfo))
-		XFRAME (frame)->mouse_moved = false;
-	    }
-
 	  dpyinfo->last_mouse_motion_frame->mouse_moved = false;
 	}
     }
-- 
2.34.1