Skip to content

Abnormal CPU usage when the window becomes active/inactive and a large file is opened

Mousepad 0.5.10, GTK 3.24.36, GSV 4.8.4

Steps to reproduce:

  • Open a "large file" (base64 /dev/urandom | head -100000 >test-file is enough for me to highlight the problem)
  • Wait until the textview is fully loaded so that Mousepad doesn't use the CPU anymore
  • Make the window active/inactive and observe the CPU usage

I have not been able to identify exactly what portion of GTK code is being executed at this time, but the problem disappears if the GDK_WINDOW_STATE_FOCUSED changed mask is intercepted in window_state_event():

diff --git a/mousepad/mousepad-window.c b/mousepad/mousepad-window.c
index b8fb73d0..722d324a 100644
--- a/mousepad/mousepad-window.c
+++ b/mousepad/mousepad-window.c
@@ -1423,6 +1423,9 @@ mousepad_window_window_state_event (GtkWidget           *widget,
 
   g_return_val_if_fail (MOUSEPAD_IS_WINDOW (window), FALSE);
 
+  if (event->changed_mask & GDK_WINDOW_STATE_FOCUSED)
+    return TRUE;
+
   /* update bars visibility when entering/leaving fullscreen mode */
   if (event->changed_mask & GDK_WINDOW_STATE_FULLSCREEN)
     {

Obviously this prevents the window from being redrawn to reflect whether it is active or not, so it is only a workaround. Also, Gedit 44.2 and Geany 1.38 do not have this problem, even though they use the same toolkit (especially Gedit). So there must be a way to avoid this problem that I can't find.

I couldn't trace the problem in GDB, because if I put a breakpoint the problem disappears! Here is what strace gives in a loop when we are at the third step above:

recvmsg(8, {msg_namelen=0}, 0)          = -1 EAGAIN (Resource temporarily unavailable)
poll([{fd=3, events=POLLIN}, {fd=8, events=POLLIN}, {fd=9, events=POLLIN}], 3, 0) = 0 (Timeout)

With sometimes:

write(3, "\1\0\0\0\0\0\0\0", 8)         = 8
poll([{fd=8, events=POLLIN|POLLOUT}], 1, -1) = 1 ([{fd=8, revents=POLLOUT}])
writev(8, [{iov_base="5 \4\0\202\26\0\4\7\0\0\4\3\0\22\0\213\4\6\0\203\26\0\4\202\26\0\4%\0\0\0"..., iov_len=572}, {iov_base=NULL, iov_len=0}, {iov_base="", iov_len=0}], 3) = 572
recvmsg(8, {msg_namelen=0}, 0)          = -1 EAGAIN (Resource temporarily unavailable)
poll([{fd=3, events=POLLIN}, {fd=8, events=POLLIN}, {fd=9, events=POLLIN}], 3, 0) = 1 ([{fd=3, revents=POLLIN}])
read(3, "\1\0\0\0\0\0\0\0", 16)         = 8

@matt I'm calling on you if you're still around in case this tells you something, because since Geany doesn't have this problem, maybe you're aware of a patch it's implementing to fix something in GTK 3? Because I don't think Mousepad does anything special here. For your information, this problem was already present in 0.4.2, and it disappears in !78 that is with GTK 4.

Edited by Gaël Bonithon