Added reparenting helper classes to help apps to grab the windows
of other applications. git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@14524 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
@@ -631,6 +631,7 @@ palette.cpp X11
|
|||||||
pen.cpp X11
|
pen.cpp X11
|
||||||
popupwin.cpp X11
|
popupwin.cpp X11
|
||||||
region.cpp X11
|
region.cpp X11
|
||||||
|
reparent.cpp X11
|
||||||
settings.cpp X11
|
settings.cpp X11
|
||||||
toplevel.cpp X11
|
toplevel.cpp X11
|
||||||
utils.cpp X11
|
utils.cpp X11
|
||||||
@@ -1206,6 +1207,7 @@ pen.h X11H
|
|||||||
print.h X11H
|
print.h X11H
|
||||||
private.h X11H
|
private.h X11H
|
||||||
region.h X11H
|
region.h X11H
|
||||||
|
reparent.h X11H
|
||||||
settings.h X11H
|
settings.h X11H
|
||||||
toolbar.h X11H
|
toolbar.h X11H
|
||||||
toplevel.h X11H
|
toplevel.h X11H
|
||||||
|
71
include/wx/x11/reparent.h
Normal file
71
include/wx/x11/reparent.h
Normal file
@@ -0,0 +1,71 @@
|
|||||||
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
// Name: reparent.h
|
||||||
|
// Purpose: Reparenting classes
|
||||||
|
// Author: Julian Smart
|
||||||
|
// Modified by:
|
||||||
|
// Created: 2002-03-09
|
||||||
|
// RCS-ID: $Id$
|
||||||
|
// Copyright: (c) Julian Smart
|
||||||
|
// Licence: wxWindows licence
|
||||||
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
#ifndef _WX_REPARENT_H_
|
||||||
|
#define _WX_REPARENT_H_
|
||||||
|
|
||||||
|
#ifdef __GNUG__
|
||||||
|
#pragma interface "reparent.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "wx/window.h"
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This class helps to reparent a specific window
|
||||||
|
*/
|
||||||
|
|
||||||
|
class wxAdoptedWindow;
|
||||||
|
class wxReparenter: public wxObject
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
wxReparenter() {}
|
||||||
|
|
||||||
|
// We assume that toReparent has had its X window set
|
||||||
|
// appropriately. toReparent is typically a wxAdoptedWindow.
|
||||||
|
bool Reparent(wxWindow* newParent, wxAdoptedWindow* toReparent);
|
||||||
|
|
||||||
|
// Wait for an appropriate window to be created.
|
||||||
|
// If exactMatch is FALSE, a substring match is OK.
|
||||||
|
// If windowName is empty, then wait for the next overrideRedirect window.
|
||||||
|
bool WaitAndReparent(wxWindow* newParent, wxAdoptedWindow* toReparent,
|
||||||
|
const wxString& windowName = wxEmptyString,
|
||||||
|
bool exactMatch = TRUE);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
|
bool ProcessXEvent(WXEvent* event);
|
||||||
|
WXWindow FindAClientWindow(WXWindow window, const wxString& name);
|
||||||
|
|
||||||
|
static bool sm_done;
|
||||||
|
static wxAdoptedWindow* sm_toReparent;
|
||||||
|
static wxWindow* sm_newParent;
|
||||||
|
static wxString sm_name;
|
||||||
|
static bool sm_exactMatch;
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* A window that adopts its handle from the native
|
||||||
|
* toolkit. It has no parent until reparented.
|
||||||
|
*/
|
||||||
|
|
||||||
|
class wxAdoptedWindow: public wxWindow
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
wxAdoptedWindow();
|
||||||
|
wxAdoptedWindow(WXWindow window);
|
||||||
|
~wxAdoptedWindow();
|
||||||
|
|
||||||
|
void SetHandle(WXWindow window) { m_mainWidget = window; }
|
||||||
|
WXWindow GetHandle() const { return GetXWindow(); }
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
|
// _WX_REPARENT_H_
|
@@ -1410,6 +1410,7 @@ int GrGetPixelColor(GR_SCREEN_INFO* sinfo, GR_PALETTE* palette, GR_PIXELVAL pixe
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
// wxUSE_NANOX
|
// wxUSE_NANOX
|
||||||
|
|
||||||
|
@@ -840,6 +840,126 @@ void wxWindowDC::DoDrawIcon( const wxIcon &icon, wxCoord x, wxCoord y)
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if wxUSE_NANOX
|
||||||
|
void wxWindowDC::DoDrawBitmap( const wxBitmap &bitmap,
|
||||||
|
wxCoord x, wxCoord y,
|
||||||
|
bool useMask )
|
||||||
|
{
|
||||||
|
wxCHECK_RET( Ok(), wxT("invalid window dc") );
|
||||||
|
|
||||||
|
wxCHECK_RET( bitmap.Ok(), wxT("invalid bitmap") );
|
||||||
|
|
||||||
|
bool is_mono = (bitmap.GetBitmap() != NULL);
|
||||||
|
|
||||||
|
/* scale/translate size and position */
|
||||||
|
int xx = XLOG2DEV(x);
|
||||||
|
int yy = YLOG2DEV(y);
|
||||||
|
|
||||||
|
int w = bitmap.GetWidth();
|
||||||
|
int h = bitmap.GetHeight();
|
||||||
|
|
||||||
|
CalcBoundingBox( x, y );
|
||||||
|
CalcBoundingBox( x + w, y + h );
|
||||||
|
|
||||||
|
if (!m_window) return;
|
||||||
|
|
||||||
|
int ww = XLOG2DEVREL(w);
|
||||||
|
int hh = YLOG2DEVREL(h);
|
||||||
|
|
||||||
|
/* compare to current clipping region */
|
||||||
|
if (!m_currentClippingRegion.IsNull())
|
||||||
|
{
|
||||||
|
wxRegion tmp( xx,yy,ww,hh );
|
||||||
|
tmp.Intersect( m_currentClippingRegion );
|
||||||
|
if (tmp.IsEmpty())
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* scale bitmap if required */
|
||||||
|
wxBitmap use_bitmap;
|
||||||
|
if ((w != ww) || (h != hh))
|
||||||
|
{
|
||||||
|
wxImage image( bitmap );
|
||||||
|
image.Rescale( ww, hh );
|
||||||
|
#if 0
|
||||||
|
if (is_mono)
|
||||||
|
use_bitmap = image.ConvertToMonoBitmap(255,255,255);
|
||||||
|
else
|
||||||
|
#endif
|
||||||
|
use_bitmap = image.ConvertToBitmap();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
use_bitmap = bitmap;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* apply mask if any */
|
||||||
|
WXPixmap mask = NULL;
|
||||||
|
if (use_bitmap.GetMask())
|
||||||
|
mask = use_bitmap.GetMask()->GetBitmap();
|
||||||
|
|
||||||
|
if (useMask && mask)
|
||||||
|
{
|
||||||
|
Pixmap pixmap = (Pixmap) use_bitmap.GetPixmap() ;
|
||||||
|
Pixmap maskPixmap = (Pixmap) use_bitmap.GetMask()->GetBitmap() ;
|
||||||
|
Pixmap bufPixmap = GrNewPixmap(w, h, 0);
|
||||||
|
GC gc = GrNewGC();
|
||||||
|
GrSetGCUseBackground(gc, FALSE);
|
||||||
|
GrSetGCMode(gc, GR_MODE_COPY);
|
||||||
|
|
||||||
|
// This code assumes that background and foreground
|
||||||
|
// colours are used in ROPs, like in MSW.
|
||||||
|
// Not sure if this is true.
|
||||||
|
|
||||||
|
// Copy destination to buffer.
|
||||||
|
// In DoBlit, we need this step because Blit has
|
||||||
|
// a ROP argument. Here, we don't need it.
|
||||||
|
// In DoBlit, we may be able to eliminate this step
|
||||||
|
// if we check if the rop = copy
|
||||||
|
#if 0
|
||||||
|
GrCopyArea(bufPixmap, gc, 0, 0, w, h, (Window) m_window,
|
||||||
|
0, 0, GR_MODE_COPY);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Copy src to buffer using selected raster op (none selected
|
||||||
|
// in DrawBitmap, so just use Gxcopy)
|
||||||
|
GrCopyArea(bufPixmap, gc, 0, 0, w, h, pixmap,
|
||||||
|
0, 0, GR_MODE_COPY);
|
||||||
|
|
||||||
|
// Set masked area in buffer to BLACK (pixel value 0)
|
||||||
|
GrSetGCBackground(gc, WHITE);
|
||||||
|
GrSetGCForeground(gc, BLACK);
|
||||||
|
GrCopyArea(bufPixmap, gc, 0, 0, w, h, maskPixmap,
|
||||||
|
0, 0, GR_MODE_AND);
|
||||||
|
|
||||||
|
// set unmasked area in dest to BLACK
|
||||||
|
GrSetGCBackground(gc, BLACK);
|
||||||
|
GrSetGCForeground(gc, WHITE);
|
||||||
|
GrCopyArea((Window) m_window, gc, xx, yy, w, h, maskPixmap,
|
||||||
|
0, 0, GR_MODE_AND);
|
||||||
|
|
||||||
|
// OR buffer to dest
|
||||||
|
GrCopyArea((Window) m_window, gc, xx, yy, w, h, bufPixmap,
|
||||||
|
0, 0, GR_MODE_OR);
|
||||||
|
|
||||||
|
GrDestroyGC(gc);
|
||||||
|
GrDestroyWindow(bufPixmap);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
XCopyArea( (Display*) m_display, (Pixmap) use_bitmap.GetPixmap(), (Window) m_window,
|
||||||
|
(GC) m_penGC, 0, 0, w, h, xx, yy );
|
||||||
|
|
||||||
|
/* remove mask again if any */
|
||||||
|
if (useMask && mask)
|
||||||
|
{
|
||||||
|
if (!m_currentClippingRegion.IsNull())
|
||||||
|
XSetRegion( (Display*) m_display, (GC) m_penGC, (Region) m_currentClippingRegion.GetX11Region() );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
// Normal X11
|
||||||
void wxWindowDC::DoDrawBitmap( const wxBitmap &bitmap,
|
void wxWindowDC::DoDrawBitmap( const wxBitmap &bitmap,
|
||||||
wxCoord x, wxCoord y,
|
wxCoord x, wxCoord y,
|
||||||
bool useMask )
|
bool useMask )
|
||||||
@@ -970,6 +1090,8 @@ void wxWindowDC::DoDrawBitmap( const wxBitmap &bitmap,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
// wxUSE_NANOX/!wxUSE_NANOX
|
||||||
|
|
||||||
bool wxWindowDC::DoBlit( wxCoord xdest, wxCoord ydest, wxCoord width, wxCoord height,
|
bool wxWindowDC::DoBlit( wxCoord xdest, wxCoord ydest, wxCoord width, wxCoord height,
|
||||||
wxDC *source, wxCoord xsrc, wxCoord ysrc, int rop, bool useMask,
|
wxDC *source, wxCoord xsrc, wxCoord ysrc, int rop, bool useMask,
|
||||||
|
@@ -27,6 +27,7 @@ ALL_SOURCES = \
|
|||||||
x11/pen.cpp \
|
x11/pen.cpp \
|
||||||
x11/popupwin.cpp \
|
x11/popupwin.cpp \
|
||||||
x11/region.cpp \
|
x11/region.cpp \
|
||||||
|
x11/reparent.cpp \
|
||||||
x11/settings.cpp \
|
x11/settings.cpp \
|
||||||
x11/toplevel.cpp \
|
x11/toplevel.cpp \
|
||||||
x11/utils.cpp \
|
x11/utils.cpp \
|
||||||
@@ -492,6 +493,7 @@ ALL_HEADERS = \
|
|||||||
x11/print.h \
|
x11/print.h \
|
||||||
x11/private.h \
|
x11/private.h \
|
||||||
x11/region.h \
|
x11/region.h \
|
||||||
|
x11/reparent.h \
|
||||||
x11/settings.h \
|
x11/settings.h \
|
||||||
x11/toolbar.h \
|
x11/toolbar.h \
|
||||||
x11/toplevel.h \
|
x11/toplevel.h \
|
||||||
@@ -622,6 +624,7 @@ GUI_LOWLEVEL_OBJS = \
|
|||||||
pen.o \
|
pen.o \
|
||||||
popupwin.o \
|
popupwin.o \
|
||||||
region.o \
|
region.o \
|
||||||
|
reparent.o \
|
||||||
settings.o \
|
settings.o \
|
||||||
toplevel.o \
|
toplevel.o \
|
||||||
utils.o \
|
utils.o \
|
||||||
|
322
src/x11/reparent.cpp
Normal file
322
src/x11/reparent.cpp
Normal file
@@ -0,0 +1,322 @@
|
|||||||
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
// Name: reparent.cpp
|
||||||
|
// Purpose: wxWindow
|
||||||
|
// Author: Julian Smart
|
||||||
|
// Modified by:
|
||||||
|
// Created: 2002-03-09
|
||||||
|
// RCS-ID: $Id$
|
||||||
|
// Copyright: (c) Julian Smart
|
||||||
|
// Licence: wxWindows licence
|
||||||
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
// ============================================================================
|
||||||
|
// declarations
|
||||||
|
// ============================================================================
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
// headers
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
#ifdef __GNUG__
|
||||||
|
#pragma implementation "reparent.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "wx/x11/reparent.h"
|
||||||
|
#include "wx/evtloop.h"
|
||||||
|
#include "wx/log.h"
|
||||||
|
#include "wx/app.h"
|
||||||
|
#include "wx/timer.h"
|
||||||
|
|
||||||
|
#include "wx/x11/private.h"
|
||||||
|
#include "X11/Xatom.h"
|
||||||
|
|
||||||
|
/*
|
||||||
|
|
||||||
|
Adapted from code by Mike Yang, as follows.
|
||||||
|
|
||||||
|
From: Mike Yang (mikey@eukanuba.wpd.sgi.com)
|
||||||
|
Subject: Re: Wrapping new widget around existing windows
|
||||||
|
Newsgroups: comp.windows.x
|
||||||
|
View: Complete Thread (17 articles) | Original Format
|
||||||
|
Date: 1991-08-09 09:45:48 PST
|
||||||
|
|
||||||
|
|
||||||
|
Enough people asked, so here's my test program which reparents another
|
||||||
|
window. It's a single file (reparent.c), and will work with Motif or
|
||||||
|
Xaw. Xaw users should comment out the "#define MOTIF" line.
|
||||||
|
|
||||||
|
The reparent program first prompts for the application name of the
|
||||||
|
client that it will reparent. If you're going to start the
|
||||||
|
application override_redirect (e.g. -xrm "*overrideRedirect: true"),
|
||||||
|
then this name is ignored and the first override_redirect window is
|
||||||
|
assumed to be the one.
|
||||||
|
|
||||||
|
Input focus is supposed to be correctly handled, as is resizing with
|
||||||
|
window manager hints. If you have input focus problems, try launching
|
||||||
|
your application override_redirect instead. This method is preferred
|
||||||
|
anyway, since you can map it off-screen and then avoid the "window
|
||||||
|
flash" effect as the application's top-level window is reparented.
|
||||||
|
|
||||||
|
-----------------------------------------------------------------------
|
||||||
|
Mike Yang Silicon Graphics, Inc.
|
||||||
|
mikey@sgi.com 415/335-1786
|
||||||
|
|
||||||
|
|
||||||
|
------------------------------- cut here ------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
|
||||||
|
Copyright 1991 by Mike Yang, mikey@sgi.com, Silicon Graphics, Inc.
|
||||||
|
|
||||||
|
Permission to use, copy, modify, distribute, and sell this software and its
|
||||||
|
documentation for any purpose is hereby granted without fee, provided that
|
||||||
|
the above copyright notice appear in all copies and that both that
|
||||||
|
copyright notice and this permission notice appear in supporting
|
||||||
|
documentation, and that the name of SGI not be used in advertising or
|
||||||
|
publicity pertaining to distribution of the software without specific,
|
||||||
|
written prior permission. SGI makes no representations about the
|
||||||
|
suitability of this software for any purpose. It is provided "as is"
|
||||||
|
without express or implied warranty.
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* wxAdoptedWindow
|
||||||
|
*/
|
||||||
|
|
||||||
|
wxAdoptedWindow::wxAdoptedWindow()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
wxAdoptedWindow::wxAdoptedWindow(WXWindow window)
|
||||||
|
{
|
||||||
|
m_mainWidget = window;
|
||||||
|
}
|
||||||
|
|
||||||
|
wxAdoptedWindow::~wxAdoptedWindow()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
* wxReparenter
|
||||||
|
*/
|
||||||
|
|
||||||
|
static bool Xerror;
|
||||||
|
static Atom WM_STATE = 0;
|
||||||
|
bool wxReparenter::sm_done = FALSE;
|
||||||
|
wxAdoptedWindow* wxReparenter::sm_toReparent = NULL;
|
||||||
|
wxWindow* wxReparenter::sm_newParent = NULL;
|
||||||
|
wxString wxReparenter::sm_name;
|
||||||
|
bool wxReparenter::sm_exactMatch = FALSE;
|
||||||
|
|
||||||
|
static int
|
||||||
|
ErrorHandler(Display* dpy, XErrorEvent* event)
|
||||||
|
{
|
||||||
|
Xerror = True;
|
||||||
|
return False;
|
||||||
|
}
|
||||||
|
|
||||||
|
// We assume that toReparent has had its X window set
|
||||||
|
// appropriately.
|
||||||
|
bool wxReparenter::Reparent(wxWindow* newParent, wxAdoptedWindow* toReparent)
|
||||||
|
{
|
||||||
|
XWindowAttributes xwa;
|
||||||
|
Window *children;
|
||||||
|
unsigned int numchildren, each;
|
||||||
|
Window returnroot, returnparent;
|
||||||
|
XErrorHandler old;
|
||||||
|
int parentOffset = 0;
|
||||||
|
|
||||||
|
old = XSetErrorHandler(ErrorHandler);
|
||||||
|
XReparentWindow((Display*) newParent->GetXDisplay(),
|
||||||
|
(Window) toReparent->GetXWindow(),
|
||||||
|
(Window) newParent->GetXWindow(),
|
||||||
|
0, 0);
|
||||||
|
|
||||||
|
if (!XQueryTree((Display*) newParent->GetXDisplay(),
|
||||||
|
(Window) toReparent->GetXWindow(),
|
||||||
|
&returnroot, &returnparent,
|
||||||
|
&children, &numchildren) || Xerror)
|
||||||
|
{
|
||||||
|
XSetErrorHandler(old);
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (numchildren > 0)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "Reparenting %d children.\n", numchildren);
|
||||||
|
/* Stacking order is preserved since XQueryTree returns its children in
|
||||||
|
bottommost to topmost order
|
||||||
|
*/
|
||||||
|
for (each=0; each<numchildren; each++)
|
||||||
|
{
|
||||||
|
XGetWindowAttributes((Display*) newParent->GetXDisplay(),
|
||||||
|
children[each], &xwa);
|
||||||
|
fprintf(stderr,
|
||||||
|
"Reparenting child at offset %d and position %d, %d.\n",
|
||||||
|
parentOffset, parentOffset+xwa.x, parentOffset+xwa.y);
|
||||||
|
XReparentWindow((Display*) newParent->GetXDisplay(),
|
||||||
|
children[each], (Window) newParent->GetXWindow(),
|
||||||
|
xwa.x, xwa.y);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
XSetErrorHandler(old);
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Wait for an appropriate window to be created.
|
||||||
|
// If exactMatch is FALSE, a substring match is OK.
|
||||||
|
// If windowName is empty, then wait for the next overrideRedirect window.
|
||||||
|
bool wxReparenter::WaitAndReparent(wxWindow* newParent, wxAdoptedWindow* toReparent,
|
||||||
|
const wxString& windowName,
|
||||||
|
bool exactMatch)
|
||||||
|
{
|
||||||
|
sm_newParent = newParent;
|
||||||
|
sm_toReparent = toReparent;
|
||||||
|
sm_exactMatch = exactMatch;
|
||||||
|
sm_name = windowName;
|
||||||
|
|
||||||
|
Display* display = (Display*) newParent->GetXDisplay() ;
|
||||||
|
XSelectInput(display,
|
||||||
|
RootWindowOfScreen(DefaultScreenOfDisplay(display)),
|
||||||
|
SubstructureNotifyMask);
|
||||||
|
|
||||||
|
if (!WM_STATE)
|
||||||
|
WM_STATE = XInternAtom(display, "WM_STATE", False);
|
||||||
|
|
||||||
|
#ifdef __WXDEBUG__
|
||||||
|
if (!windowName.IsEmpty())
|
||||||
|
wxLogDebug(_T("Waiting for window %s"), windowName.c_str());
|
||||||
|
#endif
|
||||||
|
|
||||||
|
sm_done = FALSE;
|
||||||
|
|
||||||
|
wxEventLoop eventLoop;
|
||||||
|
while (!sm_done)
|
||||||
|
{
|
||||||
|
if (eventLoop.Pending())
|
||||||
|
{
|
||||||
|
XEvent xevent;
|
||||||
|
XNextEvent(display, & xevent);
|
||||||
|
if (!wxTheApp->ProcessXEvent((WXEvent*) & xevent))
|
||||||
|
{
|
||||||
|
// Do the local event processing
|
||||||
|
ProcessXEvent((WXEvent*) & xevent);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
#if wxUSE_TIMER
|
||||||
|
wxTimer::NotifyTimers();
|
||||||
|
wxTheApp->SendIdleEvents();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool wxReparenter::ProcessXEvent(WXEvent* event)
|
||||||
|
{
|
||||||
|
XEvent* xevent = (XEvent*) event;
|
||||||
|
Window client;
|
||||||
|
|
||||||
|
if (!sm_done)
|
||||||
|
{
|
||||||
|
if (xevent->type == MapNotify)
|
||||||
|
{
|
||||||
|
wxLogDebug(_T("Window was mapped"));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (xevent->type == MapNotify && !xevent->xmap.override_redirect &&
|
||||||
|
(client = (Window) FindAClientWindow((WXWindow) xevent->xmap.window, sm_name)))
|
||||||
|
{
|
||||||
|
wxLogDebug(_T("Found a client window, about to reparent"));
|
||||||
|
wxASSERT(sm_toReparent->GetParent() == NULL);
|
||||||
|
|
||||||
|
sm_toReparent->SetHandle((WXWindow) client);
|
||||||
|
sm_newParent->AddChild(sm_toReparent);
|
||||||
|
sm_done = Reparent(sm_newParent, sm_toReparent);
|
||||||
|
return sm_done;
|
||||||
|
} else if (xevent->type == MapNotify &&
|
||||||
|
xevent->xmap.override_redirect &&
|
||||||
|
xevent->xmap.window)
|
||||||
|
{
|
||||||
|
wxLogDebug(_T("Found an override redirect window, about to reparent"));
|
||||||
|
sm_toReparent->SetHandle((WXWindow) xevent->xmap.window);
|
||||||
|
sm_newParent->AddChild(sm_toReparent);
|
||||||
|
wxASSERT(sm_toReparent->GetParent() == NULL);
|
||||||
|
|
||||||
|
sm_done = Reparent(sm_newParent, sm_toReparent);
|
||||||
|
return sm_done;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
WXWindow wxReparenter::FindAClientWindow(WXWindow window, const wxString& name)
|
||||||
|
{
|
||||||
|
int rvalue, i;
|
||||||
|
Atom actualtype;
|
||||||
|
int actualformat;
|
||||||
|
unsigned long nitems, bytesafter;
|
||||||
|
unsigned char *propreturn;
|
||||||
|
Window *children;
|
||||||
|
unsigned int numchildren;
|
||||||
|
Window returnroot, returnparent;
|
||||||
|
Window result = 0;
|
||||||
|
XErrorHandler old;
|
||||||
|
char *clientName;
|
||||||
|
|
||||||
|
Xerror = False;
|
||||||
|
old = XSetErrorHandler(ErrorHandler);
|
||||||
|
rvalue = XGetWindowProperty((Display*) wxGetDisplay(),
|
||||||
|
(Window) window, WM_STATE,
|
||||||
|
0, 1, False,
|
||||||
|
AnyPropertyType, &actualtype, &actualformat,
|
||||||
|
&nitems, &bytesafter, &propreturn);
|
||||||
|
XSetErrorHandler(old);
|
||||||
|
if (!Xerror && rvalue == Success && actualtype != None)
|
||||||
|
{
|
||||||
|
if (rvalue == Success)
|
||||||
|
{
|
||||||
|
XFree((char *) propreturn);
|
||||||
|
}
|
||||||
|
XFetchName((Display*) wxGetDisplay(), (Window) window, &clientName);
|
||||||
|
|
||||||
|
wxString str1(name);
|
||||||
|
wxString str2(clientName);
|
||||||
|
str1.Lower();
|
||||||
|
str2.Lower();
|
||||||
|
|
||||||
|
bool matches;
|
||||||
|
if (sm_exactMatch)
|
||||||
|
matches = (name == clientName);
|
||||||
|
else
|
||||||
|
matches = (str1.Contains(str2) || str2.Contains(str1));
|
||||||
|
|
||||||
|
XFree(clientName);
|
||||||
|
|
||||||
|
if (matches)
|
||||||
|
return (WXWindow) window;
|
||||||
|
else
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
old = XSetErrorHandler(ErrorHandler);
|
||||||
|
if (!XQueryTree((Display*) wxGetDisplay(), (Window) window, &returnroot, &returnparent,
|
||||||
|
&children, &numchildren) || Xerror) {
|
||||||
|
XSetErrorHandler(old);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
XSetErrorHandler(old);
|
||||||
|
|
||||||
|
result = 0;
|
||||||
|
for (i=0; i<(int)numchildren && !result ;i++) {
|
||||||
|
result = (Window) FindAClientWindow((WXWindow) children[i], name);
|
||||||
|
}
|
||||||
|
if (numchildren) {
|
||||||
|
XFree((char *) children);
|
||||||
|
} return (WXWindow) result;
|
||||||
|
}
|
||||||
|
|
Reference in New Issue
Block a user