Add --raw flag

Updated dbus API. Now it sends a signal with every capture, it may
be captureFailed or a captureTaken which contains the raw image
bytes in png format. You have to add an id to the screenshot calls
so it will be returned as a way to know the origin of the signal.
This commit is contained in:
lupoDharkael
2017-11-09 18:14:04 +01:00
parent 567c99a75e
commit bb6ac04d60
16 changed files with 362 additions and 49 deletions

View File

@@ -1,35 +1,38 @@
<!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN" "http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd"> <!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN" "http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd">
<node> <node>
<interface name="org.dharkael.Flameshot"> <interface name="org.dharkael.Flameshot">
<!-- <!--
graphicCapture: graphicCapture:
@path: the path where the screenshot will be saved. When the argument is empty the program will ask for a path graphically. @path: the path where the screenshot will be saved. When the argument is empty the program will ask for a path graphically.
@delay: delay time in milliseconds. @delay: delay time in milliseconds.
@id: identificator of the call.
Open the user interface used to capture the screen. Open the user interface used to capture the screen. Sends a captureTaken signal with the raw image after closing the GUI
due to a capture taken. It could send a captureFailed signal if the screenshot cant be retrieved.
--> -->
<method name="graphicCapture"> <method name="graphicCapture">
<arg name="path" type="s" direction="in"/> <arg name="path" type="s" direction="in"/>
<arg name="delay" type="i" direction="in"/> <arg name="delay" type="i" direction="in"/>
<annotation name="org.freedesktop.DBus.Method.NoReply" value="true"/> <arg name="id" type="i" direction="in"/>
</method> </method>
<!-- <!--
fullScreen: fullScreenRaw:
@path: the path where the screenshot will be saved. When the argument is empty the program will ask for a path graphically. @path: the path where the screenshot will be saved. When the argument is empty the program will ask for a path graphically.
@toClipboard: Whether to copy the screenshot to clipboard or not. @toClipboard: Whether to copy the screenshot to clipboard or not.
@delay: delay time in milliseconds. @delay: delay time in milliseconds, both return the @id defined in the call of this method.
@id: identificator of the call.
Takes a screenshot of the whole screen. Takes a screenshot of the whole screen and sends a captureTaken signal with the raw image or a captureFailed signal.
--> -->
<method name="fullScreen"> <method name="fullScreen">
<arg name="path" type="s" direction="in"/> <arg name="path" type="s" direction="in"/>
<arg name="toClipboard" type="b" direction="in"/> <arg name="toClipboard" type="b" direction="in"/>
<arg name="delay" type="i" direction="in"/> <arg name="delay" type="i" direction="in"/>
<annotation name="org.freedesktop.DBus.Method.NoReply" value="true"/> <arg name="id" type="i" direction="in"/>
</method> </method>
<!-- <!--
openConfig: openConfig:
@@ -38,7 +41,7 @@
<method name="openConfig"> <method name="openConfig">
<annotation name="org.freedesktop.DBus.Method.NoReply" value="true"/> <annotation name="org.freedesktop.DBus.Method.NoReply" value="true"/>
</method> </method>
<!-- <!--
trayIconEnabled: trayIconEnabled:
@enabled: The new state fot the trayIcon. @enabled: The new state fot the trayIcon.
@@ -49,5 +52,27 @@
<arg name="enabled" type="b" direction="in"/> <arg name="enabled" type="b" direction="in"/>
<annotation name="org.freedesktop.DBus.Method.NoReply" value="true"/> <annotation name="org.freedesktop.DBus.Method.NoReply" value="true"/>
</method> </method>
<!--
captureTaken:
@id: identificator of the call.
@rawImage: raw image in PNG format.
Successful capture signal returning the image.
-->
<signal name="captureTaken">
<arg name="id" type="i" direction="out"/>
<arg name="rawImage" type="ay" direction="out"/>
</signal>
<!--
captureFailed:
@id: identificator of the call.
Whenever the capture fails.
-->
<signal name="captureFailed">
<arg name="id" type="i" direction="out"/>
</signal>
</interface> </interface>
</node> </node>

View File

@@ -85,7 +85,8 @@ SOURCES += src/main.cpp\
src/capture/workers/imgur/notificationwidget.cpp \ src/capture/workers/imgur/notificationwidget.cpp \
src/core/resourceexporter.cpp \ src/core/resourceexporter.cpp \
src/capture/widget/notifierbox.cpp \ src/capture/widget/notifierbox.cpp \
src/utils/desktopinfo.cpp src/utils/desktopinfo.cpp \
src/utils/dbusutils.cpp
HEADERS += \ HEADERS += \
src/capture/widget/buttonhandler.h \ src/capture/widget/buttonhandler.h \
@@ -135,7 +136,8 @@ HEADERS += \
src/capture/workers/imgur/notificationwidget.h \ src/capture/workers/imgur/notificationwidget.h \
src/core/resourceexporter.h \ src/core/resourceexporter.h \
src/capture/widget/notifierbox.h \ src/capture/widget/notifierbox.h \
src/utils/desktopinfo.h src/utils/desktopinfo.h \
src/utils/dbusutils.h
RESOURCES += \ RESOURCES += \
graphics.qrc graphics.qrc

View File

@@ -38,6 +38,7 @@
#include <QPainter> #include <QPainter>
#include <QPaintEvent> #include <QPaintEvent>
#include <QMouseEvent> #include <QMouseEvent>
#include <QBuffer>
// CaptureWidget is the main component used to capture the screen. It contains an // CaptureWidget is the main component used to capture the screen. It contains an
// are of selection with its respective buttons. // are of selection with its respective buttons.
@@ -50,11 +51,12 @@ const int HANDLE_SIZE = 9;
} // unnamed namespace } // unnamed namespace
// enableSaveWIndow // enableSaveWIndow
CaptureWidget::CaptureWidget(const QString &forcedSavePath, QWidget *parent) : CaptureWidget::CaptureWidget(const uint id, const QString &forcedSavePath,
QWidget(parent), m_mouseOverHandle(0), m_mouseIsClicked(false), QWidget *parent) :
m_rightClick(false), m_newSelection(false), m_grabbing(false), QWidget(parent), m_screenshot(nullptr), m_mouseOverHandle(0),
m_forcedSavePath(forcedSavePath), m_mouseIsClicked(false), m_rightClick(false), m_newSelection(false),
m_state(CaptureButton::TYPE_MOVESELECTION) m_grabbing(false), m_captureDone(false), m_forcedSavePath(forcedSavePath),
m_id(id), m_state(CaptureButton::TYPE_MOVESELECTION)
{ {
ConfigHandler config; ConfigHandler config;
m_showInitialMsg = config.showHelpValue(); m_showInitialMsg = config.showHelpValue();
@@ -82,7 +84,11 @@ CaptureWidget::CaptureWidget(const QString &forcedSavePath, QWidget *parent) :
initShortcuts(); initShortcuts();
// init content // init content
QPixmap fullScreenshot(ScreenGrabber().grabEntireDesktop()); bool ok = true;
QPixmap fullScreenshot(ScreenGrabber().grabEntireDesktop(ok));
if(!ok) {
this->close();
}
m_screenshot = new Screenshot(fullScreenshot, this); m_screenshot = new Screenshot(fullScreenshot, this);
QSize size = fullScreenshot.size(); QSize size = fullScreenshot.size();
// we need to increase by 1 the size to reach to the end of the screen // we need to increase by 1 the size to reach to the end of the screen
@@ -103,6 +109,14 @@ CaptureWidget::CaptureWidget(const QString &forcedSavePath, QWidget *parent) :
} }
CaptureWidget::~CaptureWidget() { CaptureWidget::~CaptureWidget() {
if (m_captureDone) {
QByteArray byteArray;
QBuffer buffer(&byteArray);
this->pixmap().save(&buffer, "PNG");
Q_EMIT captureTaken(m_id, byteArray);
} else {
Q_EMIT captureFailed(m_id);
}
ConfigHandler().setdrawThickness(m_thickness); ConfigHandler().setdrawThickness(m_thickness);
} }
@@ -577,11 +591,13 @@ QRegion CaptureWidget::handleMask() const {
} }
void CaptureWidget::copyScreenshot() { void CaptureWidget::copyScreenshot() {
m_captureDone = true;
ResourceExporter().captureToClipboard(pixmap()); ResourceExporter().captureToClipboard(pixmap());
close(); close();
} }
void CaptureWidget::saveScreenshot() { void CaptureWidget::saveScreenshot() {
m_captureDone = true;
if (m_forcedSavePath.isEmpty()) { if (m_forcedSavePath.isEmpty()) {
ResourceExporter().captureToFileUi(pixmap()); ResourceExporter().captureToFileUi(pixmap());
} else { } else {
@@ -591,6 +607,7 @@ void CaptureWidget::saveScreenshot() {
} }
void CaptureWidget::uploadToImgur() { void CaptureWidget::uploadToImgur() {
m_captureDone = true;
ResourceExporter().captureToImgur(pixmap()); ResourceExporter().captureToImgur(pixmap());
close(); close();
} }

View File

@@ -44,13 +44,18 @@ class CaptureWidget : public QWidget {
Q_OBJECT Q_OBJECT
public: public:
explicit CaptureWidget(const QString &forcedSavePath = QString(), explicit CaptureWidget(const uint id = 0,
const QString &forcedSavePath = QString(),
QWidget *parent = nullptr); QWidget *parent = nullptr);
~CaptureWidget(); ~CaptureWidget();
void updateButtons(); void updateButtons();
QPixmap pixmap(); QPixmap pixmap();
signals:
void captureTaken(uint id, QByteArray p);
void captureFailed(uint id);
private slots: private slots:
void copyScreenshot(); void copyScreenshot();
void saveScreenshot(); void saveScreenshot();
@@ -90,10 +95,12 @@ protected:
bool m_newSelection; bool m_newSelection;
bool m_grabbing; bool m_grabbing;
bool m_showInitialMsg; bool m_showInitialMsg;
bool m_captureDone;
const QString m_forcedSavePath; const QString m_forcedSavePath;
int m_thickness; int m_thickness;
uint m_id;
NotifierBox *m_notifierBox; NotifierBox *m_notifierBox;
// naming convention for handles // naming convention for handles

View File

@@ -25,7 +25,6 @@
ScreenshotSaver::ScreenshotSaver() ScreenshotSaver::ScreenshotSaver()
{ {
} }
void ScreenshotSaver::saveToClipboard(const QPixmap &capture) { void ScreenshotSaver::saveToClipboard(const QPixmap &capture) {

View File

@@ -61,9 +61,13 @@ void Controller::initDefaults() {
} }
// creation of a new capture in GUI mode // creation of a new capture in GUI mode
void Controller::createVisualCapture(const QString &forcedSavePath) { void Controller::createVisualCapture(const uint id, const QString &forcedSavePath) {
if (!m_captureWindow) { if (!m_captureWindow) {
m_captureWindow = new CaptureWidget(forcedSavePath); m_captureWindow = new CaptureWidget(id, forcedSavePath);
connect(m_captureWindow, &CaptureWidget::captureFailed,
this, &Controller::captureFailed);
connect(m_captureWindow, &CaptureWidget::captureTaken,
this, &Controller::captureTaken);
m_captureWindow->showFullScreen(); m_captureWindow->showFullScreen();
} }
} }

View File

@@ -20,6 +20,7 @@
#include <QObject> #include <QObject>
#include <QPointer> #include <QPointer>
#include <QPixmap>
class CaptureWidget; class CaptureWidget;
class ConfigWindow; class ConfigWindow;
@@ -35,8 +36,13 @@ public:
Controller(const Controller&) = delete; Controller(const Controller&) = delete;
void operator =(const Controller&) = delete; void operator =(const Controller&) = delete;
signals:
void captureTaken(uint id, QByteArray p);
void captureFailed(uint id);
public slots: public slots:
void createVisualCapture(const QString &forcedSavePath = QString()); void createVisualCapture(const uint id = 0,
const QString &forcedSavePath = QString());
void openConfigWindow(); void openConfigWindow();
void openInfoWindow(); void openInfoWindow();

View File

@@ -22,6 +22,7 @@
#include "src/core/resourceexporter.h" #include "src/core/resourceexporter.h"
#include <QTimer> #include <QTimer>
#include <functional> #include <functional>
#include <QBuffer>
namespace { namespace {
using std::function; using std::function;
@@ -41,33 +42,53 @@ namespace {
FlameshotDBusAdapter::FlameshotDBusAdapter(QObject *parent) FlameshotDBusAdapter::FlameshotDBusAdapter(QObject *parent)
: QDBusAbstractAdaptor(parent) : QDBusAbstractAdaptor(parent)
{ {
auto controller = Controller::getInstance();
connect(controller, &Controller::captureFailed,
this, &FlameshotDBusAdapter::captureFailed);
connect(controller, &Controller::captureTaken,
this, &FlameshotDBusAdapter::captureTaken);
} }
FlameshotDBusAdapter::~FlameshotDBusAdapter() { FlameshotDBusAdapter::~FlameshotDBusAdapter() {
} }
void FlameshotDBusAdapter::graphicCapture(QString path, int delay) { void FlameshotDBusAdapter::graphicCapture(QString path, int delay, uint id) {
auto controller = Controller::getInstance(); auto controller = Controller::getInstance();
auto f = [controller, path, this]() {
controller->createVisualCapture(path); auto f = [controller, id, path, this]() {
controller->createVisualCapture(id, path);
}; };
// QTimer::singleShot(delay, controller, f); // requires Qt 5.4 // QTimer::singleShot(delay, controller, f); // requires Qt 5.4
doLater(delay, controller, f); doLater(delay, controller, f);
} }
void FlameshotDBusAdapter::fullScreen(QString path, bool toClipboard, int delay) { void FlameshotDBusAdapter::fullScreen(
auto f = [path, toClipboard, this]() { QString path, bool toClipboard, int delay, uint id)
QPixmap p(ScreenGrabber().grabEntireDesktop()); {
auto f = [id, path, toClipboard, this]() {
bool ok = true;
QPixmap p(ScreenGrabber().grabEntireDesktop(ok));
if (!ok) {
// TODO notify
Q_EMIT captureFailed(id);
return;
}
if (!toClipboard && path.isEmpty()) {
ResourceExporter().captureToFileUi(p);
goto emit_signal;
}
if(toClipboard) { if(toClipboard) {
ResourceExporter().captureToClipboard(p); ResourceExporter().captureToClipboard(p);
} }
if(path.isEmpty()) { if(!path.isEmpty()) {
ResourceExporter().captureToFileUi(p);
} else {
ResourceExporter().captureToFile(p, path); ResourceExporter().captureToFile(p, path);
} }
emit_signal:
QByteArray byteArray;
QBuffer buffer(&byteArray);
p.save(&buffer, "PNG");
Q_EMIT captureTaken(id, byteArray);
}; };
//QTimer::singleShot(delay, this, f); // // requires Qt 5.4 //QTimer::singleShot(delay, this, f); // // requires Qt 5.4
doLater(delay, this, f); doLater(delay, this, f);

View File

@@ -30,9 +30,13 @@ public:
FlameshotDBusAdapter(QObject *parent = nullptr); FlameshotDBusAdapter(QObject *parent = nullptr);
virtual ~FlameshotDBusAdapter(); virtual ~FlameshotDBusAdapter();
signals:
void captureTaken(uint id, QByteArray rawImage);
void captureFailed(uint id);
public slots: public slots:
Q_NOREPLY void graphicCapture(QString path, int delay); Q_NOREPLY void graphicCapture(QString path, int delay, uint id);
Q_NOREPLY void fullScreen(QString path, bool toClipboard, int delay); Q_NOREPLY void fullScreen(QString path, bool toClipboard, int delay, uint id);
Q_NOREPLY void openConfig(); Q_NOREPLY void openConfig();
Q_NOREPLY void trayIconEnabled(bool enabled); Q_NOREPLY void trayIconEnabled(bool enabled);

View File

@@ -22,11 +22,13 @@
#include "src/utils/confighandler.h" #include "src/utils/confighandler.h"
#include "src/cli/commandlineparser.h" #include "src/cli/commandlineparser.h"
#include "src/utils/systemnotification.h" #include "src/utils/systemnotification.h"
#include "src/utils/dbusutils.h"
#include <QApplication> #include <QApplication>
#include <QTranslator> #include <QTranslator>
#include <QDBusConnection> #include <QDBusConnection>
#include <QDBusMessage> #include <QDBusMessage>
#include <QTextStream> #include <QTextStream>
#include <QTimer>
#include <QDir> #include <QDir>
int main(int argc, char *argv[]) { int main(int argc, char *argv[]) {
@@ -49,6 +51,10 @@ int main(int argc, char *argv[]) {
auto c = Controller::getInstance(); auto c = Controller::getInstance();
new FlameshotDBusAdapter(c); new FlameshotDBusAdapter(c);
QDBusConnection dbus = QDBusConnection::sessionBus(); QDBusConnection dbus = QDBusConnection::sessionBus();
if (!dbus.isConnected()) {
SystemNotification().sendMessage(
QObject::tr("Unable to connect via DBus"));
}
dbus.registerObject("/", c); dbus.registerObject("/", c);
dbus.registerService("org.dharkael.Flameshot"); dbus.registerService("org.dharkael.Flameshot");
return app.exec(); return app.exec();
@@ -103,6 +109,9 @@ int main(int argc, char *argv[]) {
{"k", "contrastcolor"}, {"k", "contrastcolor"},
"Define the contrast UI color", "Define the contrast UI color",
"color-code"); "color-code");
CommandOption rawImageOption(
{"r", "raw"},
"Print raw PNG capture");
// Add checkers // Add checkers
auto colorChecker = [&parser](const QString &colorCode) -> bool { auto colorChecker = [&parser](const QString &colorCode) -> bool {
@@ -117,13 +126,13 @@ int main(int argc, char *argv[]) {
"- Named colors like 'blue' or 'red'\n" "- Named colors like 'blue' or 'red'\n"
"You may need to escape the '#' sign as in '\\#FFF'"; "You may need to escape the '#' sign as in '\\#FFF'";
const QString delayErr = "Ivalid delay, it must be higher than 0"; const QString delayErr = "Invalid delay, it must be higher than 0";
auto delayChecker = [&parser](const QString &delayValue) -> bool { auto delayChecker = [&parser](const QString &delayValue) -> bool {
int value = delayValue.toInt(); int value = delayValue.toInt();
return value >= 0; return value >= 0;
}; };
const QString pathErr = "Ivalid path, it must be a real path in the system"; const QString pathErr = "Invalid path, it must be a real path in the system";
auto pathChecker = [&parser, pathErr](const QString &pathValue) -> bool { auto pathChecker = [&parser, pathErr](const QString &pathValue) -> bool {
bool res = QDir(pathValue).exists(); bool res = QDir(pathValue).exists();
if (!res) { if (!res) {
@@ -132,7 +141,7 @@ int main(int argc, char *argv[]) {
return res; return res;
}; };
const QString booleanErr = "Ivalid value, it must be defined as 'true' or 'false'"; const QString booleanErr = "Invalid value, it must be defined as 'true' or 'false'";
auto booleanChecker = [&parser](const QString &value) -> bool { auto booleanChecker = [&parser](const QString &value) -> bool {
return value == "true" || value == "false"; return value == "true" || value == "false";
}; };
@@ -150,8 +159,9 @@ int main(int argc, char *argv[]) {
parser.AddArgument(configArgument); parser.AddArgument(configArgument);
auto helpOption = parser.addHelpOption(); auto helpOption = parser.addHelpOption();
auto versionOption = parser.addVersionOption(); auto versionOption = parser.addVersionOption();
parser.AddOptions({ pathOption, delayOption }, guiArgument); parser.AddOptions({ pathOption, delayOption, rawImageOption }, guiArgument);
parser.AddOptions({ pathOption, clipboardOption, delayOption }, fullArgument); parser.AddOptions({ pathOption, clipboardOption, delayOption, rawImageOption },
fullArgument);
parser.AddOptions({ filenameOption, trayOption, showHelpOption, parser.AddOptions({ filenameOption, trayOption, showHelpOption,
mainColorOption, contrastColorOption }, configArgument); mainColorOption, contrastColorOption }, configArgument);
// Parse // Parse
@@ -165,23 +175,76 @@ int main(int argc, char *argv[]) {
else if (parser.isSet(guiArgument)) { // GUI else if (parser.isSet(guiArgument)) { // GUI
QString pathValue = parser.value(pathOption); QString pathValue = parser.value(pathOption);
int delay = parser.value(delayOption).toInt(); int delay = parser.value(delayOption).toInt();
bool isRaw = parser.isSet(rawImageOption);
uint id = qHash(app.arguments().join(" "));
DBusUtils utils(id);
// Send message // Send message
QDBusMessage m = QDBusMessage::createMethodCall("org.dharkael.Flameshot", QDBusMessage m = QDBusMessage::createMethodCall("org.dharkael.Flameshot",
"/", "", "graphicCapture"); "/", "", "graphicCapture");
m << pathValue << delay; m << pathValue << delay << id;
QDBusConnection::sessionBus().call(m); QDBusConnection sessionBus = QDBusConnection::sessionBus();
utils.checkDBusConnection(sessionBus);
sessionBus.call(m);
if (isRaw) {
// TODO
// captureTaken
sessionBus.connect("org.dharkael.Flameshot",
"/", "", "captureTaken",
&utils,
SLOT(captureTaken(uint, QByteArray)));
// captureFailed
sessionBus.connect("org.dharkael.Flameshot",
"/", "", "captureFailed",
&utils,
SLOT(captureFailed(uint)));
QTimer t;
t.setInterval(1000 * 60 * 15); // 15 minutes timeout
QObject::connect(&t, &QTimer::timeout, qApp,
&QCoreApplication::quit);
t.start();
// wait
app.exec();
}
} }
else if (parser.isSet(fullArgument)) { // FULL else if (parser.isSet(fullArgument)) { // FULL
QString pathValue = parser.value(pathOption); QString pathValue = parser.value(pathOption);
int delay = parser.value(delayOption).toInt(); int delay = parser.value(delayOption).toInt();
bool toClipboard = parser.isSet(clipboardOption); bool toClipboard = parser.isSet(clipboardOption);
bool isRaw = parser.isSet(rawImageOption);
uint id = qHash(app.arguments().join(" "));
DBusUtils utils(id);
// Send message // Send message
QDBusMessage m = QDBusMessage::createMethodCall("org.dharkael.Flameshot", QDBusMessage m = QDBusMessage::createMethodCall("org.dharkael.Flameshot",
"/", "", "fullScreen"); "/", "", "fullScreen");
m << pathValue << toClipboard << delay; m << pathValue << toClipboard << delay << id;
QDBusConnection::sessionBus().call(m); QDBusConnection sessionBus = QDBusConnection::sessionBus();
utils.checkDBusConnection(sessionBus);
sessionBus.call(m);
if (isRaw) {
// TODO
// captureTaken
sessionBus.connect("org.dharkael.Flameshot",
"/", "", "captureTaken",
&utils,
SLOT(captureTaken(uint, QByteArray)));
// captureFailed
sessionBus.connect("org.dharkael.Flameshot",
"/", "", "captureFailed",
&utils,
SLOT(captureFailed(uint)));
// timeout just in case
QTimer t;
t.setInterval(2000);
QObject::connect(&t, &QTimer::timeout, qApp,
&QCoreApplication::quit);
t.start();
// wait
app.exec();
}
} }
else if (parser.isSet(configArgument)) { // CONFIG else if (parser.isSet(configArgument)) { // CONFIG
bool filename = parser.isSet(filenameOption); bool filename = parser.isSet(filenameOption);
@@ -208,7 +271,12 @@ int main(int argc, char *argv[]) {
} else if (parser.value(trayOption) == "true") { } else if (parser.value(trayOption) == "true") {
m << true; m << true;
} }
QDBusConnection::sessionBus().call(m); QDBusConnection sessionBus = QDBusConnection::sessionBus();
if (!sessionBus.isConnected()) {
SystemNotification().sendMessage(
QObject::tr("Unable to connect via DBus"));
}
sessionBus.call(m);
} }
if (help) { if (help) {
if (parser.value(showHelpOption) == "false") { if (parser.value(showHelpOption) == "false") {
@@ -232,7 +300,12 @@ int main(int argc, char *argv[]) {
if (!someFlagSet) { if (!someFlagSet) {
QDBusMessage m = QDBusMessage::createMethodCall("org.dharkael.Flameshot", QDBusMessage m = QDBusMessage::createMethodCall("org.dharkael.Flameshot",
"/", "", "openConfig"); "/", "", "openConfig");
QDBusConnection::sessionBus().call(m); QDBusConnection sessionBus = QDBusConnection::sessionBus();
if (!sessionBus.isConnected()) {
SystemNotification().sendMessage(
QObject::tr("Unable to connect via DBus"));
}
sessionBus.call(m);
} }
} }
return 0; return 0;

55
src/utils/dbusutils.cpp Normal file
View File

@@ -0,0 +1,55 @@
// Copyright 2017 Alejandro Sirgo Rica
//
// This file is part of Flameshot.
//
// Flameshot is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Flameshot is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Flameshot. If not, see <http://www.gnu.org/licenses/>.
#include "dbusutils.h"
#include "src/utils/systemnotification.h"
#include <QApplication>
#include <QTextStream>
#include <QFile>
DBusUtils::DBusUtils(QObject *parent) : QObject(parent) {
m_id = qHash(qApp->arguments().join(" "));
}
DBusUtils::DBusUtils(uint id, QObject *parent) :
QObject(parent), m_id(id)
{
}
void DBusUtils::checkDBusConnection(const QDBusConnection &c) {
if (!c.isConnected()) {
SystemNotification().sendMessage(tr("Unable to connect via DBus"));
qApp->exit();
}
}
void DBusUtils::captureTaken(uint id, QByteArray rawImage) {
if (m_id == id) {
QFile file;
file.open(stdout, QIODevice::WriteOnly);
file.write(rawImage);
file.close();
qApp->exit();
}
}
void DBusUtils::captureFailed(uint id) {
if (m_id == id) {
QTextStream(stdout) << "screenshot failed";
qApp->exit();
}
}

42
src/utils/dbusutils.h Normal file
View File

@@ -0,0 +1,42 @@
// Copyright 2017 Alejandro Sirgo Rica
//
// This file is part of Flameshot.
//
// Flameshot is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Flameshot is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Flameshot. If not, see <http://www.gnu.org/licenses/>.
#ifndef TERMINALUTILS_H
#define TERMINALUTILS_H
#include "src/cli/commandlineparser.h"
#include <QDBusConnection>
#include <QObject>
class DBusUtils : public QObject
{
Q_OBJECT
public:
explicit DBusUtils(QObject *parent = nullptr);
explicit DBusUtils(uint id, QObject *parent = nullptr);
void checkDBusConnection(const QDBusConnection &connection);
public slots:
void captureTaken(uint id, QByteArray rawImage);
void captureFailed(uint id);
private:
uint m_id;
};
#endif // TERMINALUTILS_H

View File

@@ -1,3 +1,20 @@
// Copyright 2017 Alejandro Sirgo Rica
//
// This file is part of Flameshot.
//
// Flameshot is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Flameshot is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Flameshot. If not, see <http://www.gnu.org/licenses/>.
#include "desktopinfo.h" #include "desktopinfo.h"
#include <QProcessEnvironment> #include <QProcessEnvironment>

View File

@@ -1,3 +1,20 @@
// Copyright 2017 Alejandro Sirgo Rica
//
// This file is part of Flameshot.
//
// Flameshot is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Flameshot is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Flameshot. If not, see <http://www.gnu.org/licenses/>.
#ifndef DESKTOPINFO_H #ifndef DESKTOPINFO_H
#define DESKTOPINFO_H #define DESKTOPINFO_H

View File

@@ -26,7 +26,28 @@ ScreenGrabber::ScreenGrabber(QObject *parent) : QObject(parent) {
} }
QPixmap ScreenGrabber::grabEntireDesktop() { QPixmap ScreenGrabber::grabEntireDesktop(bool &ok) {
ok = true; // revisit later
if(m_info.waylandDectected()) {
ok = false;
QPixmap res;
/*
habdle screenshot based on DE
switch (m_info.windowManager()) {
case m_info.GNOME:
// https://github.com/GNOME/gnome-shell/blob/695bfb96160033be55cfb5ac41c121998f98c328/data/org.gnome.Shell.Screenshot.xml
break;
case m_info.KDE:
// https://github.com/KDE/spectacle/blob/517a7baf46a4ca0a45f32fd3f2b1b7210b180134/src/PlatformBackends/KWinWaylandImageGrabber.cpp#L145
break;
default:
ok = false;
break;
}
*/
return res;
}
QRect geometry; QRect geometry;
for (QScreen *const screen : QGuiApplication::screens()) { for (QScreen *const screen : QGuiApplication::screens()) {
geometry = geometry.united(screen->geometry()); geometry = geometry.united(screen->geometry());

View File

@@ -18,6 +18,7 @@
#ifndef SCREENGRABBER_H #ifndef SCREENGRABBER_H
#define SCREENGRABBER_H #define SCREENGRABBER_H
#include "src/utils/desktopinfo.h"
#include <QObject> #include <QObject>
class ScreenGrabber : public QObject class ScreenGrabber : public QObject
@@ -25,8 +26,10 @@ class ScreenGrabber : public QObject
Q_OBJECT Q_OBJECT
public: public:
explicit ScreenGrabber(QObject *parent = nullptr); explicit ScreenGrabber(QObject *parent = nullptr);
QPixmap grabEntireDesktop(); QPixmap grabEntireDesktop(bool &ok);
private:
DesktopInfo m_info;
}; };
#endif // SCREENGRABBER_H #endif // SCREENGRABBER_H