kdeui Library API Documentation

krootpixmap.cpp

00001 /* vi: ts=8 sts=4 sw=4 00002 * 00003 * $Id: krootpixmap.cpp,v 1.23.2.3 2004/05/24 10:57:23 waba Exp $ 00004 * 00005 * This file is part of the KDE project, module kdeui. 00006 * Copyright (C) 1999,2000 Geert Jansen <jansen@kde.org> 00007 * 00008 * You can Freely distribute this program under the GNU Library 00009 * General Public License. See the file "COPYING.LIB" for the exact 00010 * licensing terms. 00011 */ 00012 00013 #include <qwidget.h> 00014 #include <qtimer.h> 00015 #include <qrect.h> 00016 #include <qimage.h> 00017 00018 #ifndef Q_WS_QWS //FIXME 00019 #include <kapplication.h> 00020 #include <kimageeffect.h> 00021 #include <kpixmapio.h> 00022 #include <kwinmodule.h> 00023 #include <kwin.h> 00024 #include <kdebug.h> 00025 #include <netwm.h> 00026 #include <dcopclient.h> 00027 00028 #include <ksharedpixmap.h> 00029 #include <krootpixmap.h> 00030 00031 class KRootPixmapData 00032 { 00033 public: 00034 QWidget *toplevel; 00035 KWinModule *kwin; 00036 }; 00037 00038 00039 KRootPixmap::KRootPixmap( QWidget *widget, const char *name ) 00040 : QObject(widget, name ? name : "KRootPixmap" ), m_pWidget(widget) 00041 { 00042 init(); 00043 } 00044 00045 KRootPixmap::KRootPixmap( QWidget *widget, QObject *parent, const char *name ) 00046 : QObject( parent, name ? name : "KRootPixmap" ), m_pWidget(widget) 00047 { 00048 init(); 00049 } 00050 00051 void KRootPixmap::init() 00052 { 00053 d = new KRootPixmapData; 00054 m_Fade = 0; 00055 m_pPixmap = new KSharedPixmap; 00056 m_pTimer = new QTimer( this ); 00057 m_bInit = false; 00058 m_bActive = false; 00059 m_bCustomPaint = false; 00060 00061 connect(kapp, SIGNAL(backgroundChanged(int)), SLOT(slotBackgroundChanged(int))); 00062 connect(m_pPixmap, SIGNAL(done(bool)), SLOT(slotDone(bool))); 00063 connect(m_pTimer, SIGNAL(timeout()), SLOT(repaint())); 00064 00065 d->kwin = new KWinModule( this ); 00066 connect( d->kwin, SIGNAL(currentDesktopChanged(int)), SLOT(desktopChanged(int)) ); 00067 00068 d->toplevel = m_pWidget->topLevelWidget(); 00069 d->toplevel->installEventFilter(this); 00070 m_pWidget->installEventFilter(this); 00071 } 00072 00073 KRootPixmap::~KRootPixmap() 00074 { 00075 delete m_pPixmap; 00076 delete d; 00077 } 00078 00079 00080 int KRootPixmap::currentDesktop() const 00081 { 00082 NETRootInfo rinfo( qt_xdisplay(), NET::CurrentDesktop ); 00083 rinfo.activate(); 00084 return rinfo.currentDesktop(); 00085 } 00086 00087 00088 void KRootPixmap::start() 00089 { 00090 if (m_bActive) 00091 return; 00092 00093 m_bActive = true; 00094 if ( !isAvailable() ) 00095 { 00096 // We will get a KIPC message when the shared pixmap is available. 00097 enableExports(); 00098 return; 00099 } 00100 if (m_bInit) 00101 repaint(true); 00102 } 00103 00104 00105 void KRootPixmap::stop() 00106 { 00107 m_bActive = false; 00108 m_pTimer->stop(); 00109 } 00110 00111 00112 void KRootPixmap::setFadeEffect(double fade, const QColor &color) 00113 { 00114 if (fade < 0) 00115 m_Fade = 0; 00116 else if (fade > 1) 00117 m_Fade = 1; 00118 else 00119 m_Fade = fade; 00120 m_FadeColor = color; 00121 00122 if ( m_bActive && m_bInit ) repaint(true); 00123 } 00124 00125 00126 bool KRootPixmap::eventFilter(QObject *, QEvent *event) 00127 { 00128 // Initialise after the first show or paint event on the managed widget. 00129 if (!m_bInit && ((event->type() == QEvent::Show) || (event->type() == QEvent::Paint))) 00130 { 00131 m_bInit = true; 00132 m_Desk = currentDesktop(); 00133 } 00134 00135 if (!m_bActive) 00136 return false; 00137 00138 switch (event->type()) 00139 { 00140 case QEvent::Resize: 00141 case QEvent::Move: 00142 m_pTimer->start(100, true); 00143 break; 00144 00145 case QEvent::Paint: 00146 m_pTimer->start(0, true); 00147 break; 00148 00149 case QEvent::Reparent: 00150 d->toplevel->removeEventFilter(this); 00151 d->toplevel = m_pWidget->topLevelWidget(); 00152 d->toplevel->installEventFilter(this); 00153 break; 00154 00155 default: 00156 break; 00157 } 00158 00159 return false; // always continue processing 00160 } 00161 00162 void KRootPixmap::desktopChanged( int desk ) 00163 { 00164 if( !m_pWidget->isVisible()) 00165 return; // not visible, no need to update 00166 QWidget* widget = m_pWidget->topLevelWidget(); 00167 if( !widget->testWFlags( WX11BypassWM ) 00168 && !KWin::windowInfo( widget->winId(), NET::WMDesktop ).isOnCurrentDesktop()) 00169 return; // not on current desktop -> not visible, no need to update 00170 repaint(true); 00171 } 00172 00173 void KRootPixmap::repaint() 00174 { 00175 repaint(false); 00176 } 00177 00178 00179 void KRootPixmap::repaint(bool force) 00180 { 00181 QPoint p1 = m_pWidget->mapToGlobal(m_pWidget->rect().topLeft()); 00182 QPoint p2 = m_pWidget->mapToGlobal(m_pWidget->rect().bottomRight()); 00183 if (!force && (m_Rect == QRect(p1, p2))) 00184 return; 00185 00186 // Due to northwest bit gravity, we don't need to do anything if the 00187 // bottom right corner of the widget is moved inward. 00188 // That said, konsole clears the background when it is resized, so 00189 // we have to reset the background pixmap. 00190 if ((p1 == m_Rect.topLeft()) && (m_pWidget->width() < m_Rect.width()) && 00191 (m_pWidget->height() < m_Rect.height()) 00192 ) 00193 { 00194 m_Rect = QRect(p1, p2); 00195 updateBackground( m_pPixmap ); 00196 return; 00197 } 00198 m_Rect = QRect(p1, p2); 00199 m_Desk = currentDesktop(); 00200 00201 // KSharedPixmap will correctly generate a tile for us. 00202 m_pPixmap->loadFromShared(pixmapName(m_Desk), m_Rect); 00203 } 00204 00205 bool KRootPixmap::isAvailable() const 00206 { 00207 return m_pPixmap->isAvailable(pixmapName(m_Desk)); 00208 } 00209 00210 QString KRootPixmap::pixmapName(int desk) { 00211 QString pattern = QString("DESKTOP%1"); 00212 int screen_number = DefaultScreen(qt_xdisplay()); 00213 if (screen_number) { 00214 pattern = QString("SCREEN%1-DESKTOP").arg(screen_number) + "%1"; 00215 } 00216 return pattern.arg( desk ); 00217 } 00218 00219 00220 void KRootPixmap::enableExports() 00221 { 00222 kdDebug(270) << k_lineinfo << "activating background exports.\n"; 00223 DCOPClient *client = kapp->dcopClient(); 00224 if (!client->isAttached()) 00225 client->attach(); 00226 QByteArray data; 00227 QDataStream args( data, IO_WriteOnly ); 00228 args << 1; 00229 00230 QCString appname( "kdesktop" ); 00231 int screen_number = DefaultScreen(qt_xdisplay()); 00232 if ( screen_number ) 00233 appname.sprintf("kdesktop-screen-%d", screen_number ); 00234 00235 client->send( appname, "KBackgroundIface", "setExport(int)", data ); 00236 } 00237 00238 00239 void KRootPixmap::slotDone(bool success) 00240 { 00241 if (!success) 00242 { 00243 kdWarning(270) << k_lineinfo << "loading of desktop background failed.\n"; 00244 return; 00245 } 00246 00247 // We need to test active as the pixmap might become available 00248 // after the widget has been destroyed. 00249 if ( m_bActive ) 00250 updateBackground( m_pPixmap ); 00251 } 00252 00253 void KRootPixmap::updateBackground( KSharedPixmap *spm ) 00254 { 00255 QPixmap pm = *spm; 00256 00257 if (m_Fade > 1e-6) 00258 { 00259 KPixmapIO io; 00260 QImage img = io.convertToImage(pm); 00261 img = KImageEffect::fade(img, m_Fade, m_FadeColor); 00262 pm = io.convertToPixmap(img); 00263 } 00264 00265 if ( !m_bCustomPaint ) 00266 m_pWidget->setBackgroundPixmap( pm ); 00267 else { 00268 emit backgroundUpdated( pm ); 00269 } 00270 } 00271 00272 00273 void KRootPixmap::slotBackgroundChanged(int desk) 00274 { 00275 if (!m_bInit || !m_bActive) 00276 return; 00277 00278 if (desk == m_Desk) 00279 repaint(true); 00280 } 00281 00282 #include "krootpixmap.moc" 00283 #endif
KDE Logo
This file is part of the documentation for kdeui Library Version 3.2.3.
Documentation copyright © 1996-2004 the KDE developers.
Generated on Wed Mar 16 17:22:02 2005 by doxygen 1.3.7 written by Dimitri van Heesch, © 1997-2003