diff --git a/KShare.pro b/KShare.pro index 4fce963..6ed64ca 100644 --- a/KShare.pro +++ b/KShare.pro @@ -121,7 +121,7 @@ mac { SOURCES += $$PWD/platformspecifics/x11/x11backend.cpp HEADERS += $$PWD/platformspecifics/x11/x11backend.hpp QT += x11extras - LIBS += -lxcb-cursor -lxcb-xfixes + LIBS += -lxcb-cursor -lxcb-xfixes -lxcb } else { error(Unsupported platform); } diff --git a/main.cpp b/main.cpp index 90b404f..5e870dd 100644 --- a/main.cpp +++ b/main.cpp @@ -3,6 +3,7 @@ #include #include #include +#include #include #include #include @@ -13,6 +14,7 @@ extern "C" { #include "ui_mainwindow.h" #include #include +#include #include bool verbose = false; diff --git a/mainwindow.cpp b/mainwindow.cpp index 2cb1c1d..6634544 100644 --- a/mainwindow.cpp +++ b/mainwindow.cpp @@ -8,6 +8,7 @@ #include #include #include +#include #include #include #include @@ -45,13 +46,21 @@ MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWi QAction *quit = new QAction("Quit", this); QAction *shtoggle = new QAction("Show/Hide", 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 *rec = new QAction("Record screen", this); QAction *recoff = new QAction("Stop recording", this); menu->addActions({ quit, shtoggle, picker }); menu->addSeparator(); menu->addActions({ fullscreen, area }); +#ifdef PLATFORM_CAPABILITY_ACTIVEWINDOW + menu->addAction(area); +#endif menu->addSeparator(); menu->addActions({ rec, recoff }); 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("area", [] { screenshotter::area(); }); + addHotkey("active", [] { screenshotter::active(); }); addHotkey("picker", [] { ColorPickerScene::showPicker(); }); addHotkey("recordingstop", [&] { controller->end(); }); addHotkey("recordingstart", [&] { this->rec(); }); diff --git a/platformspecifics/mac/macbackend.hpp b/platformspecifics/mac/macbackend.hpp index b62eaf4..4016511 100644 --- a/platformspecifics/mac/macbackend.hpp +++ b/platformspecifics/mac/macbackend.hpp @@ -3,6 +3,8 @@ #include +#define PLATFORM_CAPABILITY_PID + class PlatformBackend { public: QPixmap getCursor(); diff --git a/platformspecifics/u32/u32backend.cpp b/platformspecifics/u32/u32backend.cpp index dd42057..650e68a 100644 --- a/platformspecifics/u32/u32backend.cpp +++ b/platformspecifics/u32/u32backend.cpp @@ -24,3 +24,7 @@ std::tuple PlatformBackend::getCursor() { DWORD PlatformBackend::pid() { return GetCurrentProcessId(); } + +WId PlatformBackend::getActiveWID() { + return GetForegroundWindow(); +} diff --git a/platformspecifics/u32/u32backend.hpp b/platformspecifics/u32/u32backend.hpp index 46e50e8..ec2538a 100644 --- a/platformspecifics/u32/u32backend.hpp +++ b/platformspecifics/u32/u32backend.hpp @@ -4,6 +4,10 @@ #include #include +#define PLATFORM_CAPABILITY_PID +#define PLATFORM_CAPABILITY_ACTIVEWINDOW +#define PLATFORM_CAPABILITY_CURSOR + class PlatformBackend { public: std::tuple getCursor(); diff --git a/platformspecifics/x11/x11backend.cpp b/platformspecifics/x11/x11backend.cpp index decb605..8bf841b 100644 --- a/platformspecifics/x11/x11backend.cpp +++ b/platformspecifics/x11/x11backend.cpp @@ -27,3 +27,30 @@ std::tuple PlatformBackend::getCursor() { pid_t PlatformBackend::pid() { 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; +} diff --git a/platformspecifics/x11/x11backend.hpp b/platformspecifics/x11/x11backend.hpp index e72b8f8..fc1f1c5 100644 --- a/platformspecifics/x11/x11backend.hpp +++ b/platformspecifics/x11/x11backend.hpp @@ -3,6 +3,10 @@ #include +#define PLATFORM_CAPABILITY_PID +#define PLATFORM_CAPABILITY_ACTIVEWINDOW +#define PLATFORM_CAPABILITY_CURSOR + class PlatformBackend { public: std::tuple getCursor(); @@ -11,6 +15,7 @@ public: static PlatformBackend inst; return inst; } + WId getActiveWID(); }; #endif // X11BACKEND_HPP diff --git a/screenshotter.cpp b/screenshotter.cpp index 4f2101d..a39c7f5 100644 --- a/screenshotter.cpp +++ b/screenshotter.cpp @@ -5,6 +5,7 @@ #include "uploaders/uploadersingleton.hpp" #include #include +#include #include void screenshotter::area() { @@ -26,3 +27,13 @@ void screenshotter::areaDelayed() { void screenshotter::fullscreenDelayed() { 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 +} diff --git a/screenshotter.hpp b/screenshotter.hpp index 7fbe711..4c6be91 100644 --- a/screenshotter.hpp +++ b/screenshotter.hpp @@ -3,9 +3,13 @@ namespace screenshotter { void fullscreen(); -void area(); void fullscreenDelayed(); + +void area(); void areaDelayed(); + +void activeDelayed(); +void active(); } #endif // SCREENSHOTTER_HPP diff --git a/screenshotutil.cpp b/screenshotutil.cpp index a7da1cc..50284b3 100644 --- a/screenshotutil.cpp +++ b/screenshotutil.cpp @@ -8,6 +8,7 @@ #include QPixmap *screenshotutil::fullscreen(bool cursor) { +#ifdef PLATFORM_CAPABILITY_CURSOR if (cursor) { QPixmap *noCursor = window(0); QScopedPointer p(noCursor); @@ -18,6 +19,7 @@ QPixmap *screenshotutil::fullscreen(bool cursor) { painter.end(); return withCursor; } +#endif 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) { auto scr = QApplication::primaryScreen(); QRectF area(x, y, w < 0 ? scr->size().width() : w, h < 0 ? scr->size().height() : h); +#ifdef PLATFORM_CAPABILITY_CURSOR if (cursor) { QPointF point = QCursor::pos(scr); if (area.contains(point)) { @@ -48,5 +51,6 @@ QPixmap *screenshotutil::fullscreenArea(bool cursor, qreal x, qreal y, qreal w, return withCursor; } } +#endif return new QPixmap(scr->grabWindow(0, area.x(), area.y(), area.width(), area.height())); } diff --git a/settingsdialog.cpp b/settingsdialog.cpp index 595f755..062990d 100644 --- a/settingsdialog.cpp +++ b/settingsdialog.cpp @@ -2,6 +2,7 @@ #include "mainwindow.hpp" #include "ui_settingsdialog.h" +#include #include #include #include @@ -10,6 +11,7 @@ #include #include #include +#include #include #include #include @@ -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, "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, "Stop Recording", "recordingstop", [&] { MainWindow::inst()->controller->end(); }); 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->setCurrentIndex(settings::settings().value("recording/format", (int)formats::Recording::None).toInt()); setWindowTitle("Settings"); +#ifndef PLATFORM_CAPABILITY_CURSOR + ui->captureCursor->setEnabled(false); + ui->captureCursor->setText("Capture cursor (disabled: implementation missing)"); +#endif } void SettingsDialog::setScheme(QString scheme) {