Add active window capture

Not on Mac. I still don't have a way to test there.
This commit is contained in:
ArsenArsen 2017-06-27 11:33:11 +02:00
parent 614086c262
commit 2bd01bf181
12 changed files with 85 additions and 3 deletions

View File

@ -121,7 +121,7 @@ mac {
SOURCES += $$PWD/platformspecifics/x11/x11backend.cpp SOURCES += $$PWD/platformspecifics/x11/x11backend.cpp
HEADERS += $$PWD/platformspecifics/x11/x11backend.hpp HEADERS += $$PWD/platformspecifics/x11/x11backend.hpp
QT += x11extras QT += x11extras
LIBS += -lxcb-cursor -lxcb-xfixes LIBS += -lxcb-cursor -lxcb-xfixes -lxcb
} else { } else {
error(Unsupported platform); error(Unsupported platform);
} }

View File

@ -3,6 +3,7 @@
#include <QApplication> #include <QApplication>
#include <QCommandLineParser> #include <QCommandLineParser>
#include <QDebug> #include <QDebug>
#include <QScreen>
#include <QtGlobal> #include <QtGlobal>
#include <formatter.hpp> #include <formatter.hpp>
#include <iostream> #include <iostream>
@ -13,6 +14,7 @@ extern "C" {
#include "ui_mainwindow.h" #include "ui_mainwindow.h"
#include <QListWidget> #include <QListWidget>
#include <notifications.hpp> #include <notifications.hpp>
#include <platformbackend.hpp>
#include <worker/worker.hpp> #include <worker/worker.hpp>
bool verbose = false; bool verbose = false;

View File

@ -8,6 +8,7 @@
#include <colorpicker/colorpickerscene.hpp> #include <colorpicker/colorpickerscene.hpp>
#include <formats.hpp> #include <formats.hpp>
#include <hotkeying.hpp> #include <hotkeying.hpp>
#include <platformbackend.hpp>
#include <recording/recordingformats.hpp> #include <recording/recordingformats.hpp>
#include <settings.hpp> #include <settings.hpp>
#include <uploaders/uploadersingleton.hpp> #include <uploaders/uploadersingleton.hpp>
@ -45,13 +46,21 @@ MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWi
QAction *quit = new QAction("Quit", this); QAction *quit = new QAction("Quit", this);
QAction *shtoggle = new QAction("Show/Hide", this); QAction *shtoggle = new QAction("Show/Hide", this);
QAction *fullscreen = new QAction("Take fullscreen shot", this); QAction *fullscreen = new QAction("Take fullscreen shot", this);
QAction *area = new QAction("Take area shot", this);
QAction *active = new QAction("Take area shot", this);
#ifdef PLATFORM_CAPABILITY_ACTIVEWINDOW
QAction *area = new QAction("Screenshot active window", this);
connect(active, &QAction::triggered, this, [] { screenshotter::activeDelayed(); });
#endif
QAction *picker = new QAction("Show color picker", this); QAction *picker = new QAction("Show color picker", this);
QAction *rec = new QAction("Record screen", this); QAction *rec = new QAction("Record screen", this);
QAction *recoff = new QAction("Stop recording", this); QAction *recoff = new QAction("Stop recording", this);
menu->addActions({ quit, shtoggle, picker }); menu->addActions({ quit, shtoggle, picker });
menu->addSeparator(); menu->addSeparator();
menu->addActions({ fullscreen, area }); menu->addActions({ fullscreen, area });
#ifdef PLATFORM_CAPABILITY_ACTIVEWINDOW
menu->addAction(area);
#endif
menu->addSeparator(); menu->addSeparator();
menu->addActions({ rec, recoff }); menu->addActions({ rec, recoff });
connect(quit, &QAction::triggered, this, &MainWindow::quit); connect(quit, &QAction::triggered, this, &MainWindow::quit);
@ -71,6 +80,7 @@ MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWi
addHotkey("fullscreen", [] { screenshotter::fullscreen(); }); addHotkey("fullscreen", [] { screenshotter::fullscreen(); });
addHotkey("area", [] { screenshotter::area(); }); addHotkey("area", [] { screenshotter::area(); });
addHotkey("active", [] { screenshotter::active(); });
addHotkey("picker", [] { ColorPickerScene::showPicker(); }); addHotkey("picker", [] { ColorPickerScene::showPicker(); });
addHotkey("recordingstop", [&] { controller->end(); }); addHotkey("recordingstop", [&] { controller->end(); });
addHotkey("recordingstart", [&] { this->rec(); }); addHotkey("recordingstart", [&] { this->rec(); });

View File

@ -3,6 +3,8 @@
#include <QPixmap> #include <QPixmap>
#define PLATFORM_CAPABILITY_PID
class PlatformBackend { class PlatformBackend {
public: public:
QPixmap getCursor(); QPixmap getCursor();

View File

@ -24,3 +24,7 @@ std::tuple<QPoint, QPixmap> PlatformBackend::getCursor() {
DWORD PlatformBackend::pid() { DWORD PlatformBackend::pid() {
return GetCurrentProcessId(); return GetCurrentProcessId();
} }
WId PlatformBackend::getActiveWID() {
return GetForegroundWindow();
}

View File

@ -4,6 +4,10 @@
#include <QPixmap> #include <QPixmap>
#include <windows.h> #include <windows.h>
#define PLATFORM_CAPABILITY_PID
#define PLATFORM_CAPABILITY_ACTIVEWINDOW
#define PLATFORM_CAPABILITY_CURSOR
class PlatformBackend { class PlatformBackend {
public: public:
std::tuple<QPoint, QPixmap> getCursor(); std::tuple<QPoint, QPixmap> getCursor();

View File

@ -27,3 +27,30 @@ std::tuple<QPoint, QPixmap> PlatformBackend::getCursor() {
pid_t PlatformBackend::pid() { pid_t PlatformBackend::pid() {
return getpid(); return getpid();
} }
WId PlatformBackend::getActiveWID() {
xcb_connection_t *connection = QX11Info::connection();
xcb_get_input_focus_reply_t *focusReply;
xcb_query_tree_cookie_t treeCookie;
xcb_query_tree_reply_t *treeReply;
focusReply = xcb_get_input_focus_reply(connection, xcb_get_input_focus(connection), nullptr);
xcb_window_t window = focusReply->focus;
while (1) {
treeCookie = xcb_query_tree(connection, window);
treeReply = xcb_query_tree_reply(connection, treeCookie, nullptr);
if (!treeReply) {
window = 0;
break;
}
if (window == treeReply->root || treeReply->parent == treeReply->root) {
break;
} else {
window = treeReply->parent;
}
delete treeReply;
}
delete treeReply;
return window;
}

View File

@ -3,6 +3,10 @@
#include <QPixmap> #include <QPixmap>
#define PLATFORM_CAPABILITY_PID
#define PLATFORM_CAPABILITY_ACTIVEWINDOW
#define PLATFORM_CAPABILITY_CURSOR
class PlatformBackend { class PlatformBackend {
public: public:
std::tuple<QPoint, QPixmap> getCursor(); std::tuple<QPoint, QPixmap> getCursor();
@ -11,6 +15,7 @@ public:
static PlatformBackend inst; static PlatformBackend inst;
return inst; return inst;
} }
WId getActiveWID();
}; };
#endif // X11BACKEND_HPP #endif // X11BACKEND_HPP

View File

@ -5,6 +5,7 @@
#include "uploaders/uploadersingleton.hpp" #include "uploaders/uploadersingleton.hpp"
#include <QDoubleSpinBox> #include <QDoubleSpinBox>
#include <QTimer> #include <QTimer>
#include <platformbackend.hpp>
#include <settings.hpp> #include <settings.hpp>
void screenshotter::area() { void screenshotter::area() {
@ -26,3 +27,13 @@ void screenshotter::areaDelayed() {
void screenshotter::fullscreenDelayed() { void screenshotter::fullscreenDelayed() {
QTimer::singleShot(settings::settings().value("delay", 0.5).toFloat() * 1000, &screenshotter::fullscreen); QTimer::singleShot(settings::settings().value("delay", 0.5).toFloat() * 1000, &screenshotter::fullscreen);
} }
void screenshotter::activeDelayed() {
QTimer::singleShot(settings::settings().value("delay", 0.5).toFloat() * 1000, &screenshotter::activeDelayed);
}
void screenshotter::active() {
#ifdef PLATFORM_CAPABILITY_ACTIVEWINDOW
UploaderSingleton::inst().upload(screenshotutil::window(PlatformBackend::inst().getActiveWID()));
#endif
}

View File

@ -3,9 +3,13 @@
namespace screenshotter { namespace screenshotter {
void fullscreen(); void fullscreen();
void area();
void fullscreenDelayed(); void fullscreenDelayed();
void area();
void areaDelayed(); void areaDelayed();
void activeDelayed();
void active();
} }
#endif // SCREENSHOTTER_HPP #endif // SCREENSHOTTER_HPP

View File

@ -8,6 +8,7 @@
#include <platformbackend.hpp> #include <platformbackend.hpp>
QPixmap *screenshotutil::fullscreen(bool cursor) { QPixmap *screenshotutil::fullscreen(bool cursor) {
#ifdef PLATFORM_CAPABILITY_CURSOR
if (cursor) { if (cursor) {
QPixmap *noCursor = window(0); QPixmap *noCursor = window(0);
QScopedPointer<QPixmap> p(noCursor); QScopedPointer<QPixmap> p(noCursor);
@ -18,6 +19,7 @@ QPixmap *screenshotutil::fullscreen(bool cursor) {
painter.end(); painter.end();
return withCursor; return withCursor;
} }
#endif
return window(0); return window(0);
} }
@ -36,6 +38,7 @@ void screenshotutil::toClipboard(QString value) {
QPixmap *screenshotutil::fullscreenArea(bool cursor, qreal x, qreal y, qreal w, qreal h) { QPixmap *screenshotutil::fullscreenArea(bool cursor, qreal x, qreal y, qreal w, qreal h) {
auto scr = QApplication::primaryScreen(); auto scr = QApplication::primaryScreen();
QRectF area(x, y, w < 0 ? scr->size().width() : w, h < 0 ? scr->size().height() : h); QRectF area(x, y, w < 0 ? scr->size().width() : w, h < 0 ? scr->size().height() : h);
#ifdef PLATFORM_CAPABILITY_CURSOR
if (cursor) { if (cursor) {
QPointF point = QCursor::pos(scr); QPointF point = QCursor::pos(scr);
if (area.contains(point)) { if (area.contains(point)) {
@ -48,5 +51,6 @@ QPixmap *screenshotutil::fullscreenArea(bool cursor, qreal x, qreal y, qreal w,
return withCursor; return withCursor;
} }
} }
#endif
return new QPixmap(scr->grabWindow(0, area.x(), area.y(), area.width(), area.height())); return new QPixmap(scr->grabWindow(0, area.x(), area.y(), area.width(), area.height()));
} }

View File

@ -2,6 +2,7 @@
#include "mainwindow.hpp" #include "mainwindow.hpp"
#include "ui_settingsdialog.h" #include "ui_settingsdialog.h"
#include <QCheckBox>
#include <QDesktopServices> #include <QDesktopServices>
#include <QInputDialog> #include <QInputDialog>
#include <QListWidget> #include <QListWidget>
@ -10,6 +11,7 @@
#include <colorpicker/colorpickerscene.hpp> #include <colorpicker/colorpickerscene.hpp>
#include <formats.hpp> #include <formats.hpp>
#include <hotkeying.hpp> #include <hotkeying.hpp>
#include <platformbackend.hpp>
#include <recording/encoders/encodersettingsdialog.hpp> #include <recording/encoders/encodersettingsdialog.hpp>
#include <screenshotter.hpp> #include <screenshotter.hpp>
#include <settings.hpp> #include <settings.hpp>
@ -48,6 +50,9 @@ SettingsDialog::SettingsDialog(QWidget *parent) : QDialog(parent), ui(new Ui::Se
addHotkeyItem(ui->hotkeys, "Fullscreen image", "fullscreen", [] { screenshotter::fullscreen(); }); addHotkeyItem(ui->hotkeys, "Fullscreen image", "fullscreen", [] { screenshotter::fullscreen(); });
addHotkeyItem(ui->hotkeys, "Area image", "area", [] { screenshotter::area(); }); addHotkeyItem(ui->hotkeys, "Area image", "area", [] { screenshotter::area(); });
#ifdef PLATFORM_CAPABILITY_ACTIVEWINDOW
addHotkeyItem(ui->hotkeys, "Active window", "active", [&] { screenshotter::active(); });
#endif
addHotkeyItem(ui->hotkeys, "Color picker", "picker", [] { ColorPickerScene::showPicker(); }); addHotkeyItem(ui->hotkeys, "Color picker", "picker", [] { ColorPickerScene::showPicker(); });
addHotkeyItem(ui->hotkeys, "Stop Recording", "recordingstop", [&] { MainWindow::inst()->controller->end(); }); addHotkeyItem(ui->hotkeys, "Stop Recording", "recordingstop", [&] { MainWindow::inst()->controller->end(); });
addHotkeyItem(ui->hotkeys, "Start Recording", "recordingstart", [&] { MainWindow::inst()->rec(); }); addHotkeyItem(ui->hotkeys, "Start Recording", "recordingstart", [&] { MainWindow::inst()->rec(); });
@ -66,6 +71,10 @@ SettingsDialog::SettingsDialog(QWidget *parent) : QDialog(parent), ui(new Ui::Se
ui->formatBox->addItem("None"); ui->formatBox->addItem("None");
ui->formatBox->setCurrentIndex(settings::settings().value("recording/format", (int)formats::Recording::None).toInt()); ui->formatBox->setCurrentIndex(settings::settings().value("recording/format", (int)formats::Recording::None).toInt());
setWindowTitle("Settings"); setWindowTitle("Settings");
#ifndef PLATFORM_CAPABILITY_CURSOR
ui->captureCursor->setEnabled(false);
ui->captureCursor->setText("Capture cursor (disabled: implementation missing)");
#endif
} }
void SettingsDialog::setScheme(QString scheme) { void SettingsDialog::setScheme(QString scheme) {