FX::TnFXApp Class Reference

#include <TnFXApp.h>

Inheritance diagram for FX::TnFXApp:

FX::QMutex FX::FXApp FX::FXLockable FX::FXObject List of all members.

Detailed Description

The main TnFOX application object.

In your TnFOX applications you should create a TnFXApp instead of a FX::FXApp to enable the per-thread event loops enhancement TnFOX provides. This permits you to run multiple widget trees across multiple threads concurrently.

In such an environment, appropriate use of FX::FXEventLoop_Static and FX::FXLockHold of the application object is important. The latter only really arises where you use the FX::FXRegistry as returned by reg() as everything else in FXApp can be read and set in a threadsafe fashion (they are pointers only and furthermore rarely change after initialisation).

As the event loop management methods in FXApp now automatically vector through the return from getEventLoop(), you can literally copy & paste your code into its new thread and everything works just fine. create(), destroy() and detach() do the needful depending on what thread calls them. exit() shuts down all event loops and causes the primary loop to exit. It should be a transparent move.

Furthermore as event loops are created on demand automatically, you can litter opens of FX::FXMessageBox or FX::FXExceptionDialog around the place and they shall run in the thread which creates them.

Usage:

For portable behaviour, you must change your main() function slightly. The form goes from:

int main(int argc, char *argv[])
{
   FXProcess myprocess(argc, argv);
   FXApp myapp("MyApp");
   myapp.init(argc, argv);
   FXMainWindow *mainwnd=new FXMainWindow(&myapp, "My Main Window");
   <widgets inside mainwnd>
   ...
   myapp.create()
   return myapp.run();
}
to:
class MyPrimaryLoop : public TnFXAppEventLoop
{
   FXMainWindow *mainwnd;
   <widgets inside mainwnd>
public:
   MyPrimaryLoop(TnFXApp *app) : TnFXAppEventLoop(app) { }
   FXint execute(FXApp *app)
   {
      mainwnd=new FXMainWindow(app, "My Main Window");
      <widgets inside mainwnd>
      ...
      mainwnd->show();
      app->create();
      return app->run();
   }
   // May want to override cleanup() here
};

int main(int argc, char *argv[])
{
   FXProcess myprocess(argc, argv);
   TnFXApp myapp("MyApp");
   myapp.init(argc, argv);
   MyPrimaryLoop primaryLoop(&myapp);
   return myapp.run(primaryLoop);
}
The reason for this is that on X11 per-thread event queues must be emulated and to prevent all threads deadlocking when the primary thread is busy, you must execute the application's core code separately.

Warning:
Neither TnFXApp nor any event loops it returns are threadsafe apart from the postAsyncMessage() function. Do NOT use an event loop not belonging to your thread and if you use TnFXApp::reg(), lock TnFXApp first.

Signals:

Signals are a real hash with POSIX threads. Each thread maintains a signal mask which determines which signals it can received but signal handlers are on a per-thread basis. Thus the FOX signal intercept can be called in any thread but it should post an asynchronous message invoking the handler in the correct event loop.

Implementation:

You should probably know something about the implementation so you can correctly diagnose and avoid any issues which may arise. On Windows the implementation is extremely simple as Windows already provides per-thread event queues whereby messages are posted to the thread which created the window. This makes implementation on that platform trivial.

On X11 it gets more complicated as there's one event queue only. Therefore the primary thread must fetch X11 events, determine which event loop they belong to and post them to that loop for handling. Obviously to prevent deadlock the primary dispatch thread must always be available. Also because of the event loops in each thread being totally different implementations, internally TnFXApp subclasses FX::FXEventLoop twice - one for the the main X11 dispatch loop and the other for all other threads. You can always retrieve the event loop which quits the application using FXEventLoop::primaryLoop().

Watches on file descriptors are not performed the same way on Windows and X11. On Windows, the event loop local list is monitored as it monitors the thread message queue so all is well. On X11 it's much more complex as POSIX won't let you wait on a wait condition and kernel handles simultaneously, so the primary loop coalesces all the file descriptors and posts asynchronous messages when they signal.

Note:
File descriptor watching on POSIX is not implemented currently. It wouldn't be hard to add, but I personally have no use for it and I view it as a pure legacy feature.

Definition at line 149 of file TnFXApp.h.

Public Types

 ID_QUIT
 ID_DUMP
 ID_HOVER
 ID_LAST
enum  { ID_QUIT, ID_DUMP, ID_HOVER, ID_LAST }

Public Member Functions

 TnFXApp (const FXString &name="Application", const FXString &vendor="FoxDefault")
 ~TnFXApp ()
virtual FXEventLoopgetEventLoop () const
long onCmdQuit (FXObject *, FXSelector, void *)
virtual void create ()
virtual void destroy ()
virtual void detach ()
virtual void init (int &argc, char **argv, bool connect=TRUE)
virtual void exit (FXint code=0)
virtual void lock ()
virtual void unlock ()
FXint run (TnFXAppEventLoop &primaryLoop)
QMUTEX_INLINEP bool isLocked () const
QMUTEX_INLINEP FXbool locked () const
QMUTEX_INLINEP FXuint spinCount () const
QMUTEX_INLINEP void setSpinCount (FXuint c)
QMUTEX_INLINEP bool tryLock ()
QMUTEX_INLINEP FXbool trylock ()
long onCmdDump (FXObject *, FXSelector, void *)
long onCmdHover (FXObject *, FXSelector, void *)
const FXStringgetAppName () const
const FXStringgetVendorName () const
bool openDisplay (const FXchar *dpyname=NULL)
bool closeDisplay ()
void * getDisplay () const
bool isInitialized () const
FXint getArgc () const
const FXchar *const * getArgv () const
bool hasInputMethod () const
FXVisualgetDefaultVisual () const
void setDefaultVisual (FXVisual *vis)
FXVisualgetMonoVisual () const
FXRootWindowgetRootWindow () const
void setRootWindow (FXRootWindow *rt)
FXWindowgetFocusWindow () const
FXWindowgetCursorWindow () const
FXWindowgetActiveWindow () const
FXPopupgetPopupWindow () const
FXWindowfindWindowWithId (FXID xid) const
FXWindowfindWindowAt (FXint rx, FXint ry, FXID window=0) const
void addTimeout (FXObject *tgt, FXSelector sel, FXuint ms=1000, void *ptr=NULL)
void removeTimeout (FXObject *tgt, FXSelector sel)
bool hasTimeout (FXObject *tgt, FXSelector sel) const
FXuint remainingTimeout (FXObject *tgt, FXSelector sel) const
void handleTimeouts ()
void addChore (FXObject *tgt, FXSelector sel, void *ptr=NULL)
void removeChore (FXObject *tgt, FXSelector sel)
FXbool hasChore (FXObject *tgt, FXSelector sel) const
void addSignal (FXint sig, FXObject *tgt, FXSelector sel, FXbool immediate=FALSE, FXuint flags=0)
void removeSignal (FXint sig)
bool addInput (FXInputHandle fd, FXuint mode, FXObject *tgt, FXSelector sel)
bool removeInput (FXInputHandle fd, FXuint mode)
bool getKeyState (FXuint keysym) const
bool peekEvent ()
bool runOneEvent (bool blocking=true)
FXint run ()
FXint runUntil (FXuint &condition)
FXint runWhileEvents ()
FXint runModalWhileEvents (FXWindow *window=NULL)
FXint runModal ()
FXint runModalFor (FXWindow *window)
FXint runModalWhileShown (FXWindow *window)
FXint runPopup (FXWindow *window)
FXbool isModal (FXWindow *window) const
FXWindowgetModalWindow () const
FXModality getModality () const
void stop (FXint value=0)
void stopModal (FXWindow *window, FXint value=0)
void stopModal (FXint value=0)
void forceRefresh ()
void refresh ()
void flush (bool sync=false)
void repaint ()
FXRegistryreg ()
FXDragType registerDragType (const FXString &name) const
FXString getDragTypeName (FXDragType type) const
FXWindowgetDragWindow () const
void beep ()
void errorBeep ()
void setNormalFont (FXFont *font)
FXFontgetNormalFont () const
void beginWaitCursor ()
void endWaitCursor ()
void setWaitCursor (FXCursor *cur)
FXCursorgetWaitCursor () const
FXCursorgetDefaultCursor (FXDefaultCursor which) const
void setDefaultCursor (FXDefaultCursor which, FXCursor *cur)
FXbool writeWindow (FXStream &store, FXWindow *window)
FXbool readWindow (FXStream &store, FXWindow *&window, FXWindow *father, FXWindow *owner)
FXuint getTypingSpeed () const
FXuint getClickSpeed () const
FXuint getScrollSpeed () const
FXuint getScrollDelay () const
FXuint getBlinkSpeed () const
FXuint getAnimSpeed () const
FXuint getMenuPause () const
FXuint getTooltipPause () const
FXuint getTooltipTime () const
FXint getDragDelta () const
FXint getWheelLines () const
FXint getScrollBarSize () const
void setTypingSpeed (FXuint speed)
void setClickSpeed (FXuint speed)
void setScrollSpeed (FXuint speed)
void setScrollDelay (FXuint delay)
void setBlinkSpeed (FXuint speed)
void setAnimSpeed (FXuint speed)
void setMenuPause (FXuint pause)
void setTooltipPause (FXuint pause)
void setTooltipTime (FXuint time)
void setDragDelta (FXint delta)
void setWheelLines (FXint lines)
void setScrollBarSize (FXint size)
FXColor getBorderColor () const
FXColor getBaseColor () const
FXColor getHiliteColor () const
FXColor getShadowColor () const
FXColor getBackColor () const
FXColor getForeColor () const
FXColor getSelforeColor () const
FXColor getSelbackColor () const
FXColor getTipforeColor () const
FXColor getTipbackColor () const
FXColor getSelMenuTextColor () const
FXColor getSelMenuBackColor () const
void setBorderColor (FXColor color)
void setBaseColor (FXColor color)
void setHiliteColor (FXColor color)
void setShadowColor (FXColor color)
void setBackColor (FXColor color)
void setForeColor (FXColor color)
void setSelforeColor (FXColor color)
void setSelbackColor (FXColor color)
void setTipforeColor (FXColor color)
void setTipbackColor (FXColor color)
void setSelMenuTextColor (FXColor color)
void setSelMenuBackColor (FXColor color)
FXuint getWindowCount () const
virtual void save (FXStream &store) const
virtual void load (FXStream &store)
void dumpWidgets () const
void addDestructionUpcall (void(*func)(void *), void *data)
void removeDestructionUpcall (void(*func)(void *), void *data)
virtual long onDefault (FXObject *, FXSelector, void *)
const FXchargetClassName () const
bool isMemberOf (const FXMetaClass *metaclass) const
virtual long tryHandle (FXObject *sender, FXSelector sel, void *ptr)
QTransString tr (const char *text, const char *hint=0)
virtual void * getPythonObject () const
virtual void decouplePythonObject () const

Static Public Member Functions

static TnFXAppinstance ()
static QMUTEX_INLINEP bool setMutexDebugYield (bool v)
static FXEventLoopgetPrimaryEventLoop ()
static FXlong time ()

Static Public Attributes

static const FXucharcopyright

Protected Member Functions

virtual bool getNextEvent (FXRawEvent &ev, bool blocking=true)
virtual bool dispatchEvent (FXRawEvent &ev)

Protected Attributes

FXEventLoopeventLoop


The documentation for this class was generated from the following file:
(C) 2002-2009 Niall Douglas. Some parts (C) to assorted authors.
Generated on Fri Nov 20 18:37:47 2009 for TnFOX by doxygen v1.4.7