]>
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 #define XtDisplay XTDISPLAY
29 #define XtParent XTPARENT
30 #define XtScreen XTSCREEN
31 #define XtWindow XTWINDOW
32 #pragma message disable nosimpint
36 #include <X11/Shell.h>
45 #pragma message enable nosimpint
48 #include "wx/motif/private.h"
50 wxList wxModelessWindows
; // Frames and modeless dialogs
52 // ---------------------------------------------------------------------------
54 // ---------------------------------------------------------------------------
56 static void wxCloseTLWCallback( Widget widget
, XtPointer client_data
,
57 XmAnyCallbackStruct
*cbs
);
58 static void wxTLWEventHandler( Widget wid
,
59 XtPointer client_data
,
61 Boolean
*continueToDispatch
);
63 // ===========================================================================
64 // wxTopLevelWindowMotif implementation
65 // ===========================================================================
67 void wxTopLevelWindowMotif::PreDestroy()
69 wxTopLevelWindows
.DeleteObject(this);
71 if ( (GetWindowStyleFlag() & wxDIALOG_MODAL
) != wxDIALOG_MODAL
)
72 wxModelessWindows
.DeleteObject(this);
74 m_icons
.m_icons
.Empty();
78 // MessageDialog and FileDialog do not have a client widget
79 if( GetClientWidget() )
81 XtRemoveEventHandler( (Widget
)GetClientWidget(),
82 ButtonPressMask
| ButtonReleaseMask
|
83 PointerMotionMask
| KeyPressMask
,
90 wxTopLevelWindowMotif::~wxTopLevelWindowMotif()
92 SetMainWidget( (WXWidget
)0 );
94 // If this is the last top-level window, exit.
95 if (wxTheApp
&& (wxTopLevelWindows
.GetCount() == 0))
97 wxTheApp
->SetTopWindow(NULL
);
99 if (wxTheApp
->GetExitOnFrameDelete())
101 wxTheApp
->ExitMainLoop();
106 void wxTopLevelWindowMotif::Init()
111 bool wxTopLevelWindowMotif::Create( wxWindow
*parent
, wxWindowID id
,
112 const wxString
& title
,
116 const wxString
& name
)
119 m_windowStyle
= style
;
122 parent
->AddChild(this);
124 wxTopLevelWindows
.Append(this);
126 m_windowId
= ( id
> -1 ) ? id
: NewControlId();
128 bool retval
= DoCreate( parent
, id
, title
, pos
, size
, style
, name
);
130 if( !retval
) return FALSE
;
132 // Intercept CLOSE messages from the window manager
133 Widget shell
= (Widget
)GetShellWidget();
134 Atom WM_DELETE_WINDOW
= XmInternAtom( XtDisplay( shell
),
135 "WM_DELETE_WINDOW", False
);
137 // Remove and add WM_DELETE_WINDOW so ours is only handler
138 // This only appears to be necessary for wxDialog, but does not hurt
140 XmRemoveWMProtocols( shell
, &WM_DELETE_WINDOW
, 1 );
141 XmAddWMProtocols( shell
, &WM_DELETE_WINDOW
, 1 );
142 XmActivateWMProtocol( shell
, WM_DELETE_WINDOW
);
144 // Modified Steve Hammes for Motif 2.0
145 #if (XmREVISION > 1 || XmVERSION > 1)
146 XmAddWMProtocolCallback( shell
, WM_DELETE_WINDOW
,
147 (XtCallbackProc
)wxCloseTLWCallback
,
149 #elif XmREVISION == 1
150 XmAddWMProtocolCallback( shell
, WM_DELETE_WINDOW
,
151 (XtCallbackProc
)wxCloseTLWCallback
,
154 XmAddWMProtocolCallback( shell
, WM_DELETE_WINDOW
,
155 (void (*)())wxCloseTLWCallback
, (caddr_t
)this );
158 // This patch come from Torsten Liermann lier@lier1.muc.de
159 if( XmIsMotifWMRunning( shell
) )
162 if( m_windowStyle
& wxRESIZE_BORDER
)
163 decor
|= MWM_DECOR_RESIZEH
;
164 if( m_windowStyle
& wxSYSTEM_MENU
)
165 decor
|= MWM_DECOR_MENU
;
166 if( ( m_windowStyle
& wxCAPTION
) ||
167 ( m_windowStyle
& wxTINY_CAPTION_HORIZ
) ||
168 ( m_windowStyle
& wxTINY_CAPTION_VERT
) )
169 decor
|= MWM_DECOR_TITLE
;
170 if( m_windowStyle
& wxTHICK_FRAME
)
171 decor
|= MWM_DECOR_BORDER
;
172 if( m_windowStyle
& wxMINIMIZE_BOX
)
173 decor
|= MWM_DECOR_MINIMIZE
;
174 if( m_windowStyle
& wxMAXIMIZE_BOX
)
175 decor
|= MWM_DECOR_MAXIMIZE
;
177 XtVaSetValues( shell
,
178 XmNmwmDecorations
, decor
,
183 // This allows non-Motif window managers to support at least the
184 // no-decorations case.
185 if( ( m_windowStyle
& wxCAPTION
) != wxCAPTION
)
186 XtVaSetValues( shell
,
187 XmNoverrideRedirect
, TRUE
,
191 XtAddEventHandler( (Widget
)GetClientWidget(),
192 ButtonPressMask
| ButtonReleaseMask
|
193 PointerMotionMask
| KeyPressMask
,
201 void wxTopLevelWindowMotif::Raise()
203 Widget top
= (Widget
) GetTopWidget();
204 Window parent_window
= XtWindow( top
),
205 next_parent
= XtWindow( top
),
206 root
= RootWindowOfScreen( XtScreen( top
) );
207 // search for the parent that is child of ROOT, because the WM may
208 // reparent twice and notify only the next parent (like FVWM)
209 while( next_parent
!= root
)
214 parent_window
= next_parent
;
215 XQueryTree( XtDisplay( top
), parent_window
, &root
,
216 &next_parent
, &theChildren
, &n
);
217 XFree( theChildren
); // not needed
219 XRaiseWindow( XtDisplay( top
), parent_window
);
222 void wxTopLevelWindowMotif::Lower()
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 XLowerWindow( XtDisplay( top
), parent_window
);
243 static inline Widget
GetShell( const wxTopLevelWindowMotif
* tlw
)
245 Widget main
= (Widget
) tlw
->GetMainWidget();
246 if( !main
) return (Widget
) NULL
;
248 return XtParent( main
);
251 WXWidget
wxTopLevelWindowMotif::GetShellWidget() const
253 return (WXWidget
) GetShell( this );
256 bool wxTopLevelWindowMotif::ShowFullScreen( bool show
,
263 bool wxTopLevelWindowMotif::IsFullScreen() const
269 void wxTopLevelWindowMotif::Restore()
271 Widget shell
= GetShell( this );
274 XtVaSetValues( shell
,
279 void wxTopLevelWindowMotif::Iconize( bool iconize
)
281 Widget shell
= GetShell( this );
287 XtVaSetValues( shell
,
288 XmNiconic
, (Boolean
)iconize
,
292 bool wxTopLevelWindowMotif::IsIconized() const
294 Widget shell
= GetShell( this );
300 XtVaGetValues( shell
,
307 void wxTopLevelWindowMotif::Maximize( bool maximize
)
315 bool wxTopLevelWindowMotif::IsMaximized() const
320 void wxTopLevelWindowMotif::SetSizeHints( int minW
, int minH
,
324 wxTopLevelWindowBase::SetSizeHints( minW
, minH
, maxW
, maxH
, incW
, incH
);
329 if( minW
> -1 ) { XtSetArg( args
[count
], XmNminWidth
, minW
); ++count
; }
330 if( minH
> -1 ) { XtSetArg( args
[count
], XmNminHeight
, minH
); ++count
; }
331 if( maxW
> -1 ) { XtSetArg( args
[count
], XmNmaxWidth
, maxW
); ++count
; }
332 if( maxH
> -1 ) { XtSetArg( args
[count
], XmNmaxHeight
, maxH
); ++count
; }
333 if( incW
> -1 ) { XtSetArg( args
[count
], XmNwidthInc
, incW
); ++count
; }
334 if( incH
> -1 ) { XtSetArg( args
[count
], XmNheightInc
, incH
); ++count
; }
336 XtSetValues( (Widget
)GetShellWidget(), args
, count
);
339 bool wxTopLevelWindowMotif::SetShape( const wxRegion
& region
)
341 return wxDoSetShape( (Display
*)GetXDisplay(),
342 XtWindow( (Widget
)GetShellWidget() ),
346 // ---------------------------------------------------------------------------
347 // Callback definition
348 // ---------------------------------------------------------------------------
350 // Handle a close event from the window manager
351 static void wxCloseTLWCallback( Widget
WXUNUSED(widget
), XtPointer client_data
,
352 XmAnyCallbackStruct
*WXUNUSED(cbs
) )
354 wxTopLevelWindowMotif
* tlw
= (wxTopLevelWindowMotif
*)client_data
;
355 wxCloseEvent
closeEvent( wxEVT_CLOSE_WINDOW
, tlw
->GetId() );
356 closeEvent
.SetEventObject( tlw
);
358 // May delete the dialog (with delayed deletion)
359 tlw
->GetEventHandler()->ProcessEvent(closeEvent
);
362 void wxTLWEventHandler( Widget wid
,
363 XtPointer
WXUNUSED(client_data
),
365 Boolean
* continueToDispatch
)
367 wxTopLevelWindowMotif
* tlw
=
368 (wxTopLevelWindowMotif
*)wxGetWindowFromTable( wid
);
372 wxMouseEvent
wxevent( wxEVT_NULL
);
374 if( wxTranslateMouseEvent( wxevent
, tlw
, wid
, event
) )
376 wxevent
.SetEventObject( tlw
);
377 wxevent
.SetId( tlw
->GetId() );
378 tlw
->GetEventHandler()->ProcessEvent( wxevent
);
382 // An attempt to implement OnCharHook by calling OnCharHook first;
383 // if this returns TRUE, set continueToDispatch to False
384 // (don't continue processing).
385 // Otherwise set it to True and call OnChar.
386 wxKeyEvent
keyEvent( wxEVT_CHAR
);
387 if( wxTranslateKeyEvent( keyEvent
, tlw
, wid
, event
))
389 keyEvent
.SetEventObject( tlw
);
390 keyEvent
.SetId( tlw
->GetId() );
391 keyEvent
.SetEventType( wxEVT_CHAR_HOOK
);
392 if( tlw
->GetEventHandler()->ProcessEvent( keyEvent
) )
394 *continueToDispatch
= False
;
399 // For simplicity, OnKeyDown is the same as OnChar
400 // TODO: filter modifier key presses from OnChar
401 keyEvent
.SetEventType( wxEVT_KEY_DOWN
);
403 // Only process OnChar if OnKeyDown didn't swallow it
404 if( !tlw
->GetEventHandler()->ProcessEvent( keyEvent
) )
406 keyEvent
.SetEventType( wxEVT_CHAR
);
407 tlw
->GetEventHandler()->ProcessEvent( keyEvent
);
414 *continueToDispatch
= True
;