Hi Jeremy,

Thanks for the detailed pointers about wxWidgets, GUIs, and multi-threading.  My use is actually very simple.  The only reason I wanted multiple (sequential, not concurrent) invocations of 'start' is for convenience of use in ghci.

I recently switched from wxWidgets 2.4.2 to 2.6.3, and I remember that this problem was worked around in 2.4.2 for use with ghci.  Is there really no way to fix the situation with 2.6.3?

Do wxWidgets-2.4.2, wxHaskell-0.10.1 and ghc-6.6 get along together, including unicode issues? 

Does anyone use ghci with wxHaskell-0.10.1 and ghc-6.6?

  - Conal


On 12/7/06, Jeremy O'Donoghue <jeremy.odonoghue@gmail.com> wrote:
Hi Conal,

On 07/12/06, Conal Elliott <conal@conal.net> wrote:
> I submitted this bug report at the sourceforge project.  Is this a known
> problem?  Any work-arounds?
>
> > Running two 'start'ed actions kills the process under ghc and ghci.
> Example:
> >
> > import Graphics.UI.WX
> > main = io >> io where io = start (frame [] >> return ())

I'm not sure whether anyone has tried this before, but I would fully
expect it not to work for several reasons:

* I'm pretty sure that wxHaskell only expects to see a single instance
of a wxWidgets wxApp (which is what start boils down to creating,
among other things).

* In fact, I think the whole point about wxApp is that it encapsulates
a process with an event loop for handling GUI events, so the
limitation is probably with wxWidgets itself (as it happens, I'm
sceptical that what you are trying would work on any common GUI
framework, for much the same reason)

Work-around will depend on what you are trying to do.

You can certainly have multiple top level frames, but they will share
the same event loop. This is, by some margin, the easiest approach.

If you genuinely want two communicating processes, you most likely
need to create two separate executables - let's call them A and B. As
part of start-up of A, it spawns B as a forked process, and A abd B
communicate via pipes, IP sockets or some other appropriate mechanism.

Another wrinkle to watch out for (again, common to most GUIs) is that
only one thread should perform all event handling (in practice, this
usually ends up being simplest by running all GUI activities in a
single thread). Windows is expecially strict about this - X is
slightly more permissive, but you are much better off following the
'one GUI thread' rule.

Assuming that you have a multi-threaded application, typical design is
for GUI to signal other 'worker' threads (which signal back). Again,
details are likely to be very application dependent.

One  final, somewhat unrelated issue: if you are planning to use
wxWidgets with GHCi, it is worth knowing that you can actually only
issue one start command in a given GHCi session. This is an underlying
wxWidgets issue (use of static destructors in C++ code, I believe)
which means that wxWidgets can only be restarted by unloading and
reloading the wxWidgets DLL. Since GHCi isn't capable of doing this,
you basically need to quit and restart a new session.

There *is* a workaround for this: use wxWidgets 2.4.2 or earlier,
which have a different allocation/deallocation strategy. This is why
we continue to support wxWidgets 2.4.2.

Regards
Jeremy