Chord: add Acme left+right = Paste
The paste chord (Acme 1-3) now works: with the left button held, a right tap pastes over the selection via edit_paste (standard KDE clipboard). This is conflict-free because the radial gesture is already suppressed while the left button is held — right alone opens the radial, right while left-held pastes. The paired right release is swallowed so it doesn't leak a context menu or other action. All 5 ctest suites green.
This commit is contained in:
parent
87f5587bd4
commit
3129662f31
26
docs/PLAN.md
26
docs/PLAN.md
|
|
@ -128,20 +128,18 @@ Therefore the palette is replaced, not extended, and the replacement is built on
|
|||
- Not yet done: free-form stroke gestures (only button-press gesture so far);
|
||||
user-file config loading (built-in default only); frecency.
|
||||
|
||||
### Mouse chording (Acme-style) — DONE (first increment)
|
||||
- Left+middle chord = **Cut**: with the left button held while selecting
|
||||
(button 1 anchor), a tap of the middle button (button 2) cuts the current
|
||||
selection via `edit_cut`, which uses the **standard KDE clipboard**
|
||||
(Klipper-backed), not the X11 primary selection.
|
||||
- **Middle-click primary paste is suppressed** inside the editor. Kate pastes
|
||||
the primary selection on the middle event; the filter consumes the middle
|
||||
button on **both press and release** (swallowing only the press let the paste
|
||||
leak through on release). So middle-click no longer pastes in the editor —
|
||||
paste is the normal `Ctrl+V` / palette paste from the KDE clipboard.
|
||||
- Right-button chords are intentionally **not** ported — the right button is the
|
||||
radial gesture. (Revisit later.)
|
||||
- The radial gesture is suppressed while the left button is held, so an RMB tap
|
||||
mid-selection (or during a left+middle chord) does not pop the radial.
|
||||
### Mouse chording (Acme-style) — DONE
|
||||
- Left-button chords (button 1 held while selecting is the anchor):
|
||||
**left + middle = Cut**, **left + right = Paste**. Both use `edit_cut` /
|
||||
`edit_paste` → the **standard KDE clipboard** (Klipper-backed), not the X11
|
||||
primary selection.
|
||||
- The right-button paste chord is free of conflict because the radial gesture is
|
||||
already suppressed while the left button is held: right alone = radial, right
|
||||
while left-held = paste.
|
||||
- **Middle-click primary paste is suppressed** inside the editor — the middle
|
||||
button is consumed on both press and release (the paste fires on release, so
|
||||
swallowing only the press leaked it). Paste in the editor is the KDE-clipboard
|
||||
paste (`Ctrl+V`, palette, or the left+right chord).
|
||||
|
||||
### M5 — Command vocabulary + project model + switchers — NEXT
|
||||
- `:`-verb pack via `KTextEditor::Command`: `sort`, `align`, `json`, `b64`,
|
||||
|
|
|
|||
|
|
@ -347,13 +347,14 @@ bool OllieView::eventFilter(QObject *obj, QEvent *event)
|
|||
}
|
||||
}
|
||||
|
||||
// Acme-style left+middle chord = Cut, and suppression of X11 primary-
|
||||
// selection paste. Middle-button events inside the view are consumed on
|
||||
// BOTH press and release (Kate pastes the primary selection on the middle
|
||||
// event; swallowing only the press lets the paste leak through on release).
|
||||
// When the left button is held, the middle tap cuts the current selection
|
||||
// via edit_cut, which uses the standard KDE clipboard (Klipper-backed).
|
||||
// Right-button chords are intentionally not ported (RMB is the radial).
|
||||
// Acme-style left-button chords, plus suppression of X11 primary-selection
|
||||
// paste. Button 1 (left) held while selecting is the anchor:
|
||||
// left + middle tap = Cut, left + right tap = Paste.
|
||||
// Both use edit_cut / edit_paste, which use the standard KDE clipboard
|
||||
// (Klipper-backed). The right-button chord is free because the radial
|
||||
// gesture is already suppressed while the left button is held. Middle-button
|
||||
// events in the view are consumed on BOTH press and release to kill the
|
||||
// middle-click primary paste (it fires on release, not just press).
|
||||
if (event->type() == QEvent::MouseButtonRelease) {
|
||||
auto *mev = static_cast<QMouseEvent *>(event);
|
||||
if (mev->button() == Qt::LeftButton) {
|
||||
|
|
@ -363,12 +364,25 @@ bool OllieView::eventFilter(QObject *obj, QEvent *event)
|
|||
m_swallowMiddleRelease = false;
|
||||
return true; // suppress the primary paste that fires on release
|
||||
}
|
||||
if (mev->button() == Qt::RightButton && m_swallowRightRelease) {
|
||||
m_swallowRightRelease = false;
|
||||
return true; // paired release of a paste chord
|
||||
}
|
||||
} else if (event->type() == QEvent::MouseButtonPress) {
|
||||
auto *mev = static_cast<QMouseEvent *>(event);
|
||||
KTextEditor::View *v = m_mainWindow->activeView();
|
||||
auto *w = qobject_cast<QWidget *>(obj);
|
||||
const bool inView = v && w && v->isAncestorOf(w);
|
||||
|
||||
// left + right tap = Paste over the selection.
|
||||
if (mev->button() == Qt::RightButton && m_leftDownInView && inView) {
|
||||
if (QAction *paste = findActionByName(QStringLiteral("edit_paste"))) {
|
||||
paste->trigger();
|
||||
}
|
||||
m_swallowRightRelease = true;
|
||||
return true; // consume: chord, not a radial / context menu
|
||||
}
|
||||
|
||||
if (mev->button() == Qt::MiddleButton && inView) {
|
||||
if (m_leftDownInView) {
|
||||
if (QAction *cut = findActionByName(QStringLiteral("edit_cut"))) {
|
||||
|
|
|
|||
|
|
@ -91,6 +91,7 @@ private:
|
|||
bool m_gestureActive = false; // an RMB drag gesture is in progress
|
||||
bool m_leftDownInView = false; // LMB held inside the view (Acme chord anchor)
|
||||
bool m_swallowMiddleRelease = false; // swallow the release paired with a consumed middle press
|
||||
bool m_swallowRightRelease = false; // swallow the release paired with a left+right paste chord
|
||||
QHash<QString, QPointer<QAction>> m_actionsById;
|
||||
};
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue