[prev in list] [next in list] [prev in thread] [next in thread] 

List:       kde-commits
Subject:    KDE/kdegraphics/ksnapshot
From:       Martin Gräßlin <kde () martin-graesslin ! com>
Date:       2010-09-14 19:56:28
Message-ID: 20100914200123.C499FAC871 () svn ! kde ! org
[Download RAW message or body]

SVN commit 1175357 by graesslin:

KSnaphot uses KWin's new screenshot effect for grabbing windows.

This allows to capture a window including it's shadow and translucency.
The KWin effect is invoked via DBus and KWin passes a pixmap handle of
the screenshot to KSnapshot. If the screenshot effect is not available
the normal mode is used.

Thanks to Aaron for review.

Please see http://reviewboard.kde.org/r/4814/



 M  +48 -0     ksnapshot.cpp  
 M  +2 -0      ksnapshot.h  
 M  +1 -0      ksnapshotpreview.cpp  


--- trunk/KDE/kdegraphics/ksnapshot/ksnapshot.cpp #1175356:1175357
@@ -5,6 +5,7 @@
  *  Copyright (C) 2003 Nadeem Hasan <nhasan@kde.org>
  *  Copyright (C) 2004 Bernd Brandstetter <bbrand@freenet.de>
  *  Copyright (C) 2006 Urs Wolfer <uwolfer @ kde.org>
+ *  Copyright (C) 2010 Martin Gräßlin <kde@martin-graesslin.com>
  *
  *  This program is free software; you can redistribute it and/or modify
  *  it under the terms of the GNU Lesser General Public License as published by
@@ -29,6 +30,10 @@
 #include <QMenu>
 #include <QDesktopWidget>
 #include <QVarLengthArray>
+#include <QtCore/QXmlStreamReader>
+#include <QtDBus/QDBusConnection>
+#include <QtDBus/QDBusConnectionInterface>
+#include <QtDBus/QDBusInterface>
 
 #include <klocale.h>
 
@@ -138,6 +143,26 @@
 #endif
     setIncludePointer(conf.readEntry("includePointer", false));
 
+    // check if kwin screenshot effect is available
+    includeAlpha = false;
+    if ( QDBusConnection::sessionBus().interface()->isServiceRegistered( "org.kde.kwin" ) ) {
+        QDBusInterface kwinInterface( "org.kde.kwin", "/", "org.freedesktop.DBus.Introspectable" );
+        QDBusReply<QString> reply = kwinInterface.call( "Introspect" );
+        if ( reply.isValid() ) {
+            QXmlStreamReader xml( reply.value() );
+            while ( !xml.atEnd() ) {
+                xml.readNext();
+                if ( xml.tokenType() == QXmlStreamReader::StartElement &&
+                    xml.name().toString() == "node" ) {
+                    if ( xml.attributes().value( "name" ).toString() == "Screenshot" ) {
+                        includeAlpha = true;
+                        break;
+                    }
+                }
+            }
+        }
+    }
+
     kDebug() << "Mode = " << mode;
     if ( mode == KSnapshotObject::FullScreen ) {
         snapshot = QPixmap::grabWindow( QApplication::desktop()->winId() );
@@ -466,6 +491,11 @@
     show();
 }
 
+void KSnapshot::slotScreenshotReceived( qulonglong handle )
+{
+    slotWindowGrabbed( QPixmap::fromX11Pixmap( handle ) );
+}
+
 void KSnapshot::closeEvent( QCloseEvent * e )
 {
     KConfigGroup conf(KGlobal::config(), "GENERAL");
@@ -544,6 +574,23 @@
         qDebug() << "last window position is" << offset;
     }
     else if ( mode() == WindowUnderCursor ) {
+        if ( includeAlpha ) {
+            // use kwin effect
+            QDBusConnection::sessionBus().connect("org.kde.kwin", "/Screenshot",
+                                                  "org.kde.kwin.Screenshot", "screenshotCreated",
+                                                  this, SLOT(slotScreenshotReceived(qulonglong)));
+            QDBusInterface interface( "org.kde.kwin", "/Screenshot", "org.kde.kwin.Screenshot" );
+            int mask = 0;
+            if ( includeDecorations() )
+            {
+                mask |= 1 << 0;
+            }
+            if ( includePointer() )
+            {
+                mask |= 1 << 1;
+            }
+            interface.call( "screenshotWindowUnderCursor", mask );
+        } else {
         snapshot = WindowGrabber::grabCurrent( includeDecorations() );
 
         QPoint offset = WindowGrabber::lastWindowPosition();
@@ -557,6 +604,7 @@
             windowClass = WindowGrabber::lastWindowClass();
         }
     }
+    }
     else if ( mode() == CurrentScreen ) {
         kDebug() << "Desktop Geom2 = " << QApplication::desktop()->geometry();
         QDesktopWidget *desktop = QApplication::desktop();
--- trunk/KDE/kdegraphics/ksnapshot/ksnapshot.h #1175356:1175357
@@ -116,6 +116,7 @@
     int previewWidth() const;
     int previewHeight() const;
     void startUndelayedGrab();
+    void slotScreenshotReceived(qulonglong handle);
 
 public:
     int grabMode() const;
@@ -134,6 +135,7 @@
     bool modified;
     QPoint savedPosition;
     bool haveXFixes;
+    bool includeAlpha;
 };
 
 #endif // KSNAPSHOT_H
--- trunk/KDE/kdegraphics/ksnapshot/ksnapshotpreview.cpp #1175356:1175357
@@ -66,6 +66,7 @@
         QPainter p(&blur);
         p.setCompositionMode(QPainter::CompositionMode_SourceIn);
         p.fillRect(blur.rect(), color);
+        p.fillRect(QRect(blurRect.topLeft(), pixmap.size()), Qt::transparent);
         p.setCompositionMode(QPainter::CompositionMode_SourceOver);
         p.drawPixmap(QRect(blurRect.topLeft(), pixmap.size()), pixmap);
         p.end();
[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic