mirror of
https://invent.kde.org/system/dolphin
synced 2024-11-05 18:47:12 +00:00
6ce84cd8c1
- Don't activate the Xt pump when not needed; it's not for most commonly used plugins - Don't use our glib pump's timer when Qt's glib event loop is on anyway. This doesn't cover 100% of situations, and doesn't really explain why QT_NO_GLIB works better for some people (never saw this particular case myself), but it should cover the "nspluginviewer wakes up a lot and uses a few% of cpu" case for most people. Hopefully. CCBUG: 182869 I am thinking off holding of on backporting this till 4.4.1, though.... svn path=/trunk/KDE/kdebase/apps/; revision=1075295
176 lines
5.9 KiB
C++
176 lines
5.9 KiB
C++
/*
|
|
|
|
Xt plugin embedding support
|
|
|
|
Copyright (c) 2000 Matthias Hoelzer-Kluepfel <hoelzer@kde.org>
|
|
Stefan Schimanski <1Stein@gmx.de>
|
|
2003-2005 George Staikos <staikos@kde.org>
|
|
2007 Maksim orlovich <maksim@kde.org>
|
|
|
|
This program is free software; you can redistribute it and/or modify
|
|
it under the terms of the GNU General Public License as published by
|
|
the Free Software Foundation; either version 2 of the License, or
|
|
(at your option) any later version.
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
GNU General Public License for more details.
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
along with this program; if not, write to the Free Software
|
|
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|
|
|
*/
|
|
|
|
#include "pluginhost_xt.h"
|
|
#include <QX11Info>
|
|
#include <QVBoxLayout>
|
|
#include <QLabel>
|
|
|
|
#include "xtevents.h"
|
|
|
|
// BEGIN Workaround for QX11EmbedWidget silliness --- it maps widgets by default
|
|
// Most of the code is from Qt 4.3.3, Copyright (C) 1992-2007 Trolltech ASA
|
|
static unsigned int XEMBED_VERSION = 0;
|
|
static Atom _XEMBED_INFO = None;
|
|
static void initXEmbedAtoms(Display *d)
|
|
{
|
|
if (_XEMBED_INFO == None)
|
|
_XEMBED_INFO = XInternAtom(d, "_XEMBED_INFO", false);
|
|
}
|
|
|
|
static void doNotAskForXEmbedMapping(QX11EmbedWidget* widget)
|
|
{
|
|
initXEmbedAtoms(widget->x11Info().display());
|
|
unsigned int data[] = {XEMBED_VERSION, 0 /* e.g. not XEMBED_MAPPED*/};
|
|
XChangeProperty(widget->x11Info().display(), widget->winId(), _XEMBED_INFO,
|
|
_XEMBED_INFO, 32, PropModeReplace,
|
|
(unsigned char*) data, 2);
|
|
}
|
|
|
|
// END Workaround for QX11EmbedWidget silliness.
|
|
|
|
|
|
PluginHostXt::PluginHostXt(NSPluginInstance* plugin):
|
|
_plugin(plugin), _outside(0), _toplevel(0), _form(0)
|
|
{
|
|
XtEvents::enable();
|
|
}
|
|
|
|
|
|
void PluginHostXt::setupWindow(int winId, int width, int height)
|
|
{
|
|
_outside = new QX11EmbedWidget();
|
|
doNotAskForXEmbedMapping(_outside);
|
|
_outside->embedInto(winId);
|
|
|
|
Arg args[7];
|
|
Cardinal nargs = 0;
|
|
XtSetArg(args[nargs], XtNwidth, width); nargs++;
|
|
XtSetArg(args[nargs], XtNheight, height); nargs++;
|
|
XtSetArg(args[nargs], XtNborderWidth, 0); nargs++;
|
|
|
|
String n, c;
|
|
XtGetApplicationNameAndClass(QX11Info::display(), &n, &c);
|
|
_toplevel = XtAppCreateShell("drawingArea", c, applicationShellWidgetClass,
|
|
QX11Info::display(), args, nargs);
|
|
|
|
//if (embed)
|
|
XtSetMappedWhenManaged(_toplevel, False);
|
|
XtRealizeWidget(_toplevel);
|
|
|
|
// Create form window that is searched for by flash plugin
|
|
_form = XtVaCreateWidget("form", compositeWidgetClass, _toplevel, NULL);
|
|
XtSetArg(args[nargs], XtNvisual, QX11Info::appVisual()); nargs++;
|
|
XtSetArg(args[nargs], XtNdepth, QX11Info::appDepth()); nargs++;
|
|
XtSetArg(args[nargs], XtNcolormap, QX11Info::appColormap()); nargs++;
|
|
XtSetValues(_form, args, nargs);
|
|
XSync(QX11Info::display(), false);
|
|
|
|
// From mozilla - not sure if it's needed yet, nor what to use for embedder
|
|
#if 0
|
|
/* this little trick seems to finish initializing the widget */
|
|
#if XlibSpecificationRelease >= 6
|
|
XtRegisterDrawable(QX11Info::display(), embedderid, _toplevel);
|
|
#else
|
|
_XtRegisterWindow(embedderid, _toplevel);
|
|
#endif
|
|
#endif
|
|
XtRealizeWidget(_form);
|
|
XtManageChild(_form);
|
|
|
|
// Register forwarder
|
|
XtAddEventHandler(_toplevel, (KeyPressMask|KeyReleaseMask),
|
|
False, forwarder, (XtPointer)this );
|
|
XtAddEventHandler(_form, (KeyPressMask|KeyReleaseMask),
|
|
False, forwarder, (XtPointer)this );
|
|
|
|
// Embed the Xt widget into the Qt widget
|
|
XReparentWindow(QX11Info::display(), XtWindow(_toplevel), _outside->winId(), 0, 0);
|
|
XtMapWidget(_toplevel);
|
|
setupPluginWindow(_plugin, (void*) XtWindow(_form), width, height);
|
|
}
|
|
|
|
PluginHostXt::~PluginHostXt()
|
|
{
|
|
if (_form) {
|
|
XtRemoveEventHandler(_form, (KeyPressMask|KeyReleaseMask),
|
|
False, forwarder, (XtPointer)this);
|
|
XtRemoveEventHandler(_toplevel, (KeyPressMask|KeyReleaseMask),
|
|
False, forwarder, (XtPointer)this);
|
|
XtDestroyWidget(_form);
|
|
XtDestroyWidget(_toplevel);
|
|
_form = 0;
|
|
_toplevel = 0;
|
|
}
|
|
delete _outside;
|
|
}
|
|
|
|
void PluginHostXt::forwarder(Widget w, XtPointer cl_data, XEvent * event, Boolean * cont)
|
|
{
|
|
Q_UNUSED(w);
|
|
PluginHostXt *inst = (PluginHostXt*)cl_data;
|
|
*cont = True;
|
|
if (inst->_form == 0 || event->xkey.window == XtWindow(inst->_form))
|
|
return;
|
|
*cont = False;
|
|
event->xkey.window = XtWindow(inst->_form);
|
|
event->xkey.subwindow = None;
|
|
XtDispatchEvent(event);
|
|
}
|
|
|
|
|
|
static void resizeWidgets(Window w, int width, int height) {
|
|
Window rroot, parent, *children;
|
|
unsigned int nchildren = 0;
|
|
|
|
if (XQueryTree(QX11Info::display(), w, &rroot, &parent, &children, &nchildren)) {
|
|
for (unsigned int i = 0; i < nchildren; i++) {
|
|
XResizeWindow(QX11Info::display(), children[i], width, height);
|
|
}
|
|
XFree(children);
|
|
}
|
|
}
|
|
|
|
void PluginHostXt::resizePlugin(int /*pluginWinId*/, int w, int h)
|
|
{
|
|
kDebug(1431) << w << h;
|
|
XResizeWindow(QX11Info::display(), XtWindow(_form), w, h);
|
|
XResizeWindow(QX11Info::display(), XtWindow(_toplevel), w, h);
|
|
|
|
Arg args[7];
|
|
Cardinal nargs = 0;
|
|
XtSetArg(args[nargs], XtNwidth, w); nargs++;
|
|
XtSetArg(args[nargs], XtNheight, h); nargs++;
|
|
XtSetArg(args[nargs], XtNvisual, QX11Info::appVisual()); nargs++;
|
|
XtSetArg(args[nargs], XtNdepth, QX11Info::appDepth()); nargs++;
|
|
XtSetArg(args[nargs], XtNcolormap, QX11Info::appColormap()); nargs++;
|
|
XtSetArg(args[nargs], XtNborderWidth, 0); nargs++;
|
|
|
|
XtSetValues(_form, args, nargs);
|
|
|
|
resizeWidgets(XtWindow(_form), w, h);
|
|
}
|
|
|
|
// kate: indent-width 4; replace-tabs on; tab-width 4; space-indent on;
|