-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(effect): allow mousemark to configure modifier buttons for drawing
Hard-coded modifiers Shift+Meta may interfere with some other actions. FEATURE: 337043
- Loading branch information
Showing
5 changed files
with
262 additions
and
42 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,6 @@ | ||
/* | ||
SPDX-FileCopyrightText: 2021 Vlad Zahorodnii <[email protected]> | ||
SPDX-FileCopyrightText: 2023 Andrew Shark <ashark at linuxcomp.ru> | ||
SPDX-License-Identifier: GPL-2.0-or-later | ||
*/ | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1,7 @@ | ||
/* | ||
SPDX-FileCopyrightText: 2006 Lubos Lunak <[email protected]> | ||
SPDX-FileCopyrightText: 2007 Christian Nitschkowski <[email protected]> | ||
SPDX-FileCopyrightText: 2023 Andrew Shark <ashark at linuxcomp.ru> | ||
SPDX-License-Identifier: GPL-2.0-or-later | ||
*/ | ||
|
@@ -16,10 +17,13 @@ SPDX-License-Identifier: GPL-2.0-or-later | |
|
||
#include <KLocalizedString> | ||
#include <QAction> | ||
#include <QLoggingCategory> | ||
#include <QPainter> | ||
|
||
#include <cmath> | ||
|
||
Q_LOGGING_CATEGORY(KWIN_MOUSEMARK, "kwin_effect_mousemark", QtWarningMsg) | ||
|
||
namespace KWin | ||
{ | ||
|
||
|
@@ -50,7 +54,7 @@ MouseMarkEffect::MouseMarkEffect() | |
this, | ||
&MouseMarkEffect::screenLockingChanged); | ||
reconfigure(ReconfigureAll); | ||
arrow_start = nullPoint(); | ||
arrow_tail = nullPoint(); | ||
effects->startMousePolling(); // We require it to detect activation as well | ||
} | ||
|
||
|
@@ -62,11 +66,38 @@ MouseMarkEffect::~MouseMarkEffect() | |
static int width_2 = 1; | ||
void MouseMarkEffect::reconfigure(ReconfigureFlags) | ||
{ | ||
m_freedraw_modifiers = Qt::KeyboardModifiers(); | ||
m_arrowdraw_modifiers = Qt::KeyboardModifiers(); | ||
MouseMarkConfig::self()->read(); | ||
width = MouseMarkConfig::lineWidth(); | ||
width_2 = width / 2; | ||
color = MouseMarkConfig::color(); | ||
color.setAlphaF(1.0); | ||
if (MouseMarkConfig::freedrawshift()) { | ||
m_freedraw_modifiers |= Qt::ShiftModifier; | ||
} | ||
if (MouseMarkConfig::freedrawalt()) { | ||
m_freedraw_modifiers |= Qt::AltModifier; | ||
} | ||
if (MouseMarkConfig::freedrawcontrol()) { | ||
m_freedraw_modifiers |= Qt::ControlModifier; | ||
} | ||
if (MouseMarkConfig::freedrawmeta()) { | ||
m_freedraw_modifiers |= Qt::MetaModifier; | ||
} | ||
|
||
if (MouseMarkConfig::arrowdrawshift()) { | ||
m_arrowdraw_modifiers |= Qt::ShiftModifier; | ||
} | ||
if (MouseMarkConfig::arrowdrawalt()) { | ||
m_arrowdraw_modifiers |= Qt::AltModifier; | ||
} | ||
if (MouseMarkConfig::arrowdrawcontrol()) { | ||
m_arrowdraw_modifiers |= Qt::ControlModifier; | ||
} | ||
if (MouseMarkConfig::arrowdrawmeta()) { | ||
m_arrowdraw_modifiers |= Qt::MetaModifier; | ||
} | ||
} | ||
|
||
void MouseMarkEffect::paintScreen(effect::screen_paint_data& data) | ||
|
@@ -146,22 +177,34 @@ void MouseMarkEffect::slotMouseChanged(const QPoint& pos, | |
Qt::KeyboardModifiers modifiers, | ||
Qt::KeyboardModifiers) | ||
{ | ||
if (modifiers == (Qt::META | Qt::SHIFT | Qt::CTRL)) { // start/finish arrow | ||
if (arrow_start != nullPoint()) { | ||
marks.append(createArrow(arrow_start, pos)); | ||
arrow_start = nullPoint(); | ||
qCDebug(KWIN_MOUSEMARK) << "MouseChanged" << pos; | ||
if (modifiers == m_arrowdraw_modifiers | ||
&& m_arrowdraw_modifiers != Qt::NoModifier) { // start/finish arrow | ||
if (arrow_tail != nullPoint()) { | ||
if (drawing.length() != 0) { | ||
clearLast(); // clear our arrow with tail at previous position | ||
} | ||
drawing = createArrow(pos, arrow_tail); | ||
effects->addRepaintFull(); | ||
return; | ||
} else | ||
arrow_start = pos; | ||
} | ||
if (arrow_start != nullPoint()) { | ||
return; | ||
} | ||
// TODO the shortcuts now trigger this right before they're activated | ||
if (modifiers == (Qt::META | Qt::SHIFT)) { // activated | ||
if (drawing.isEmpty()) | ||
} else { | ||
if (drawing.length() > 0) { // has unfinished freedraw right before arrowdraw | ||
marks.append(drawing); | ||
drawing.clear(); | ||
} | ||
arrow_tail = pos; | ||
} | ||
} else if (modifiers == m_freedraw_modifiers && m_freedraw_modifiers != Qt::NoModifier) { | ||
// activated | ||
if (arrow_tail != nullPoint()) { | ||
// for the case when user started freedraw right after arrowdraw | ||
arrow_tail = nullPoint(); | ||
marks.append(drawing); | ||
drawing.clear(); | ||
} | ||
if (drawing.isEmpty()) { | ||
drawing.append(pos); | ||
} | ||
if (drawing.last() == pos) | ||
return; | ||
QPoint pos2 = drawing.last(); | ||
|
@@ -172,24 +215,27 @@ void MouseMarkEffect::slotMouseChanged(const QPoint& pos, | |
qMax(pos.y(), pos2.y())); | ||
repaint.adjust(-width, -width, width, width); | ||
effects->addRepaint(repaint); | ||
} else if (!drawing.isEmpty()) { | ||
marks.append(drawing); | ||
drawing.clear(); | ||
} else { // neither freedraw, nor arrowdraw modifiers pressed, but mouse moved | ||
if (drawing.length() > 1) { | ||
marks.append(drawing); | ||
drawing.clear(); | ||
} | ||
arrow_tail = nullPoint(); | ||
} | ||
} | ||
|
||
void MouseMarkEffect::clear() | ||
{ | ||
arrow_tail = nullPoint(); | ||
drawing.clear(); | ||
marks.clear(); | ||
effects->addRepaintFull(); | ||
} | ||
|
||
void MouseMarkEffect::clearLast() | ||
{ | ||
if (arrow_start != nullPoint()) { | ||
arrow_start = nullPoint(); | ||
} else if (!drawing.isEmpty()) { | ||
if (drawing.length() > 1) { // just pressing a modifiers already create a drawing with 1 point | ||
// (so not visible), treat it as non-existent | ||
drawing.clear(); | ||
effects->addRepaintFull(); | ||
} else if (!marks.isEmpty()) { | ||
|
@@ -198,19 +244,21 @@ void MouseMarkEffect::clearLast() | |
} | ||
} | ||
|
||
MouseMarkEffect::Mark MouseMarkEffect::createArrow(QPoint arrow_start, QPoint arrow_end) | ||
MouseMarkEffect::Mark MouseMarkEffect::createArrow(QPoint arrow_head, QPoint arrow_tail) | ||
{ | ||
Mark ret; | ||
double angle = atan2(static_cast<double>(arrow_end.y() - arrow_start.y()), | ||
static_cast<double>(arrow_end.x() - arrow_start.x())); | ||
ret += arrow_start | ||
+ QPoint(50 * cos(angle + M_PI / 6), | ||
50 * sin(angle + M_PI / 6)); // right one | ||
ret += arrow_start; | ||
ret += arrow_end; | ||
ret += arrow_start; // it's connected lines, so go back with the middle one | ||
ret += arrow_start + QPoint(50 * cos(angle - M_PI / 6), | ||
50 * sin(angle - M_PI / 6)); // left one | ||
double angle = atan2((double)(arrow_tail.y() - arrow_head.y()), | ||
(double)(arrow_tail.x() - arrow_head.x())); | ||
// Arrow is made of connected lines. We make it's last point at tail, so freedraw can begin from | ||
// the tail | ||
ret += arrow_head; | ||
ret += arrow_head + QPoint(50 * cos(angle + M_PI / 6), | ||
50 * sin(angle + M_PI / 6)); // right one | ||
ret += arrow_head; | ||
ret += arrow_head + QPoint(50 * cos(angle - M_PI / 6), | ||
50 * sin(angle - M_PI / 6)); // left one | ||
ret += arrow_head; | ||
ret += arrow_tail; | ||
return ret; | ||
} | ||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,6 @@ | ||
/* | ||
SPDX-FileCopyrightText: 2007 Lubos Lunak <[email protected]> | ||
SPDX-FileCopyrightText: 2023 Andrew Shark <ashark at linuxcomp.ru> | ||
SPDX-License-Identifier: GPL-2.0-or-later | ||
*/ | ||
|
@@ -17,6 +18,8 @@ class MouseMarkEffect : public Effect | |
Q_OBJECT | ||
Q_PROPERTY(int width READ configuredWidth) | ||
Q_PROPERTY(QColor color READ configuredColor) | ||
Q_PROPERTY(Qt::KeyboardModifiers modifiers READ freedraw_modifiers) | ||
Q_PROPERTY(Qt::KeyboardModifiers modifiers READ arrowdraw_modifiers) | ||
public: | ||
MouseMarkEffect(); | ||
~MouseMarkEffect() override; | ||
|
@@ -34,6 +37,14 @@ class MouseMarkEffect : public Effect | |
{ | ||
return color; | ||
} | ||
Qt::KeyboardModifiers freedraw_modifiers() const | ||
{ | ||
return m_freedraw_modifiers; | ||
} | ||
Qt::KeyboardModifiers arrowdraw_modifiers() const | ||
{ | ||
return m_freedraw_modifiers; | ||
} | ||
private Q_SLOTS: | ||
void clear(); | ||
void clearLast(); | ||
|
@@ -48,12 +59,14 @@ private Q_SLOTS: | |
private: | ||
typedef QVector<QPoint> Mark; | ||
void drawMark(QPainter* painter, const Mark& mark); | ||
static Mark createArrow(QPoint arrow_start, QPoint arrow_end); | ||
static Mark createArrow(QPoint arrow_head, QPoint arrow_tail); | ||
QVector<Mark> marks; | ||
Mark drawing; | ||
QPoint arrow_start; | ||
QPoint arrow_tail; | ||
int width; | ||
QColor color; | ||
Qt::KeyboardModifiers m_freedraw_modifiers; | ||
Qt::KeyboardModifiers m_arrowdraw_modifiers; | ||
}; | ||
|
||
} // namespace | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.