X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/83df96d63a52ebb08b9e32549dc255354b4a18d0..409521e45d44fc57df39efcb965701d378edcb20:/src/x11/toplevel.cpp?ds=inline diff --git a/src/x11/toplevel.cpp b/src/x11/toplevel.cpp index 14b660afe3..384b7ae317 100644 --- a/src/x11/toplevel.cpp +++ b/src/x11/toplevel.cpp @@ -1,13 +1,13 @@ -///////////////////////////////////////////////////////////////////////////// -// Name: motif/frame.cpp -// Purpose: wxFrame +/////////////////////////////////////////////////////////////////////////////// +// Name: src/x11/toplevel.cpp +// Purpose: implements wxTopLevelWindow for X11 // Author: Julian Smart // Modified by: -// Created: 17/09/98 +// Created: 24.09.01 // RCS-ID: $Id$ -// Copyright: (c) Julian Smart -// Licence: wxWindows licence -///////////////////////////////////////////////////////////////////////////// +// Copyright: (c) 2002 Julian Smart +// License: wxWindows licence +/////////////////////////////////////////////////////////////////////////////// // ============================================================================ // declarations @@ -17,395 +17,235 @@ // headers // ---------------------------------------------------------------------------- -#ifdef __GNUG__ - #pragma implementation "frame.h" -#endif - +// For compilers that support precompilation, includes "wx.h". +#include "wx/wxprec.h" -#ifdef __VMS -#define XtDisplay XTDISPLAY -#define XtWindow XTWINDOW -#define XtScreen XTSCREEN +#ifdef __BORLANDC__ + #pragma hdrstop #endif -# include "wx/frame.h" -#include "wx/statusbr.h" -#include "wx/toolbar.h" -#include "wx/menuitem.h" -#include "wx/menu.h" -#include "wx/dcclient.h" -#include "wx/dialog.h" -#include "wx/settings.h" -#include "wx/app.h" -#include "wx/utils.h" -#include "wx/log.h" - -#ifdef __VMS__ - #pragma message disable nosimpint -#endif +#include "wx/toplevel.h" -#if defined(__ultrix) || defined(__sgi) - #include -#endif +#ifndef WX_PRECOMP + #include "wx/app.h" + #include "wx/string.h" + #include "wx/log.h" + #include "wx/intl.h" + #include "wx/frame.h" + #include "wx/menu.h" + #include "wx/statusbr.h" + #include "wx/settings.h" +#endif //WX_PRECOMP -#include -#include -#if XmVersion >= 1002 - #include -#else - #include -#endif -#include -#include -#include -#include -#include -#include -#include -#include -#include -#if XmVersion > 1000 - #include -#endif +#include "wx/x11/private.h" +#include "X11/Xutil.h" -#ifdef __VMS__ - #pragma message enable nosimpint -#endif +#include "wx/unix/utilsx11.h" -#include "wx/motif/private.h" +bool wxMWMIsRunning(Window w); // ---------------------------------------------------------------------------- -// private functions +// wxTopLevelWindowX11 creation // ---------------------------------------------------------------------------- -static void wxFrameEventHandler(Widget wid, - XtPointer WXUNUSED(client_data), - XEvent* event, - Boolean* continueToDispatch); -static void wxCloseFrameCallback(Widget, XtPointer, XmAnyCallbackStruct *cbs); -static void wxFrameFocusProc(Widget workArea, XtPointer clientData, - XmAnyCallbackStruct *cbs); -static void wxFrameMapProc(Widget frameShell, XtPointer clientData, - XCrossingEvent * event); - -// ---------------------------------------------------------------------------- -// globals -// ---------------------------------------------------------------------------- +void wxTopLevelWindowX11::Init() +{ + m_iconized = + m_maximizeOnShow = false; -extern wxList wxModelessWindows; -extern wxList wxPendingDelete; + // unlike (almost?) all other windows, frames are created hidden + m_isShown = false; -// TODO: this should be tidied so that any frame can be the -// top frame -static bool wxTopLevelUsed = FALSE; + // Data to save/restore when calling ShowFullScreen + m_fsStyle = 0; + m_fsIsMaximized = false; + m_fsIsShowing = false; -// ---------------------------------------------------------------------------- -// wxWin macros -// ---------------------------------------------------------------------------- + m_needResizeInIdle = false; -BEGIN_EVENT_TABLE(wxFrame, wxFrameBase) - EVT_ACTIVATE(wxFrame::OnActivate) - EVT_SYS_COLOUR_CHANGED(wxFrame::OnSysColourChanged) -END_EVENT_TABLE() + m_x = wxDefaultCoord; + m_y = wxDefaultCoord; + m_width = 20; + m_height = 20; +} -IMPLEMENT_DYNAMIC_CLASS(wxFrame, wxWindow) +bool wxTopLevelWindowX11::Create(wxWindow *parent, + wxWindowID id, + const wxString& title, + const wxPoint& pos, + const wxSize& size, + long style, + const wxString& name) +{ + // init our fields + Init(); -// ============================================================================ -// implementation -// ============================================================================ + m_windowStyle = style; + m_parent = parent; -// ---------------------------------------------------------------------------- -// frame construction -// ---------------------------------------------------------------------------- + SetName(name); -void wxFrame::Init() -{ - m_iconized = FALSE; - - //// Motif-specific - m_frameShell = (WXWidget) NULL; - m_frameWidget = (WXWidget) NULL;; - m_workArea = (WXWidget) NULL;; - m_clientArea = (WXWidget) NULL;; - m_visibleStatus = TRUE; -} + m_windowId = id == wxID_ANY ? NewControlId() : id; -bool wxFrame::Create(wxWindow *parent, - wxWindowID id, - const wxString& title, - const wxPoint& pos, - const wxSize& size, - long style, - const wxString& name) -{ - if ( parent ) + if (parent) parent->AddChild(this); - else - wxTopLevelWindows.Append(this); - wxModelessWindows.Append(this); + wxTopLevelWindows.Append(this); - SetName(name); + Display *xdisplay = wxGlobalDisplay(); + int xscreen = DefaultScreen( xdisplay ); + Visual *xvisual = DefaultVisual( xdisplay, xscreen ); + Window xparent = RootWindow( xdisplay, xscreen ); + Colormap cm = DefaultColormap( xdisplay, xscreen ); - m_windowStyle = style; + if (GetExtraStyle() & wxTOPLEVEL_EX_DIALOG) + m_backgroundColour = wxSystemSettings::GetColour(wxSYS_COLOUR_BTNFACE); + else + m_backgroundColour = wxSystemSettings::GetColour(wxSYS_COLOUR_APPWORKSPACE); + m_backgroundColour.CalcPixel( (WXColormap) cm ); + m_hasBgCol = true; - m_backgroundColour = wxSystemSettings::GetColour(wxSYS_COLOUR_APPWORKSPACE); - m_foregroundColour = *wxBLACK; - m_font = wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT); + m_x = pos.x; + if (m_x < -1) + m_x = 10; - if ( id > -1 ) - m_windowId = id; - else - m_windowId = (int)NewControlId(); + m_y = pos.y; + if (m_y < 0) + m_y = 10; - int x = pos.x, y = pos.y; - int width = size.x, height = size.y; + m_width = size.x; + if (m_width < 0) + m_width = 500; - // Set reasonable values for position and size if defaults have been - // requested - // - // MB TODO: something better than these arbitrary values ? - // VZ should use X resources for this... - if ( width == -1 ) - width = 400; - if ( height == -1 ) - height = 400; + m_height = size.y; + if (m_height < 0) + m_height = 380; - int displayW, displayH; - wxDisplaySize( &displayW, &displayH ); +#if !wxUSE_NANOX + XSetWindowAttributes xattributes; - if ( x == -1 ) - { - x = (displayW - width) / 2; - if (x < 10) x = 10; - } - if ( y == -1 ) - { - y = (displayH - height) / 2; - if (y < 10) y = 10; - } + long xattributes_mask = + CWBorderPixel | CWBackPixel; + + xattributes.background_pixel = m_backgroundColour.GetPixel(); + xattributes.border_pixel = BlackPixel( xdisplay, xscreen ); - // VZ: what does this do?? - if (wxTopLevelUsed) + if (HasFlag( wxNO_BORDER )) { - // Change suggested by Matthew Flatt - m_frameShell = (WXWidget)XtAppCreateShell - ( - name, - wxTheApp->GetClassName(), - topLevelShellWidgetClass, - (Display*) wxGetDisplay(), - NULL, - 0 - ); + xattributes_mask |= CWOverrideRedirect; + xattributes.override_redirect = True; } - else - { - m_frameShell = wxTheApp->GetTopLevelWidget(); - wxTopLevelUsed = TRUE; - } - - XtVaSetValues((Widget) m_frameShell, - // Allows menu to resize - XmNallowShellResize, True, - XmNdeleteResponse, XmDO_NOTHING, - XmNmappedWhenManaged, False, - XmNiconic, (style & wxICONIZE) ? TRUE : FALSE, - NULL); - - if (!title.IsEmpty()) - XtVaSetValues((Widget) m_frameShell, - XmNtitle, title.c_str(), - NULL); - - m_frameWidget = (WXWidget) XtVaCreateManagedWidget("main_window", - xmMainWindowWidgetClass, (Widget) m_frameShell, - XmNresizePolicy, XmRESIZE_NONE, - NULL); - - m_workArea = (WXWidget) XtVaCreateWidget("form", - xmFormWidgetClass, (Widget) m_frameWidget, - XmNresizePolicy, XmRESIZE_NONE, - NULL); - - m_clientArea = (WXWidget) XtVaCreateWidget("client", - xmBulletinBoardWidgetClass, (Widget) m_workArea, - XmNmarginWidth, 0, - XmNmarginHeight, 0, - XmNrightAttachment, XmATTACH_FORM, - XmNleftAttachment, XmATTACH_FORM, - XmNtopAttachment, XmATTACH_FORM, - XmNbottomAttachment, XmATTACH_FORM, - // XmNresizePolicy, XmRESIZE_ANY, - NULL); - - wxLogTrace(wxTRACE_Messages, - "Created frame (0x%08x) with work area 0x%08x and client " - "area 0x%08x", m_frameWidget, m_workArea, m_clientArea); - - XtAddEventHandler((Widget) m_clientArea, ExposureMask,FALSE, - wxUniversalRepaintProc, (XtPointer) this); - - XtAddEventHandler((Widget) m_clientArea, - ButtonPressMask | ButtonReleaseMask | PointerMotionMask | KeyPressMask, - FALSE, - wxFrameEventHandler, - (XtPointer)this); - - XtVaSetValues((Widget) m_frameWidget, - XmNworkWindow, (Widget) m_workArea, - NULL); - - XtManageChild((Widget) m_clientArea); - XtManageChild((Widget) m_workArea); - - wxAddWindowToTable((Widget) m_workArea, this); - wxAddWindowToTable((Widget) m_clientArea, this); - - XtTranslations ptr; - - XtOverrideTranslations((Widget) m_workArea, - ptr = XtParseTranslationTable(": resize()")); - - XtFree((char *)ptr); - - XtAddCallback((Widget) m_workArea, XmNfocusCallback, - (XtCallbackProc)wxFrameFocusProc, (XtPointer)this); - - /* Part of show-&-hide fix */ - XtAddEventHandler((Widget) m_frameShell, StructureNotifyMask, - False, (XtEventHandler)wxFrameMapProc, - (XtPointer)m_workArea); - - if (x > -1) - XtVaSetValues((Widget) m_frameShell, XmNx, x, NULL); - if (y > -1) - XtVaSetValues((Widget) m_frameShell, XmNy, y, NULL); - if (width > -1) - XtVaSetValues((Widget) m_frameShell, XmNwidth, width, NULL); - if (height > -1) - XtVaSetValues((Widget) m_frameShell, XmNheight, height, NULL); - - m_mainWidget = m_frameWidget; - - ChangeFont(FALSE); - - // This patch comes from Torsten Liermann lier@lier1.muc.de - if (XmIsMotifWMRunning( (Widget) m_frameShell )) - { - int decor = 0; - if (style & wxRESIZE_BORDER) - decor |= MWM_DECOR_RESIZEH; - if (style & wxSYSTEM_MENU) - decor |= MWM_DECOR_MENU; - if ((style & wxCAPTION) || - (style & wxTINY_CAPTION_HORIZ) || - (style & wxTINY_CAPTION_VERT)) - decor |= MWM_DECOR_TITLE; - if (style & wxTHICK_FRAME) - decor |= MWM_DECOR_BORDER; - if (style & wxTHICK_FRAME) - decor |= MWM_DECOR_BORDER; - if (style & wxMINIMIZE_BOX) - decor |= MWM_DECOR_MINIMIZE; - if (style & wxMAXIMIZE_BOX) - decor |= MWM_DECOR_MAXIMIZE; - XtVaSetValues((Widget) m_frameShell,XmNmwmDecorations,decor,NULL); - } - // This allows non-Motif window managers to support at least the - // no-decorations case. - else + + if (!HasFlag( wxFULL_REPAINT_ON_RESIZE )) { - if (style == 0) - XtVaSetValues((Widget) m_frameShell,XmNoverrideRedirect,TRUE,NULL); + xattributes_mask |= CWBitGravity; + xattributes.bit_gravity = NorthWestGravity; } - XtRealizeWidget((Widget) m_frameShell); - // Intercept CLOSE messages from the window manager - Atom WM_DELETE_WINDOW = XmInternAtom(XtDisplay((Widget) m_frameShell), "WM_DELETE_WINDOW", False); -#if (XmREVISION > 1 || XmVERSION > 1) - XmAddWMProtocolCallback((Widget) m_frameShell, WM_DELETE_WINDOW, (XtCallbackProc) wxCloseFrameCallback, (XtPointer)this); -#else -#if XmREVISION == 1 - XmAddWMProtocolCallback((Widget) m_frameShell, WM_DELETE_WINDOW, (XtCallbackProc) wxCloseFrameCallback, (caddr_t)this); -#else - XmAddWMProtocolCallback((Widget) m_frameShell, WM_DELETE_WINDOW, (void (*)())wxCloseFrameCallback, (caddr_t)this); -#endif -#endif + xattributes_mask |= CWEventMask; + xattributes.event_mask = + ExposureMask | KeyPressMask | KeyReleaseMask | ButtonPressMask | ButtonReleaseMask | + ButtonMotionMask | EnterWindowMask | LeaveWindowMask | PointerMotionMask | + KeymapStateMask | FocusChangeMask | ColormapChangeMask | StructureNotifyMask | + PropertyChangeMask; - ChangeBackgroundColour(); - - PreResize(); - - wxSizeEvent sizeEvent(wxSize(width, height), GetId()); - sizeEvent.SetEventObject(this); + Window xwindow = XCreateWindow( xdisplay, xparent, m_x, m_y, m_width, m_height, + 0, DefaultDepth(xdisplay,xscreen), InputOutput, xvisual, xattributes_mask, &xattributes ); +#else + long backColor, foreColor; + backColor = GR_RGB(m_backgroundColour.Red(), m_backgroundColour.Green(), m_backgroundColour.Blue()); + foreColor = GR_RGB(m_foregroundColour.Red(), m_foregroundColour.Green(), m_foregroundColour.Blue()); - GetEventHandler()->ProcessEvent(sizeEvent); + Window xwindow = XCreateWindowWithColor( xdisplay, xparent, m_x, m_y, m_width, m_height, + 0, 0, InputOutput, xvisual, backColor, foreColor); +#endif - return TRUE; -} + m_mainWindow = (WXWindow) xwindow; + m_clientWindow = (WXWindow) xwindow; + wxAddWindowToTable( xwindow, (wxWindow*) this ); + +#if wxUSE_NANOX + XSelectInput( xdisplay, xwindow, + GR_EVENT_MASK_CLOSE_REQ | + ExposureMask | + KeyPressMask | + KeyReleaseMask | + ButtonPressMask | + ButtonReleaseMask | + ButtonMotionMask | + EnterWindowMask | + LeaveWindowMask | + PointerMotionMask | + KeymapStateMask | + FocusChangeMask | + ColormapChangeMask | + StructureNotifyMask | + PropertyChangeMask + ); +#endif -wxFrame::~wxFrame() -{ - m_isBeingDeleted = TRUE; + // Set background to None which will prevent X11 from clearing the + // background completely. + XSetWindowBackgroundPixmap( xdisplay, xwindow, None ); - if (m_clientArea) +#if !wxUSE_NANOX + if (HasFlag( wxSTAY_ON_TOP )) { - XtRemoveEventHandler((Widget) m_clientArea, ExposureMask, FALSE, - wxUniversalRepaintProc, (XtPointer) this); - XtRemoveEventHandler((Widget) m_clientArea, ButtonPressMask | ButtonReleaseMask | PointerMotionMask | KeyPressMask, - FALSE, - wxFrameEventHandler, (XtPointer) this); - wxDeleteWindowFromTable((Widget) m_clientArea); + Window xroot = RootWindow( xdisplay, xscreen ); + XSetTransientForHint( xdisplay, xwindow, xroot ); } - - if (GetMainWidget()) - Show(FALSE); - - if (m_frameMenuBar) + else { - m_frameMenuBar->DestroyMenuBar(); - - // Hack to stop core dump on Ultrix, OSF, for some strange reason. -#if MOTIF_MENUBAR_DELETE_FIX - GetMenuBar()->SetMainWidget((WXWidget) NULL); -#endif - delete m_frameMenuBar; - m_frameMenuBar = NULL; + if (GetExtraStyle() & wxTOPLEVEL_EX_DIALOG) + { + if (GetParent() && GetParent()->GetMainWindow()) + { + Window xparentwindow = (Window) GetParent()->GetMainWindow(); + XSetTransientForHint( xdisplay, xwindow, xparentwindow ); + } + } } - wxTopLevelWindows.DeleteObject(this); - wxModelessWindows.DeleteObject(this); - - if (m_frameStatusBar) + XSizeHints size_hints; + size_hints.flags = PSize | PPosition | PWinGravity; + size_hints.x = m_x; + size_hints.y = m_y; + size_hints.width = m_width; + size_hints.height = m_height; + size_hints.win_gravity = NorthWestGravity; + XSetWMNormalHints( xdisplay, xwindow, &size_hints); + + XWMHints wm_hints; + wm_hints.flags = InputHint | StateHint; + if (GetParent()) { - delete m_frameStatusBar; - m_frameStatusBar = NULL; + wm_hints.flags |= WindowGroupHint; + wm_hints.window_group = (Window) GetParent()->GetMainWindow(); } + wm_hints.input = True; + wm_hints.initial_state = NormalState; + XSetWMHints( xdisplay, xwindow, &wm_hints); - DestroyChildren(); + Atom wm_protocols[2]; + wm_protocols[0] = XInternAtom( xdisplay, "WM_DELETE_WINDOW", False ); + wm_protocols[1] = XInternAtom( xdisplay, "WM_TAKE_FOCUS", False ); + XSetWMProtocols( xdisplay, xwindow, wm_protocols, 2); - if (m_workArea) - { - wxDeleteWindowFromTable((Widget) m_workArea); - - XtDestroyWidget ((Widget) m_workArea); - } +#endif - if (m_frameWidget) - { - wxDeleteWindowFromTable((Widget) m_frameWidget); - XtDestroyWidget ((Widget) m_frameWidget); - } + wxSetWMDecorations( xwindow, style); - if (m_frameShell) - XtDestroyWidget ((Widget) m_frameShell); + SetTitle(title); - SetMainWidget((WXWidget) NULL); + return true; +} - /* Check if it's the last top-level window */ +wxTopLevelWindowX11::~wxTopLevelWindowX11() +{ + wxTopLevelWindows.DeleteObject(this); - if (wxTheApp && (wxTopLevelWindows.Number() == 0)) + // If this is the last top-level window, exit. + if ( wxTheApp && (wxTopLevelWindows.GetCount() == 0) ) { wxTheApp->SetTopWindow(NULL); @@ -417,514 +257,539 @@ wxFrame::~wxFrame() } } -// Get size *available for subwindows* i.e. excluding menu bar, toolbar etc. -void wxFrame::DoGetClientSize(int *x, int *y) const +void wxTopLevelWindowX11::OnInternalIdle() { - Dimension xx, yy; - XtVaGetValues((Widget) m_workArea, XmNwidth, &xx, XmNheight, &yy, NULL); + wxWindow::OnInternalIdle(); - if (m_frameStatusBar) + // Do this only after the last idle event so that + // all windows have been updated before a new + // round of size events is sent + if (m_needResizeInIdle && !wxTheApp->Pending()) { - int sbw, sbh; - m_frameStatusBar->GetSize(& sbw, & sbh); - yy -= sbh; + wxSizeEvent event( GetClientSize(), GetId() ); + event.SetEventObject( this ); + GetEventHandler()->ProcessEvent( event ); + + m_needResizeInIdle = false; } -#if wxUSE_TOOLBAR - if (m_frameToolBar) - { - int tbw, tbh; - m_frameToolBar->GetSize(& tbw, & tbh); - if (m_frameToolBar->GetWindowStyleFlag() & wxTB_VERTICAL) - xx -= tbw; - else - yy -= tbh; - } -#endif // wxUSE_TOOLBAR - /* - if (GetMenuBar() != (wxMenuBar*) NULL) - { - // it seems that if a frame holds a panel, the menu bar size - // gets automatically taken care of --- grano@cs.helsinki.fi 4.4.95 - bool hasSubPanel = FALSE; - for(wxNode* node = GetChildren().First(); node; node = node->Next()) - { - wxWindow *win = (wxWindow *)node->Data(); - hasSubPanel = (win->IsKindOf(CLASSINFO(wxPanel)) && !win->IsKindOf(CLASSINFO(wxDialog))); - - if (hasSubPanel) - break; - } - if (! hasSubPanel) { - Dimension ys; - XtVaGetValues((Widget) GetMenuBarWidget(), XmNheight, &ys, NULL); - yy -= ys; - } - } - */ - - *x = xx; *y = yy; } -// Set the client size (i.e. leave the calculation of borders etc. -// to wxWindows) -void wxFrame::DoSetClientSize(int width, int height) -{ - // Calculate how large the new main window should be - // by finding the difference between the client area and the - // main window area, and adding on to the new client area - if (width > -1) - XtVaSetValues((Widget) m_workArea, XmNwidth, width, NULL); +// ---------------------------------------------------------------------------- +// wxTopLevelWindowX11 showing +// ---------------------------------------------------------------------------- - if (height > -1) +bool wxTopLevelWindowX11::Show(bool show) +{ + if (show) { - if (m_frameStatusBar) - { - int sbw, sbh; - m_frameStatusBar->GetSize(& sbw, & sbh); - height += sbh; - } -#if wxUSE_TOOLBAR - if (m_frameToolBar) - { - int tbw, tbh; - m_frameToolBar->GetSize(& tbw, & tbh); - if (m_frameToolBar->GetWindowStyleFlag() & wxTB_VERTICAL) - width += tbw; - else - height += tbh; - } -#endif // wxUSE_TOOLBAR + wxSizeEvent event(GetSize(), GetId()); + + event.SetEventObject(this); + GetEventHandler()->ProcessEvent(event); - XtVaSetValues((Widget) m_workArea, XmNheight, height, NULL); + m_needResizeInIdle = false; } - PreResize(); - wxSizeEvent sizeEvent(wxSize(width, height), GetId()); - sizeEvent.SetEventObject(this); + bool ret = wxWindowX11::Show(show); - GetEventHandler()->ProcessEvent(sizeEvent); + return ret; +} + +// ---------------------------------------------------------------------------- +// wxTopLevelWindowX11 maximize/minimize +// ---------------------------------------------------------------------------- +void wxTopLevelWindowX11::Maximize(bool WXUNUSED(maximize)) +{ + // TODO } -void wxFrame::DoGetSize(int *width, int *height) const +bool wxTopLevelWindowX11::IsMaximized() const { - Dimension xx, yy; - XtVaGetValues((Widget) m_frameShell, XmNwidth, &xx, XmNheight, &yy, NULL); - *width = xx; *height = yy; + // TODO + return true; } -void wxFrame::DoGetPosition(int *x, int *y) const +void wxTopLevelWindowX11::Iconize(bool iconize) { - Window parent_window = XtWindow((Widget) m_frameShell), - next_parent = XtWindow((Widget) m_frameShell), - root = RootWindowOfScreen(XtScreen((Widget) m_frameShell)); + if ( !iconize ) + { + Restore(); + return; + } - // search for the parent that is child of ROOT, because the WM may - // reparent twice and notify only the next parent (like FVWM) - while (next_parent != root) { - Window *theChildren; unsigned int n; - parent_window = next_parent; - XQueryTree(XtDisplay((Widget) m_frameShell), parent_window, &root, - &next_parent, &theChildren, &n); - XFree(theChildren); // not needed + if (!m_iconized && GetMainWindow()) + { + if (XIconifyWindow(wxGlobalDisplay(), + (Window) GetMainWindow(), DefaultScreen(wxGlobalDisplay())) != 0) + m_iconized = true; } - int xx, yy; unsigned int dummy; - XGetGeometry(XtDisplay((Widget) m_frameShell), parent_window, &root, - &xx, &yy, &dummy, &dummy, &dummy, &dummy); - if (x) *x = xx; - if (y) *y = yy; } -void wxFrame::DoSetSize(int x, int y, int width, int height, int WXUNUSED(sizeFlags)) +bool wxTopLevelWindowX11::IsIconized() const { - if (x > -1) - XtVaSetValues((Widget) m_frameShell, XmNx, x, NULL); - if (y > -1) - XtVaSetValues((Widget) m_frameShell, XmNy, y, NULL); - if (width > -1) - XtVaSetValues((Widget) m_frameWidget, XmNwidth, width, NULL); - if (height > -1) - XtVaSetValues((Widget) m_frameWidget, XmNheight, height, NULL); - - if (!(height == -1 && width == -1)) - { - PreResize(); - - wxSizeEvent sizeEvent(wxSize(width, height), GetId()); - sizeEvent.SetEventObject(this); + return m_iconized; +} - GetEventHandler()->ProcessEvent(sizeEvent); +void wxTopLevelWindowX11::Restore() +{ + // This is the way to deiconify the window, according to the X FAQ + if (m_iconized && GetMainWindow()) + { + XMapWindow(wxGlobalDisplay(), (Window) GetMainWindow()); + m_iconized = false; } } -bool wxFrame::Show(bool show) +// ---------------------------------------------------------------------------- +// wxTopLevelWindowX11 fullscreen +// ---------------------------------------------------------------------------- + +bool wxTopLevelWindowX11::ShowFullScreen(bool show, long style) { - if (!m_frameShell) - return wxWindow::Show(show); + if (show) + { + if (IsFullScreen()) + return false; - m_visibleStatus = show; /* show-&-hide fix */ + m_fsIsShowing = true; + m_fsStyle = style; - m_isShown = show; - if (show) { - XtMapWidget((Widget) m_frameShell); - XRaiseWindow(XtDisplay((Widget) m_frameShell), XtWindow((Widget) m_frameShell)); - } else { - XtUnmapWidget((Widget) m_frameShell); - // XmUpdateDisplay(wxTheApp->topLevel); // Experimental: may be responsible for crashes + // TODO + + return true; } - return TRUE; -} + else + { + if (!IsFullScreen()) + return false; -void wxFrame::Iconize(bool iconize) -{ - if (!iconize) - Show(TRUE); + m_fsIsShowing = false; - if (m_frameShell) - XtVaSetValues((Widget) m_frameShell, XmNiconic, (Boolean)iconize, NULL); + // TODO + return true; + } } -void wxFrame::Restore() -{ - if ( m_frameShell ) - XtVaSetValues((Widget) m_frameShell, XmNiconic, FALSE, NULL); -} +// ---------------------------------------------------------------------------- +// wxTopLevelWindowX11 misc +// ---------------------------------------------------------------------------- -void wxFrame::Maximize(bool maximize) +void wxTopLevelWindowX11::DoSetIcon(const wxIcon& icon) { - Show(TRUE); + if (icon.Ok() && GetMainWindow()) + { +#if !wxUSE_NANOX + XWMHints *wmHints = XAllocWMHints(); + wmHints->icon_pixmap = (Pixmap) icon.GetPixmap(); - if ( maximize ) - Restore(); + wmHints->flags = IconPixmapHint; + + if (icon.GetMask()) + { + wmHints->flags |= IconMaskHint; + wmHints->icon_mask = (Pixmap) icon.GetMask()->GetBitmap(); + } + + XSetWMHints(wxGlobalDisplay(), (Window) GetMainWindow(), wmHints); + XFree(wmHints); +#endif + } } -bool wxFrame::IsIconized() const +void wxTopLevelWindowX11::SetIcons(const wxIconBundle& icons ) { - if (!m_frameShell) - return FALSE; + // this sets m_icon + wxTopLevelWindowBase::SetIcons( icons ); - Boolean iconic; - XtVaGetValues((Widget) m_frameShell, XmNiconic, &iconic, NULL); - return iconic; + DoSetIcon( icons.GetIcon( -1 ) ); + wxSetIconsX11( wxGlobalDisplay(), GetMainWindow(), icons ); } -// Is it maximized? -bool wxFrame::IsMaximized() const +bool wxTopLevelWindowX11::SetShape(const wxRegion& region) { - // No maximizing in Motif (?) - return FALSE; + return wxDoSetShape( wxGlobalDisplay(), + (Window)GetMainWindow(), + region ); } -void wxFrame::SetTitle(const wxString& title) +void wxTopLevelWindowX11::SetTitle(const wxString& title) { - if (title == m_title) - return; - m_title = title; - if (!title.IsNull()) - XtVaSetValues((Widget) m_frameShell, - XmNtitle, title.c_str(), - XmNiconName, title.c_str(), - NULL); + if (GetMainWindow()) + { +#if wxUSE_UNICODE + // I wonder of e.g. Metacity takes UTF-8 here + XStoreName(wxGlobalDisplay(), (Window) GetMainWindow(), + (const char*) title.ToAscii() ); + XSetIconName(wxGlobalDisplay(), (Window) GetMainWindow(), + (const char*) title.ToAscii() ); +#else + XStoreName(wxGlobalDisplay(), (Window) GetMainWindow(), + (const char*) title); + XSetIconName(wxGlobalDisplay(), (Window) GetMainWindow(), + (const char*) title); +#endif + } } -void wxFrame::SetIcon(const wxIcon& icon) +wxString wxTopLevelWindowX11::GetTitle() const { - m_icon = icon; - - if (!m_frameShell) - return; - - if (!icon.Ok() || !icon.GetPixmap()) - return; - - XtVaSetValues((Widget) m_frameShell, XtNiconPixmap, icon.GetPixmap(), NULL); + return m_title; } -void wxFrame::PositionStatusBar() +// For implementation purposes - sometimes decorations make the client area +// smaller +wxPoint wxTopLevelWindowX11::GetClientAreaOrigin() const { - if (!m_frameStatusBar) - return; - - int w, h; - GetClientSize(&w, &h); - int sw, sh; - m_frameStatusBar->GetSize(&sw, &sh); - - // Since we wish the status bar to be directly under the client area, - // we use the adjusted sizes without using wxSIZE_NO_ADJUSTMENTS. - m_frameStatusBar->SetSize(0, h, w, sh); + // wxFrame::GetClientAreaOrigin + // does the required calculation already. + return wxPoint(0, 0); } -WXWidget wxFrame::GetMenuBarWidget() const +void wxTopLevelWindowX11::DoGetClientSize( int *width, int *height ) const { - if (GetMenuBar()) - return GetMenuBar()->GetMainWidget(); - else - return (WXWidget) NULL; + if (width) + *width = m_width; + if (height) + *height = m_height; } -void wxFrame::SetMenuBar(wxMenuBar *menuBar) +void wxTopLevelWindowX11::DoGetSize( int *width, int *height ) const { - if (!menuBar) - { - m_frameMenuBar = NULL; - return; - } - - // Currently can't set it twice - // wxASSERT_MSG( (m_frameMenuBar == (wxMenuBar*) NULL), "Cannot set the menubar more than once"); + // TODO add non-client size - if (m_frameMenuBar) - { - m_frameMenuBar->DestroyMenuBar(); - delete m_frameMenuBar; - } - - m_frameMenuBar = menuBar; - m_frameMenuBar->CreateMenuBar(this); + if (width) + *width = m_width; + if (height) + *height = m_height; } -// Responds to colour changes, and passes event on to children. -void wxFrame::OnSysColourChanged(wxSysColourChangedEvent& event) +void wxTopLevelWindowX11::DoSetClientSize(int width, int height) { - SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_APPWORKSPACE)); - Refresh(); + int old_width = m_width; + int old_height = m_height; - if ( m_frameStatusBar ) - { - wxSysColourChangedEvent event2; - event2.SetEventObject( m_frameStatusBar ); - m_frameStatusBar->ProcessEvent(event2); - } + m_width = width; + m_height = height; - // Propagate the event to the non-top-level children - wxWindow::OnSysColourChanged(event); + if (m_width == old_width && m_height == old_height) + return; + + // wxLogDebug("DoSetClientSize: %s (%ld) %dx%d", GetClassInfo()->GetClassName(), GetId(), width, height); + +#if !wxUSE_NANOX + XSizeHints size_hints; + size_hints.flags = PSize; + size_hints.width = width; + size_hints.height = height; + XSetWMNormalHints( wxGlobalDisplay(), (Window) GetMainWindow(), &size_hints ); +#endif + + wxWindowX11::DoSetClientSize(width, height); } -// Default activation behaviour - set the focus for the first child -// subwindow found. -void wxFrame::OnActivate(wxActivateEvent& event) +void wxTopLevelWindowX11::DoSetSize(int x, int y, int width, int height, int sizeFlags) { - if (!event.GetActive()) - return; + int old_x = m_x; + int old_y = m_y; + int old_width = m_width; + int old_height = m_height; - for(wxNode *node = GetChildren().First(); node; node = node->Next()) - { - // Find a child that's a subwindow, but not a dialog box. - wxWindow *child = (wxWindow *)node->Data(); - if (!child->IsKindOf(CLASSINFO(wxFrame)) && - !child->IsKindOf(CLASSINFO(wxDialog))) - { - child->SetFocus(); - return; - } - } -} + if (x != wxDefaultCoord || (sizeFlags & wxSIZE_ALLOW_MINUS_ONE)) + m_x = x; -#if wxUSE_TOOLBAR + if (y != wxDefaultCoord || (sizeFlags & wxSIZE_ALLOW_MINUS_ONE)) + m_y = y; -wxToolBar* wxFrame::CreateToolBar(long style, - wxWindowID id, - const wxString& name) -{ - if ( wxFrameBase::CreateToolBar(style, id, name) ) - { - PositionToolBar(); - } + if (width != wxDefaultCoord || (sizeFlags & wxSIZE_ALLOW_MINUS_ONE)) + m_width = width; - return m_frameToolBar; -} + if (height != wxDefaultCoord || (sizeFlags & wxSIZE_ALLOW_MINUS_ONE)) + m_height = height; -void wxFrame::PositionToolBar() -{ - if (GetToolBar()) - { - int cw, ch; - GetClientSize(& cw, &ch); + if (m_x == old_x && m_y == old_y && m_width == old_width && m_height == old_height) + return; - int tw, th; - GetToolBar()->GetSize(& tw, & th); + // wxLogDebug("DoSetSize: %s (%ld) %d, %d %dx%d", GetClassInfo()->GetClassName(), GetId(), x, y, width, height); + +#if !wxUSE_NANOX + XSizeHints size_hints; + size_hints.flags = 0; + size_hints.flags |= PPosition; + size_hints.flags |= PSize; + size_hints.x = m_x; + size_hints.y = m_y; + size_hints.width = m_width; + size_hints.height = m_height; + XSetWMNormalHints( wxGlobalDisplay(), (Window) GetMainWindow(), &size_hints); +#endif - if (GetToolBar()->GetWindowStyleFlag() & wxTB_VERTICAL) - { - // Use the 'real' position. wxSIZE_NO_ADJUSTMENTS - // means, pretend we don't have toolbar/status bar, so we - // have the original client size. - GetToolBar()->SetSize(0, 0, tw, ch + th, wxSIZE_NO_ADJUSTMENTS); - } - else - { - // Use the 'real' position - GetToolBar()->SetSize(0, 0, cw, th, wxSIZE_NO_ADJUSTMENTS); - } - } -} -#endif // wxUSE_TOOLBAR + wxWindowX11::DoSetSize(x, y, width, height, sizeFlags); + +#if 0 + Display *display = wxGlobalDisplay(); + Window root = RootWindowOfScreen(DefaultScreenOfDisplay(display)); + Window parent_window = window, + next_parent = window; -void wxFrame::Raise() -{ - Window parent_window = XtWindow((Widget) m_frameShell), - next_parent = XtWindow((Widget) m_frameShell), - root = RootWindowOfScreen(XtScreen((Widget) m_frameShell)); // search for the parent that is child of ROOT, because the WM may // reparent twice and notify only the next parent (like FVWM) while (next_parent != root) { - Window *theChildren; unsigned int n; + Window *theChildren; +#if wxUSE_NANOX + GR_COUNT n; +#else + unsigned int n; +#endif parent_window = next_parent; - XQueryTree(XtDisplay((Widget) m_frameShell), parent_window, &root, + XQueryTree(display, parent_window, &root, &next_parent, &theChildren, &n); XFree(theChildren); // not needed } - XRaiseWindow(XtDisplay((Widget) m_frameShell), parent_window); + + XWindowChanges windowChanges; + windowChanges.x = x; + windowChanges.y = y; + windowChanges.width = width; + windowChanges.height = height; + windowChanges.stack_mode = 0; + int valueMask = CWX | CWY | CWWidth | CWHeight; + + if (x != wxDefaultCoord || (sizeFlags & wxSIZE_ALLOW_MINUS_ONE)) + { + valueMask |= CWX; + } + if (y != wxDefaultCoord || (sizeFlags & wxSIZE_ALLOW_MINUS_ONE)) + { + valueMask |= CWY; + } + if (width != wxDefaultCoord) + { + windowChanges.width = wxMax(1, width); + valueMask |= CWWidth; + } + if (height != wxDefaultCoord) + { + windowChanges.height = wxMax(1, height); + valueMask |= CWHeight; + } + + XConfigureWindow( display, parent_window, valueMask, &windowChanges ); +#endif } -void wxFrame::Lower() +void wxTopLevelWindowX11::DoGetPosition(int *x, int *y) const { - Window parent_window = XtWindow((Widget) m_frameShell), - next_parent = XtWindow((Widget) m_frameShell), - root = RootWindowOfScreen(XtScreen((Widget) m_frameShell)); + XSync(wxGlobalDisplay(), False); + Window window = (Window) m_mainWindow; + if (!window) + return ; + + Display *display = wxGlobalDisplay(); + Window root = RootWindowOfScreen(DefaultScreenOfDisplay(display)); + Window parent_window = window, + next_parent = window; + // search for the parent that is child of ROOT, because the WM may // reparent twice and notify only the next parent (like FVWM) while (next_parent != root) { - Window *theChildren; unsigned int n; + Window *theChildren; +#if wxUSE_NANOX + GR_COUNT n; +#else + unsigned int n; +#endif parent_window = next_parent; - XQueryTree(XtDisplay((Widget) m_frameShell), parent_window, &root, + XQueryTree(display, parent_window, &root, &next_parent, &theChildren, &n); XFree(theChildren); // not needed } - XLowerWindow(XtDisplay((Widget) m_frameShell), parent_window); +#if 0 + int xx, yy; unsigned int dummy; + XGetGeometry(display, parent_window, &root, + &xx, &yy, &dummy, &dummy, &dummy, &dummy); + if (x) *x = xx; + if (y) *y = yy; +#else + XWindowAttributes attr; + Status status = XGetWindowAttributes( wxGlobalDisplay(), parent_window, & attr); + if (status) + { + if (x) *x = attr.x; + if (y) *y = attr.y; + } + else + { + if (x) *x = 0; + if (y) *y = 0; + } +#endif } -void wxFrameFocusProc(Widget WXUNUSED(workArea), XtPointer WXUNUSED(clientData), - XmAnyCallbackStruct *WXUNUSED(cbs)) -{ - // wxDebugMsg("focus proc from frame %ld\n",(long)frame); - // TODO - // wxFrame *frame = (wxFrame *)clientData; - // frame->GetEventHandler()->OnSetFocus(); -} -/* MATTEW: Used to insure that hide-&-show within an event cycle works */ -static void wxFrameMapProc(Widget frameShell, XtPointer clientData, - XCrossingEvent * event) +#ifndef MWM_DECOR_BORDER + +#define MWM_HINTS_FUNCTIONS (1L << 0) +#define MWM_HINTS_DECORATIONS (1L << 1) +#define MWM_HINTS_INPUT_MODE (1L << 2) +#define MWM_HINTS_STATUS (1L << 3) + +#define MWM_DECOR_ALL (1L << 0) +#define MWM_DECOR_BORDER (1L << 1) +#define MWM_DECOR_RESIZEH (1L << 2) +#define MWM_DECOR_TITLE (1L << 3) +#define MWM_DECOR_MENU (1L << 4) +#define MWM_DECOR_MINIMIZE (1L << 5) +#define MWM_DECOR_MAXIMIZE (1L << 6) + +#define MWM_FUNC_ALL (1L << 0) +#define MWM_FUNC_RESIZE (1L << 1) +#define MWM_FUNC_MOVE (1L << 2) +#define MWM_FUNC_MINIMIZE (1L << 3) +#define MWM_FUNC_MAXIMIZE (1L << 4) +#define MWM_FUNC_CLOSE (1L << 5) + +#define MWM_INPUT_MODELESS 0 +#define MWM_INPUT_PRIMARY_APPLICATION_MODAL 1 +#define MWM_INPUT_SYSTEM_MODAL 2 +#define MWM_INPUT_FULL_APPLICATION_MODAL 3 +#define MWM_INPUT_APPLICATION_MODAL MWM_INPUT_PRIMARY_APPLICATION_MODAL + +#define MWM_TEAROFF_WINDOW (1L<<0) + +#endif + +struct MwmHints { + long flags; + long functions; + long decorations; + long input_mode; +}; + +#define PROP_MOTIF_WM_HINTS_ELEMENTS 5 + +// Set the window manager decorations according to the +// given wxWidgets style +bool wxSetWMDecorations(Window w, long style) { - wxFrame *frame = (wxFrame *)wxGetWindowFromTable((Widget)clientData); +#if wxUSE_NANOX + GR_WM_PROPERTIES wmProp; - if (frame) { - XEvent *e = (XEvent *)event; + wmProp.flags = 0; + wmProp.props = 0; - if (e->xany.type == MapNotify) - { - // Iconize fix - XtVaSetValues(frameShell, XmNiconic, (Boolean)False, NULL); - if (!frame->GetVisibleStatus()) - { - /* We really wanted this to be hidden! */ - XtUnmapWidget((Widget) frame->GetShellWidget()); - } - } - else if (e->xany.type == UnmapNotify) - // Iconize fix - XtVaSetValues(frameShell, XmNiconic, (Boolean)True, NULL); + if (style & wxRESIZE_BORDER) + { + wmProp.props |= GR_WM_PROPS_APPFRAME ; + wmProp.flags |= GR_WM_FLAGS_PROPS ; } -} -//// Motif-specific -bool wxFrame::PreResize() -{ -#if wxUSE_TOOLBAR - PositionToolBar(); -#endif // wxUSE_TOOLBAR + if (style & wxCLOSE_BOX) + { + wmProp.props |= GR_WM_PROPS_CLOSEBOX ; + wmProp.flags |= GR_WM_FLAGS_PROPS ; + } -#if wxUSE_STATUSBAR - PositionStatusBar(); -#endif // wxUSE_STATUSBAR + if ((style & wxCAPTION) || + (style & wxTINY_CAPTION_HORIZ) || + (style & wxTINY_CAPTION_VERT)) + { + wmProp.props |= GR_WM_PROPS_CAPTION ; + wmProp.flags |= GR_WM_FLAGS_PROPS ; - return TRUE; -} + // The default dialog style doesn't include any kind + // of border, which is a bit odd. Anyway, inclusion + // of a caption surely implies a border. + style |= wxRESIZE_BORDER; + } -WXWidget wxFrame::GetClientWidget() const -{ - return m_clientArea; -} + if (style & wxRESIZE_BORDER) + { + wmProp.props |= GR_WM_PROPS_APPFRAME ; + wmProp.flags |= GR_WM_FLAGS_PROPS ; + } -void wxFrame::ChangeFont(bool WXUNUSED(keepOriginalSize)) -{ - // TODO -} + if (style & wxSIMPLE_BORDER) + { + wmProp.props |= GR_WM_PROPS_BORDER ; + wmProp.flags |= GR_WM_FLAGS_PROPS ; + } -void wxFrame::ChangeBackgroundColour() -{ - if (GetClientWidget()) - DoChangeBackgroundColour(GetClientWidget(), m_backgroundColour); -} + if (style & wxMINIMIZE_BOX) + { + } -void wxFrame::ChangeForegroundColour() -{ - if (GetClientWidget()) - DoChangeForegroundColour(GetClientWidget(), m_foregroundColour); -} + if (style & wxMAXIMIZE_BOX) + { + wmProp.props |= GR_WM_PROPS_MAXIMIZE ; + wmProp.flags |= GR_WM_FLAGS_PROPS ; + } -void wxCloseFrameCallback(Widget WXUNUSED(widget), XtPointer client_data, XmAnyCallbackStruct *WXUNUSED(cbs)) -{ - wxFrame *frame = (wxFrame *)client_data; + if (((style & wxBORDER) != wxBORDER) && ((style & wxRESIZE_BORDER) != wxRESIZE_BORDER) + && ((style & wxRESIZE_BORDER) != wxRESIZE_BORDER)) + { + wmProp.props |= GR_WM_PROPS_NODECORATE ; + wmProp.flags |= GR_WM_FLAGS_PROPS ; + } - wxCloseEvent closeEvent(wxEVT_CLOSE_WINDOW, frame->GetId()); - closeEvent.SetEventObject(frame); + GrSetWMProperties(w, & wmProp); - // May delete the frame (with delayed deletion) - frame->GetEventHandler()->ProcessEvent(closeEvent); -} +#else -static void wxFrameEventHandler(Widget wid, - XtPointer WXUNUSED(client_data), - XEvent* event, - Boolean* continueToDispatch) -{ - wxFrame *frame = (wxFrame *)wxGetWindowFromTable(wid); - if (frame) + Atom mwm_wm_hints = XInternAtom(wxGlobalDisplay(),"_MOTIF_WM_HINTS", False); + if (mwm_wm_hints == 0) + return false; + + MwmHints hints; + hints.flags = MWM_HINTS_DECORATIONS | MWM_HINTS_FUNCTIONS; + hints.decorations = 0; + hints.functions = 0; + + if ((style & wxSIMPLE_BORDER) || (style & wxNO_BORDER)) { - wxMouseEvent wxevent(wxEVT_NULL); - if (wxTranslateMouseEvent(wxevent, frame, wid, event)) + // leave zeros + } + else + { + hints.decorations = MWM_DECOR_BORDER; + hints.functions = MWM_FUNC_MOVE; + + if ((style & wxCAPTION) != 0) + hints.decorations |= MWM_DECOR_TITLE; + + if ((style & wxSYSTEM_MENU) != 0) + hints.decorations |= MWM_DECOR_MENU; + + if ((style & wxCLOSE_BOX) != 0) + hints.functions |= MWM_FUNC_CLOSE; + + if ((style & wxMINIMIZE_BOX) != 0) { - wxevent.SetEventObject(frame); - wxevent.SetId(frame->GetId()); - frame->GetEventHandler()->ProcessEvent(wxevent); + hints.functions |= MWM_FUNC_MINIMIZE; + hints.decorations |= MWM_DECOR_MINIMIZE; } - else + + if ((style & wxMAXIMIZE_BOX) != 0) { - // An attempt to implement OnCharHook by calling OnCharHook first; - // if this returns TRUE, set continueToDispatch to False - // (don't continue processing). - // Otherwise set it to True and call OnChar. - wxKeyEvent keyEvent(wxEVT_CHAR); - if (wxTranslateKeyEvent(keyEvent, frame, wid, event)) - { - keyEvent.SetEventObject(frame); - keyEvent.SetId(frame->GetId()); - keyEvent.SetEventType(wxEVT_CHAR_HOOK); - if (frame->GetEventHandler()->ProcessEvent(keyEvent)) - { - *continueToDispatch = False; - return; - } - else - { - // 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 (!frame->GetEventHandler()->ProcessEvent (keyEvent)) - { - keyEvent.SetEventType(wxEVT_CHAR); - frame->GetEventHandler()->ProcessEvent(keyEvent); - } - } - } + hints.functions |= MWM_FUNC_MAXIMIZE; + hints.decorations |= MWM_DECOR_MAXIMIZE; + } + + if ((style & wxRESIZE_BORDER) != 0) + { + hints.functions |= MWM_FUNC_RESIZE; + hints.decorations |= MWM_DECOR_RESIZEH; } } - *continueToDispatch = True; + + XChangeProperty(wxGlobalDisplay(), + w, + mwm_wm_hints, mwm_wm_hints, + 32, PropModeReplace, + (unsigned char *) &hints, PROP_MOTIF_WM_HINTS_ELEMENTS); + +#endif + return true; }