Hello all,

I've found out a few important things with regard to threaded
background pyglet windows, and in particular, issues that may relate
to pyglet 1.1a2 vs 1.0.

(1) It appears that for pyglet 1.0 (at least on Windows and OS X),
pyglet windows need to be created local to the thread from which they
will be handled. On Windows, failure to do so will produce an
exception (a ContextError), while on OS X, the GUI thread (visible in
the dock) will just freeze.

(2) Moreover, it seems that for pyglet 1.1a2, ANY import statements
for pyglet ('import pyglet.window', or even 'import pyglet') must be
done in the context of the thread which will be handling the windows.
I had initially thought that the issue was that when pyglet.window is
imported (under version 1.1a2), a "shadow window" is created,
producing a default context that will be shared with the contexts of
further windows unless otherwise specified. But something bad happens
even when pyglet is imported, despite the lazy-loading stuff, so I
really have no idea what's going on!

In Windows, it is possible to import pyglet from one thread and then
construct a new context for a new window in a separate thread, and
successfully run that window. (However, when the window is closed, an
glException for an "invalid operation" appears as the thread exits.)
On OS X, even after creating a new context, I can't run a window in a
thread separate from the thread in which pyglet was first imported.
Using pyglet 1.0, there's no issue with what thread pyglet or
pyglet.window was first imported in.

I don't know if this is properly a "bug" in pyglet 1.1a2, but it
certainly is an oddity in how it operates and a definite gotcha.

(3) The fact that importing pyglet.window creates a "shadow window" is
a bit annoying on OS X, because when that is created, a dock icon
appears and just bounces perpetually, until a real window is started
and events are handled. With 1.0, the dock icon only appears when a
pyglet.window.Window() is created. This means that apps with more set-
up time between importing pyglet.window and actually drawing windows
will have a long-bouncing, unresponsive dock icon.

So, to do threading safely with pyglet 1.1a2, it seems that EVERY call
to pyglet, including imports (!) must be done from within the "pyglet"
thread.
Moreover, despite the lazy-loading, it appears that even an 'import
pyglet' call causes problems, much less 'import pyglet.window'! So all
imports must be done only within the relevant thread, at least with
how 1.1a2 is organized. (Again, not the case with 1.0) I think that
this is a bit of a problem, but I have no idea what the underlying
issues are, or if it's possible to fix them.

Here is some minimal code that works with both pyglet 1.0 and 1.1 to
run a window in the background:

import threading
def event_loop():
  import pyglet.window
  w = pyglet.window.Window(resizable=True)
  while not w.has_exit:
    w.dispatch_events()
  w.close()

t = threading.Thread(target=event_loop)
t.start()


The following works on Windows, but not OS X:

import threading, pyglet.window
def event_loop():
  import pyglet.window
  platform = pyglet.window.get_platform()
  display = platform.get_default_display()
  screen = display.get_default_screen()
  template = pyglet.gl.Config(alpha_size=8)
  config = screen.get_best_config(template)
  context = config.create_context(None)
  w = pyglet.window.Window(context=context, resizable=True)
  while not w.has_exit:
    w.dispatch_events()
  w.close()

t = threading.Thread(target=event_loop)
t.start()


Note that of course, replacing the hand-rolled event loop with
pyglet.app.run() works (or doesn't work) in the same ways that the
above code works or fails. I just wrote the loop explicitly to make
the "test case" smaller. Probably the best minimal threading example
for 1.1a2 is:

import threading
def event_loop():
  import pyglet
  w = pyglet.window.Window(resizable=True)
  pyglet.app.run()

t = threading.Thread(target=event_loop)
t.start()

I'd be happy to learn more about what's going on with the pyglet
import process that causes all of these problems -- especially how
importing pyglet, which does little more than bootstrap some lazy-
loading code, could possibly break windowing in other threads...

Zach
--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups 
"pyglet-users" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/pyglet-users?hl=en
-~----------~----~----~----~------~----~------~--~---

Reply via email to