]>
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(__APPLE__)
21 #pragma implementation "toplevel.h"
24 #include "wx/toplevel.h"
28 #pragma message disable nosimpint
32 #include <X11/Shell.h>
41 #pragma message enable nosimpint
44 #include "wx/motif/private.h"
46 wxList wxModelessWindows
; // Frames and modeless dialogs
48 // ---------------------------------------------------------------------------
50 // ---------------------------------------------------------------------------
52 static void wxCloseTLWCallback( Widget widget
, XtPointer client_data
,
53 XmAnyCallbackStruct
*cbs
);
54 static void wxTLWEventHandler( Widget wid
,
55 XtPointer client_data
,
57 Boolean
*continueToDispatch
);
59 // ===========================================================================
60 // wxTopLevelWindowMotif implementation
61 // ===========================================================================
63 wxTopLevelWindowMotif::~wxTopLevelWindowMotif()
65 wxTopLevelWindows
.DeleteObject(this);
67 if ( (GetWindowStyleFlag() & wxDIALOG_MODAL
) != wxDIALOG_MODAL
)
68 wxModelessWindows
.DeleteObject(this);
70 m_icons
.m_icons
.Empty();
74 // MessageDialog and FileDialog do not have a client widget
75 if( GetClientWidget() )
77 XtRemoveEventHandler( (Widget
)GetClientWidget(),
78 ButtonPressMask
| ButtonReleaseMask
|
79 PointerMotionMask
| KeyPressMask
,
87 SetMainWidget( (WXWidget
)0 );
89 // If this is the last top-level window, exit.
90 if (wxTheApp
&& (wxTopLevelWindows
.Number() == 0))
92 wxTheApp
->SetTopWindow(NULL
);
94 if (wxTheApp
->GetExitOnFrameDelete())
96 wxTheApp
->ExitMainLoop();
101 void wxTopLevelWindowMotif::Init()
106 bool wxTopLevelWindowMotif::Create( wxWindow
*parent
, wxWindowID id
,
107 const wxString
& title
,
111 const wxString
& name
)
114 m_windowStyle
= style
;
117 parent
->AddChild(this);
119 wxTopLevelWindows
.Append(this);
121 m_windowId
= ( id
> -1 ) ? id
: NewControlId();
123 bool retval
= DoCreate( parent
, id
, title
, pos
, size
, style
, name
);
125 if( !retval
) return FALSE
;
127 // Intercept CLOSE messages from the window manager
128 Widget shell
= (Widget
)GetShellWidget();
129 Atom WM_DELETE_WINDOW
= XmInternAtom( XtDisplay( shell
),
130 "WM_DELETE_WINDOW", False
);
132 // Remove and add WM_DELETE_WINDOW so ours is only handler
133 // This only appears to be necessary for wxDialog, but does not hurt
135 XmRemoveWMProtocols( shell
, &WM_DELETE_WINDOW
, 1 );
136 XmAddWMProtocols( shell
, &WM_DELETE_WINDOW
, 1 );
137 XmActivateWMProtocol( shell
, WM_DELETE_WINDOW
);
139 // Modified Steve Hammes for Motif 2.0
140 #if (XmREVISION > 1 || XmVERSION > 1)
141 XmAddWMProtocolCallback( shell
, WM_DELETE_WINDOW
,
142 (XtCallbackProc
)wxCloseTLWCallback
,
144 #elif XmREVISION == 1
145 XmAddWMProtocolCallback( shell
, WM_DELETE_WINDOW
,
146 (XtCallbackProc
)wxCloseTLWCallback
,
149 XmAddWMProtocolCallback( shell
, WM_DELETE_WINDOW
,
150 (void (*)())wxCloseTLWCallback
, (caddr_t
)this );
153 // This patch come from Torsten Liermann lier@lier1.muc.de
154 if( XmIsMotifWMRunning( shell
) )
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
& wxTHICK_FRAME
)
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::Raise()
198 Widget top
= (Widget
) GetTopWidget();
199 Window parent_window
= XtWindow( top
),
200 next_parent
= XtWindow( top
),
201 root
= RootWindowOfScreen( XtScreen( top
) );
202 // search for the parent that is child of ROOT, because the WM may
203 // reparent twice and notify only the next parent (like FVWM)
204 while( next_parent
!= root
)
209 parent_window
= next_parent
;
210 XQueryTree( XtDisplay( top
), parent_window
, &root
,
211 &next_parent
, &theChildren
, &n
);
212 XFree( theChildren
); // not needed
214 XRaiseWindow( XtDisplay( top
), parent_window
);
217 void wxTopLevelWindowMotif::Lower()
219 Widget top
= (Widget
) GetTopWidget();
220 Window parent_window
= XtWindow( top
),
221 next_parent
= XtWindow( top
),
222 root
= RootWindowOfScreen( XtScreen( top
) );
223 // search for the parent that is child of ROOT, because the WM may
224 // reparent twice and notify only the next parent (like FVWM)
225 while( next_parent
!= root
)
230 parent_window
= next_parent
;
231 XQueryTree( XtDisplay( top
), parent_window
, &root
,
232 &next_parent
, &theChildren
, &n
);
233 XFree( theChildren
); // not needed
235 XLowerWindow( XtDisplay( top
), parent_window
);
238 static inline Widget
GetShell( const wxTopLevelWindowMotif
* tlw
)
240 Widget main
= (Widget
) tlw
->GetMainWidget();
241 if( !main
) return (Widget
) NULL
;
243 return XtParent( main
);
246 WXWidget
wxTopLevelWindowMotif::GetShellWidget() const
248 return (WXWidget
) GetShell( this );
251 bool wxTopLevelWindowMotif::ShowFullScreen( bool show
,
252 long style
= wxFULLSCREEN_ALL
)
258 bool wxTopLevelWindowMotif::IsFullScreen() const
264 void wxTopLevelWindowMotif::Restore()
266 Widget shell
= GetShell( this );
269 XtVaSetValues( shell
,
274 void wxTopLevelWindowMotif::Iconize( bool iconize
= TRUE
)
276 Widget shell
= GetShell( this );
282 XtVaSetValues( shell
,
283 XmNiconic
, (Boolean
)iconize
,
287 bool wxTopLevelWindowMotif::IsIconized() const
289 Widget shell
= GetShell( this );
295 XtVaGetValues( shell
,
302 void wxTopLevelWindowMotif::Maximize( bool maximize
= TRUE
)
310 bool wxTopLevelWindowMotif::IsMaximized() const
315 // ---------------------------------------------------------------------------
316 // Callback definition
317 // ---------------------------------------------------------------------------
319 // Handle a close event from the window manager
320 static void wxCloseTLWCallback( Widget
WXUNUSED(widget
), XtPointer client_data
,
321 XmAnyCallbackStruct
*WXUNUSED(cbs
) )
323 wxTopLevelWindowMotif
* tlw
= (wxTopLevelWindowMotif
*)client_data
;
324 wxCloseEvent
closeEvent( wxEVT_CLOSE_WINDOW
, tlw
->GetId() );
325 closeEvent
.SetEventObject( tlw
);
327 // May delete the dialog (with delayed deletion)
328 tlw
->GetEventHandler()->ProcessEvent(closeEvent
);
331 void wxTLWEventHandler( Widget wid
,
332 XtPointer
WXUNUSED(client_data
),
334 Boolean
* continueToDispatch
)
336 wxTopLevelWindowMotif
* tlw
=
337 (wxTopLevelWindowMotif
*)wxGetWindowFromTable( wid
);
341 wxMouseEvent
wxevent( wxEVT_NULL
);
343 if( wxTranslateMouseEvent( wxevent
, tlw
, wid
, event
) )
345 wxevent
.SetEventObject( tlw
);
346 wxevent
.SetId( tlw
->GetId() );
347 tlw
->GetEventHandler()->ProcessEvent( wxevent
);
351 // An attempt to implement OnCharHook by calling OnCharHook first;
352 // if this returns TRUE, set continueToDispatch to False
353 // (don't continue processing).
354 // Otherwise set it to True and call OnChar.
355 wxKeyEvent
keyEvent( wxEVT_CHAR
);
356 if( wxTranslateKeyEvent( keyEvent
, tlw
, wid
, event
))
358 keyEvent
.SetEventObject( tlw
);
359 keyEvent
.SetId( tlw
->GetId() );
360 keyEvent
.SetEventType( wxEVT_CHAR_HOOK
);
361 if( tlw
->GetEventHandler()->ProcessEvent( keyEvent
) )
363 *continueToDispatch
= False
;
368 // For simplicity, OnKeyDown is the same as OnChar
369 // TODO: filter modifier key presses from OnChar
370 keyEvent
.SetEventType( wxEVT_KEY_DOWN
);
372 // Only process OnChar if OnKeyDown didn't swallow it
373 if( !tlw
->GetEventHandler()->ProcessEvent( keyEvent
) )
375 keyEvent
.SetEventType( wxEVT_CHAR
);
376 tlw
->GetEventHandler()->ProcessEvent( keyEvent
);
383 *continueToDispatch
= True
;