]> git.saurik.com Git - wxWidgets.git/blame - src/x11/toplevel.cpp
Fix wxHtmlHelpData::SetTempDir() to behave correctly without trailing slash.
[wxWidgets.git] / src / x11 / toplevel.cpp
CommitLineData
1b0fb34b 1///////////////////////////////////////////////////////////////////////////////
ffd84c94 2// Name: src/x11/toplevel.cpp
1b0fb34b 3// Purpose: implements wxTopLevelWindow for X11
83df96d6
JS
4// Author: Julian Smart
5// Modified by:
1b0fb34b 6// Created: 24.09.01
1b0fb34b 7// Copyright: (c) 2002 Julian Smart
526954c5 8// Licence: wxWindows licence
1b0fb34b 9///////////////////////////////////////////////////////////////////////////////
83df96d6
JS
10
11// ============================================================================
12// declarations
13// ============================================================================
14
15// ----------------------------------------------------------------------------
16// headers
17// ----------------------------------------------------------------------------
18
1b0fb34b
JS
19// For compilers that support precompilation, includes "wx.h".
20#include "wx/wxprec.h"
83df96d6 21
1b0fb34b
JS
22#ifdef __BORLANDC__
23 #pragma hdrstop
83df96d6
JS
24#endif
25
1832043f
WS
26#include "wx/toplevel.h"
27
1b0fb34b
JS
28#ifndef WX_PRECOMP
29 #include "wx/app.h"
1b0fb34b
JS
30 #include "wx/string.h"
31 #include "wx/log.h"
32 #include "wx/intl.h"
33 #include "wx/frame.h"
e5053ade
JS
34 #include "wx/menu.h"
35 #include "wx/statusbr.h"
9eddec69 36 #include "wx/settings.h"
1b0fb34b 37#endif //WX_PRECOMP
83df96d6 38
1b0fb34b 39#include "wx/x11/private.h"
2034b748 40#include "X11/Xutil.h"
b513212d 41
f618020a
MB
42#include "wx/unix/utilsx11.h"
43
1b0b798d 44bool wxMWMIsRunning(Window w);
b513212d 45
83df96d6 46// ----------------------------------------------------------------------------
1b0fb34b 47// wxTopLevelWindowX11 creation
83df96d6
JS
48// ----------------------------------------------------------------------------
49
1b0fb34b
JS
50void wxTopLevelWindowX11::Init()
51{
52 m_iconized =
ffd84c94 53 m_maximizeOnShow = false;
83df96d6 54
1b0fb34b 55 // unlike (almost?) all other windows, frames are created hidden
ffd84c94 56 m_isShown = false;
83df96d6 57
1b0fb34b
JS
58 // Data to save/restore when calling ShowFullScreen
59 m_fsStyle = 0;
ffd84c94
WS
60 m_fsIsMaximized = false;
61 m_fsIsShowing = false;
62
63 m_needResizeInIdle = false;
64
65 m_x = wxDefaultCoord;
66 m_y = wxDefaultCoord;
c2c0dabf
RR
67 m_width = 20;
68 m_height = 20;
1b0fb34b 69}
83df96d6 70
1b0fb34b
JS
71bool wxTopLevelWindowX11::Create(wxWindow *parent,
72 wxWindowID id,
73 const wxString& title,
74 const wxPoint& pos,
75 const wxSize& size,
76 long style,
77 const wxString& name)
78{
79 // init our fields
80 Init();
83df96d6
JS
81
82 m_windowStyle = style;
b28d3abf 83 m_parent = parent;
83df96d6 84
1b0fb34b 85 SetName(name);
83df96d6 86
ffd84c94 87 m_windowId = id == wxID_ANY ? NewControlId() : id;
83df96d6 88
b28d3abf
JS
89 if (parent)
90 parent->AddChild(this);
91
1b0fb34b 92 wxTopLevelWindows.Append(this);
ffd84c94 93
952ebeba
RR
94 Display *xdisplay = wxGlobalDisplay();
95 int xscreen = DefaultScreen( xdisplay );
96 Visual *xvisual = DefaultVisual( xdisplay, xscreen );
97 Window xparent = RootWindow( xdisplay, xscreen );
2034b748 98 Colormap cm = DefaultColormap( xdisplay, xscreen );
ffd84c94 99
7e085304
RR
100 if (GetExtraStyle() & wxTOPLEVEL_EX_DIALOG)
101 m_backgroundColour = wxSystemSettings::GetColour(wxSYS_COLOUR_BTNFACE);
102 else
103 m_backgroundColour = wxSystemSettings::GetColour(wxSYS_COLOUR_APPWORKSPACE);
2034b748 104 m_backgroundColour.CalcPixel( (WXColormap) cm );
ffd84c94
WS
105 m_hasBgCol = true;
106
c2c0dabf
RR
107 m_x = pos.x;
108 if (m_x < -1)
109 m_x = 10;
ffd84c94 110
c2c0dabf
RR
111 m_y = pos.y;
112 if (m_y < 0)
113 m_y = 10;
ffd84c94 114
c2c0dabf
RR
115 m_width = size.x;
116 if (m_width < 0)
117 m_width = 500;
ffd84c94 118
c2c0dabf
RR
119 m_height = size.y;
120 if (m_height < 0)
121 m_height = 380;
ffd84c94 122
461e93f9 123#if !wxUSE_NANOX
952ebeba 124 XSetWindowAttributes xattributes;
ffd84c94 125
952ebeba 126 long xattributes_mask =
952ebeba 127 CWBorderPixel | CWBackPixel;
461e93f9 128
2034b748 129 xattributes.background_pixel = m_backgroundColour.GetPixel();
952ebeba 130 xattributes.border_pixel = BlackPixel( xdisplay, xscreen );
5e29f97a 131
ab6b6b15
RR
132 if (HasFlag( wxNO_BORDER ))
133 {
134 xattributes_mask |= CWOverrideRedirect;
135 xattributes.override_redirect = True;
136 }
ffd84c94 137
e441e1f4 138 if (!HasFlag( wxFULL_REPAINT_ON_RESIZE ))
2f12683e
RR
139 {
140 xattributes_mask |= CWBitGravity;
065722d7 141 xattributes.bit_gravity = NorthWestGravity;
2f12683e 142 }
ffd84c94 143
2f12683e 144 xattributes_mask |= CWEventMask;
ffd84c94 145 xattributes.event_mask =
2f12683e
RR
146 ExposureMask | KeyPressMask | KeyReleaseMask | ButtonPressMask | ButtonReleaseMask |
147 ButtonMotionMask | EnterWindowMask | LeaveWindowMask | PointerMotionMask |
148 KeymapStateMask | FocusChangeMask | ColormapChangeMask | StructureNotifyMask |
149 PropertyChangeMask;
ffd84c94 150
c2c0dabf 151 Window xwindow = XCreateWindow( xdisplay, xparent, m_x, m_y, m_width, m_height,
2f12683e
RR
152 0, DefaultDepth(xdisplay,xscreen), InputOutput, xvisual, xattributes_mask, &xattributes );
153#else
461e93f9
JS
154 long backColor, foreColor;
155 backColor = GR_RGB(m_backgroundColour.Red(), m_backgroundColour.Green(), m_backgroundColour.Blue());
156 foreColor = GR_RGB(m_foregroundColour.Red(), m_foregroundColour.Green(), m_foregroundColour.Blue());
ffd84c94 157
c2c0dabf 158 Window xwindow = XCreateWindowWithColor( xdisplay, xparent, m_x, m_y, m_width, m_height,
461e93f9 159 0, 0, InputOutput, xvisual, backColor, foreColor);
461e93f9 160#endif
2f12683e 161
ab6b6b15
RR
162 m_mainWindow = (WXWindow) xwindow;
163 m_clientWindow = (WXWindow) xwindow;
164 wxAddWindowToTable( xwindow, (wxWindow*) this );
307be31a 165
256d631a 166#if wxUSE_NANOX
461e93f9 167 XSelectInput( xdisplay, xwindow,
2f12683e 168 GR_EVENT_MASK_CLOSE_REQ |
70b8ab77
JS
169 ExposureMask |
170 KeyPressMask |
171 KeyReleaseMask |
172 ButtonPressMask |
173 ButtonReleaseMask |
174 ButtonMotionMask |
175 EnterWindowMask |
176 LeaveWindowMask |
177 PointerMotionMask |
178 KeymapStateMask |
179 FocusChangeMask |
180 ColormapChangeMask |
181 StructureNotifyMask |
182 PropertyChangeMask
183 );
2f12683e 184#endif
307be31a 185
ba696cfa
RR
186 // Set background to None which will prevent X11 from clearing the
187 // background completely.
188 XSetWindowBackgroundPixmap( xdisplay, xwindow, None );
189
461e93f9 190#if !wxUSE_NANOX
ab6b6b15 191 if (HasFlag( wxSTAY_ON_TOP ))
7e4501ee 192 {
ab6b6b15
RR
193 Window xroot = RootWindow( xdisplay, xscreen );
194 XSetTransientForHint( xdisplay, xwindow, xroot );
195 }
196 else
197 {
198 if (GetExtraStyle() & wxTOPLEVEL_EX_DIALOG)
199 {
679918f9 200 if (GetParent() && GetParent()->X11GetMainWindow())
ab6b6b15 201 {
679918f9 202 Window xparentwindow = (Window) GetParent()->X11GetMainWindow();
ab6b6b15
RR
203 XSetTransientForHint( xdisplay, xwindow, xparentwindow );
204 }
7e4501ee
RR
205 }
206 }
207
c2c0dabf 208 XSizeHints size_hints;
065722d7 209 size_hints.flags = PSize | PPosition | PWinGravity;
c2c0dabf
RR
210 size_hints.x = m_x;
211 size_hints.y = m_y;
212 size_hints.width = m_width;
213 size_hints.height = m_height;
065722d7 214 size_hints.win_gravity = NorthWestGravity;
952ebeba 215 XSetWMNormalHints( xdisplay, xwindow, &size_hints);
ffd84c94 216
461e93f9 217 XWMHints wm_hints;
ab6b6b15
RR
218 wm_hints.flags = InputHint | StateHint;
219 if (GetParent())
ffd84c94 220 {
ab6b6b15 221 wm_hints.flags |= WindowGroupHint;
679918f9 222 wm_hints.window_group = (Window) GetParent()->X11GetMainWindow();
ab6b6b15 223 }
952ebeba
RR
224 wm_hints.input = True;
225 wm_hints.initial_state = NormalState;
226 XSetWMHints( xdisplay, xwindow, &wm_hints);
461e93f9 227
7e4501ee
RR
228 Atom wm_protocols[2];
229 wm_protocols[0] = XInternAtom( xdisplay, "WM_DELETE_WINDOW", False );
230 wm_protocols[1] = XInternAtom( xdisplay, "WM_TAKE_FOCUS", False );
231 XSetWMProtocols( xdisplay, xwindow, wm_protocols, 2);
1016f0de 232
461e93f9 233#endif
ffd84c94 234
7e4501ee 235 wxSetWMDecorations( xwindow, style);
83df96d6 236
b513212d 237 SetTitle(title);
ffd84c94
WS
238
239 return true;
83df96d6
JS
240}
241
1b0fb34b 242wxTopLevelWindowX11::~wxTopLevelWindowX11()
83df96d6 243{
83df96d6 244 wxTopLevelWindows.DeleteObject(this);
83df96d6 245
1b0fb34b 246 // If this is the last top-level window, exit.
09a1dffa 247 if ( wxTheApp && (wxTopLevelWindows.GetCount() == 0) )
83df96d6
JS
248 {
249 wxTheApp->SetTopWindow(NULL);
250
251 if (wxTheApp->GetExitOnFrameDelete())
252 {
253 // Signal to the app that we're going to close
254 wxTheApp->ExitMainLoop();
255 }
256 }
257}
258
77df2fbc
RR
259void wxTopLevelWindowX11::OnInternalIdle()
260{
261 wxWindow::OnInternalIdle();
ffd84c94 262
193e19cf
RR
263 // Do this only after the last idle event so that
264 // all windows have been updated before a new
265 // round of size events is sent
266 if (m_needResizeInIdle && !wxTheApp->Pending())
77df2fbc
RR
267 {
268 wxSizeEvent event( GetClientSize(), GetId() );
269 event.SetEventObject( this );
937013e0 270 HandleWindowEvent( event );
ffd84c94
WS
271
272 m_needResizeInIdle = false;
77df2fbc
RR
273 }
274}
275
1b0fb34b
JS
276// ----------------------------------------------------------------------------
277// wxTopLevelWindowX11 showing
278// ----------------------------------------------------------------------------
83df96d6 279
1b0fb34b 280bool wxTopLevelWindowX11::Show(bool show)
83df96d6 281{
e25f954b
JS
282 if (show)
283 {
284 wxSizeEvent event(GetSize(), GetId());
ffd84c94 285
e25f954b 286 event.SetEventObject(this);
937013e0 287 HandleWindowEvent(event);
ffd84c94
WS
288
289 m_needResizeInIdle = false;
e25f954b 290 }
7ded318b 291
df0e1b64 292 bool ret = wxWindowX11::Show(show);
ffd84c94 293
df0e1b64 294 return ret;
83df96d6
JS
295}
296
1b0fb34b
JS
297// ----------------------------------------------------------------------------
298// wxTopLevelWindowX11 maximize/minimize
299// ----------------------------------------------------------------------------
83df96d6 300
89954433 301void wxTopLevelWindowX11::Maximize(bool WXUNUSED(maximize))
83df96d6 302{
1b0fb34b 303 // TODO
83df96d6
JS
304}
305
1b0fb34b 306bool wxTopLevelWindowX11::IsMaximized() const
83df96d6 307{
1b0fb34b 308 // TODO
ffd84c94 309 return true;
83df96d6
JS
310}
311
1b0fb34b 312void wxTopLevelWindowX11::Iconize(bool iconize)
83df96d6 313{
89954433
VZ
314 if ( !iconize )
315 {
316 Restore();
317 return;
318 }
319
679918f9 320 if (!m_iconized && X11GetMainWindow())
b513212d
JS
321 {
322 if (XIconifyWindow(wxGlobalDisplay(),
679918f9 323 (Window) X11GetMainWindow(), DefaultScreen(wxGlobalDisplay())) != 0)
ffd84c94 324 m_iconized = true;
b513212d 325 }
83df96d6
JS
326}
327
1b0fb34b 328bool wxTopLevelWindowX11::IsIconized() const
83df96d6 329{
1b0fb34b 330 return m_iconized;
83df96d6
JS
331}
332
1b0fb34b 333void wxTopLevelWindowX11::Restore()
83df96d6 334{
b513212d 335 // This is the way to deiconify the window, according to the X FAQ
679918f9 336 if (m_iconized && X11GetMainWindow())
b513212d 337 {
679918f9 338 XMapWindow(wxGlobalDisplay(), (Window) X11GetMainWindow());
ffd84c94 339 m_iconized = false;
b513212d 340 }
83df96d6
JS
341}
342
1b0fb34b
JS
343// ----------------------------------------------------------------------------
344// wxTopLevelWindowX11 fullscreen
345// ----------------------------------------------------------------------------
83df96d6 346
1b0fb34b 347bool wxTopLevelWindowX11::ShowFullScreen(bool show, long style)
83df96d6 348{
1b0fb34b 349 if (show)
83df96d6 350 {
1b0fb34b 351 if (IsFullScreen())
ffd84c94 352 return false;
83df96d6 353
ffd84c94 354 m_fsIsShowing = true;
1b0fb34b 355 m_fsStyle = style;
83df96d6 356
1b0fb34b 357 // TODO
83df96d6 358
ffd84c94 359 return true;
83df96d6 360 }
1b0fb34b 361 else
83df96d6 362 {
1b0fb34b 363 if (!IsFullScreen())
ffd84c94 364 return false;
83df96d6 365
ffd84c94 366 m_fsIsShowing = false;
83df96d6 367
1b0fb34b 368 // TODO
ffd84c94 369 return true;
83df96d6
JS
370 }
371}
372
1b0fb34b
JS
373// ----------------------------------------------------------------------------
374// wxTopLevelWindowX11 misc
375// ----------------------------------------------------------------------------
83df96d6 376
f618020a 377void wxTopLevelWindowX11::DoSetIcon(const wxIcon& icon)
83df96d6 378{
a1b806b9 379 if (icon.IsOk() && X11GetMainWindow())
b513212d 380 {
ea098413 381#if !wxUSE_NANOX
b513212d 382 XWMHints *wmHints = XAllocWMHints();
6a44bffd 383 wmHints->icon_pixmap = (Pixmap) icon.GetPixmap();
b513212d 384
6a44bffd 385 wmHints->flags = IconPixmapHint;
b513212d
JS
386
387 if (icon.GetMask())
388 {
6a44bffd 389 wmHints->flags |= IconMaskHint;
a11672a4 390 wmHints->icon_mask = (Pixmap) icon.GetMask()->GetBitmap();
b513212d
JS
391 }
392
679918f9 393 XSetWMHints(wxGlobalDisplay(), (Window) X11GetMainWindow(), wmHints);
b513212d 394 XFree(wmHints);
461e93f9 395#endif
b513212d
JS
396 }
397}
398
f618020a
MB
399void wxTopLevelWindowX11::SetIcons(const wxIconBundle& icons )
400{
401 // this sets m_icon
402 wxTopLevelWindowBase::SetIcons( icons );
403
404 DoSetIcon( icons.GetIcon( -1 ) );
679918f9 405 wxSetIconsX11( wxGlobalDisplay(), X11GetMainWindow(), icons );
f618020a
MB
406}
407
f7f78039
MB
408bool wxTopLevelWindowX11::SetShape(const wxRegion& region)
409{
410 return wxDoSetShape( wxGlobalDisplay(),
679918f9 411 (Window)X11GetMainWindow(),
f7f78039
MB
412 region );
413}
414
b513212d
JS
415void wxTopLevelWindowX11::SetTitle(const wxString& title)
416{
417 m_title = title;
ffd84c94 418
679918f9 419 if (X11GetMainWindow())
b513212d 420 {
2b5f62a0
VZ
421#if wxUSE_UNICODE
422 // I wonder of e.g. Metacity takes UTF-8 here
679918f9 423 XStoreName(wxGlobalDisplay(), (Window) X11GetMainWindow(),
2b5f62a0 424 (const char*) title.ToAscii() );
679918f9 425 XSetIconName(wxGlobalDisplay(), (Window) X11GetMainWindow(),
2b5f62a0
VZ
426 (const char*) title.ToAscii() );
427#else
679918f9 428 XStoreName(wxGlobalDisplay(), (Window) X11GetMainWindow(),
b513212d 429 (const char*) title);
679918f9 430 XSetIconName(wxGlobalDisplay(), (Window) X11GetMainWindow(),
b513212d 431 (const char*) title);
2b5f62a0 432#endif
c2c0dabf
RR
433 }
434}
435
436wxString wxTopLevelWindowX11::GetTitle() const
437{
438 return m_title;
439}
b28d3abf 440
c2c0dabf
RR
441// For implementation purposes - sometimes decorations make the client area
442// smaller
443wxPoint wxTopLevelWindowX11::GetClientAreaOrigin() const
444{
445 // wxFrame::GetClientAreaOrigin
446 // does the required calculation already.
447 return wxPoint(0, 0);
448}
449
450void wxTopLevelWindowX11::DoGetClientSize( int *width, int *height ) const
451{
452 if (width)
453 *width = m_width;
454 if (height)
455 *height = m_height;
456}
457
e97d2576
RR
458void wxTopLevelWindowX11::DoGetSize( int *width, int *height ) const
459{
460 // TODO add non-client size
461
462 if (width)
463 *width = m_width;
464 if (height)
465 *height = m_height;
466}
467
c2c0dabf
RR
468void wxTopLevelWindowX11::DoSetClientSize(int width, int height)
469{
e97d2576
RR
470 int old_width = m_width;
471 int old_height = m_height;
472
c2c0dabf
RR
473 m_width = width;
474 m_height = height;
ffd84c94 475
e97d2576
RR
476 if (m_width == old_width && m_height == old_height)
477 return;
ffd84c94 478
e97d2576 479 // wxLogDebug("DoSetClientSize: %s (%ld) %dx%d", GetClassInfo()->GetClassName(), GetId(), width, height);
ffd84c94 480
c2c0dabf
RR
481#if !wxUSE_NANOX
482 XSizeHints size_hints;
483 size_hints.flags = PSize;
484 size_hints.width = width;
485 size_hints.height = height;
679918f9 486 XSetWMNormalHints( wxGlobalDisplay(), (Window) X11GetMainWindow(), &size_hints );
c2c0dabf 487#endif
ffd84c94 488
c2c0dabf
RR
489 wxWindowX11::DoSetClientSize(width, height);
490}
491
492void wxTopLevelWindowX11::DoSetSize(int x, int y, int width, int height, int sizeFlags)
493{
e97d2576
RR
494 int old_x = m_x;
495 int old_y = m_y;
496 int old_width = m_width;
497 int old_height = m_height;
c2c0dabf 498
ffd84c94 499 if (x != wxDefaultCoord || (sizeFlags & wxSIZE_ALLOW_MINUS_ONE))
c2c0dabf 500 m_x = x;
ffd84c94
WS
501
502 if (y != wxDefaultCoord || (sizeFlags & wxSIZE_ALLOW_MINUS_ONE))
c2c0dabf 503 m_y = y;
ffd84c94
WS
504
505 if (width != wxDefaultCoord || (sizeFlags & wxSIZE_ALLOW_MINUS_ONE))
c2c0dabf 506 m_width = width;
ffd84c94
WS
507
508 if (height != wxDefaultCoord || (sizeFlags & wxSIZE_ALLOW_MINUS_ONE))
c2c0dabf 509 m_height = height;
ffd84c94 510
e97d2576
RR
511 if (m_x == old_x && m_y == old_y && m_width == old_width && m_height == old_height)
512 return;
ffd84c94 513
e97d2576
RR
514 // wxLogDebug("DoSetSize: %s (%ld) %d, %d %dx%d", GetClassInfo()->GetClassName(), GetId(), x, y, width, height);
515
ffd84c94 516#if !wxUSE_NANOX
c2c0dabf
RR
517 XSizeHints size_hints;
518 size_hints.flags = 0;
519 size_hints.flags |= PPosition;
520 size_hints.flags |= PSize;
521 size_hints.x = m_x;
522 size_hints.y = m_y;
523 size_hints.width = m_width;
524 size_hints.height = m_height;
679918f9 525 XSetWMNormalHints( wxGlobalDisplay(), (Window) X11GetMainWindow(), &size_hints);
c2c0dabf
RR
526#endif
527
528 wxWindowX11::DoSetSize(x, y, width, height, sizeFlags);
ffd84c94 529
b513212d 530#if 0
c2c0dabf
RR
531 Display *display = wxGlobalDisplay();
532 Window root = RootWindowOfScreen(DefaultScreenOfDisplay(display));
533 Window parent_window = window,
534 next_parent = window;
535
536 // search for the parent that is child of ROOT, because the WM may
537 // reparent twice and notify only the next parent (like FVWM)
538 while (next_parent != root) {
539 Window *theChildren;
540#if wxUSE_NANOX
541 GR_COUNT n;
542#else
543 unsigned int n;
b513212d 544#endif
c2c0dabf
RR
545 parent_window = next_parent;
546 XQueryTree(display, parent_window, &root,
547 &next_parent, &theChildren, &n);
548 XFree(theChildren); // not needed
549 }
550
551 XWindowChanges windowChanges;
552 windowChanges.x = x;
553 windowChanges.y = y;
554 windowChanges.width = width;
555 windowChanges.height = height;
556 windowChanges.stack_mode = 0;
557 int valueMask = CWX | CWY | CWWidth | CWHeight;
558
ffd84c94 559 if (x != wxDefaultCoord || (sizeFlags & wxSIZE_ALLOW_MINUS_ONE))
c2c0dabf
RR
560 {
561 valueMask |= CWX;
562 }
ffd84c94 563 if (y != wxDefaultCoord || (sizeFlags & wxSIZE_ALLOW_MINUS_ONE))
c2c0dabf
RR
564 {
565 valueMask |= CWY;
b513212d 566 }
ffd84c94 567 if (width != wxDefaultCoord)
c2c0dabf
RR
568 {
569 windowChanges.width = wxMax(1, width);
570 valueMask |= CWWidth;
571 }
ffd84c94 572 if (height != wxDefaultCoord)
c2c0dabf
RR
573 {
574 windowChanges.height = wxMax(1, height);
575 valueMask |= CWHeight;
576 }
577
578 XConfigureWindow( display, parent_window, valueMask, &windowChanges );
579#endif
b513212d
JS
580}
581
c2c0dabf 582void wxTopLevelWindowX11::DoGetPosition(int *x, int *y) const
b513212d 583{
c2c0dabf
RR
584 XSync(wxGlobalDisplay(), False);
585 Window window = (Window) m_mainWindow;
586 if (!window)
587 return ;
588
589 Display *display = wxGlobalDisplay();
590 Window root = RootWindowOfScreen(DefaultScreenOfDisplay(display));
591 Window parent_window = window,
592 next_parent = window;
593
594 // search for the parent that is child of ROOT, because the WM may
595 // reparent twice and notify only the next parent (like FVWM)
596 while (next_parent != root) {
597 Window *theChildren;
598#if wxUSE_NANOX
599 GR_COUNT n;
600#else
601 unsigned int n;
602#endif
603 parent_window = next_parent;
604 XQueryTree(display, parent_window, &root,
605 &next_parent, &theChildren, &n);
606 XFree(theChildren); // not needed
607 }
608#if 0
609 int xx, yy; unsigned int dummy;
610 XGetGeometry(display, parent_window, &root,
611 &xx, &yy, &dummy, &dummy, &dummy, &dummy);
612 if (x) *x = xx;
613 if (y) *y = yy;
614#else
615 XWindowAttributes attr;
616 Status status = XGetWindowAttributes( wxGlobalDisplay(), parent_window, & attr);
617 if (status)
618 {
619 if (x) *x = attr.x;
620 if (y) *y = attr.y;
621 }
622 else
623 {
624 if (x) *x = 0;
625 if (y) *y = 0;
626 }
627#endif
b513212d
JS
628}
629
c2c0dabf 630
b513212d 631#ifndef MWM_DECOR_BORDER
5268c5a3
RR
632
633#define MWM_HINTS_FUNCTIONS (1L << 0)
634#define MWM_HINTS_DECORATIONS (1L << 1)
635#define MWM_HINTS_INPUT_MODE (1L << 2)
636#define MWM_HINTS_STATUS (1L << 3)
b513212d
JS
637
638#define MWM_DECOR_ALL (1L << 0)
639#define MWM_DECOR_BORDER (1L << 1)
640#define MWM_DECOR_RESIZEH (1L << 2)
641#define MWM_DECOR_TITLE (1L << 3)
642#define MWM_DECOR_MENU (1L << 4)
643#define MWM_DECOR_MINIMIZE (1L << 5)
644#define MWM_DECOR_MAXIMIZE (1L << 6)
5268c5a3
RR
645
646#define MWM_FUNC_ALL (1L << 0)
647#define MWM_FUNC_RESIZE (1L << 1)
648#define MWM_FUNC_MOVE (1L << 2)
649#define MWM_FUNC_MINIMIZE (1L << 3)
650#define MWM_FUNC_MAXIMIZE (1L << 4)
651#define MWM_FUNC_CLOSE (1L << 5)
652
653#define MWM_INPUT_MODELESS 0
654#define MWM_INPUT_PRIMARY_APPLICATION_MODAL 1
655#define MWM_INPUT_SYSTEM_MODAL 2
656#define MWM_INPUT_FULL_APPLICATION_MODAL 3
657#define MWM_INPUT_APPLICATION_MODAL MWM_INPUT_PRIMARY_APPLICATION_MODAL
658
ffd84c94 659#define MWM_TEAROFF_WINDOW (1L<<0)
5268c5a3 660
b513212d
JS
661#endif
662
663struct MwmHints {
664 long flags;
665 long functions;
666 long decorations;
667 long input_mode;
668};
669
670#define PROP_MOTIF_WM_HINTS_ELEMENTS 5
671
672// Set the window manager decorations according to the
77ffb593 673// given wxWidgets style
b28d3abf 674bool wxSetWMDecorations(Window w, long style)
b513212d 675{
461e93f9
JS
676#if wxUSE_NANOX
677 GR_WM_PROPERTIES wmProp;
678
679 wmProp.flags = 0;
0b5c0e1a 680 wmProp.props = 0;
461e93f9
JS
681
682 if (style & wxRESIZE_BORDER)
683 {
684 wmProp.props |= GR_WM_PROPS_APPFRAME ;
685 wmProp.flags |= GR_WM_FLAGS_PROPS ;
686 }
687
850c6ed4 688 if (style & wxCLOSE_BOX)
461e93f9
JS
689 {
690 wmProp.props |= GR_WM_PROPS_CLOSEBOX ;
691 wmProp.flags |= GR_WM_FLAGS_PROPS ;
692 }
693
694 if ((style & wxCAPTION) ||
7282b067 695 (style & wxTINY_CAPTION))
461e93f9
JS
696 {
697 wmProp.props |= GR_WM_PROPS_CAPTION ;
698 wmProp.flags |= GR_WM_FLAGS_PROPS ;
bc55104d
JS
699
700 // The default dialog style doesn't include any kind
701 // of border, which is a bit odd. Anyway, inclusion
702 // of a caption surely implies a border.
1c067fe3 703 style |= wxRESIZE_BORDER;
461e93f9
JS
704 }
705
1c067fe3 706 if (style & wxRESIZE_BORDER)
461e93f9
JS
707 {
708 wmProp.props |= GR_WM_PROPS_APPFRAME ;
709 wmProp.flags |= GR_WM_FLAGS_PROPS ;
710 }
711
712 if (style & wxSIMPLE_BORDER)
713 {
714 wmProp.props |= GR_WM_PROPS_BORDER ;
715 wmProp.flags |= GR_WM_FLAGS_PROPS ;
716 }
717
718 if (style & wxMINIMIZE_BOX)
719 {
720 }
721
722 if (style & wxMAXIMIZE_BOX)
723 {
724 wmProp.props |= GR_WM_PROPS_MAXIMIZE ;
725 wmProp.flags |= GR_WM_FLAGS_PROPS ;
726 }
727
488b8b52 728 if ( !(style & wxBORDER) && !(style & wxRESIZE_BORDER) )
461e93f9
JS
729 {
730 wmProp.props |= GR_WM_PROPS_NODECORATE ;
731 wmProp.flags |= GR_WM_FLAGS_PROPS ;
732 }
733
734 GrSetWMProperties(w, & wmProp);
ffd84c94 735
461e93f9 736#else
b513212d
JS
737
738 Atom mwm_wm_hints = XInternAtom(wxGlobalDisplay(),"_MOTIF_WM_HINTS", False);
5268c5a3 739 if (mwm_wm_hints == 0)
ffd84c94
WS
740 return false;
741
b513212d 742 MwmHints hints;
5268c5a3 743 hints.flags = MWM_HINTS_DECORATIONS | MWM_HINTS_FUNCTIONS;
b513212d 744 hints.decorations = 0;
5268c5a3 745 hints.functions = 0;
ffd84c94 746
5268c5a3 747 if ((style & wxSIMPLE_BORDER) || (style & wxNO_BORDER))
b513212d 748 {
5268c5a3 749 // leave zeros
b513212d 750 }
5268c5a3 751 else
b513212d 752 {
5268c5a3
RR
753 hints.decorations = MWM_DECOR_BORDER;
754 hints.functions = MWM_FUNC_MOVE;
b513212d 755
5268c5a3
RR
756 if ((style & wxCAPTION) != 0)
757 hints.decorations |= MWM_DECOR_TITLE;
ffd84c94 758
5268c5a3 759 if ((style & wxSYSTEM_MENU) != 0)
5268c5a3 760 hints.decorations |= MWM_DECOR_MENU;
ffd84c94 761
850c6ed4 762 if ((style & wxCLOSE_BOX) != 0)
c3d8ee42 763 hints.functions |= MWM_FUNC_CLOSE;
ffd84c94 764
5268c5a3
RR
765 if ((style & wxMINIMIZE_BOX) != 0)
766 {
767 hints.functions |= MWM_FUNC_MINIMIZE;
768 hints.decorations |= MWM_DECOR_MINIMIZE;
769 }
ffd84c94 770
5268c5a3
RR
771 if ((style & wxMAXIMIZE_BOX) != 0)
772 {
773 hints.functions |= MWM_FUNC_MAXIMIZE;
774 hints.decorations |= MWM_DECOR_MAXIMIZE;
775 }
ffd84c94 776
5268c5a3
RR
777 if ((style & wxRESIZE_BORDER) != 0)
778 {
779 hints.functions |= MWM_FUNC_RESIZE;
780 hints.decorations |= MWM_DECOR_RESIZEH;
781 }
b513212d
JS
782 }
783
784 XChangeProperty(wxGlobalDisplay(),
ffd84c94
WS
785 w,
786 mwm_wm_hints, mwm_wm_hints,
787 32, PropModeReplace,
788 (unsigned char *) &hints, PROP_MOTIF_WM_HINTS_ELEMENTS);
b513212d 789
461e93f9 790#endif
ffd84c94 791 return true;
b513212d 792}