After an evaluation, GNOME has moved from Bugzilla to GitLab. Learn more about GitLab.
No new issues can be reported in GNOME Bugzilla anymore.
To report an issue in a GNOME project, go to GNOME GitLab.
Do not go to GNOME Gitlab for: Bluefish, Doxygen, GnuCash, GStreamer, java-gnome, LDTP, NetworkManager, Tomboy.
Bug 552041 - Windows' System Menu from taskbar is buggy
Windows' System Menu from taskbar is buggy
Status: RESOLVED FIXED
Product: gtk+
Classification: Platform
Component: Backend: Win32
2.14.x
Other All
: Normal minor
: ---
Assigned To: gtk-win32 maintainers
gtk-bugs
: 635065 (view as bug list)
Depends on:
Blocks:
 
 
Reported: 2008-09-12 21:57 UTC by Zac Luzader
Modified: 2011-11-08 19:07 UTC
See Also:
GNOME target: ---
GNOME version: ---


Attachments
script.txt (79 bytes, text/plain)
2010-08-18 11:32 UTC, Dieter Verfaillie
Details
test.c (432 bytes, application/octet-stream)
2010-08-18 11:32 UTC, Dieter Verfaillie
Details
output.txt (8.34 KB, text/plain)
2010-08-18 11:33 UTC, Dieter Verfaillie
Details
fix_gdk_gsource.patch (1.32 KB, application/octet-stream)
2010-08-18 11:34 UTC, Dieter Verfaillie
Details

Description Zac Luzader 2008-09-12 21:57:12 UTC
Please describe the problem:
Right clicking a GTK window's entry in the Windows Taskbar to bring up the System Menu causes a similar bug to 539164, and is almost assuredly related. Any drawing in the window freezes, but unlinke 539164, the following warnings also appear in the console:

(gtk-demo.exe:3708): GLib-WARNING **: g_main_context_prepare() called recursivel
y from within a source's check() or prepare() member.

(gtk-demo.exe:3708): GLib-WARNING **: g_main_context_check() called recursively
from within a source's check() or prepare() member.

These pair of warnings print repeatedly while the menu is up. This is not a crasher, the application behaves normally once the menu is dismissed, same as 539164.

Steps to reproduce:
1. Run gtk-demo.exe
2. Open the pixbufs demo. (Or the Images demo, the behavior is the same.)
3. Right click "Pixbufs" in the taskbar.


Actual results:
Animation freezes and GLib-WARNINGS print to the console.

Expected results:
The animation should continue and no warnings should appear. Bobviously.

Does this happen every time?
Yes.

Other information:
I don't mean to seem ungrateful by filing a bug about the same thing as 539164. But this is a little corner case that got through. I'll get a dev environment on this stupid windows box one of these days!
Comment 1 Tor Lillqvist 2008-09-13 19:52:25 UTC
Eek! Nice catch. Note that if one just right-clicks on the taskbar entry of gtk-demo in its initial state with no demo running one also gets warnings as long as the right-click menu is up.
Comment 2 Serge Potapov 2008-10-19 12:28:50 UTC
I found this bug in:

gtk+-bundle_2.14.4-20081018_win32.zip
gtk+-bundle_2.14.3-20081017_win32.zip
gtk+-bundle_2.14.2-20080924_win32.zip

It's in gtk-demo.
It's in empty (and any) window I run from Gtk2::Perl.

It's probably in any win32 window with gtk_main() created
without special jumps around.
Comment 3 Zac Luzader 2009-03-22 07:14:44 UTC
No longer seeing this after upgrade to 2.16.0.
Comment 4 Tor Lillqvist 2009-03-22 08:24:50 UTC
I do see the same problem with 2.16.0, trying exactly what the initial description says.
Comment 5 Zac Luzader 2009-03-22 20:55:34 UTC
(In reply to comment #4)
> I do see the same problem with 2.16.0, trying exactly what the initial
> description says.
> 
I am terribly embarrassed to say that I tried to reproduce by right clicking the titlebar, forgetting that the bug is triggered by the taskbar instead. Sorry for the noise and wasted time. (In the future I will read my own reports.)

Comment 6 Steven T. Snyder 2010-04-06 23:50:37 UTC
I also see this problem when I right-click the taskbar in my pygtk application.
I'm using pygtk-2.16.0 with the gtk2 2.16.6 runtime files.

I get the following warnings:
C:\myui.py:183: Warning: g_main_context_prepare() called recursively from within a source's check() or prepare() member.
C:\myui.py:183: Warning: g_main_context_check() called recursively from within a source's check() or prepare() member.

Line 183 is my call to gtk.main().

The program locks up while the right-click menu is open.
Comment 7 Allan 2010-05-03 07:01:25 UTC
I also see this problem,platform is windows XP:

(gtk-demo.exe:6584): GLib-WARNING **: g_main_context_prepare() called recursively from within a source's check() or prepare() member.

(gtk-demo.exe:6584): GLib-WARNING **: g_main_context_check() called recursively from within a source's check() or prepare() member.

(gtk-demo.exe:6584): GLib-WARNING **: g_main_context_prepare() called recursively from within a source's check() or prepare() member.

(gtk-demo.exe:6584): GLib-WARNING **: g_main_context_check() called recursively from within a source's check() or prepare() member.


Is this gonna be fixed?
Comment 8 Tor Lillqvist 2010-05-03 08:01:57 UTC
Allan, what vesion of GTK+ are you using?
Comment 9 Allan 2010-05-03 08:07:39 UTC
(In reply to comment #8)
> Allan, what vesion of GTK+ are you using?

It's the latest version:

http://ftp.gnome.org/pub/GNOME/binaries/win32/gtk+/2.20/gtk+-bundle_2.20.0-20100406_win32.zip

It seems this problem doesn't exist for some windows XP users,but unfortunately it does exist for me :(
Comment 10 Steven T. Snyder 2010-05-20 18:28:24 UTC
Has anyone managed to find a workaround for this that can be implemented in the program source code?
Comment 11 Dieter Verfaillie 2010-08-18 11:31:36 UTC
I've been tracing this with a simple test program[1], using
gtk+-bundle_2.20.0-20100406_win32, a recompiled
gtk+-2.20.0 and glib-2.24.0 with debug symbols and eventually
found a way to "see" where this warning is produced... Every time
modal_timer_proc gets executed when right-clicking the taskbar
entry resulted in the flood of warnings.

I've run test.exe through gdb with the attached script.txt as follows:
G_DEBUG="fatal_warnings" GDK_DEBUG=EVENTS gdb --command script.txt test.exe.
The moment the task bar entry appears, I've right-clicked it.
On my XP machine the 26th time g_main_context_prepare gets
executed results in a warning (not always, but reliably enough to hit
the right spot in a couple of tries...)

Stepping through the 25th hit revealed the problem: the PeekMessageW call
in gdk_event_prepare seems to release control! See output.txt:181.

As the PeekMessageW function gets called with the PM_NOREMOVE
parameter, it's only goal is to see if there are messages on the message
queue, so we can replace this call with GetQueueStatus (QS_ALLINPUT)[2].

I've done this for all 3 calls to PeekMessageW that get called with
PM_NOREMOVE (in gdk_events_pending, gdk_event_prepare and gdk_event_check)
and the warnings are gone. Eureka!

After that I've tested "Pixbufs" from gtk-demo to verify modal_timer_proc
still functions (the animation continues even when right-clicking the title bar
or the task bar entry for both the “GTK+ Code Demos” and the “Pixbufs”
windows without producing warnings. I've tested with other "in house"
PyGTK applications and have not yet encountered any other problems
caused by this patch.

Note I'm far from an expert on the glib mainloop nor gdk-win32, so
did I get it right?

[1] attached test.c, compile with gcc -Wall -ggdb test.c -o test `pkg-config --cflags gtk+-2.0` `pkg-config --libs gtk+-2.0`
[2] http://msdn.microsoft.com/en-us/library/ms644940%28v=VS.85%29.aspx
Comment 12 Dieter Verfaillie 2010-08-18 11:32:16 UTC
Created attachment 168191 [details]
script.txt
Comment 13 Dieter Verfaillie 2010-08-18 11:32:35 UTC
Created attachment 168192 [details]
test.c
Comment 14 Dieter Verfaillie 2010-08-18 11:33:11 UTC
Created attachment 168193 [details]
output.txt
Comment 15 Dieter Verfaillie 2010-08-18 11:34:02 UTC
Created attachment 168194 [details]
fix_gdk_gsource.patch
Comment 16 Steven T. Snyder 2011-05-12 17:10:59 UTC
Was the patch committed? I'm not experiencing the problem anymore with Gtk 2.22 (32-bit) running on Windows 7 Professional 64-bit.
Comment 17 Dieter Verfaillie 2011-05-12 18:28:28 UTC
I don't think anybody ever looked at the patch... A shame, really, it took three weeks of free time to hunt this down :( For the record, the problem continues to exist in gtk+ 2.22 and 2.24 (on windows xp, at least)...
Comment 18 Dieter Verfaillie 2011-06-10 08:14:13 UTC
*** Bug 635065 has been marked as a duplicate of this bug. ***
Comment 19 Dieter Verfaillie 2011-07-20 09:48:47 UTC
This would likely also fix GLib bug #137968 and what looks
like it's duplicate #468910...
Comment 20 Hans Breuer 2011-07-20 18:41:00 UTC
I've now applied your patch to my local build of gtk-2-16 and it seems to work.
But the only explaination I have is the one given by Tor in bug #137968:

"""The 
PeekMessage() calls apparently can cause calls to the window procedure. The 
calls to PeekMessage(PM_NOREMOVE) in gmain.c and gdkevents-win32.c probabnly 
should be changed to GetQueueStatus(QS_ALLINPUT) calls instead. as that does 
less unexpected stuff."""

That looks reasonable and from my current understanding there also should be no problem by "(GetQueueStatus) does not guarantee that a subsequent call to the GetMessage or PeekMessage function will return a message" [1] but I'm a bit uncertain about that.

[1] http://msdn.microsoft.com/en-us/library/ms644940%28v=vs.85%29.aspx
Comment 21 Dieter Verfaillie 2011-07-25 10:13:12 UTC
(In reply to comment #20)
> I've now applied your patch to my local build of gtk-2-16 and it seems to work.
> But the only explaination I have is the one given by Tor in bug #137968:
> 
> """The 
> PeekMessage() calls apparently can cause calls to the window procedure. The 
> calls to PeekMessage(PM_NOREMOVE) in gmain.c and gdkevents-win32.c probabnly 
> should be changed to GetQueueStatus(QS_ALLINPUT) calls instead. as that does 
> less unexpected stuff."""

Yeah, there are more remarks like that to be found on the web but actual
real documentation on some of the quirks of PeekMessage seems to be hard
to come by these days. My best guess is that we are seeing a ghost of
the old 16-bit Windows' cooperative multitasking days, where PeekMessage,
GetMessage and Yield released control to allow another application to
run (and who knows what else lies hidden within these functions).
I'm also distinctly remember once reading a page mentioning any code
calling PeekMessage should be prepared to be reentrant safe. Alas my
bookmarks are failing me here.

> That looks reasonable and from my current understanding there also should be no
> problem by "(GetQueueStatus) does not guarantee that a subsequent call to the
> GetMessage or PeekMessage function will return a message" [1] but I'm a bit
> uncertain about that.
> 
> [1] http://msdn.microsoft.com/en-us/library/ms644940%28v=vs.85%29.aspx

Worst case scenario gdk_events_pending, gdk_event_prepare or gdk_event_check
will say there's something to do. Then when gdk_event_dispatch is called
there's nothing to be done. gdk_event_dispatch already checks for
that case so nothing actually happens.

I don't think that should be a problem, but that's also from my current
understanding of gdk internals...

Thanks for your review,
Dieter
Comment 22 Alexander Larsson 2011-10-21 09:30:27 UTC
Ok, I've researched this, and this patch looks very correct.

Messages in win32 are either "posted" or "sent". Posted messages are queued on the message queue for the thread, and are then eventually returned by GetMessage or PeekMessage. However, "sent" messages are delivered directly to the window procedure, meaning that if the SendMessage call is in the same thread as the window it will be a direct function call, and if not the message will be queued on the destination thread and will be dispatched immediately to the window procedure the first thing when GetMessage *or* PeekMessage is called (no filtering possible).

Here are some relevant links:

http://stackoverflow.com/questions/1133507/is-there-a-function-like-peekmessage-that-doesnt-process-messages

http://books.google.com/books?id=wYrCitbs5PQC&pg=PT342&lpg=PT342&dq=PeekMessage+nonqueued+messages&source=bl&ots=VpbOhZHZiC&sig=MccIqAUpy_PlnJ6u1L7fFwWepV0&hl=en&ei=hzShTv7TGYP6sgavo_GwBw&sa=X&oi=book_result&ct=result&resnum=3&ved=0CCoQ6AEwAg#v=onepage&q=PeekMessage%20nonqueued%20messages&f=false

PeekMessage API func says:
http://msdn.microsoft.com/en-us/library/windows/desktop/ms644943%28v=vs.85%29.aspx
 During this call, the system delivers pending, nonqueued messages, that is, 
 messages sent to windows owned by the calling thread using the SendMessage, 
 SendMessageCallback, SendMessageTimeout, or SendNotifyMessage function. Then 
 the first queued message that matches the specified filter is retrieved. The 
 system may also process internal events.

http://msdn.microsoft.com/en-us/library/windows/desktop/ms644927%28v=vs.85%29.aspx
Has this part:
 Note that the receiving thread need not yield control explicitly; calling any 
 of the following functions can cause a thread to yield control implicitly.
    DialogBox
    DialogBoxIndirect
    DialogBoxIndirectParam
    DialogBoxParam
    GetMessage
    MessageBox
    PeekMessage
    SendMessage

I'm pulling this patch into my gtk-2-24-win32 branch which I hope to merge soon.
Comment 23 Alexander Larsson 2011-10-21 09:32:24 UTC
Oh, and GetQueueStatus possibly returning early seems safe to me, as look as it doesn't keep doing that after we've called GetMessage, because that might be an infinite loop. I don't think that will happen though.
Comment 24 Dieter Verfaillie 2011-11-08 19:07:48 UTC
http://git.gnome.org/browse/gtk+/commit/?h=gtk-2-24&id=12507a7cc2dcbc4f4c85acaafda8596de9364048

This problem has been fixed in our software repository. The fix will go into the next software release. Thank you for your bug report.