Radial: warp the mouse to the pane after a focus-change split action

When a radial slice fires a go_*_split_view action (Focus Left/Right/Up/
Down/Next/Prev), warp the OS pointer onto the center of the newly active
view so the mouse follows the keyboard focus. Deferred via a 0ms timer so
Kate finishes activating the target view first. Scoped to the six pane-
focus actions only — other radial activations and ordinary view changes
(clicks, file opens) do not move the pointer.
This commit is contained in:
Levi Neely 2026-10-08 11:58:02 +02:00
parent 145d597742
commit ea7d84868d
2 changed files with 36 additions and 0 deletions

View File

@ -25,6 +25,7 @@
#include <QAction>
#include <QApplication>
#include <QCursor>
#include <QDateTime>
#include <QDir>
#include <QEvent>
@ -35,6 +36,7 @@
#include <QMouseEvent>
#include <QSet>
#include <QStandardPaths>
#include <QTimer>
#include <QUrl>
#include <QWidget>
@ -43,6 +45,19 @@ namespace katecustom
namespace
{
// True for the Kate actions that move keyboard focus to another split pane.
// After one of these fires we warp the mouse pointer onto the new pane so the
// cursor follows the focus (mouse-first UX).
bool isPaneFocusAction(const QString &id)
{
return id == QLatin1String("go_left_split_view")
|| id == QLatin1String("go_right_split_view")
|| id == QLatin1String("go_upward_split_view")
|| id == QLatin1String("go_downward_split_view")
|| id == QLatin1String("go_next_split_view")
|| id == QLatin1String("go_prev_split_view");
}
// Bracket pairs understood by the double-click selection feature.
QChar matchingBracket(QChar c, bool &isOpener)
{
@ -1136,9 +1151,26 @@ void OllieView::onRadialActivated(const QString &actionId)
}
if (QAction *a = findActionByName(actionId)) {
a->trigger();
// If this moved focus to another split pane, warp the pointer onto that
// pane so the mouse follows the focus. Deferred to the next event-loop
// turn so Kate has finished activating the target view first.
if (isPaneFocusAction(actionId)) {
QTimer::singleShot(0, this, [this]() { warpCursorToActiveView(); });
}
}
}
void OllieView::warpCursorToActiveView()
{
KTextEditor::View *view = m_mainWindow->activeView();
if (!view) {
return;
}
// KTextEditor::View is a QWidget; center the pointer in its editing area.
const QPoint center = view->mapToGlobal(view->rect().center());
QCursor::setPos(center);
}
// ---------------------------------------------------------------------------
// Acme-style line-editing keys
//

View File

@ -89,6 +89,10 @@ private:
// Size and place a palette: it spans the active window's width (minus a
// small margin), anchored near the top.
void positionPalette(PaletteWidget *palette);
// Move the OS pointer onto the center of the active view — used after a
// radial pane-focus action so the mouse follows the keyboard focus.
void warpCursorToActiveView();
// One harvested, runnable action with the provenance needed to build a
// unique id and to disambiguate labels shared by several commands.
struct ActionEntry {