Add support for modifier+wheel action
Implemented in the ForwardEventFilter: before forwarding the event to the window we check whether a modifier is pressed and perform the wheel command. Possible improvements: each axis event triggers the same change, there is no adjusted scaling.
This commit is contained in:
parent
ba7c5bbd77
commit
1f1a4ac6e8
2 changed files with 88 additions and 1 deletions
|
@ -60,6 +60,8 @@ private Q_SLOTS:
|
||||||
void testUpdateFocusAfterScreenChange();
|
void testUpdateFocusAfterScreenChange();
|
||||||
void testModifierClickUnrestrictedMove_data();
|
void testModifierClickUnrestrictedMove_data();
|
||||||
void testModifierClickUnrestrictedMove();
|
void testModifierClickUnrestrictedMove();
|
||||||
|
void testModifierScrollOpacity_data();
|
||||||
|
void testModifierScrollOpacity();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void render(KWayland::Client::Surface *surface, const QSize &size = QSize(100, 50));
|
void render(KWayland::Client::Surface *surface, const QSize &size = QSize(100, 50));
|
||||||
|
@ -397,6 +399,73 @@ void PointerInputTest::testModifierClickUnrestrictedMove()
|
||||||
QVERIFY(!buttonSpy.wait(100));
|
QVERIFY(!buttonSpy.wait(100));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void PointerInputTest::testModifierScrollOpacity_data()
|
||||||
|
{
|
||||||
|
QTest::addColumn<int>("modifierKey");
|
||||||
|
QTest::addColumn<QString>("modKey");
|
||||||
|
|
||||||
|
const QString alt = QStringLiteral("Alt");
|
||||||
|
const QString meta = QStringLiteral("Meta");
|
||||||
|
|
||||||
|
QTest::newRow("Left Alt") << KEY_LEFTALT << alt;
|
||||||
|
QTest::newRow("Right Alt") << KEY_RIGHTALT << alt;
|
||||||
|
QTest::newRow("Left Meta") << KEY_LEFTMETA << meta;
|
||||||
|
QTest::newRow("Right Meta") << KEY_RIGHTMETA << meta;
|
||||||
|
}
|
||||||
|
|
||||||
|
void PointerInputTest::testModifierScrollOpacity()
|
||||||
|
{
|
||||||
|
// this test verifies that mod+wheel performs a window operation and does not
|
||||||
|
// pass the wheel to the window
|
||||||
|
using namespace KWayland::Client;
|
||||||
|
// create pointer and signal spy for button events
|
||||||
|
auto pointer = m_seat->createPointer(m_seat);
|
||||||
|
QVERIFY(pointer);
|
||||||
|
QVERIFY(pointer->isValid());
|
||||||
|
QSignalSpy axisSpy(pointer, &Pointer::axisChanged);
|
||||||
|
QVERIFY(axisSpy.isValid());
|
||||||
|
|
||||||
|
// first modify the config for this run
|
||||||
|
QFETCH(QString, modKey);
|
||||||
|
KConfigGroup group = kwinApp()->config()->group("MouseBindings");
|
||||||
|
group.writeEntry("CommandAllKey", modKey);
|
||||||
|
group.writeEntry("CommandAllWheel", "change opacity");
|
||||||
|
group.sync();
|
||||||
|
workspace()->slotReconfigure();
|
||||||
|
|
||||||
|
// create a window
|
||||||
|
QSignalSpy clientAddedSpy(waylandServer(), &WaylandServer::shellClientAdded);
|
||||||
|
QVERIFY(clientAddedSpy.isValid());
|
||||||
|
Surface *surface = m_compositor->createSurface(m_compositor);
|
||||||
|
QVERIFY(surface);
|
||||||
|
ShellSurface *shellSurface = m_shell->createSurface(surface, surface);
|
||||||
|
QVERIFY(shellSurface);
|
||||||
|
render(surface);
|
||||||
|
QVERIFY(clientAddedSpy.wait());
|
||||||
|
AbstractClient *window = workspace()->activeClient();
|
||||||
|
QVERIFY(window);
|
||||||
|
// set the opacity to 0.5
|
||||||
|
window->setOpacity(0.5);
|
||||||
|
QCOMPARE(window->opacity(), 0.5);
|
||||||
|
|
||||||
|
// move cursor on window
|
||||||
|
Cursor::setPos(window->geometry().center());
|
||||||
|
|
||||||
|
// simulate modifier+wheel
|
||||||
|
quint32 timestamp = 1;
|
||||||
|
QFETCH(int, modifierKey);
|
||||||
|
waylandServer()->backend()->keyboardKeyPressed(modifierKey, timestamp++);
|
||||||
|
waylandServer()->backend()->pointerAxisVertical(5, timestamp++);
|
||||||
|
QCOMPARE(window->opacity(), 0.6);
|
||||||
|
waylandServer()->backend()->pointerAxisVertical(-5, timestamp++);
|
||||||
|
QCOMPARE(window->opacity(), 0.5);
|
||||||
|
waylandServer()->backend()->keyboardKeyReleased(modifierKey, timestamp++);
|
||||||
|
|
||||||
|
// axis should have been filtered out
|
||||||
|
QCOMPARE(axisSpy.count(), 0);
|
||||||
|
QVERIFY(!axisSpy.wait(100));
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
WAYLANDTEST_MAIN(KWin::PointerInputTest)
|
WAYLANDTEST_MAIN(KWin::PointerInputTest)
|
||||||
|
|
18
input.cpp
18
input.cpp
|
@ -564,7 +564,25 @@ public:
|
||||||
auto seat = waylandServer()->seat();
|
auto seat = waylandServer()->seat();
|
||||||
seat->setTimestamp(event->timestamp());
|
seat->setTimestamp(event->timestamp());
|
||||||
const Qt::Orientation orientation = event->angleDelta().x() == 0 ? Qt::Vertical : Qt::Horizontal;
|
const Qt::Orientation orientation = event->angleDelta().x() == 0 ? Qt::Vertical : Qt::Horizontal;
|
||||||
|
|
||||||
|
// check for modifier
|
||||||
|
bool passThrough = true;
|
||||||
|
if (AbstractClient *c = dynamic_cast<AbstractClient*>(input()->pointer()->window().data())) {
|
||||||
|
// TODO: implement wheel action
|
||||||
|
bool wasAction = false;
|
||||||
|
Options::MouseCommand command = Options::MouseNothing;
|
||||||
|
if (orientation == Qt::Vertical && event->modifiers() == options->commandAllModifier()) {
|
||||||
|
wasAction = true;
|
||||||
|
command = options->operationWindowMouseWheel(event->angleDelta().y());
|
||||||
|
}
|
||||||
|
if (wasAction) {
|
||||||
|
passThrough = c->performMouseCommand(command, event->globalPos());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (passThrough) {
|
||||||
seat->pointerAxis(orientation, orientation == Qt::Horizontal ? event->angleDelta().x() : event->angleDelta().y());
|
seat->pointerAxis(orientation, orientation == Qt::Horizontal ? event->angleDelta().x() : event->angleDelta().y());
|
||||||
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
bool keyEvent(QKeyEvent *event) override {
|
bool keyEvent(QKeyEvent *event) override {
|
||||||
|
|
Loading…
Reference in a new issue