diff -Nur compiz-0.8.2/kde/window-decorator-kde4/decorator.cpp compiz-0.8.2-kde43/kde/window-decorator-kde4/decorator.cpp
--- compiz-0.8.2/kde/window-decorator-kde4/decorator.cpp 2009-02-15 10:10:23.000000000 +0100
+++ compiz-0.8.2-kde43/kde/window-decorator-kde4/decorator.cpp 2010-02-13 14:47:05.000000000 +0100
@@ -61,16 +61,9 @@
#define DBUS_METHOD_GET "get"
#define DBUS_SIGNAL_CHANGED "changed"
-double decorationOpacity = 0.75;
-bool decorationOpacityShade = false;
-double activeDecorationOpacity = 1.0;
-bool activeDecorationOpacityShade = false;
int blurType = BLUR_TYPE_NONE;
-decor_context_t KWD::Decorator::mDefaultContext;
-decor_extents_t KWD::Decorator::mDefaultBorder;
decor_shadow_t *KWD::Decorator::mNoBorderShadow = 0;
-decor_shadow_t *KWD::Decorator::mDefaultShadow = 0;
KWD::PluginManager *KWD::Decorator::mPlugins = 0;
KWD::Options *KWD::Decorator::mOptions = 0;
NETRootInfo *KWD::Decorator::mRootInfo;
@@ -91,10 +84,8 @@
}
-KWD::Decorator::Decorator (Display* display,
- Qt::HANDLE visual,
- Qt::HANDLE colormap) :
- KApplication (display, visual, colormap),
+KWD::Decorator::Decorator () :
+ KApplication (),
mConfig (0),
mCompositeWindow (0),
mSwitcher (0)
@@ -200,13 +191,11 @@
}
bool
-KWD::Decorator::enableDecorations (Time timestamp,
- int damageEvent)
+KWD::Decorator::enableDecorations (Time timestamp)
{
QList <WId>::ConstIterator it;
mDmSnTimestamp = timestamp;
- mDamageEvent = damageEvent;
if (!pluginManager ()->loadPlugin (""))
return false;
@@ -239,8 +228,6 @@
foreach (WId id, KWindowSystem::windows ())
handleWindowAdded (id);
- connect (&mIdleTimer, SIGNAL (timeout ()), SLOT (processDamage ()));
-
connect (Plasma::Theme::defaultTheme (), SIGNAL (themeChanged ()),
SLOT (plasmaThemeChanged ()));
@@ -252,31 +239,6 @@
}
void
-KWD::Decorator::updateDefaultShadow (KWD::Window *w)
-{
- bool uniqueHorzShape, uniqueVertShape;
-
- if (mDefaultShadow)
- {
- decor_shadow_destroy (QX11Info::display(), mDefaultShadow);
- mDefaultShadow = NULL;
- }
-
- w->getShapeInfo (&uniqueHorzShape, &uniqueVertShape);
-
- /* only return shadow if decoration doesn't use a unique shape */
- if (uniqueHorzShape || uniqueVertShape)
- return;
-
- mDefaultContext = *w->context ();
- mDefaultBorder = *w->border ();
- mDefaultShadow = w->shadow ();
-
- if (mDefaultShadow)
- decor_shadow_reference (mDefaultShadow);
-}
-
-void
KWD::Decorator::updateAllShadowOptions (void)
{
QDBusInterface *compiz;
@@ -345,12 +307,6 @@
mShadowOptions = *opt;
updateShadow ();
-
- mDecorNormal->reloadDecoration ();
- mDecorActive->reloadDecoration ();
-
- for (it = mClients.constBegin (); it != mClients.constEnd (); it++)
- it.value ()->reloadDecoration ();
}
void
@@ -362,12 +318,6 @@
xscreen = ScreenOfDisplay (xdisplay, QX11Info::appScreen ());
- if (mDefaultShadow)
- {
- decor_shadow_destroy (xdisplay, mDefaultShadow);
- mDefaultShadow = NULL;
- }
-
if (mNoBorderShadow)
decor_shadow_destroy (xdisplay, mNoBorderShadow);
@@ -410,18 +360,6 @@
}
}
-void
-KWD::Decorator::processDamage (void)
-{
- QMap <WId, KWD::Window *>::ConstIterator it;
-
- mDecorNormal->processDamage ();
- mDecorActive->processDamage ();
-
- for (it = mClients.constBegin (); it != mClients.constEnd (); it++)
- it.value ()->processDamage ();
-}
-
bool
KWD::Decorator::x11EventFilter (XEvent *xevent)
{
@@ -429,50 +367,12 @@
int status;
switch (xevent->type) {
- case MapNotify: {
- XMapEvent *xme = reinterpret_cast <XMapEvent *> (xevent);
-
- if (mWindows.contains (xme->window))
- client = mWindows[xme->window];
- else if (mDecorNormal->winId () == xme->window)
- client = mDecorNormal;
- else if (mDecorActive->winId () == xme->window)
- client = mDecorActive;
- else
- break;
-
- if (client->handleMap ())
- {
- if (!mIdleTimer.isActive ())
- {
- mIdleTimer.setSingleShot (true);
- mIdleTimer.start (0);
- }
- }
- } break;
case ConfigureNotify: {
XConfigureEvent *xce = reinterpret_cast <XConfigureEvent *> (xevent);
if (mFrames.contains (xce->window))
mFrames[xce->window]->updateFrame (xce->window);
- if (mWindows.contains (xce->window))
- client = mWindows[xce->window];
- else if (mDecorNormal->winId () == xce->window)
- client = mDecorNormal;
- else if (mDecorActive->winId () == xce->window)
- client = mDecorActive;
- else
- break;
-
- if (client->handleConfigure (QSize (xce->width, xce->height)))
- {
- if (!mIdleTimer.isActive ())
- {
- mIdleTimer.setSingleShot (true);
- mIdleTimer.start (0);
- }
- }
} break;
case SelectionRequest:
decor_handle_selection_request (QX11Info::display(), xevent, mDmSnTimestamp);
@@ -512,6 +412,9 @@
break;
client = mFrames[xce->window];
+
+ if (!client->decorWidget ())
+ break;
child = client->childAt (xce->x, xce->y);
if (child)
@@ -549,6 +452,9 @@
break;
client = mFrames[xme->window];
+
+ if (!client->decorWidget ())
+ break;
child = client->childAt (xme->x, xme->y);
@@ -569,8 +475,8 @@
client->setActiveChild (child);
}
- if (client != child)
- qp -= QPoint (child->pos ().x (), child->pos ().y ());
+ if (client->decorWidget () != child)
+ qp = child->mapFrom (client->decorWidget (), qp);
QMouseEvent qme (QEvent::MouseMove, qp, Qt::NoButton,
Qt::NoButton, Qt::NoModifier);
@@ -590,6 +496,9 @@
break;
client = mFrames[xbe->window];
+
+ if (!client->decorWidget ())
+ break;
child = client->childAt (xbe->x, xbe->y);
@@ -597,11 +506,11 @@
{
XButtonEvent xbe2 = *xbe;
xbe2.window = child->winId ();
- if (client != child)
- {
- xbe2.x = xbe->x - child->pos ().x ();
- xbe2.y = xbe->y - child->pos ().y ();
- }
+ QPoint p;
+
+ p = client->mapToChildAt (QPoint (xbe->x, xbe->y));
+ xbe2.x = p.x ();
+ xbe2.y = p.y ();
client->setFakeRelease (false);
QApplication::x11ProcessEvent ((XEvent *) &xbe2);
@@ -661,36 +570,6 @@
}
break;
default:
- if (xevent->type == mDamageEvent + XDamageNotify)
- {
- XDamageNotifyEvent *xde =
- reinterpret_cast <XDamageNotifyEvent *>(xevent);
-
- if (mWindows.contains (xde->drawable))
- client = mWindows[xde->drawable];
- else if (mDecorNormal->winId () == xde->drawable)
- client = mDecorNormal;
- else if (mDecorActive->winId () == xde->drawable)
- client = mDecorActive;
- else
- break;
-
- client->addDamageRect (xde->area.x,
- xde->area.y,
- xde->area.width,
- xde->area.height);
-
- if (client->pixmapId ())
- {
- if (!mIdleTimer.isActive ())
- {
- mIdleTimer.setSingleShot (true);
- mIdleTimer.start (0);
- }
- }
-
- return true;
- }
break;
}
@@ -794,7 +673,6 @@
height + border * 2);
mClients.insert (id, client);
- mWindows.insert (client->winId (), client);
mFrames.insert (frame, client);
}
else
@@ -814,7 +692,6 @@
if (client)
{
mClients.remove (client->windowId ());
- mWindows.remove (client->winId ());
mFrames.remove (client->frameId ());
delete client;
@@ -835,7 +712,6 @@
if (window)
{
mClients.remove (window->windowId ());
- mWindows.remove (window->winId ());
mFrames.remove (window->frameId ());
delete window;
}
diff -Nur compiz-0.8.2/kde/window-decorator-kde4/decorator.h compiz-0.8.2-kde43/kde/window-decorator-kde4/decorator.h
--- compiz-0.8.2/kde/window-decorator-kde4/decorator.h 2009-02-15 10:10:04.000000000 +0100
+++ compiz-0.8.2-kde43/kde/window-decorator-kde4/decorator.h 2010-02-13 17:13:17.000000000 +0100
@@ -54,11 +54,6 @@
extern struct _cursor cursors[3][3];
-extern double decorationOpacity;
-extern bool decorationOpacityShade;
-extern double activeDecorationOpacity;
-extern bool activeDecorationOpacityShade;
-
#define BLUR_TYPE_NONE 0
#define BLUR_TYPE_TITLEBAR 1
#define BLUR_TYPE_ALL 2
@@ -84,7 +79,7 @@
class Decorator:public KApplication {
Q_OBJECT public:
- Decorator (Display* display, Qt::HANDLE visual, Qt::HANDLE colormap);
+ Decorator ();
~Decorator (void);
static NETRootInfo *rootInfo (void)
@@ -107,18 +102,7 @@
{
return &mShadowOptions;
}
- static decor_shadow_t *defaultWindowShadow (decor_context_t *context,
- decor_extents_t *border)
- {
- if (!mDefaultShadow)
- return NULL;
- if (memcmp (border, &mDefaultBorder, sizeof (decor_extents_t)) != 0)
- return NULL;
-
- *context = mDefaultContext;
- return mDefaultShadow;
- }
static void sendClientMessage (WId eventWid,
WId wid,
Atom atom,
@@ -126,9 +110,8 @@
long data1 = 0,
long data2 = 0,
long data3 = 0);
- static void updateDefaultShadow (KWD::Window *w);
-
- bool enableDecorations (Time timestamp, int damageEvent);
+
+ bool enableDecorations (Time timestamp);
bool x11EventFilter (XEvent *xevent);
void changeShadowOptions (decor_shadow_options_t *opt);
@@ -146,7 +129,7 @@
void handleActiveWindowChanged (WId id);
void handleWindowChanged (WId id,
const unsigned long *properties);
- void processDamage (void);
+
void shadowRadiusChanged (double value);
void shadowOpacityChanged (double value);
void shadowXOffsetChanged (int value);
@@ -158,9 +141,6 @@
private:
static PluginManager *mPlugins;
static KWD::Options *mOptions;
- static decor_extents_t mDefaultBorder;
- static decor_context_t mDefaultContext;
- static decor_shadow_t *mDefaultShadow;
static decor_shadow_t *mNoBorderShadow;
static decor_shadow_options_t mShadowOptions;
static NETRootInfo *mRootInfo;
@@ -170,11 +150,8 @@
KWD::Window *mDecorActive;
QMap <WId, KWD::Window *>mClients;
QMap <WId, KWD::Window *>mFrames;
- QMap <WId, KWD::Window *>mWindows;
KConfig *mConfig;
Time mDmSnTimestamp;
- int mDamageEvent;
- QTimer mIdleTimer;
WId mCompositeWindow;
diff -Nur compiz-0.8.2/kde/window-decorator-kde4/main.cpp compiz-0.8.2-kde43/kde/window-decorator-kde4/main.cpp
--- compiz-0.8.2/kde/window-decorator-kde4/main.cpp 2009-02-15 10:10:23.000000000 +0100
+++ compiz-0.8.2-kde43/kde/window-decorator-kde4/main.cpp 2010-02-13 14:50:13.000000000 +0100
@@ -44,24 +44,12 @@
KCmdLineArgs *args;
KCmdLineOptions options;
int status;
- int event, error;
Time timestamp;
- Colormap colormap = 0;
- Visual *visual = 0;
- int event_base, error_base;
- Display *dpy;
- int screen;
QString appname;
options.add ("replace", ki18n ("Replace existing window decorator"));
options.add ("sm-disable", ki18n ("Disable connection to session manager"));
- options.add ("opacity <value>", ki18n ("Decoration opacity"), "0.75");
- options.add ("no-opacity-shade", ki18n ("No decoration opacity shading"));
- options.add ("active-opacity <value>",
- ki18n ("Active decoration opacity"), "1.0");
- options.add ("no-active-opacity-shade",
- ki18n ("No active decoration opacity shading"));
- options.add ("blur <type>", ki18n ("Blur type"), "none");
+ options.add ("blur <type>", ki18n ("Blur type (none,titlebar,all)"), "none");
KCmdLineArgs::init (argc, argv,
"kde-window-decorator",
@@ -71,19 +59,6 @@
KCmdLineArgs::addCmdLineOptions (options);
args = KCmdLineArgs::parsedArgs ();
- if (args->isSet ("opacity"))
- decorationOpacity = args->getOption ("opacity").toDouble ();
-
- if (args->isSet ("-opacity-shade"))
- decorationOpacityShade = true;
-
- if (args->isSet ("active-opacity"))
- activeDecorationOpacity =
- args->getOption ("active-opacity").toDouble ();
-
- if (args->isSet ("-active-opacity-shade"))
- activeDecorationOpacityShade = true;
-
if (args->isSet ("blur"))
{
QString blur = args->getOption ("blur");
@@ -94,56 +69,11 @@
blurType = BLUR_TYPE_ALL;
}
- dpy = XOpenDisplay(0); // open default display
- screen = DefaultScreen (dpy);
- if (!dpy) {
- kError() << "Cannot connect to the X server" << endl;
- return 0;
- }
-
- if (XRenderQueryExtension (dpy, &event_base, &error_base))
- {
- int nvi;
- XVisualInfo templ;
- templ.screen = screen;
- templ.depth = 32;
- templ.c_class = TrueColor;
- XVisualInfo *xvi = XGetVisualInfo (dpy, VisualScreenMask |
- VisualDepthMask |
- VisualClassMask, &templ, &nvi);
-
- for (int i = 0; i < nvi; i++)
- {
- XRenderPictFormat *format =
- XRenderFindVisualFormat (dpy, xvi[i].visual);
- if (format->type == PictTypeDirect && format->direct.alphaMask)
- {
- visual = xvi[i].visual;
- colormap = XCreateColormap (dpy, RootWindow (dpy, screen),
- visual, AllocNone);
- break;
- }
- }
- }
-
- // Disable window less child widgets
- QApplication::setAttribute(Qt::AA_NativeWindows, true);
-
- app = new KWD::Decorator (dpy, visual ? Qt::HANDLE(visual) : 0,
- colormap ? Qt::HANDLE(colormap) : 0);
+ app = new KWD::Decorator ();
if (args->isSet ("sm-disable"))
app->disableSessionManagement ();
- if (!XDamageQueryExtension (QX11Info::display(), &event, &error))
- {
- fprintf (stderr,
- "%s: Damage extension is missing on display \"%s\"\n",
- argv[0], DisplayString (QX11Info::display()));
-
- return 1;
- }
-
status = decor_acquire_dm_session (QX11Info::display(),
QX11Info::appScreen (),
"kwd", args->isSet ("replace"),
@@ -174,7 +104,7 @@
decor_set_dm_check_hint (QX11Info::display(), QX11Info::appScreen ());
- if (!app->enableDecorations (timestamp, event))
+ if (!app->enableDecorations (timestamp))
{
fprintf (stderr,
"%s: Could not enable decorations on display \"%s\"\n",
diff -Nur compiz-0.8.2/kde/window-decorator-kde4/Makefile.am compiz-0.8.2-kde43/kde/window-decorator-kde4/Makefile.am
--- compiz-0.8.2/kde/window-decorator-kde4/Makefile.am 2009-02-15 10:10:23.000000000 +0100
+++ compiz-0.8.2-kde43/kde/window-decorator-kde4/Makefile.am 2010-02-13 17:57:41.000000000 +0100
@@ -3,6 +3,7 @@
BUILDSOURCES = \
decorator.moc.cpp \
window.moc.cpp \
+ paintredirector.moc.cpp \
kwinadaptor.moc.cpp \
kwinadaptor.cpp \
kwinadaptor.h
@@ -30,6 +31,8 @@
kdecoration_plugins.h \
switcher.cpp \
switcher.h \
+ paintredirector.cpp \
+ paintredirector.h \
org.kde.KWin.xml
kde4_window_decorator_program = kde4-window-decorator
diff -Nur compiz-0.8.2/kde/window-decorator-kde4/Makefile.in compiz-0.8.2-kde43/kde/window-decorator-kde4/Makefile.in
--- compiz-0.8.2/kde/window-decorator-kde4/Makefile.in 2009-03-01 13:15:43.000000000 +0100
+++ compiz-0.8.2-kde43/kde/window-decorator-kde4/Makefile.in 2010-02-13 18:03:23.000000000 +0100
@@ -49,14 +49,14 @@
am__dist_kde4_window_decorator_SOURCES_DIST = main.cpp utils.cpp \
utils.h decorator.cpp decorator.h window.cpp window.h \
options.cpp options.h kdecoration_plugins.cpp \
- kdecoration_plugins.h switcher.cpp switcher.h org.kde.KWin.xml
+ kdecoration_plugins.h switcher.cpp switcher.h paintredirector.cpp paintredirector.h org.kde.KWin.xml
@USE_KDE4_TRUE@dist_kde4_window_decorator_OBJECTS = main.$(OBJEXT) \
@USE_KDE4_TRUE@ utils.$(OBJEXT) decorator.$(OBJEXT) \
@USE_KDE4_TRUE@ window.$(OBJEXT) options.$(OBJEXT) \
@USE_KDE4_TRUE@ kdecoration_plugins.$(OBJEXT) \
-@USE_KDE4_TRUE@ switcher.$(OBJEXT)
+@USE_KDE4_TRUE@ switcher.$(OBJEXT) paintredirector.$(OBJEXT)
@USE_KDE4_TRUE@am__objects_1 = decorator.moc.$(OBJEXT) \
-@USE_KDE4_TRUE@ window.moc.$(OBJEXT) kwinadaptor.moc.$(OBJEXT) \
+@USE_KDE4_TRUE@ window.moc.$(OBJEXT) paintredirector.moc.$(OBJEXT) kwinadaptor.moc.$(OBJEXT) \
@USE_KDE4_TRUE@ kwinadaptor.$(OBJEXT)
@USE_KDE4_TRUE@nodist_kde4_window_decorator_OBJECTS = \
@USE_KDE4_TRUE@ $(am__objects_1)
@@ -310,6 +310,7 @@
@USE_KDE4_TRUE@BUILDSOURCES = \
@USE_KDE4_TRUE@ decorator.moc.cpp \
@USE_KDE4_TRUE@ window.moc.cpp \
+@USE_KDE4_TRUE@ paintredirector.moc.cpp \
@USE_KDE4_TRUE@ kwinadaptor.moc.cpp \
@USE_KDE4_TRUE@ kwinadaptor.cpp \
@USE_KDE4_TRUE@ kwinadaptor.h
@@ -338,6 +339,8 @@
@USE_KDE4_TRUE@ kdecoration_plugins.h \
@USE_KDE4_TRUE@ switcher.cpp \
@USE_KDE4_TRUE@ switcher.h \
+@USE_KDE4_TRUE@ paintredirector.cpp \
+@USE_KDE4_TRUE@ paintredirector.h \
@USE_KDE4_TRUE@ org.kde.KWin.xml
@USE_KDE4_TRUE@kde4_window_decorator_program = kde4-window-decorator
@@ -423,6 +426,8 @@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/main.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/options.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/switcher.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/paintredirector.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/paintredirector.moc.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/utils.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/window.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/window.moc.Po@am__quote@
diff -Nur compiz-0.8.2/kde/window-decorator-kde4/paintredirector.cpp compiz-0.8.2-kde43/kde/window-decorator-kde4/paintredirector.cpp
--- compiz-0.8.2/kde/window-decorator-kde4/paintredirector.cpp 1970-01-01 01:00:00.000000000 +0100
+++ compiz-0.8.2-kde43/kde/window-decorator-kde4/paintredirector.cpp 2010-02-13 14:42:38.000000000 +0100
@@ -0,0 +1,125 @@
+/*****************************************************************
+This file is part of the KDE project.
+
+Copyright (C) 2009 Lubos Lunak <l.lunak@kde.org>
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the "Software"),
+to deal in the Software without restriction, including without limitation
+the rights to use, copy, modify, merge, publish, distribute, sublicense,
+and/or sell copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+DEALINGS IN THE SOFTWARE.
+******************************************************************/
+
+#include "paintredirector.h"
+
+#include <kdebug.h>
+#include <qevent.h>
+#include <qpainter.h>
+
+namespace KWin
+{
+
+PaintRedirector::PaintRedirector( QWidget* w )
+ : widget( w )
+ , recursionCheck( false )
+ {
+ timer.setSingleShot( true );
+ connect( &timer, SIGNAL( timeout()), SIGNAL( paintPending()));
+ added( w );
+ }
+
+QPixmap PaintRedirector::performPendingPaint()
+ {
+ //qDebug() << "### performing paint, pending:" << pending.boundingRect();
+ QPixmap pixmap( pending.boundingRect().size());
+ pixmap.fill( Qt::transparent );
+ recursionCheck = true;
+ // do not use DrawWindowBackground, it's ok to be transparent
+ widget->render( &pixmap, QPoint(), pending.boundingRect(), QWidget::DrawChildren );
+ recursionCheck = false;
+ pending = QRegion();
+ return pixmap;
+ }
+
+bool PaintRedirector::isToolTip( QWidget *object ) const
+ {
+ // ### We need a more reliable way of doing this
+ return object->metaObject()->className() == QString("QWidget") &&
+ object->objectName() != QString("decoration widget");
+ }
+
+bool PaintRedirector::eventFilter( QObject* o, QEvent* e )
+ {
+ switch( e->type())
+ {
+ case QEvent::ChildAdded:
+ {
+ QChildEvent* c = static_cast< QChildEvent* >( e );
+ if( c->child()->isWidgetType() && !isToolTip( static_cast< QWidget* >( c->child() ) ) )
+ added( static_cast< QWidget* >( c->child()));
+ break;
+ }
+ case QEvent::ChildRemoved:
+ {
+ QChildEvent* c = static_cast< QChildEvent* >( e );
+ if( c->child()->isWidgetType())
+ removed( static_cast< QWidget* >( c->child()));
+ break;
+ }
+ case QEvent::Paint:
+ {
+ if( !recursionCheck )
+ {
+ QPaintEvent* pe = static_cast< QPaintEvent* >( e );
+ QWidget* w = static_cast< QWidget* >( o );
+ pending |= pe->region().translated( w->mapTo( widget, QPoint( 0, 0 )));
+ timer.start( 0 );
+ return true; // filter out
+ }
+ }
+ default:
+ break;
+ }
+ return false;
+ }
+
+QRegion PaintRedirector::pendingRegion() const
+ {
+ return pending;
+ }
+
+void PaintRedirector::added( QWidget* w )
+ {
+ w->installEventFilter( this );
+ foreach( QObject* o, w->children())
+ {
+ if( o->isWidgetType() && !isToolTip( static_cast< QWidget* >( o ) ) )
+ added( static_cast< QWidget* >( o ));
+ }
+ }
+
+void PaintRedirector::removed( QWidget* w )
+ {
+ foreach( QObject* o, w->children())
+ {
+ if( o->isWidgetType())
+ removed( static_cast< QWidget* >( o ));
+ }
+ w->installEventFilter( this );
+ }
+
+} // namespace
+
+//#include "paintredirector.moc"
diff -Nur compiz-0.8.2/kde/window-decorator-kde4/paintredirector.h compiz-0.8.2-kde43/kde/window-decorator-kde4/paintredirector.h
--- compiz-0.8.2/kde/window-decorator-kde4/paintredirector.h 1970-01-01 01:00:00.000000000 +0100
+++ compiz-0.8.2-kde43/kde/window-decorator-kde4/paintredirector.h 2010-02-13 14:42:38.000000000 +0100
@@ -0,0 +1,60 @@
+/*****************************************************************
+This file is part of the KDE project.
+
+Copyright (C) 2009 Lubos Lunak <l.lunak@kde.org>
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the "Software"),
+to deal in the Software without restriction, including without limitation
+the rights to use, copy, modify, merge, publish, distribute, sublicense,
+and/or sell copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+DEALINGS IN THE SOFTWARE.
+******************************************************************/
+
+#ifndef PAINTREDIRECTOR_H
+#define PAINTREDIRECTOR_H
+
+#include <qregion.h>
+#include <qtimer.h>
+#include <qwidget.h>
+
+namespace KWin
+{
+
+// This class redirects all painting of a given widget (including its children)
+// into a paint device (QPixmap).
+class PaintRedirector
+ : public QObject
+ {
+ Q_OBJECT
+ public:
+ PaintRedirector( QWidget* widget );
+ QPixmap performPendingPaint();
+ virtual bool eventFilter( QObject* o, QEvent* e );
+ QRegion pendingRegion() const;
+ signals:
+ void paintPending();
+ private:
+ void added( QWidget* widget );
+ void removed( QWidget* widget );
+ bool isToolTip( QWidget* widget ) const;
+ QWidget* widget;
+ QRegion pending;
+ bool recursionCheck;
+ QTimer timer;
+ };
+
+} // namespace
+
+#endif
diff -Nur compiz-0.8.2/kde/window-decorator-kde4/window.cpp compiz-0.8.2-kde43/kde/window-decorator-kde4/window.cpp
--- compiz-0.8.2/kde/window-decorator-kde4/window.cpp 2009-02-15 10:10:23.000000000 +0100
+++ compiz-0.8.2-kde43/kde/window-decorator-kde4/window.cpp 2010-02-13 17:56:17.000000000 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright © 2008 Dennis Kasprzyk <onestone@opencompositing.org>
+ * Copyright © 2009 Dennis Kasprzyk <onestone@compiz-fusion.org>
* Copyright © 2006 Novell, Inc.
* Copyright © 2006 Volker Krause <vkrause@kde.org>
*
@@ -26,6 +26,9 @@
#include "options.h"
#include "utils.h"
+#include <unistd.h>
+#include <stdio.h>
+
#include <X11/Xlib.h>
#include <X11/extensions/shape.h>
#include <X11/extensions/Xcomposite.h>
@@ -55,6 +58,9 @@
#include <QVector>
#include <QProcess>
#include <QStyle>
+#include <QPainter>
+
+#include "paintredirector.h"
KWD::Window::Window (WId parentId,
WId clientId,
@@ -63,7 +69,7 @@
int x,
int y,
int w,
- int h): QWidget (0, 0),
+ int h):
mType (type),
mParentId (parentId),
mFrame (0),
@@ -71,22 +77,12 @@
mSelectedId (0),
mDecor (0),
mPixmap (0),
- mDamageId (0),
- mShadow (0),
- mPicture (0),
- mTexturePicture (0),
- mDecorationPicture (0),
mUpdateProperty (false),
mShapeSet (false),
- mUniqueHorzShape (false),
- mUniqueVertShape (false),
mPopup (0),
mAdvancedMenu (0),
mOpacityMenu (0),
mDesktopMenu (0),
- mMapped (false),
- mPendingMap (0),
- mPendingConfigure (0),
mProcessKiller (this),
mKeys (this),
mResizeOpAction (0),
@@ -98,7 +94,8 @@
mFullScreenOpAction (0),
mMinimizeOpAction (0),
mCloseOpAction (0),
- mDesktopOpAction (0)
+ mDesktopOpAction (0),
+ mPaintRedirector (0)
{
memset (&mBorder, 0, sizeof (mBorder));
@@ -162,27 +159,18 @@
KWD::Window::~Window (void)
{
- if (mShadow)
- decor_shadow_destroy (QX11Info::display(), mShadow);
-
- if (mPicture)
- XRenderFreePicture (QX11Info::display(), mPicture);
-
if (mPixmap)
XFreePixmap (QX11Info::display(), mPixmap);
- if (mTexturePicture)
- XRenderFreePicture (QX11Info::display(), mTexturePicture);
-
- if (mDecorationPicture)
- XRenderFreePicture (QX11Info::display(), mDecorationPicture);
-
if (mDecor)
delete mDecor;
if (mPopup)
delete mPopup;
+ if (mPaintRedirector)
+ delete mPaintRedirector;
+
if (mProcessKiller.state () == QProcess::Running)
{
mProcessKiller.terminate ();
@@ -372,8 +360,6 @@
void
KWD::Window::showWindowMenu (const QPoint &pos)
{
- QPoint pnt;
-
if (!mPopup)
{
QAction *action;
@@ -489,10 +475,10 @@
mCloseOpAction->setData (KDecorationDefines::CloseOp);
}
- pnt = mapFromGlobal (pos);
+ QPoint pnt = mDecor->widget ()->mapFromGlobal (pos);
- pnt += QPoint (mGeometry.x () - mBorder.left,
- mGeometry.y () - mBorder.top);
+ pnt += QPoint (mGeometry.x () - mBorder.left - mPadding.left,
+ mGeometry.y () - mBorder.top - mPadding.top);
mPopup->exec (pnt);
}
@@ -606,7 +592,7 @@
QRect
KWD::Window::geometry (void) const
{
- QRect rect = QWidget::geometry ();
+ QRect rect = mGeometry;
return QRect (rect.x () - ROOT_OFF_X,
rect.y () - ROOT_OFF_Y,
@@ -749,7 +735,7 @@
QWidget *
KWD::Window::initialParentWidget (void) const
{
- return const_cast <Window *> (this);
+ return 0;
}
Qt::WFlags
@@ -763,31 +749,12 @@
{
}
-void
-KWD::Window::repaintShadow (void)
-{
-}
-
bool
KWD::Window::compositingActive (void) const
{
return true;
}
-bool
-KWD::Window::shadowsActive (void) const
-{
- /* we are drawing the shadows ourselves, no need for the
- decoration engine to do so */
- return false;
-}
-
-double
-KWD::Window::opacity (void) const
-{
- return 1.0;
-}
-
void
KWD::Window::createDecoration (void)
{
@@ -801,6 +768,17 @@
mDecor = decor;
+ mPaintRedirector = new KWin::PaintRedirector (mDecor->widget ());
+ connect (mPaintRedirector, SIGNAL (paintPending()),
+ this, SLOT (decorRepaintPending ()));
+
+ mPadding.top = mPadding.bottom = mPadding.left = mPadding.right = 0;
+
+ if (KDecorationUnstable *deco2 = dynamic_cast<KDecorationUnstable*>(decor))
+ deco2->padding (mPadding.left, mPadding.right, mPadding.top, mPadding.bottom);
+
+ XReparentWindow (QX11Info::display(), mDecor->widget ()->winId (), mParentId, 0, 0);
+
if (mType == Normal && mFrame)
{
KWD::trapXError ();
@@ -812,455 +790,81 @@
return;
}
- KWD::trapXError ();
- XSelectInput (QX11Info::display(), this->winId(),
- StructureNotifyMask | PropertyChangeMask);
- KWD::popXError ();
-
resizeDecoration (true);
}
-static void
-fillQRegion (Display *xdisplay,
- Picture picture,
- int clipX1,
- int clipY1,
- int clipX2,
- int clipY2,
- int xOff,
- int yOff,
- QRegion *region)
-{
- static XRenderColor white = { 0xffff, 0xffff, 0xffff, 0xffff };
- QVector <QRect> rects = region->rects ();
- int x1, y1, x2, y2;
-
- foreach (QRect rect, rects)
- {
- x1 = rect.x ();
- y1 = rect.y ();
- x2 = x1 + rect.width ();
- y2 = y1 + rect.height ();
-
- if (x1 < clipX1)
- x1 = clipX1;
- if (y1 < clipY1)
- y1 = clipY1;
- if (x2 > clipX2)
- x2 = clipX2;
- if (y2 > clipY2)
- y2 = clipY2;
-
- if (x1 < x2 && y1 < y2)
- XRenderFillRectangle (xdisplay, PictOpSrc, picture, &white,
- xOff + x1,
- yOff + y1,
- x2 - x1,
- y2 - y1);
- }
-}
-
-static void
-drawBorderShape (Display *xdisplay,
- Pixmap pixmap,
- Picture picture,
- int width,
- int height,
- decor_context_t *c,
- void *closure)
-{
- static XRenderColor clear = { 0x0000, 0x0000, 0x0000, 0x0000 };
- static XRenderColor white = { 0xffff, 0xffff, 0xffff, 0xffff };
- KWD::Window *w = (KWD::Window *) closure;
- QRegion *shape;
- bool uniqueHorzShade;
- bool uniqueVertShade;
- int xOffLeft, yOffTop, xOffRight, yOffBottom;
- QRect rect = w->geometry ();
- int x1, y1, x2, y2;
-
- (void) pixmap;
-
- XRenderFillRectangle (xdisplay, PictOpSrc, picture, &clear,
- 0, 0, width, height);
-
- shape = w->getShape ();
- w->getShapeInfo (&uniqueHorzShade, &uniqueVertShade);
-
- xOffLeft = c->left_space - c->extents.left;
- yOffTop = c->top_space - c->extents.top;
-
- xOffRight = c->left_space - c->extents.left;
- yOffBottom = c->top_space - c->extents.top;
-
- x1 = c->left_space;
- y1 = c->top_space;
- x2 = width - c->right_space;
- y2 = height - c->bottom_space;
-
- if (shape)
- {
- if (uniqueHorzShade && uniqueVertShade)
- {
- fillQRegion (xdisplay, picture,
- 0, 0,
- rect.width (), rect.height (),
- xOffLeft, yOffTop, shape);
- }
- else
- {
- if (!uniqueHorzShade)
- xOffRight = x2 - (rect.width () - c->extents.right);
-
- if (!uniqueVertShade)
- yOffBottom = y2 - (rect.height () - c->extents.bottom);
-
- if (uniqueHorzShade)
- {
- fillQRegion (xdisplay, picture,
- 0, 0,
- rect.width (), c->extents.top,
- xOffLeft, yOffTop, shape);
- fillQRegion (xdisplay, picture,
- 0, rect.height () - c->extents.bottom,
- rect.width (), rect.height (),
- xOffLeft, yOffBottom, shape);
- }
- else
- {
- fillQRegion (xdisplay, picture,
- 0, 0,
- c->extents.left, c->extents.top,
- xOffLeft, yOffTop, shape);
- fillQRegion (xdisplay, picture,
- rect.width () - c->extents.right, 0,
- rect.width (), c->extents.top,
- xOffRight, yOffTop, shape);
- fillQRegion (xdisplay, picture,
- 0, rect.height () - c->extents.bottom,
- c->extents.left, rect.height (),
- xOffLeft, yOffBottom, shape);
- fillQRegion (xdisplay, picture,
- rect.width () - c->extents.right,
- rect.height () - c->extents.bottom,
- rect.width (), rect.height (),
- xOffRight, yOffBottom, shape);
-
- y1 -= c->extents.top;
- y2 += c->extents.bottom;
- }
-
- if (uniqueVertShade)
- {
- fillQRegion (xdisplay, picture,
- 0, c->extents.top,
- c->extents.left,
- rect.height () - c->extents.bottom,
- xOffLeft, yOffTop, shape);
- fillQRegion (xdisplay, picture,
- rect.width () - c->extents.right, c->extents.top,
- rect.width (),
- rect.height () - c->extents.bottom,
- xOffRight, yOffTop, shape);
- }
- else
- {
- x1 -= c->extents.left;
- x2 += c->extents.right;
- }
- }
- }
- else
- {
- x1 -= c->extents.left;
- x2 += c->extents.right;
- y1 -= c->extents.top;
- y2 += c->extents.bottom;
- }
-
- XRenderFillRectangle (xdisplay, PictOpSrc, picture, &white,
- x1,
- y1,
- x2 - x1,
- y2 - y1);
-}
-
-static void
-cornersFromQRegion (QRegion *region,
- int width,
- int height,
- int left,
- int right,
- int top,
- int bottom,
- int *leftCorner,
- int *rightCorner,
- int *topCorner,
- int *bottomCorner)
-{
- QRegion l, r, t, b;
-
- l = QRegion (0, top, left, height - top - bottom) - *region;
- r = QRegion (width - right, top, right, height - top - bottom) - *region;
- t = QRegion (0, 0, width, top) - *region;
- b = QRegion (0, height - bottom, width, bottom) - *region;
-
- if (l.isEmpty ())
- *leftCorner = left;
- else
- *leftCorner = left -
- (l.boundingRect ().x () + l.boundingRect ().width ());
-
- if (r.isEmpty ())
- *rightCorner = right;
- else
- *rightCorner = r.boundingRect ().x () - width + right;
-
- if (t.isEmpty ())
- *topCorner = top;
- else
- *topCorner = top -
- (t.boundingRect ().y () + t.boundingRect ().height ());
-
- if (b.isEmpty ())
- *bottomCorner = bottom;
- else
- *bottomCorner = b.boundingRect ().y () - height + bottom;
-}
-
void
-KWD::Window::updateShadow (void)
+KWD::Window::setMask (const QRegion ®ion, int)
{
- Display *xdisplay = QX11Info::display();
- Screen *xscreen;
- XRenderPictFormat *xformat;
- int leftCorner, rightCorner, topCorner, bottomCorner;
-
- xscreen = ScreenOfDisplay (xdisplay, QX11Info::appScreen ());
-
- if (mShadow)
- {
- decor_shadow_destroy (QX11Info::display(), mShadow);
- mShadow = NULL;
- }
-
- if (mShapeSet)
+ if (region.isEmpty ())
{
- cornersFromQRegion (&mShape,
- mGeometry.width () + mBorder.left + mBorder.right,
- mGeometry.height () + mBorder.top + mBorder.bottom,
- mBorder.left,
- mBorder.right,
- mBorder.top,
- mBorder.bottom,
- &leftCorner,
- &rightCorner,
- &topCorner,
- &bottomCorner);
- }
- else
- {
- leftCorner = mBorder.left;
- rightCorner = mBorder.right;
- topCorner = mBorder.top;
- bottomCorner = mBorder.bottom;
- }
-
- /* use default shadow if such exist */
- if (!mUniqueHorzShape && !mUniqueVertShape)
- {
- mShadow = Decorator::defaultWindowShadow (&mContext, &mBorder);
- if (mShadow)
- decor_shadow_reference (mShadow);
- }
-
- if (!mShadow)
- {
- mShadow = decor_shadow_create (xdisplay,
- xscreen,
- mUniqueHorzShape ?
- mGeometry.width () : 1,
- mUniqueVertShape ?
- mGeometry.height () : 1,
- mBorder.left,
- mBorder.right,
- mBorder.top,
- mBorder.bottom,
- leftCorner,
- rightCorner,
- topCorner,
- bottomCorner,
- KWD::Decorator::shadowOptions (),
- &mContext,
- drawBorderShape,
- (void *) this);
-
- if (mType == Default)
- KWD::Decorator::updateDefaultShadow (this);
+ if (mFrame && mShapeSet)
+ {
+ QRegion r (0, 0, mGeometry.width () + mBorder.left + mBorder.right,
+ mGeometry.height () + mBorder.top + mBorder.bottom);
+
+ r -= QRegion (mBorder.left, mBorder.top,
+ mGeometry.width (), mGeometry.height ());
+ r = QRegion ();
+ KWD::trapXError ();
+ XShapeCombineRegion (QX11Info::display(), mFrame, ShapeInput,
+ 0, 0, r.handle (), ShapeSet);
+ KWD::popXError ();
+ }
+
+ mShapeSet = false;
+ return;
}
- /* create new layout */
- if (mType == Normal)
- decor_get_best_layout (&mContext,
- mGeometry.width (),
- mGeometry.height (),
- &mLayout);
- else
- decor_get_default_layout (&mContext,
- mGeometry.width (),
- mGeometry.height (),
- &mLayout);
-
- if (mDecorationPicture)
- XRenderFreePicture (QX11Info::display(), mDecorationPicture);
-
- if (mTexturePicture)
- XRenderFreePicture (QX11Info::display(), mTexturePicture);
-
- mTexturePixmap = QPixmap (mLayout.width, mLayout.height);
- mTexturePixmapBuffer = QPixmap (mLayout.width, mLayout.height);
-
- xformat = XRenderFindStandardFormat (QX11Info::display(),
- PictStandardARGB32);
-
- mDecorationPicture =
- XRenderCreatePicture (QX11Info::display(),
- mTexturePixmap.handle (),
- xformat, 0, NULL);
- mTexturePicture =
- XRenderCreatePicture (QX11Info::display(),
- mTexturePixmapBuffer.handle (),
- xformat, 0, NULL);
-
- decor_fill_picture_extents_with_shadow (QX11Info::display(),
- mShadow,
- &mContext,
- mTexturePicture,
- &mLayout);
-
- if (mPixmap)
- mDecor->widget ()->repaint ();
-
- mUpdateProperty = true;
-}
-
-void
-KWD::Window::setMask (const QRegion ®, int)
-{
- QRegion top, bottom, left, right;
- bool uniqueHorzShape, uniqueVertShape;
-
- if (mShapeSet && reg == mShape)
+ if (mShapeSet && region == mShape)
return;
- mShape = reg;
+ mShape = region;
mShapeSet = true;
if (mFrame)
{
- QRegion r;
+ QRegion r = region.translated (-mPadding.left, -mPadding.top);
- r = reg - QRegion (mBorder.left, mBorder.top,
- mGeometry.width (), mGeometry.height ());
+ r -= QRegion (mBorder.left, mBorder.top,
+ mGeometry.width (), mGeometry.height ());
KWD::trapXError ();
- XShapeCombineRegion (QX11Info::display(),
- mFrame,
- ShapeInput,
- 0,
- 0,
- r.handle (),
- ShapeSet);
+ XShapeCombineRegion (QX11Info::display(), mFrame, ShapeInput,
+ 0, 0, r.handle (), ShapeSet);
KWD::popXError ();
}
-
- top = QRegion (mBorder.left, 0,
- mGeometry.width (), mBorder.top) - reg;
- bottom = QRegion (mBorder.left, mGeometry.height () + mBorder.top,
- mGeometry.width (), mBorder.bottom) - reg;
- left = QRegion (0, mBorder.top, mBorder.left,
- mGeometry.height ()) - reg;
- right = QRegion (mBorder.left + mGeometry.width (), mBorder.top,
- mBorder.right, mGeometry.height ()) - reg;
-
- uniqueHorzShape = !top.isEmpty () || !bottom.isEmpty ();
- uniqueVertShape = !left.isEmpty () || !right.isEmpty ();
-
- if (uniqueHorzShape || mUniqueHorzShape ||
- uniqueVertShape || mUniqueVertShape)
- {
- mUniqueHorzShape = uniqueHorzShape;
- mUniqueVertShape = uniqueVertShape;
-
- if (mPixmap)
- QTimer::singleShot (0, this, SLOT (updateShadow ()));
- }
}
-bool
+void
KWD::Window::resizeDecoration (bool force)
{
int w, h;
mDecor->borders (mBorder.left, mBorder.right, mBorder.top, mBorder.bottom);
+
+ mExtents.left = mBorder.left + mPadding.left;
+ mExtents.right = mBorder.right + mPadding.right;
+ mExtents.top = mBorder.top + mPadding.top;
+ mExtents.bottom = mBorder.bottom + mPadding.bottom;
- w = mGeometry.width () + mBorder.left + mBorder.right;
- h = mGeometry.height () + mBorder.top + mBorder.bottom;
-
- if (!force)
+ if (mType != Normal)
{
- if (w == width () && h == height ())
- return FALSE;
+ mGeometry = QRect (50, 50, 100, 100);
}
- /* reset shape */
- mShapeSet = false;
- mUniqueHorzShape = false;
- mUniqueVertShape = false;
-
- if (mType != Normal)
+ w = mGeometry.width () + mExtents.left + mExtents.right;
+ h = mGeometry.height () + mExtents.top + mExtents.bottom;
+
+ if (!force)
{
- Display *xdisplay = QX11Info::display();
- Screen *xscreen;
- decor_shadow_t *tmpShadow;
- decor_context_t c;
-
- xscreen = ScreenOfDisplay (xdisplay, QX11Info::appScreen ());
-
- /* XXX: we have to create a temporary shadow to get the client
- geometry. libdecoration should be fixed so it's able to just
- fill out a context struct and not necessarily generate a
- shadow for this purpose. */
- tmpShadow = decor_shadow_create (xdisplay,
- xscreen,
- 1, 1,
- mBorder.left,
- mBorder.right,
- mBorder.top,
- mBorder.bottom,
- mBorder.left,
- mBorder.right,
- mBorder.top,
- mBorder.bottom,
- KWD::Decorator::shadowOptions (),
- &c,
- decor_draw_simple,
- (void *) 0);
-
- decor_shadow_destroy (xdisplay, tmpShadow);
-
- w = c.left_corner_space + 1 + c.right_corner_space;
-
- /* most styles render something useful at least 30 px width */
- if (w < 30)
- w = 30;
-
- mGeometry = QRect (50, 50, w,
- c.top_corner_space + 1 + c.bottom_corner_space);
+ if (w == decorWidget ()->width () && h == decorWidget ()->height ())
+ return;
}
-
- w = mGeometry.width () + mBorder.left + mBorder.right;
- h = mGeometry.height () + mBorder.top + mBorder.bottom;
+
+ /* reset shape */
+ setMask (QRegion (), 0);
+
if (mPixmap)
{
@@ -1268,106 +872,24 @@
mPixmap = None;
}
- if (mPicture)
- {
- XRenderFreePicture (QX11Info::display(), mPicture);
- mPicture = 0;
- }
-
- if (w != width() || h != height())
- {
- mPendingConfigure = 1;
- }
-
- setGeometry (QRect (mGeometry.x () + ROOT_OFF_X - mBorder.left,
- mGeometry.y () + ROOT_OFF_Y - mBorder.top,
- w, h));
- XMoveResizeWindow (QX11Info::display(), winId(),
- mGeometry.x () + ROOT_OFF_X - mBorder.left,
- mGeometry.y () + ROOT_OFF_Y - mBorder.top,
- w, h);
-
- mSize = QSize (w, h);
-
- if (!mMapped)
- {
- mPendingMap = 1;
-
- XReparentWindow (QX11Info::display(), winId (), mParentId, 0, 0);
-
- show ();
-
- mMapped = true;
-
- if (mDamageId != winId ())
- {
- mDamageId = winId ();
- XDamageCreate (QX11Info::display(), mDamageId,
- XDamageReportRawRectangles);
- }
- }
-
mDecor->resize (QSize (w, h));
mDecor->widget ()->show ();
mDecor->widget ()->update ();
- return TRUE;
-}
-
-void
-KWD::Window::rebindPixmap (void)
-{
- XRenderPictFormat *xformat;
-
- if (mPicture)
- XRenderFreePicture (QX11Info::display(), mPicture);
-
- if (mPixmap)
- XFreePixmap (QX11Info::display(), mPixmap);
-
- mPixmap = XCompositeNameWindowPixmap (QX11Info::display(), winId ());
-
- xformat = XRenderFindVisualFormat (QX11Info::display(),
- (Visual *) QX11Info::appVisual ());
-
- mPicture = XRenderCreatePicture (QX11Info::display(), mPixmap,
- xformat, 0, NULL);
-
- updateShadow ();
-}
-
-bool
-KWD::Window::handleMap (void)
-{
- if (!mPendingMap)
- return FALSE;
+ mPixmap = XCreatePixmap (QX11Info::display(),
+ QX11Info::appRootWindow (),
+ qMax (w, mGeometry.height ()),
+ mExtents.top + mExtents.bottom +
+ mExtents.left + mExtents.right, 32);
- mPendingMap = 0;
+ mPixmapQt = QPixmap::fromX11Pixmap (mPixmap, QPixmap::ExplicitlyShared);
- if (mPendingConfigure)
- return FALSE;
+ mPixmapQt.fill (Qt::transparent);
- rebindPixmap ();
-
- return TRUE;
-}
-
-bool
-KWD::Window::handleConfigure (QSize size)
-{
- if (!mPendingConfigure)
- return FALSE;
-
- if (size != mSize)
- return FALSE;
-
- mPendingConfigure = 0;
- if (mPendingConfigure || mPendingMap)
- return FALSE;
-
- rebindPixmap ();
-
- return TRUE;
+ if (mPaintRedirector)
+ mUpdateProperty = true;
+ else
+ updateProperty ();
}
void
@@ -1385,54 +907,54 @@
int size = 0;
int w, h;
- w = mGeometry.width () + mContext.extents.left + mContext.extents.right;
- h = mGeometry.height () + mContext.extents.top + mContext.extents.bottom;
+ w = mGeometry.width () + mBorder.left + mBorder.right;
+ h = mGeometry.height () + mBorder.top + mBorder.bottom;
if (blurType != BLUR_TYPE_NONE)
{
QRegion r, shape = QRegion (0, 0, w, h);
if (mShapeSet)
- shape = mShape;
+ shape = mShape.translated (-mPadding.left, -mPadding.top);
- r = QRegion (0, 0, w, mContext.extents.top);
+ r = QRegion (0, 0, w, mBorder.top);
topQRegion = r.intersect (shape);
if (!topQRegion.isEmpty ())
{
- topQRegion.translate (-mContext.extents.left,
- -mContext.extents.top);
+ topQRegion.translate (-mBorder.left,
+ -mBorder.top);
topRegion = topQRegion.handle ();
}
if (blurType == BLUR_TYPE_ALL)
{
- r = QRegion (0, h - mContext.extents.bottom,
- w, mContext.extents.bottom);
+ r = QRegion (0, h - mBorder.bottom,
+ w, mBorder.bottom);
bottomQRegion = r.intersect (shape);
if (!bottomQRegion.isEmpty ())
{
- bottomQRegion.translate (-mContext.extents.left,
- -(h - mContext.extents.bottom));
+ bottomQRegion.translate (-mBorder.left,
+ -(h - mBorder.bottom));
bottomRegion = bottomQRegion.handle ();
}
- r = QRegion (0, mContext.extents.top,
- mContext.extents.left, mGeometry.height ());
+ r = QRegion (0, mBorder.top,
+ mBorder.left, mGeometry.height ());
leftQRegion = r.intersect (shape);
if (!leftQRegion.isEmpty ())
{
- leftQRegion.translate (-mContext.extents.left,
- -mContext.extents.top);
+ leftQRegion.translate (-mBorder.left,
+ -mBorder.top);
leftRegion = leftQRegion.handle ();
}
- r = QRegion (w - mContext.extents.right, mContext.extents.top,
- mContext.extents.right, mGeometry.height ());
+ r = QRegion (w - mBorder.right, mBorder.top,
+ mBorder.right, mGeometry.height ());
rightQRegion = r.intersect (shape);
if (!rightQRegion.isEmpty ())
{
- rightQRegion.translate (-(w - mContext.extents.right),
- -mContext.extents.top);
+ rightQRegion.translate (-(w - mBorder.right),
+ -mBorder.top);
rightRegion = rightQRegion.handle ();
}
}
@@ -1481,10 +1003,8 @@
decor_extents_t maxExtents;
long data[256];
decor_quad_t quads[N_QUADS_MAX];
- int nQuad;
- int lh, rh;
- int w;
- int minWidth;
+ int nQuad = 0;
+ int left, right, top, bottom, width, height;
unsigned int saveState;
if (mType == Default)
@@ -1499,29 +1019,22 @@
mState = saveState;
mDecor->borders (mBorder.left, mBorder.right, mBorder.top, mBorder.bottom);
- if (mLayout.rotation)
- lh = mLayout.left.x2 - mLayout.left.x1;
- else
- lh = mLayout.left.y2 - mLayout.left.y1;
-
- if (mLayout.rotation)
- rh = mLayout.right.x2 - mLayout.right.x1;
- else
- rh = mLayout.right.y2 - mLayout.right.y1;
-
- w = mLayout.top.x2 - mLayout.top.x1 - mContext.left_space -
- mContext.right_space;
+ left = mExtents.left;
+ right = mExtents.right;
+ top = mExtents.top;
+ bottom = mExtents.bottom;
+ width = mGeometry.width ();
+ height = mGeometry.height ();
if (mType == Normal)
{
- int topXOffset = w / 2;
+ decor_quad_t *q = quads;
+ int n = 0;
+
+ int topXOffset = width;
QWidget *widget = mDecor->widget ();
int x;
- x = w - mContext.left_space - mContext.left_corner_space;
- if (x > topXOffset)
- topXOffset = x;
-
if (widget)
{
const QList<QObject*> children = widget->children ();
@@ -1535,35 +1048,76 @@
child = static_cast <QWidget *> (obj);
- x = child->x () - mBorder.left - 2;
- if (x > w / 2 && x < topXOffset)
+ x = child->x () - mExtents.left - 2;
+ if (x > width / 2 && x < topXOffset)
topXOffset = x;
}
}
- nQuad = decor_set_lXrXtXbX_window_quads (quads,
- &mContext,
- &mLayout,
- lh / 2,
- rh / 2,
- topXOffset,
- w / 2);
+ // top quads
+ n = decor_set_horz_quad_line (q, left, topXOffset, right,
+ width - topXOffset - 1, -top, 0, GRAVITY_NORTH,
+ left + right + width, -(width - topXOffset - 1),
+ GRAVITY_EAST, 0, 0);
- updateBlurProperty (topXOffset, w / 2, lh / 2, rh / 2);
+ q += n; nQuad += n;
+
+ // bottom quads
+ n = decor_set_horz_quad_line (q, left, width / 2, right, (width / 2) - 1, 0,
+ bottom, GRAVITY_SOUTH, left + right + width,
+ -((width / 2) - 1), GRAVITY_EAST, 0, top);
- minWidth = mContext.left_corner_space + 1 + mContext.right_corner_space;
+ q += n; nQuad += n;
+
+ // left quads
+ n = decor_set_vert_quad_row (q, 0, height / 2, 0, (height / 2) - 1, -left, 0,
+ GRAVITY_WEST, height, -((height / 2) - 1),
+ GRAVITY_SOUTH, 0, top + bottom, 1);
+
+ q += n; nQuad += n;
+
+ // right quads
+ n = decor_set_vert_quad_row (q, 0, height / 2, 0, (height / 2) - 1, 0, right,
+ GRAVITY_EAST, height, -((height / 2) - 1),
+ GRAVITY_SOUTH, 0, top + bottom + left, 1);
+
+ q += n; nQuad += n;
+
+ updateBlurProperty (topXOffset, width / 2, height / 2, height / 2);
}
else
{
- nQuad = decor_set_lSrStSbS_window_quads (quads, &mContext, &mLayout);
+ decor_quad_t *q = quads;
+ int n = 0;
+
+ // top
+ n = decor_set_horz_quad_line (q, left, 0, right, 0, -top, 0,
+ GRAVITY_NORTH, left + right + width,
+ width / 2, 0, 0, 0);
- minWidth = 1;
- }
+ q += n; nQuad += n;
+
+ // bottom
+ n = decor_set_horz_quad_line (q, left, 0, right, 0, 0, bottom,
+ GRAVITY_SOUTH, left + right + width,
+ width / 2, 0, 0, top);
- decor_quads_to_property (data, mTexturePixmap.handle (),
- &mBorder, &maxExtents,
- minWidth, 0,
- quads, nQuad);
+ q += n; nQuad += n;
+
+ // left
+ n = decor_set_vert_quad_row (q, 0, 0, 0, 0, -left, 0, GRAVITY_WEST,
+ height, height / 2, 0, 0, top + bottom, 1);
+
+ q += n; nQuad += n;
+
+ // right
+ n = decor_set_vert_quad_row (q, 0, 0, 0, 0, 0, right, GRAVITY_EAST,
+ height, height / 2, 0, 0, top + bottom + left, 1);
+
+ q += n; nQuad += n;
+ }
+ decor_quads_to_property (data, mPixmap, &mBorder, &maxExtents,
+ 1, 0, quads, nQuad);
KWD::trapXError ();
XChangeProperty (QX11Info::display(), mClientId, atom,
@@ -1618,17 +1172,13 @@
{
mGeometry = geometry;
- if (resizeDecoration ())
- return;
+ resizeDecoration ();
}
else if (mGeometry.x () != geometry.x () ||
mGeometry.y () != geometry.y ())
{
mGeometry = geometry;
}
-
- move (mGeometry.x () + ROOT_OFF_X - mBorder.left,
- mGeometry.y () + ROOT_OFF_Y - mBorder.top);
}
void
@@ -1637,14 +1187,10 @@
delete mDecor;
mDecor = 0;
- mMapped = false;
- mShapeSet = false;
+ delete mPaintRedirector;
+ mPaintRedirector = 0;
- if (mShadow)
- {
- decor_shadow_destroy (QX11Info::display(), mShadow);
- mShadow = NULL;
- }
+ mShapeSet = false;
createDecoration ();
}
@@ -1652,7 +1198,7 @@
Cursor
KWD::Window::positionToCursor (QPoint pos)
{
- switch (mDecor->mousePosition (pos)) {
+ switch (mDecor->mousePosition (pos + QPoint (mPadding.left, mPadding.top))) {
case PositionCenter:
return cursors[1][1].cursor;
case PositionLeft:
@@ -1962,14 +1508,8 @@
setShade (false);
break;
case Options::MouseOperationsMenu:
- {
- QPoint mp (0, 0);
-
- if (qme)
- mp = mapToGlobal (qme->pos ());
-
- showWindowMenu (mp);
- } break;
+ showWindowMenu (mDecor->widget ()->mapToGlobal (qme->pos ()));
+ break;
case Options::MouseMaximize:
maximize (KDecoration::MaximizeFull);
break;
@@ -2042,145 +1582,6 @@
}
void
-KWD::Window::processDamage (void)
-{
- QRegion r1, r2;
- int xOff, yOff, w;
- double alpha;
- int shade_alpha;
-
- if (isActive ())
- {
- alpha = activeDecorationOpacity;
- shade_alpha = activeDecorationOpacityShade;
- }
- else
- {
- alpha = decorationOpacity;
- shade_alpha = decorationOpacityShade;
- }
-
- if (!mPixmap)
- return;
-
- if (mDamage.isEmpty ())
- return;
-
- if (mShapeSet)
- mDamage = mShape.intersect (mDamage);
-
- w = mGeometry.width () + mContext.extents.left + mContext.extents.right;
-
- xOff = 0;
- yOff = 0;
-
- r1 = QRegion (xOff, yOff, w, mContext.extents.top);
- r2 = r1.intersect (mDamage);
-
- if (!r2.isEmpty ())
- {
- r2.translate (-xOff, -yOff);
-
- decor_blend_border_picture (QX11Info::display(),
- &mContext,
- mPicture,
- xOff, xOff,
- mTexturePicture,
- &mLayout,
- BORDER_TOP,
- r2.handle (),
- (unsigned short) (alpha * 0xffff),
- shade_alpha,
- TRUE);
- }
-
- xOff = 0;
- yOff = mContext.extents.top + mGeometry.height ();
-
- r1 = QRegion (xOff, yOff, w, mContext.extents.bottom);
- r2 = r1.intersect (mDamage);
-
- if (!r2.isEmpty ())
- {
- r2.translate (-xOff, -yOff);
-
- decor_blend_border_picture (QX11Info::display(),
- &mContext,
- mPicture,
- xOff, yOff,
- mTexturePicture,
- &mLayout,
- BORDER_BOTTOM,
- r2.handle (),
- (unsigned short) (alpha * 0xffff),
- shade_alpha,
- TRUE);
- }
-
- xOff = 0;
- yOff = mContext.extents.top;
-
- r1 = QRegion (xOff, yOff, mContext.extents.left, mGeometry.height ());
- r2 = r1.intersect (mDamage);
-
- if (!r2.isEmpty ())
- {
- r2.translate (-xOff, -yOff);
-
- decor_blend_border_picture (QX11Info::display(),
- &mContext,
- mPicture,
- xOff, yOff,
- mTexturePicture,
- &mLayout,
- BORDER_LEFT,
- r2.handle (),
- (unsigned short) (alpha * 0xffff),
- shade_alpha,
- TRUE);
- }
-
- xOff = mContext.extents.left + mGeometry.width ();
- yOff = mContext.extents.top;
-
- r1 = QRegion (xOff, yOff, mContext.extents.right, mGeometry.height ());
- r2 = r1.intersect (mDamage);
-
- if (!r2.isEmpty ())
- {
- r2.translate (-xOff, -yOff);
-
- decor_blend_border_picture (QX11Info::display(),
- &mContext,
- mPicture,
- xOff, yOff,
- mTexturePicture,
- &mLayout,
- BORDER_RIGHT,
- r2.handle (),
- (unsigned short) (alpha * 0xffff),
- shade_alpha,
- TRUE);
- }
-
- mDamage = QRegion ();
-
- XRenderComposite (QX11Info::display(),
- PictOpSrc,
- mTexturePicture,
- None,
- mDecorationPicture,
- 0, 0,
- 0, 0,
- 0, 0,
- mTexturePixmap.width (),
- mTexturePixmap.height ());
-
- if (mUpdateProperty)
- updateProperty ();
-}
-
-void
KWD::Window::showKillProcessDialog (Time timestamp)
{
KWindowInfo kWinInfo =
@@ -2223,3 +1624,128 @@
mProcessKiller.terminate ();
}
}
+
+void
+KWD::Window::decorRepaintPending ()
+{
+ if (!mPaintRedirector || !mPixmap)
+ return;
+
+ QRegion reg = mPaintRedirector->pendingRegion();
+ if (reg.isEmpty())
+ return;
+
+ QRect bBox = reg.boundingRect();
+
+ if (mShapeSet)
+ reg &= mShape;
+
+ int l = mExtents.left;
+ int r = mExtents.right;
+ int t = mExtents.top;
+ int b = mExtents.bottom;
+ int w = mGeometry.width ();
+ int h = mGeometry.height ();
+
+ QRect top = QRect (0, 0, w + l + r, t);
+ QRect bottom = QRect (0, t + h, w + l + r, b);
+ QRect left = QRect (0, t, l, h);
+ QRect right = QRect (l + w, t, r, h);
+
+ QRegion rtop = reg & top;
+ QRegion rbottom = reg & bottom;
+ QRegion rleft = reg & left;
+ QRegion rright = reg & right;
+
+ QPixmap p = mPaintRedirector->performPendingPaint();
+
+ QPainter pt (&mPixmapQt);
+ pt.setCompositionMode( QPainter::CompositionMode_Source );
+ pt.setClipRegion( reg );
+
+ QRect bb, pb;
+
+ // Top
+ if (!rtop.isEmpty ())
+ {
+ bb = rtop.boundingRect();
+ pb = bb;
+ pb.moveTo (bb.topLeft () - bBox.topLeft ());
+ pt.resetTransform ();
+ pt.setClipRegion( reg );
+ pt.drawPixmap( bb.topLeft(), p, pb );
+ }
+
+ // Bottom
+ if (!rbottom.isEmpty ())
+ {
+ bb = rbottom.boundingRect();
+ pb = bb;
+ pb.moveTo (bb.topLeft () - bBox.topLeft ());
+ pt.resetTransform ();
+ pt.translate(0, -h);
+ pt.setClipRegion( reg );
+ pt.drawPixmap( bb.topLeft(), p, pb );
+ }
+
+ // Left
+ if (!rleft.isEmpty ())
+ {
+ bb = rleft.boundingRect();
+ pb = bb;
+ pb.moveTo (bb.topLeft () - bBox.topLeft ());
+ pt.resetTransform ();
+ pt.translate(0, t + b);
+ pt.rotate (90);
+ pt.scale (1.0, -1.0);
+ pt.translate(0, -t);
+ pt.setClipRegion( reg );
+ pt.drawPixmap( bb.topLeft(), p, pb );
+ }
+
+ // Right
+ if (!rright.isEmpty ())
+ {
+ bb = rright.boundingRect();
+ pb = bb;
+ pb.moveTo (bb.topLeft () - bBox.topLeft ());
+ pt.resetTransform ();
+ pt.translate(0, t + b + l);
+ pt.rotate (90);
+ pt.scale (1.0, -1.0);
+ pt.translate(- (l + w), -t);
+ pt.setClipRegion( reg );
+ pt.drawPixmap( bb.topLeft(), p, pb );
+ }
+
+ if (mUpdateProperty)
+ updateProperty ();
+}
+
+QWidget *
+KWD::Window::decorWidget (void) const
+{
+ if (!mDecor)
+ return 0;
+ return mDecor->widget ();
+}
+
+QWidget *
+KWD::Window::childAt (int x, int y) const
+{
+ if (!mDecor)
+ return 0;
+
+ QWidget *child = mDecor->widget ()->childAt (x + mPadding.left, y + mPadding.top);
+ return (child)? child : decorWidget ();
+}
+
+QPoint
+KWD::Window::mapToChildAt (QPoint p) const
+{
+ if (!mDecor)
+ return p;
+ if (childAt (p.x (), p.y ()) == decorWidget ())
+ return p + QPoint (mPadding.left, mPadding.right);
+ return childAt (p.x (), p.y ())->mapFrom (decorWidget (), p + QPoint (mPadding.left, mPadding.right));
+}
diff -Nur compiz-0.8.2/kde/window-decorator-kde4/window.h compiz-0.8.2-kde43/kde/window-decorator-kde4/window.h
--- compiz-0.8.2/kde/window-decorator-kde4/window.h 2009-02-15 10:10:23.000000000 +0100
+++ compiz-0.8.2-kde43/kde/window-decorator-kde4/window.h 2010-02-13 17:36:27.000000000 +0100
@@ -43,9 +43,14 @@
class KActionCollection;
class QMenu;
+namespace KWin
+{
+ class PaintRedirector;
+}
+
namespace KWD
{
-class Window:public QWidget, public KDecorationBridgeUnstable {
+class Window: public QObject, public KDecorationBridgeUnstable {
Q_OBJECT public:
enum Type
@@ -105,44 +110,38 @@
virtual void grabXServer (bool grab);
/* unstable API */
- virtual void repaintShadow ();
virtual bool compositingActive () const;
- virtual bool shadowsActive () const;
- virtual double opacity () const;
void handleActiveChange (void);
void updateFrame (WId frame);
void updateWindowGeometry (void);
void updateCursor (QPoint pos);
void updateSelected (WId selected);
+
WId frameId (void) const
{
return mFrame;
}
+
KDecoration *decoration (void) const
{
return mDecor;
}
+
+ QWidget *decorWidget (void) const;
+ QWidget *childAt (int x, int y) const;
+ QPoint mapToChildAt (QPoint p) const;
+
QWidget *activeChild (void) const
{
return mActiveChild;
}
+
void setActiveChild (QWidget * child)
{
mActiveChild = child;
}
- QRegion *getShape (void)
- {
- if (mShapeSet)
- return &mShape;
-
- return NULL;
- }
- void getShapeInfo (bool *horz, bool *vert)
- {
- *horz = mUniqueHorzShape;
- *vert = mUniqueVertShape;
- }
+
void moveWindow (QMouseEvent *qme);
void reloadDecoration (void);
void updateState (void);
@@ -157,21 +156,7 @@
{
return mPixmap;
}
- void addDamageRect (int x, int y, int w, int h)
- {
- mDamage += QRegion (x, y, w, h);
- }
- bool handleMap (void);
- bool handleConfigure (QSize size);
- void processDamage (void);
- decor_context_t *context (void)
- {
- return &mContext;
- }
- decor_shadow_t *shadow (void)
- {
- return mShadow;
- }
+
decor_extents_t *border (void)
{
return &mBorder;
@@ -194,7 +179,7 @@
private:
void createDecoration (void);
- bool resizeDecoration (bool force = false);
+ void resizeDecoration (bool force = false);
void updateBlurProperty (int topOffset,
int bottomOffset,
int leftOffset,
@@ -205,16 +190,16 @@
QMouseEvent *qme);
NET::Direction positionToDirection (int pos);
Cursor positionToCursor (QPoint pos);
- void rebindPixmap (void);
private slots:
- void updateShadow (void);
void handlePopupActivated (QAction *action);
void handleOpacityPopupActivated (QAction *action);
void handleDesktopPopupActivated (QAction *action);
void handlePopupAboutToShow (void);
+ void decorRepaintPending ();
+
private:
Type mType;
WId mParentId;
@@ -226,23 +211,14 @@
QPixmap mIcon;
QPixmap mMiniIcon;
decor_extents_t mBorder;
+ decor_extents_t mPadding;
+ decor_extents_t mExtents;
unsigned short mOpacity;
KDecoration *mDecor;
- QPixmap mTexturePixmap;
- QPixmap mTexturePixmapBuffer;
Pixmap mPixmap;
- QRegion mDamage;
- WId mDamageId;
- decor_layout_t mLayout;
- decor_context_t mContext;
- decor_shadow_t *mShadow;
- Picture mPicture;
- Picture mTexturePicture;
- Picture mDecorationPicture;
+ QPixmap mPixmapQt;
bool mUpdateProperty;
bool mShapeSet;
- bool mUniqueHorzShape;
- bool mUniqueVertShape;
QRegion mShape;
QWidget *mActiveChild;
bool mSupportTakeFocus;
@@ -252,10 +228,7 @@
QMenu *mOpacityMenu;
QMenu *mDesktopMenu;
unsigned long mState;
- bool mMapped;
- int mPendingMap;
- int mPendingConfigure;
- QSize mSize;
+
QProcess mProcessKiller;
KActionCollection mKeys;
bool mFakeRelease;
@@ -271,6 +244,8 @@
QAction *mMinimizeOpAction;
QAction *mCloseOpAction;
QAction *mDesktopOpAction;
+
+ KWin::PaintRedirector *mPaintRedirector;
};
}