]>
git.saurik.com Git - wxWidgets.git/blob - src/motif/toplevel.cpp
aaa53556dab1b635d529f029d4786b77ee5f34aa
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: src/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 // For compilers that support precompilation, includes "wx.h".
21 #include "wx/wxprec.h"
23 #include "wx/toplevel.h"
24 #include "wx/settings.h"
32 #define XtDisplay XTDISPLAY
33 #define XtParent XTPARENT
34 #define XtScreen XTSCREEN
35 #define XtWindow XTWINDOW
36 #pragma message disable nosimpint
40 #include <X11/Shell.h>
49 #pragma message enable nosimpint
52 #include "wx/motif/private.h"
54 wxList wxModelessWindows
; // Frames and modeless dialogs
56 // ---------------------------------------------------------------------------
58 // ---------------------------------------------------------------------------
60 static void wxCloseTLWCallback( Widget widget
, XtPointer client_data
,
61 XmAnyCallbackStruct
*cbs
);
62 static void wxTLWEventHandler( Widget wid
,
63 XtPointer client_data
,
65 Boolean
*continueToDispatch
);
67 // ===========================================================================
68 // wxTopLevelWindowMotif implementation
69 // ===========================================================================
71 void wxTopLevelWindowMotif::PreDestroy()
73 wxModelessWindows
.DeleteObject(this);
75 m_icons
.m_icons
.Empty();
79 // MessageDialog and FileDialog do not have a client widget
80 if( GetClientWidget() )
82 XtRemoveEventHandler( (Widget
)GetClientWidget(),
83 ButtonPressMask
| ButtonReleaseMask
|
84 PointerMotionMask
| KeyPressMask
,
91 wxTopLevelWindowMotif::~wxTopLevelWindowMotif()
93 SetMainWidget( (WXWidget
)0 );
96 void wxTopLevelWindowMotif::Init()
101 bool wxTopLevelWindowMotif::Create( wxWindow
*parent
, wxWindowID id
,
102 const wxString
& title
,
106 const wxString
& name
)
109 m_windowStyle
= style
;
112 parent
->AddChild(this);
114 wxTopLevelWindows
.Append(this);
116 m_windowId
= ( id
> -1 ) ? id
: NewControlId();
117 // MBN: More backward compatible, but uglier
118 m_font
= wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT
);
119 m_inheritFont
= true;
121 bool retval
= XmDoCreateTLW( parent
, id
, title
, pos
, size
, style
, name
);
123 if( !retval
) return false;
125 // Intercept CLOSE messages from the window manager
126 Widget shell
= (Widget
)GetShellWidget();
127 Atom WM_DELETE_WINDOW
= XmInternAtom( XtDisplay( shell
),
128 "WM_DELETE_WINDOW", False
);
130 // Remove and add WM_DELETE_WINDOW so ours is only handler
131 // This only appears to be necessary for wxDialog, but does not hurt
133 XmRemoveWMProtocols( shell
, &WM_DELETE_WINDOW
, 1 );
134 XmAddWMProtocols( shell
, &WM_DELETE_WINDOW
, 1 );
135 XmActivateWMProtocol( shell
, WM_DELETE_WINDOW
);
137 // Modified Steve Hammes for Motif 2.0
138 #if (XmREVISION > 1 || XmVERSION > 1)
139 XmAddWMProtocolCallback( shell
, WM_DELETE_WINDOW
,
140 (XtCallbackProc
)wxCloseTLWCallback
,
142 #elif XmREVISION == 1
143 XmAddWMProtocolCallback( shell
, WM_DELETE_WINDOW
,
144 (XtCallbackProc
)wxCloseTLWCallback
,
147 XmAddWMProtocolCallback( shell
, WM_DELETE_WINDOW
,
148 (void (*)())wxCloseTLWCallback
, (caddr_t
)this );
151 // This patch come from Torsten Liermann lier@lier1.muc.de
152 if( XmIsMotifWMRunning( shell
) )
155 if( !(m_windowStyle
& wxNO_BORDER
) )
156 decor
|= MWM_DECOR_BORDER
;
157 if( m_windowStyle
& wxRESIZE_BORDER
)
158 decor
|= MWM_DECOR_RESIZEH
;
159 if( m_windowStyle
& wxSYSTEM_MENU
)
160 decor
|= MWM_DECOR_MENU
;
161 if( ( m_windowStyle
& wxCAPTION
) ||
162 ( m_windowStyle
& wxTINY_CAPTION_HORIZ
) ||
163 ( m_windowStyle
& wxTINY_CAPTION_VERT
) )
164 decor
|= MWM_DECOR_TITLE
;
165 if( m_windowStyle
& wxRESIZE_BORDER
)
166 decor
|= MWM_DECOR_BORDER
;
167 if( m_windowStyle
& wxMINIMIZE_BOX
)
168 decor
|= MWM_DECOR_MINIMIZE
;
169 if( m_windowStyle
& wxMAXIMIZE_BOX
)
170 decor
|= MWM_DECOR_MAXIMIZE
;
172 XtVaSetValues( shell
,
173 XmNmwmDecorations
, decor
,
178 // This allows non-Motif window managers to support at least the
179 // no-decorations case.
180 if( ( m_windowStyle
& wxCAPTION
) != wxCAPTION
)
181 XtVaSetValues( shell
,
182 XmNoverrideRedirect
, True
,
186 XtAddEventHandler( (Widget
)GetClientWidget(),
187 ButtonPressMask
| ButtonReleaseMask
|
188 PointerMotionMask
| KeyPressMask
,
196 void wxTopLevelWindowMotif::DoGetPosition(int *x
, int *y
) const
198 Widget top
= (Widget
) GetTopWidget();
199 Window parent_window
= XtWindow((Widget
) top
),
200 next_parent
= XtWindow((Widget
) top
),
201 root
= RootWindowOfScreen(XtScreen((Widget
) top
));
203 // search for the parent that is child of ROOT, because the WM may
204 // reparent twice and notify only the next parent (like FVWM)
205 while (next_parent
!= root
) {
206 Window
*theChildren
; unsigned int n
;
207 parent_window
= next_parent
;
208 XQueryTree(XtDisplay((Widget
) top
), parent_window
, &root
,
209 &next_parent
, &theChildren
, &n
);
210 XFree(theChildren
); // not needed
212 int xx
, yy
; unsigned int dummy
;
213 XGetGeometry(XtDisplay((Widget
) top
), parent_window
, &root
,
214 &xx
, &yy
, &dummy
, &dummy
, &dummy
, &dummy
);
219 void wxTopLevelWindowMotif::Raise()
221 Widget top
= (Widget
) GetTopWidget();
222 Window parent_window
= XtWindow( top
),
223 next_parent
= XtWindow( top
),
224 root
= RootWindowOfScreen( XtScreen( top
) );
225 // search for the parent that is child of ROOT, because the WM may
226 // reparent twice and notify only the next parent (like FVWM)
227 while( next_parent
!= root
)
232 parent_window
= next_parent
;
233 XQueryTree( XtDisplay( top
), parent_window
, &root
,
234 &next_parent
, &theChildren
, &n
);
235 XFree( theChildren
); // not needed
237 XRaiseWindow( XtDisplay( top
), parent_window
);
240 void wxTopLevelWindowMotif::Lower()
242 Widget top
= (Widget
) GetTopWidget();
243 Window parent_window
= XtWindow( top
),
244 next_parent
= XtWindow( top
),
245 root
= RootWindowOfScreen( XtScreen( top
) );
246 // search for the parent that is child of ROOT, because the WM may
247 // reparent twice and notify only the next parent (like FVWM)
248 while( next_parent
!= root
)
253 parent_window
= next_parent
;
254 XQueryTree( XtDisplay( top
), parent_window
, &root
,
255 &next_parent
, &theChildren
, &n
);
256 XFree( theChildren
); // not needed
258 XLowerWindow( XtDisplay( top
), parent_window
);
261 static inline Widget
GetShell( const wxTopLevelWindowMotif
* tlw
)
263 Widget main
= (Widget
) tlw
->GetMainWidget();
264 if( !main
) return (Widget
) NULL
;
266 return XtParent( main
);
269 WXWidget
wxTopLevelWindowMotif::GetShellWidget() const
271 return (WXWidget
) GetShell( this );
274 bool wxTopLevelWindowMotif::ShowFullScreen( bool WXUNUSED(show
),
275 long WXUNUSED(style
) )
281 bool wxTopLevelWindowMotif::IsFullScreen() const
287 void wxTopLevelWindowMotif::Restore()
289 Widget shell
= GetShell( this );
292 XtVaSetValues( shell
,
297 void wxTopLevelWindowMotif::Iconize( bool iconize
)
299 Widget shell
= GetShell( this );
305 XtVaSetValues( shell
,
306 XmNiconic
, (Boolean
)iconize
,
310 bool wxTopLevelWindowMotif::IsIconized() const
312 Widget shell
= GetShell( this );
318 XtVaGetValues( shell
,
322 return (iconic
== True
);
325 void wxTopLevelWindowMotif::Maximize( bool maximize
)
333 bool wxTopLevelWindowMotif::IsMaximized() const
338 void wxTopLevelWindowMotif::DoSetSizeHints( int minW
, int minH
,
342 wxTopLevelWindowBase::DoSetSizeHints( minW
, minH
, maxW
, maxH
, incW
, incH
);
347 if( minW
> -1 ) { XtSetArg( args
[count
], XmNminWidth
, minW
); ++count
; }
348 if( minH
> -1 ) { XtSetArg( args
[count
], XmNminHeight
, minH
); ++count
; }
349 if( maxW
> -1 ) { XtSetArg( args
[count
], XmNmaxWidth
, maxW
); ++count
; }
350 if( maxH
> -1 ) { XtSetArg( args
[count
], XmNmaxHeight
, maxH
); ++count
; }
351 if( incW
> -1 ) { XtSetArg( args
[count
], XmNwidthInc
, incW
); ++count
; }
352 if( incH
> -1 ) { XtSetArg( args
[count
], XmNheightInc
, incH
); ++count
; }
354 XtSetValues( (Widget
)GetShellWidget(), args
, count
);
357 bool wxTopLevelWindowMotif::SetShape( const wxRegion
& region
)
359 return wxDoSetShape( (Display
*)GetXDisplay(),
360 XtWindow( (Widget
)GetShellWidget() ),
364 // ---------------------------------------------------------------------------
365 // Callback definition
366 // ---------------------------------------------------------------------------
368 // Handle a close event from the window manager
369 static void wxCloseTLWCallback( Widget
WXUNUSED(widget
), XtPointer client_data
,
370 XmAnyCallbackStruct
*WXUNUSED(cbs
) )
372 wxTopLevelWindowMotif
* tlw
= (wxTopLevelWindowMotif
*)client_data
;
373 wxCloseEvent
closeEvent( wxEVT_CLOSE_WINDOW
, tlw
->GetId() );
374 closeEvent
.SetEventObject( tlw
);
376 // May delete the dialog (with delayed deletion)
377 tlw
->GetEventHandler()->ProcessEvent(closeEvent
);
380 void wxTLWEventHandler( Widget wid
,
381 XtPointer
WXUNUSED(client_data
),
383 Boolean
* continueToDispatch
)
385 wxTopLevelWindowMotif
* tlw
=
386 (wxTopLevelWindowMotif
*)wxGetWindowFromTable( wid
);
390 wxMouseEvent
wxevent( wxEVT_NULL
);
392 if( wxTranslateMouseEvent( wxevent
, tlw
, wid
, event
) )
394 wxevent
.SetEventObject( tlw
);
395 wxevent
.SetId( tlw
->GetId() );
396 tlw
->GetEventHandler()->ProcessEvent( wxevent
);
400 // An attempt to implement OnCharHook by calling OnCharHook first;
401 // if this returns true, set continueToDispatch to False
402 // (don't continue processing).
403 // Otherwise set it to True and call OnChar.
404 wxKeyEvent
keyEvent( wxEVT_CHAR
);
405 if( wxTranslateKeyEvent( keyEvent
, tlw
, wid
, event
))
407 keyEvent
.SetEventObject( tlw
);
408 keyEvent
.SetId( tlw
->GetId() );
409 keyEvent
.SetEventType( wxEVT_CHAR_HOOK
);
410 if( tlw
->GetEventHandler()->ProcessEvent( keyEvent
) )
412 *continueToDispatch
= False
;
417 // For simplicity, OnKeyDown is the same as OnChar
418 // TODO: filter modifier key presses from OnChar
419 keyEvent
.SetEventType( wxEVT_KEY_DOWN
);
421 // Only process OnChar if OnKeyDown didn't swallow it
422 if( !tlw
->GetEventHandler()->ProcessEvent( keyEvent
) )
424 keyEvent
.SetEventType( wxEVT_CHAR
);
425 tlw
->GetEventHandler()->ProcessEvent( keyEvent
);
432 *continueToDispatch
= True
;