]>
git.saurik.com Git - wxWidgets.git/blob - src/x11/reparent.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: src/x11/reparent.cpp
4 // Author: Julian Smart
8 // Copyright: (c) Julian Smart
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
12 // for compilers that support precompilation, includes "wx.h".
13 #include "wx/wxprec.h"
15 #if defined(__BORLANDC__)
19 // ============================================================================
21 // ============================================================================
23 // ----------------------------------------------------------------------------
25 // ----------------------------------------------------------------------------
29 #include "wx/x11/reparent.h"
37 #include "wx/evtloop.h"
39 #include "wx/x11/private.h"
40 #include "X11/Xatom.h"
42 #include "wx/generic/private/timer.h"
48 wxAdoptedWindow::wxAdoptedWindow()
52 wxAdoptedWindow::wxAdoptedWindow(WXWindow window
)
54 m_mainWindow
= window
;
57 wxAdoptedWindow::~wxAdoptedWindow()
66 static Atom WM_STATE
= 0;
67 bool wxReparenter::sm_done
= false;
68 wxAdoptedWindow
* wxReparenter::sm_toReparent
= NULL
;
69 wxWindow
* wxReparenter::sm_newParent
= NULL
;
70 wxString
wxReparenter::sm_name
;
71 bool wxReparenter::sm_exactMatch
= false;
73 static int ErrorHandler(Display
* WXUNUSED(dpy
), XErrorEvent
* WXUNUSED(event
))
79 // We assume that toReparent has had its X window set
81 bool wxReparenter::Reparent(wxWindow
* newParent
, wxAdoptedWindow
* toReparent
)
83 XWindowAttributes xwa
;
85 unsigned int numchildren
, each
;
86 Window returnroot
, returnparent
;
90 old
= XSetErrorHandler(ErrorHandler
);
91 XReparentWindow( wxGlobalDisplay(),
92 (Window
) toReparent
->X11GetMainWindow(),
93 (Window
) newParent
->X11GetMainWindow(),
96 if (!XQueryTree( wxGlobalDisplay(),
97 (Window
) toReparent
->X11GetMainWindow(),
98 &returnroot
, &returnparent
,
99 &children
, &numchildren
) || Xerror
)
101 XSetErrorHandler(old
);
107 // TEST: see if we can get away with reparenting just
111 wxLogDebug(wxT("Found %d, but only reparenting 1 child."), numchildren
);
114 wxLogDebug(wxT("Reparenting %d children."), numchildren
);
115 /* Stacking order is preserved since XQueryTree returns its children in
116 bottommost to topmost order
118 for (each
=0; each
<numchildren
; each
++)
120 XGetWindowAttributes( wxGlobalDisplay(),
121 children
[each
], &xwa
);
123 "Reparenting child at offset %d and position %d, %d.\n",
124 parentOffset
, parentOffset
+xwa
.x
, parentOffset
+xwa
.y
);
125 XReparentWindow( wxGlobalDisplay(),
126 children
[each
], (Window
) newParent
->X11GetMainWindow(),
131 XSetErrorHandler(old
);
135 // Wait for an appropriate window to be created.
136 // If exactMatch is false, a substring match is OK.
137 // If windowName is empty, then wait for the next overrideRedirect window.
138 bool wxReparenter::WaitAndReparent(wxWindow
* newParent
, wxAdoptedWindow
* toReparent
,
139 const wxString
& windowName
,
142 sm_newParent
= newParent
;
143 sm_toReparent
= toReparent
;
144 sm_exactMatch
= exactMatch
;
145 sm_name
= windowName
;
147 Display
* display
= wxGlobalDisplay();
148 XSelectInput(display
,
149 RootWindowOfScreen(DefaultScreenOfDisplay(display
)),
150 SubstructureNotifyMask
);
153 WM_STATE
= XInternAtom(display
, "WM_STATE", False
);
157 wxEventLoop eventLoop
;
160 if (eventLoop
.Pending())
163 XNextEvent(display
, & xevent
);
164 if (!wxTheApp
->ProcessXEvent((WXEvent
*) & xevent
))
166 // Do the local event processing
167 ProcessXEvent((WXEvent
*) & xevent
);
173 wxGenericTimerImpl::NotifyTimers();
174 wxTheApp
->ProcessIdle();
181 bool wxReparenter::ProcessXEvent(WXEvent
* event
)
183 XEvent
* xevent
= (XEvent
*) event
;
188 if (xevent
->type
== MapNotify
)
190 wxLogDebug(wxT("Window was mapped"));
193 if (xevent
->type
== MapNotify
&& !xevent
->xmap
.override_redirect
&&
194 (client
= (Window
) FindAClientWindow((WXWindow
) xevent
->xmap
.window
, sm_name
)))
196 wxLogDebug(wxT("Found a client window, about to reparent"));
197 wxASSERT(sm_toReparent
->GetParent() == NULL
);
199 sm_toReparent
->SetHandle((WXWindow
) client
);
200 sm_newParent
->AddChild(sm_toReparent
);
201 sm_done
= Reparent(sm_newParent
, sm_toReparent
);
203 } else if (xevent
->type
== MapNotify
&&
204 xevent
->xmap
.override_redirect
&&
207 wxLogDebug(wxT("Found an override redirect window, about to reparent"));
208 sm_toReparent
->SetHandle((WXWindow
) xevent
->xmap
.window
);
209 sm_newParent
->AddChild(sm_toReparent
);
210 wxASSERT(sm_toReparent
->GetParent() == NULL
);
212 sm_done
= Reparent(sm_newParent
, sm_toReparent
);
219 WXWindow
wxReparenter::FindAClientWindow(WXWindow window
, const wxString
& name
)
224 unsigned long nitems
, bytesafter
;
225 unsigned char *propreturn
;
227 unsigned int numchildren
;
228 Window returnroot
, returnparent
;
234 old
= XSetErrorHandler(ErrorHandler
);
235 rvalue
= XGetWindowProperty((Display
*) wxGetDisplay(),
236 (Window
) window
, WM_STATE
,
238 AnyPropertyType
, &actualtype
, &actualformat
,
239 &nitems
, &bytesafter
, &propreturn
);
241 XSetErrorHandler(old
);
243 if (!Xerror
&& rvalue
== Success
&& actualtype
!= None
)
245 if (rvalue
== Success
)
247 XFree((char *) propreturn
);
249 XFetchName((Display
*) wxGetDisplay(), (Window
) window
, &clientName
);
252 wxString str2
= wxString::FromAscii(clientName
);
258 matches
= (name
== wxString::FromAscii(clientName
));
260 matches
= (str1
.Contains(str2
) || str2
.Contains(str1
));
265 return (WXWindow
) window
;
270 old
= XSetErrorHandler(ErrorHandler
);
271 if (!XQueryTree((Display
*) wxGetDisplay(), (Window
) window
, &returnroot
, &returnparent
,
272 &children
, &numchildren
) || Xerror
)
274 XSetErrorHandler(old
);
277 XSetErrorHandler(old
);
280 for (i
=0; i
<(int)numchildren
&& !result
;i
++) {
281 result
= (Window
) FindAClientWindow((WXWindow
) children
[i
], name
);
284 XFree((char *) children
);
285 } return (WXWindow
) result
;
288 #endif // !wxUSE_NANOX