diff --git a/src/config/shortcutswidget.cpp b/src/config/shortcutswidget.cpp index 4345d742..5951c2d0 100644 --- a/src/config/shortcutswidget.cpp +++ b/src/config/shortcutswidget.cpp @@ -17,6 +17,7 @@ #include "shortcutswidget.h" #include "setshortcutwidget.h" +#include "src/core/qguiappcurrentscreen.h" #include #include #include @@ -28,7 +29,6 @@ #if (QT_VERSION >= QT_VERSION_CHECK(5, 10, 0)) #include -#include #include #include #endif @@ -42,7 +42,7 @@ ShortcutsWidget::ShortcutsWidget(QWidget* parent) #if (QT_VERSION >= QT_VERSION_CHECK(5, 10, 0)) QRect position = frameGeometry(); - QScreen* screen = QGuiApplication::screenAt(QCursor::pos()); + QScreen* screen = QGuiAppCurrentScreen().currentScreen(); position.moveCenter(screen->availableGeometry().center()); move(position.topLeft()); #endif diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt index 39e35b6b..703fd89a 100644 --- a/src/core/CMakeLists.txt +++ b/src/core/CMakeLists.txt @@ -1,8 +1,8 @@ # Required to generate MOC -target_sources(flameshot PRIVATE controller.h flameshotdbusadapter.h) +target_sources(flameshot PRIVATE controller.h flameshotdbusadapter.h qguiappcurrentscreen.h) -target_sources(flameshot PRIVATE capturerequest.cpp controller.cpp flameshotdbusadapter.cpp) +target_sources(flameshot PRIVATE capturerequest.cpp controller.cpp flameshotdbusadapter.cpp qguiappcurrentscreen.cpp) IF (WIN32) target_sources(flameshot PRIVATE globalshortcutfilter.h globalshortcutfilter.cpp) diff --git a/src/core/controller.cpp b/src/core/controller.cpp index e388731a..bfecc515 100644 --- a/src/core/controller.cpp +++ b/src/core/controller.cpp @@ -18,6 +18,7 @@ #include "controller.h" #include "external/QHotkey/QHotkey" #include "src/config/configwindow.h" +#include "src/core/qguiappcurrentscreen.h" #include "src/utils/confighandler.h" #include "src/utils/history.h" #include "src/utils/screengrabber.h" @@ -99,7 +100,7 @@ Controller::Controller() // Try to take a test screenshot, MacOS will request a "Screen Recording" // permissions on the first run. Otherwise it will be hidden under the // CaptureWidget - QScreen* currentScreen = QGuiApplication::screenAt(QCursor::pos()); + QScreen* currentScreen = QGuiAppCurrentScreen().currentScreen(); currentScreen->grabWindow(QApplication::desktop()->winId(), 0, 0, 1, 1); // set global shortcuts for MacOS @@ -266,15 +267,16 @@ void Controller::startVisualCapture(const uint id, if (nullptr == m_captureWindow) { int timeout = 5000; // 5 seconds - for (; timeout >= 0; timeout -= 10) { - QWidget* modalWidget = qApp->activeModalWidget(); - if (modalWidget) { - modalWidget->close(); - modalWidget->deleteLater(); - } else { + const int delay = 100; + QWidget* modalWidget = nullptr; + for (; timeout >= 0; timeout -= delay) { + modalWidget = qApp->activeModalWidget(); + if (nullptr == modalWidget) { break; } - QThread::msleep(10); + modalWidget->close(); + modalWidget->deleteLater(); + QThread::msleep(delay); } if (0 == timeout) { QMessageBox::warning( @@ -492,6 +494,15 @@ void Controller::enableTrayIcon() #endif m_trayIcon->show(); + if (ConfigHandler().showStartupLaunchMessage()) { + m_trayIcon->showMessage( + "Flameshot", + QObject::tr( + "Hello, I'm here! Click icon in the tray to take a screenshot or " + "click with a right button to see more options."), + QSystemTrayIcon::Information, + 3000); + } } void Controller::disableTrayIcon() diff --git a/src/core/qguiappcurrentscreen.cpp b/src/core/qguiappcurrentscreen.cpp new file mode 100644 index 00000000..a69effac --- /dev/null +++ b/src/core/qguiappcurrentscreen.cpp @@ -0,0 +1,65 @@ +// +// Created by yuriypuchkov on 09.02.2021. +// + +#include "qguiappcurrentscreen.h" +#include +#include +#include +#include +#include + +QGuiAppCurrentScreen::QGuiAppCurrentScreen() +{ + m_currentScreen = nullptr; +} + +QScreen* QGuiAppCurrentScreen::currentScreen() +{ + return currentScreen(QCursor::pos()); +} + +QScreen* QGuiAppCurrentScreen::currentScreen(const QPoint& pos) +{ + m_currentScreen = screenAt(pos); +#if (defined(Q_OS_MAC) || defined(Q_OS_MAC64) || defined(Q_OS_MACOS) || \ + defined(Q_OS_MACX)) + // On the MacOS if mouse position is at the edge of bottom or right sides + // qGuiApp->screenAt will return nullptr, so we need to try to find current + // screen by moving 1 pixel inside to the current desktop area + if (!m_currentScreen && pos.x() > 0) { + QPoint posCorrected(pos.x() - 1, pos.y()); + m_currentScreen = screenAt(posCorrected); + } + if (!m_currentScreen && pos.y() > 0) { + QPoint posCorrected(pos.x(), pos.y() - 1); + m_currentScreen = screenAt(posCorrected); + } + if (!m_currentScreen && pos.x() > 0 && pos.y() > 0) { + QPoint posCorrected(pos.x() - 1, pos.y() - 1); + m_currentScreen = screenAt(posCorrected); + } +#endif + if (!m_currentScreen) { + qCritical("Unable to get current screen, starting to use primary " + "screen. It may be a cause of logical error and working with " + "a wrong screen."); + m_currentScreen = qGuiApp->primaryScreen(); + } + return m_currentScreen; +} + +QScreen* QGuiAppCurrentScreen::screenAt(const QPoint& pos) +{ +#if (QT_VERSION >= QT_VERSION_CHECK(5, 10, 0)) + m_currentScreen = qGuiApp->screenAt(pos); +#else + for (QScreen* const screen : QGuiApplication::screens()) { + m_currentScreen = screen; + if (screen->geometry().contains(pos)) { + break; + } + } +#endif + return m_currentScreen; +} \ No newline at end of file diff --git a/src/core/qguiappcurrentscreen.h b/src/core/qguiappcurrentscreen.h new file mode 100644 index 00000000..8d43dc80 --- /dev/null +++ b/src/core/qguiappcurrentscreen.h @@ -0,0 +1,27 @@ +// +// Created by yuriypuchkov on 09.02.2021. +// + +#ifndef FLAMESHOT_QGUIAPPCURRENTSCREEN_H +#define FLAMESHOT_QGUIAPPCURRENTSCREEN_H + +#include + +class QScreen; + +class QGuiAppCurrentScreen +{ +public: + explicit QGuiAppCurrentScreen(); + QScreen* currentScreen(); + QScreen* currentScreen(const QPoint& pos); + +private: + QScreen* screenAt(const QPoint& pos); + + // class members +private: + QScreen* m_currentScreen; +}; + +#endif // FLAMESHOT_QGUIAPPCURRENTSCREEN_H diff --git a/src/tools/abstracttwopointtool.cpp b/src/tools/abstracttwopointtool.cpp index 681d8312..728fd399 100644 --- a/src/tools/abstracttwopointtool.cpp +++ b/src/tools/abstracttwopointtool.cpp @@ -17,7 +17,6 @@ #include "abstracttwopointtool.h" #include -#include #include #include diff --git a/src/tools/pin/pintool.cpp b/src/tools/pin/pintool.cpp index 863d523b..6ef8bb5e 100644 --- a/src/tools/pin/pintool.cpp +++ b/src/tools/pin/pintool.cpp @@ -16,8 +16,8 @@ // along with Flameshot. If not, see . #include "pintool.h" +#include "src/core/qguiappcurrentscreen.h" #include "src/tools/pin/pinwidget.h" -#include #include PinTool::PinTool(QObject* parent) @@ -54,7 +54,7 @@ QWidget* PinTool::widget() qreal devicePixelRatio = 1; #if (defined(Q_OS_MAC) || defined(Q_OS_MAC64) || defined(Q_OS_MACOS) || \ defined(Q_OS_MACX)) - QScreen* currentScreen = QGuiApplication::screenAt(QCursor::pos()); + QScreen* currentScreen = QGuiAppCurrentScreen().currentScreen(); if (currentScreen) { devicePixelRatio = currentScreen->devicePixelRatio(); } diff --git a/src/utils/screengrabber.cpp b/src/utils/screengrabber.cpp index 306a41d6..e66154e8 100644 --- a/src/utils/screengrabber.cpp +++ b/src/utils/screengrabber.cpp @@ -16,6 +16,7 @@ // along with Flameshot. If not, see . #include "screengrabber.h" +#include "src/core/qguiappcurrentscreen.h" #include "src/utils/filenamehandler.h" #include "src/utils/systemnotification.h" #include @@ -40,7 +41,7 @@ QPixmap ScreenGrabber::grabEntireDesktop(bool& ok) ok = true; #if (defined(Q_OS_MAC) || defined(Q_OS_MAC64) || defined(Q_OS_MACOS) || \ defined(Q_OS_MACX)) - QScreen* currentScreen = QGuiApplication::screenAt(QCursor::pos()); + QScreen* currentScreen = QGuiAppCurrentScreen().currentScreen(); QPixmap screenPixmap( currentScreen->grabWindow(QApplication::desktop()->winId(), currentScreen->geometry().x(), diff --git a/src/widgets/capture/buttonhandler.cpp b/src/widgets/capture/buttonhandler.cpp index c45dba5d..c3d18640 100644 --- a/src/widgets/capture/buttonhandler.cpp +++ b/src/widgets/capture/buttonhandler.cpp @@ -17,7 +17,6 @@ #include "buttonhandler.h" #include "src/utils/globalvalues.h" -#include #include #include diff --git a/src/widgets/capture/capturewidget.cpp b/src/widgets/capture/capturewidget.cpp index 10c5cefb..df10d254 100644 --- a/src/widgets/capture/capturewidget.cpp +++ b/src/widgets/capture/capturewidget.cpp @@ -25,6 +25,7 @@ #include "capturewidget.h" #include "src/core/controller.h" +#include "src/core/qguiappcurrentscreen.h" #include "src/tools/toolfactory.h" #include "src/utils/colorutils.h" #include "src/utils/screengrabber.h" @@ -40,7 +41,6 @@ #include #include #include -#include #include #include #include @@ -113,12 +113,9 @@ CaptureWidget::CaptureWidget(const uint id, for (QScreen* const screen : QGuiApplication::screens()) { QPoint topLeftScreen = screen->geometry().topLeft(); - - if (topLeftScreen.x() < topLeft.x()) { - topLeft.setX(topLeftScreen.x()); - } - if (topLeftScreen.y() < topLeft.y()) { - topLeft.setY(topLeftScreen.y()); + if (topLeft.x() > topLeftScreen.x() || + topLeft.y() > topLeftScreen.y()) { + topLeft = topLeftScreen; } } move(topLeft); @@ -132,7 +129,7 @@ CaptureWidget::CaptureWidget(const uint id, // Qt::NoDropShadowWindowHint | Qt::ToolTip | // Qt::Popup // ); - QScreen* currentScreen = QGuiApplication::screenAt(QCursor::pos()); + QScreen* currentScreen = QGuiAppCurrentScreen().currentScreen(); move(currentScreen->geometry().x(), currentScreen->geometry().y()); resize(currentScreen->size()); #else @@ -153,12 +150,12 @@ CaptureWidget::CaptureWidget(const uint id, #if (defined(Q_OS_MAC) || defined(Q_OS_MAC64) || defined(Q_OS_MACOS) || \ defined(Q_OS_MACX)) - QPoint currentPos = QCursor::pos(); // MacOS works just with one active display, so we need to append // just one current display and keep multiple displays logic for // other OS - QScreen* const screen = qGuiApp->screenAt(currentPos); - QRect r = screen->geometry(); + QRect r; + QScreen* screen = QGuiAppCurrentScreen().currentScreen(); + r = screen->geometry(); // all calculations are processed according to (0, 0) start // point so we need to move current object to (0, 0) r.moveTo(0, 0); @@ -339,16 +336,17 @@ void CaptureWidget::paintEvent(QPaintEvent*) painter.setClipRect(rect()); if (m_showInitialMsg) { -#if (defined(Q_OS_LINUX) && QT_VERSION < QT_VERSION_CHECK(5, 10, 0)) - QRect helpRect = QGuiApplication::primaryScreen()->geometry(); -#else +#if (defined(Q_OS_MAC) || defined(Q_OS_MAC64) || defined(Q_OS_MACOS) || \ + defined(Q_OS_MACX)) QRect helpRect; - QScreen* currentScreen = QGuiApplication::screenAt(QCursor::pos()); + QScreen* currentScreen = QGuiAppCurrentScreen().currentScreen(); if (currentScreen) { helpRect = currentScreen->geometry(); } else { helpRect = QGuiApplication::primaryScreen()->geometry(); } +#else + QRect helpRect = QGuiApplication::primaryScreen()->geometry(); #endif helpRect.moveTo(mapFromGlobal(helpRect.topLeft())); @@ -472,7 +470,6 @@ void CaptureWidget::mouseMoveEvent(QMouseEvent* e) QPoint newTopLeft = initialRect.topLeft() + (e->pos() - m_dragStartPoint); inputRect = QRect(newTopLeft, initialRect.size()); - } else { // Dragging a handle inputRect = m_selection->savedGeometry(); @@ -729,7 +726,8 @@ void CaptureWidget::initPanel() panelRect.moveTo(panelRect.x() / devicePixelRatio, panelRect.y() / devicePixelRatio); #else - QScreen* currentScreen = QGuiApplication::screenAt(QCursor::pos()); + QScreen* currentScreen = QGuiAppCurrentScreen().currentScreen(); + if (currentScreen) { panelRect = currentScreen->geometry(); auto devicePixelRatio = currentScreen->devicePixelRatio(); @@ -770,7 +768,7 @@ void CaptureWidget::initPanel() makeChild(m_panel); #if (defined(Q_OS_MAC) || defined(Q_OS_MAC64) || defined(Q_OS_MACOS) || \ defined(Q_OS_MACX)) - QScreen* currentScreen = QGuiApplication::screenAt(QCursor::pos()); + QScreen* currentScreen = QGuiAppCurrentScreen().currentScreen(); panelRect.moveTo(mapFromGlobal(panelRect.topLeft())); m_panel->setFixedWidth(m_colorPicker->width() * 1.5); m_panel->setFixedHeight(currentScreen->geometry().height()); @@ -816,7 +814,10 @@ void CaptureWidget::showAppUpdateNotification(const QString& appLatestVersion, m_updateNotificationWidget = new UpdateNotificationWidget(this, appLatestVersion, appLatestUrl); } -#if (defined(Q_OS_LINUX) && QT_VERSION < QT_VERSION_CHECK(5, 10, 0)) +#if (defined(Q_OS_MAC) || defined(Q_OS_MAC64) || defined(Q_OS_MACOS) || \ + defined(Q_OS_MACX)) + int ax = (width() - m_updateNotificationWidget->width()) / 2; +#elif (defined(Q_OS_LINUX) && QT_VERSION < QT_VERSION_CHECK(5, 10, 0)) QRect helpRect = QGuiApplication::primaryScreen()->geometry(); #else QRect helpRect; @@ -826,10 +827,9 @@ void CaptureWidget::showAppUpdateNotification(const QString& appLatestVersion, } else { helpRect = QGuiApplication::primaryScreen()->geometry(); } -#endif int ax = helpRect.left() + ((helpRect.width() - m_updateNotificationWidget->width()) / 2); - +#endif m_updateNotificationWidget->move(ax, 0); makeChild(m_updateNotificationWidget); m_updateNotificationWidget->show(); diff --git a/src/widgets/infowindow.cpp b/src/widgets/infowindow.cpp index 6a7eaf71..83b76db1 100644 --- a/src/widgets/infowindow.cpp +++ b/src/widgets/infowindow.cpp @@ -16,6 +16,7 @@ // along with Flameshot. If not, see . #include "infowindow.h" +#include "src/core/qguiappcurrentscreen.h" #include #include #include @@ -23,8 +24,6 @@ #include #if (QT_VERSION >= QT_VERSION_CHECK(5, 10, 0)) -#include -#include #include #include #endif @@ -40,7 +39,7 @@ InfoWindow::InfoWindow(QWidget* parent) #if (QT_VERSION >= QT_VERSION_CHECK(5, 10, 0)) QRect position = frameGeometry(); - QScreen* screen = QGuiApplication::screenAt(QCursor::pos()); + QScreen* screen = QGuiAppCurrentScreen().currentScreen(); position.moveCenter(screen->availableGeometry().center()); move(position.topLeft()); #endif diff --git a/src/widgets/panel/sidepanelwidget.cpp b/src/widgets/panel/sidepanelwidget.cpp index 7c2a5d6e..00ffc152 100644 --- a/src/widgets/panel/sidepanelwidget.cpp +++ b/src/widgets/panel/sidepanelwidget.cpp @@ -16,6 +16,7 @@ // along with Flameshot. If not, see . #include "sidepanelwidget.h" +#include "src/core/qguiappcurrentscreen.h" #include "src/utils/colorutils.h" #include "src/utils/pathinfo.h" #include @@ -26,7 +27,6 @@ #include #if (defined(Q_OS_MAC) || defined(Q_OS_MAC64) || defined(Q_OS_MACOS) || \ defined(Q_OS_MACX)) -#include #include #endif @@ -168,7 +168,7 @@ QColor SidePanelWidget::grabPixmapColor(const QPoint& p) if (m_pixmap) { #if (defined(Q_OS_MAC) || defined(Q_OS_MAC64) || defined(Q_OS_MACOS) || \ defined(Q_OS_MACX)) - QScreen* currentScreen = QGuiApplication::screenAt(QCursor::pos()); + QScreen* currentScreen = QGuiAppCurrentScreen().currentScreen(); QPoint point = p; if (currentScreen) { point = QPoint((p.x() - currentScreen->geometry().x()) *