Open GoogleCodeExporter opened 9 years ago
I say 'any pyglet application', but just in case, here's a minimal repro script
I was
using to investigate it. The key handlers are not required to reproduce, I was
just
adding them to investigate precisely when the hang seems to occur.
Best regards,
Jonathan
import random
from pyglet import app, clock
from pyglet.event import EVENT_HANDLED
from pyglet.window import Window
win = None
def on_draw():
print 'draw', random.randint(0, 10)
win.clear()
def update(_):
print 'update', random.randint(0, 10)
def on_key_press(symbol, modifiers):
print 'key press', symbol, modifiers
def on_key_release(symbol, modifiers):
print 'key release', symbol, modifiers
return EVENT_HANDLED
win = Window(fullscreen=False)
win.on_draw = on_draw
win.on_key_press = on_key_press
win.on_key_release = on_key_release
clock.schedule(update)
app.run()
Original comment by tart...@gmail.com
on 12 Jan 2010 at 1:15
I can't reproduce it on Linux using your script.
Original comment by useboxnet
on 17 Jul 2013 at 5:05
This is definitely an issue only on Windows. Sorry if this wasn't clear.
The beep you get is the same one that Windows produces when it intercepts a
keypress without handing it to the application (e,g, for a window layout
operation like maximise or using pull-down menus) but then realises that the
keypress is invalid for some reason. I imagine Windows has suspended the
application while it thinks it's handing some pull-down menu operation, even
though the app has no pull-downs defined.
Original comment by tart...@gmail.com
on 18 Jul 2013 at 7:15
Also: At the time I reported this, I was running windows XP. I'll try it again
on Windows 7 and report back...
Original comment by tart...@gmail.com
on 18 Jul 2013 at 7:16
Original comment by Adam.JT...@gmail.com
on 19 Jul 2013 at 11:31
Original comment by useboxnet
on 21 Sep 2013 at 10:37
I have this issue as well on my Windows 8.1 system. I am sure this will affect
all windows users. As predicted by "tart", this seems to be related to the
lack of a window menu. I have made a small patch and was able to fix this
problem. This patch removes the window menu for the the default window style.
Original comment by Leif.The...@gmail.com
on 20 Dec 2014 at 10:07
Attachments:
Turns out earlier my patch removes the close button in the window decoration.
I didn't catch that right away since my window manager removes window
decoration. I've revised my patch now. On closer examination, this issue was
related to an unreported bug where events would be handled incorrectly. It has
been resolved by implementing a check for the ALT key, fixing the bug, along
with verifying that all event handlers conform. I've outlined the changes and
rationale below.
http://msdn.microsoft.com/en-us/library/windows/desktop/ms633572%28v=vs.85%29.as
px
According to windows api, the application should return 0 if the app handles
the event, and should call user32.DefWindowProcW(hwnd, msg, wParam, lParam) to
provide default processing for any window messages that an application does not
process. In order to prevent the pyglet app from hanging when the ALT key is
pressed, we must provide a handler for WM_SYSCOMMAND and to check for the key
then return 0 so that windows does not attempt to open the window menu bar and
hang.
https://code.google.com/p/pyglet/source/browse/pyglet/window/win32/__init__.py#6
09
Event handlers should be able to return a value, and if that value is 0, pass
it on to the Window Procedure to halt processing of the event. Non-zero values
are also valid, but have a different meaning depending on the context of the
message. For the purposes of this issue, that is not important. It seems that
the intended behaviour of the event handlers is to allow the individual
functions to return 0 to stop processing, and some other value to let Windows
continue to process it by calling user32.DefWindowProcW.
However, the implementation of the event handler handlers (formally "_wnd_proc"
and "_wnd_proc_view") in pyglet/window/win32/__init__.py never allows event
processing to stop because user32.DefWindowProcW (which passes the message back
to Windows) will always be called. The ambiguity lies in the check on line 618:
https://code.google.com/p/pyglet/source/browse/pyglet/window/win32/__init__.py#6
18
None and 0 will both be evaluated as False effectively, removing the
distinction between None and 0. This causes the event to always be processed
by the event handler, and Windows, which often isn't what we want to happen. I
have modified the method so that behaviour is unambiguous:
return None => let windows process the event (call user32.DefWindowProcW)
return all other values => returned to the Window Procedure
Thus, you may create a event handler and omit the return value, which would
cause the event to continue on being processed, or you may return any other
value, which then would be passed the the Window Procedure. I've also noted
the duplicated code in _wnd_proc and _wnd_proc_view and combined them into a
closure suitable for generating event handler handlers.
https://code.google.com/p/pyglet/source/browse/pyglet/window/win32/__init__.py#6
18
This line checks for the WM_CLOSE message. I went through the windows API
docs, but was unable to find why pyglet needs to treat WM_CLOSE messages
differently than normal messages. As is, our handler returns 0, which would
let make Windows ignore it. As a result, I have also removed the check for the
WM_CLOSE message.
There were other event handlers that were implemented sub-optimally, and I have
changed them to reflect the changes made to the event handler handlers
(formally "_wnd_proc" and "_wnd_proc_view").
In closing, I tried to keep changes to a minimum and have tested the changes
and deemed them passing using pyglet's test suite. In the future, if though to
be necessary, checks could be made to restrict values passed to the Window
Procedure to just 0.
Original comment by Leif.The...@gmail.com
on 24 Dec 2014 at 8:02
Attachments:
Original issue reported on code.google.com by
tart...@gmail.com
on 12 Jan 2010 at 1:10