From b650231fa521bc4de7a063ded5580c36410a7229 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Haris=20Gu=C5=A1i=C4=87?= Date: Fri, 8 Oct 2021 22:24:27 +0200 Subject: [PATCH 1/3] Improve tool object performance (#1954) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Update tool object thickness in real time Signed-off-by: Haris Gušić * Fix update when drawing with modifier key Signed-off-by: Haris Gušić * Rename updateToolMousePreview to updateTool Signed-off-by: Haris Gušić * Fix update bug when changing tool size Signed-off-by: Haris Gušić --- src/widgets/capture/capturewidget.cpp | 40 +++++++++++++++++---------- src/widgets/capture/capturewidget.h | 2 +- 2 files changed, 26 insertions(+), 16 deletions(-) diff --git a/src/widgets/capture/capturewidget.cpp b/src/widgets/capture/capturewidget.cpp index 1c5bfa4c..c2408268 100644 --- a/src/widgets/capture/capturewidget.cpp +++ b/src/widgets/capture/capturewidget.cpp @@ -372,7 +372,7 @@ void CaptureWidget::uncheckActiveTool() // uncheck active tool m_panel->setToolWidget(nullptr); m_activeButton->setColor(m_uiColor); - updateToolMousePreview(activeButtonTool()); + updateTool(activeButtonTool()); m_activeButton = nullptr; releaseActiveTool(); updateSelectionState(); @@ -569,7 +569,7 @@ void CaptureWidget::mouseMoveEvent(QMouseEvent* e) { m_context.mousePos = e->pos(); if (e->buttons() != Qt::LeftButton) { - updateToolMousePreview(activeButtonTool()); + updateTool(activeButtonTool()); updateCursor(); return; } @@ -614,7 +614,7 @@ void CaptureWidget::mouseMoveEvent(QMouseEvent* e) m_activeTool->drawMove(e->pos()); } // update drawing object - updateToolMousePreview(m_activeTool); + updateTool(m_activeTool); // Hides the buttons under the mouse. If the mouse leaves, it shows // them. if (m_buttonHandler->buttonsAreInside()) { @@ -669,7 +669,7 @@ void CaptureWidget::mouseReleaseEvent(QMouseEvent* e) void CaptureWidget::updateThickness(int thickness) { auto tool = activeButtonTool(); - updateToolMousePreview(tool); + updateTool(tool); m_context.thickness = qBound(1, thickness, maxDrawThickness); QPoint topLeft = @@ -680,7 +680,7 @@ void CaptureWidget::updateThickness(int thickness) if (tool && tool->showMousePreview()) { setCursor(Qt::BlankCursor); - updateToolMousePreview(tool); + updateTool(tool); } // update selected object thickness @@ -691,6 +691,7 @@ void CaptureWidget::updateThickness(int thickness) m_captureToolObjectsBackup = m_captureToolObjects; m_existingObjectIsChanged = true; } + setDrawThickness(m_context.thickness); } emit thicknessChanged(m_context.thickness); } @@ -984,7 +985,7 @@ void CaptureWidget::setState(CaptureToolButton* b) loadDrawThickness(); updateCursor(); updateSelectionState(); - updateToolMousePreview(b->tool()); + updateTool(b->tool()); } } @@ -1161,6 +1162,7 @@ void CaptureWidget::setDrawThickness(int t) toolItem->onThicknessChanged(t); drawToolsData(); drawObjectSelection(); + updateTool(toolItem); } else { emit thicknessChanged(m_context.thickness); } @@ -1285,22 +1287,30 @@ void CaptureWidget::updateSelectionState() } } -void CaptureWidget::updateToolMousePreview(CaptureTool* tool) +void CaptureWidget::updateTool(CaptureTool* tool) { if (!tool || !tool->showMousePreview()) { return; } - static QRect oldRect; + static QRect oldPreviewRect, oldToolObjectRect; - QRect r(tool->mousePreviewRect(m_context)); - r += QMargins(r.width(), r.height(), r.width(), r.height()); + QRect previewRect(tool->mousePreviewRect(m_context)); + previewRect += QMargins(previewRect.width(), + previewRect.height(), + previewRect.width(), + previewRect.height()); QRect toolObjectRect = paddedUpdateRect(tool->boundingRect()); - // oldRect is united with the current rect to handle sudden mouse movement - update(r.united(oldRect).united(toolObjectRect)); - oldRect = r; + // old rects are united with current rects to handle sudden mouse movement + update(previewRect); + update(toolObjectRect); + update(oldPreviewRect); + update(oldToolObjectRect); + + oldPreviewRect = previewRect; + oldToolObjectRect = toolObjectRect; } void CaptureWidget::updateLayersPanel() @@ -1417,13 +1427,13 @@ void CaptureWidget::togglePanel() void CaptureWidget::childEnter() { m_previewEnabled = false; - updateToolMousePreview(activeButtonTool()); + updateTool(activeButtonTool()); } void CaptureWidget::childLeave() { m_previewEnabled = true; - updateToolMousePreview(activeButtonTool()); + updateTool(activeButtonTool()); } void CaptureWidget::copyScreenshot() diff --git a/src/widgets/capture/capturewidget.h b/src/widgets/capture/capturewidget.h index 4b9691e4..4d1b4b23 100644 --- a/src/widgets/capture/capturewidget.h +++ b/src/widgets/capture/capturewidget.h @@ -112,7 +112,7 @@ private: void updateSizeIndicator(); void updateCursor(); void updateSelectionState(); - void updateToolMousePreview(CaptureTool* tool); + void updateTool(CaptureTool* tool); void updateLayersPanel(); void pushToolToStack(); void makeChild(QWidget* w); From 454e8f887a4bcfa95344a1b7ea5346ce5ea6f731 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Haris=20Gu=C5=A1i=C4=87?= Date: Mon, 11 Oct 2021 03:27:23 +0200 Subject: [PATCH 2/3] Workaround for focus problem (#1958) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Haris Gušić --- src/widgets/capture/capturetoolbutton.cpp | 1 + src/widgets/capture/capturewidget.cpp | 40 +++++++++++++++-------- src/widgets/capture/capturewidget.h | 3 +- 3 files changed, 30 insertions(+), 14 deletions(-) diff --git a/src/widgets/capture/capturetoolbutton.cpp b/src/widgets/capture/capturetoolbutton.cpp index a54d8595..37205e48 100644 --- a/src/widgets/capture/capturetoolbutton.cpp +++ b/src/widgets/capture/capturetoolbutton.cpp @@ -97,6 +97,7 @@ QIcon CaptureToolButton::icon() const void CaptureToolButton::mousePressEvent(QMouseEvent* e) { + activateWindow(); if (e->button() == Qt::LeftButton) { emit pressedButton(this); emit pressed(); diff --git a/src/widgets/capture/capturewidget.cpp b/src/widgets/capture/capturewidget.cpp index c2408268..19b049d4 100644 --- a/src/widgets/capture/capturewidget.cpp +++ b/src/widgets/capture/capturewidget.cpp @@ -135,7 +135,7 @@ CaptureWidget::CaptureWidget(uint id, move(currentScreen->geometry().x(), currentScreen->geometry().y()); resize(currentScreen->size()); #else -// Call cmake with -DFLAMESHOT_DEBUG_CAPTURE=true to enable easier debugging +// Call cmake with -DFLAMESHOT_DEBUG_CAPTURE=ON to enable easier debugging #if !defined(FLAMESHOT_DEBUG_CAPTURE) setWindowFlags(Qt::BypassWindowManagerHint | Qt::WindowStaysOnTopHint | Qt::FramelessWindowHint | Qt::Tool); @@ -399,8 +399,17 @@ void CaptureWidget::paintEvent(QPaintEvent* paintEvent) // draw inactive region drawInactiveRegion(&painter); - if (m_configError || m_configErrorResolved) { - drawConfigErrorMessage(&painter); + if (!isActiveWindow()) { + drawErrorMessage( + tr("Flameshot has lost focus. Keyboard shortcuts won't " + "work until you click somewhere."), + &painter); + } else if (m_configError) { + drawErrorMessage(ConfigHandler().errorMessage(), &painter); + } else if (m_configErrorResolved) { + drawErrorMessage(tr("Configuration error resolved. Launch `flameshot " + "gui` again to apply it."), + &painter); } } @@ -497,6 +506,7 @@ int CaptureWidget::selectToolItemAtPos(const QPoint& pos) void CaptureWidget::mousePressEvent(QMouseEvent* e) { + activateWindow(); m_startMove = false; m_startMovePos = QPoint(); m_mousePressedPos = e->pos(); @@ -783,6 +793,16 @@ void CaptureWidget::moveEvent(QMoveEvent* e) m_context.widgetOffset = mapToGlobal(QPoint(0, 0)); } +void CaptureWidget::changeEvent(QEvent* e) +{ + if (e->type() == QEvent::ActivationChange) { + QPoint bottomRight = rect().bottomRight(); + // Update the message in the bottom right corner. A rough estimate is + // used for the update rect + update(QRect(bottomRight - QPoint(1000, 200), bottomRight)); + } +} + void CaptureWidget::initContext(const QString& savePath, bool fullscreen) { m_context.color = m_config.drawColor(); @@ -1532,19 +1552,13 @@ QRect CaptureWidget::paddedUpdateRect(const QRect& r) const } } -void CaptureWidget::drawConfigErrorMessage(QPainter* painter) +void CaptureWidget::drawErrorMessage(const QString& msg, QPainter* painter) { - QString msg; - if (m_configError) { - msg = ConfigHandler().errorMessage(); - } else if (m_configErrorResolved) { - msg = tr("Configuration error resolved. Launch `flameshot " - "gui` again to apply it."); - } - auto textRect = painter->fontMetrics().boundingRect(msg); int w = textRect.width(), h = textRect.height(); - textRect = { size().width() - w, size().height() - h, w + 100, h + 100 }; + textRect = { + size().width() - w - 10, size().height() - h - 5, w + 100, h + 100 + }; QScreen* currentScreen = QGuiAppCurrentScreen().currentScreen(); if (!textRect.contains(QCursor::pos(currentScreen))) { diff --git a/src/widgets/capture/capturewidget.h b/src/widgets/capture/capturewidget.h index 4d1b4b23..dd2e9559 100644 --- a/src/widgets/capture/capturewidget.h +++ b/src/widgets/capture/capturewidget.h @@ -94,6 +94,7 @@ protected: void wheelEvent(QWheelEvent* wheelEvent) override; void resizeEvent(QResizeEvent* resizeEvent) override; void moveEvent(QMoveEvent* moveEvent) override; + void changeEvent(QEvent* changeEvent) override; private: void loadDrawThickness(); @@ -122,7 +123,7 @@ private: QRect extendedSelection() const; QRect extendedRect(const QRect& r) const; QRect paddedUpdateRect(const QRect& r) const; - void drawConfigErrorMessage(QPainter* painter); + void drawErrorMessage(const QString& msg, QPainter* painter); void drawInactiveRegion(QPainter* painter); void drawToolsData(); void drawObjectSelection(); From 0e43d4b36f2b9d2df5731ebc0a3e1a97f8020563 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Haris=20Gu=C5=A1i=C4=87?= Date: Mon, 11 Oct 2021 03:32:00 +0200 Subject: [PATCH 3/3] Fix boundary bug with pixelate and invert tools (#1957) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Fix invert tool selection Signed-off-by: Haris Gušić * Fix pixelate tool Signed-off-by: Haris Gušić --- src/tools/invert/inverttool.cpp | 18 ++++-------------- src/tools/pixelate/pixelatetool.cpp | 21 ++++++--------------- 2 files changed, 10 insertions(+), 29 deletions(-) diff --git a/src/tools/invert/inverttool.cpp b/src/tools/invert/inverttool.cpp index 3f52ef4f..d8093ee6 100644 --- a/src/tools/invert/inverttool.cpp +++ b/src/tools/invert/inverttool.cpp @@ -37,11 +37,7 @@ QString InvertTool::description() const QRect InvertTool::boundingRect() const { - return QRect(std::min(points().first.x(), points().second.x()), - std::min(points().first.y(), points().second.y()), - std::abs(points().first.x() - points().second.x()), - std::abs(points().first.y() - points().second.y())) - .normalized(); + return QRect(points().first, points().second).normalized(); } CaptureTool* InvertTool::copy(QObject* parent) @@ -53,26 +49,20 @@ CaptureTool* InvertTool::copy(QObject* parent) void InvertTool::process(QPainter& painter, const QPixmap& pixmap) { - QPoint p0 = points().first; - QPoint p1 = points().second; - QRect selection = QRect(p0, p1).normalized(); + QRect selection = boundingRect(); // Invert selection QPixmap inv = pixmap.copy(selection); QImage img = inv.toImage(); img.invertPixels(); - painter.drawImage(selection, img); + painter.drawImage(selection.intersected(pixmap.rect()), img); } void InvertTool::drawSearchArea(QPainter& painter, const QPixmap& pixmap) { Q_UNUSED(pixmap) - painter.fillRect(std::min(points().first.x(), points().second.x()), - std::min(points().first.y(), points().second.y()), - std::abs(points().first.x() - points().second.x()), - std::abs(points().first.y() - points().second.y()), - QBrush(Qt::black)); + painter.fillRect(boundingRect(), QBrush(Qt::black)); } void InvertTool::paintMousePreview(QPainter& painter, diff --git a/src/tools/pixelate/pixelatetool.cpp b/src/tools/pixelate/pixelatetool.cpp index d1ddef79..654b77a7 100644 --- a/src/tools/pixelate/pixelatetool.cpp +++ b/src/tools/pixelate/pixelatetool.cpp @@ -18,6 +18,7 @@ QIcon PixelateTool::icon(const QColor& background, bool inEditor) const Q_UNUSED(inEditor) return QIcon(iconPath(background) + "pixelate.svg"); } + QString PixelateTool::name() const { return tr("Pixelate"); @@ -35,11 +36,7 @@ QString PixelateTool::description() const QRect PixelateTool::boundingRect() const { - return QRect(std::min(points().first.x(), points().second.x()), - std::min(points().first.y(), points().second.y()), - std::abs(points().first.x() - points().second.x()), - std::abs(points().first.y() - points().second.y())) - .normalized(); + return QRect(points().first, points().second).normalized(); } CaptureTool* PixelateTool::copy(QObject* parent) @@ -51,12 +48,10 @@ CaptureTool* PixelateTool::copy(QObject* parent) void PixelateTool::process(QPainter& painter, const QPixmap& pixmap) { - QPoint p0 = points().first; - QPoint p1 = points().second; - QRect selection = QRect(p0, p1).normalized(); + QRect selection = boundingRect().intersected(pixmap.rect()); auto pixelRatio = pixmap.devicePixelRatio(); - QRect selectionScaled = - QRect(p0 * pixelRatio, p1 * pixelRatio).normalized(); + QRect selectionScaled = QRect(selection.topLeft() * pixelRatio, + selection.bottomRight() * pixelRatio); // If thickness is less than 1, use old blur process if (thickness() <= 1) { @@ -91,11 +86,7 @@ void PixelateTool::process(QPainter& painter, const QPixmap& pixmap) void PixelateTool::drawSearchArea(QPainter& painter, const QPixmap& pixmap) { Q_UNUSED(pixmap) - painter.fillRect(std::min(points().first.x(), points().second.x()), - std::min(points().first.y(), points().second.y()), - std::abs(points().first.x() - points().second.x()), - std::abs(points().first.y() - points().second.y()), - QBrush(Qt::black)); + painter.fillRect(boundingRect(), QBrush(Qt::black)); } void PixelateTool::paintMousePreview(QPainter& painter,