]>
git.saurik.com Git - wxWidgets.git/blob - src/motif/toplevel.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: src/motif/toplevel.cpp
3 // Purpose: wxTopLevelWindow Motif implementation
4 // Author: Mattia Barbon
7 // Copyright: (c) Mattia Barbon
8 // Licence: wxWindows licence
9 /////////////////////////////////////////////////////////////////////////////
11 // ============================================================================
13 // ============================================================================
15 // ----------------------------------------------------------------------------
17 // ----------------------------------------------------------------------------
19 // For compilers that support precompilation, includes "wx.h".
20 #include "wx/wxprec.h"
22 #include "wx/toplevel.h"
23 #include "wx/settings.h"
31 #pragma message disable nosimpint
35 #include <X11/Shell.h>
44 #pragma message enable nosimpint
47 #include "wx/motif/private.h"
49 wxList wxModelessWindows
; // Frames and modeless dialogs
51 // ---------------------------------------------------------------------------
53 // ---------------------------------------------------------------------------
55 static void wxCloseTLWCallback( Widget widget
, XtPointer client_data
,
56 XmAnyCallbackStruct
*cbs
);
57 static void wxTLWEventHandler( Widget wid
,
58 XtPointer client_data
,
60 Boolean
*continueToDispatch
);
62 // ===========================================================================
63 // wxTopLevelWindowMotif implementation
64 // ===========================================================================
66 void wxTopLevelWindowMotif::PreDestroy()
68 wxModelessWindows
.DeleteObject(this);
72 // MessageDialog and FileDialog do not have a client widget
73 if( GetClientWidget() )
75 XtRemoveEventHandler( (Widget
)GetClientWidget(),
76 ButtonPressMask
| ButtonReleaseMask
|
77 PointerMotionMask
| KeyPressMask
,
84 wxTopLevelWindowMotif::~wxTopLevelWindowMotif()
86 SetMainWidget( (WXWidget
)0 );
89 void wxTopLevelWindowMotif::Init()
94 bool wxTopLevelWindowMotif::Create( wxWindow
*parent
, wxWindowID id
,
95 const wxString
& title
,
99 const wxString
& name
)
102 m_windowStyle
= style
;
105 parent
->AddChild(this);
107 wxTopLevelWindows
.Append(this);
109 m_windowId
= ( id
> -1 ) ? id
: NewControlId();
110 // MBN: More backward compatible, but uglier
111 m_font
= wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT
);
112 m_inheritFont
= true;
114 bool retval
= XmDoCreateTLW( parent
, id
, title
, pos
, size
, style
, name
);
116 if( !retval
) return false;
118 // Intercept CLOSE messages from the window manager
119 Widget shell
= (Widget
)GetShellWidget();
120 Atom WM_DELETE_WINDOW
= XmInternAtom( XtDisplay( shell
),
121 "WM_DELETE_WINDOW", False
);
123 // Remove and add WM_DELETE_WINDOW so ours is only handler
124 // This only appears to be necessary for wxDialog, but does not hurt
126 XmRemoveWMProtocols( shell
, &WM_DELETE_WINDOW
, 1 );
127 XmAddWMProtocols( shell
, &WM_DELETE_WINDOW
, 1 );
128 XmActivateWMProtocol( shell
, WM_DELETE_WINDOW
);
130 // Modified Steve Hammes for Motif 2.0
131 #if (XmREVISION > 1 || XmVERSION > 1)
132 XmAddWMProtocolCallback( shell
, WM_DELETE_WINDOW
,
133 (XtCallbackProc
)wxCloseTLWCallback
,
135 #elif XmREVISION == 1
136 XmAddWMProtocolCallback( shell
, WM_DELETE_WINDOW
,
137 (XtCallbackProc
)wxCloseTLWCallback
,
140 XmAddWMProtocolCallback( shell
, WM_DELETE_WINDOW
,
141 (void (*)())wxCloseTLWCallback
, (caddr_t
)this );
144 // This patch come from Torsten Liermann lier@lier1.muc.de
145 if( XmIsMotifWMRunning( shell
) )
148 if( !(m_windowStyle
& wxNO_BORDER
) )
149 decor
|= MWM_DECOR_BORDER
;
150 if( m_windowStyle
& wxRESIZE_BORDER
)
151 decor
|= MWM_DECOR_RESIZEH
;
152 if( m_windowStyle
& wxSYSTEM_MENU
)
153 decor
|= MWM_DECOR_MENU
;
154 if( ( m_windowStyle
& wxCAPTION
) ||
155 ( m_windowStyle
& wxTINY_CAPTION
) )
156 decor
|= MWM_DECOR_TITLE
;
157 if( m_windowStyle
& wxRESIZE_BORDER
)
158 decor
|= MWM_DECOR_BORDER
;
159 if( m_windowStyle
& wxMINIMIZE_BOX
)
160 decor
|= MWM_DECOR_MINIMIZE
;
161 if( m_windowStyle
& wxMAXIMIZE_BOX
)
162 decor
|= MWM_DECOR_MAXIMIZE
;
164 XtVaSetValues( shell
,
165 XmNmwmDecorations
, decor
,
170 // This allows non-Motif window managers to support at least the
171 // no-decorations case.
172 if( ( m_windowStyle
& wxCAPTION
) != wxCAPTION
)
173 XtVaSetValues( shell
,
174 XmNoverrideRedirect
, True
,
178 XtAddEventHandler( (Widget
)GetClientWidget(),
179 ButtonPressMask
| ButtonReleaseMask
|
180 PointerMotionMask
| KeyPressMask
,
188 void wxTopLevelWindowMotif::DoGetPosition(int *x
, int *y
) const
190 Widget top
= (Widget
) GetTopWidget();
191 Window parent_window
= XtWindow((Widget
) top
),
192 next_parent
= XtWindow((Widget
) top
),
193 root
= RootWindowOfScreen(XtScreen((Widget
) top
));
195 // search for the parent that is child of ROOT, because the WM may
196 // reparent twice and notify only the next parent (like FVWM)
197 while (next_parent
!= root
) {
198 Window
*theChildren
; unsigned int n
;
199 parent_window
= next_parent
;
200 XQueryTree(XtDisplay((Widget
) top
), parent_window
, &root
,
201 &next_parent
, &theChildren
, &n
);
202 XFree(theChildren
); // not needed
204 int xx
, yy
; unsigned int dummy
;
205 XGetGeometry(XtDisplay((Widget
) top
), parent_window
, &root
,
206 &xx
, &yy
, &dummy
, &dummy
, &dummy
, &dummy
);
211 void wxTopLevelWindowMotif::Raise()
213 Widget top
= (Widget
) GetTopWidget();
214 Window parent_window
= XtWindow( top
),
215 next_parent
= XtWindow( top
),
216 root
= RootWindowOfScreen( XtScreen( top
) );
217 // search for the parent that is child of ROOT, because the WM may
218 // reparent twice and notify only the next parent (like FVWM)
219 while( next_parent
!= root
)
224 parent_window
= next_parent
;
225 XQueryTree( XtDisplay( top
), parent_window
, &root
,
226 &next_parent
, &theChildren
, &n
);
227 XFree( theChildren
); // not needed
229 XRaiseWindow( XtDisplay( top
), parent_window
);
232 void wxTopLevelWindowMotif::Lower()
234 Widget top
= (Widget
) GetTopWidget();
235 Window parent_window
= XtWindow( top
),
236 next_parent
= XtWindow( top
),
237 root
= RootWindowOfScreen( XtScreen( top
) );
238 // search for the parent that is child of ROOT, because the WM may
239 // reparent twice and notify only the next parent (like FVWM)
240 while( next_parent
!= root
)
245 parent_window
= next_parent
;
246 XQueryTree( XtDisplay( top
), parent_window
, &root
,
247 &next_parent
, &theChildren
, &n
);
248 XFree( theChildren
); // not needed
250 XLowerWindow( XtDisplay( top
), parent_window
);
253 static inline Widget
GetShell( const wxTopLevelWindowMotif
* tlw
)
255 Widget main
= (Widget
) tlw
->GetMainWidget();
256 if( !main
) return (Widget
) NULL
;
258 return XtParent( main
);
261 WXWidget
wxTopLevelWindowMotif::GetShellWidget() const
263 return (WXWidget
) GetShell( this );
266 bool wxTopLevelWindowMotif::ShowFullScreen( bool WXUNUSED(show
),
267 long WXUNUSED(style
) )
273 bool wxTopLevelWindowMotif::IsFullScreen() const
279 void wxTopLevelWindowMotif::Restore()
281 Widget shell
= GetShell( this );
284 XtVaSetValues( shell
,
289 void wxTopLevelWindowMotif::Iconize( bool iconize
)
291 Widget shell
= GetShell( this );
297 XtVaSetValues( shell
,
298 XmNiconic
, (Boolean
)iconize
,
302 bool wxTopLevelWindowMotif::IsIconized() const
304 Widget shell
= GetShell( this );
310 XtVaGetValues( shell
,
314 return (iconic
== True
);
317 void wxTopLevelWindowMotif::Maximize( bool maximize
)
325 bool wxTopLevelWindowMotif::IsMaximized() const
330 void wxTopLevelWindowMotif::DoSetSizeHints( int minW
, int minH
,
334 wxTopLevelWindowBase::DoSetSizeHints( minW
, minH
, maxW
, maxH
, incW
, incH
);
339 if( minW
> -1 ) { XtSetArg( args
[count
], XmNminWidth
, minW
); ++count
; }
340 if( minH
> -1 ) { XtSetArg( args
[count
], XmNminHeight
, minH
); ++count
; }
341 if( maxW
> -1 ) { XtSetArg( args
[count
], XmNmaxWidth
, maxW
); ++count
; }
342 if( maxH
> -1 ) { XtSetArg( args
[count
], XmNmaxHeight
, maxH
); ++count
; }
343 if( incW
> -1 ) { XtSetArg( args
[count
], XmNwidthInc
, incW
); ++count
; }
344 if( incH
> -1 ) { XtSetArg( args
[count
], XmNheightInc
, incH
); ++count
; }
346 XtSetValues( (Widget
)GetShellWidget(), args
, count
);
349 bool wxTopLevelWindowMotif::SetShape( const wxRegion
& region
)
351 return wxDoSetShape( (Display
*)GetXDisplay(),
352 XtWindow( (Widget
)GetShellWidget() ),
356 // ---------------------------------------------------------------------------
357 // Callback definition
358 // ---------------------------------------------------------------------------
360 // Handle a close event from the window manager
361 static void wxCloseTLWCallback( Widget
WXUNUSED(widget
), XtPointer client_data
,
362 XmAnyCallbackStruct
*WXUNUSED(cbs
) )
364 wxTopLevelWindowMotif
* tlw
= (wxTopLevelWindowMotif
*)client_data
;
365 wxCloseEvent
closeEvent( wxEVT_CLOSE_WINDOW
, tlw
->GetId() );
366 closeEvent
.SetEventObject( tlw
);
368 // May delete the dialog (with delayed deletion)
369 tlw
->HandleWindowEvent(closeEvent
);
372 void wxTLWEventHandler( Widget wid
,
373 XtPointer
WXUNUSED(client_data
),
375 Boolean
* continueToDispatch
)
377 wxTopLevelWindowMotif
* tlw
=
378 (wxTopLevelWindowMotif
*)wxGetWindowFromTable( wid
);
382 wxMouseEvent
wxevent( wxEVT_NULL
);
384 if( wxTranslateMouseEvent( wxevent
, tlw
, wid
, event
) )
386 wxevent
.SetEventObject( tlw
);
387 wxevent
.SetId( tlw
->GetId() );
388 tlw
->HandleWindowEvent( wxevent
);
392 // An attempt to implement OnCharHook by calling OnCharHook first;
393 // if this returns true, set continueToDispatch to False
394 // (don't continue processing).
395 // Otherwise set it to True and call OnChar.
396 wxKeyEvent
keyEvent( wxEVT_CHAR
);
397 if( wxTranslateKeyEvent( keyEvent
, tlw
, wid
, event
))
399 keyEvent
.SetEventObject( tlw
);
400 keyEvent
.SetId( tlw
->GetId() );
401 keyEvent
.SetEventType( wxEVT_CHAR_HOOK
);
402 if( tlw
->HandleWindowEvent( keyEvent
) )
404 *continueToDispatch
= False
;
409 // For simplicity, OnKeyDown is the same as OnChar
410 // TODO: filter modifier key presses from OnChar
411 keyEvent
.SetEventType( wxEVT_KEY_DOWN
);
413 // Only process OnChar if OnKeyDown didn't swallow it
414 if( !tlw
->HandleWindowEvent( keyEvent
) )
416 keyEvent
.SetEventType( wxEVT_CHAR
);
417 tlw
->HandleWindowEvent( keyEvent
);
424 *continueToDispatch
= True
;