]>
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"
30 #include "wx/evtloop.h"
35 #include "wx/x11/private.h"
36 #include "X11/Xatom.h"
42 wxAdoptedWindow::wxAdoptedWindow()
46 wxAdoptedWindow::wxAdoptedWindow(WXWindow window
)
48 m_mainWindow
= window
;
51 wxAdoptedWindow::~wxAdoptedWindow()
60 static Atom WM_STATE
= 0;
61 bool wxReparenter::sm_done
= FALSE
;
62 wxAdoptedWindow
* wxReparenter::sm_toReparent
= NULL
;
63 wxWindow
* wxReparenter::sm_newParent
= NULL
;
64 wxString
wxReparenter::sm_name
;
65 bool wxReparenter::sm_exactMatch
= FALSE
;
67 static int ErrorHandler(Display
* dpy
, XErrorEvent
* event
)
73 // We assume that toReparent has had its X window set
75 bool wxReparenter::Reparent(wxWindow
* newParent
, wxAdoptedWindow
* toReparent
)
77 XWindowAttributes xwa
;
79 unsigned int numchildren
, each
;
80 Window returnroot
, returnparent
;
84 old
= XSetErrorHandler(ErrorHandler
);
85 XReparentWindow( wxGlobalDisplay(),
86 (Window
) toReparent
->GetMainWindow(),
87 (Window
) newParent
->GetMainWindow(),
90 if (!XQueryTree( wxGlobalDisplay(),
91 (Window
) toReparent
->GetMainWindow(),
92 &returnroot
, &returnparent
,
93 &children
, &numchildren
) || Xerror
)
95 XSetErrorHandler(old
);
101 // TEST: see if we can get away with reparenting just
105 wxLogDebug(wxT("Found %d, but only reparenting 1 child."), numchildren
);
108 wxLogDebug(wxT("Reparenting %d children."), numchildren
);
109 /* Stacking order is preserved since XQueryTree returns its children in
110 bottommost to topmost order
112 for (each
=0; each
<numchildren
; each
++)
114 XGetWindowAttributes( wxGlobalDisplay(),
115 children
[each
], &xwa
);
117 "Reparenting child at offset %d and position %d, %d.\n",
118 parentOffset
, parentOffset
+xwa
.x
, parentOffset
+xwa
.y
);
119 XReparentWindow( wxGlobalDisplay(),
120 children
[each
], (Window
) newParent
->GetMainWindow(),
125 XSetErrorHandler(old
);
129 // Wait for an appropriate window to be created.
130 // If exactMatch is FALSE, a substring match is OK.
131 // If windowName is empty, then wait for the next overrideRedirect window.
132 bool wxReparenter::WaitAndReparent(wxWindow
* newParent
, wxAdoptedWindow
* toReparent
,
133 const wxString
& windowName
,
136 sm_newParent
= newParent
;
137 sm_toReparent
= toReparent
;
138 sm_exactMatch
= exactMatch
;
139 sm_name
= windowName
;
141 Display
* display
= wxGlobalDisplay();
142 XSelectInput(display
,
143 RootWindowOfScreen(DefaultScreenOfDisplay(display
)),
144 SubstructureNotifyMask
);
147 WM_STATE
= XInternAtom(display
, "WM_STATE", False
);
150 if (!windowName
.empty())
151 wxLogDebug(_T("Waiting for window %s"), windowName
.c_str());
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 wxTimer::NotifyTimers();
173 wxTheApp
->ProcessIdle();
180 bool wxReparenter::ProcessXEvent(WXEvent
* event
)
182 XEvent
* xevent
= (XEvent
*) event
;
187 if (xevent
->type
== MapNotify
)
189 wxLogDebug(_T("Window was mapped"));
192 if (xevent
->type
== MapNotify
&& !xevent
->xmap
.override_redirect
&&
193 (client
= (Window
) FindAClientWindow((WXWindow
) xevent
->xmap
.window
, sm_name
)))
195 wxLogDebug(_T("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(_T("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
;