Skip to content

Commit

Permalink
feat(effect): allow mousemark to configure modifier buttons for drawing
Browse files Browse the repository at this point in the history
Hard-coded modifiers Shift+Meta may interfere with some other actions.

FEATURE: 337043
  • Loading branch information
Ashark authored and romangg committed Sep 14, 2023
1 parent e991106 commit 8d17ad5
Show file tree
Hide file tree
Showing 5 changed files with 262 additions and 42 deletions.
1 change: 1 addition & 0 deletions plugins/effects/mousemark/main.cpp
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
*/
Expand Down
110 changes: 79 additions & 31 deletions plugins/effects/mousemark/mousemark.cpp
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
*/
Expand All @@ -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
{

Expand Down Expand Up @@ -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
}

Expand All @@ -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)
Expand Down Expand Up @@ -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();
Expand All @@ -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()) {
Expand All @@ -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;
}

Expand Down
17 changes: 15 additions & 2 deletions plugins/effects/mousemark/mousemark.h
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
*/
Expand All @@ -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;
Expand All @@ -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();
Expand All @@ -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
Expand Down
25 changes: 25 additions & 0 deletions plugins/effects/mousemark/mousemark.kcfg
Original file line number Diff line number Diff line change
Expand Up @@ -18,5 +18,30 @@ SPDX-License-Identifier: GPL-2.0-or-later
<entry name="Color" type="Color">
<default>255,0,0</default>
</entry>
<entry name="Freedrawmeta" type="Bool">
<default>true</default>
</entry>
<entry name="Freedrawcontrol" type="Bool">
<default>false</default>
</entry>
<entry name="Freedrawalt" type="Bool">
<default>false</default>
</entry>
<entry name="Freedrawshift" type="Bool">
<default>true</default>
</entry>

<entry name="Arrowdrawmeta" type="Bool">
<default>true</default>
</entry>
<entry name="Arrowdrawcontrol" type="Bool">
<default>true</default>
</entry>
<entry name="Arrowdrawalt" type="Bool">
<default>false</default>
</entry>
<entry name="Arrowdrawshift" type="Bool">
<default>true</default>
</entry>
</group>
</kcfg>
Loading

0 comments on commit 8d17ad5

Please sign in to comment.