GNOME Bugzilla – Bug 573123
blank/dead window if gtk_widget_show/gtk_widget_hide are called frequently
Last modified: 2018-02-10 03:24:30 UTC
Please describe the problem: Some applications which call gtk_widget_show(window) & gtk_widget_hide(window) frequenctly can encounter a blank screen problem. One of the applications is gcin, which is a input-method program. When a blank screen occurs, the gtk application cannot write to the window anymore. In other words, the window is dead. It has been verifed that the versions: 2.8.20, 2.10.0, 2.10.14, 2.11.6 : OK versions >= 2.12.0 : have this problem. Steps to reproduce: Use the following simplified testcase: http://hyperrate.com/topic-files-dir/33/9233-lXyKLnTUkI/blank.tbz To run this case: $ tar xvfj blank.tbz $ cd blank $ make $ ./blank Note that the blank window problem usually occurs when the X window load is heavy, such as moving/resizing a firefox window or switching to a new desktop with firefox and other windows. The testcase randomly writes strings and shows/hides the window. When the blank window problem occurs, there is no text output in the window and the window is filled with the partial image of other window. Actual results: A blank/dead window. Expected results: The text in the window should not disappear. Does this happen every time? In this testcase it's possible reproduce almost every time. In gcin, sometimes. It also appears in some windows of gimp. Other information: Probably related to this bug. + * gdk_window_freeze_toplevel_updates_libgtk_only: + * @window: a #GdkWindow + * + * Temporarily freezes a window and all its descendants such that it won't + * receive expose events. The window will begin receiving expose events + * again when gdk_window_thaw_toplevel_updates_libgtk_only() is called. If + * gdk_window_freeze_toplevel_updates_libgtk_only() + * has been called more than once, + * gdk_window_thaw_toplevel_updates_libgtk_only() must be called + * an equal number of times to begin processing exposes. + * + * This function is not part of the GDK public API and is only + * for use by GTK+.
Created attachment 129491 [details] testcase testcase tar xvfj blank.tbz
Created attachment 129531 [details] [review] A workaround for blank/dead window
> It has been verifed that the versions: > 2.8.20, 2.10.0, 2.10.14, 2.11.6 : OK > versions >= 2.12.0 : have this problem. I also tested newer ones. All 2.12, 2.14, 2.15 series have this problem. (2.12.1, 2.12.9, 2.12.11, 2.12.12, 2.14.7, 2.15.4.) Screenshots of the testcase [1]: http://cle.linux.org.tw/trac/wiki/TmpBugzilla573123 Left 4 images show how the testcase is supposed to work. Right 4 images show what this bug is. I can 100% reproduce the bug with following steps: 1. build and run testcase [1] 2. open an Firefox browser. Maximize Firefox and unmaximize it rapidly, repeatly. My testing machine is Athlon64 Dual Core 3000Mhz (6000+) + 4 Gib RAM. If your machine is old and slow, it is even more easily to reproduce the bug. [1] testcase: the first attachment of this bug
I made a patch [2] to solve this bug. It fix all 2.12, 2.14, 2.15 series. (It has been tested on 2.12.0, 2.14.7, and 2.15.4.) However, it may affect GTK+ bug #426246 ("Spurious" expose events during asynchronous GtkWindow resizing). [3] I do not know what bug #426246 really is, so I can not test my patch against it. [2] patch id #129531 of this bug (A workaround for blank/dead window ) [3] http://bugzilla.gnome.org/426246 I paste the GTK+ 2.12.0 changelog below about bug #426246 > 2007-09-12 Kristian Rietveld <kris@imendio.com> > > Fixes #426246. > > * gdk/gdk.symbols: > * gdk/gdkwindow.[ch] > (gdk_window_freeze_toplevel_updates_libgtk_only), > (gdk_window_thaw_toplevel_updates_libgtk_only): new functions > to freeze a toplevel window and all its descendants. To be made > public in 2.14, > (gdk_window_schedule_update): return if toplevel is frozen, > (gdk_window_process_all_updates): defer processing updates if toplevel > is frozen. > > * gtk/gtkwindow.c (gtk_window_configure_event): directly size > allocate for override redirect windows, freeze toplevel and > descendants otherwise and wait until resizing is done.
(In reply to comment #0)a blank screen problem. One of the applications is > gcin, which is a input-method program. When a blank screen Oops. s/screen/window
Created attachment 129623 [details] newer and simpler testcase
I think it is a gtk_window_resize() specific bug. Please download new testcase: [4] * blank.c is original testcase provided by reporter * noresize.c is blank.c without gtk_window_resize() [5] * timeout.c is a very simple testcase to show how gtk_window_resize() is buggy 1. "make" and run "./noresize", you will see that everything is normal (but no gtk_window_resize, of course.) 2. "make" and run "./timeout", and try to increase X11 loading When X11 loading is low: "./timeout" will will show "__________" and "IIIIIIIIII" repeatedly. ( "__________" -> "IIIIIIIIII" -> "__________" -> "IIIIIIIIII" -> ...) When X11 loading is not low (Just a little higher and you can see the bug): "./timeout" will only show "__________" or "IIIIIIIIII" (only "__________", or only "IIIIIIIIII" ) You can edit #define TIMEOUT in timeout.c and rebuild it. No matter how TIMEOUT is large, you still can see the bug when X11 loading increase. I can reproduce the bug even when TIMEOUT is 2000. [4] attachment id 129623 of this bug [5] ~$ diff -Nur noresize.c blank.c --- noresize.c 2009-02-27 10:18:39.000000000 +0800 +++ blank.c 2009-02-27 10:18:39.000000000 +0800 @@ -47,6 +47,7 @@ #endif int txt = rand() % textN; gtk_label_set_markup(GTK_LABEL(lab), text[txt]); + gtk_window_resize(GTK_WINDOW(mainwin), 32, 12); }
To clarify the problem: The bug only can be seen when: 1. X11 loading is not low 2. gtk_window_resize() is used Window size is correctly changed by gtk_window_resize(). But the window content is blank or "part of other window" when X11 loading is not low.
Created attachment 129708 [details] use LD_PRELOAD to avoid the bug
Now you can avoid the bug via a very simple .so wapper without rebuild GTK+. 1. Download and build thaw.so [6] 2. export LD_PRELOAD=/PATH/TO/YOUR/thaw/thaw.so 3. execute whatever testcase or GTK+ applications you want There are only 3 lines of source code of thaw.so: #include <gdk/gdk.h> void gdk_window_freeze_toplevel_updates_libgtk_only(GdkWindow *window){} void gdk_window_thaw_toplevel_updates_libgtk_only(GdkWindow *window){} [6] attachment id 129708
If you have time to reproduce, is this still a problem in gtk+ 3.2?
We're moving to gitlab! As part of this move, we are closing bugs that haven't seen activity in more than 5 years. If this issue is still imporant to you and still relevant with GTK+ 3.22 or master, please consider creating a gitlab issue for it.