mirror of
https://github.com/fergalmoran/flameshot.git
synced 2025-12-22 09:51:06 +00:00
Fix - MacOS - get currentScreen on the edge bottom and right returns nullptr and application crashes
(cherry picked from commit 01ae74fbed34849db485db53ffbdf4a938ebea8e)
This commit is contained in:
@@ -17,6 +17,7 @@
|
||||
|
||||
#include "shortcutswidget.h"
|
||||
#include "setshortcutwidget.h"
|
||||
#include "src/core/qguiappcurrentscreen.h"
|
||||
#include <QHeaderView>
|
||||
#include <QIcon>
|
||||
#include <QKeyEvent>
|
||||
@@ -28,7 +29,6 @@
|
||||
|
||||
#if (QT_VERSION >= QT_VERSION_CHECK(5, 10, 0))
|
||||
#include <QCursor>
|
||||
#include <QGuiApplication>
|
||||
#include <QRect>
|
||||
#include <QScreen>
|
||||
#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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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()
|
||||
|
||||
65
src/core/qguiappcurrentscreen.cpp
Normal file
65
src/core/qguiappcurrentscreen.cpp
Normal file
@@ -0,0 +1,65 @@
|
||||
//
|
||||
// Created by yuriypuchkov on 09.02.2021.
|
||||
//
|
||||
|
||||
#include "qguiappcurrentscreen.h"
|
||||
#include <QCursor>
|
||||
#include <QDesktopWidget>
|
||||
#include <QGuiApplication>
|
||||
#include <QPoint>
|
||||
#include <QScreen>
|
||||
|
||||
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;
|
||||
}
|
||||
27
src/core/qguiappcurrentscreen.h
Normal file
27
src/core/qguiappcurrentscreen.h
Normal file
@@ -0,0 +1,27 @@
|
||||
//
|
||||
// Created by yuriypuchkov on 09.02.2021.
|
||||
//
|
||||
|
||||
#ifndef FLAMESHOT_QGUIAPPCURRENTSCREEN_H
|
||||
#define FLAMESHOT_QGUIAPPCURRENTSCREEN_H
|
||||
|
||||
#include <QPoint>
|
||||
|
||||
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
|
||||
@@ -17,7 +17,6 @@
|
||||
|
||||
#include "abstracttwopointtool.h"
|
||||
#include <QCursor>
|
||||
#include <QGuiApplication>
|
||||
#include <QScreen>
|
||||
#include <cmath>
|
||||
|
||||
|
||||
@@ -16,8 +16,8 @@
|
||||
// along with Flameshot. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
#include "pintool.h"
|
||||
#include "src/core/qguiappcurrentscreen.h"
|
||||
#include "src/tools/pin/pinwidget.h"
|
||||
#include <QGuiApplication>
|
||||
#include <QScreen>
|
||||
|
||||
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();
|
||||
}
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
// along with Flameshot. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
#include "screengrabber.h"
|
||||
#include "src/core/qguiappcurrentscreen.h"
|
||||
#include "src/utils/filenamehandler.h"
|
||||
#include "src/utils/systemnotification.h"
|
||||
#include <QApplication>
|
||||
@@ -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(),
|
||||
|
||||
@@ -17,7 +17,6 @@
|
||||
|
||||
#include "buttonhandler.h"
|
||||
#include "src/utils/globalvalues.h"
|
||||
#include <QGuiApplication>
|
||||
#include <QPoint>
|
||||
#include <QScreen>
|
||||
|
||||
|
||||
@@ -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 <QApplication>
|
||||
#include <QDateTime>
|
||||
#include <QDesktopWidget>
|
||||
#include <QGuiApplication>
|
||||
#include <QPaintEvent>
|
||||
#include <QPainter>
|
||||
#include <QScreen>
|
||||
@@ -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();
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
// along with Flameshot. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
#include "infowindow.h"
|
||||
#include "src/core/qguiappcurrentscreen.h"
|
||||
#include <QHeaderView>
|
||||
#include <QIcon>
|
||||
#include <QKeyEvent>
|
||||
@@ -23,8 +24,6 @@
|
||||
#include <QVBoxLayout>
|
||||
|
||||
#if (QT_VERSION >= QT_VERSION_CHECK(5, 10, 0))
|
||||
#include <QCursor>
|
||||
#include <QGuiApplication>
|
||||
#include <QRect>
|
||||
#include <QScreen>
|
||||
#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
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
// along with Flameshot. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
#include "sidepanelwidget.h"
|
||||
#include "src/core/qguiappcurrentscreen.h"
|
||||
#include "src/utils/colorutils.h"
|
||||
#include "src/utils/pathinfo.h"
|
||||
#include <QFormLayout>
|
||||
@@ -26,7 +27,6 @@
|
||||
#include <QVBoxLayout>
|
||||
#if (defined(Q_OS_MAC) || defined(Q_OS_MAC64) || defined(Q_OS_MACOS) || \
|
||||
defined(Q_OS_MACX))
|
||||
#include <QGuiApplication>
|
||||
#include <QScreen>
|
||||
#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()) *
|
||||
|
||||
Reference in New Issue
Block a user