]>
git.saurik.com Git - wxWidgets.git/blob - src/x11/reparent.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: src/x11/reparent.cpp
4 // Author: Julian Smart
7 // Copyright: (c) Julian Smart
8 // Licence: wxWindows licence
9 /////////////////////////////////////////////////////////////////////////////
11 // for compilers that support precompilation, includes "wx.h".
12 #include "wx/wxprec.h"
14 #if defined(__BORLANDC__)
18 // ============================================================================
20 // ============================================================================
22 // ----------------------------------------------------------------------------
24 // ----------------------------------------------------------------------------
28 #include "wx/x11/reparent.h"
36 #include "wx/evtloop.h"
38 #include "wx/x11/private.h"
39 #include "X11/Xatom.h"
41 #include "wx/generic/private/timer.h"
47 wxAdoptedWindow::wxAdoptedWindow()
51 wxAdoptedWindow::wxAdoptedWindow(WXWindow window
)
53 m_mainWindow
= window
;
56 wxAdoptedWindow::~wxAdoptedWindow()
65 static Atom WM_STATE
= 0;
66 bool wxReparenter::sm_done
= false;
67 wxAdoptedWindow
* wxReparenter::sm_toReparent
= NULL
;
68 wxWindow
* wxReparenter::sm_newParent
= NULL
;
69 wxString
wxReparenter::sm_name
;
70 bool wxReparenter::sm_exactMatch
= false;
72 static int ErrorHandler(Display
* WXUNUSED(dpy
), XErrorEvent
* WXUNUSED(event
))
78 // We assume that toReparent has had its X window set
80 bool wxReparenter::Reparent(wxWindow
* newParent
, wxAdoptedWindow
* toReparent
)
82 XWindowAttributes xwa
;
84 unsigned int numchildren
, each
;
85 Window returnroot
, returnparent
;
89 old
= XSetErrorHandler(ErrorHandler
);
90 XReparentWindow( wxGlobalDisplay(),
91 (Window
) toReparent
->X11GetMainWindow(),
92 (Window
) newParent
->X11GetMainWindow(),
95 if (!XQueryTree( wxGlobalDisplay(),
96 (Window
) toReparent
->X11GetMainWindow(),
97 &returnroot
, &returnparent
,
98 &children
, &numchildren
) || Xerror
)
100 XSetErrorHandler(old
);
106 // TEST: see if we can get away with reparenting just
110 wxLogDebug(wxT("Found %d, but only reparenting 1 child."), numchildren
);
113 wxLogDebug(wxT("Reparenting %d children."), numchildren
);
114 /* Stacking order is preserved since XQueryTree returns its children in
115 bottommost to topmost order
117 for (each
=0; each
<numchildren
; each
++)
119 XGetWindowAttributes( wxGlobalDisplay(),
120 children
[each
], &xwa
);
122 "Reparenting child at offset %d and position %d, %d.\n",
123 parentOffset
, parentOffset
+xwa
.x
, parentOffset
+xwa
.y
);
124 XReparentWindow( wxGlobalDisplay(),
125 children
[each
], (Window
) newParent
->X11GetMainWindow(),
130 XSetErrorHandler(old
);
134 // Wait for an appropriate window to be created.
135 // If exactMatch is false, a substring match is OK.
136 // If windowName is empty, then wait for the next overrideRedirect window.
137 bool wxReparenter::WaitAndReparent(wxWindow
* newParent
, wxAdoptedWindow
* toReparent
,
138 const wxString
& windowName
,
141 sm_newParent
= newParent
;
142 sm_toReparent
= toReparent
;
143 sm_exactMatch
= exactMatch
;
144 sm_name
= windowName
;
146 Display
* display
= wxGlobalDisplay();
147 XSelectInput(display
,
148 RootWindowOfScreen(DefaultScreenOfDisplay(display
)),
149 SubstructureNotifyMask
);
152 WM_STATE
= XInternAtom(display
, "WM_STATE", False
);
156 wxEventLoop eventLoop
;
159 if (eventLoop
.Pending())
162 XNextEvent(display
, & xevent
);
163 if (!wxTheApp
->ProcessXEvent((WXEvent
*) & xevent
))
165 // Do the local event processing
166 ProcessXEvent((WXEvent
*) & xevent
);
172 wxGenericTimerImpl::NotifyTimers();
173 wxTheApp
->ProcessIdle();
180 bool wxReparenter::ProcessXEvent(WXEvent
* event
)
182 XEvent
* xevent
= (XEvent
*) event
;
187 if (xevent
->type
== MapNotify
)
189 wxLogDebug(wxT("Window was mapped"));
192 if (xevent
->type
== MapNotify
&& !xevent
->xmap
.override_redirect
&&
193 (client
= (Window
) FindAClientWindow((WXWindow
) xevent
->xmap
.window
, sm_name
)))
195 wxLogDebug(wxT("Found a client window, about to reparent"));
196 wxASSERT(sm_toReparent
->GetParent() == NULL
);
198 sm_toReparent
->SetHandle((WXWindow
) client
);
199 sm_newParent
->AddChild(sm_toReparent
);
200 sm_done
= Reparent(sm_newParent
, sm_toReparent
);
202 } else if (xevent
->type
== MapNotify
&&
203 xevent
->xmap
.override_redirect
&&
206 wxLogDebug(wxT("Found an override redirect window, about to reparent"));
207 sm_toReparent
->SetHandle((WXWindow
) xevent
->xmap
.window
);
208 sm_newParent
->AddChild(sm_toReparent
);
209 wxASSERT(sm_toReparent
->GetParent() == NULL
);
211 sm_done
= Reparent(sm_newParent
, sm_toReparent
);
218 WXWindow
wxReparenter::FindAClientWindow(WXWindow window
, const wxString
& name
)
223 unsigned long nitems
, bytesafter
;
224 unsigned char *propreturn
;
226 unsigned int numchildren
;
227 Window returnroot
, returnparent
;
233 old
= XSetErrorHandler(ErrorHandler
);
234 rvalue
= XGetWindowProperty((Display
*) wxGetDisplay(),
235 (Window
) window
, WM_STATE
,
237 AnyPropertyType
, &actualtype
, &actualformat
,
238 &nitems
, &bytesafter
, &propreturn
);
240 XSetErrorHandler(old
);
242 if (!Xerror
&& rvalue
== Success
&& actualtype
!= None
)
244 if (rvalue
== Success
)
246 XFree((char *) propreturn
);
248 XFetchName((Display
*) wxGetDisplay(), (Window
) window
, &clientName
);
251 wxString str2
= wxString::FromAscii(clientName
);
257 matches
= (name
== wxString::FromAscii(clientName
));
259 matches
= (str1
.Contains(str2
) || str2
.Contains(str1
));
264 return (WXWindow
) window
;
269 old
= XSetErrorHandler(ErrorHandler
);
270 if (!XQueryTree((Display
*) wxGetDisplay(), (Window
) window
, &returnroot
, &returnparent
,
271 &children
, &numchildren
) || Xerror
)
273 XSetErrorHandler(old
);
276 XSetErrorHandler(old
);
279 for (i
=0; i
<(int)numchildren
&& !result
;i
++) {
280 result
= (Window
) FindAClientWindow((WXWindow
) children
[i
], name
);
283 XFree((char *) children
);
284 } return (WXWindow
) result
;
287 #endif // !wxUSE_NANOX