1 /////////////////////////////////////////////////////////////////////////////
2 // Name: motif/frame.cpp
4 // Author: Julian Smart
8 // Copyright: (c) Julian Smart
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
12 // ============================================================================
14 // ============================================================================
16 // ----------------------------------------------------------------------------
18 // ----------------------------------------------------------------------------
21 #pragma implementation "frame.h"
25 #include "wx/statusbr.h"
26 #include "wx/toolbar.h"
27 #include "wx/menuitem.h"
29 #include "wx/dcclient.h"
30 #include "wx/dialog.h"
31 #include "wx/settings.h"
37 #pragma message disable nosimpint
40 #if defined(__ultrix) || defined(__sgi)
45 #include <X11/Shell.h>
51 #include <Xm/MwmUtil.h>
52 #include <Xm/BulletinB.h>
55 #include <Xm/RowColumn.h>
57 #include <Xm/AtomMgr.h>
58 #include <Xm/LabelG.h>
61 #include <Xm/Protocols.h>
65 #pragma message enable nosimpint
68 #include "wx/motif/private.h"
70 // ----------------------------------------------------------------------------
72 // ----------------------------------------------------------------------------
74 static void wxFrameEventHandler(Widget wid
,
75 XtPointer
WXUNUSED(client_data
),
77 Boolean
* continueToDispatch
);
78 static void wxCloseFrameCallback(Widget
, XtPointer
, XmAnyCallbackStruct
*cbs
);
79 static void wxFrameFocusProc(Widget workArea
, XtPointer clientData
,
80 XmAnyCallbackStruct
*cbs
);
81 static void wxFrameMapProc(Widget frameShell
, XtPointer clientData
,
82 XCrossingEvent
* event
);
84 // ----------------------------------------------------------------------------
86 // ----------------------------------------------------------------------------
88 extern wxList wxModelessWindows
;
89 extern wxList wxPendingDelete
;
91 // TODO: this should be tidied so that any frame can be the
93 static bool wxTopLevelUsed
= FALSE
;
95 // ----------------------------------------------------------------------------
97 // ----------------------------------------------------------------------------
99 BEGIN_EVENT_TABLE(wxFrame
, wxFrameBase
)
100 EVT_ACTIVATE(wxFrame::OnActivate
)
101 EVT_SYS_COLOUR_CHANGED(wxFrame::OnSysColourChanged
)
104 IMPLEMENT_DYNAMIC_CLASS(wxFrame
, wxWindow
)
106 // ============================================================================
108 // ============================================================================
110 // ----------------------------------------------------------------------------
111 // frame construction
112 // ----------------------------------------------------------------------------
119 m_frameShell
= (WXWidget
) NULL
;
120 m_frameWidget
= (WXWidget
) NULL
;;
121 m_workArea
= (WXWidget
) NULL
;;
122 m_clientArea
= (WXWidget
) NULL
;;
123 m_visibleStatus
= TRUE
;
126 bool wxFrame::Create(wxWindow
*parent
,
128 const wxString
& title
,
132 const wxString
& name
)
135 parent
->AddChild(this);
137 wxTopLevelWindows
.Append(this);
139 wxModelessWindows
.Append(this);
143 m_windowStyle
= style
;
145 m_backgroundColour
= wxSystemSettings::GetSystemColour(wxSYS_COLOUR_APPWORKSPACE
);
146 m_foregroundColour
= *wxBLACK
;
147 m_font
= wxSystemSettings::GetSystemFont(wxSYS_DEFAULT_GUI_FONT
);
152 m_windowId
= (int)NewControlId();
154 int x
= pos
.x
, y
= pos
.y
;
155 int width
= size
.x
, height
= size
.y
;
157 // Set reasonable values for position and size if defaults have been
160 // MB TODO: something better than these arbitrary values ?
161 // VZ should use X resources for this...
167 int displayW
, displayH
;
168 wxDisplaySize( &displayW
, &displayH
);
172 x
= (displayW
- width
) / 2;
177 y
= (displayH
- height
) / 2;
181 // VZ: what does this do??
184 // Change suggested by Matthew Flatt
185 m_frameShell
= (WXWidget
)XtAppCreateShell
188 wxTheApp
->GetClassName(),
189 topLevelShellWidgetClass
,
190 (Display
*) wxGetDisplay(),
197 m_frameShell
= wxTheApp
->GetTopLevelWidget();
198 wxTopLevelUsed
= TRUE
;
201 XtVaSetValues((Widget
) m_frameShell
,
202 // Allows menu to resize
203 XmNallowShellResize
, True
,
204 XmNdeleteResponse
, XmDO_NOTHING
,
205 XmNmappedWhenManaged
, False
,
206 XmNiconic
, (style
& wxICONIZE
) ? TRUE
: FALSE
,
209 if (!title
.IsEmpty())
210 XtVaSetValues((Widget
) m_frameShell
,
211 XmNtitle
, title
.c_str(),
214 m_frameWidget
= (WXWidget
) XtVaCreateManagedWidget("main_window",
215 xmMainWindowWidgetClass
, (Widget
) m_frameShell
,
216 XmNresizePolicy
, XmRESIZE_NONE
,
219 m_workArea
= (WXWidget
) XtVaCreateWidget("form",
220 xmFormWidgetClass
, (Widget
) m_frameWidget
,
221 XmNresizePolicy
, XmRESIZE_NONE
,
224 m_clientArea
= (WXWidget
) XtVaCreateWidget("client",
225 xmBulletinBoardWidgetClass
, (Widget
) m_workArea
,
228 XmNrightAttachment
, XmATTACH_FORM
,
229 XmNleftAttachment
, XmATTACH_FORM
,
230 XmNtopAttachment
, XmATTACH_FORM
,
231 XmNbottomAttachment
, XmATTACH_FORM
,
232 // XmNresizePolicy, XmRESIZE_ANY,
235 wxLogTrace(wxTRACE_Messages
,
236 "Created frame (0x%08x) with work area 0x%08x and client "
237 "area 0x%08x", m_frameWidget
, m_workArea
, m_clientArea
);
239 XtAddEventHandler((Widget
) m_clientArea
, ExposureMask
,FALSE
,
240 wxUniversalRepaintProc
, (XtPointer
) this);
242 XtAddEventHandler((Widget
) m_clientArea
,
243 ButtonPressMask
| ButtonReleaseMask
| PointerMotionMask
| KeyPressMask
,
248 XtVaSetValues((Widget
) m_frameWidget
,
249 XmNworkWindow
, (Widget
) m_workArea
,
252 XtManageChild((Widget
) m_clientArea
);
253 XtManageChild((Widget
) m_workArea
);
255 wxAddWindowToTable((Widget
) m_workArea
, this);
256 wxAddWindowToTable((Widget
) m_clientArea
, this);
260 XtOverrideTranslations((Widget
) m_workArea
,
261 ptr
= XtParseTranslationTable("<Configure>: resize()"));
265 XtAddCallback((Widget
) m_workArea
, XmNfocusCallback
,
266 (XtCallbackProc
)wxFrameFocusProc
, (XtPointer
)this);
268 /* Part of show-&-hide fix */
269 XtAddEventHandler((Widget
) m_frameShell
, StructureNotifyMask
,
270 False
, (XtEventHandler
)wxFrameMapProc
,
271 (XtPointer
)m_workArea
);
274 XtVaSetValues((Widget
) m_frameShell
, XmNx
, x
, NULL
);
276 XtVaSetValues((Widget
) m_frameShell
, XmNy
, y
, NULL
);
278 XtVaSetValues((Widget
) m_frameShell
, XmNwidth
, width
, NULL
);
280 XtVaSetValues((Widget
) m_frameShell
, XmNheight
, height
, NULL
);
282 m_mainWidget
= m_frameWidget
;
286 // This patch comes from Torsten Liermann lier@lier1.muc.de
287 if (XmIsMotifWMRunning( (Widget
) m_frameShell
))
290 if (style
& wxRESIZE_BORDER
)
291 decor
|= MWM_DECOR_RESIZEH
;
292 if (style
& wxSYSTEM_MENU
)
293 decor
|= MWM_DECOR_MENU
;
294 if ((style
& wxCAPTION
) ||
295 (style
& wxTINY_CAPTION_HORIZ
) ||
296 (style
& wxTINY_CAPTION_VERT
))
297 decor
|= MWM_DECOR_TITLE
;
298 if (style
& wxTHICK_FRAME
)
299 decor
|= MWM_DECOR_BORDER
;
300 if (style
& wxTHICK_FRAME
)
301 decor
|= MWM_DECOR_BORDER
;
302 if (style
& wxMINIMIZE_BOX
)
303 decor
|= MWM_DECOR_MINIMIZE
;
304 if (style
& wxMAXIMIZE_BOX
)
305 decor
|= MWM_DECOR_MAXIMIZE
;
306 XtVaSetValues((Widget
) m_frameShell
,XmNmwmDecorations
,decor
,NULL
);
308 // This allows non-Motif window managers to support at least the
309 // no-decorations case.
313 XtVaSetValues((Widget
) m_frameShell
,XmNoverrideRedirect
,TRUE
,NULL
);
315 XtRealizeWidget((Widget
) m_frameShell
);
317 // Intercept CLOSE messages from the window manager
318 Atom WM_DELETE_WINDOW
= XmInternAtom(XtDisplay((Widget
) m_frameShell
), "WM_DELETE_WINDOW", False
);
319 #if (XmREVISION > 1 || XmVERSION > 1)
320 XmAddWMProtocolCallback((Widget
) m_frameShell
, WM_DELETE_WINDOW
, (XtCallbackProc
) wxCloseFrameCallback
, (XtPointer
)this);
323 XmAddWMProtocolCallback((Widget
) m_frameShell
, WM_DELETE_WINDOW
, (XtCallbackProc
) wxCloseFrameCallback
, (caddr_t
)this);
325 XmAddWMProtocolCallback((Widget
) m_frameShell
, WM_DELETE_WINDOW
, (void (*)())wxCloseFrameCallback
, (caddr_t
)this);
329 ChangeBackgroundColour();
333 wxSizeEvent
sizeEvent(wxSize(width
, height
), GetId());
334 sizeEvent
.SetEventObject(this);
336 GetEventHandler()->ProcessEvent(sizeEvent
);
343 m_isBeingDeleted
= TRUE
;
347 XtRemoveEventHandler((Widget
) m_clientArea
, ExposureMask
, FALSE
,
348 wxUniversalRepaintProc
, (XtPointer
) this);
349 XtRemoveEventHandler((Widget
) m_clientArea
, ButtonPressMask
| ButtonReleaseMask
| PointerMotionMask
| KeyPressMask
,
351 wxFrameEventHandler
, (XtPointer
) this);
352 wxDeleteWindowFromTable((Widget
) m_clientArea
);
360 m_frameMenuBar
->DestroyMenuBar();
362 // Hack to stop core dump on Ultrix, OSF, for some strange reason.
363 #if MOTIF_MENUBAR_DELETE_FIX
364 GetMenuBar()->SetMainWidget((WXWidget
) NULL
);
366 delete m_frameMenuBar
;
367 m_frameMenuBar
= NULL
;
370 wxTopLevelWindows
.DeleteObject(this);
371 wxModelessWindows
.DeleteObject(this);
373 if (m_frameStatusBar
)
375 delete m_frameStatusBar
;
376 m_frameStatusBar
= NULL
;
383 wxDeleteWindowFromTable((Widget
) m_workArea
);
385 XtDestroyWidget ((Widget
) m_workArea
);
390 wxDeleteWindowFromTable((Widget
) m_frameWidget
);
391 XtDestroyWidget ((Widget
) m_frameWidget
);
395 XtDestroyWidget ((Widget
) m_frameShell
);
397 SetMainWidget((WXWidget
) NULL
);
399 /* Check if it's the last top-level window */
401 if (wxTheApp
&& (wxTopLevelWindows
.Number() == 0))
403 wxTheApp
->SetTopWindow(NULL
);
405 if (wxTheApp
->GetExitOnFrameDelete())
407 // Signal to the app that we're going to close
408 wxTheApp
->ExitMainLoop();
413 // Get size *available for subwindows* i.e. excluding menu bar, toolbar etc.
414 void wxFrame::DoGetClientSize(int *x
, int *y
) const
417 XtVaGetValues((Widget
) m_workArea
, XmNwidth
, &xx
, XmNheight
, &yy
, NULL
);
419 if (m_frameStatusBar
)
422 m_frameStatusBar
->GetSize(& sbw
, & sbh
);
429 m_frameToolBar
->GetSize(& tbw
, & tbh
);
430 if (m_frameToolBar
->GetWindowStyleFlag() & wxTB_VERTICAL
)
435 #endif // wxUSE_TOOLBAR
437 if (GetMenuBar() != (wxMenuBar*) NULL)
439 // it seems that if a frame holds a panel, the menu bar size
440 // gets automatically taken care of --- grano@cs.helsinki.fi 4.4.95
441 bool hasSubPanel = FALSE;
442 for(wxNode* node = GetChildren().First(); node; node = node->Next())
444 wxWindow *win = (wxWindow *)node->Data();
445 hasSubPanel = (win->IsKindOf(CLASSINFO(wxPanel)) && !win->IsKindOf(CLASSINFO(wxDialog)));
452 XtVaGetValues((Widget) GetMenuBarWidget(), XmNheight, &ys, NULL);
461 // Set the client size (i.e. leave the calculation of borders etc.
463 void wxFrame::DoSetClientSize(int width
, int height
)
465 // Calculate how large the new main window should be
466 // by finding the difference between the client area and the
467 // main window area, and adding on to the new client area
469 XtVaSetValues((Widget
) m_workArea
, XmNwidth
, width
, NULL
);
473 if (m_frameStatusBar
)
476 m_frameStatusBar
->GetSize(& sbw
, & sbh
);
483 m_frameToolBar
->GetSize(& tbw
, & tbh
);
484 if (m_frameToolBar
->GetWindowStyleFlag() & wxTB_VERTICAL
)
489 #endif // wxUSE_TOOLBAR
491 XtVaSetValues((Widget
) m_workArea
, XmNheight
, height
, NULL
);
495 wxSizeEvent
sizeEvent(wxSize(width
, height
), GetId());
496 sizeEvent
.SetEventObject(this);
498 GetEventHandler()->ProcessEvent(sizeEvent
);
502 void wxFrame::DoGetSize(int *width
, int *height
) const
505 XtVaGetValues((Widget
) m_frameShell
, XmNwidth
, &xx
, XmNheight
, &yy
, NULL
);
506 *width
= xx
; *height
= yy
;
509 void wxFrame::DoGetPosition(int *x
, int *y
) const
511 Window parent_window
= XtWindow((Widget
) m_frameShell
),
512 next_parent
= XtWindow((Widget
) m_frameShell
),
513 root
= RootWindowOfScreen(XtScreen((Widget
) m_frameShell
));
515 // search for the parent that is child of ROOT, because the WM may
516 // reparent twice and notify only the next parent (like FVWM)
517 while (next_parent
!= root
) {
518 Window
*theChildren
; unsigned int n
;
519 parent_window
= next_parent
;
520 XQueryTree(XtDisplay((Widget
) m_frameShell
), parent_window
, &root
,
521 &next_parent
, &theChildren
, &n
);
522 XFree(theChildren
); // not needed
524 int xx
, yy
; unsigned int dummy
;
525 XGetGeometry(XtDisplay((Widget
) m_frameShell
), parent_window
, &root
,
526 &xx
, &yy
, &dummy
, &dummy
, &dummy
, &dummy
);
531 void wxFrame::DoSetSize(int x
, int y
, int width
, int height
, int WXUNUSED(sizeFlags
))
534 XtVaSetValues((Widget
) m_frameShell
, XmNx
, x
, NULL
);
536 XtVaSetValues((Widget
) m_frameShell
, XmNy
, y
, NULL
);
538 XtVaSetValues((Widget
) m_frameWidget
, XmNwidth
, width
, NULL
);
540 XtVaSetValues((Widget
) m_frameWidget
, XmNheight
, height
, NULL
);
542 if (!(height
== -1 && width
== -1))
546 wxSizeEvent
sizeEvent(wxSize(width
, height
), GetId());
547 sizeEvent
.SetEventObject(this);
549 GetEventHandler()->ProcessEvent(sizeEvent
);
553 bool wxFrame::Show(bool show
)
556 return wxWindow::Show(show
);
558 m_visibleStatus
= show
; /* show-&-hide fix */
562 XtMapWidget((Widget
) m_frameShell
);
563 XRaiseWindow(XtDisplay((Widget
) m_frameShell
), XtWindow((Widget
) m_frameShell
));
565 XtUnmapWidget((Widget
) m_frameShell
);
566 // XmUpdateDisplay(wxTheApp->topLevel); // Experimental: may be responsible for crashes
571 void wxFrame::Iconize(bool iconize
)
577 XtVaSetValues((Widget
) m_frameShell
, XmNiconic
, (Boolean
)iconize
, NULL
);
580 void wxFrame::Restore()
583 XtVaSetValues((Widget
) m_frameShell
, XmNiconic
, FALSE
, NULL
);
586 void wxFrame::Maximize(bool maximize
)
594 bool wxFrame::IsIconized() const
600 XtVaGetValues((Widget
) m_frameShell
, XmNiconic
, &iconic
, NULL
);
605 bool wxFrame::IsMaximized() const
607 // No maximizing in Motif (?)
611 void wxFrame::SetTitle(const wxString
& title
)
613 if (title
== m_title
)
619 XtVaSetValues((Widget
) m_frameShell
,
620 XmNtitle
, title
.c_str(),
621 XmNiconName
, title
.c_str(),
625 void wxFrame::SetIcon(const wxIcon
& icon
)
632 if (!icon
.Ok() || !icon
.GetPixmap())
635 XtVaSetValues((Widget
) m_frameShell
, XtNiconPixmap
, icon
.GetPixmap(), NULL
);
638 void wxFrame::PositionStatusBar()
640 if (!m_frameStatusBar
)
644 GetClientSize(&w
, &h
);
646 m_frameStatusBar
->GetSize(&sw
, &sh
);
648 // Since we wish the status bar to be directly under the client area,
649 // we use the adjusted sizes without using wxSIZE_NO_ADJUSTMENTS.
650 m_frameStatusBar
->SetSize(0, h
, w
, sh
);
653 WXWidget
wxFrame::GetMenuBarWidget() const
656 return GetMenuBar()->GetMainWidget();
658 return (WXWidget
) NULL
;
661 void wxFrame::SetMenuBar(wxMenuBar
*menuBar
)
665 m_frameMenuBar
= NULL
;
669 // Currently can't set it twice
670 // wxASSERT_MSG( (m_frameMenuBar == (wxMenuBar*) NULL), "Cannot set the menubar more than once");
674 m_frameMenuBar
->DestroyMenuBar();
675 delete m_frameMenuBar
;
678 m_frameMenuBar
= menuBar
;
679 m_frameMenuBar
->CreateMenuBar(this);
682 // Responds to colour changes, and passes event on to children.
683 void wxFrame::OnSysColourChanged(wxSysColourChangedEvent
& event
)
685 SetBackgroundColour(wxSystemSettings::GetSystemColour(wxSYS_COLOUR_APPWORKSPACE
));
688 if ( m_frameStatusBar
)
690 wxSysColourChangedEvent event2
;
691 event2
.SetEventObject( m_frameStatusBar
);
692 m_frameStatusBar
->ProcessEvent(event2
);
695 // Propagate the event to the non-top-level children
696 wxWindow::OnSysColourChanged(event
);
699 // Default activation behaviour - set the focus for the first child
701 void wxFrame::OnActivate(wxActivateEvent
& event
)
703 if (!event
.GetActive())
706 for(wxNode
*node
= GetChildren().First(); node
; node
= node
->Next())
708 // Find a child that's a subwindow, but not a dialog box.
709 wxWindow
*child
= (wxWindow
*)node
->Data();
710 if (!child
->IsKindOf(CLASSINFO(wxFrame
)) &&
711 !child
->IsKindOf(CLASSINFO(wxDialog
)))
721 wxToolBar
* wxFrame::CreateToolBar(long style
,
723 const wxString
& name
)
725 if ( wxFrameBase::CreateToolBar(style
, id
, name
) )
730 return m_frameToolBar
;
733 void wxFrame::PositionToolBar()
738 GetClientSize(& cw
, &ch
);
741 GetToolBar()->GetSize(& tw
, & th
);
743 if (GetToolBar()->GetWindowStyleFlag() & wxTB_VERTICAL
)
745 // Use the 'real' position. wxSIZE_NO_ADJUSTMENTS
746 // means, pretend we don't have toolbar/status bar, so we
747 // have the original client size.
748 GetToolBar()->SetSize(0, 0, tw
, ch
+ th
, wxSIZE_NO_ADJUSTMENTS
);
752 // Use the 'real' position
753 GetToolBar()->SetSize(0, 0, cw
, th
, wxSIZE_NO_ADJUSTMENTS
);
757 #endif // wxUSE_TOOLBAR
759 void wxFrame::Raise()
761 Window parent_window
= XtWindow((Widget
) m_frameShell
),
762 next_parent
= XtWindow((Widget
) m_frameShell
),
763 root
= RootWindowOfScreen(XtScreen((Widget
) m_frameShell
));
764 // search for the parent that is child of ROOT, because the WM may
765 // reparent twice and notify only the next parent (like FVWM)
766 while (next_parent
!= root
) {
767 Window
*theChildren
; unsigned int n
;
768 parent_window
= next_parent
;
769 XQueryTree(XtDisplay((Widget
) m_frameShell
), parent_window
, &root
,
770 &next_parent
, &theChildren
, &n
);
771 XFree(theChildren
); // not needed
773 XRaiseWindow(XtDisplay((Widget
) m_frameShell
), parent_window
);
776 void wxFrame::Lower()
778 Window parent_window
= XtWindow((Widget
) m_frameShell
),
779 next_parent
= XtWindow((Widget
) m_frameShell
),
780 root
= RootWindowOfScreen(XtScreen((Widget
) m_frameShell
));
781 // search for the parent that is child of ROOT, because the WM may
782 // reparent twice and notify only the next parent (like FVWM)
783 while (next_parent
!= root
) {
784 Window
*theChildren
; unsigned int n
;
785 parent_window
= next_parent
;
786 XQueryTree(XtDisplay((Widget
) m_frameShell
), parent_window
, &root
,
787 &next_parent
, &theChildren
, &n
);
788 XFree(theChildren
); // not needed
790 XLowerWindow(XtDisplay((Widget
) m_frameShell
), parent_window
);
793 void wxFrameFocusProc(Widget
WXUNUSED(workArea
), XtPointer
WXUNUSED(clientData
),
794 XmAnyCallbackStruct
*WXUNUSED(cbs
))
796 // wxDebugMsg("focus proc from frame %ld\n",(long)frame);
798 // wxFrame *frame = (wxFrame *)clientData;
799 // frame->GetEventHandler()->OnSetFocus();
802 /* MATTEW: Used to insure that hide-&-show within an event cycle works */
803 static void wxFrameMapProc(Widget frameShell
, XtPointer clientData
,
804 XCrossingEvent
* event
)
806 wxFrame
*frame
= (wxFrame
*)wxGetWindowFromTable((Widget
)clientData
);
809 XEvent
*e
= (XEvent
*)event
;
811 if (e
->xany
.type
== MapNotify
)
814 XtVaSetValues(frameShell
, XmNiconic
, (Boolean
)False
, NULL
);
815 if (!frame
->GetVisibleStatus())
817 /* We really wanted this to be hidden! */
818 XtUnmapWidget((Widget
) frame
->GetShellWidget());
821 else if (e
->xany
.type
== UnmapNotify
)
823 XtVaSetValues(frameShell
, XmNiconic
, (Boolean
)True
, NULL
);
828 bool wxFrame::PreResize()
832 #endif // wxUSE_TOOLBAR
836 #endif // wxUSE_STATUSBAR
841 WXWidget
wxFrame::GetClientWidget() const
846 void wxFrame::ChangeFont(bool WXUNUSED(keepOriginalSize
))
851 void wxFrame::ChangeBackgroundColour()
853 if (GetClientWidget())
854 DoChangeBackgroundColour(GetClientWidget(), m_backgroundColour
);
857 void wxFrame::ChangeForegroundColour()
859 if (GetClientWidget())
860 DoChangeForegroundColour(GetClientWidget(), m_foregroundColour
);
863 void wxCloseFrameCallback(Widget
WXUNUSED(widget
), XtPointer client_data
, XmAnyCallbackStruct
*WXUNUSED(cbs
))
865 wxFrame
*frame
= (wxFrame
*)client_data
;
867 wxCloseEvent
closeEvent(wxEVT_CLOSE_WINDOW
, frame
->GetId());
868 closeEvent
.SetEventObject(frame
);
870 // May delete the frame (with delayed deletion)
871 frame
->GetEventHandler()->ProcessEvent(closeEvent
);
874 static void wxFrameEventHandler(Widget wid
,
875 XtPointer
WXUNUSED(client_data
),
877 Boolean
* continueToDispatch
)
879 wxFrame
*frame
= (wxFrame
*)wxGetWindowFromTable(wid
);
882 wxMouseEvent
wxevent(wxEVT_NULL
);
883 if (wxTranslateMouseEvent(wxevent
, frame
, wid
, event
))
885 wxevent
.SetEventObject(frame
);
886 wxevent
.SetId(frame
->GetId());
887 frame
->GetEventHandler()->ProcessEvent(wxevent
);
891 // An attempt to implement OnCharHook by calling OnCharHook first;
892 // if this returns TRUE, set continueToDispatch to False
893 // (don't continue processing).
894 // Otherwise set it to True and call OnChar.
895 wxKeyEvent
keyEvent(wxEVT_CHAR
);
896 if (wxTranslateKeyEvent(keyEvent
, frame
, wid
, event
))
898 keyEvent
.SetEventObject(frame
);
899 keyEvent
.SetId(frame
->GetId());
900 keyEvent
.SetEventType(wxEVT_CHAR_HOOK
);
901 if (frame
->GetEventHandler()->ProcessEvent(keyEvent
))
903 *continueToDispatch
= False
;
908 // For simplicity, OnKeyDown is the same as OnChar
909 // TODO: filter modifier key presses from OnChar
910 keyEvent
.SetEventType(wxEVT_KEY_DOWN
);
912 // Only process OnChar if OnKeyDown didn't swallow it
913 if (!frame
->GetEventHandler()->ProcessEvent (keyEvent
))
915 keyEvent
.SetEventType(wxEVT_CHAR
);
916 frame
->GetEventHandler()->ProcessEvent(keyEvent
);
922 *continueToDispatch
= True
;