X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/c75e66953f7e46b9a488fd5a4aa1ec726621b13f..00421206821da3373ddc075d63149826b3be38af:/src/motif/dialog.cpp diff --git a/src/motif/dialog.cpp b/src/motif/dialog.cpp index 3aad3f823b..41d930d7f1 100644 --- a/src/motif/dialog.cpp +++ b/src/motif/dialog.cpp @@ -42,7 +42,6 @@ #include "wx/motif/private.h" static void wxCloseDialogCallback(Widget widget, XtPointer client_data, XmAnyCallbackStruct *cbs); -static void wxDialogBoxRepaintProc(Widget w, XtPointer c_data, XEvent *event, char *); static void wxDialogBoxEventHandler (Widget wid, XtPointer client_data, XEvent* event, @@ -231,7 +230,7 @@ bool wxDialog::Create(wxWindow *parent, wxWindowID id, SetSize(pos.x, pos.y, size.x, size.y); } XtAddEventHandler(dialogShell,ExposureMask,FALSE, - wxDialogBoxRepaintProc, (XtPointer) this); + wxUniversalRepaintProc, (XtPointer) this); XtAddEventHandler(dialogShell, ButtonPressMask | ButtonReleaseMask | PointerMotionMask | KeyPressMask, @@ -259,6 +258,10 @@ void wxDialog::SetModal(bool flag) wxDialog::~wxDialog() { + if (m_mainWidget) + XtRemoveEventHandler((Widget) m_mainWidget, ExposureMask, FALSE, + wxUniversalRepaintProc, (XtPointer) this); + m_modalShowing = FALSE; if (!wxUSE_INVISIBLE_RESIZE && m_mainWidget) { @@ -285,26 +288,16 @@ wxDialog::~wxDialog() // but I think this should work, if we destroy the children first. // Note that this might need to be done for wxFrame also. DestroyChildren(); - - // This causes a crash in e.g. the resource sample when closing - // the example dialog. TODO: Probably not necessary (?) -#if 0 - // Now process all events, because otherwise - // this might remain on the screen. - Display* display; - if (m_mainWidget) - display = XtDisplay((Widget) m_mainWidget); - else - display = (Display*) wxGetDisplay(); - - XSync(display, FALSE); - XEvent event; - while (XtAppPending((XtAppContext) wxTheApp->GetAppContext())) { - XFlush(display); - XtAppNextEvent((XtAppContext) wxTheApp->GetAppContext(), &event); - XtDispatchEvent(&event); + + // The idea about doing it here is that if you have to remove the + // XtDestroyWidget from ~wxWindow, at least top-level windows + // will still be deleted (and destroy children implicitly). + if (GetMainWidget()) + { + DetachWidget(GetMainWidget()); // Removes event handlers + XtDestroyWidget((Widget) GetMainWidget()); + SetMainWidget((WXWidget) NULL); } -#endif } // By default, pressing escape cancels the dialog @@ -342,19 +335,18 @@ XtVaGetValues((Widget) m_mainWidget, XmNiconic, &iconic, NULL); return FALSE; } -void wxDialog::SetSize(int x, int y, int width, int height, int sizeFlags) +void wxDialog::DoSetSize(int x, int y, int width, int height, int sizeFlags) { XtVaSetValues((Widget) m_mainWidget, XmNresizePolicy, XmRESIZE_ANY, NULL); - wxWindow::SetSize(x, y, width, height, sizeFlags); + wxWindow::DoSetSize(x, y, width, height, sizeFlags); XtVaSetValues((Widget) m_mainWidget, XmNresizePolicy, XmRESIZE_NONE, NULL); } -void wxDialog::SetClientSize(int width, int height) +void wxDialog::DoSetClientSize(int width, int height) { - SetSize(-1, -1, width, height); + wxWindow::SetSize(-1, -1, width, height); } - void wxDialog::SetTitle(const wxString& title) { m_dialogTitle = title; @@ -564,35 +556,34 @@ void wxDialog::OnCancel(wxCommandEvent& WXUNUSED(event)) } } -bool wxDialog::OnClose() +void wxDialog::OnCloseWindow(wxCloseEvent& event) { - // Behaviour changed in 2.0: we'll send a Cancel message by default, + // We'll send a Cancel message by default, // which may close the dialog. - // Check for looping if the Cancel event handler calls Close() - + // Check for looping if the Cancel event handler calls Close(). + + // Note that if a cancel button and handler aren't present in the dialog, + // nothing will happen when you close the dialog via the window manager, or + // via Close(). + // We wouldn't want to destroy the dialog by default, since the dialog may have been + // created on the stack. + // However, this does mean that calling dialog->Close() won't delete the dialog + // unless the handler for wxID_CANCEL does so. So use Destroy() if you want to be + // sure to destroy the dialog. + // The default OnCancel (above) simply ends a modal dialog, and hides a modeless dialog. + static wxList closing; if ( closing.Member(this) ) - return FALSE; + return; closing.Append(this); wxCommandEvent cancelEvent(wxEVT_COMMAND_BUTTON_CLICKED, wxID_CANCEL); cancelEvent.SetEventObject( this ); - GetEventHandler()->ProcessEvent(cancelEvent); - - closing.DeleteObject(this); - - return FALSE; -} + GetEventHandler()->ProcessEvent(cancelEvent); // This may close the dialog -void wxDialog::OnCloseWindow(wxCloseEvent& event) -{ - // Compatibility - if ( GetEventHandler()->OnClose() || event.GetForce()) - { - this->Destroy(); - } + closing.DeleteObject(this); } // Destroy the window (delayed, if a managed window) @@ -611,6 +602,7 @@ void wxDialog::OnSysColourChanged(wxSysColourChangedEvent& WXUNUSED(event)) void wxDialog::Fit() { + wxWindow::Fit(); } // Handle a close event from the window manager @@ -625,47 +617,7 @@ static void wxCloseDialogCallback( Widget WXUNUSED(widget), XtPointer client_dat dialog->GetEventHandler()->ProcessEvent(closeEvent); } -// TODO: Preferably, we should have a universal repaint proc. -// Meanwhile, use a special one for dialogs. -static void wxDialogBoxRepaintProc(Widget w, XtPointer WXUNUSED(c_data), XEvent *event, char *) -{ - Window window; - Display *display; - - wxWindow* win = (wxWindow *)wxWidgetHashTable->Get((long)w); - if (!win) - return; - - switch(event -> type) - { - case Expose : - { - window = (Window) win -> GetXWindow(); - display = (Display *) win -> GetXDisplay(); - - wxRect* rect = new wxRect(event->xexpose.x, event->xexpose.y, - event->xexpose.width, event->xexpose.height); - win->m_updateRects.Append((wxObject*) rect); - - if (event -> xexpose.count == 0) - { - wxPaintEvent event(win->GetId()); - event.SetEventObject(win); - win->GetEventHandler()->ProcessEvent(event); - - win->ClearUpdateRects(); - } - break; - } - default : - { - cout << "\n\nNew Event ! is = " << event -> type << "\n"; - break; - } - } -} - -static void wxDialogBoxEventHandler (Widget wid, +void wxDialogBoxEventHandler (Widget wid, XtPointer WXUNUSED(client_data), XEvent* event, Boolean *continueToDispatch) @@ -699,8 +651,16 @@ static void wxDialogBoxEventHandler (Widget wid, } else { - keyEvent.SetEventType(wxEVT_CHAR); - dialog->GetEventHandler()->ProcessEvent(keyEvent); + // For simplicity, OnKeyDown is the same as OnChar + // TODO: filter modifier key presses from OnChar + keyEvent.SetEventType(wxEVT_KEY_DOWN); + + // Only process OnChar if OnKeyDown didn't swallow it + if (!dialog->GetEventHandler()->ProcessEvent (keyEvent)) + { + keyEvent.SetEventType(wxEVT_CHAR); + dialog->GetEventHandler()->ProcessEvent(keyEvent); + } } } }