]>
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
->GetMainWindow(), 
  93                      (Window
) newParent
->GetMainWindow(), 
  96     if (!XQueryTree( wxGlobalDisplay(), 
  97                      (Window
) toReparent
->GetMainWindow(), 
  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
->GetMainWindow(), 
 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(_T("Window was mapped")); 
 193         if (xevent
->type 
== MapNotify 
&& !xevent
->xmap
.override_redirect 
&& 
 194             (client 
= (Window
) FindAClientWindow((WXWindow
) xevent
->xmap
.window
, sm_name
))) 
 196             wxLogDebug(_T("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(_T("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