#include "wx/dnd.h"
#endif
+// DoSetSizeIntr and CanvasSetSizeIntr
+// PROBLEM:
+// under Motif composite controls (such as wxCalendarCtrl or generic wxSpinCtrl
+// don't work and/or segfault because
+// 1) wxWindow::Create calls SetSize,
+// which results in a call to DoSetSize much earlier than in the other ports
+// 2) if wxWindow::Create is called (wxControl::Create calls it)
+// then DoSetSize is never called, causing layout problems in composite
+// controls
+//
+// SOLUTION:
+// 1) don't call SetSize, DoSetSize, DoMoveWindow, DoGetPosition,
+// DoSetPosition directly or indirectly from wxWindow::Create
+// 2) call DoMoveWindow from DoSetSize, allowing controls to override it,
+// but make wxWindow::DoMoveWindow a no-op if it is called from
+// an overridden DoMoveWindow (i.e. wxFoo::DoMoveWindow calls
+// wxWindow::DoMoveWindow; this is to preserve the behaviour
+// before this change
+
#ifdef __VMS__
#pragma message disable nosimpint
#endif
}
}
-bool wxWindow::MapOrUnmap(WXWidget widget, bool map)
+bool wxWindow::MapOrUnmap(WXWidget widget, bool domap)
{
Widget w = (Widget)widget;
if ( !w )
return FALSE;
- if ( map )
+ if ( domap )
XtMapWidget(w);
else
XtUnmapWidget(w);
+ // Rationale: a lot of common operations (including but not
+ // limited to moving, resizing and appending items to a listbox)
+ // unmamange the widget, do their work, then manage it again.
+ // This means that, for example adding an item to a listbox will show it,
+ // or that most controls are shown every time they are moved or resized!
+ XtSetMappedWhenManaged( w, domap );
+
return TRUE;
}
// sample).
SetCursor(*wxSTANDARD_CURSOR);
SetFont(wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT));
- SetSize(pos.x, pos.y, size.x, size.y);
-
+ DoSetSizeIntr(pos.x, pos.y, size.x,size.y, wxSIZE_AUTO, TRUE);
return TRUE;
}
wxWindow::~wxWindow()
{
if (g_captureWindow == this)
- g_captureWindow = NULL;
+ g_captureWindow = NULL;
m_isBeingDeleted = TRUE;
if (w)
{
XtDestroyWidget(w);
- m_drawingArea = (WXWidget) 0;
+ m_drawingArea = (WXWidget) 0;
}
// Only if we're _really_ a canvas (not a dialog box/panel)
if (m_hScrollBar)
{
wxDeleteWindowFromTable((Widget) m_hScrollBar);
- XtUnmanageChild((Widget) m_hScrollBar);
+ XtUnmanageChild((Widget) m_hScrollBar);
}
if (m_vScrollBar)
{
wxDeleteWindowFromTable((Widget) m_vScrollBar);
- XtUnmanageChild((Widget) m_vScrollBar);
+ XtUnmanageChild((Widget) m_vScrollBar);
}
if (m_hScrollBar)
- XtDestroyWidget((Widget) m_hScrollBar);
+ XtDestroyWidget((Widget) m_hScrollBar);
if (m_vScrollBar)
- XtDestroyWidget((Widget) m_vScrollBar);
+ XtDestroyWidget((Widget) m_vScrollBar);
UnmanageAndDestroy(m_scrolledWindow);
Widget scrollBar = (Widget)GetScrollbar((wxOrientation)orient);
wxCHECK_MSG( scrollBar, 0, "no such scrollbar" );
- int range;
- XtVaGetValues(scrollBar, XmNmaximum, &range, NULL);
+ int range = 0;
+ if (scrollBar)
+ XtVaGetValues(scrollBar, XmNmaximum, &range, NULL);
return range;
}
while (cnode)
{
wxWindow *child = (wxWindow*) cnode->Data();
- int sx = 0;
- int sy = 0;
- child->GetSize( &sx, &sy );
+ int sx = 0;
+ int sy = 0;
+ child->GetSize( &sx, &sy );
wxPoint pos( child->GetPosition() );
- child->SetSize( pos.x + dx, pos.y + dy, sx, sy, wxSIZE_ALLOW_MINUS_ONE );
- cnode = cnode->Next();
+ child->SetSize( pos.x + dx, pos.y + dy, sx, sy, wxSIZE_ALLOW_MINUS_ONE );
+ cnode = cnode->Next();
}
int x1 = (dx >= 0) ? x : x - dx;
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
+ // the menu has been dismissed and the widgets cleaned up.
+ // In other words, once this routine returns, it is safe to delete
+ // the menu object.
+ // Ian Brown <ian.brown@printsoft.de>
+ 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
+ }
+ }
+ }
return TRUE;
}
}
void wxWindow::DoSetSize(int x, int y, int width, int height, int sizeFlags)
+{
+ DoSetSizeIntr(x, y, width, height, sizeFlags, FALSE);
+}
+
+void wxWindow::DoSetSizeIntr(int x, int y, int width, int height,
+ int sizeFlags, bool fromCtor)
{
// A bit of optimization to help sort out the flickers.
- int oldX, oldY, oldW, oldH;
- GetSize(& oldW, & oldH);
- GetPosition(& oldX, & oldY);
+ int oldX = -1, oldY = -1, oldW = -1, oldH = -1;
+ if( !fromCtor )
+ {
+ GetSize(& oldW, & oldH);
+ GetPosition(& oldX, & oldY);
+ }
if ( !(sizeFlags & wxSIZE_ALLOW_MINUS_ONE) )
{
{
if (m_drawingArea)
{
- CanvasSetSize(x, y, width, height, sizeFlags);
+ CanvasSetSizeIntr(x, y, width, height, sizeFlags, fromCtor);
+ if( !fromCtor ) DoMoveWindow(x, y, width, height);
return;
}
void wxWindow::DoMoveWindow(int x, int y, int width, int height)
{
+ // see the top of the file, near DoSetSizeIntr
+ if (m_drawingArea)
+ return;
+
+ if (width == 0)
+ width = 1;
+ if (height == 0)
+ height = 1;
+
XtVaSetValues((Widget)GetTopWidget(),
XmNx, x,
XmNy, y,
wxCHECK_RET( fontToUse->Ok(), "valid window font needed" );
- WXFontStructPtr pFontStruct = theFont->GetFontStruct(1.0, GetXDisplay());
+ WXFontStructPtr pFontStruct = fontToUse->GetFontStruct(1.0, GetXDisplay());
int direction, ascent, descent2;
XCharStruct overall;
if (entry->MatchesEvent(event))
{
// Bingo, we have a match. Now find a control that matches the
- // entry command id.
+ // entry command id.
// Need to go up to the top of the window hierarchy, since it might
// be e.g. a menu item
}
case KeyPress:
{
- KeySym keySym;
- static char buf[100];
-#if 0
- XComposeStatus compose;
- (void) XLookupString ((XKeyEvent *) & local_event, buf, 20, &keySym, &compose);
-#endif // 0
-
- (void) XLookupString ((XKeyEvent *) & local_event, buf, 20, &keySym, NULL);
- int id = wxCharCodeXToWX (keySym);
-
- wxEventType eventType = wxEVT_CHAR;
-
- wxKeyEvent event (eventType);
-
- if (local_event.xkey.state & ShiftMask)
- event.m_shiftDown = TRUE;
- if (local_event.xkey.state & ControlMask)
- event.m_controlDown = TRUE;
- if (local_event.xkey.state & Mod3Mask)
- event.m_altDown = TRUE;
- if (local_event.xkey.state & Mod1Mask)
- event.m_metaDown = TRUE;
- event.SetEventObject(canvas);
- event.m_keyCode = id;
- event.SetTimestamp(local_event.xkey.time);
-
- if (id > -1)
+ wxKeyEvent event (wxEVT_CHAR);
+ if (wxTranslateKeyEvent (event, canvas, (Widget) 0, &local_event))
{
// Implement wxFrame::OnCharHook by checking ancestor.
wxWindow *parent = canvas->GetParent();
}
case KeyRelease:
{
- static char buf[100];
- KeySym keySym;
- (void) XLookupString ((XKeyEvent *) & local_event, buf, 20, &keySym, NULL);
- int id = wxCharCodeXToWX (keySym);
-
wxKeyEvent event (wxEVT_KEY_UP);
-
- if (local_event.xkey.state & ShiftMask)
- event.m_shiftDown = TRUE;
- if (local_event.xkey.state & ControlMask)
- event.m_controlDown = TRUE;
- if (local_event.xkey.state & Mod3Mask)
- event.m_altDown = TRUE;
- if (local_event.xkey.state & Mod1Mask)
- event.m_metaDown = TRUE;
- event.SetEventObject(canvas);
- event.m_keyCode = id;
- event.SetTimestamp(local_event.xkey.time);
-
- if (id > -1)
+ if (wxTranslateKeyEvent (event, canvas, (Widget) 0, &local_event))
{
canvas->GetEventHandler()->ProcessEvent (event);
}
// CanvaseXXXSize() functions
// ----------------------------------------------------------------------------
+void wxWindow::CanvasSetSize(int x, int y, int w, int h, int sizeFlags)
+{
+ CanvasSetSizeIntr(x, y, w, h, sizeFlags, FALSE);
+}
+
// SetSize, but as per old wxCanvas (with drawing widget etc.)
-void wxWindow::CanvasSetSize (int x, int y, int w, int h, int sizeFlags)
+void wxWindow::CanvasSetSizeIntr(int x, int y, int w, int h, int sizeFlags,
+ bool fromCtor)
{
// A bit of optimization to help sort out the flickers.
- int oldX, oldY, oldW, oldH;
- GetSize(& oldW, & oldH);
- GetPosition(& oldX, & oldY);
+ int oldX = -1, oldY = -1, oldW = -1, oldH = -1;
+ // see the top of the file, near DoSetSizeIntr
+ if( !fromCtor )
+ {
+ GetSize(& oldW, & oldH);
+ GetPosition(& oldX, & oldY);
+ }
bool useOldPos = FALSE;
bool useOldSize = FALSE;
#endif // 0
(void) XLookupString ((XKeyEvent *) xevent, buf, 20, &keySym, NULL);
int id = wxCharCodeXToWX (keySym);
+ // id may be WXK_xxx code - these are outside ASCII range, so we
+ // can't just use toupper() on id
+ if (id >= 'a' && id <= 'z')
+ id = toupper(id);
if (xevent->xkey.state & ShiftMask)
wxevent.m_shiftDown = TRUE;
int width, height, width1, height1;
GetSize(& width, & height);
- // lesstif 0.87 hangs here
-#ifndef LESSTIF_VERSION
+ // lesstif 0.87 hangs here, but 0.93 does not
+#if !defined(LESSTIF_VERSION) \
+ || (defined(LesstifVersion) && LesstifVersion >= 93)
XtVaSetValues (w,
XmNfontList, (XmFontList) m_font.GetFontList(1.0, XtDisplay(w)),
NULL);
unsigned int maskReturn;
XQueryPointer (display,
- rootWindow,
- &rootReturn,
+ rootWindow,
+ &rootReturn,
&childReturn,
&rootX, &rootY, &winX, &winY, &maskReturn);
return wxPoint(rootX, rootY);