on xenial help sign in
Refactor screenshotting code and make it work in multimonitor scenarios

+ Implement snapshotting the focused window with Alt+PrtScn + Workaround bug in QWindow regarding visibility when moving between screens

commite407b3c836bf923e1f1ce8d1d6ed6b411a81d107 authorDaniel d'Andrada <daniel.dandrada@canonical.com> dateThu 28 Apr 2016, 09:06 (10 years ago) parent7c4428e
22 files changed+166−326
debian/unity8-private.install+1−1 plugins/CMakeLists.txt+1−1 plugins/ScreenGrabber/CMakeLists.txt−13 plugins/ScreenGrabber/qmldir−3 plugins/ScreenGrabber/screengrabber.cpp−115 plugins/ScreenGrabber/screengrabber.h−49 plugins/ScreenshotDirectory/CMakeLists.txt+9 plugins/ScreenGrabber/ScreenGrabber.qmltypes → plugins/ScreenshotDirectory/ScreenGrabber.qmltypes plugins/ScreenshotDirectory/ScreenshotDirectory.cpp+64 tests/plugins/ScreenGrabber/grabber.qml → plugins/ScreenshotDirectory/ScreenshotDirectory.h+21−13 plugins/ScreenGrabber/plugin.cpp → plugins/ScreenshotDirectory/plugin.cpp+5−7 plugins/ScreenGrabber/plugin.h → plugins/ScreenshotDirectory/plugin.h+5−7 plugins/ScreenshotDirectory/qmldir+2 qml/Components/ScreenGrabber.qml → qml/Components/ItemGrabber.qml+27−17 qml/Components/NotificationAudio.qml+7−3 qml/Shell.qml+11−5 qml/Stages/AbstractStage.qml+1 qml/Stages/DesktopStage.qml+6 src/ShellApplication.cpp+6 tests/plugins/CMakeLists.txt−1 tests/plugins/ScreenGrabber/CMakeLists.txt−14 tests/plugins/ScreenGrabber/ScreenGrabberTest.cpp−77
debian/unity8-private.install+1−1
@@ -8,7 +8,7 @@ usr/lib/*/unity8/qml/Greeter
88usr/lib/*/unity8/qml/IntegratedLightDM
99usr/lib/*/unity8/qml/Lights
1010usr/lib/*/unity8/qml/Powerd
11−usr/lib/*/unity8/qml/ScreenGrabber
11+usr/lib/*/unity8/qml/ScreenshotDirectory
1212usr/lib/*/unity8/qml/SessionBroadcast
1313usr/lib/*/unity8/qml/Ubuntu
1414usr/lib/*/unity8/qml/Unity
plugins/CMakeLists.txt+1−1
@@ -19,8 +19,8 @@ add_subdirectory(IntegratedLightDM)
1919add_subdirectory(Lights)
2020add_subdirectory(Dash)
2121add_subdirectory(Powerd)
22+add_subdirectory(ScreenshotDirectory)
2223add_subdirectory(SessionBroadcast)
23−add_subdirectory(ScreenGrabber)
2424add_subdirectory(Ubuntu)
2525add_subdirectory(UInput)
2626add_subdirectory(Unity)
plugins/ScreenGrabber/CMakeLists.txtdeleted−13
@@ -1,13 +0,0 @@
1−include_directories(
2− ${CMAKE_CURRENT_BINARY_DIR}
3−)
4−
5−set(SCREENGRABBERSOURCES
6− screengrabber.cpp
7− plugin.cpp
8−)
9−
10−add_library(ScreenGrabber-qml MODULE ${SCREENGRABBERSOURCES})
11−qt5_use_modules(ScreenGrabber-qml Qml Gui Quick Concurrent)
12−
13−add_unity8_plugin(ScreenGrabber 0.1 ScreenGrabber TARGETS ScreenGrabber-qml)
plugins/ScreenGrabber/qmldirdeleted−3
@@ -1,3 +0,0 @@
1−module ScreenGrabber
2−plugin ScreenGrabber-qml
3−typeinfo ScreenGrabber.qmltypes
plugins/ScreenGrabber/screengrabber.cppdeleted−115
@@ -1,115 +0,0 @@
1−/*
2− * Copyright (C) 2014-2015 Canonical, Ltd.
3− *
4− * This program is free software; you can redistribute it and/or modify
5− * it under the terms of the GNU General Public License as published by
6− * the Free Software Foundation; version 3.
7− *
8− * This program is distributed in the hope that it will be useful,
9− * but WITHOUT ANY WARRANTY; without even the implied warranty of
10− * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11− * GNU General Public License for more details.
12− *
13− * You should have received a copy of the GNU General Public License
14− * along with this program. If not, see <http://www.gnu.org/licenses/>.
15− */
16−
17−#include "screengrabber.h"
18−
19−#include <QDir>
20−#include <QDateTime>
21−#include <QStandardPaths>
22−#include <QTemporaryDir>
23−#include <QtGui/QImage>
24−#include <QtGui/QGuiApplication>
25−#include <QtQuick/QQuickWindow>
26−
27−#include <QDebug>
28−
29−QString saveScreenshot(const QImage &screenshot, const QString &filename, const QString &format, int quality)
30−{
31− if (screenshot.save(filename, format.toLatin1().data(), quality)) {
32− return filename;
33− } else {
34− qWarning() << "ScreenGrabber: failed to save snapshot!";
35− }
36− return QString();
37−}
38−
39−ScreenGrabber::ScreenGrabber(QObject *parent)
40− : QObject(parent)
41−{
42− QObject::connect(&m_watcher,
43− &QFutureWatcher<QString>::finished,
44− this,
45− &ScreenGrabber::onScreenshotSaved);
46−
47− QDir screenshotsDir;
48− if (qEnvironmentVariableIsSet("UNITY_TESTING")) {
49− QTemporaryDir tDir;
50− tDir.setAutoRemove(false);
51− screenshotsDir = tDir.path();
52− } else {
53− screenshotsDir = QStandardPaths::writableLocation(QStandardPaths::PicturesLocation);
54− }
55− screenshotsDir.mkpath(QStringLiteral("Screenshots"));
56− screenshotsDir.cd(QStringLiteral("Screenshots"));
57− if (screenshotsDir.exists()) {
58− fileNamePrefix = screenshotsDir.absolutePath();
59− fileNamePrefix.append("/screenshot");
60− } else {
61− qWarning() << "ScreenGrabber: failed to create directory at: " << screenshotsDir.absolutePath();
62− }
63−}
64−
65−void ScreenGrabber::captureAndSave(int angle)
66−{
67− if (fileNamePrefix.isEmpty())
68− {
69− qWarning() << "ScreenShotter: no directory to save screenshot";
70− return;
71− }
72−
73− const QWindowList windows = QGuiApplication::topLevelWindows();
74− if (windows.empty())
75− {
76− qWarning() << "ScreenShotter: no top level windows found!";
77− return;
78− }
79−
80− QQuickWindow *main_window = qobject_cast<QQuickWindow *>(windows[0]);
81− if (!main_window)
82− {
83− qWarning() << "ScreenShotter: can only take screenshots of QQuickWindows";
84− return;
85− }
86−
87− const QImage screenshot = main_window->grabWindow().transformed(QTransform().rotate(angle));
88− const QString filename = makeFileName();
89− qDebug() << "Saving screenshot to" << filename;
90− QFuture<QString> saveFuture(QtConcurrent::run(saveScreenshot, screenshot, filename, getFormat(), screenshotQuality));
91− m_watcher.setFuture(saveFuture);
92−}
93−
94−void ScreenGrabber::onScreenshotSaved()
95−{
96− const QString filename = m_watcher.future().result();
97− if (!filename.isEmpty()) {
98− Q_EMIT screenshotSaved(filename);
99− }
100−}
101−
102−QString ScreenGrabber::makeFileName() const
103−{
104− QString fileName(fileNamePrefix);
105− fileName.append(QDateTime::currentDateTime().toString(QStringLiteral("yyyyMMdd_hhmmsszzz")));
106− fileName.append(".");
107− fileName.append(getFormat());
108− return fileName;
109−}
110−
111−QString ScreenGrabber::getFormat() const
112−{
113− //TODO: This should be configurable (perhaps through gsettings?)
114− return QStringLiteral("png");
115−}
plugins/ScreenGrabber/screengrabber.hdeleted−49
@@ -1,49 +0,0 @@
1−/*
2− * Copyright (C) 2014-2015 Canonical, Ltd.
3− *
4− * This program is free software; you can redistribute it and/or modify
5− * it under the terms of the GNU General Public License as published by
6− * the Free Software Foundation; version 3.
7− *
8− * This program is distributed in the hope that it will be useful,
9− * but WITHOUT ANY WARRANTY; without even the implied warranty of
10− * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11− * GNU General Public License for more details.
12− *
13− * You should have received a copy of the GNU General Public License
14− * along with this program. If not, see <http://www.gnu.org/licenses/>.
15− */
16−
17−#ifndef SNAPSHOTTER_H
18−#define SNAPSHOTTER_H
19−
20−#include <QObject>
21−#include <QString>
22−#include <QtConcurrent>
23−
24−class ScreenGrabber: public QObject
25−{
26− Q_OBJECT
27−
28−public:
29− explicit ScreenGrabber(QObject *parent = 0);
30− ~ScreenGrabber() = default;
31−
32−public Q_SLOTS:
33− void captureAndSave(int angle = 0);
34−
35−Q_SIGNALS:
36− void screenshotSaved(const QString &filename);
37−
38−private Q_SLOTS:
39− void onScreenshotSaved();
40−
41−private:
42− QString makeFileName() const;
43− QString getFormat() const;
44− QString fileNamePrefix;
45− int screenshotQuality = -1; // default quality for the format
46− QFutureWatcher<QString> m_watcher;
47−};
48−
49−#endif
plugins/ScreenshotDirectory/CMakeLists.txtnew file+9
@@ -0,0 +1,9 @@
1+set(PLUGIN_SOURCES
2+ ScreenshotDirectory.cpp
3+ plugin.cpp
4+)
5+
6+add_library(ScreenshotDirectory-qml MODULE ${PLUGIN_SOURCES})
7+qt5_use_modules(ScreenshotDirectory-qml Qml Gui Quick)
8+
9+add_unity8_plugin(ScreenshotDirectory 0.1 ScreenshotDirectory TARGETS ScreenshotDirectory-qml)
plugins/ScreenGrabber/ScreenGrabber.qmltypes → plugins/ScreenshotDirectory/ScreenGrabber.qmltypesrenamed

The content is the same.

plugins/ScreenshotDirectory/ScreenshotDirectory.cppnew file+64
@@ -0,0 +1,64 @@
1+/*
2+ * Copyright (C) 2014-2016 Canonical, Ltd.
3+ *
4+ * This program is free software; you can redistribute it and/or modify
5+ * it under the terms of the GNU General Public License as published by
6+ * the Free Software Foundation; version 3.
7+ *
8+ * This program is distributed in the hope that it will be useful,
9+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+ * GNU General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU General Public License
14+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
15+ */
16+
17+#include "ScreenshotDirectory.h"
18+
19+#include <QDir>
20+#include <QDateTime>
21+#include <QStandardPaths>
22+#include <QTemporaryDir>
23+
24+#include <QDebug>
25+
26+ScreenshotDirectory::ScreenshotDirectory(QObject *parent)
27+ : QObject(parent)
28+{
29+ QDir screenshotsDir;
30+ if (qEnvironmentVariableIsSet("UNITY_TESTING")) {
31+ QTemporaryDir tDir;
32+ tDir.setAutoRemove(false);
33+ screenshotsDir = tDir.path();
34+ } else {
35+ screenshotsDir = QStandardPaths::writableLocation(QStandardPaths::PicturesLocation);
36+ }
37+ screenshotsDir.mkpath(QStringLiteral("Screenshots"));
38+ screenshotsDir.cd(QStringLiteral("Screenshots"));
39+ if (screenshotsDir.exists()) {
40+ m_fileNamePrefix = screenshotsDir.absolutePath();
41+ m_fileNamePrefix.append("/screenshot");
42+ } else {
43+ qWarning() << "ScreenshotDirectory: failed to create directory at:" << screenshotsDir.absolutePath();
44+ }
45+}
46+
47+QString ScreenshotDirectory::makeFileName() const
48+{
49+ if (m_fileNamePrefix.isEmpty()) {
50+ return QString();
51+ }
52+
53+ QString fileName(m_fileNamePrefix);
54+ fileName.append(QDateTime::currentDateTime().toString(QStringLiteral("yyyyMMdd_hhmmsszzz")));
55+ fileName.append(".");
56+ fileName.append(format());
57+ return fileName;
58+}
59+
60+QString ScreenshotDirectory::format() const
61+{
62+ //TODO: This should be configurable (perhaps through gsettings?)
63+ return QStringLiteral("png");
64+}
tests/plugins/ScreenGrabber/grabber.qml → plugins/ScreenshotDirectory/ScreenshotDirectory.hrenamed+21−13
@@ -1,5 +1,5 @@
11/*
2− * Copyright 2015 Canonical Ltd.
2+ * Copyright (C) 2014-2016 Canonical, Ltd.
33 *
44 * This program is free software; you can redistribute it and/or modify
55 * it under the terms of the GNU General Public License as published by
@@ -14,18 +14,26 @@
1414 * along with this program. If not, see <http://www.gnu.org/licenses/>.
1515 */
1616
17−import QtQuick 2.4
18−import ScreenGrabber 0.1
17+#ifndef SCREENSHOTDIRECTORY_H
18+#define SCREENSHOTDIRECTORY_H
1919
20−Rectangle {
21− property var grabber: screenGrabber
20+#include <QObject>
21+#include <QString>
2222
23− width: 101 // width intentionally bigger than height to test rotation
24− height: 100
25− color: "green"
23+class ScreenshotDirectory: public QObject
24+{
25+ Q_OBJECT
2626
27− ScreenGrabber {
28− id: screenGrabber
29− objectName: "screenGrabber"
30− }
31−}
27+public:
28+ explicit ScreenshotDirectory(QObject *parent = 0);
29+ ~ScreenshotDirectory() = default;
30+
31+public Q_SLOTS:
32+ QString makeFileName() const;
33+
34+private:
35+ QString format() const;
36+ QString m_fileNamePrefix;
37+};
38+
39+#endif // SCREENSHOTDIRECTORY_H
plugins/ScreenGrabber/plugin.cpp → plugins/ScreenshotDirectory/plugin.cpprenamed+5−7
@@ -1,5 +1,5 @@
11/*
2− * Copyright (C) 2014 Canonical, Ltd.
2+ * Copyright (C) 2014,2016 Canonical, Ltd.
33 *
44 * This program is free software; you can redistribute it and/or modify
55 * it under the terms of the GNU General Public License as published by
@@ -12,17 +12,15 @@
1212 *
1313 * You should have received a copy of the GNU General Public License
1414 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15− *
16− * Authors: Alberto Aguirre <alberto.aguirre@canonical.com>
1715 */
1816
1917#include "plugin.h"
20−#include "screengrabber.h"
18+#include "ScreenshotDirectory.h"
2119
2220#include <QtQml/qqml.h>
2321
24−void ScreenGrabberPlugin::registerTypes(const char *uri)
22+void ScreenshotDirectoryPlugin::registerTypes(const char *uri)
2523{
26− Q_ASSERT(uri == QLatin1String("ScreenGrabber"));
27− qmlRegisterType<ScreenGrabber>(uri, 0, 1, "ScreenGrabber");
24+ Q_ASSERT(uri == QLatin1String("ScreenshotDirectory"));
25+ qmlRegisterType<ScreenshotDirectory>(uri, 0, 1, "ScreenshotDirectory");
2826}
plugins/ScreenGrabber/plugin.h → plugins/ScreenshotDirectory/plugin.hrenamed+5−7
@@ -1,5 +1,5 @@
11/*
2− * Copyright (C) 2014 Canonical, Ltd.
2+ * Copyright (C) 2014,2016 Canonical, Ltd.
33 *
44 * This program is free software; you can redistribute it and/or modify
55 * it under the terms of the GNU General Public License as published by
@@ -12,16 +12,14 @@
1212 *
1313 * You should have received a copy of the GNU General Public License
1414 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15− *
16− * Authors: Alberto Aguirre <alberto.aguirre@canonical.com>
1715 */
1816
19−#ifndef SCREENGRABBER_PLUGIN_H
20−#define SCREENGRABBER_PLUGIN_H
17+#ifndef SCREENSHOTDIRECTORY_PLUGIN_H
18+#define SCREENSHOTDIRECTORY_PLUGIN_H
2119
2220#include <QtQml/QQmlExtensionPlugin>
2321
24−class ScreenGrabberPlugin : public QQmlExtensionPlugin
22+class ScreenshotDirectoryPlugin : public QQmlExtensionPlugin
2523{
2624 Q_OBJECT
2725 Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QQmlExtensionInterface")
@@ -30,4 +28,4 @@ public:
3028 void registerTypes(const char *uri) override;
3129};
3230
33−#endif // SCREENGRABBER_PLUGIN_H
31+#endif // SCREENSHOTDIRECTORY_PLUGIN_H
plugins/ScreenshotDirectory/qmldirnew file+2
@@ -0,0 +1,2 @@
1+module ScreenshotDirectory
2+plugin ScreenshotDirectory-qml
qml/Components/ScreenGrabber.qml → qml/Components/ItemGrabber.qmlrenamed+27−17
@@ -1,5 +1,5 @@
11/*
2− * Copyright (C) 2014-2015 Canonical, Ltd.
2+ * Copyright (C) 2014-2016 Canonical, Ltd.
33 *
44 * This program is free software; you can redistribute it and/or modify
55 * it under the terms of the GNU General Public License as published by
@@ -15,36 +15,31 @@
1515 */
1616
1717import QtQuick 2.4
18−import ScreenGrabber 0.1
19−import GlobalShortcut 1.0
18+import ScreenshotDirectory 0.1
2019
20+/*
21+ Captures an image of the given item and saves it in a screenshots directory.
22+ It also displays a flash visual effect and camera shutter sound, as feedback
23+ to the user to hint that a screenshot was taken.
24+ */
2125Rectangle {
2226 id: root
2327 visible: false
2428 color: "white"
25− anchors.fill: parent
2629 opacity: 0.0
2730
28− // to be set from outside
29− property int rotationAngle: 0
30−
31− ScreenGrabber {
32− id: screenGrabber
31+ ScreenshotDirectory {
32+ id: screenshotDirectory
3333 objectName: "screenGrabber"
3434 }
3535
36− GlobalShortcut {
37− id: screenshotShortcut
38− shortcut: Qt.Key_Print
39− onTriggered: capture()
40− }
41−
4236 NotificationAudio {
4337 id: shutterSound
4438 source: "/system/media/audio/ui/camera_click.ogg"
4539 }
4640
47− function capture() {
41+ function capture(item) {
42+ d.target = item;
4843 visible = true;
4944 shutterSound.stop();
5045 shutterSound.play();
@@ -62,13 +57,28 @@ Rectangle {
6257 }
6358 }
6459
60+ QtObject {
61+ id: d
62+ property Item target
63+ }
64+
6565 NumberAnimation on opacity {
6666 id: fadeOut
6767 from: 1.0
6868 to: 0.0
6969 onStopped: {
7070 if (visible) {
71− screenGrabber.captureAndSave(root.rotationAngle);
71+ d.target.grabToImage(function(result)
72+ {
73+ var fileName = screenshotDirectory.makeFileName();
74+ if (fileName.length === 0) {
75+ console.warn("ItemGrabber: No fileName to save image to");
76+ } else {
77+ console.log("ItemGrabber: Saving image to " + fileName);
78+ result.saveToFile(fileName);
79+ }
80+ });
81+
7282 visible = false;
7383 }
7484 }
qml/Components/NotificationAudio.qml+7−3
@@ -1,5 +1,5 @@
11/*
2− * Copyright (C) 2015 Canonical, Ltd.
2+ * Copyright (C) 2015-2016 Canonical, Ltd.
33 *
44 * This program is free software; you can redistribute it and/or modify
55 * it under the terms of the GNU General Public License as published by
@@ -22,10 +22,14 @@ Item {
2222 readonly property var playbackState: priv.audio ? priv.audio.playbackState : 0
2323
2424 function play() {
25− priv.audio.play();
25+ if (priv.audio) {
26+ priv.audio.play();
27+ }
2628 }
2729 function stop() {
28− priv.audio.stop();
30+ if (priv.audio) {
31+ priv.audio.stop();
32+ }
2933 }
3034
3135 QtObject {
qml/Shell.qml+11−5
@@ -193,7 +193,7 @@ Item {
193193 onPowerKeyLongPressed: dialogs.showPowerDialog();
194194 onVolumeDownTriggered: volumeControl.volumeDown();
195195 onVolumeUpTriggered: volumeControl.volumeUp();
196− onScreenshotTriggered: screenGrabber.capture();
196+ onScreenshotTriggered: itemGrabber.capture(shell);
197197 }
198198
199199 GlobalShortcut {
@@ -706,16 +706,22 @@ Item {
706706 onShowHome: showHome()
707707 }
708708
709− ScreenGrabber {
710− id: screenGrabber
711− rotationAngle: -shell.orientationAngle
709+ ItemGrabber {
710+ id: itemGrabber
711+ anchors.fill: parent
712712 z: dialogs.z + 10
713+ GlobalShortcut { shortcut: Qt.Key_Print; onTriggered: itemGrabber.capture(shell) }
714+ Connections {
715+ target: applicationsDisplayLoader.item
716+ ignoreUnknownSignals: true
717+ onItemSnapshotRequested: itemGrabber.capture(item)
718+ }
713719 }
714720
715721 Cursor {
716722 id: cursor
717723 visible: shell.hasMouse
718− z: screenGrabber.z + 1
724+ z: itemGrabber.z + 1
719725
720726 onPushedLeftBoundary: {
721727 if (buttons === Qt.NoButton) {
qml/Stages/AbstractStage.qml+1
@@ -60,6 +60,7 @@ FocusScope {
6060 | Qt.InvertedLandscapeOrientation
6161
6262 signal stageAboutToBeUnloaded
63+ signal itemSnapshotRequested(Item item)
6364
6465 // Shared code for use in stage implementations
6566 GSettings {
qml/Stages/DesktopStage.qml+6
@@ -94,6 +94,12 @@ AbstractStage {
9494 active: priv.focusedAppDelegate !== null
9595 }
9696
97+ GlobalShortcut {
98+ shortcut: Qt.ControlModifier|Qt.Key_Print
99+ onTriggered: root.itemSnapshotRequested(priv.focusedAppDelegate)
100+ active: priv.focusedAppDelegate !== null
101+ }
102+
97103 Connections {
98104 target: root.topLevelSurfaceList
99105 onCountChanged: {
src/ShellApplication.cpp+6
@@ -168,6 +168,9 @@ void ShellApplication::onScreenAdded(QScreen * /*screen*/)
168168 // Changing the QScreen where a QWindow is drawn makes it also lose focus (besides having
169169 // its backing QPlatformWindow recreated). So lets refocus it.
170170 m_shellView->requestActivate();
171+ // QWindow::destroy() is called when it changes between screens. We have to manually make it visible again
172+ // <dandrader> This bug is supposedly fixed in Qt 5.5.1, although I can still reproduce it there. :-/
173+ m_shellView->setVisible(true);
171174
172175 m_secondaryWindow = new SecondaryWindow(m_qmlEngine);
173176 m_secondaryWindow->setScreen(screens().at(0));
@@ -194,5 +197,8 @@ void ShellApplication::onScreenAboutToBeRemoved(QScreen *screen)
194197 // Changing the QScreen where a QWindow is drawn makes it also lose focus (besides having
195198 // its backing QPlatformWindow recreated). So lets refocus it.
196199 m_shellView->requestActivate();
200+ // QWindow::destroy() is called when it changes between screens. We have to manually make it visible again
201+ // <dandrader> This bug is supposedly fixed in Qt 5.5.1, although I can still reproduce it there. :-/
202+ m_shellView->setVisible(true);
197203 }
198204}
tests/plugins/CMakeLists.txt−1
@@ -3,7 +3,6 @@ add_subdirectory(GlobalShortcut)
33add_subdirectory(Greeter)
44add_subdirectory(IntegratedLightDM)
55add_subdirectory(Dash)
6−add_subdirectory(ScreenGrabber)
76add_subdirectory(Ubuntu)
87add_subdirectory(Unity)
98add_subdirectory(Utils)
tests/plugins/ScreenGrabber/CMakeLists.txtdeleted−14
@@ -1,14 +0,0 @@
1−include_directories(
2− ${CMAKE_SOURCE_DIR}/plugins/ScreenGrabber
3− ${CMAKE_CURRENT_BINARY_DIR}
4− )
5−
6−add_definitions(
7− -DCURRENT_SOURCE_DIR="${CMAKE_CURRENT_SOURCE_DIR}"
8− )
9−add_definitions(-DBUILT_PLUGINS_DIR="${CMAKE_BINARY_DIR}/plugins")
10−
11−add_executable(ScreenGrabberTestExec ScreenGrabberTest.cpp ${CMAKE_SOURCE_DIR}/plugins/ScreenGrabber/screengrabber.cpp)
12−qt5_use_modules(ScreenGrabberTestExec Test Quick Concurrent)
13−target_link_libraries(ScreenGrabberTestExec ${Qt5Quick_LIBRARIES} ScreenGrabber-qml)
14−add_unity8_uitest(ScreenGrabber ScreenGrabberTestExec DEPENDS ScreenGrabber-qml)
tests/plugins/ScreenGrabber/ScreenGrabberTest.cppdeleted−77
@@ -1,77 +0,0 @@
1−/*
2− * Copyright (C) 2015 Canonical, Ltd.
3− *
4− * This program is free software; you can redistribute it and/or modify
5− * it under the terms of the GNU General Public License as published by
6− * the Free Software Foundation; version 3.
7− *
8− * This program is distributed in the hope that it will be useful,
9− * but WITHOUT ANY WARRANTY; without even the implied warranty of
10− * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11− * GNU General Public License for more details.
12− *
13− * You should have received a copy of the GNU General Public License
14− * along with this program. If not, see <http://www.gnu.org/licenses/>.
15− */
16−
17−#include "screengrabber.h"
18−
19−#include <QtTest>
20−#include <QtQuick/QQuickView>
21−#include <QtQuick/QQuickItem>
22−#include <QQmlEngine>
23−
24−class ScreenGrabberTest: public QObject
25−{
26− Q_OBJECT
27−
28−private Q_SLOTS:
29−
30− void initTestCase()
31− {
32− m_view = new QQuickView();
33− m_view->engine()->addImportPath(BUILT_PLUGINS_DIR);
34− m_view->setSource(QUrl::fromLocalFile(CURRENT_SOURCE_DIR "/grabber.qml"));
35− m_grabber = dynamic_cast<ScreenGrabber*>(m_view->rootObject()->property("grabber").value<QObject*>());
36− QVERIFY(m_grabber);
37− m_view->show();
38− QTest::qWaitForWindowExposed(m_view);
39− }
40−
41− void cleanupTestCase()
42− {
43− delete m_view;
44− m_view = nullptr;
45− QTRY_COMPARE(QThreadPool::globalInstance()->activeThreadCount(), 0);
46− }
47−
48− void testGrabScreenshot()
49− {
50− QSignalSpy grabberSpy(m_grabber, &ScreenGrabber::screenshotSaved);
51− m_grabber->captureAndSave();
52− QTRY_VERIFY(grabberSpy.count() == 1);
53− const QVariantList args = grabberSpy.takeFirst();
54− QVERIFY(args.count() == 1); // verify we got a non-empty filename where the screenshot has been saved
55− QVERIFY(!args.first().toString().isEmpty());
56− }
57−
58− void testRotatedScreenshot()
59− {
60− QSignalSpy grabberSpy(m_grabber, &ScreenGrabber::screenshotSaved);
61− m_grabber->captureAndSave(90); // rotate by 90°
62− QTRY_VERIFY(grabberSpy.count() == 1);
63− const QVariantList args = grabberSpy.takeFirst();
64− const QString filename = args.first().toString();
65− QVERIFY(!filename.isEmpty());
66− QImage img(filename);
67− QVERIFY(img.height() > img.width()); // verify that the image got rotated by 90° (height > width)
68− }
69−
70−private:
71− QQuickView *m_view;
72− ScreenGrabber *m_grabber = nullptr;
73−};
74−
75−QTEST_MAIN(ScreenGrabberTest)
76−
77−#include "ScreenGrabberTest.moc"