1 ///////////////////////////////////////////////////////////////////////////////
2 // Name: x11/toplevel.cpp
3 // Purpose: implements wxTopLevelWindow for X11
4 // Author: Julian Smart
8 // Copyright: (c) 2002 Julian Smart
9 // License: wxWindows licence
10 ///////////////////////////////////////////////////////////////////////////////
12 // ============================================================================
14 // ============================================================================
16 // ----------------------------------------------------------------------------
18 // ----------------------------------------------------------------------------
21 #pragma implementation "toplevel.h"
24 // For compilers that support precompilation, includes "wx.h".
25 #include "wx/wxprec.h"
33 #include "wx/toplevel.h"
34 #include "wx/string.h"
40 #include "wx/x11/private.h"
41 #include "X11/Xatom.h"
42 #include "X11/Xutil.h"
44 // Set the window manager decorations according to the
45 // given wxWindows style
47 static bool SetWMDecorations(Widget w
, long style
);
49 static bool MWMIsRunning(Window w
);
51 // ----------------------------------------------------------------------------
52 // wxTopLevelWindowX11 creation
53 // ----------------------------------------------------------------------------
55 void wxTopLevelWindowX11::Init()
58 m_maximizeOnShow
= FALSE
;
60 // unlike (almost?) all other windows, frames are created hidden
63 // Data to save/restore when calling ShowFullScreen
65 m_fsIsMaximized
= FALSE
;
66 m_fsIsShowing
= FALSE
;
69 bool wxTopLevelWindowX11::CreateDialog(const wxString
& title
,
77 bool wxTopLevelWindowX11::CreateFrame(const wxString
& title
,
85 bool wxTopLevelWindowX11::Create(wxWindow
*parent
,
87 const wxString
& title
,
96 m_windowStyle
= style
;
100 m_windowId
= id
== -1 ? NewControlId() : id
;
102 wxTopLevelWindows
.Append(this);
104 Display
*xdisplay
= wxGlobalDisplay();
105 int xscreen
= DefaultScreen( xdisplay
);
106 Visual
*xvisual
= DefaultVisual( xdisplay
, xscreen
);
107 Window xparent
= RootWindow( xdisplay
, xscreen
);
109 XSetWindowAttributes xattributes
;
110 XSizeHints size_hints
;
113 long xattributes_mask
=
115 CWBorderPixel
| CWBackPixel
;
116 xattributes
.background_pixel
= BlackPixel( xdisplay
, xscreen
);
117 xattributes
.border_pixel
= BlackPixel( xdisplay
, xscreen
);
118 xattributes
.override_redirect
= False
;
120 Window xwindow
= XCreateWindow( xdisplay
, xparent
, pos
.x
, pos
.y
, size
.x
, size
.y
,
121 0, DefaultDepth(xdisplay
,xscreen
), InputOutput
, xvisual
, xattributes_mask
, &xattributes
);
123 XSelectInput( xdisplay
, xwindow
,
124 ExposureMask
| KeyPressMask
| KeyReleaseMask
| ButtonPressMask
| ButtonReleaseMask
|
125 ButtonMotionMask
| EnterWindowMask
| LeaveWindowMask
| PointerMotionMask
|
126 KeymapStateMask
| FocusChangeMask
| ColormapChangeMask
| StructureNotifyMask
|
127 PropertyChangeMask
);
129 wxAddWindowToTable( xwindow
, (wxWindow
*) this );
131 XSetTransientForHint( xdisplay
, xwindow
, xparent
);
133 size_hints
.flags
= PSize
;
134 size_hints
.width
= size
.x
;
135 size_hints
.height
= size
.y
;
136 XSetWMNormalHints( xdisplay
, xwindow
, &size_hints
);
138 wm_hints
.flags
= InputHint
| StateHint
/* | WindowGroupHint */;
139 wm_hints
.input
= True
;
140 wm_hints
.initial_state
= NormalState
;
141 XSetWMHints( xdisplay
, xwindow
, &wm_hints
);
143 Atom wm_delete_window
= XInternAtom( xdisplay
, "WM_DELETE_WINDOW", False
);
144 XSetWMProtocols( xdisplay
, xwindow
, &wm_delete_window
, 1);
147 SetWMDecorations((Window
) GetMainWindow(), style
);
155 wxTopLevelWindowX11::~wxTopLevelWindowX11()
157 wxTopLevelWindows
.DeleteObject(this);
159 // If this is the last top-level window, exit.
160 if ( wxTheApp
&& (wxTopLevelWindows
.Number() == 0) )
162 wxTheApp
->SetTopWindow(NULL
);
164 if (wxTheApp
->GetExitOnFrameDelete())
166 // Signal to the app that we're going to close
167 wxTheApp
->ExitMainLoop();
172 // ----------------------------------------------------------------------------
173 // wxTopLevelWindowX11 showing
174 // ----------------------------------------------------------------------------
176 bool wxTopLevelWindowX11::Show(bool show
)
178 if ( !wxWindowBase::Show(show
) )
181 return wxWindowX11::Show(show
);
184 // ----------------------------------------------------------------------------
185 // wxTopLevelWindowX11 maximize/minimize
186 // ----------------------------------------------------------------------------
188 void wxTopLevelWindowX11::Maximize(bool maximize
)
193 bool wxTopLevelWindowX11::IsMaximized() const
199 void wxTopLevelWindowX11::Iconize(bool iconize
)
201 if (!m_iconized
&& GetMainWindow())
203 if (XIconifyWindow(wxGlobalDisplay(),
204 (Window
) GetMainWindow(), DefaultScreen(wxGlobalDisplay())) != 0)
209 bool wxTopLevelWindowX11::IsIconized() const
214 void wxTopLevelWindowX11::Restore()
216 // This is the way to deiconify the window, according to the X FAQ
217 if (m_iconized
&& GetMainWindow())
219 XMapWindow(wxGlobalDisplay(), (Window
) GetMainWindow());
224 // ----------------------------------------------------------------------------
225 // wxTopLevelWindowX11 fullscreen
226 // ----------------------------------------------------------------------------
228 bool wxTopLevelWindowX11::ShowFullScreen(bool show
, long style
)
235 m_fsIsShowing
= TRUE
;
247 m_fsIsShowing
= FALSE
;
254 // ----------------------------------------------------------------------------
255 // wxTopLevelWindowX11 misc
256 // ----------------------------------------------------------------------------
258 void wxTopLevelWindowX11::SetIcon(const wxIcon
& icon
)
261 wxTopLevelWindowBase::SetIcon(icon
);
263 if (icon
.Ok() && GetMainWindow())
266 XWMHints
*wmHints
= XAllocWMHints();
267 wmHints
.icon_pixmap
= (Pixmap
) icon
.GetPixmap();
269 wmHints
.flags
= IconPixmapHint
;
273 wmHints
.flags
|= IconMaskHint
;
274 wmHints
.icon_mask
= (Pixmap
) icon
.GetMask()->GetPixmap();
277 XSetWMHints(wxGlobalDisplay(), (Window
) GetMainWindow(),
284 void wxTopLevelWindowX11::SetTitle(const wxString
& title
)
289 XStoreName(wxGlobalDisplay(), (Window
) GetMainWindow(),
290 (const char*) title
);
291 XSetIconName(wxGlobalDisplay(), (Window
) GetMainWindow(),
292 (const char*) title
);
294 XTextProperty textProperty
;
295 textProperty
.value
= (unsigned char*) title
;
296 textProperty
.encoding
= XA_STRING
;
297 textProperty
.format
= 8;
298 textProperty
.nitems
= 1;
300 XSetTextProperty(wxGlobalDisplay(), (Window
) GetMainWindow(),
301 & textProperty
, WM_NAME
);
306 wxString
wxTopLevelWindowX11::GetTitle() const
311 #ifndef MWM_DECOR_BORDER
312 /* bit definitions for MwmHints.flags */
313 #define MWM_HINTS_FUNCTIONS (1L << 0)
314 #define MWM_HINTS_DECORATIONS (1L << 1)
315 #define MWM_HINTS_INPUT_MODE (1L << 2)
316 #define MWM_HINTS_STATUS (1L << 3)
318 #define MWM_DECOR_ALL (1L << 0)
319 #define MWM_DECOR_BORDER (1L << 1)
320 #define MWM_DECOR_RESIZEH (1L << 2)
321 #define MWM_DECOR_TITLE (1L << 3)
322 #define MWM_DECOR_MENU (1L << 4)
323 #define MWM_DECOR_MINIMIZE (1L << 5)
324 #define MWM_DECOR_MAXIMIZE (1L << 6)
334 #define PROP_MOTIF_WM_HINTS_ELEMENTS 5
336 // Set the window manager decorations according to the
337 // given wxWindows style
339 static bool SetWMDecorations(Widget w
, long style
)
341 if (!MWMIsRunning(w
))
344 Atom mwm_wm_hints
= XInternAtom(wxGlobalDisplay(),"_MOTIF_WM_HINTS", False
);
347 hints
.decorations
= 0;
349 if (style
& wxRESIZE_BORDER
)
351 hints
.flags
|= MWM_HINTS_DECORATIONS
;
352 hints
.decorations
|= MWM_DECOR_RESIZEH
;
355 if (style
& wxSYSTEM_MENU
)
357 hints
.flags
|= MWM_HINTS_DECORATIONS
;
358 hints
.decorations
|= MWM_DECOR_MENU
;
361 if ((style
& wxCAPTION
) ||
362 (style
& wxTINY_CAPTION_HORIZ
) ||
363 (style
& wxTINY_CAPTION_VERT
))
365 hints
.flags
|= MWM_HINTS_DECORATIONS
;
366 hints
.decorations
|= MWM_DECOR_TITLE
;
369 if (style
& wxTHICK_FRAME
)
371 hints
.flags
|= MWM_HINTS_DECORATIONS
;
372 hints
.decorations
|= MWM_DECOR_BORDER
;
375 if (style
& wxTHICK_FRAME
)
377 hints
.flags
|= MWM_HINTS_DECORATIONS
;
378 hints
.decorations
|= MWM_DECOR_BORDER
;
381 if (style
& wxMINIMIZE_BOX
)
383 hints
.flags
|= MWM_HINTS_DECORATIONS
;
384 hints
.decorations
|= MWM_DECOR_MINIMIZE
;
387 if (style
& wxMAXIMIZE_BOX
)
389 hints
.flags
|= MWM_HINTS_DECORATIONS
;
390 hints
.decorations
|= MWM_DECOR_MAXIMIZE
;
393 XChangeProperty(wxGlobalDisplay(),
395 mwm_wm_hints
, mem_wm_hints
,
397 (unsigned char *) &hints
, PROP_MOTIF_WM_HINTS_ELEMENTS
);
403 static bool MWMIsRunning(Window w
)
405 Display
*dpy
= (Display
*)wxGetDisplay();
406 Atom motifWmInfo
= XInternAtom(dpy
, "_MOTIF_WM_INFO", False
);
408 unsigned long length
, bytesafter
;
409 unsigned char value
[20];
410 unsigned char *ptr
= &value
[0];
414 type
= format
= length
= 0;
417 ret
= XGetWindowProperty(wxGlobalDisplay(), w
, motifWmInfo
,
418 0L, 2, False
, motifWmInfo
,
419 &type
, &format
, &length
, &bytesafter
, &ptr
);
421 return (ret
== Success
);