Fix Windows capture with a screen on the left of the main screen

This commit is contained in:
lupoDharkael
2018-02-12 20:46:59 +01:00
parent db8a483b7f
commit b1174a1e05
5 changed files with 79 additions and 44 deletions

View File

@@ -24,15 +24,15 @@
// manipulate the buttons as a unit.
ButtonHandler::ButtonHandler(const QVector<CaptureButton*> &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<QPoint> ButtonHandler::horizontalPoints(
@@ -191,7 +191,7 @@ QVector<QPoint> 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<QPoint> ButtonHandler::verticalPoints(
@@ -218,7 +218,6 @@ QVector<QPoint> 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<QRect> &rects) {
m_screenRegions = QRegion();
for (QScreen *const screen : QGuiApplication::screens()) {
m_screenRegions += screen->geometry();
for (const QRect &rect: rects) {
m_screenRegions += rect;
}
}

View File

@@ -29,8 +29,8 @@ class QPoint;
class ButtonHandler : public QObject {
Q_OBJECT
public:
ButtonHandler(const QVector<CaptureButton*>&, const QRect &limits, QObject *parent = nullptr);
ButtonHandler(const QRect &limits, QObject *parent = nullptr);
ButtonHandler(const QVector<CaptureButton*>&, 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<CaptureButton*>);
bool contains(const QPoint &p) const;
void updateScreenRegions();
void updateScreenRegions(const QVector<QRect> &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();

View File

@@ -14,10 +14,10 @@
//
// You should have received a copy of the GNU General Public License
// along with Flameshot. If not, see <http://www.gnu.org/licenses/>.
// Based on Lightscreen areadialog.cpp, Copyright 2017 Christian Kaiser <info@ckaiser.com.ar>
// released under the GNU GPL2 <https://www.gnu.org/licenses/gpl-2.0.txt>
// Based on KDE's KSnapshot regiongrabber.cpp, revision 796531, Copyright 2007 Luca Gugelmann <lucag@student.ethz.ch>
// released under the GNU LGPL <http://www.gnu.org/licenses/old-licenses/library.txt>
@@ -38,13 +38,14 @@
#include <QPaintEvent>
#include <QMouseEvent>
#include <QBuffer>
#include <QDesktopWidget>
// 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<QRect> 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();

View File

@@ -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();

View File

@@ -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,