From b1174a1e0501fff9e1d09bdf14028ca230746fe5 Mon Sep 17 00:00:00 2001 From: lupoDharkael Date: Mon, 12 Feb 2018 20:46:59 +0100 Subject: [PATCH] Fix Windows capture with a screen on the left of the main screen --- src/capture/widgets/buttonhandler.cpp | 21 ++++---- src/capture/widgets/buttonhandler.h | 14 +++--- src/capture/widgets/capturewidget.cpp | 70 +++++++++++++++++++++------ src/capture/widgets/capturewidget.h | 7 +++ src/core/controller.cpp | 11 ----- 5 files changed, 79 insertions(+), 44 deletions(-) diff --git a/src/capture/widgets/buttonhandler.cpp b/src/capture/widgets/buttonhandler.cpp index eb5afca0..88be6ae3 100644 --- a/src/capture/widgets/buttonhandler.cpp +++ b/src/capture/widgets/buttonhandler.cpp @@ -24,15 +24,15 @@ // manipulate the buttons as a unit. ButtonHandler::ButtonHandler(const QVector &v, - const QRect &limits, QObject *parent) : - QObject(parent), m_limits(limits) + QObject *parent) : + QObject(parent) { setButtons(v); init(); } -ButtonHandler::ButtonHandler(const QRect &limits, QObject *parent) : - QObject(parent), m_limits(limits) +ButtonHandler::ButtonHandler(QObject *parent) : + QObject(parent) { init(); } @@ -69,7 +69,7 @@ size_t ButtonHandler::size() const { return m_vectorButtons.size(); } -// UpdatePosition updates the position of the buttons around the +// updatePosition updates the position of the buttons around the // selection area. Ignores the sides blocked by the end of the screen. // When the selection is too small it works on a virtual selection with // the original in the center. @@ -165,7 +165,7 @@ void ButtonHandler::updatePosition(const QRect &selection) { } } -// GetHPoints is an auxiliar method for the button position computation. +// horizontalPoints is an auxiliar method for the button position computation. // starts from a known center and keeps adding elements horizontally // and returns the computed positions. QVector ButtonHandler::horizontalPoints( @@ -191,7 +191,7 @@ QVector ButtonHandler::horizontalPoints( return res; } -// getHPoints is an auxiliar method for the button position computation. +// verticalPoints is an auxiliar method for the button position computation. // starts from a known center and keeps adding elements vertically // and returns the computed positions. QVector ButtonHandler::verticalPoints( @@ -218,7 +218,6 @@ QVector ButtonHandler::verticalPoints( } void ButtonHandler::init() { - updateScreenRegions(); m_separator = CaptureButton::buttonBaseSize() / 4; } @@ -367,9 +366,9 @@ bool ButtonHandler::contains(const QPoint &p) const { return r.contains(p); } -void ButtonHandler::updateScreenRegions() { +void ButtonHandler::updateScreenRegions(const QVector &rects) { m_screenRegions = QRegion(); - for (QScreen *const screen : QGuiApplication::screens()) { - m_screenRegions += screen->geometry(); + for (const QRect &rect: rects) { + m_screenRegions += rect; } } diff --git a/src/capture/widgets/buttonhandler.h b/src/capture/widgets/buttonhandler.h index 0fa0f780..f9a43055 100644 --- a/src/capture/widgets/buttonhandler.h +++ b/src/capture/widgets/buttonhandler.h @@ -29,8 +29,8 @@ class QPoint; class ButtonHandler : public QObject { Q_OBJECT public: - ButtonHandler(const QVector&, const QRect &limits, QObject *parent = nullptr); - ButtonHandler(const QRect &limits, QObject *parent = nullptr); + ButtonHandler(const QVector&, QObject *parent = nullptr); + ButtonHandler(QObject *parent = nullptr); void hideSectionUnderMouse(const QPoint &p); @@ -41,7 +41,7 @@ public: void updatePosition(const QRect &selection); void setButtons(const QVector); bool contains(const QPoint &p) const; - void updateScreenRegions(); + void updateScreenRegions(const QVector &rects); public slots: void hide(); @@ -57,6 +57,9 @@ private: QRegion m_screenRegions; + QRect m_selection; + + int m_separator; int m_buttonExtendedSize; int m_buttonBaseSize; @@ -69,11 +72,6 @@ private: bool m_horizontalyBlocked; bool m_allSidesBlocked; - QRect m_limits; - QRect m_selection; - - int m_separator; - // aux methods void init(); void resetRegionTrack(); diff --git a/src/capture/widgets/capturewidget.cpp b/src/capture/widgets/capturewidget.cpp index a2ee94ee..615e228e 100644 --- a/src/capture/widgets/capturewidget.cpp +++ b/src/capture/widgets/capturewidget.cpp @@ -14,10 +14,10 @@ // // You should have received a copy of the GNU General Public License // along with Flameshot. If not, see . - + // Based on Lightscreen areadialog.cpp, Copyright 2017 Christian Kaiser // released under the GNU GPL2 - + // Based on KDE's KSnapshot regiongrabber.cpp, revision 796531, Copyright 2007 Luca Gugelmann // released under the GNU LGPL @@ -38,13 +38,14 @@ #include #include #include +#include // CaptureWidget is the main component used to capture the screen. It contains an // are of selection with its respective buttons. // enableSaveWIndow CaptureWidget::CaptureWidget(const uint id, const QString &forcedSavePath, - QWidget *parent) : + CaptureWidget::LaunchMode mode, QWidget *parent) : QWidget(parent), m_screenshot(nullptr), m_mouseOverHandle(0), m_mouseIsClicked(false), m_rightClick(false), m_newSelection(false), m_grabbing(false), m_captureDone(false), m_toolIsForDrawing(false), @@ -75,26 +76,62 @@ CaptureWidget::CaptureWidget(const uint id, const QString &forcedSavePath, updateCursor(); initShortcuts(); - // init content - bool ok = true; - QPixmap fullScreenshot(ScreenGrabber().grabEntireDesktop(ok)); - if(!ok) { - SystemNotification().sendMessage(tr("Unable to capture screen")); - this->close(); - } - m_screenshot = new Screenshot(fullScreenshot, this); +#ifdef Q_OS_WIN + QPoint topLeft(0,0); +#endif + if (mode == FULLSCREEN) { + // init content + bool ok = true; + QPixmap fullScreenshot(ScreenGrabber().grabEntireDesktop(ok)); + if(!ok) { + SystemNotification().sendMessage(tr("Unable to capture screen")); + this->close(); + } + m_screenshot = new Screenshot(fullScreenshot, this); +#ifdef Q_OS_WIN + setWindowFlags(Qt::WindowStaysOnTopHint + | Qt::FramelessWindowHint + | Qt::Popup); + + for (QScreen *const screen : QGuiApplication::screens()) { + QPoint topLeftScreen = screen->geometry().topLeft(); + if (topLeft.x() > topLeftScreen.x() || + topLeft.y() > topLeftScreen.y()) { + topLeft = topLeftScreen; + } + } + move(topLeft); +#else + setWindowFlags(Qt::BypassWindowManagerHint + | Qt::WindowStaysOnTopHint + | Qt::FramelessWindowHint + | Qt::Tool); +#endif + resize(pixmap().size()); + } // create buttons - m_buttonHandler = new ButtonHandler(rect(), this); + m_buttonHandler = new ButtonHandler(this); updateButtons(); + QVector areas; + if (mode == FULLSCREEN) { + for (QScreen *const screen : QGuiApplication::screens()) { + QRect r = screen->geometry(); +#ifdef Q_OS_WIN + r.moveTo(r.topLeft() - topLeft); +#endif + areas.append(r); + } + } else { + areas.append(rect()); + } + m_buttonHandler->updateScreenRegions(areas); m_buttonHandler->hide(); // init interface color m_colorPicker = new ColorPicker(this); m_colorPicker->hide(); m_notifierBox = new NotifierBox(this); - auto geometry = QGuiApplication::primaryScreen()->geometry(); - m_notifierBox->move(geometry.left() +20, geometry.left() +20); m_notifierBox->hide(); } @@ -179,6 +216,7 @@ void CaptureWidget::paintEvent(QPaintEvent *) { if (m_showInitialMsg) { QRect helpRect = QGuiApplication::primaryScreen()->geometry(); + helpRect.moveTo(mapFromGlobal(helpRect.topLeft())); QString helpTxt = tr("Select an area with the mouse, or press Esc to exit." "\nPress Enter to capture the screen." @@ -417,6 +455,10 @@ void CaptureWidget::keyPressEvent(QKeyEvent *e) { void CaptureWidget::wheelEvent(QWheelEvent *e) { m_thickness += e->delta() / 120; m_thickness = qBound(0, m_thickness, 100); + QPoint topLeft = qApp->desktop()->screenGeometry( + qApp->desktop()->screenNumber(QCursor::pos())).topLeft(); + int offset = m_notifierBox->width() / 4; + m_notifierBox->move(mapFromGlobal(topLeft) + QPoint(offset, offset)); m_notifierBox->showMessage(QString::number(m_thickness)); if (m_toolIsForDrawing) { update(); diff --git a/src/capture/widgets/capturewidget.h b/src/capture/widgets/capturewidget.h index bca575dc..9ac07903 100644 --- a/src/capture/widgets/capturewidget.h +++ b/src/capture/widgets/capturewidget.h @@ -44,11 +44,18 @@ class CaptureWidget : public QWidget { Q_OBJECT public: + enum LaunchMode { + WINDOW_MODE, + FULLSCREEN, + }; + explicit CaptureWidget(const uint id = 0, const QString &forcedSavePath = QString(), + CaptureWidget::LaunchMode mode = LaunchMode::FULLSCREEN, QWidget *parent = nullptr); ~CaptureWidget(); + void updateButtons(); QPixmap pixmap(); diff --git a/src/core/controller.cpp b/src/core/controller.cpp index 9324d2ae..bc339f0d 100644 --- a/src/core/controller.cpp +++ b/src/core/controller.cpp @@ -74,17 +74,6 @@ void Controller::createVisualCapture(const uint id, const QString &forcedSavePat } while (modalWidget); m_captureWindow = new CaptureWidget(id, forcedSavePath); -#ifdef Q_OS_WIN - m_captureWindow->setWindowFlags(Qt::WindowStaysOnTopHint - | Qt::FramelessWindowHint - | Qt::Popup); -#else - m_captureWindow->setWindowFlags(Qt::BypassWindowManagerHint - | Qt::WindowStaysOnTopHint - | Qt::FramelessWindowHint - | Qt::Tool); -#endif - m_captureWindow->resize(m_captureWindow->pixmap().size()); connect(m_captureWindow, &CaptureWidget::captureFailed, this, &Controller::captureFailed); connect(m_captureWindow, &CaptureWidget::captureTaken,