summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSam Spilsbury <smspillaz@XPS-FEDORA.(none)>2009-08-08 13:35:13 +0800
committerSam Spilsbury <smspillaz@XPS-FEDORA.(none)>2009-08-08 13:35:13 +0800
commit2a7d93099344aeaa1a0eab75e6c4759371bd9120 (patch)
tree1df6593e41b4868bb84bd27ef4d1815cbe33eb9c
parent223b935a3c791db70406b0f488cd5b5a3e4603f3 (diff)
parent6f4df47b184980ffcdf2e59933ce2302c0cef6c2 (diff)
downloadunity-window-decorator-2a7d93099344aeaa1a0eab75e6c4759371bd9120.tar.gz
unity-window-decorator-2a7d93099344aeaa1a0eab75e6c4759371bd9120.tar.bz2
Merge branch 'master' of git+ssh://git.compiz.org/git/compiz/core
-rw-r--r--cmake/CompizCommon.cmake20
-rw-r--r--include/compiz.h7
-rw-r--r--kde/window-decorator-kde4/CMakeLists.txt3
-rw-r--r--kde/window-decorator-kde4/decorator.cpp164
-rw-r--r--kde/window-decorator-kde4/decorator.h29
-rw-r--r--kde/window-decorator-kde4/main.cpp87
-rw-r--r--kde/window-decorator-kde4/paintredirector.cpp125
-rw-r--r--kde/window-decorator-kde4/paintredirector.h60
-rw-r--r--kde/window-decorator-kde4/window.cpp1393
-rw-r--r--kde/window-decorator-kde4/window.h112
-rw-r--r--plugins/compiztoolbox/include/compiztoolbox/compiztoolbox.h19
-rw-r--r--plugins/compiztoolbox/src/compiztoolbox.cpp71
-rw-r--r--plugins/screenshot/CMakeLists.txt2
-rw-r--r--plugins/screenshot/screenshot.xml.in4
-rw-r--r--plugins/screenshot/src/screenshot.cpp6
-rw-r--r--plugins/screenshot/src/screenshot.h2
-rw-r--r--plugins/wobbly/src/wobbly.cpp13
-rw-r--r--plugins/wobbly/src/wobbly.h1
-rw-r--r--src/window.cpp3
19 files changed, 843 insertions, 1278 deletions
diff --git a/cmake/CompizCommon.cmake b/cmake/CompizCommon.cmake
index 0a38861..1e9ad1e 100644
--- a/cmake/CompizCommon.cmake
+++ b/cmake/CompizCommon.cmake
@@ -209,3 +209,23 @@ macro (compiz_add_uninstall)
endif ()
endmacro ()
+#posix 2008 scandir check
+include (CheckCXXSourceCompiles)
+CHECK_CXX_SOURCE_COMPILES (
+ "# include <dirent.h>
+ int func (const char *d, dirent ***list, void *sort)
+ {
+ int n = scandir(d, list, 0, (int(*)(const dirent **, const dirent **))sort);
+ return n;
+ }
+
+ int main (int, char **)
+ {
+ return 0;
+ }
+ "
+ HAVE_SCANDIR_POSIX)
+
+if (HAVE_SCANDIR_POSIX)
+ add_definitions (-DHAVE_SCANDIR_POSIX)
+endif ()
diff --git a/include/compiz.h b/include/compiz.h
index ab1b5ca..b548c16 100644
--- a/include/compiz.h
+++ b/include/compiz.h
@@ -52,6 +52,13 @@
#define DEG2RAD (M_PI / 180.0f)
+#if defined(HAVE_SCANDIR_POSIX)
+ // POSIX (2008) defines the comparison function like this:
+ #define scandir(a,b,c,d) scandir((a), (b), (c), (int(*)(const dirent **, const dirent **))(d));
+#else
+ #define scandir(a,b,c,d) scandir((a), (b), (c), (int(*)(const void*,const void*))(d));
+#endif
+
typedef std::string CompString;
typedef std::list<CompString> CompStringList;
diff --git a/kde/window-decorator-kde4/CMakeLists.txt b/kde/window-decorator-kde4/CMakeLists.txt
index b115c8e..5cee30a 100644
--- a/kde/window-decorator-kde4/CMakeLists.txt
+++ b/kde/window-decorator-kde4/CMakeLists.txt
@@ -4,7 +4,7 @@ set (USE_KDE4 1 CACHE BOOL "Build KDE 4 window decorator")
if (USE_KDE4)
- find_package(KDE4 4.1.80)
+ find_package(KDE4 4.3.0)
if (KDE4_FOUND)
include(KDE4Defaults)
@@ -38,6 +38,7 @@ if (USE_KDE4)
options.cpp
kdecoration_plugins.cpp
switcher.cpp
+ paintredirector.cpp
${kwd4_SRCS}
)
diff --git a/kde/window-decorator-kde4/decorator.cpp b/kde/window-decorator-kde4/decorator.cpp
index 24ae4aa..ed7985d 100644
--- a/kde/window-decorator-kde4/decorator.cpp
+++ b/kde/window-decorator-kde4/decorator.cpp
@@ -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;
@@ -92,15 +85,9 @@ KWD::PluginManager::PluginManager (KSharedConfigPtr config):
defaultPlugin = "kwin3_plastik";
}
-#ifdef QT_45
+
KWD::Decorator::Decorator () :
KApplication (),
-#else
-KWD::Decorator::Decorator (Display* display,
- Qt::HANDLE visual,
- Qt::HANDLE colormap) :
- KApplication (display, visual, colormap),
-#endif
mConfig (0),
mCompositeWindow (0),
mSwitcher (0)
@@ -209,13 +196,11 @@ KWD::Decorator::~Decorator (void)
}
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;
@@ -250,8 +235,6 @@ KWD::Decorator::enableDecorations (Time timestamp,
foreach (WId id, KWindowSystem::windows ())
handleWindowAdded (id);
- connect (&mIdleTimer, SIGNAL (timeout ()), SLOT (processDamage ()));
-
connect (Plasma::Theme::defaultTheme (), SIGNAL (themeChanged ()),
SLOT (plasmaThemeChanged ()));
@@ -263,31 +246,6 @@ KWD::Decorator::enableDecorations (Time timestamp,
}
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;
@@ -356,12 +314,6 @@ KWD::Decorator::changeShadowOptions (decor_shadow_options_t *opt)
mShadowOptions = *opt;
updateShadow ();
-
- mDecorNormal->reloadDecoration ();
- mDecorActive->reloadDecoration ();
-
- for (it = mClients.constBegin (); it != mClients.constEnd (); it++)
- it.value ()->reloadDecoration ();
}
void
@@ -373,12 +325,6 @@ KWD::Decorator::updateShadow (void)
xscreen = ScreenOfDisplay (xdisplay, QX11Info::appScreen ());
- if (mDefaultShadow)
- {
- decor_shadow_destroy (xdisplay, mDefaultShadow);
- mDefaultShadow = NULL;
- }
-
if (mNoBorderShadow)
decor_shadow_destroy (xdisplay, mNoBorderShadow);
@@ -421,18 +367,6 @@ KWD::Decorator::updateShadow (void)
}
}
-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)
{
@@ -440,50 +374,12 @@ KWD::Decorator::x11EventFilter (XEvent *xevent)
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 (),
@@ -528,6 +424,9 @@ KWD::Decorator::x11EventFilter (XEvent *xevent)
break;
client = mFrames[xce->window];
+
+ if (!client->decorWidget ())
+ break;
child = client->childAt (xce->x, xce->y);
if (child)
@@ -565,6 +464,9 @@ KWD::Decorator::x11EventFilter (XEvent *xevent)
break;
client = mFrames[xme->window];
+
+ if (!client->decorWidget ())
+ break;
child = client->childAt (xme->x, xme->y);
@@ -585,8 +487,8 @@ KWD::Decorator::x11EventFilter (XEvent *xevent)
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);
@@ -606,6 +508,9 @@ KWD::Decorator::x11EventFilter (XEvent *xevent)
break;
client = mFrames[xbe->window];
+
+ if (!client->decorWidget ())
+ break;
child = client->childAt (xbe->x, xbe->y);
@@ -613,11 +518,11 @@ KWD::Decorator::x11EventFilter (XEvent *xevent)
{
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);
@@ -677,36 +582,6 @@ KWD::Decorator::x11EventFilter (XEvent *xevent)
}
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;
}
@@ -830,7 +705,6 @@ KWD::Decorator::handleWindowAdded (WId id)
height + border * 2);
mClients.insert (id, client);
- mWindows.insert (client->winId (), client);
mFrames.insert (frame, client);
}
else
@@ -850,7 +724,6 @@ KWD::Decorator::handleWindowAdded (WId id)
if (client)
{
mClients.remove (client->windowId ());
- mWindows.remove (client->winId ());
mFrames.remove (client->frameId ());
delete client;
@@ -871,7 +744,6 @@ KWD::Decorator::handleWindowRemoved (WId id)
if (window)
{
mClients.remove (window->windowId ());
- mWindows.remove (window->winId ());
mFrames.remove (window->frameId ());
delete window;
}
diff --git a/kde/window-decorator-kde4/decorator.h b/kde/window-decorator-kde4/decorator.h
index bd41b6a..1df3024 100644
--- a/kde/window-decorator-kde4/decorator.h
+++ b/kde/window-decorator-kde4/decorator.h
@@ -55,11 +55,6 @@ struct _cursor {
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
@@ -112,18 +107,7 @@ class Decorator:public KApplication {
{
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,
@@ -131,9 +115,8 @@ class Decorator:public KApplication {
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);
@@ -151,7 +134,7 @@ class Decorator:public KApplication {
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);
@@ -163,9 +146,6 @@ class Decorator:public KApplication {
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;
@@ -175,11 +155,8 @@ class Decorator:public KApplication {
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 --git a/kde/window-decorator-kde4/main.cpp b/kde/window-decorator-kde4/main.cpp
index 91c96ee..2eb7ea4 100644
--- a/kde/window-decorator-kde4/main.cpp
+++ b/kde/window-decorator-kde4/main.cpp
@@ -27,6 +27,7 @@
#include <fixx11h.h>
#include <KDE/KApplication>
#include <KDE/KCmdLineArgs>
+#include <KDE/KAboutData>
#include <KDE/KDebug>
#include <KDE/KLocale>
@@ -45,28 +46,16 @@ main (int argc, char **argv)
KCmdLineArgs *args;
KCmdLineOptions options;
int status;
- int event, error;
Time timestamp;
QString appname;
-#ifndef QT_45
- Colormap colormap = 0;
- Visual *visual = 0;
- int event_base, error_base;
- Display *dpy;
- int screen;
-#endif
-
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");
+ KAboutData about("kde-window-decorator", "kwin", ki18n ("KDE Window Decorator"),
+ "0.0.1", KLocalizedString(), KAboutData::License_GPL,
+ KLocalizedString(), KLocalizedString(), "http://www.compiz.org",
+ "dev@lists.compiz-fusion.org");
KCmdLineArgs::init (argc, argv,
"kde-window-decorator",
"kwin",
@@ -75,19 +64,6 @@ main (int argc, char **argv)
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");
@@ -98,60 +74,11 @@ main (int argc, char **argv)
blurType = BLUR_TYPE_ALL;
}
- // Disable window less child widgets
- QApplication::setAttribute (Qt::AA_NativeWindows, true);
-
-#ifdef QT_45
app = new KWD::Decorator ();
-#else
- 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;
- }
- }
- }
-
- app = new KWD::Decorator (dpy, visual ? Qt::HANDLE (visual) : 0,
- colormap ? Qt::HANDLE (colormap) : 0);
-#endif
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"),
@@ -184,7 +111,7 @@ main (int argc, char **argv)
WINDOW_DECORATION_TYPE_PIXMAP |
WINDOW_DECORATION_TYPE_WINDOW);
- if (!app->enableDecorations (timestamp, event))
+ if (!app->enableDecorations (timestamp))
{
fprintf (stderr,
"%s: Could not enable decorations on display \"%s\"\n",
diff --git a/kde/window-decorator-kde4/paintredirector.cpp b/kde/window-decorator-kde4/paintredirector.cpp
new file mode 100644
index 0000000..88d2824
--- /dev/null
+++ b/kde/window-decorator-kde4/paintredirector.cpp
@@ -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 --git a/kde/window-decorator-kde4/paintredirector.h b/kde/window-decorator-kde4/paintredirector.h
new file mode 100644
index 0000000..5ce9780
--- /dev/null
+++ b/kde/window-decorator-kde4/paintredirector.h
@@ -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 --git a/kde/window-decorator-kde4/window.cpp b/kde/window-decorator-kde4/window.cpp
index aa87d0d..5383e7b 100644
--- a/kde/window-decorator-kde4/window.cpp
+++ b/kde/window-decorator-kde4/window.cpp
@@ -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>
*
@@ -27,6 +27,7 @@
#include "utils.h"
#include <unistd.h>
+#include <stdio.h>
#include <X11/Xlib.h>
#include <X11/extensions/shape.h>
@@ -57,6 +58,9 @@
#include <QVector>
#include <QProcess>
#include <QStyle>
+#include <QPainter>
+
+#include "paintredirector.h"
KWD::Window::Window (WId parentId,
WId clientId,
@@ -65,32 +69,20 @@ KWD::Window::Window (WId parentId,
int x,
int y,
int w,
- int h): QWidget (0, Qt::X11BypassWindowManagerHint),
+ int h) :
mType (type),
mParentId (parentId),
mFrame (0),
mClientId (clientId),
mSelectedId (0),
mDecor (0),
- mTexturePixmap (0),
- mTexturePixmapBuffer (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),
@@ -102,7 +94,8 @@ KWD::Window::Window (WId parentId,
mFullScreenOpAction (0),
mMinimizeOpAction (0),
mCloseOpAction (0),
- mDesktopOpAction (0)
+ mDesktopOpAction (0),
+ mPaintRedirector (0)
{
memset (&mBorder, 0, sizeof (mBorder));
@@ -113,29 +106,38 @@ KWD::Window::Window (WId parentId,
mState = wInfo.state ();
- mName = wInfo.visibleName ();
+ if (mType == Normal || mType == Normal2D)
+ {
+ mName = wInfo.visibleName ();
- mIcon = KWindowSystem::icon (mClientId, 32, 32, true,
- KWindowSystem::NETWM |
- KWindowSystem::WMHints );
+ mIcon = KWindowSystem::icon (mClientId, 32, 32, true,
+ KWindowSystem::NETWM |
+ KWindowSystem::WMHints );
- mMiniIcon = KWindowSystem::icon (mClientId, 16, 16, true,
- KWindowSystem::NETWM |
- KWindowSystem::WMHints );
+ mMiniIcon = KWindowSystem::icon (mClientId, 16, 16, true,
+ KWindowSystem::NETWM |
+ KWindowSystem::WMHints );
- if (mIcon.isNull ())
+ if (mIcon.isNull ())
+ {
+ mIcon = KWindowSystem::icon (mClientId, 32, 32, true,
+ KWindowSystem::ClassHint |
+ KWindowSystem::XApp );
+ mMiniIcon = KWindowSystem::icon (mClientId, 16, 16, true,
+ KWindowSystem::ClassHint |
+ KWindowSystem::XApp );
+ }
+
+ mOpacity = readPropertyShort (mClientId, Atoms::netWmWindowOpacity,
+ 0xffff);
+ }
+ else
{
- mIcon = KWindowSystem::icon (mClientId, 32, 32, true,
- KWindowSystem::ClassHint |
- KWindowSystem::XApp );
- mMiniIcon = KWindowSystem::icon (mClientId, 16, 16, true,
- KWindowSystem::ClassHint |
- KWindowSystem::XApp );
+ mIcon = QPixmap ();
+ mMiniIcon = QPixmap ();
+ mName = QString ("");
}
- mOpacity = readPropertyShort (mClientId, Atoms::netWmWindowOpacity,
- 0xffff);
-
updateFrame (frame);
mGeometry = QRect (x, y, w, h);
@@ -157,26 +159,8 @@ KWD::Window::Window (WId parentId,
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 (mTexturePixmap)
- XFreePixmap (QX11Info::display (), mTexturePixmap);
-
- if (mTexturePixmapBuffer)
- XFreePixmap (QX11Info::display (), mTexturePixmapBuffer);
+ XFreePixmap (QX11Info::display(), mPixmap);
if (mDecor)
delete mDecor;
@@ -184,6 +168,9 @@ KWD::Window::~Window (void)
if (mPopup)
delete mPopup;
+ if (mPaintRedirector)
+ delete mPaintRedirector;
+
if (mProcessKiller.state () == QProcess::Running)
{
mProcessKiller.terminate ();
@@ -373,13 +360,11 @@ KWD::Window::caption (void) const
void
KWD::Window::showWindowMenu (const QPoint &pos)
{
- QPoint pnt;
-
if (!mPopup)
{
QAction *action;
const int levels[] = { 100, 90, 75, 50, 25, 10 };
-
+
mPopup = new QMenu ();
mPopup->setFont (KGlobalSettings::menuFont ());
@@ -420,25 +405,23 @@ KWD::Window::showWindowMenu (const QPoint &pos)
action = mPopup->addMenu (mAdvancedMenu);
action->setText (i18n ("Ad&vanced"));
- if (mType != Normal2D)
- {
- mOpacityMenu = new QMenu (mPopup);
- mOpacityMenu->setFont (KGlobalSettings::menuFont ());
+ mOpacityMenu = new QMenu (mPopup);
+ mOpacityMenu->setFont (KGlobalSettings::menuFont ());
- connect (mOpacityMenu, SIGNAL (triggered (QAction*)),
- SLOT (handleOpacityPopupActivated (QAction*)));
+ connect (mOpacityMenu, SIGNAL (triggered (QAction*)),
+ SLOT (handleOpacityPopupActivated (QAction*)));
+
- for (unsigned int i = 0;
- i < sizeof (levels) / sizeof (levels[0]); ++i)
- {
- action = mOpacityMenu->addAction
- (QString::number (levels[i]) + "%");
- action->setCheckable (true);
- action->setData (levels[i]);
- }
- action = mPopup->addMenu (mOpacityMenu);
- action->setText (i18n ("&Opacity"));
+ for( unsigned int i = 0; i < sizeof (levels) / sizeof (levels[0]); ++i)
+ {
+ action = mOpacityMenu->addAction
+ (QString::number (levels[i]) + "%");
+ action->setCheckable (true);
+ action->setData (levels[i]);
}
+ action = mPopup->addMenu (mOpacityMenu);
+ action->setText (i18n ("&Opacity"));
+
mDesktopMenu = new QMenu (mPopup);
mDesktopMenu->setFont (KGlobalSettings::menuFont ());
@@ -457,7 +440,7 @@ KWD::Window::showWindowMenu (const QPoint &pos)
mMoveOpAction->setData (KDecorationDefines::MoveOp);
mResizeOpAction = mPopup->addAction (i18n ("Re&size"));
- kaction = qobject_cast<KAction*> (mKeys.action ("Window Resize"));
+ kaction = qobject_cast<KAction*> (mKeys.action("Window Resize"));
if (kaction != 0)
mResizeOpAction->setShortcut (kaction->globalShortcut ().primary ());
mResizeOpAction->setData (KDecorationDefines::ResizeOp);
@@ -484,18 +467,18 @@ KWD::Window::showWindowMenu (const QPoint &pos)
mPopup->addSeparator ();
- mCloseOpAction = mPopup->addAction (i18n ("&Close"));
+ mCloseOpAction = mPopup->addAction (i18n("&Close"));
mCloseOpAction->setIcon (KIcon ("window-close" ));
- kaction = qobject_cast<KAction*> (mKeys.action ("Window Close"));
+ kaction = qobject_cast<KAction*> (mKeys.action("Window Close"));
if (kaction != 0)
mCloseOpAction->setShortcut (kaction->globalShortcut ().primary ());
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);
}
@@ -518,15 +501,15 @@ KWD::Window::processMousePressEvent (QMouseEvent *qme)
switch (qme->button ()) {
case Qt::LeftButton:
com = active ? Decorator::options ()->commandActiveTitlebar1 () :
- Decorator::options ()->commandInactiveTitlebar1 ();
+ Decorator::options()->commandInactiveTitlebar1 ();
break;
case Qt::MidButton:
com = active ? Decorator::options ()->commandActiveTitlebar2 () :
- Decorator::options ()->commandInactiveTitlebar2 ();
+ Decorator::options()->commandInactiveTitlebar2 ();
break;
case Qt::RightButton:
com = active ? Decorator::options ()->commandActiveTitlebar3 () :
- Decorator::options ()->commandInactiveTitlebar3 ();
+ Decorator::options()->commandInactiveTitlebar3 ();
default:
break;
}
@@ -609,7 +592,7 @@ KWD::Window::isPreview (void) const
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,
@@ -627,6 +610,13 @@ QRect
KWD::Window::clientGeometry (void)
{
return mGeometry;
+
+ QRect frame = geometry ();
+
+ return QRect (frame.x () + mBorder.left,
+ frame.y () + mBorder.top,
+ frame.width () - mBorder.left - mBorder.right,
+ frame.height () - mBorder.top - mBorder.bottom);
}
QRegion
@@ -732,7 +722,7 @@ KWD::Window::titlebarMouseWheelOperation (int delta)
{
Options::MouseCommand com;
- com = Decorator::options ()->operationTitlebarMouseWheel (delta);
+ com = Decorator::options()->operationTitlebarMouseWheel (delta);
performMouseCommand (com, 0);
}
@@ -745,16 +735,12 @@ KWD::Window::currentDesktop (void) const
QWidget *
KWD::Window::initialParentWidget (void) const
{
- if (mType == Normal2D)
- return NULL;
- return const_cast <Window *> (this);
+ return 0;
}
Qt::WFlags
KWD::Window::initialWFlags (void) const
{
- if (mType == Normal2D)
- return Qt::X11BypassWindowManagerHint;
return 0;
}
@@ -763,6 +749,12 @@ KWD::Window::grabXServer (bool)
{
}
+bool
+KWD::Window::compositingActive (void) const
+{
+ return (mType != Normal2D);
+}
+
void
KWD::Window::createDecoration (void)
{
@@ -775,607 +767,143 @@ KWD::Window::createDecoration (void)
decor->init ();
mDecor = decor;
-
+
if (mType == Normal2D)
decor->widget ()->installEventFilter (this);
- if (mFrame)
- {
- KWD::trapXError ();
- XSelectInput (QX11Info::display (), mFrame,
- StructureNotifyMask | PropertyChangeMask |
- ButtonPressMask | ButtonReleaseMask | PointerMotionMask |
- EnterWindowMask | LeaveWindowMask);
- if (KWD::popXError ())
- return;
- }
-
- KWD::trapXError ();
- XSelectInput (QX11Info::display (), QWidget::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)
+ if (mType != Normal2D)
{
- 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);
+ mPaintRedirector = new KWin::PaintRedirector (mDecor->widget ());
+ connect (mPaintRedirector, SIGNAL (paintPending()),
+ this, SLOT (decorRepaintPending ()));
}
-}
-
-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);
+ mPadding.top = mPadding.bottom = mPadding.left = mPadding.right = 0;
- xOffLeft = c->left_space - c->extents.left;
- yOffTop = c->top_space - c->extents.top;
+ if (KDecorationUnstable *deco2 = dynamic_cast<KDecorationUnstable*>(decor))
+ deco2->padding (mPadding.left, mPadding.right, mPadding.top, mPadding.bottom);
- 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 (mType == Normal2D && mFrame)
{
- 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;
- }
- }
+ XReparentWindow (QX11Info::display(), mDecor->widget ()->winId (), mFrame, 0, 0);
+ XMoveWindow (QX11Info::display(), mDecor->widget ()->winId (), -mPadding.left, -mPadding.top);
}
else
+ XReparentWindow (QX11Info::display(), mDecor->widget ()->winId (), mParentId, 0, 0);
+
+ if (mType == Normal && mFrame)
{
- x1 -= c->extents.left;
- x2 += c->extents.right;
- y1 -= c->extents.top;
- y2 += c->extents.bottom;
+ KWD::trapXError ();
+ XSelectInput (QX11Info::display(), mFrame,
+ StructureNotifyMask | PropertyChangeMask |
+ ButtonPressMask | ButtonReleaseMask | PointerMotionMask |
+ EnterWindowMask | LeaveWindowMask);
+ if (KWD::popXError ())
+ return;
}
- 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;
+ resizeDecoration (true);
}
void
-KWD::Window::updateShadow (void)
+KWD::Window::setMask (const QRegion &region, int)
{
- Display *xdisplay = QX11Info::display ();
- Screen *xscreen;
- XRenderPictFormat *xformat;
- int leftCorner, rightCorner, topCorner, bottomCorner;
-
- xscreen = ScreenOfDisplay (xdisplay, QX11Info::appScreen ());
-
- if (mType == Normal2D)
- return;
-
- if (mShadow)
- {
- decor_shadow_destroy (QX11Info::display (), mShadow);
- mShadow = NULL;
- }
-
- if (mShapeSet)
- {
- 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
+ if (region.isEmpty ())
{
- leftCorner = mBorder.left;
- rightCorner = mBorder.right;
- topCorner = mBorder.top;
- bottomCorner = mBorder.bottom;
+ 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,
+ (mType == Normal2D)? ShapeBounding : ShapeInput,
+ 0, 0, r.handle (), ShapeSet);
+ KWD::popXError ();
+ }
+
+ mShapeSet = false;
+ return;
}
- /* 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);
- }
-
- /* 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);
-
- if (mTexturePixmap)
- XFreePixmap (QX11Info::display (), mTexturePixmap);
-
- if (mTexturePixmapBuffer)
- XFreePixmap (QX11Info::display (), mTexturePixmapBuffer);
-
- mTexturePixmap = XCreatePixmap (QX11Info::display (),
- QX11Info::appRootWindow (),
- mLayout.width, mLayout.height, 32);
- mTexturePixmapBuffer = XCreatePixmap (QX11Info::display (),
- QX11Info::appRootWindow (),
- mLayout.width, mLayout.height, 32);
- mTexturePixmapSize = QSize (mLayout.width, mLayout.height);
-
- xformat = XRenderFindStandardFormat (QX11Info::display (),
- PictStandardARGB32);
-
- mDecorationPicture =
- XRenderCreatePicture (QX11Info::display (),
- mTexturePixmap,
- xformat, 0, NULL);
- mTexturePicture =
- XRenderCreatePicture (QX11Info::display (),
- mTexturePixmapBuffer,
- 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 &reg, 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,
- (mType == Normal2D) ? ShapeBounding : ShapeInput,
- 0,
- 0,
- r.handle (),
- ShapeSet);
+ XShapeCombineRegion (QX11Info::display(), mFrame,
+ (mType == Normal2D)? ShapeBounding : 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 && mType != Normal2D)
{
- if (w == width () && h == height ())
- return FALSE;
+ mGeometry = QRect (50, 50, 100, 100);
}
- /* reset shape */
- mShapeSet = false;
- mUniqueHorzShape = false;
- mUniqueVertShape = false;
-
- if (mType != Normal && mType != Normal2D)
+ 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)
{
- XFreePixmap (QX11Info::display (), mPixmap);
+ XFreePixmap (QX11Info::display(), mPixmap);
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));
-
- mSize = QSize (w, h);
-
- if (mType != Normal2D)
- {
- XMoveResizeWindow (QX11Info::display (), winId (),
- mGeometry.x () + ROOT_OFF_X - mBorder.left,
- mGeometry.y () + ROOT_OFF_Y - mBorder.top,
- 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);
- }
- }
- }
- else
- {
- if (!mMapped)
- {
- XReparentWindow (QX11Info::display (), mDecor->widget ()->winId (),
- mFrame, 0, 0);
- mMapped = true;
- updateProperty ();
- }
- }
-
mDecor->resize (QSize (w, h));
mDecor->widget ()->show ();
mDecor->widget ()->update ();
- return TRUE;
-}
-
-void
-KWD::Window::rebindPixmap (void)
-{
- XRenderPictFormat *xformat;
-
- if (mType == Normal2D)
- return;
-
- 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;
-
- mPendingMap = 0;
-
- if (mPendingConfigure)
- return FALSE;
-
- rebindPixmap ();
+ mPixmap = XCreatePixmap (QX11Info::display(),
+ QX11Info::appRootWindow (),
+ qMax (w, mGeometry.height ()),
+ mExtents.top + mExtents.bottom +
+ mExtents.left + mExtents.right, 32);
- return TRUE;
-}
+ mPixmapQt = QPixmap::fromX11Pixmap (mPixmap, QPixmap::ExplicitlyShared);
-bool
-KWD::Window::handleConfigure (QSize size)
-{
- if (!mPendingConfigure)
- return FALSE;
+ mPixmapQt.fill (Qt::transparent);
- if (size != mSize)
- return FALSE;
-
- mPendingConfigure = 0;
- if (mPendingConfigure || mPendingMap)
- return FALSE;
-
- rebindPixmap ();
-
- return TRUE;
+ if (mPaintRedirector)
+ mUpdateProperty = true;
+ else
+ updateProperty ();
}
void
@@ -1393,54 +921,54 @@ KWD::Window::updateBlurProperty (int topOffset,
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 ();
}
}
@@ -1468,7 +996,7 @@ KWD::Window::updateBlurProperty (int topOffset,
rightRegion, rightOffset);
KWD::trapXError ();
- XChangeProperty (QX11Info::display (), mClientId, atom,
+ XChangeProperty (QX11Info::display(), mClientId, atom,
XA_INTEGER,
32, PropModeReplace, (unsigned char *) data,
2 + size * 6);
@@ -1477,7 +1005,7 @@ KWD::Window::updateBlurProperty (int topOffset,
else
{
KWD::trapXError ();
- XDeleteProperty (QX11Info::display (), mClientId, atom);
+ XDeleteProperty (QX11Info::display(), mClientId, atom);
KWD::popXError ();
}
}
@@ -1490,9 +1018,7 @@ KWD::Window::updateProperty (void)
long data[256];
decor_quad_t quads[N_QUADS_MAX];
int nQuad = 0;
- int lh, rh;
- int w;
- int minWidth;
+ int left, right, top, bottom, width, height;
unsigned int saveState;
if (mType == Default)
@@ -1508,82 +1034,118 @@ KWD::Window::updateProperty (void)
mDecor->borders (normExtents.left, normExtents.right,
normExtents.top, normExtents.bottom);
mState = saveState;
+ mState = saveState;
mDecor->borders (mBorder.left, mBorder.right, mBorder.top, mBorder.bottom);
+ left = mExtents.left;
+ right = mExtents.right;
+ top = mExtents.top;
+ bottom = mExtents.bottom;
+ width = mGeometry.width ();
+ height = mGeometry.height ();
+
if (mType != Normal2D)
{
- 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;
-
- if (mType == Normal)
- {
- int topXOffset = w / 2;
- 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 ();
-
- foreach (QObject *obj, children)
- {
- QWidget *child;
-
- if (!obj->isWidgetType ())
- continue;
-
- child = static_cast <QWidget *> (obj);
-
- x = child->x () - mBorder.left - 2;
- if (x > w / 2 && x < topXOffset)
- topXOffset = x;
- }
- }
- nQuad = decor_set_lXrXtXbX_window_quads (quads,
- &mContext,
- &mLayout,
- lh / 2,
- rh / 2,
- topXOffset,
- w / 2);
-
- updateBlurProperty (topXOffset, w / 2, lh / 2, rh / 2);
-
- minWidth = mContext.left_corner_space + 1 + mContext.right_corner_space;
- }
- else
- {
- nQuad = decor_set_lSrStSbS_window_quads (quads, &mContext, &mLayout);
-
- minWidth = 1;
- }
-
- decor_quads_to_property (data, mTexturePixmap,
- &normExtents, &maxExtents,
- minWidth, 0,
- quads, nQuad);
- }
- else
- {
+ if (mType == Normal)
+ {
+ decor_quad_t *q = quads;
+ int n = 0;
+
+ int topXOffset = width;
+ QWidget *widget = mDecor->widget ();
+ int x;
+
+ if (widget)
+ {
+ const QList<QObject*> children = widget->children ();
+
+ foreach (QObject *obj, children)
+ {
+ QWidget *child;
+
+ if (!obj->isWidgetType ())
+ continue;
+
+ child = static_cast <QWidget *> (obj);
+
+ x = child->x () - mExtents.left - 2;
+ if (x > width / 2 && x < topXOffset)
+ topXOffset = x;
+ }
+ }
+
+ // 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);
+
+ 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);
+
+ 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
+ {
+ 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);
+
+ 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);
+
+ 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);
+ }
+ else
+ {
decor_gen_window_property (data, &normExtents, &maxExtents, 1, 0);
- }
+ }
KWD::trapXError ();
- XChangeProperty (QX11Info::display (), mClientId, atom,
+ XChangeProperty (QX11Info::display(), mClientId, atom,
XA_INTEGER,
32, PropModeReplace, (unsigned char *) data,
BASE_PROP_SIZE + QUAD_PROP_SIZE * nQuad);
@@ -1602,14 +1164,17 @@ KWD::Window::handleActiveChange (void)
void
KWD::Window::updateFrame (WId frame)
{
- if (mMapped && mType == Normal2D && mFrame != frame)
+ if (mType == Normal2D && frame != mFrame && mDecor)
{
- XReparentWindow (QX11Info::display (), winId (), frame, 0, 0);
+ reloadDecoration ();
+ //XReparentWindow (QX11Info::display(), mDecor->widget ()->winId (), frame, 0, 0);
+ //XMoveWindow (QX11Info::display(), mDecor->widget ()->winId (), -mPadding.left, -mPadding.top);
}
+
mFrame = frame;
KWD::trapXError ();
- XSelectInput (QX11Info::display (), mFrame,
+ XSelectInput (QX11Info::display(), mFrame,
StructureNotifyMask | PropertyChangeMask |
ButtonPressMask | ButtonReleaseMask | PointerMotionMask |
EnterWindowMask | LeaveWindowMask);
@@ -1627,29 +1192,24 @@ KWD::Window::updateSelected (WId selectedId)
void
KWD::Window::updateWindowGeometry (void)
{
- KWindowInfo wInfo = KWindowSystem::windowInfo (mClientId, NET::WMGeometry |
- NET::WMDesktop | NET::WMState);
+ KWindowInfo wInfo = KWindowSystem::windowInfo (mClientId, NET::WMGeometry);
QRect geometry = wInfo.geometry ();
+ int w, h;
- if (wInfo.state () & NET::Shaded && mType == Normal2D)
- geometry.setHeight (0);
+ w = mGeometry.width () + mBorder.left + mBorder.right;
+ h = mGeometry.height () + mBorder.top + mBorder.bottom;
if (mGeometry.width () != geometry.width () ||
mGeometry.height () != geometry.height ())
{
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
@@ -1658,14 +1218,10 @@ KWD::Window::reloadDecoration (void)
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 ();
}
@@ -1673,7 +1229,7 @@ KWD::Window::reloadDecoration (void)
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:
@@ -1703,10 +1259,10 @@ void
KWD::Window::updateCursor (QPoint pos)
{
KWD::trapXError ();
- if (mType == Normal2D)
- XDefineCursor (QX11Info::display (), winId (), positionToCursor (pos));
+ if (mType == Normal2D && mDecor)
+ XDefineCursor (QX11Info::display(), mDecor->widget ()->winId (), positionToCursor (pos));
else
- XDefineCursor (QX11Info::display (), mFrame, positionToCursor (pos));
+ XDefineCursor (QX11Info::display(), mFrame, positionToCursor (pos));
KWD::popXError ();
}
@@ -1721,7 +1277,7 @@ KWD::Window::getWindowProtocols (void)
mSupportContextHelp = false;
KWD::trapXError ();
- status = XGetWMProtocols (QX11Info::display (), mClientId, &p, &n);
+ status = XGetWMProtocols (QX11Info::display(), mClientId, &p, &n);
if (KWD::popXError ())
return;
@@ -1745,21 +1301,20 @@ KWD::Window::getWindowProtocols (void)
void
KWD::Window::handlePopupActivated (QAction * action)
{
- WindowOperation op;
+ WindowOperation op = static_cast <WindowOperation> (action->data().toInt());
- op = static_cast <WindowOperation> (action->data ().toInt ());
performWindowOperation (op);
}
void
KWD::Window::handleOpacityPopupActivated (QAction *action)
{
- int op = action->data ().toInt ();
+ int op = action->data().toInt();
op = op * 0xffff / 100;
if (op != mOpacity)
- Decorator::sendClientMessage (QX11Info::appRootWindow (), mClientId,
+ Decorator::sendClientMessage (QX11Info::appRootWindow(), mClientId,
Atoms::netWmWindowOpacity,
(op << 16) | op);
}
@@ -1768,8 +1323,9 @@ KWD::Window::handleOpacityPopupActivated (QAction *action)
void
KWD::Window::handleDesktopPopupActivated (QAction *action)
{
- if (action->data ().toInt ())
- setDesktop (action->data ().toInt ());
+
+ if (action->data().toInt())
+ setDesktop (action->data().toInt());
else
KWindowSystem::setOnAllDesktops (mClientId, true);
}
@@ -1838,16 +1394,13 @@ KWD::Window::handlePopupAboutToShow (void)
mMinimizeOpAction->setEnabled (isMinimizable ());
mCloseOpAction->setEnabled (isCloseable ());
- if (mType != Normal2D)
+ foreach (QAction* action, mOpacityMenu->actions ())
{
- foreach (QAction* action, mOpacityMenu->actions ())
- {
- if (action->data ().toInt () ==
- qRound ((float) mOpacity * 100.0 / 0xffff))
- action->setChecked (true);
- else
- action->setChecked (false);
- }
+ if(action->data ().toInt () ==
+ qRound ((float)mOpacity * 100.0 / 0xffff))
+ action->setChecked( true );
+ else
+ action->setChecked( false );
}
}
@@ -1877,10 +1430,7 @@ KWD::Window::updateState (void)
if (stateChange & NET::KeepBelow && mState & NET::KeepBelow)
mDecor->emitKeepBelowChanged (mState & NET::KeepBelow);
if (stateChange & NET::Shaded)
- {
mDecor->shadeChange ();
- updateWindowGeometry ();
- }
if (stateChange & NET::Sticky)
mDecor->desktopChange ();
}
@@ -1955,12 +1505,12 @@ KWD::Window::moveWindow (QMouseEvent *qme)
direction = positionToDirection (mDecor->mousePosition (qme->pos ()));
- XUngrabPointer (QX11Info::display (), CurrentTime);
- XUngrabKeyboard (QX11Info::display (), CurrentTime);
+ XUngrabPointer (QX11Info::display(), CurrentTime);
+ XUngrabKeyboard (QX11Info::display(), CurrentTime);
Decorator::rootInfo ()->restackRequest (mClientId, NET::FromApplication,
- None, Above,
- QX11Info::appTime ());
+ None, Above,
+ QX11Info::appTime());
Decorator::rootInfo ()->moveResizeRequest (mClientId,
qme->globalX (),
qme->globalY (),
@@ -1992,14 +1542,8 @@ KWD::Window::performMouseCommand (Options::MouseCommand command,
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;
@@ -2035,7 +1579,7 @@ KWD::Window::performMouseCommand (Options::MouseCommand command,
if (opacity > 0xffff)
opacity = 0xffff;
- Decorator::sendClientMessage (QX11Info::appRootWindow (),
+ Decorator::sendClientMessage (QX11Info::appRootWindow(),
mClientId,
Atoms::netWmWindowOpacity,
(opacity << 16) | opacity);
@@ -2051,7 +1595,7 @@ KWD::Window::performMouseCommand (Options::MouseCommand command,
if (opacity < OPACITY_STEP)
opacity = OPACITY_STEP;
- Decorator::sendClientMessage (QX11Info::appRootWindow (),
+ Decorator::sendClientMessage (QX11Info::appRootWindow(),
mClientId,
Atoms::netWmWindowOpacity,
(opacity << 16) | opacity);
@@ -2072,153 +1616,13 @@ KWD::Window::performMouseCommand (Options::MouseCommand command,
}
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,
- mTexturePixmapSize.width (),
- mTexturePixmapSize.height ());
-
- if (mUpdateProperty)
- updateProperty ();
-}
-
-void
KWD::Window::showKillProcessDialog (Time timestamp)
{
KWindowInfo kWinInfo =
KWindowSystem::windowInfo (mClientId, 0, NET::WM2WindowClass |
NET::WM2ClientMachine);
- NETWinInfo wInfo = NETWinInfo (QX11Info::display (), mClientId,
- QX11Info::appRootWindow (),
- NET::WMPid);
+ NETWinInfo wInfo = NETWinInfo (QX11Info::display(), mClientId,
+ QX11Info::appRootWindow(), NET::WMPid);
QByteArray clientMachine, resourceClass;
pid_t pid;
char buf[257];
@@ -2255,39 +1659,148 @@ KWD::Window::hideKillProcessDialog (void)
}
}
-bool
-KWD::Window::eventFilter (QObject *o,
- QEvent *e)
+void
+KWD::Window::decorRepaintPending ()
{
- if (!mDecor || o != mDecor->widget ())
- return false;
- if (e->type () == QEvent::MouseMove)
+ 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();
+
+ if (mType != Normal2D)
{
- QMouseEvent* ev = static_cast<QMouseEvent *> (e);
- updateCursor (QPoint (ev->x (), ev->y ()));
+ 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 );
+ }
}
- return false;
+ else
+ {
+
+ }
+
+ if (mUpdateProperty)
+ updateProperty ();
}
-// unsable API part
-void
-KWD::Window::repaintShadow ()
+QWidget *
+KWD::Window::decorWidget (void) const
{
+ if (!mDecor)
+ return 0;
+ return mDecor->widget ();
}
-bool
-KWD::Window::compositingActive () const
+QWidget *
+KWD::Window::childAt (int x, int y) const
{
- return false;
+ if (!mDecor)
+ return 0;
+
+ QWidget *child = mDecor->widget ()->childAt (x + mPadding.left, y + mPadding.top);
+ return (child)? child : decorWidget ();
}
-bool
-KWD::Window::shadowsActive () const
+QPoint
+KWD::Window::mapToChildAt (QPoint p) const
{
- return false;
+ 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));
}
-double KWD::Window::opacity () const
+bool
+KWD::Window::eventFilter (QObject *o,
+ QEvent *e)
{
- return 1.0;
+ if (!mDecor || o != mDecor->widget ())
+ return false;
+ if (e->type () == QEvent::MouseMove)
+ {
+ QMouseEvent* ev = static_cast<QMouseEvent *> (e);
+ updateCursor (QPoint (ev->x () - mPadding.left, ev->y () - mPadding.top));
+ }
+ return false;
}
diff --git a/kde/window-decorator-kde4/window.h b/kde/window-decorator-kde4/window.h
index de7031a..4c80b9c 100644
--- a/kde/window-decorator-kde4/window.h
+++ b/kde/window-decorator-kde4/window.h
@@ -43,17 +43,22 @@ class KDecoration;
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
{
+ Normal2D,
Normal,
Default,
- DefaultActive,
- Normal2D
+ DefaultActive
};
public:
@@ -61,13 +66,6 @@ class Window:public QWidget, public KDecorationBridgeUnstable {
int x = 0, int y = 0, int w = 1, int h = 1);
~Window (void);
- // unsable API part
- virtual void repaintShadow ();
- virtual bool compositingActive () const;
- virtual bool shadowsActive () const;
- virtual double opacity () const;
-
- // stable API part;
virtual bool isActive (void) const;
virtual bool isCloseable (void) const;
virtual bool isMaximizable (void) const;
@@ -112,39 +110,39 @@ class Window:public QWidget, public KDecorationBridgeUnstable {
virtual Qt::WFlags initialWFlags (void) const;
virtual void grabXServer (bool grab);
+ /* unstable API */
+ virtual bool compositingActive () 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);
@@ -159,21 +157,7 @@ class Window:public QWidget, public KDecorationBridgeUnstable {
{
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;
@@ -192,31 +176,12 @@ class Window:public QWidget, public KDecorationBridgeUnstable {
{
return mFakeRelease;
}
-
- WId winId ()
- {
- if (mType == Normal2D && mDecor)
- return mDecor->widget ()->winId ();
- return QWidget::winId ();
- }
-
- QWidget *childAt (int x, int y)
- {
- QWidget *rv;
- if (mType == Normal2D && mDecor)
- {
- rv = mDecor->widget ()->childAt (x, y);
- if (!rv)
- rv = mDecor->widget ();
- return rv;
- }
- return QWidget::childAt (x, y);
- }
-
+
virtual bool eventFilter (QObject *o, QEvent *e);
private:
- bool resizeDecoration (bool force = false);
+ void createDecoration (void);
+ void resizeDecoration (bool force = false);
void updateBlurProperty (int topOffset,
int bottomOffset,
int leftOffset,
@@ -227,17 +192,15 @@ class Window:public QWidget, public KDecorationBridgeUnstable {
QMouseEvent *qme);
NET::Direction positionToDirection (int pos);
Cursor positionToCursor (QPoint pos);
- void rebindPixmap (void);
-
private slots:
- void createDecoration (void);
- 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;
@@ -249,24 +212,14 @@ class Window:public QWidget, public KDecorationBridgeUnstable {
QPixmap mIcon;
QPixmap mMiniIcon;
decor_extents_t mBorder;
+ decor_extents_t mPadding;
+ decor_extents_t mExtents;
unsigned short mOpacity;
KDecoration *mDecor;
- Pixmap mTexturePixmap;
- Pixmap mTexturePixmapBuffer;
- QSize mTexturePixmapSize;
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;
@@ -276,10 +229,7 @@ class Window:public QWidget, public KDecorationBridgeUnstable {
QMenu *mOpacityMenu;
QMenu *mDesktopMenu;
unsigned long mState;
- bool mMapped;
- int mPendingMap;
- int mPendingConfigure;
- QSize mSize;
+
QProcess mProcessKiller;
KActionCollection mKeys;
bool mFakeRelease;
@@ -295,6 +245,8 @@ class Window:public QWidget, public KDecorationBridgeUnstable {
QAction *mMinimizeOpAction;
QAction *mCloseOpAction;
QAction *mDesktopOpAction;
+
+ KWin::PaintRedirector *mPaintRedirector;
};
}
diff --git a/plugins/compiztoolbox/include/compiztoolbox/compiztoolbox.h b/plugins/compiztoolbox/include/compiztoolbox/compiztoolbox.h
index cea3fe8..bf14888 100644
--- a/plugins/compiztoolbox/include/compiztoolbox/compiztoolbox.h
+++ b/plugins/compiztoolbox/include/compiztoolbox/compiztoolbox.h
@@ -36,8 +36,25 @@
#include <X11/Xatom.h>
#include <X11/extensions/Xrender.h>
+#include <fstream>
-typedef enum {
+typedef enum
+{
+ XDGUserDirDesktop = 0,
+ XDGUserDirDownload,
+ XDGUserDirTemplates,
+ XDGUserDirPublicshare,
+ XDGUserDirDocuments,
+ XDGUserDirMusic,
+ XDGUserDirPictures,
+ XDGUserDirVideos
+} XDGUserDir;
+
+CompString getXDGUserDir (XDGUserDir userDir);
+
+
+typedef enum
+{
CurrentViewport = 0,
AllViewports,
Panels,
diff --git a/plugins/compiztoolbox/src/compiztoolbox.cpp b/plugins/compiztoolbox/src/compiztoolbox.cpp
index d12a523..41aa64e 100644
--- a/plugins/compiztoolbox/src/compiztoolbox.cpp
+++ b/plugins/compiztoolbox/src/compiztoolbox.cpp
@@ -27,6 +27,77 @@
#include <compiztoolbox/compiztoolbox.h>
+CompString
+getXDGUserDir (XDGUserDir userDir)
+{
+ std::ifstream userDirsFile;
+ CompString userDirsFilePath;
+ const char *userDirsPathSuffix = "/user-dirs.dirs";
+ const char *varNames[8] =
+ {
+ "XDG_DESKTOP_DIR",
+ "XDG_DOWNLOAD_DIR",
+ "XDG_TEMPLATES_DIR",
+ "XDG_PUBLICSHARE_DIR",
+ "XDG_DOCUMENTS_DIR",
+ "XDG_MUSIC_DIR",
+ "XDG_PICTURES_DIR",
+ "XDG_VIDEOS_DIR"
+ };
+ const char *varName = varNames[userDir];
+ size_t varLength = strlen (varName);
+
+ char *home = getenv ("HOME");
+ if (!(home && strlen (home)))
+ return "";
+
+ char *configHome = getenv ("XDG_CONFIG_HOME");
+ if (configHome && strlen (configHome))
+ {
+ userDirsFilePath = configHome;
+ userDirsFilePath += userDirsPathSuffix;
+ }
+ else
+ {
+ userDirsFilePath = home;
+ userDirsFilePath =
+ userDirsFilePath + "/.config" + userDirsPathSuffix;
+ }
+ userDirsFile.open (userDirsFilePath.c_str (), std::ifstream::in);
+ if (!userDirsFile.is_open ())
+ return "";
+
+ // The user-dirs file has lines like:
+ // XDG_DESKTOP_DIR="$HOME/Desktop"
+ // Read it line by line until the desired directory is found.
+ while (!userDirsFile.eof())
+ {
+ CompString line;
+ getline (userDirsFile, line);
+
+ size_t varPos = line.find (varName);
+ if (varPos != CompString::npos) // if found
+ {
+ userDirsFile.close ();
+
+ // Skip the =" part
+ size_t valueStartPos = varPos + varLength + 2;
+
+ // Ignore the " at the end
+ CompString value = line.substr (valueStartPos,
+ line.length () - valueStartPos - 1);
+
+ if (value.substr (0, 5) == "$HOME")
+ return CompString (home) + value.substr (5);
+ else if (value.substr (0, 7) == "${HOME}")
+ return CompString (home) + value.substr (7);
+ else
+ return value;
+ }
+ }
+ return "";
+}
+
void
BaseSwitchScreen::setSelectedWindowHint ()
diff --git a/plugins/screenshot/CMakeLists.txt b/plugins/screenshot/CMakeLists.txt
index 42147ae..5cf2eb6 100644
--- a/plugins/screenshot/CMakeLists.txt
+++ b/plugins/screenshot/CMakeLists.txt
@@ -2,4 +2,4 @@ find_package (Compiz REQUIRED)
include (CompizPlugin)
-compiz_plugin(screenshot PLUGINDEPS composite opengl)
+compiz_plugin(screenshot PLUGINDEPS composite opengl compiztoolbox)
diff --git a/plugins/screenshot/screenshot.xml.in b/plugins/screenshot/screenshot.xml.in
index 9c812b2..e2ec6be 100644
--- a/plugins/screenshot/screenshot.xml.in
+++ b/plugins/screenshot/screenshot.xml.in
@@ -16,9 +16,9 @@
</option>
<option name="directory" type="string">
<_short>Directory</_short>
- <_long>Put screenshot images in this directory</_long>
+ <_long>Put screenshot images in this directory. If empty, the desktop directory will be used.</_long>
<hints>directory;</hints>
- <default>Desktop</default>
+ <default></default>
</option>
<option name="launch_app" type="string">
<_short>Launch Application</_short>
diff --git a/plugins/screenshot/src/screenshot.cpp b/plugins/screenshot/src/screenshot.cpp
index 1941390..b7aa682 100644
--- a/plugins/screenshot/src/screenshot.cpp
+++ b/plugins/screenshot/src/screenshot.cpp
@@ -154,6 +154,12 @@ ShotScreen::paint (CompOutput::ptrList &outputs,
GLubyte *buffer;
CompString dir (optionGetDirectory ());
+ if (dir.length () == 0)
+ {
+ // If dir is empty, use user's desktop directory instead
+ dir = getXDGUserDir (XDGUserDirDesktop);
+ }
+
buffer = (GLubyte *)malloc (sizeof (GLubyte) * w * h * 4);
if (buffer)
{
diff --git a/plugins/screenshot/src/screenshot.h b/plugins/screenshot/src/screenshot.h
index 7975ce1..03a9e94 100644
--- a/plugins/screenshot/src/screenshot.h
+++ b/plugins/screenshot/src/screenshot.h
@@ -29,6 +29,8 @@
#include "screenshot_options.h"
+#include <compiztoolbox/compiztoolbox.h>
+
#include <composite/composite.h>
#include <opengl/opengl.h>
diff --git a/plugins/wobbly/src/wobbly.cpp b/plugins/wobbly/src/wobbly.cpp
index 49b2d18..d767bbb 100644
--- a/plugins/wobbly/src/wobbly.cpp
+++ b/plugins/wobbly/src/wobbly.cpp
@@ -2191,6 +2191,16 @@ WobblyScreen::snapKeyChanged (CompOption *opt)
opt->value ().action ().setKey (newKeyBinding);
}
+void
+WobblyScreen::snapInvertedChanged (CompOption *opt)
+{
+ // ignore the key
+ if (opt->value ().b ())
+ enableSnapping ();
+ else
+ disableSnapping ();
+}
+
WobblyScreen::WobblyScreen (CompScreen *s) :
PluginClassHandler<WobblyScreen, CompScreen> (s),
cScreen (CompositeScreen::get (s)),
@@ -2208,6 +2218,9 @@ WobblyScreen::WobblyScreen (CompScreen *s) :
optionSetShiverInitiate (boost::bind (&WobblyScreen::shiver, this, _3));
optionSetSnapKeyNotify (boost::bind (&WobblyScreen::snapKeyChanged, _1));
+ optionSetSnapInvertedNotify (boost::bind
+ (&WobblyScreen::snapInvertedChanged,
+ this, _1));
ScreenInterface::setHandler (::screen);
CompositeScreenInterface::setHandler (cScreen, false);
diff --git a/plugins/wobbly/src/wobbly.h b/plugins/wobbly/src/wobbly.h
index 2e385df..fb4cc3e 100644
--- a/plugins/wobbly/src/wobbly.h
+++ b/plugins/wobbly/src/wobbly.h
@@ -225,6 +225,7 @@ public:
unsigned int);
static void snapKeyChanged (CompOption *opt);
+ void snapInvertedChanged (CompOption *opt);
CompositeScreen *cScreen;
GLScreen *gScreen;
diff --git a/src/window.cpp b/src/window.cpp
index fa431c6..fc4df0c 100644
--- a/src/window.cpp
+++ b/src/window.cpp
@@ -5186,7 +5186,8 @@ CompWindow::updateFrameRegion ()
int x, y;
if ((priv->input.left || priv->input.right ||
- priv->input.top || priv->input.bottom) && priv->frame)
+ priv->input.top || priv->input.bottom) && priv->frame &&
+ priv->serverGeometry == priv->geometry)
{
priv->frameRegion = CompRegion ();