Implemented wxEventLoop for wxMotif, and used it in wxDialog::ShowModal,
wxWindow::DoPopupMenu and for the application main loop. Implemented wxWakeUpIdle. Fixed crash when a popup menu entry is used to close/destroy the parent window of the menu. git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@19078 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
parent
d894c20113
commit
7e1bcfa80e
@ -584,6 +584,7 @@ dcclient.cpp Motif
|
||||
dcmemory.cpp Motif
|
||||
dcscreen.cpp Motif
|
||||
dialog.cpp Motif
|
||||
evtloop.cpp Motif
|
||||
filedlg.cpp Motif
|
||||
font.cpp Motif
|
||||
frame.cpp Motif
|
||||
|
@ -20,7 +20,6 @@
|
||||
// headers
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
#include "wx/gdicmn.h"
|
||||
#include "wx/event.h"
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
@ -32,6 +31,7 @@ class WXDLLEXPORT wxWindow;
|
||||
class WXDLLEXPORT wxApp;
|
||||
class WXDLLEXPORT wxKeyEvent;
|
||||
class WXDLLEXPORT wxLog;
|
||||
class WXDLLEXPORT wxEventLoop;
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// the wxApp class for Motif - see wxAppBase for more details
|
||||
@ -43,7 +43,7 @@ class WXDLLEXPORT wxApp : public wxAppBase
|
||||
|
||||
public:
|
||||
wxApp();
|
||||
~wxApp() {}
|
||||
virtual ~wxApp();
|
||||
|
||||
// override base class (pure) virtuals
|
||||
// -----------------------------------
|
||||
@ -71,20 +71,6 @@ public:
|
||||
// Returns TRUE if more idle time is requested.
|
||||
bool SendIdleEvents(wxWindow* win);
|
||||
|
||||
// Motif implementation.
|
||||
|
||||
// Processes an X event.
|
||||
virtual void ProcessXEvent(WXEvent* event);
|
||||
|
||||
// Returns TRUE if an accelerator has been processed
|
||||
virtual bool CheckForAccelerator(WXEvent* event);
|
||||
|
||||
// Returns TRUE if a key down event has been processed
|
||||
virtual bool CheckForKeyDown(WXEvent* event);
|
||||
|
||||
// Returns TRUE if a key up event has been processed
|
||||
virtual bool CheckForKeyUp(WXEvent* event);
|
||||
|
||||
protected:
|
||||
bool m_showOnInit;
|
||||
|
||||
@ -105,12 +91,11 @@ public:
|
||||
// This handler is called when a property change event occurs
|
||||
virtual void HandlePropertyChange(WXEvent *event);
|
||||
|
||||
public:
|
||||
private:
|
||||
static long sm_lastMessageTime;
|
||||
int m_nCmdShow;
|
||||
|
||||
protected:
|
||||
bool m_keepGoing;
|
||||
|
||||
wxEventLoop* m_eventLoop;
|
||||
|
||||
// Motif-specific
|
||||
WXAppContext m_appContext;
|
||||
|
@ -18,6 +18,8 @@
|
||||
|
||||
WXDLLEXPORT_DATA(extern const char*) wxDialogNameStr;
|
||||
|
||||
class WXDLLEXPORT wxEventLoop;
|
||||
|
||||
// Dialog boxes
|
||||
class WXDLLEXPORT wxDialog : public wxDialogBase
|
||||
{
|
||||
@ -102,6 +104,7 @@ private:
|
||||
|
||||
//// Motif-specific
|
||||
bool m_modalShowing;
|
||||
wxEventLoop* m_eventLoop;
|
||||
|
||||
protected:
|
||||
virtual void DoSetSize(int x, int y,
|
||||
|
@ -93,7 +93,8 @@ public:
|
||||
WXWidget GetHandle() const { return m_menuWidget; }
|
||||
|
||||
bool IsTearOff() const { return (m_style & wxMENU_TEAROFF) != 0; }
|
||||
|
||||
|
||||
void DestroyWidgetAndDetach();
|
||||
public:
|
||||
// Motif-specific data
|
||||
int m_numColumns;
|
||||
|
@ -25,10 +25,12 @@
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
// All widgets should have this as their resize proc.
|
||||
extern void wxWidgetResizeProc(Widget w, XConfigureEvent *event, String args[], int *num_args);
|
||||
extern void wxWidgetResizeProc(Widget w, XConfigureEvent *event,
|
||||
String args[], int *num_args);
|
||||
|
||||
// For repainting arbitrary windows
|
||||
void wxUniversalRepaintProc(Widget w, XtPointer WXUNUSED(c_data), XEvent *event, char *);
|
||||
void wxUniversalRepaintProc(Widget w, XtPointer WXUNUSED(c_data),
|
||||
XEvent *event, char *);
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// we maintain a hash table which contains the mapping from Widget to wxWindow
|
||||
@ -51,11 +53,17 @@ extern XmString wxFindAcceleratorText (const char *s);
|
||||
// ----------------------------------------------------------------------------
|
||||
// TranslateXXXEvent() functions - translate Motif event to wxWindow one
|
||||
// ----------------------------------------------------------------------------
|
||||
extern bool wxTranslateMouseEvent(wxMouseEvent& wxevent, wxWindow *win, Widget widget, XEvent *xevent);
|
||||
extern bool wxTranslateKeyEvent(wxKeyEvent& wxevent, wxWindow *win, Widget widget, XEvent *xevent);
|
||||
|
||||
extern void wxDoChangeForegroundColour(WXWidget widget, wxColour& foregroundColour);
|
||||
extern void wxDoChangeBackgroundColour(WXWidget widget, wxColour& backgroundColour, bool changeArmColour = FALSE);
|
||||
extern bool wxTranslateMouseEvent(wxMouseEvent& wxevent, wxWindow *win,
|
||||
Widget widget, XEvent *xevent);
|
||||
extern bool wxTranslateKeyEvent(wxKeyEvent& wxevent, wxWindow *win,
|
||||
Widget widget, XEvent *xevent);
|
||||
|
||||
extern void wxDoChangeForegroundColour(WXWidget widget,
|
||||
wxColour& foregroundColour);
|
||||
extern void wxDoChangeBackgroundColour(WXWidget widget,
|
||||
wxColour& backgroundColour,
|
||||
bool changeArmColour = FALSE);
|
||||
|
||||
#define wxNO_COLORS 0x00
|
||||
#define wxBACK_COLORS 0x01
|
||||
@ -78,6 +86,11 @@ extern XColor itemColors[5] ;
|
||||
class wxXmString
|
||||
{
|
||||
public:
|
||||
wxXmString(const char* str)
|
||||
{
|
||||
m_string = XmStringCreateLtoR((char *)str, XmSTRING_DEFAULT_CHARSET);
|
||||
}
|
||||
|
||||
wxXmString(const wxString& str)
|
||||
{
|
||||
m_string = XmStringCreateLtoR((char *)str.c_str(),
|
||||
@ -94,6 +107,15 @@ private:
|
||||
XmString m_string;
|
||||
};
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// executes one main loop iteration (implemented in src/motif/evtloop.cpp)
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
class wxEventLoop;
|
||||
|
||||
// returns true if the loop should be exited
|
||||
bool wxDoEventLoopIteration( wxEventLoop& evtLoop );
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// macros to avoid casting WXFOO to Foo all the time
|
||||
// ----------------------------------------------------------------------------
|
||||
|
@ -35,6 +35,7 @@
|
||||
#include "wx/memory.h"
|
||||
#include "wx/log.h"
|
||||
#include "wx/intl.h"
|
||||
#include "wx/evtloop.h"
|
||||
|
||||
#if wxUSE_THREADS
|
||||
#include "wx/thread.h"
|
||||
@ -61,6 +62,7 @@
|
||||
#include <string.h>
|
||||
|
||||
extern wxList wxPendingDelete;
|
||||
extern bool wxAddIdleCallback();
|
||||
|
||||
wxApp *wxTheApp = NULL;
|
||||
|
||||
@ -267,6 +269,7 @@ wxApp::wxApp()
|
||||
argc = 0;
|
||||
argv = NULL;
|
||||
|
||||
m_eventLoop = new wxEventLoop;
|
||||
m_mainColormap = (WXColormap) NULL;
|
||||
m_appContext = (WXAppContext) NULL;
|
||||
m_topLevelWidget = (WXWidget) NULL;
|
||||
@ -274,6 +277,11 @@ wxApp::wxApp()
|
||||
m_initialDisplay = (WXDisplay*) 0;
|
||||
}
|
||||
|
||||
wxApp::~wxApp()
|
||||
{
|
||||
delete m_eventLoop;
|
||||
}
|
||||
|
||||
bool wxApp::Initialized()
|
||||
{
|
||||
if (GetTopWindow())
|
||||
@ -284,8 +292,6 @@ bool wxApp::Initialized()
|
||||
|
||||
int wxApp::MainLoop()
|
||||
{
|
||||
m_keepGoing = TRUE;
|
||||
|
||||
/*
|
||||
* Sit around forever waiting to process X-events. Property Change
|
||||
* event are handled special, because they have to refer to
|
||||
@ -297,129 +303,23 @@ int wxApp::MainLoop()
|
||||
XDefaultRootWindow(XtDisplay((Widget) wxTheApp->GetTopLevelWidget())),
|
||||
PropertyChangeMask);
|
||||
|
||||
XEvent event;
|
||||
|
||||
// Use this flag to allow breaking the loop via wxApp::ExitMainLoop()
|
||||
while (m_keepGoing)
|
||||
{
|
||||
XtAppNextEvent( (XtAppContext) wxTheApp->GetAppContext(), &event);
|
||||
|
||||
ProcessXEvent((WXEvent*) & event);
|
||||
|
||||
if (XtAppPending( (XtAppContext) wxTheApp->GetAppContext() ) == 0)
|
||||
{
|
||||
if (!ProcessIdle())
|
||||
{
|
||||
#if wxUSE_THREADS
|
||||
// leave the main loop to give other threads a chance to
|
||||
// perform their GUI work
|
||||
wxMutexGuiLeave();
|
||||
wxUsleep(20);
|
||||
wxMutexGuiEnter();
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
m_eventLoop->Run();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Processes an X event.
|
||||
void wxApp::ProcessXEvent(WXEvent* _event)
|
||||
{
|
||||
XEvent* event = (XEvent*) _event;
|
||||
|
||||
if (event->type == KeyPress)
|
||||
{
|
||||
#if 0 // def __WXDEBUG__
|
||||
Widget widget = XtWindowToWidget(event->xany.display, event->xany.window);
|
||||
wxLogDebug("Got key press event for 0x%08x (parent = 0x%08x)",
|
||||
widget, XtParent(widget));
|
||||
#endif // DEBUG
|
||||
|
||||
if (CheckForAccelerator(_event))
|
||||
{
|
||||
// Do nothing! We intercepted and processed the event as an
|
||||
// accelerator.
|
||||
return;
|
||||
}
|
||||
#if 1
|
||||
// It seemed before that this hack was redundant and
|
||||
// key down events were being generated by wxCanvasInputEvent.
|
||||
// But no longer - why ???
|
||||
//
|
||||
else if (CheckForKeyDown(_event))
|
||||
{
|
||||
// We intercepted and processed the key down event
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
else
|
||||
{
|
||||
XtDispatchEvent(event);
|
||||
return;
|
||||
}
|
||||
}
|
||||
else if (event->type == KeyRelease)
|
||||
{
|
||||
// TODO: work out why we still need this ! -michael
|
||||
//
|
||||
if (CheckForKeyUp(_event))
|
||||
{
|
||||
// We intercepted and processed the key up event
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
XtDispatchEvent(event);
|
||||
return;
|
||||
}
|
||||
}
|
||||
else if (event->type == PropertyNotify)
|
||||
{
|
||||
HandlePropertyChange(_event);
|
||||
return;
|
||||
}
|
||||
else if (event->type == ResizeRequest)
|
||||
{
|
||||
/* Terry Gitnick <terryg@scientech.com> - 1/21/98
|
||||
* If resize event, don't resize until the last resize event for this
|
||||
* window is recieved. Prevents flicker as windows are resized.
|
||||
*/
|
||||
|
||||
Display *disp = XtDisplay((Widget) wxTheApp->GetTopLevelWidget());
|
||||
Window win = event->xany.window;
|
||||
XEvent report;
|
||||
|
||||
// to avoid flicker
|
||||
report = * event;
|
||||
while( XCheckTypedWindowEvent (disp, win, ResizeRequest, &report));
|
||||
|
||||
// TODO: when implementing refresh optimization, we can use
|
||||
// XtAddExposureToRegion to expand the window's paint region.
|
||||
|
||||
XtDispatchEvent(event);
|
||||
}
|
||||
else
|
||||
{
|
||||
XtDispatchEvent(event);
|
||||
}
|
||||
}
|
||||
|
||||
// Processes an idle event.
|
||||
// Returns TRUE if more time is needed.
|
||||
bool wxApp::ProcessIdle()
|
||||
{
|
||||
wxIdleEvent event;
|
||||
event.SetEventObject(this);
|
||||
ProcessEvent(event);
|
||||
|
||||
return event.MoreRequested();
|
||||
return ProcessEvent(event) && event.MoreRequested();
|
||||
}
|
||||
|
||||
void wxApp::ExitMainLoop()
|
||||
{
|
||||
m_keepGoing = FALSE;
|
||||
m_eventLoop->Exit();
|
||||
}
|
||||
|
||||
// Is a message/event pending?
|
||||
@ -435,11 +335,7 @@ bool wxApp::Pending()
|
||||
// Dispatch a message.
|
||||
void wxApp::Dispatch()
|
||||
{
|
||||
// XtAppProcessEvent( (XtAppContext) wxTheApp->GetAppContext(), XtIMAll);
|
||||
|
||||
XEvent event;
|
||||
XtAppNextEvent((XtAppContext) GetAppContext(), &event);
|
||||
ProcessXEvent((WXEvent*) & event);
|
||||
m_eventLoop->Dispatch();
|
||||
}
|
||||
|
||||
// This should be redefined in a derived class for
|
||||
@ -489,13 +385,6 @@ void wxApp::OnIdle(wxIdleEvent& event)
|
||||
inOnIdle = FALSE;
|
||||
}
|
||||
|
||||
void wxWakeUpIdle()
|
||||
{
|
||||
// **** please implement me! ****
|
||||
// Wake up the idle handler processor, even if it is in another thread...
|
||||
}
|
||||
|
||||
|
||||
// Send idle event to all top-level windows
|
||||
bool wxApp::SendIdleEvents()
|
||||
{
|
||||
@ -539,7 +428,7 @@ bool wxApp::SendIdleEvents(wxWindow* win)
|
||||
|
||||
void wxApp::DeletePendingObjects()
|
||||
{
|
||||
wxNode *node = wxPendingDelete.GetFirst();
|
||||
wxList::Node *node = wxPendingDelete.GetFirst();
|
||||
while (node)
|
||||
{
|
||||
wxObject *obj = node->GetData();
|
||||
@ -610,6 +499,8 @@ bool wxApp::OnInitGui()
|
||||
GetMainColormap(dpy);
|
||||
m_maxRequestSize = XMaxRequestSize((Display*) dpy);
|
||||
|
||||
wxAddIdleCallback();
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@ -629,91 +520,6 @@ WXColormap wxApp::GetMainColormap(WXDisplay* display)
|
||||
return (WXColormap) c;
|
||||
}
|
||||
|
||||
// Returns TRUE if an accelerator has been processed
|
||||
bool wxApp::CheckForAccelerator(WXEvent* event)
|
||||
{
|
||||
XEvent* xEvent = (XEvent*) event;
|
||||
if (xEvent->xany.type == KeyPress)
|
||||
{
|
||||
// Find a wxWindow for this window
|
||||
// TODO: should get display for the window, not the current display
|
||||
Widget widget = XtWindowToWidget((Display*) wxGetDisplay(), xEvent->xany.window);
|
||||
wxWindow* win = NULL;
|
||||
|
||||
// Find the first wxWindow that corresponds to this event window
|
||||
while (widget && !(win = wxGetWindowFromTable(widget)))
|
||||
widget = XtParent(widget);
|
||||
|
||||
if (!widget || !win)
|
||||
return FALSE;
|
||||
|
||||
wxKeyEvent keyEvent(wxEVT_CHAR);
|
||||
wxTranslateKeyEvent(keyEvent, win, (Widget) 0, xEvent);
|
||||
|
||||
// Now we have a wxKeyEvent and we have a wxWindow.
|
||||
// Go up the hierarchy until we find a matching accelerator,
|
||||
// or we get to the top.
|
||||
while (win)
|
||||
{
|
||||
if (win->ProcessAccelerator(keyEvent))
|
||||
return TRUE;
|
||||
win = win->GetParent();
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
bool wxApp::CheckForKeyDown(WXEvent* event)
|
||||
{
|
||||
XEvent* xEvent = (XEvent*) event;
|
||||
if (xEvent->xany.type == KeyPress)
|
||||
{
|
||||
Widget widget = XtWindowToWidget((Display*) wxGetDisplay(),
|
||||
xEvent->xany.window);
|
||||
wxWindow* win = NULL;
|
||||
|
||||
// Find the first wxWindow that corresponds to this event window
|
||||
while (widget && !(win = wxGetWindowFromTable(widget)))
|
||||
widget = XtParent(widget);
|
||||
|
||||
if (!widget || !win)
|
||||
return FALSE;
|
||||
|
||||
wxKeyEvent keyEvent(wxEVT_KEY_DOWN);
|
||||
wxTranslateKeyEvent(keyEvent, win, (Widget) 0, xEvent);
|
||||
|
||||
return win->ProcessEvent( keyEvent );
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
bool wxApp::CheckForKeyUp(WXEvent* event)
|
||||
{
|
||||
XEvent* xEvent = (XEvent*) event;
|
||||
if (xEvent->xany.type == KeyRelease)
|
||||
{
|
||||
Widget widget = XtWindowToWidget((Display*) wxGetDisplay(),
|
||||
xEvent->xany.window);
|
||||
wxWindow* win = NULL;
|
||||
|
||||
// Find the first wxWindow that corresponds to this event window
|
||||
while (widget && !(win = wxGetWindowFromTable(widget)))
|
||||
widget = XtParent(widget);
|
||||
|
||||
if (!widget || !win)
|
||||
return FALSE;
|
||||
|
||||
wxKeyEvent keyEvent(wxEVT_KEY_UP);
|
||||
wxTranslateKeyEvent(keyEvent, win, (Widget) 0, xEvent);
|
||||
|
||||
return win->ProcessEvent( keyEvent );
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
void wxExit()
|
||||
{
|
||||
int retValue = 0;
|
||||
|
@ -24,6 +24,7 @@
|
||||
#include "wx/utils.h"
|
||||
#include "wx/app.h"
|
||||
#include "wx/settings.h"
|
||||
#include "wx/evtloop.h"
|
||||
|
||||
#ifdef __VMS__
|
||||
#pragma message disable nosimpint
|
||||
@ -56,7 +57,7 @@
|
||||
// A stack of modal_showing flags, since we can't rely
|
||||
// on accessing wxDialog::m_modalShowing within
|
||||
// wxDialog::Show in case a callback has deleted the wxDialog.
|
||||
static wxList wxModalShowingStack;
|
||||
// static wxList wxModalShowingStack;
|
||||
|
||||
// Lists to keep track of windows, so we can disable/enable them
|
||||
// for modal dialogs
|
||||
@ -81,6 +82,7 @@ END_EVENT_TABLE()
|
||||
wxDialog::wxDialog()
|
||||
{
|
||||
m_modalShowing = FALSE;
|
||||
m_eventLoop = NULL;
|
||||
m_backgroundColour = wxSystemSettings::GetColour(wxSYS_COLOUR_3DFACE);
|
||||
}
|
||||
|
||||
@ -98,6 +100,7 @@ bool wxDialog::Create(wxWindow *parent, wxWindowID id,
|
||||
return FALSE;
|
||||
|
||||
m_modalShowing = FALSE;
|
||||
m_eventLoop = NULL;
|
||||
|
||||
m_backgroundColour = wxSystemSettings::GetColour(wxSYS_COLOUR_3DFACE);
|
||||
m_foregroundColour = *wxBLACK;
|
||||
@ -204,6 +207,7 @@ void wxDialog::SetModal(bool flag)
|
||||
wxDialog::~wxDialog()
|
||||
{
|
||||
m_isBeingDeleted = TRUE;
|
||||
delete m_eventLoop;
|
||||
|
||||
if (m_mainWidget)
|
||||
{
|
||||
@ -312,52 +316,24 @@ int wxDialog::ShowModal()
|
||||
|
||||
if (m_modalShowing)
|
||||
return 0;
|
||||
|
||||
wxModalShowingStack.Insert((wxObject *)TRUE);
|
||||
m_eventLoop = new wxEventLoop;
|
||||
|
||||
m_modalShowing = TRUE;
|
||||
XtAddGrab((Widget) m_mainWidget, TRUE, FALSE);
|
||||
|
||||
XEvent event;
|
||||
|
||||
// Loop until we signal that the dialog should be closed
|
||||
while ((wxModalShowingStack.Number() > 0) && ((int)(wxModalShowingStack.First()->Data()) != 0))
|
||||
{
|
||||
// XtAppProcessEvent((XtAppContext) wxTheApp->GetAppContext(), XtIMAll);
|
||||
|
||||
XtAppNextEvent((XtAppContext) wxTheApp->GetAppContext(), &event);
|
||||
wxTheApp->ProcessXEvent((WXEvent*) &event);
|
||||
|
||||
if (XtAppPending( (XtAppContext) wxTheApp->GetAppContext() ) == 0)
|
||||
{
|
||||
if (!wxTheApp->ProcessIdle())
|
||||
{
|
||||
#if wxUSE_THREADS
|
||||
// leave the main loop to give other threads a chance to
|
||||
// perform their GUI work
|
||||
wxMutexGuiLeave();
|
||||
wxUsleep(20);
|
||||
wxMutexGuiEnter();
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Remove modal dialog flag from stack
|
||||
wxNode *node = wxModalShowingStack.First();
|
||||
if (node)
|
||||
delete node;
|
||||
m_eventLoop->Run();
|
||||
|
||||
// Now process all events in case they get sent to a destroyed dialog
|
||||
XSync(XtDisplay((Widget) wxTheApp->GetTopLevelWidget()), FALSE);
|
||||
while (XtAppPending((XtAppContext) wxTheApp->GetAppContext()))
|
||||
while (m_eventLoop->Pending())
|
||||
{
|
||||
XFlush(XtDisplay((Widget) wxTheApp->GetTopLevelWidget()));
|
||||
XtAppNextEvent((XtAppContext) wxTheApp->GetAppContext(), &event);
|
||||
|
||||
wxTheApp->ProcessXEvent((WXEvent*) &event);
|
||||
m_eventLoop->Dispatch();
|
||||
}
|
||||
|
||||
delete m_eventLoop;
|
||||
m_eventLoop = NULL;
|
||||
|
||||
// TODO: is it safe to call this, if the dialog may have been deleted
|
||||
// by now? Probably only if we're using delayed deletion of dialogs.
|
||||
return GetReturnCode();
|
||||
@ -376,10 +352,7 @@ void wxDialog::EndModal(int retCode)
|
||||
Show(FALSE);
|
||||
|
||||
m_modalShowing = FALSE;
|
||||
|
||||
wxNode *node = wxModalShowingStack.First();
|
||||
if (node)
|
||||
node->SetData((wxObject *)FALSE);
|
||||
m_eventLoop->Exit();
|
||||
}
|
||||
|
||||
// Standard buttons
|
||||
|
467
src/motif/evtloop.cpp
Normal file
467
src/motif/evtloop.cpp
Normal file
@ -0,0 +1,467 @@
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Name: motif/evtloop.cpp
|
||||
// Purpose: implements wxEventLoop for Motif
|
||||
// Author: Mattia Barbon
|
||||
// Modified by:
|
||||
// Created: 01.11.02
|
||||
// RCS-ID: $Id$
|
||||
// Copyright: (c) 2002 Mattia Barbon
|
||||
// License: wxWindows license
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// ============================================================================
|
||||
// declarations
|
||||
// ============================================================================
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// headers
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
#ifdef __GNUG__
|
||||
#pragma implementation "evtloop.h"
|
||||
#endif
|
||||
|
||||
#ifdef __VMS
|
||||
#define XtParent XTPARENT
|
||||
#define XtDisplay XTDISPLAY
|
||||
#endif
|
||||
|
||||
// For compilers that support precompilation, includes "wx.h".
|
||||
#include "wx/wxprec.h"
|
||||
|
||||
#ifndef WX_PRECOMP
|
||||
#endif //WX_PRECOMP
|
||||
|
||||
#include "wx/evtloop.h"
|
||||
#include "wx/event.h"
|
||||
#include "wx/app.h"
|
||||
|
||||
#ifdef __VMS__
|
||||
#pragma message disable nosimpint
|
||||
#endif
|
||||
#include <Xm/Xm.h>
|
||||
#include <X11/Xlib.h>
|
||||
#ifdef __VMS__
|
||||
#pragma message enable nosimpint
|
||||
#endif
|
||||
|
||||
#include "wx/motif/private.h"
|
||||
|
||||
static bool CheckForKeyUp(XEvent* event);
|
||||
static bool CheckForKeyDown(XEvent* event);
|
||||
static bool CheckForAccelerator(XEvent* event);
|
||||
static void ProcessXEvent(XEvent* event);
|
||||
static void wxBreakDispatch();
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// wxEventLoopImpl
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
class WXDLLEXPORT wxEventLoopImpl
|
||||
{
|
||||
public:
|
||||
// ctor
|
||||
wxEventLoopImpl() { SetExitCode(0); }
|
||||
|
||||
// set/get the exit code
|
||||
void SetExitCode(int exitcode) { m_exitcode = exitcode; }
|
||||
int GetExitCode() const { return m_exitcode; }
|
||||
|
||||
bool SendIdleMessage();
|
||||
bool GetKeepGoing() const { return m_keepGoing; }
|
||||
void SetKeepGoing(bool keepGoing) { m_keepGoing = keepGoing; }
|
||||
private:
|
||||
// the exit code of the event loop
|
||||
int m_exitcode;
|
||||
bool m_keepGoing;
|
||||
};
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// wxEventLoopImpl idle event processing
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
static bool SendIdleMessage()
|
||||
{
|
||||
wxIdleEvent event;
|
||||
|
||||
return wxTheApp->ProcessEvent(event) && event.MoreRequested();
|
||||
}
|
||||
|
||||
bool wxEventLoopImpl::SendIdleMessage()
|
||||
{
|
||||
return ::SendIdleMessage();
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// wxEventLoop implementation
|
||||
// ============================================================================
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// wxEventLoop running and exiting
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
wxEventLoop *wxEventLoop::ms_activeLoop = NULL;
|
||||
|
||||
wxEventLoop::~wxEventLoop()
|
||||
{
|
||||
wxASSERT_MSG( !m_impl, _T("should have been deleted in Run()") );
|
||||
}
|
||||
|
||||
bool wxEventLoop::IsRunning() const
|
||||
{
|
||||
return m_impl != NULL;
|
||||
}
|
||||
|
||||
int wxEventLoop::Run()
|
||||
{
|
||||
// event loops are not recursive, you need to create another loop!
|
||||
wxCHECK_MSG( !IsRunning(), -1, _T("can't reenter a message loop") );
|
||||
|
||||
wxEventLoop *oldLoop = ms_activeLoop;
|
||||
ms_activeLoop = this;
|
||||
|
||||
m_impl = new wxEventLoopImpl;
|
||||
m_impl->SetKeepGoing( true );
|
||||
|
||||
for( ;; )
|
||||
{
|
||||
if( !wxDoEventLoopIteration( *this ) )
|
||||
break;
|
||||
}
|
||||
|
||||
int exitcode = m_impl->GetExitCode();
|
||||
delete m_impl;
|
||||
m_impl = NULL;
|
||||
|
||||
ms_activeLoop = oldLoop;
|
||||
|
||||
return exitcode;
|
||||
}
|
||||
|
||||
void wxEventLoop::Exit(int rc)
|
||||
{
|
||||
wxCHECK_RET( IsRunning(), _T("can't call Exit() if not running") );
|
||||
|
||||
m_impl->SetExitCode(rc);
|
||||
m_impl->SetKeepGoing( false );
|
||||
|
||||
::wxBreakDispatch();
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// wxEventLoop message processing dispatching
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
bool wxEventLoop::Pending() const
|
||||
{
|
||||
return XtAppPending( (XtAppContext)wxTheApp->GetAppContext() ) != 0;
|
||||
}
|
||||
|
||||
bool wxEventLoop::Dispatch()
|
||||
{
|
||||
XEvent event;
|
||||
XtAppContext context = (XtAppContext)wxTheApp->GetAppContext();
|
||||
|
||||
if( XtAppPeekEvent( context, &event ) != 0 )
|
||||
{
|
||||
XtAppNextEvent( context, &event );
|
||||
ProcessXEvent( &event );
|
||||
}
|
||||
else
|
||||
XtAppProcessEvent( context, XtIMTimer|XtIMAlternateInput|XtIMSignal );
|
||||
|
||||
return m_impl ? m_impl->GetKeepGoing() : true;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Static functions (originally in app.cpp)
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
void ProcessXEvent(XEvent* event)
|
||||
{
|
||||
if (event->type == KeyPress)
|
||||
{
|
||||
if (CheckForAccelerator(event))
|
||||
{
|
||||
// Do nothing! We intercepted and processed the event as an
|
||||
// accelerator.
|
||||
return;
|
||||
}
|
||||
// It seemed before that this hack was redundant and
|
||||
// key down events were being generated by wxCanvasInputEvent.
|
||||
// But no longer - why ???
|
||||
//
|
||||
else if (CheckForKeyDown(event))
|
||||
{
|
||||
// We intercepted and processed the key down event
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
XtDispatchEvent(event);
|
||||
return;
|
||||
}
|
||||
}
|
||||
else if (event->type == KeyRelease)
|
||||
{
|
||||
// TODO: work out why we still need this ! -michael
|
||||
//
|
||||
if (::CheckForKeyUp(event))
|
||||
{
|
||||
// We intercepted and processed the key up event
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
XtDispatchEvent(event);
|
||||
return;
|
||||
}
|
||||
}
|
||||
else if (event->type == PropertyNotify)
|
||||
{
|
||||
wxTheApp->HandlePropertyChange(event);
|
||||
return;
|
||||
}
|
||||
else if (event->type == ResizeRequest)
|
||||
{
|
||||
/* Terry Gitnick <terryg@scientech.com> - 1/21/98
|
||||
* If resize event, don't resize until the last resize event for this
|
||||
* window is recieved. Prevents flicker as windows are resized.
|
||||
*/
|
||||
|
||||
Display *disp = XtDisplay((Widget) wxTheApp->GetTopLevelWidget());
|
||||
Window win = event->xany.window;
|
||||
XEvent report;
|
||||
|
||||
// to avoid flicker
|
||||
report = * event;
|
||||
while( XCheckTypedWindowEvent (disp, win, ResizeRequest, &report));
|
||||
|
||||
// TODO: when implementing refresh optimization, we can use
|
||||
// XtAddExposureToRegion to expand the window's paint region.
|
||||
|
||||
XtDispatchEvent(event);
|
||||
}
|
||||
else
|
||||
{
|
||||
XtDispatchEvent(event);
|
||||
}
|
||||
}
|
||||
|
||||
// Returns true if an accelerator has been processed
|
||||
bool CheckForAccelerator(XEvent* event)
|
||||
{
|
||||
if (event->xany.type == KeyPress)
|
||||
{
|
||||
// Find a wxWindow for this window
|
||||
// TODO: should get display for the window, not the current display
|
||||
Widget widget = XtWindowToWidget((Display*) wxGetDisplay(),
|
||||
event->xany.window);
|
||||
wxWindow* win = NULL;
|
||||
|
||||
// Find the first wxWindow that corresponds to this event window
|
||||
while (widget && !(win = wxGetWindowFromTable(widget)))
|
||||
widget = XtParent(widget);
|
||||
|
||||
if (!widget || !win)
|
||||
return false;
|
||||
|
||||
wxKeyEvent keyEvent(wxEVT_CHAR);
|
||||
wxTranslateKeyEvent(keyEvent, win, (Widget) 0, event);
|
||||
|
||||
// Now we have a wxKeyEvent and we have a wxWindow.
|
||||
// Go up the hierarchy until we find a matching accelerator,
|
||||
// or we get to the top.
|
||||
while (win)
|
||||
{
|
||||
if (win->ProcessAccelerator(keyEvent))
|
||||
return true;
|
||||
win = win->GetParent();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// bool wxApp::CheckForKeyDown(WXEvent* event) { wxFAIL; return false; }
|
||||
|
||||
bool CheckForKeyDown(XEvent* event)
|
||||
{
|
||||
if (event->xany.type == KeyPress)
|
||||
{
|
||||
Widget widget = XtWindowToWidget((Display*) wxGetDisplay(),
|
||||
event->xany.window);
|
||||
wxWindow* win = NULL;
|
||||
|
||||
// Find the first wxWindow that corresponds to this event window
|
||||
while (widget && !(win = wxGetWindowFromTable(widget)))
|
||||
widget = XtParent(widget);
|
||||
|
||||
if (!widget || !win)
|
||||
return false;
|
||||
|
||||
wxKeyEvent keyEvent(wxEVT_KEY_DOWN);
|
||||
wxTranslateKeyEvent(keyEvent, win, (Widget) 0, event);
|
||||
|
||||
return win->ProcessEvent( keyEvent );
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// bool wxApp::CheckForKeyUp(WXEvent* event) { wxFAIL; return false; }
|
||||
|
||||
bool CheckForKeyUp(XEvent* event)
|
||||
{
|
||||
if (event->xany.type == KeyRelease)
|
||||
{
|
||||
Widget widget = XtWindowToWidget((Display*) wxGetDisplay(),
|
||||
event->xany.window);
|
||||
wxWindow* win = NULL;
|
||||
|
||||
// Find the first wxWindow that corresponds to this event window
|
||||
while (widget && !(win = wxGetWindowFromTable(widget)))
|
||||
widget = XtParent(widget);
|
||||
|
||||
if (!widget || !win)
|
||||
return false;
|
||||
|
||||
wxKeyEvent keyEvent(wxEVT_KEY_UP);
|
||||
wxTranslateKeyEvent(keyEvent, win, (Widget) 0, event);
|
||||
|
||||
return win->ProcessEvent( keyEvent );
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// executes one main loop iteration (declared in include/wx/motif/private.h)
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
bool wxDoEventLoopIteration( wxEventLoop& evtLoop )
|
||||
{
|
||||
#if wxUSE_THREADS
|
||||
// leave the main loop to give other threads a chance to
|
||||
// perform their GUI work
|
||||
wxMutexGuiLeave();
|
||||
wxUsleep(20);
|
||||
wxMutexGuiEnter();
|
||||
#endif
|
||||
|
||||
while ( !evtLoop.Pending() && ::SendIdleMessage() )
|
||||
;
|
||||
|
||||
if( !evtLoop.Dispatch() )
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// ::wxWakeUpIdle implementation
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
// As per Vadim's suggestion, we open a pipe, and XtAppAddInputSource it;
|
||||
// writing a single byte to the pipe will cause wxEventLoop::Pending
|
||||
// to return true, and wxEventLoop::Dispatch to dispatch an input handler
|
||||
// that simply removes the byte(s), and to return, which will cause
|
||||
// an idle event to be sent
|
||||
|
||||
// also wxEventLoop::Exit is implemented that way, so that exiting an
|
||||
// event loop won't require an event being in the queue
|
||||
|
||||
#include "wx/module.h"
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/time.h>
|
||||
#include <unistd.h>
|
||||
|
||||
static XtInputId inputId;
|
||||
static int idleFds[2] = { -1, -1 };
|
||||
|
||||
class wxIdlePipeModule : public wxModule
|
||||
{
|
||||
public:
|
||||
wxIdlePipeModule() {};
|
||||
|
||||
virtual bool OnInit()
|
||||
{
|
||||
if( pipe(idleFds) != 0 )
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
virtual void OnExit()
|
||||
{
|
||||
close( idleFds[0] );
|
||||
close( idleFds[1] );
|
||||
}
|
||||
private:
|
||||
DECLARE_DYNAMIC_CLASS(wxIdlePipeModule);
|
||||
};
|
||||
|
||||
IMPLEMENT_DYNAMIC_CLASS(wxIdlePipeModule, wxModule);
|
||||
|
||||
static void wxInputCallback( XtPointer, int* fd, XtInputId* )
|
||||
{
|
||||
char buffer[128];
|
||||
|
||||
// wxWakeUpIdle may have been called more than once
|
||||
for(;;)
|
||||
{
|
||||
fd_set in;
|
||||
struct timeval timeout;
|
||||
|
||||
timeout.tv_sec = 0;
|
||||
timeout.tv_usec = 0;
|
||||
|
||||
FD_ZERO( &in );
|
||||
FD_SET( *fd, &in );
|
||||
|
||||
if( select( *fd + 1, &in, NULL, NULL, &timeout ) <= 0 )
|
||||
break;
|
||||
if( read( *fd, buffer, sizeof(buffer) - 1 ) != sizeof(buffer) - 1 )
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void wxBreakDispatch()
|
||||
{
|
||||
char dummy;
|
||||
|
||||
// check if wxWakeUpIdle has already been called
|
||||
fd_set in;
|
||||
struct timeval timeout;
|
||||
|
||||
timeout.tv_sec = 0;
|
||||
timeout.tv_usec = 0;
|
||||
|
||||
FD_ZERO( &in );
|
||||
FD_SET( idleFds[0], &in );
|
||||
|
||||
if( select( idleFds[0] + 1, &in, NULL, NULL, &timeout ) > 0 )
|
||||
return;
|
||||
|
||||
// write a single byte
|
||||
write( idleFds[1], &dummy, 1 );
|
||||
}
|
||||
|
||||
void wxWakeUpIdle()
|
||||
{
|
||||
::wxBreakDispatch();
|
||||
}
|
||||
|
||||
bool wxAddIdleCallback()
|
||||
{
|
||||
// install input handler for wxWakeUpIdle
|
||||
inputId = XtAppAddInput( (XtAppContext) wxTheApp->GetAppContext(),
|
||||
idleFds[0],
|
||||
(XtPointer)XtInputReadMask,
|
||||
wxInputCallback,
|
||||
NULL );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -199,6 +199,7 @@ ALL_SOURCES = \
|
||||
motif/dcmemory.cpp \
|
||||
motif/dcscreen.cpp \
|
||||
motif/dialog.cpp \
|
||||
motif/evtloop.cpp \
|
||||
motif/filedlg.cpp \
|
||||
motif/font.cpp \
|
||||
motif/frame.cpp \
|
||||
@ -834,6 +835,7 @@ GUIOBJS = \
|
||||
dcmemory.o \
|
||||
dcscreen.o \
|
||||
dialog.o \
|
||||
evtloop.o \
|
||||
filedlg.o \
|
||||
font.o \
|
||||
frame.o \
|
||||
|
@ -440,28 +440,20 @@ bool wxMenuBar::DestroyMenuBar()
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
//// Motif-specific
|
||||
static XtWorkProcId WorkProcMenuId;
|
||||
|
||||
/* Since PopupMenu under Motif stills grab right mouse button events
|
||||
* after it was closed, we need to delete the associated widgets to
|
||||
* allow next PopUpMenu to appear...
|
||||
*/
|
||||
|
||||
int PostDeletionOfMenu( XtPointer* clientData )
|
||||
// Since PopupMenu under Motif stills grab right mouse button events
|
||||
// after it was closed, we need to delete the associated widgets to
|
||||
// allow next PopUpMenu to appear...
|
||||
void wxMenu::DestroyWidgetAndDetach()
|
||||
{
|
||||
XtRemoveWorkProc(WorkProcMenuId);
|
||||
wxMenu *menu = (wxMenu *)clientData;
|
||||
|
||||
if (menu->GetMainWidget())
|
||||
if (GetMainWidget())
|
||||
{
|
||||
wxMenu *menuParent = menu->GetParent();
|
||||
wxMenu *menuParent = GetParent();
|
||||
if ( menuParent )
|
||||
{
|
||||
wxMenuItemList::Node *node = menuParent->GetMenuItems().GetFirst();
|
||||
while ( node )
|
||||
{
|
||||
if ( node->GetData()->GetSubMenu() == menu )
|
||||
if ( node->GetData()->GetSubMenu() == this )
|
||||
{
|
||||
menuParent->GetMenuItems().DeleteNode(node);
|
||||
|
||||
@ -472,33 +464,11 @@ int PostDeletionOfMenu( XtPointer* clientData )
|
||||
}
|
||||
}
|
||||
|
||||
menu->DestroyMenu(TRUE);
|
||||
DestroyMenu(TRUE);
|
||||
}
|
||||
|
||||
// Mark as no longer popped up
|
||||
menu->m_menuId = -1;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void
|
||||
wxMenuPopdownCallback(Widget WXUNUSED(w), XtPointer clientData,
|
||||
XtPointer WXUNUSED(ptr))
|
||||
{
|
||||
wxMenu *menu = (wxMenu *)clientData;
|
||||
|
||||
// Added by JOREL Jean-Charles <jjorel@silr.ireste.fr>
|
||||
/* Since Callbacks of MenuItems are not yet processed, we put a
|
||||
* background job which will be done when system will be idle.
|
||||
* What awful hack!! :(
|
||||
*/
|
||||
|
||||
WorkProcMenuId = XtAppAddWorkProc(
|
||||
(XtAppContext) wxTheApp->GetAppContext(),
|
||||
(XtWorkProc) PostDeletionOfMenu,
|
||||
(XtPointer) menu );
|
||||
// Apparently not found in Motif headers
|
||||
// XtVaSetValues( w, XmNpopupEnabled, XmPOPUP_DISABLED, NULL );
|
||||
m_menuId = -1;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -518,10 +488,12 @@ WXWidget wxMenu::CreateMenu (wxMenuBar * menuBar, WXWidget parent, wxMenu * topM
|
||||
if (!pullDown)
|
||||
{
|
||||
menu = XmCreatePopupMenu ((Widget) parent, "popup", args, 2);
|
||||
#if 0
|
||||
XtAddCallback(menu,
|
||||
XmNunmapCallback,
|
||||
(XtCallbackProc)wxMenuPopdownCallback,
|
||||
(XtPointer)this);
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -354,6 +354,7 @@ void wxMenuItemCallback (Widget WXUNUSED(w), XtPointer clientData,
|
||||
|
||||
item->GetMenuBar()->GetMenuBarFrame()->GetEventHandler()->ProcessEvent(commandEvent);
|
||||
}
|
||||
// this is the child of a popup menu
|
||||
else if (item->GetTopMenu())
|
||||
{
|
||||
wxCommandEvent event (wxEVT_COMMAND_MENU_SELECTED, item->GetId());
|
||||
@ -361,6 +362,14 @@ void wxMenuItemCallback (Widget WXUNUSED(w), XtPointer clientData,
|
||||
event.SetInt( item->GetId() );
|
||||
|
||||
item->GetTopMenu()->ProcessCommand (event);
|
||||
|
||||
// Since PopupMenu under Motif stills grab right mouse
|
||||
// button events after it was closed, we need to delete
|
||||
// the associated widgets to allow next PopUpMenu to
|
||||
// appear; this needs to be done there because doing it in
|
||||
// a WorkProc as before may cause crashes if a menu item causes
|
||||
// the parent window of the menu to be destroyed
|
||||
item->GetTopMenu()->DestroyWidgetAndDetach();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -45,6 +45,7 @@
|
||||
#include "wx/module.h"
|
||||
#include "wx/menuitem.h"
|
||||
#include "wx/log.h"
|
||||
#include "wx/evtloop.h"
|
||||
|
||||
#if wxUSE_DRAG_AND_DROP
|
||||
#include "wx/dnd.h"
|
||||
@ -1151,6 +1152,8 @@ void wxWindow::DoSetToolTip(wxToolTip * WXUNUSED(tooltip))
|
||||
// popup menus
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
#if wxUSE_MENUS
|
||||
|
||||
bool wxWindow::DoPopupMenu(wxMenu *menu, int x, int y)
|
||||
{
|
||||
Widget widget = (Widget) GetMainWidget();
|
||||
@ -1165,7 +1168,8 @@ bool wxWindow::DoPopupMenu(wxMenu *menu, int x, int y)
|
||||
if (menu->GetParent() && (menu->GetId() != -1))
|
||||
return FALSE;
|
||||
|
||||
if (menu->GetMainWidget()) {
|
||||
if (menu->GetMainWidget())
|
||||
{
|
||||
menu->DestroyMenu(TRUE);
|
||||
}
|
||||
|
||||
@ -1214,7 +1218,6 @@ bool wxWindow::DoPopupMenu(wxMenu *menu, int x, int y)
|
||||
XmMenuPosition (menuWidget, &event);
|
||||
XtManageChild (menuWidget);
|
||||
|
||||
XEvent x_event;
|
||||
// The ID of a pop-up menu is 1 when active, and is set to 0 by the
|
||||
// idle-time destroy routine.
|
||||
// Waiting until this ID changes causes this function to block until
|
||||
@ -1222,29 +1225,19 @@ bool wxWindow::DoPopupMenu(wxMenu *menu, int x, int y)
|
||||
// In other words, once this routine returns, it is safe to delete
|
||||
// the menu object.
|
||||
// Ian Brown <ian.brown@printsoft.de>
|
||||
|
||||
wxEventLoop evtLoop;
|
||||
|
||||
while (menu->GetId() == 1)
|
||||
{
|
||||
XtAppNextEvent( (XtAppContext) wxTheApp->GetAppContext(), &x_event);
|
||||
|
||||
wxTheApp->ProcessXEvent((WXEvent*) & x_event);
|
||||
|
||||
if (XtAppPending( (XtAppContext) wxTheApp->GetAppContext() ) == 0)
|
||||
{
|
||||
if (!wxTheApp->ProcessIdle())
|
||||
{
|
||||
#if wxUSE_THREADS
|
||||
// leave the main loop to give other threads a chance to
|
||||
// perform their GUI work
|
||||
wxMutexGuiLeave();
|
||||
wxUsleep(20);
|
||||
wxMutexGuiEnter();
|
||||
#endif
|
||||
}
|
||||
}
|
||||
wxDoEventLoopIteration( evtLoop );
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// moving and resizing
|
||||
// ---------------------------------------------------------------------------
|
||||
@ -1352,9 +1345,9 @@ void wxWindow::DoSetSizeIntr(int x, int y, int width, int height,
|
||||
y = oldY;
|
||||
}
|
||||
|
||||
if ( width == -1 )
|
||||
if ( width <= 0 )
|
||||
width = oldW;
|
||||
if ( height == -1 )
|
||||
if ( height <= 0 )
|
||||
height = oldH;
|
||||
|
||||
bool nothingChanged = (x == oldX) && (y == oldY) &&
|
||||
@ -1390,15 +1383,6 @@ void wxWindow::DoSetSizeIntr(int x, int y, int width, int height,
|
||||
|
||||
if (managed)
|
||||
XtManageChild(widget);
|
||||
|
||||
// How about this bit. Maybe we don't need to generate size events
|
||||
// all the time -- they'll be generated when the window is sized anyway.
|
||||
#if 0
|
||||
wxSizeEvent sizeEvent(wxSize(width, height), GetId());
|
||||
sizeEvent.SetEventObject(this);
|
||||
|
||||
GetEventHandler()->ProcessEvent(sizeEvent);
|
||||
#endif // 0
|
||||
}
|
||||
}
|
||||
|
||||
@ -1727,6 +1711,7 @@ void wxWindow::OnIdle(wxIdleEvent& WXUNUSED(event))
|
||||
|
||||
bool wxWindow::ProcessAccelerator(wxKeyEvent& event)
|
||||
{
|
||||
#if wxUSE_ACCEL
|
||||
if (!m_acceleratorTable.Ok())
|
||||
return FALSE;
|
||||
|
||||
@ -1753,6 +1738,7 @@ bool wxWindow::ProcessAccelerator(wxKeyEvent& event)
|
||||
wxFrame* frame = wxDynamicCast(parent, wxFrame);
|
||||
if ( frame )
|
||||
{
|
||||
#if wxUSE_MENUS
|
||||
// Try for a menu command
|
||||
if (frame->GetMenuBar())
|
||||
{
|
||||
@ -1767,6 +1753,7 @@ bool wxWindow::ProcessAccelerator(wxKeyEvent& event)
|
||||
return frame->GetEventHandler()->ProcessEvent(commandEvent);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
// Find a child matching the command id
|
||||
@ -1788,6 +1775,7 @@ bool wxWindow::ProcessAccelerator(wxKeyEvent& event)
|
||||
return FALSE;
|
||||
} // matches event
|
||||
}// for
|
||||
#endif
|
||||
|
||||
// We didn't match the key event against an accelerator.
|
||||
return FALSE;
|
||||
|
Loading…
Reference in New Issue
Block a user