]>
git.saurik.com Git - wxWidgets.git/blob - src/motif/toplevel.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: motif/toplevel.cpp
3 // Purpose: wxTopLevelWindow Motif implementation
4 // Author: Mattia Barbon
8 // Copyright: (c) Mattia Barbon
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
12 // ============================================================================
14 // ============================================================================
16 // ----------------------------------------------------------------------------
18 // ----------------------------------------------------------------------------
20 #if defined(__GNUG__) && !defined(NO_GCC_PRAGMA)
21 #pragma implementation "toplevel.h"
24 // For compilers that support precompilation, includes "wx.h".
25 #include "wx/wxprec.h"
27 #include "wx/toplevel.h"
31 #define XtDisplay XTDISPLAY
32 #define XtParent XTPARENT
33 #define XtScreen XTSCREEN
34 #define XtWindow XTWINDOW
35 #pragma message disable nosimpint
39 #include <X11/Shell.h>
48 #pragma message enable nosimpint
51 #include "wx/motif/private.h"
53 wxList wxModelessWindows
; // Frames and modeless dialogs
55 // ---------------------------------------------------------------------------
57 // ---------------------------------------------------------------------------
59 static void wxCloseTLWCallback( Widget widget
, XtPointer client_data
,
60 XmAnyCallbackStruct
*cbs
);
61 static void wxTLWEventHandler( Widget wid
,
62 XtPointer client_data
,
64 Boolean
*continueToDispatch
);
66 // ===========================================================================
67 // wxTopLevelWindowMotif implementation
68 // ===========================================================================
70 void wxTopLevelWindowMotif::PreDestroy()
73 #pragma message disable codcauunr
75 if ( (GetWindowStyleFlag() & wxDIALOG_MODAL
) != wxDIALOG_MODAL
)
76 wxModelessWindows
.DeleteObject(this);
78 #pragma message enable codcauunr
81 m_icons
.m_icons
.Empty();
85 // MessageDialog and FileDialog do not have a client widget
86 if( GetClientWidget() )
88 XtRemoveEventHandler( (Widget
)GetClientWidget(),
89 ButtonPressMask
| ButtonReleaseMask
|
90 PointerMotionMask
| KeyPressMask
,
97 wxTopLevelWindowMotif::~wxTopLevelWindowMotif()
99 SetMainWidget( (WXWidget
)0 );
102 void wxTopLevelWindowMotif::Init()
107 bool wxTopLevelWindowMotif::Create( wxWindow
*parent
, wxWindowID id
,
108 const wxString
& title
,
112 const wxString
& name
)
115 m_windowStyle
= style
;
118 parent
->AddChild(this);
120 wxTopLevelWindows
.Append(this);
122 m_windowId
= ( id
> -1 ) ? id
: NewControlId();
124 bool retval
= DoCreate( parent
, id
, title
, pos
, size
, style
, name
);
126 if( !retval
) return false;
128 // Intercept CLOSE messages from the window manager
129 Widget shell
= (Widget
)GetShellWidget();
130 Atom WM_DELETE_WINDOW
= XmInternAtom( XtDisplay( shell
),
131 "WM_DELETE_WINDOW", False
);
133 // Remove and add WM_DELETE_WINDOW so ours is only handler
134 // This only appears to be necessary for wxDialog, but does not hurt
136 XmRemoveWMProtocols( shell
, &WM_DELETE_WINDOW
, 1 );
137 XmAddWMProtocols( shell
, &WM_DELETE_WINDOW
, 1 );
138 XmActivateWMProtocol( shell
, WM_DELETE_WINDOW
);
140 // Modified Steve Hammes for Motif 2.0
141 #if (XmREVISION > 1 || XmVERSION > 1)
142 XmAddWMProtocolCallback( shell
, WM_DELETE_WINDOW
,
143 (XtCallbackProc
)wxCloseTLWCallback
,
145 #elif XmREVISION == 1
146 XmAddWMProtocolCallback( shell
, WM_DELETE_WINDOW
,
147 (XtCallbackProc
)wxCloseTLWCallback
,
150 XmAddWMProtocolCallback( shell
, WM_DELETE_WINDOW
,
151 (void (*)())wxCloseTLWCallback
, (caddr_t
)this );
154 // This patch come from Torsten Liermann lier@lier1.muc.de
155 if( XmIsMotifWMRunning( shell
) )
158 if( !(m_windowStyle
& wxNO_BORDER
) )
159 decor
|= MWM_DECOR_BORDER
;
160 if( m_windowStyle
& wxRESIZE_BORDER
)
161 decor
|= MWM_DECOR_RESIZEH
;
162 if( m_windowStyle
& wxSYSTEM_MENU
)
163 decor
|= MWM_DECOR_MENU
;
164 if( ( m_windowStyle
& wxCAPTION
) ||
165 ( m_windowStyle
& wxTINY_CAPTION_HORIZ
) ||
166 ( m_windowStyle
& wxTINY_CAPTION_VERT
) )
167 decor
|= MWM_DECOR_TITLE
;
168 if( m_windowStyle
& wxTHICK_FRAME
)
169 decor
|= MWM_DECOR_BORDER
;
170 if( m_windowStyle
& wxMINIMIZE_BOX
)
171 decor
|= MWM_DECOR_MINIMIZE
;
172 if( m_windowStyle
& wxMAXIMIZE_BOX
)
173 decor
|= MWM_DECOR_MAXIMIZE
;
175 XtVaSetValues( shell
,
176 XmNmwmDecorations
, decor
,
181 // This allows non-Motif window managers to support at least the
182 // no-decorations case.
183 if( ( m_windowStyle
& wxCAPTION
) != wxCAPTION
)
184 XtVaSetValues( shell
,
185 XmNoverrideRedirect
, True
,
189 XtAddEventHandler( (Widget
)GetClientWidget(),
190 ButtonPressMask
| ButtonReleaseMask
|
191 PointerMotionMask
| KeyPressMask
,
199 void wxTopLevelWindowMotif::DoGetPosition(int *x
, int *y
) const
201 Widget top
= (Widget
) GetTopWidget();
202 Window parent_window
= XtWindow((Widget
) top
),
203 next_parent
= XtWindow((Widget
) top
),
204 root
= RootWindowOfScreen(XtScreen((Widget
) top
));
206 // search for the parent that is child of ROOT, because the WM may
207 // reparent twice and notify only the next parent (like FVWM)
208 while (next_parent
!= root
) {
209 Window
*theChildren
; unsigned int n
;
210 parent_window
= next_parent
;
211 XQueryTree(XtDisplay((Widget
) top
), parent_window
, &root
,
212 &next_parent
, &theChildren
, &n
);
213 XFree(theChildren
); // not needed
215 int xx
, yy
; unsigned int dummy
;
216 XGetGeometry(XtDisplay((Widget
) top
), parent_window
, &root
,
217 &xx
, &yy
, &dummy
, &dummy
, &dummy
, &dummy
);
222 void wxTopLevelWindowMotif::Raise()
224 Widget top
= (Widget
) GetTopWidget();
225 Window parent_window
= XtWindow( top
),
226 next_parent
= XtWindow( top
),
227 root
= RootWindowOfScreen( XtScreen( top
) );
228 // search for the parent that is child of ROOT, because the WM may
229 // reparent twice and notify only the next parent (like FVWM)
230 while( next_parent
!= root
)
235 parent_window
= next_parent
;
236 XQueryTree( XtDisplay( top
), parent_window
, &root
,
237 &next_parent
, &theChildren
, &n
);
238 XFree( theChildren
); // not needed
240 XRaiseWindow( XtDisplay( top
), parent_window
);
243 void wxTopLevelWindowMotif::Lower()
245 Widget top
= (Widget
) GetTopWidget();
246 Window parent_window
= XtWindow( top
),
247 next_parent
= XtWindow( top
),
248 root
= RootWindowOfScreen( XtScreen( top
) );
249 // search for the parent that is child of ROOT, because the WM may
250 // reparent twice and notify only the next parent (like FVWM)
251 while( next_parent
!= root
)
256 parent_window
= next_parent
;
257 XQueryTree( XtDisplay( top
), parent_window
, &root
,
258 &next_parent
, &theChildren
, &n
);
259 XFree( theChildren
); // not needed
261 XLowerWindow( XtDisplay( top
), parent_window
);
264 static inline Widget
GetShell( const wxTopLevelWindowMotif
* tlw
)
266 Widget main
= (Widget
) tlw
->GetMainWidget();
267 if( !main
) return (Widget
) NULL
;
269 return XtParent( main
);
272 WXWidget
wxTopLevelWindowMotif::GetShellWidget() const
274 return (WXWidget
) GetShell( this );
277 bool wxTopLevelWindowMotif::ShowFullScreen( bool show
,
284 bool wxTopLevelWindowMotif::IsFullScreen() const
290 void wxTopLevelWindowMotif::Restore()
292 Widget shell
= GetShell( this );
295 XtVaSetValues( shell
,
300 void wxTopLevelWindowMotif::Iconize( bool iconize
)
302 Widget shell
= GetShell( this );
308 XtVaSetValues( shell
,
309 XmNiconic
, (Boolean
)iconize
,
313 bool wxTopLevelWindowMotif::IsIconized() const
315 Widget shell
= GetShell( this );
321 XtVaGetValues( shell
,
328 void wxTopLevelWindowMotif::Maximize( bool maximize
)
336 bool wxTopLevelWindowMotif::IsMaximized() const
341 void wxTopLevelWindowMotif::DoSetSizeHints( int minW
, int minH
,
345 wxTopLevelWindowBase::DoSetSizeHints( minW
, minH
, maxW
, maxH
, incW
, incH
);
350 if( minW
> -1 ) { XtSetArg( args
[count
], XmNminWidth
, minW
); ++count
; }
351 if( minH
> -1 ) { XtSetArg( args
[count
], XmNminHeight
, minH
); ++count
; }
352 if( maxW
> -1 ) { XtSetArg( args
[count
], XmNmaxWidth
, maxW
); ++count
; }
353 if( maxH
> -1 ) { XtSetArg( args
[count
], XmNmaxHeight
, maxH
); ++count
; }
354 if( incW
> -1 ) { XtSetArg( args
[count
], XmNwidthInc
, incW
); ++count
; }
355 if( incH
> -1 ) { XtSetArg( args
[count
], XmNheightInc
, incH
); ++count
; }
357 XtSetValues( (Widget
)GetShellWidget(), args
, count
);
360 bool wxTopLevelWindowMotif::SetShape( const wxRegion
& region
)
362 return wxDoSetShape( (Display
*)GetXDisplay(),
363 XtWindow( (Widget
)GetShellWidget() ),
367 // ---------------------------------------------------------------------------
368 // Callback definition
369 // ---------------------------------------------------------------------------
371 // Handle a close event from the window manager
372 static void wxCloseTLWCallback( Widget
WXUNUSED(widget
), XtPointer client_data
,
373 XmAnyCallbackStruct
*WXUNUSED(cbs
) )
375 wxTopLevelWindowMotif
* tlw
= (wxTopLevelWindowMotif
*)client_data
;
376 wxCloseEvent
closeEvent( wxEVT_CLOSE_WINDOW
, tlw
->GetId() );
377 closeEvent
.SetEventObject( tlw
);
379 // May delete the dialog (with delayed deletion)
380 tlw
->GetEventHandler()->ProcessEvent(closeEvent
);
383 void wxTLWEventHandler( Widget wid
,
384 XtPointer
WXUNUSED(client_data
),
386 Boolean
* continueToDispatch
)
388 wxTopLevelWindowMotif
* tlw
=
389 (wxTopLevelWindowMotif
*)wxGetWindowFromTable( wid
);
393 wxMouseEvent
wxevent( wxEVT_NULL
);
395 if( wxTranslateMouseEvent( wxevent
, tlw
, wid
, event
) )
397 wxevent
.SetEventObject( tlw
);
398 wxevent
.SetId( tlw
->GetId() );
399 tlw
->GetEventHandler()->ProcessEvent( wxevent
);
403 // An attempt to implement OnCharHook by calling OnCharHook first;
404 // if this returns true, set continueToDispatch to False
405 // (don't continue processing).
406 // Otherwise set it to True and call OnChar.
407 wxKeyEvent
keyEvent( wxEVT_CHAR
);
408 if( wxTranslateKeyEvent( keyEvent
, tlw
, wid
, event
))
410 keyEvent
.SetEventObject( tlw
);
411 keyEvent
.SetId( tlw
->GetId() );
412 keyEvent
.SetEventType( wxEVT_CHAR_HOOK
);
413 if( tlw
->GetEventHandler()->ProcessEvent( keyEvent
) )
415 *continueToDispatch
= False
;
420 // For simplicity, OnKeyDown is the same as OnChar
421 // TODO: filter modifier key presses from OnChar
422 keyEvent
.SetEventType( wxEVT_KEY_DOWN
);
424 // Only process OnChar if OnKeyDown didn't swallow it
425 if( !tlw
->GetEventHandler()->ProcessEvent( keyEvent
) )
427 keyEvent
.SetEventType( wxEVT_CHAR
);
428 tlw
->GetEventHandler()->ProcessEvent( keyEvent
);
435 *continueToDispatch
= True
;