diff options
author | Síle Ekaterin Liszka <sheila@vulpine.house> | 2023-11-26 01:18:38 -0800 |
---|---|---|
committer | A. Wilcox <awilcox@wilcox-tech.com> | 2023-11-27 09:59:05 +0000 |
commit | 265a2e4ca1e7902421b1a4f88ecb478a2cfd0610 (patch) | |
tree | 9c486cb407cb3e86afc76517ced6d6d71aef66f5 /user | |
parent | f053a1ed2ffbcb4b7bd559a0d006dd82e040d75c (diff) | |
download | packages-265a2e4ca1e7902421b1a4f88ecb478a2cfd0610.tar.gz packages-265a2e4ca1e7902421b1a4f88ecb478a2cfd0610.tar.bz2 packages-265a2e4ca1e7902421b1a4f88ecb478a2cfd0610.tar.xz packages-265a2e4ca1e7902421b1a4f88ecb478a2cfd0610.zip |
user/screengrab: upgrade to 2.7.0
The patch accompanying this upgrade should be removed when kwindowsystem
is bumped.
Diffstat (limited to 'user')
-rw-r--r-- | user/screengrab/APKBUILD | 11 | ||||
-rw-r--r-- | user/screengrab/revert-kwindowsystem-bump.patch | 899 |
2 files changed, 906 insertions, 4 deletions
diff --git a/user/screengrab/APKBUILD b/user/screengrab/APKBUILD index 5cb1a06b5..5bf829f5b 100644 --- a/user/screengrab/APKBUILD +++ b/user/screengrab/APKBUILD @@ -1,7 +1,8 @@ # Contributor: Síle Ekaterin Liszka <sheila@vulpine.house> # Maintainer: Síle Ekaterin Liszka <sheila@vulpine.house> pkgname=screengrab -pkgver=2.6.0 +pkgver=2.7.0 +_qtxdg=3.12 pkgrel=0 pkgdesc="Cross-platform Qt-based software for taking screenshots" url="https://github.com/lxqt/screengrab" @@ -10,9 +11,10 @@ options="!check" # No test suite. license="GPL-2.0+" depends="" makedepends="cmake extra-cmake-modules qt5-qtbase-dev qt5-qttools-dev - kwindowsystem-dev libqtxdg-dev>=3.7" + kwindowsystem-dev libqtxdg-dev>=$_qtxdg" subpackages="$pkgname-doc" -source="https://github.com/lxqt/screengrab/releases/download/$pkgver/screengrab-$pkgver.tar.xz" +source="https://github.com/lxqt/screengrab/releases/download/$pkgver/screengrab-$pkgver.tar.xz + revert-kwindowsystem-bump.patch" build() { if [ "$CBUILD" != "$CHOST" ]; then @@ -37,4 +39,5 @@ package() { make DESTDIR="$pkgdir" -C build install } -sha512sums="622bd9fa4548dbbd2b965f2a38446d6b6002786ff2154f9efe86a4970ac464174d1d7e34b8fdc61761f935c97bf4ac8bb2e8ffd166b859cddd3183bd76380b88 screengrab-2.6.0.tar.xz" +sha512sums="0becd8972408a788b56affc9091cdc9ce1fe79160bba27ae29c5f1bf48ed0b73bafdabf3aeaac1eafe646aeaa4e162c0302b7ba1ee4f07785010e50a7d8131a1 screengrab-2.7.0.tar.xz +6f9d5029ea45f22341861d10acabb6134f314cf7841dab6141995c792d25cb5c6055afae3d50e6032dc1c053445e8e6ea1178851d6bdda72009631b5c76c47df revert-kwindowsystem-bump.patch" diff --git a/user/screengrab/revert-kwindowsystem-bump.patch b/user/screengrab/revert-kwindowsystem-bump.patch new file mode 100644 index 000000000..4ce6967ec --- /dev/null +++ b/user/screengrab/revert-kwindowsystem-bump.patch @@ -0,0 +1,899 @@ +diff '--color=auto' -Nurd screengrab-2.7.0/CMakeLists.txt screengrab-2.7.0.new/CMakeLists.txt +--- screengrab-2.7.0/CMakeLists.txt 2023-11-05 04:30:13.000000000 -0800 ++++ screengrab-2.7.0.new/CMakeLists.txt 2023-11-26 01:15:30.572898382 -0800 +@@ -15,7 +15,7 @@ + option(UPDATE_TRANSLATIONS "Update source translation translations/*.ts files" OFF) + + # Minimum Versions +-set(KF5_MINIMUM_VERSION "5.101.0") ++set(KF5_MINIMUM_VERSION "5.36.0") + set(QT_MINIMUM_VERSION "5.15.0") + set(QTXDG_MINIMUM_VERSION "3.12.0") + +diff '--color=auto' -Nurd screengrab-2.7.0/CMakeLists.txt.orig screengrab-2.7.0.new/CMakeLists.txt.orig +--- screengrab-2.7.0/CMakeLists.txt.orig 1969-12-31 16:00:00.000000000 -0800 ++++ screengrab-2.7.0.new/CMakeLists.txt.orig 2023-11-26 01:13:58.403649484 -0800 +@@ -0,0 +1,224 @@ ++cmake_minimum_required(VERSION 3.1.0 FATAL_ERROR) ++# CMP0000: Call the cmake_minimum_required() command at the beginning of the top-level ++# CMakeLists.txt file even before calling the project() command. ++# The cmake_minimum_required(VERSION) command implicitly invokes the cmake_policy(VERSION) ++# command to specify that the current project code is written for the given range of CMake ++# versions. ++project(screengrab) ++ ++include(GNUInstallDirs) ++set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_CURRENT_SOURCE_DIR}/cmake") ++ ++# options ++option(SG_DBUS_NOTIFY "Enable D-Bus notifications" ON) ++option(SG_EXT_EDIT "Enable ability to edit screenshots in external editor" ON) ++option(UPDATE_TRANSLATIONS "Update source translation translations/*.ts files" OFF) ++ ++# Minimum Versions ++set(KF5_MINIMUM_VERSION "5.101.0") ++set(QT_MINIMUM_VERSION "5.15.0") ++set(QTXDG_MINIMUM_VERSION "3.12.0") ++ ++find_package(Qt5LinguistTools ${QT_MINIMUM_VERSION} REQUIRED) ++find_package(Qt5Network ${QT_MINIMUM_VERSION} REQUIRED) ++find_package(Qt5Widgets ${QT_MINIMUM_VERSION} REQUIRED) ++find_package(Qt5X11Extras ${QT_MINIMUM_VERSION} REQUIRED) ++find_package(KF5WindowSystem ${KF5_MINIMUM_VERSION} REQUIRED) ++ ++# right now we declare it as required ++find_package(X11 REQUIRED) ++set(HAVE_X11 1) ++ ++find_package( ++ XCB REQUIRED MODULE COMPONENTS ++ XCB ++ SHAPE ++ XFIXES ++) ++ ++find_package( ++ X11_XCB REQUIRED MODULE ++) ++ ++set(CMAKE_AUTOMOC ON) ++set(CMAKE_AUTOUIC ON) ++set(CMAKE_INCLUDE_CURRENT_DIR ON) ++ ++set(SCREENGRAB_VERSION "2.7.0") ++ ++if (DEV_VERSION) ++ set(VERSION "${SCREENGRAB_VERSION}-dev (${DEV_VERSION})") ++else() ++ set(VERSION ${SCREENGRAB_VERSION}) ++endif() ++ ++add_definitions( ++ -DVERSION="${VERSION}" ++ -DQT_NO_FOREACH ++) ++ ++if(NOT CMAKE_BUILD_TYPE) ++ set(CMAKE_BUILD_TYPE Release) ++endif() ++ ++message(STATUS "Build type: " ${CMAKE_BUILD_TYPE}) ++message(STATUS "Install prefix: " ${CMAKE_INSTALL_PREFIX}) ++ ++set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wnon-virtual-dtor -Woverloaded-virtual -Wall -Wextra") ++ ++# Although the names, LXQtTranslateTs and LXQtTranslateDesktop, they don't ++# bring any dependency on lxqt. ++include(LXQtTranslateTs) ++include(LXQtTranslateDesktop) ++include(Qt5TranslationLoader) ++ ++if(SG_EXT_EDIT) ++ add_definitions( -DSG_EXT_EDIT="1") ++ find_package(Qt5Xdg ${QTXDG_MINIMUM_VERSION} REQUIRED) ++endif() ++ ++if(SG_DBUS_NOTIFY) ++ find_package(Qt5DBus ${QT_MINIMUM_VERSION} REQUIRED) ++ add_definitions( -DSG_DBUS_NOTIFY="1") ++endif() ++ ++message(STATUS "Editing screenshots in external editor support: " ${SG_EXT_EDIT}) ++message(STATUS "Enable D-Bus notifications: " ${SG_DBUS_NOTIFY}) ++message(STATUS "Use system Qxt Library: " ${SG_USE_SYSTEM_QXT}) ++message(STATUS "Update source translation translations/*.ts files: " ${UPDATE_TRANSLATIONS}) ++ ++# docs ++# CMAKE_INSTALL_FULL_DOCDIR = CMAKE_INSTALL_PREFIX/CMAKE_INSTALL_DATADIR/doc/PROJECT_NAME ++message(STATUS "Documentation directory: " ${CMAKE_INSTALL_FULL_DOCDIR}) ++add_definitions(-DSG_DOCDIR="${CMAKE_INSTALL_FULL_DOCDIR}") ++ ++# app icon path ++add_definitions(-DSG_ICONPATH="${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_DATADIR}/icons/hicolor/scalable/apps/screengrab.svg") ++ ++include_directories("${CMAKE_CURRENT_SOURCE_DIR}/src") ++add_subdirectory("${CMAKE_CURRENT_SOURCE_DIR}/src/common/qkeysequencewidget") ++include_directories("${CMAKE_CURRENT_SOURCE_DIR}/src/common/qkeysequencewidget/src") ++ ++if (SG_EXT_EDIT) ++ include_directories("${CMAKE_CURRENT_SOURCE_DIR}/src/modules/extedit") ++ add_subdirectory("${CMAKE_CURRENT_SOURCE_DIR}/src/modules/extedit") ++endif() ++ ++set(SCREENGRAB_SRC ++ src/core/main.cpp ++ src/core/singleapp.cpp ++ src/core/core.cpp ++ src/core/config.cpp ++ src/core/regionselect.cpp ++ src/core/shortcutmanager.cpp ++ src/core/modulemanager.cpp ++ src/core/ui/configwidget.cpp ++ src/core/ui/about.cpp ++ src/core/ui/mainwindow.cpp ++) ++ ++if(SG_DBUS_NOTIFY) ++ set(SCREENGRAB_SRC ${SCREENGRAB_SRC} src/core/dbusnotifier.cpp) ++endif() ++ ++if(X11_FOUND) ++ set(SCREENGRAB_SRC ${SCREENGRAB_SRC} src/core/x11utils.cpp) ++endif() ++ ++set(SCREENGRAB_HDR ++ src/core/singleapp.h ++) ++ ++set(SCREENGRAB_UI ++ src/core/ui/configwidget.ui ++ src/core/ui/aboutwidget.ui ++ src/core/ui/mainwindow.ui ++) ++ ++# Qt resource file ++set(SCREENGRAB_QRC screengrab.qrc) ++qt5_add_resources(QRC_SOURCES ${SCREENGRAB_QRC}) ++ ++message(STATUS "Generating localize ...") ++ ++set(SCREENGRAB_CONFIG_FILES ++ screengrab.conf ++) ++ ++set(SCREENGRAB_DESKTOP_FILES_IN ++ screengrab.desktop.in ++) ++ ++lxqt_translate_ts(SCREENGRAB_QMS ++ USE_QT5 TRUE ++ UPDATE_TRANSLATIONS ${UPDATE_TRANSLATIONS} ++ SOURCES ++ ${SCREENGRAB_SRC} ++ ${SCREENGRAB_UI} ++ INSTALL_DIR "${CMAKE_INSTALL_DATADIR}/${PROJECT_NAME}/translations" ++) ++ ++lxqt_translate_desktop(SCREENGRAB_DESKTOP_FILES ++ SOURCES ${SCREENGRAB_DESKTOP_FILES_IN} ++ USE_YAML ++) ++ ++qt5_translation_loader(SCREENGRAB_QM_LOADER ++ "${CMAKE_INSTALL_FULL_DATADIR}/${PROJECT_NAME}/translations" ++ ${PROJECT_NAME} ++) ++ ++# generating executable ++add_executable(screengrab ++ ${SCREENGRAB_SRC} ++ ${SCREENGRAB_UI_H} ++ ${QRC_SOURCES} ++ ${SCREENGRAB_QMS} ++ ${SCREENGRAB_DESKTOP_FILES} ++ ${SCREENGRAB_QM_LOADER} ++) ++ ++if(SG_EXT_EDIT) ++ target_link_libraries(screengrab extedit) ++endif() ++ ++if(SG_DBUS_NOTIFY) ++ target_link_libraries(screengrab Qt5::DBus) ++endif() ++ ++if (X11_XCB_FOUND) ++ add_definitions( -DX11_XCB_FOUND="1") ++ target_link_libraries(screengrab ${X11_XCB_LIBRARIES}) ++endif() ++ ++if (XCB_XCB_FOUND) ++ add_definitions( -DXCB_XCB_FOUND="1") ++ target_link_libraries(screengrab ${XCB_XCB_LIBRARY}) ++endif() ++ ++if (XCB_SHAPE_FOUND) ++ add_definitions( -DXCB_SHAPE_FOUND="1") ++ target_link_libraries(screengrab ${XCB_SHAPE_LIBRARY}) ++endif() ++ ++if (XCB_XFIXES_FOUND) ++ add_definitions( -DXCB_XFOXES_FOUND="1") ++ target_link_libraries(screengrab ${XCB_XFIXES_LIBRARY}) ++endif() ++ ++# Link with Network and X11Extras. See pull#86. TODO: Should be optional when upload module is needed. ++target_link_libraries(screengrab qkeysequencewidget Qt5::Widgets KF5::WindowSystem Qt5::X11Extras Qt5::Network ${X11_LIBRARIES}) ++ ++# installing ++install(TARGETS screengrab RUNTIME DESTINATION bin) ++# install html docs ++install(DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/docs/html" DESTINATION "${CMAKE_INSTALL_FULL_DOCDIR}") ++# install config files ++install(FILES ${SCREENGRAB_CONFIG_FILES} DESTINATION ${CMAKE_INSTALL_DATADIR}/${PROJECT_NAME}) ++# install desktop files ++install(FILES ${SCREENGRAB_DESKTOP_FILES} DESTINATION ${CMAKE_INSTALL_DATADIR}/applications) ++# install pixmap ++install(FILES "${CMAKE_CURRENT_SOURCE_DIR}/img/screengrab.svg" DESTINATION "${CMAKE_INSTALL_DATADIR}/icons/hicolor/scalable/apps") ++install(FILES screengrab.metainfo.xml ++ DESTINATION ${CMAKE_INSTALL_DATADIR}/metainfo ++) +diff '--color=auto' -Nurd screengrab-2.7.0/src/core/core.cpp screengrab-2.7.0.new/src/core/core.cpp +--- screengrab-2.7.0/src/core/core.cpp 2023-11-05 04:30:13.000000000 -0800 ++++ screengrab-2.7.0.new/src/core/core.cpp 2023-11-26 01:15:31.602889989 -0800 +@@ -32,8 +32,7 @@ + #include <XdgMimeApps> + #include <qt5xdg/XdgDesktopFile> + +-#include <KWindowSystem/KWindowSystem> +-#include <KWindowSystem/KX11Extras> ++#include <KF5/KWindowSystem/KWindowSystem> + #include <xcb/xfixes.h> + + #ifdef X11_XCB_FOUND +@@ -269,15 +268,15 @@ + if (screen == nullptr) + screen = QGuiApplication::screens().at(0); + +- WId wnd = KX11Extras::activeWindow(); ++ WId wnd = KWindowSystem::activeWindow(); + + // this window screenshot will be invalid + // if there's no active window or the active window is ours +- bool invalid(!wnd || !KX11Extras::hasWId(wnd) || (_wnd && _wnd->winId() == wnd)); ++ bool invalid(!wnd || !KWindowSystem::hasWId(wnd) || (_wnd && _wnd->winId() == wnd)); + if (!invalid) + { // or if it isn't on the current desktop + KWindowInfo info(wnd, NET::WMDesktop); +- invalid = info.valid() && !info.isOnDesktop(KX11Extras::currentDesktop()); ++ invalid = info.valid() && !info.isOnDesktop(KWindowSystem::currentDesktop()); + if (!invalid) + { // or if it is a desktop or panel/dock + info = KWindowInfo(wnd, NET::WMWindowType); +diff '--color=auto' -Nurd screengrab-2.7.0/src/core/core.cpp.orig screengrab-2.7.0.new/src/core/core.cpp.orig +--- screengrab-2.7.0/src/core/core.cpp.orig 1969-12-31 16:00:00.000000000 -0800 ++++ screengrab-2.7.0.new/src/core/core.cpp.orig 2023-11-26 01:13:58.413649402 -0800 +@@ -0,0 +1,623 @@ ++/*************************************************************************** ++ * Copyright (C) 2009 - 2013 by Artem 'DOOMer' Galichkin * ++ * doomer3d@gmail.com * ++ * * ++ * This program 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 2 of the License, or * ++ * (at your option) any later version. * ++ * * ++ * This program 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 this program. If not, see <http://www.gnu.org/licenses/>. * ++ ***************************************************************************/ ++ ++#include <QMutex> ++#include <QWaitCondition> ++#include <QApplication> ++#include <QScreen> ++#include <QChar> ++#include <QBuffer> ++#include <QFile> ++#include <QDir> ++#include <QUuid> ++#include <QMimeDatabase> ++ ++#include <QDebug> ++ ++#include <XdgMimeApps> ++#include <qt5xdg/XdgDesktopFile> ++ ++#include <KWindowSystem/KWindowSystem> ++#include <KWindowSystem/KX11Extras> ++#include <xcb/xfixes.h> ++ ++#ifdef X11_XCB_FOUND ++#include "x11utils.h" ++#endif ++ ++#include "core/core.h" ++ ++#ifdef SG_DBUS_NOTIFY ++#include "dbusnotifier.h" ++#endif ++ ++Core* Core::corePtr = nullptr; ++ ++Core::Core() ++{ ++ qRegisterMetaType<StateNotifyMessage>("StateNotifyMessage"); ++ ++ _conf = Config::instance(); ++ _conf->loadSettings(); ++ _lastSelectedArea = _conf->getLastSelection(); ++ ++ _pixelMap = new QPixmap; ++ _selector = nullptr; ++ _firstScreen = true; ++ ++ _cmdLine.setApplicationDescription(QStringLiteral("ScreenGrab ") + tr("is a crossplatform application for fast creating screenshots of your desktop.")); ++ _cmdLine.addHelpOption(); ++ _cmdLine.addVersionOption(); ++ ++ QCommandLineOption optFullScreen(QStringList() << QStringLiteral("f") << QStringLiteral("fullscreen"), tr("Take a fullscreen screenshot")); ++ _cmdLine.addOption(optFullScreen); ++ _screenTypeOpts.append(optFullScreen); ++ ++ QCommandLineOption optActiveWnd(QStringList() << QStringLiteral("a") << QStringLiteral("active"), tr("Take a screenshot of the active window")); ++ _cmdLine.addOption(optActiveWnd); ++ _screenTypeOpts.append(optActiveWnd); ++ ++ QCommandLineOption optSelectedRect(QStringList() << QStringLiteral("r") << QStringLiteral("region"), tr("Take a screenshot of a selection of the screen")); ++ _cmdLine.addOption(optSelectedRect); ++ _screenTypeOpts.append(optSelectedRect); ++ ++ QCommandLineOption optRunMinimized(QStringList() << QStringLiteral("m") << QStringLiteral("minimized"), tr("Run the application with a hidden main window")); ++ _cmdLine.addOption(optRunMinimized); ++ ++ sleep(250); ++ ++ _wnd = nullptr; ++} ++ ++Core::Core(const Core& ): QObject() ++{ ++} ++ ++Core& Core::operator=(const Core &) ++{ ++ return *this; ++} ++ ++Core* Core::instance() ++{ ++ if (!corePtr) ++ corePtr = new Core; ++ return corePtr; ++} ++ ++Core::~Core() ++{ ++ killTempFile(); ++ delete _pixelMap; ++ _conf->killInstance(); ++} ++ ++void Core::initWindow(const QString& ipcMessage) ++{ ++ if (!_wnd) { ++ _wnd = new MainWindow; ++ _wnd->setConfig(_conf); ++ _wnd->updateModulesActions(_modules.generateModulesActions()); ++ _wnd->updateModulesMenus(_modules.generateModulesMenus()); ++ ++ screenShot(true); // first screenshot ++ ++ _wnd->resize(_conf->getRestoredWndSize()); ++ ++ if (_wnd) { ++ if (runAsMinimized()) ++ { ++ if (_wnd->isTrayed()) ++ _wnd->windowHideShow(); ++ else ++ _wnd->showMinimized(); ++ } else ++ _wnd->show(); ++ } ++ } else { ++ _wnd->showWindow(ipcMessage); ++ screenShot(); ++ } ++} ++ ++void Core::sleep(int msec) ++{ ++ QMutex mutex; ++ mutex.lock(); ++ QWaitCondition pause; ++ pause.wait(&mutex, msec); // def 240 ++ mutex.unlock(); ++} ++ ++void Core::coreQuit() ++{ ++ _conf->setLastSelection(_lastSelectedArea); ++ _conf->saveScreenshotSettings(); ++ ++ if (_wnd) { ++ _conf->setRestoredWndSize(_wnd->width(), _wnd->height()); ++ _conf->saveWndSize(); ++ _wnd->close(); ++ } ++ ++ if (corePtr) ++ { ++ delete corePtr; ++ corePtr = nullptr; ++ } ++ ++ qApp->quit(); ++} ++ ++void Core::setScreen() ++{ ++ _wnd->hideToShot(); ++ ++ // new code experimental ++ if (_conf->getDelay() == 0) ++ QTimer::singleShot(200, this, SLOT(screenShot())); ++ else ++ QTimer::singleShot(1000 * _conf->getDelay(), this, SLOT(screenShot())); ++ ++} ++ ++void Core::getFullScreenPixmap(QScreen* screen) ++{ ++ const auto siblings = screen->virtualSiblings(); ++ if (siblings.size() == 1) ++ *_pixelMap = screen->grabWindow(0); // 0 for the entire screen ++ else ++ { // consider all siblings ++ QPixmap pix = QPixmap(screen->virtualSize()); ++ pix.fill(Qt::transparent); ++ QPainter painter(&pix); ++ for (const auto& sc : siblings) ++ painter.drawPixmap(sc->geometry().topLeft(), sc->grabWindow(0)); ++ *_pixelMap = pix; ++ } ++} ++ ++// get screenshot ++void Core::screenShot(bool first) ++{ ++ killTempFile(); // remove the old temp file if any ++ ++ sleep(400); // delay for hide "fade effect" bug in the KWin with compositing ++ _firstScreen = first; ++ ++ // Update the last saving date, if this is the first screenshot ++ if (_firstScreen) ++ _conf->updateLastSaveDate(); ++ ++ switch(_conf->getDefScreenshotType()) ++ { ++ case Core::FullScreen: ++ { ++ auto screen = QGuiApplication::screenAt(QCursor::pos()); ++ if (screen == nullptr) ++ screen = QGuiApplication::screens().at(0); ++ getFullScreenPixmap(screen); ++ grabCursor(0, 0); ++ ++ checkAutoSave(first); ++ _wnd->updatePixmap(_pixelMap); ++ break; ++ } ++ case Core::Window: ++ { ++ getActiveWindow(); ++ checkAutoSave(first); ++ _wnd->updatePixmap(_pixelMap); ++ break; ++ } ++ case Core::Area: ++ { ++ _selector = new RegionSelect(_conf); ++ connect(_selector, &RegionSelect::processDone, this, &Core::regionGrabbed); ++ break; ++ } ++ case Core::PreviousSelection: ++ { ++ _selector = new RegionSelect(_conf, _lastSelectedArea); ++ connect(_selector, &RegionSelect::processDone, this, &Core::regionGrabbed); ++ break; ++ } ++ default: ++ getFullScreenPixmap(QGuiApplication::primaryScreen()); ++ break; ++ } ++ ++ ++ ++ _wnd->updatePixmap(_pixelMap); ++ _wnd->restoreFromShot(); ++} ++ ++void Core::checkAutoSave(bool first) ++{ ++ if (_conf->getAutoSave()) ++ { ++ // hack ++ if (first) ++ { ++ if (_conf->getAutoSaveFirst()) ++ QTimer::singleShot(600, this, SLOT(autoSave())); ++ } ++ else ++ autoSave(); ++ } ++} ++ ++void Core::getActiveWindow() // called only with window screenshots ++{ ++ auto screen = QGuiApplication::screenAt(QCursor::pos()); ++ if (screen == nullptr) ++ screen = QGuiApplication::screens().at(0); ++ ++ WId wnd = KX11Extras::activeWindow(); ++ ++ // this window screenshot will be invalid ++ // if there's no active window or the active window is ours ++ bool invalid(!wnd || !KX11Extras::hasWId(wnd) || (_wnd && _wnd->winId() == wnd)); ++ if (!invalid) ++ { // or if it isn't on the current desktop ++ KWindowInfo info(wnd, NET::WMDesktop); ++ invalid = info.valid() && !info.isOnDesktop(KX11Extras::currentDesktop()); ++ if (!invalid) ++ { // or if it is a desktop or panel/dock ++ info = KWindowInfo(wnd, NET::WMWindowType); ++ QFlags<NET::WindowTypeMask> flags; ++ flags |= NET::DesktopMask; ++ flags |= NET::DockMask; ++ invalid = info.valid() && NET::typeMatchesMask(info.windowType(NET::AllTypesMask), flags); ++ } ++ } ++ ++ // also invalid if the window is shaded/invisible ++ KWindowInfo info(wnd, NET::XAWMState | NET::WMFrameExtents); ++ if (!invalid && info.mappingState() != NET::Visible) ++ invalid = true; ++ ++ // if this is an invalid screenshot, take a fullscreen shot instead ++ if (invalid) ++ { ++ qWarning() << "Could not take a window screenshot."; ++ *_pixelMap = screen->grabWindow(0); ++ return; ++ } ++ ++ // no decorations option is selected ++ if (_conf->getNoDecoration()) ++ { ++ *_pixelMap = screen->grabWindow(wnd); ++ return; ++ } ++ ++ QRect geometry = info.frameGeometry(); ++ ++ // WARNING: Until now, "KWindowInfo::frameGeometry" does not consider the screens's ++ // device pixel ratio. So, the frame geometry should be transformed. ++ qreal pixelRatio = screen->devicePixelRatio(); ++ geometry.setTopLeft(QPointF(geometry.topLeft() / pixelRatio).toPoint()); ++ geometry.setBottomRight(QPointF(geometry.bottomRight() / pixelRatio).toPoint()); ++ ++ // The offscreen part of the window will appear as a black area in the screenshot. ++ // Until a better method is found, the offscreen area is ignored here. ++ QRect r = screen->virtualGeometry().intersected(geometry); ++ ++ // the window positon should be calculated relative to the screen ++ *_pixelMap = screen->grabWindow(0, ++ r.x() - screen->geometry().x(), ++ r.y() - screen->geometry().y(), ++ r.width(), ++ r.height()); ++ ++ grabCursor(geometry.x(), geometry.y()); ++} ++ ++void Core::grabCursor(int offsetX, int offsetY) ++{ ++#ifdef XCB_XFOXES_FOUND ++ if (_conf->getIncludeCursor()) ++ X11Utils::compositePointer(offsetX, offsetY, _pixelMap); ++#else ++ Q_UNUSED(offsetx); ++ Q_UNUSED(offsety); ++#endif ++ ++ ++} ++ ++void Core::sendSystemNotify(const StateNotifyMessage& /*notify*/) ++{ ++ qDebug() << "Send system notification"; ++} ++ ++QString Core::getSaveFilePath(const QString &format) ++{ ++ QString initPath; ++ ++ do ++ { ++ QDir dir(_conf->getSaveDir()); ++ const QString filePath = dir.filePath(_conf->getSaveFileName()); ++ if (_conf->getDateTimeInFilename()) ++ initPath = filePath + QStringLiteral("-") + getDateTimeFileName() + QStringLiteral(".") + format; ++ else ++ { ++ if (_conf->getScrNum() != 0) ++ initPath = filePath + _conf->getScrNumStr() + QStringLiteral(".") + format; ++ else ++ initPath = filePath + QStringLiteral(".") + format; ++ } ++ } while (checkExsistFile(initPath)); ++ ++ return initPath; ++} ++ ++bool Core::checkExsistFile(const QString &path) ++{ ++ bool exist = QFile::exists(path); ++ ++ if (exist) ++ _conf->increaseScrNum(); ++ ++ return exist; ++} ++ ++QString Core::getDateTimeFileName() ++{ ++ QString currentDateTime = QDateTime::currentDateTime().toString(_conf->getDateTimeTpl()); ++ ++ if (currentDateTime == _conf->getLastSaveDate().toString(_conf->getDateTimeTpl()) && _conf->getScrNum() != 0) ++ currentDateTime += QStringLiteral("-") + _conf->getScrNumStr(); ++ else ++ _conf->resetScrNum(); ++ ++ return currentDateTime; ++} ++ ++Config *Core::config() ++{ ++ return _conf; ++} ++ ++void Core::updatePixmap() ++{ ++ if (QFile::exists(_tempFilename)) ++ { ++ _pixelMap->load(_tempFilename, "png"); ++ _wnd->updatePixmap(_pixelMap); ++ } ++} ++ ++QString Core::getTempFilename(const QString& format) ++{ ++ if (_tempFilename.isEmpty()) ++ { ++ _tempFilename = QUuid::createUuid().toString(); ++ int size = _tempFilename.size() - 2; ++ _tempFilename = _tempFilename.mid(1, size).left(8); ++ _tempFilename = QDir::tempPath() + QDir::separator() ++ + QStringLiteral("screenshot-") + _tempFilename ++ + QStringLiteral(".") + format; ++ } ++ return _tempFilename; ++} ++ ++void Core::killTempFile() ++{ ++ if (QFile::exists(_tempFilename)) ++ QFile::remove(_tempFilename); ++ _tempFilename.clear(); ++} ++ ++bool Core::writeScreen(QString& fileName, QString& format, bool tmpScreen) ++{ ++ // adding extension format ++ if (!fileName.contains(QStringLiteral(".") + format)) ++ fileName.append(QStringLiteral(".") + format); ++ ++ // saving temp file ++ if (tmpScreen) ++ { ++ if (!fileName.isEmpty()) ++ return _pixelMap->save(fileName, format.toLatin1().constData(), _conf->getImageQuality()); ++ else ++ return false; ++ } ++ ++ // writing file ++ bool saved = false; ++ if (!fileName.isEmpty()) ++ { ++ if (format == QLatin1String("jpg")) ++ saved = _pixelMap->save(fileName,format.toLatin1().constData(), _conf->getImageQuality()); ++ else ++ saved = _pixelMap->save(fileName,format.toLatin1().constData(), -1); ++ ++ if (saved) ++ { ++ StateNotifyMessage message(tr("Saved"), tr("Saved to ") + fileName); ++ ++ message.message = message.message + copyFileNameToCliipboard(fileName); ++ _conf->updateLastSaveDate(); ++ sendNotify(message); ++ } ++ else ++ qWarning() << "Error saving file " << fileName; ++ } ++ ++ return saved; ++} ++ ++QString Core::copyFileNameToCliipboard(QString file) ++{ ++ QString retString = QLatin1String(""); ++ switch (_conf->getAutoCopyFilenameOnSaving()) ++ { ++ case Config::nameToClipboardFile: ++ { ++ file = file.section(QLatin1Char('/'), -1); ++ QApplication::clipboard()->setText(file); ++ retString = QChar(QChar::LineSeparator) + tr("Name of saved file is copied to the clipboard"); ++ break; ++ } ++ case Config::nameToClipboardPath: ++ { ++ QApplication::clipboard()->setText(file); ++ retString = QChar(QChar::LineSeparator) + tr("Path to saved file is copied to the clipboard"); ++ break; ++ } ++ default: ++ break; ++ } ++ return retString; ++} ++ ++void Core::sendNotify(const StateNotifyMessage &message) ++{ ++#ifdef SG_DBUS_NOTIFY ++ DBusNotifier *notifier = new DBusNotifier(); ++ notifier->displayNotify(message); ++#else ++ _wnd->showTrayMessage(message.header, message.message); ++#endif ++} ++ ++void Core::copyScreen() ++{ ++ QApplication::clipboard()->setPixmap(*_pixelMap, QClipboard::Clipboard); ++ StateNotifyMessage message(tr("Copied"), tr("Screenshot is copied to clipboard")); ++ sendNotify(message); ++} ++ ++void Core::openInExtViewer() ++{ ++ if (_conf->getEnableExtView()) ++ { ++ QString format = _conf->getSaveFormat(); ++ if (format.isEmpty()) ++ format = QLatin1String("png"); ++ ++ QString tempFileName = getTempFilename(format); ++ writeScreen(tempFileName, format, true); ++ ++ QMimeDatabase db; ++ XdgMimeApps mimeAppsDb; ++ QMimeType mt = db.mimeTypeForFile(tempFileName); ++ auto app = mimeAppsDb.defaultApp(mt.name()); ++ if (app != nullptr) ++ { ++ QString exec; ++ exec = app->expandExecString().first(); ++ delete app; ++ QStringList args; ++ args << tempFileName; ++ ++ QProcess::startDetached(exec, args); ++ } ++ } ++} ++ ++ModuleManager* Core::modules() ++{ ++ return &_modules; ++} ++ ++void Core::addCmdLineOption(const QCommandLineOption& option) ++{ ++ _cmdLine.addOption(option); ++} ++ ++bool Core::checkCmdLineOption(const QCommandLineOption& option) ++{ ++ return _cmdLine.isSet(option); ++} ++ ++bool Core::checkCmdLineOptions(const QStringList &options) ++{ ++ for (int i = 0; i < options.count(); ++i) ++ if (_cmdLine.isSet(options.at(i))) ++ return true; ++ return false; ++} ++ ++void Core::processCmdLineOpts(const QStringList& arguments) ++{ ++ _cmdLine.process(arguments); ++ ++ // Check commandline parameters and set screenshot type ++ for (int i=0; i < _screenTypeOpts.count(); ++i) ++ if (_cmdLine.isSet(_screenTypeOpts.at(i))) ++ _conf->setDefScreenshotType(i); ++ ++ initWindow(); ++} ++ ++bool Core::runAsMinimized() ++{ ++ return (_cmdLine.isSet(QStringLiteral("minimized")) || _cmdLine.isSet(QStringLiteral("m"))); ++} ++ ++void Core::autoSave() ++{ ++ QString format = _conf->getSaveFormat(); ++ QString fileName = getSaveFilePath(format); ++ writeScreen(fileName, format); ++} ++ ++QString Core::getVersionPrintable() ++{ ++ QString str = QStringLiteral("ScreenGrab: ") + qApp->applicationVersion() + QStringLiteral("\n"); ++ str += QStringLiteral("Qt: ") + QString::fromLatin1(qVersion()) + QStringLiteral("\n"); ++ return str; ++} ++ ++QPixmap* Core::getPixmap() ++{ ++ return _pixelMap; ++} ++ ++QByteArray Core::getScreenData() ++{ ++ QByteArray bytes; ++ QBuffer buffer(&bytes); ++ buffer.open(QIODevice::WriteOnly); ++ _pixelMap->save(&buffer, _conf->getSaveFormat().toLatin1().constData()); ++ return bytes; ++} ++ ++void Core::regionGrabbed(bool grabbed) ++{ ++ if (grabbed) ++ { ++ *_pixelMap = _selector->getSelection(); ++ ++ int x = _selector->getSelectionStartPos().x(); ++ int y = _selector->getSelectionStartPos().y(); ++ int w = _pixelMap->rect().width() / _pixelMap->devicePixelRatio(); ++ int h = _pixelMap->rect().height() / _pixelMap->devicePixelRatio(); ++ _lastSelectedArea.setRect(x, y, w, h); ++ ++ checkAutoSave(); ++ } ++ ++ _wnd->updatePixmap(_pixelMap); ++ _selector->deleteLater(); ++} |