diff options
author | toma <toma@283d02a7-25f6-0310-bc7c-ecb5cbfe19da> | 2009-11-25 17:56:58 +0000 |
---|---|---|
committer | toma <toma@283d02a7-25f6-0310-bc7c-ecb5cbfe19da> | 2009-11-25 17:56:58 +0000 |
commit | ce4a32fe52ef09d8f5ff1dd22c001110902b60a2 (patch) | |
tree | 5ac38a06f3dde268dc7927dc155896926aaf7012 /kdeui/krootpixmap.cpp | |
download | tdelibs-ce4a32fe52ef09d8f5ff1dd22c001110902b60a2.tar.gz tdelibs-ce4a32fe52ef09d8f5ff1dd22c001110902b60a2.zip |
Copy the KDE 3.5 branch to branches/trinity for new KDE 3.5 features.
BUG:215923
git-svn-id: svn://anonsvn.kde.org/home/kde/branches/trinity/kdelibs@1054174 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
Diffstat (limited to 'kdeui/krootpixmap.cpp')
-rw-r--r-- | kdeui/krootpixmap.cpp | 332 |
1 files changed, 332 insertions, 0 deletions
diff --git a/kdeui/krootpixmap.cpp b/kdeui/krootpixmap.cpp new file mode 100644 index 000000000..5f9591b5b --- /dev/null +++ b/kdeui/krootpixmap.cpp @@ -0,0 +1,332 @@ +/* vi: ts=8 sts=4 sw=4 + * + * + * This file is part of the KDE project, module kdeui. + * Copyright (C) 1999,2000 Geert Jansen <jansen@kde.org> + * + * You can Freely distribute this program under the GNU Library + * General Public License. See the file "COPYING.LIB" for the exact + * licensing terms. + */ + +#include <qwidget.h> +#include <qtimer.h> +#include <qrect.h> +#include <qimage.h> + +#include <kapplication.h> +#include <kimageeffect.h> +#include <kpixmapio.h> +#include <kwinmodule.h> +#include <kwin.h> +#include <kdebug.h> +#include <netwm.h> +#include <dcopclient.h> +#include <dcopref.h> + +#include <ksharedpixmap.h> +#include <krootpixmap.h> + + +static QString wallpaperForDesktop(int desktop) +{ + return DCOPRef("kdesktop", "KBackgroundIface").call("currentWallpaper", desktop); +} + +class KRootPixmapData +{ +public: + QWidget *toplevel; +#ifdef Q_WS_X11 + KWinModule *kwin; +#endif +}; + + +KRootPixmap::KRootPixmap( QWidget *widget, const char *name ) + : QObject(widget, name ? name : "KRootPixmap" ), m_Desk(0), m_pWidget(widget) +{ + init(); +} + +KRootPixmap::KRootPixmap( QWidget *widget, QObject *parent, const char *name ) + : QObject( parent, name ? name : "KRootPixmap" ), m_Desk(0), m_pWidget(widget) +{ + init(); +} + +void KRootPixmap::init() +{ + d = new KRootPixmapData; + m_Fade = 0; + m_pPixmap = new KSharedPixmap; //ordinary KPixmap on win32 + m_pTimer = new QTimer( this ); + m_bInit = false; + m_bActive = false; + m_bCustomPaint = false; + + connect(kapp, SIGNAL(backgroundChanged(int)), SLOT(slotBackgroundChanged(int))); + connect(m_pTimer, SIGNAL(timeout()), SLOT(repaint())); +#ifdef Q_WS_X11 + connect(m_pPixmap, SIGNAL(done(bool)), SLOT(slotDone(bool))); + + d->kwin = new KWinModule( this ); + connect(d->kwin, SIGNAL(windowChanged(WId, unsigned int)), SLOT(desktopChanged(WId, unsigned int))); + connect(d->kwin, SIGNAL(currentDesktopChanged(int)), SLOT(desktopChanged(int))); +#endif + + d->toplevel = m_pWidget->topLevelWidget(); + d->toplevel->installEventFilter(this); + m_pWidget->installEventFilter(this); +} + +KRootPixmap::~KRootPixmap() +{ + delete m_pPixmap; + delete d; +} + + +int KRootPixmap::currentDesktop() const +{ +#ifdef Q_WS_X11 + NETRootInfo rinfo( qt_xdisplay(), NET::CurrentDesktop ); + rinfo.activate(); + return rinfo.currentDesktop(); +#else + //OK? + return QApplication::desktop()->screenNumber(m_pWidget); +#endif +} + + +void KRootPixmap::start() +{ + if (m_bActive) + return; + + m_bActive = true; + if ( !isAvailable() ) + { + // We will get a KIPC message when the shared pixmap is available. + enableExports(); + return; + } + if (m_bInit) + repaint(true); +} + + +void KRootPixmap::stop() +{ + m_bActive = false; + m_pTimer->stop(); +} + + +void KRootPixmap::setFadeEffect(double fade, const QColor &color) +{ + if (fade < 0) + m_Fade = 0; + else if (fade > 1) + m_Fade = 1; + else + m_Fade = fade; + m_FadeColor = color; + + if ( m_bActive && m_bInit ) repaint(true); +} + + +bool KRootPixmap::eventFilter(QObject *, QEvent *event) +{ + // Initialise after the first show or paint event on the managed widget. + if (!m_bInit && ((event->type() == QEvent::Show) || (event->type() == QEvent::Paint))) + { + m_bInit = true; + m_Desk = currentDesktop(); + } + + if (!m_bActive) + return false; + + switch (event->type()) + { + case QEvent::Resize: + case QEvent::Move: + m_pTimer->start(100, true); + break; + + case QEvent::Paint: + m_pTimer->start(0, true); + break; + + case QEvent::Reparent: + d->toplevel->removeEventFilter(this); + d->toplevel = m_pWidget->topLevelWidget(); + d->toplevel->installEventFilter(this); + break; + + default: + break; + } + + return false; // always continue processing +} + +void KRootPixmap::desktopChanged(int desktop) +{ + if (wallpaperForDesktop(m_Desk) == wallpaperForDesktop(desktop) && + !wallpaperForDesktop(m_Desk).isNull()) + return; + +#ifdef Q_WS_X11 + if (KWin::windowInfo(m_pWidget->topLevelWidget()->winId()).desktop() == NET::OnAllDesktops && + pixmapName(m_Desk) != pixmapName(desktop)) +#endif + repaint(true); +} + +void KRootPixmap::desktopChanged( WId window, unsigned int properties ) +{ +#ifdef Q_WS_X11 + if( !(properties & NET::WMDesktop) || + (window != m_pWidget->topLevelWidget()->winId())) + return; +#endif + + kdDebug() << k_funcinfo << endl; + repaint(true); +} + +void KRootPixmap::repaint() +{ + repaint(false); +} + + +void KRootPixmap::repaint(bool force) +{ + QPoint p1 = m_pWidget->mapToGlobal(m_pWidget->rect().topLeft()); + QPoint p2 = m_pWidget->mapToGlobal(m_pWidget->rect().bottomRight()); + if (!force && (m_Rect == QRect(p1, p2))) + return; + + // Due to northwest bit gravity, we don't need to do anything if the + // bottom right corner of the widget is moved inward. + // That said, konsole clears the background when it is resized, so + // we have to reset the background pixmap. + if ((p1 == m_Rect.topLeft()) && (m_pWidget->width() < m_Rect.width()) && + (m_pWidget->height() < m_Rect.height()) + ) + { + m_Rect = QRect(p1, p2); + updateBackground( m_pPixmap ); + return; + } + m_Rect = QRect(p1, p2); +#ifdef Q_WS_X11 + m_Desk = KWin::windowInfo(m_pWidget->topLevelWidget()->winId()).desktop(); + if (m_Desk == NET::OnAllDesktops) + m_Desk = currentDesktop(); + + // KSharedPixmap will correctly generate a tile for us. + m_pPixmap->loadFromShared(pixmapName(m_Desk), m_Rect); +#else + m_Desk = currentDesktop(); + // !x11 note: tile is not generated! + // TODO: pixmapName() is a nonsense now! + m_pPixmap->load( pixmapName(m_Desk) ); + if (!m_pPixmap->isNull()) { + m_pPixmap->resize( m_Rect.size() ); + slotDone(true); + } +#endif +} + +bool KRootPixmap::isAvailable() const +{ +#ifdef Q_WS_X11 + return m_pPixmap->isAvailable(pixmapName(m_Desk)); +#else + return m_pPixmap->isNull(); +#endif +} + +QString KRootPixmap::pixmapName(int desk) { + QString pattern = QString("DESKTOP%1"); +#ifdef Q_WS_X11 + int screen_number = DefaultScreen(qt_xdisplay()); + if (screen_number) { + pattern = QString("SCREEN%1-DESKTOP").arg(screen_number) + "%1"; + } +#endif + return pattern.arg( desk ); +} + + +void KRootPixmap::enableExports() +{ +#ifdef Q_WS_X11 + kdDebug(270) << k_lineinfo << "activating background exports.\n"; + DCOPClient *client = kapp->dcopClient(); + if (!client->isAttached()) + client->attach(); + QByteArray data; + QDataStream args( data, IO_WriteOnly ); + args << 1; + + QCString appname( "kdesktop" ); + int screen_number = DefaultScreen(qt_xdisplay()); + if ( screen_number ) + appname.sprintf("kdesktop-screen-%d", screen_number ); + + client->send( appname, "KBackgroundIface", "setExport(int)", data ); +#endif +} + + +void KRootPixmap::slotDone(bool success) +{ + if (!success) + { + kdWarning(270) << k_lineinfo << "loading of desktop background failed.\n"; + return; + } + + // We need to test active as the pixmap might become available + // after the widget has been destroyed. + if ( m_bActive ) + updateBackground( m_pPixmap ); +} + +void KRootPixmap::updateBackground( KSharedPixmap *spm ) +{ + QPixmap pm = *spm; + + if (m_Fade > 1e-6) + { + KPixmapIO io; + QImage img = io.convertToImage(pm); + img = KImageEffect::fade(img, m_Fade, m_FadeColor); + pm = io.convertToPixmap(img); + } + + if ( !m_bCustomPaint ) + m_pWidget->setBackgroundPixmap( pm ); + else { + emit backgroundUpdated( pm ); + } +} + + +void KRootPixmap::slotBackgroundChanged(int desk) +{ + if (!m_bInit || !m_bActive) + return; + + if (desk == m_Desk) + repaint(true); +} + +#include "krootpixmap.moc" |