]>
git.saurik.com Git - wxWidgets.git/blob - src/x11/reparent.cpp
7e76d2334d040a052f4eb4aa3c4ee2bd4a63f447
   1 ///////////////////////////////////////////////////////////////////////////// 
   4 // Author:      Julian Smart 
   8 // Copyright:   (c) Julian Smart 
   9 // Licence:     wxWindows licence 
  10 ///////////////////////////////////////////////////////////////////////////// 
  12 // ============================================================================ 
  14 // ============================================================================ 
  16 // ---------------------------------------------------------------------------- 
  18 // ---------------------------------------------------------------------------- 
  20 #if defined(__GNUG__) && !defined(NO_GCC_PRAGMA) 
  21     #pragma implementation "reparent.h" 
  28 #include "wx/x11/reparent.h" 
  29 #include "wx/evtloop.h" 
  34 #include "wx/x11/private.h" 
  35 #include "X11/Xatom.h" 
  41 wxAdoptedWindow::wxAdoptedWindow() 
  45 wxAdoptedWindow::wxAdoptedWindow(WXWindow window
) 
  47     m_mainWindow 
= window
; 
  50 wxAdoptedWindow::~wxAdoptedWindow() 
  59 static Atom WM_STATE 
= 0; 
  60 bool wxReparenter::sm_done 
= FALSE
; 
  61 wxAdoptedWindow
* wxReparenter::sm_toReparent 
= NULL
; 
  62 wxWindow
* wxReparenter::sm_newParent 
= NULL
; 
  63 wxString 
wxReparenter::sm_name
; 
  64 bool wxReparenter::sm_exactMatch 
= FALSE
; 
  66 static int ErrorHandler(Display
* dpy
, XErrorEvent
* event
) 
  72 // We assume that toReparent has had its X window set 
  74 bool wxReparenter::Reparent(wxWindow
* newParent
, wxAdoptedWindow
* toReparent
) 
  76     XWindowAttributes xwa
; 
  78     unsigned int numchildren
, each
; 
  79     Window returnroot
, returnparent
; 
  83     old 
= XSetErrorHandler(ErrorHandler
); 
  84     XReparentWindow( wxGlobalDisplay(), 
  85                      (Window
) toReparent
->GetMainWindow(), 
  86                      (Window
) newParent
->GetMainWindow(), 
  89     if (!XQueryTree( wxGlobalDisplay(), 
  90                      (Window
) toReparent
->GetMainWindow(), 
  91                      &returnroot
, &returnparent
, 
  92                      &children
, &numchildren
) || Xerror
) 
  94         XSetErrorHandler(old
); 
 100         // TEST: see if we can get away with reparenting just 
 104             wxLogDebug(wxT("Found %d, but only reparenting 1 child."), numchildren
); 
 107         wxLogDebug(wxT("Reparenting %d children."), numchildren
); 
 108         /* Stacking order is preserved since XQueryTree returns its children in 
 109            bottommost to topmost order 
 111         for (each
=0; each
<numchildren
; each
++) 
 113             XGetWindowAttributes( wxGlobalDisplay(), 
 114                                   children
[each
], &xwa
); 
 116               "Reparenting child at offset %d and position %d, %d.\n", 
 117                parentOffset
, parentOffset
+xwa
.x
, parentOffset
+xwa
.y
); 
 118             XReparentWindow( wxGlobalDisplay(), 
 119                              children
[each
], (Window
) newParent
->GetMainWindow(), 
 124     XSetErrorHandler(old
); 
 128 // Wait for an appropriate window to be created. 
 129 // If exactMatch is FALSE, a substring match is OK. 
 130 // If windowName is empty, then wait for the next overrideRedirect window. 
 131 bool wxReparenter::WaitAndReparent(wxWindow
* newParent
, wxAdoptedWindow
* toReparent
, 
 132                                    const wxString
& windowName
, 
 135     sm_newParent 
= newParent
; 
 136     sm_toReparent 
= toReparent
; 
 137     sm_exactMatch 
= exactMatch
; 
 138     sm_name 
= windowName
; 
 140     Display
* display 
= wxGlobalDisplay(); 
 141     XSelectInput(display
, 
 142         RootWindowOfScreen(DefaultScreenOfDisplay(display
)), 
 143         SubstructureNotifyMask
); 
 146         WM_STATE 
= XInternAtom(display
, "WM_STATE", False
); 
 149     if (!windowName
.IsEmpty()) 
 150         wxLogDebug(_T("Waiting for window %s"), windowName
.c_str()); 
 155     wxEventLoop eventLoop
; 
 158         if (eventLoop
.Pending()) 
 161             XNextEvent(display
, & xevent
); 
 162             if (!wxTheApp
->ProcessXEvent((WXEvent
*) & xevent
)) 
 164                 // Do the local event processing 
 165                 ProcessXEvent((WXEvent
*) & xevent
); 
 171             wxTimer::NotifyTimers(); 
 172             wxTheApp
->ProcessIdle(); 
 179 bool wxReparenter::ProcessXEvent(WXEvent
* event
) 
 181     XEvent
* xevent 
= (XEvent
*) event
; 
 186         if (xevent
->type 
== MapNotify
) 
 188             wxLogDebug(_T("Window was mapped")); 
 191         if (xevent
->type 
== MapNotify 
&& !xevent
->xmap
.override_redirect 
&& 
 192             (client 
= (Window
) FindAClientWindow((WXWindow
) xevent
->xmap
.window
, sm_name
))) 
 194             wxLogDebug(_T("Found a client window, about to reparent")); 
 195             wxASSERT(sm_toReparent
->GetParent() == NULL
); 
 197             sm_toReparent
->SetHandle((WXWindow
) client
); 
 198             sm_newParent
->AddChild(sm_toReparent
); 
 199             sm_done 
= Reparent(sm_newParent
, sm_toReparent
); 
 201         } else if (xevent
->type 
== MapNotify 
&& 
 202                    xevent
->xmap
.override_redirect 
&& 
 205             wxLogDebug(_T("Found an override redirect window, about to reparent")); 
 206             sm_toReparent
->SetHandle((WXWindow
) xevent
->xmap
.window
); 
 207             sm_newParent
->AddChild(sm_toReparent
); 
 208             wxASSERT(sm_toReparent
->GetParent() == NULL
); 
 210             sm_done 
= Reparent(sm_newParent
, sm_toReparent
); 
 217 WXWindow 
wxReparenter::FindAClientWindow(WXWindow window
, const wxString
& name
) 
 222     unsigned long nitems
, bytesafter
; 
 223     unsigned char *propreturn
; 
 225     unsigned int numchildren
; 
 226     Window returnroot
, returnparent
; 
 232     old 
= XSetErrorHandler(ErrorHandler
); 
 233     rvalue 
= XGetWindowProperty((Display
*) wxGetDisplay(), 
 234         (Window
) window
, WM_STATE
, 
 236         AnyPropertyType
, &actualtype
, &actualformat
, 
 237         &nitems
, &bytesafter
, &propreturn
); 
 239     XSetErrorHandler(old
); 
 241     if (!Xerror 
&& rvalue 
== Success 
&& actualtype 
!= None
) 
 243         if (rvalue 
== Success
) 
 245             XFree((char *) propreturn
); 
 247         XFetchName((Display
*) wxGetDisplay(), (Window
) window
, &clientName
); 
 250         wxString str2 
= wxString::FromAscii(clientName
); 
 256             matches 
= (name 
== wxString::FromAscii(clientName
)); 
 258             matches 
= (str1
.Contains(str2
) || str2
.Contains(str1
)); 
 263             return (WXWindow
) window
; 
 268     old 
= XSetErrorHandler(ErrorHandler
); 
 269     if (!XQueryTree((Display
*) wxGetDisplay(), (Window
) window
, &returnroot
, &returnparent
, 
 270         &children
, &numchildren
) || Xerror
) 
 272         XSetErrorHandler(old
); 
 275     XSetErrorHandler(old
); 
 278     for (i
=0; i
<(int)numchildren 
&& !result 
;i
++) { 
 279         result 
= (Window
) FindAClientWindow((WXWindow
) children
[i
], name
); 
 282         XFree((char *) children
); 
 283     } return (WXWindow
) result
;