]>
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"
46 wxAdoptedWindow::wxAdoptedWindow()
50 wxAdoptedWindow::wxAdoptedWindow(WXWindow window
)
52 m_mainWindow
= window
;
55 wxAdoptedWindow::~wxAdoptedWindow()
64 static Atom WM_STATE
= 0;
65 bool wxReparenter::sm_done
= false;
66 wxAdoptedWindow
* wxReparenter::sm_toReparent
= NULL
;
67 wxWindow
* wxReparenter::sm_newParent
= NULL
;
68 wxString
wxReparenter::sm_name
;
69 bool wxReparenter::sm_exactMatch
= false;
71 static int ErrorHandler(Display
* dpy
, XErrorEvent
* event
)
77 // We assume that toReparent has had its X window set
79 bool wxReparenter::Reparent(wxWindow
* newParent
, wxAdoptedWindow
* toReparent
)
81 XWindowAttributes xwa
;
83 unsigned int numchildren
, each
;
84 Window returnroot
, returnparent
;
88 old
= XSetErrorHandler(ErrorHandler
);
89 XReparentWindow( wxGlobalDisplay(),
90 (Window
) toReparent
->GetMainWindow(),
91 (Window
) newParent
->GetMainWindow(),
94 if (!XQueryTree( wxGlobalDisplay(),
95 (Window
) toReparent
->GetMainWindow(),
96 &returnroot
, &returnparent
,
97 &children
, &numchildren
) || Xerror
)
99 XSetErrorHandler(old
);
105 // TEST: see if we can get away with reparenting just
109 wxLogDebug(wxT("Found %d, but only reparenting 1 child."), numchildren
);
112 wxLogDebug(wxT("Reparenting %d children."), numchildren
);
113 /* Stacking order is preserved since XQueryTree returns its children in
114 bottommost to topmost order
116 for (each
=0; each
<numchildren
; each
++)
118 XGetWindowAttributes( wxGlobalDisplay(),
119 children
[each
], &xwa
);
121 "Reparenting child at offset %d and position %d, %d.\n",
122 parentOffset
, parentOffset
+xwa
.x
, parentOffset
+xwa
.y
);
123 XReparentWindow( wxGlobalDisplay(),
124 children
[each
], (Window
) newParent
->GetMainWindow(),
129 XSetErrorHandler(old
);
133 // Wait for an appropriate window to be created.
134 // If exactMatch is false, a substring match is OK.
135 // If windowName is empty, then wait for the next overrideRedirect window.
136 bool wxReparenter::WaitAndReparent(wxWindow
* newParent
, wxAdoptedWindow
* toReparent
,
137 const wxString
& windowName
,
140 sm_newParent
= newParent
;
141 sm_toReparent
= toReparent
;
142 sm_exactMatch
= exactMatch
;
143 sm_name
= windowName
;
145 Display
* display
= wxGlobalDisplay();
146 XSelectInput(display
,
147 RootWindowOfScreen(DefaultScreenOfDisplay(display
)),
148 SubstructureNotifyMask
);
151 WM_STATE
= XInternAtom(display
, "WM_STATE", False
);
154 if (!windowName
.empty())
155 wxLogDebug(_T("Waiting for window %s"), windowName
.c_str());
160 wxEventLoop eventLoop
;
163 if (eventLoop
.Pending())
166 XNextEvent(display
, & xevent
);
167 if (!wxTheApp
->ProcessXEvent((WXEvent
*) & xevent
))
169 // Do the local event processing
170 ProcessXEvent((WXEvent
*) & xevent
);
176 wxTimer::NotifyTimers();
177 wxTheApp
->ProcessIdle();
184 bool wxReparenter::ProcessXEvent(WXEvent
* event
)
186 XEvent
* xevent
= (XEvent
*) event
;
191 if (xevent
->type
== MapNotify
)
193 wxLogDebug(_T("Window was mapped"));
196 if (xevent
->type
== MapNotify
&& !xevent
->xmap
.override_redirect
&&
197 (client
= (Window
) FindAClientWindow((WXWindow
) xevent
->xmap
.window
, sm_name
)))
199 wxLogDebug(_T("Found a client window, about to reparent"));
200 wxASSERT(sm_toReparent
->GetParent() == NULL
);
202 sm_toReparent
->SetHandle((WXWindow
) client
);
203 sm_newParent
->AddChild(sm_toReparent
);
204 sm_done
= Reparent(sm_newParent
, sm_toReparent
);
206 } else if (xevent
->type
== MapNotify
&&
207 xevent
->xmap
.override_redirect
&&
210 wxLogDebug(_T("Found an override redirect window, about to reparent"));
211 sm_toReparent
->SetHandle((WXWindow
) xevent
->xmap
.window
);
212 sm_newParent
->AddChild(sm_toReparent
);
213 wxASSERT(sm_toReparent
->GetParent() == NULL
);
215 sm_done
= Reparent(sm_newParent
, sm_toReparent
);
222 WXWindow
wxReparenter::FindAClientWindow(WXWindow window
, const wxString
& name
)
227 unsigned long nitems
, bytesafter
;
228 unsigned char *propreturn
;
230 unsigned int numchildren
;
231 Window returnroot
, returnparent
;
237 old
= XSetErrorHandler(ErrorHandler
);
238 rvalue
= XGetWindowProperty((Display
*) wxGetDisplay(),
239 (Window
) window
, WM_STATE
,
241 AnyPropertyType
, &actualtype
, &actualformat
,
242 &nitems
, &bytesafter
, &propreturn
);
244 XSetErrorHandler(old
);
246 if (!Xerror
&& rvalue
== Success
&& actualtype
!= None
)
248 if (rvalue
== Success
)
250 XFree((char *) propreturn
);
252 XFetchName((Display
*) wxGetDisplay(), (Window
) window
, &clientName
);
255 wxString str2
= wxString::FromAscii(clientName
);
261 matches
= (name
== wxString::FromAscii(clientName
));
263 matches
= (str1
.Contains(str2
) || str2
.Contains(str1
));
268 return (WXWindow
) window
;
273 old
= XSetErrorHandler(ErrorHandler
);
274 if (!XQueryTree((Display
*) wxGetDisplay(), (Window
) window
, &returnroot
, &returnparent
,
275 &children
, &numchildren
) || Xerror
)
277 XSetErrorHandler(old
);
280 XSetErrorHandler(old
);
283 for (i
=0; i
<(int)numchildren
&& !result
;i
++) {
284 result
= (Window
) FindAClientWindow((WXWindow
) children
[i
], name
);
287 XFree((char *) children
);
288 } return (WXWindow
) result
;
291 #endif // !wxUSE_NANOX