Disable modifier window actions if global shortcuts are disabled

Summary:
Same is done on X11 (see Client::updateMouseGrab), so we should have this
on Wayland as well.

Also adding the pointer confinement restriction for modifier + wheel.

Test Plan: Run new and adjusted testcases with and without the change

Reviewers: #kwin, #plasma

Subscribers: kwin

Tags: #kwin

Differential Revision: https://phabricator.kde.org/D16025
This commit is contained in:
Martin Flöser 2018-10-07 21:02:09 +02:00
parent e3c778da9f
commit 77e3bbef7e
3 changed files with 131 additions and 3 deletions

View file

@ -193,6 +193,7 @@ void TestPointerConstraints::testConfinedPointer()
group.writeEntry("CommandAll1", "Move");
group.writeEntry("CommandAll2", "Move");
group.writeEntry("CommandAll3", "Move");
group.writeEntry("CommandAllWheel", "change opacity");
group.sync();
workspace()->slotReconfigure();
QCOMPARE(options->commandAllModifier(), Qt::AltModifier);
@ -205,6 +206,17 @@ void TestPointerConstraints::testConfinedPointer()
kwinApp()->platform()->pointerButtonPressed(BTN_LEFT, timestamp++);
QVERIFY(!c->isMove());
kwinApp()->platform()->pointerButtonReleased(BTN_LEFT, timestamp++);
// set the opacity to 0.5
c->setOpacity(0.5);
QCOMPARE(c->opacity(), 0.5);
// pointer is confined so shortcut should not work
kwinApp()->platform()->pointerAxisVertical(-5, timestamp++);
QCOMPARE(c->opacity(), 0.5);
kwinApp()->platform()->pointerAxisVertical(5, timestamp++);
QCOMPARE(c->opacity(), 0.5);
kwinApp()->platform()->keyboardKeyReleased(KEY_LEFTALT, timestamp++);
// deactivate the client, this should unconfine

View file

@ -63,8 +63,10 @@ private Q_SLOTS:
void testUpdateFocusAfterScreenChange();
void testModifierClickUnrestrictedMove_data();
void testModifierClickUnrestrictedMove();
void testModifierClickUnrestrictedMoveGlobalShortcutsDisabled();
void testModifierScrollOpacity_data();
void testModifierScrollOpacity();
void testModifierScrollOpacityGlobalShortcutsDisabled();
void testScrollAction();
void testFocusFollowsMouse();
void testMouseActionInactiveWindow_data();
@ -424,6 +426,64 @@ void PointerInputTest::testModifierClickUnrestrictedMove()
QVERIFY(!buttonSpy.wait(100));
}
void PointerInputTest::testModifierClickUnrestrictedMoveGlobalShortcutsDisabled()
{
// this test ensures that Alt+mouse button press triggers unrestricted move
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 buttonSpy(pointer, &Pointer::buttonStateChanged);
QVERIFY(buttonSpy.isValid());
// first modify the config for this run
KConfigGroup group = kwinApp()->config()->group("MouseBindings");
group.writeEntry("CommandAllKey", "Alt");
group.writeEntry("CommandAll1", "Move");
group.writeEntry("CommandAll2", "Move");
group.writeEntry("CommandAll3", "Move");
group.sync();
workspace()->slotReconfigure();
QCOMPARE(options->commandAllModifier(), Qt::AltModifier);
QCOMPARE(options->commandAll1(), Options::MouseUnrestrictedMove);
QCOMPARE(options->commandAll2(), Options::MouseUnrestrictedMove);
QCOMPARE(options->commandAll3(), Options::MouseUnrestrictedMove);
// create a window
QSignalSpy clientAddedSpy(waylandServer(), &WaylandServer::shellClientAdded);
QVERIFY(clientAddedSpy.isValid());
Surface *surface = Test::createSurface(m_compositor);
QVERIFY(surface);
ShellSurface *shellSurface = Test::createShellSurface(surface, surface);
QVERIFY(shellSurface);
render(surface);
QVERIFY(clientAddedSpy.wait());
AbstractClient *window = workspace()->activeClient();
QVERIFY(window);
// disable global shortcuts
QVERIFY(!workspace()->globalShortcutsDisabled());
workspace()->disableGlobalShortcutsForClient(true);
QVERIFY(workspace()->globalShortcutsDisabled());
// move cursor on window
Cursor::setPos(window->geometry().center());
// simulate modifier+click
quint32 timestamp = 1;
kwinApp()->platform()->keyboardKeyPressed(KEY_LEFTALT, timestamp++);
QVERIFY(!window->isMove());
kwinApp()->platform()->pointerButtonPressed(BTN_LEFT, timestamp++);
QVERIFY(!window->isMove());
// release modifier should not change it
kwinApp()->platform()->keyboardKeyReleased(KEY_LEFTALT, timestamp++);
QVERIFY(!window->isMove());
kwinApp()->platform()->pointerButtonReleased(BTN_LEFT, timestamp++);
workspace()->disableGlobalShortcutsForClient(false);
}
void PointerInputTest::testModifierScrollOpacity_data()
{
QTest::addColumn<int>("modifierKey");
@ -503,6 +563,60 @@ void PointerInputTest::testModifierScrollOpacity()
QVERIFY(!axisSpy.wait(100));
}
void PointerInputTest::testModifierScrollOpacityGlobalShortcutsDisabled()
{
// 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
KConfigGroup group = kwinApp()->config()->group("MouseBindings");
group.writeEntry("CommandAllKey", "Alt");
group.writeEntry("CommandAllWheel", "change opacity");
group.sync();
workspace()->slotReconfigure();
// create a window
QSignalSpy clientAddedSpy(waylandServer(), &WaylandServer::shellClientAdded);
QVERIFY(clientAddedSpy.isValid());
Surface *surface = Test::createSurface(m_compositor);
QVERIFY(surface);
ShellSurface *shellSurface = Test::createShellSurface(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());
// disable global shortcuts
QVERIFY(!workspace()->globalShortcutsDisabled());
workspace()->disableGlobalShortcutsForClient(true);
QVERIFY(workspace()->globalShortcutsDisabled());
// simulate modifier+wheel
quint32 timestamp = 1;
kwinApp()->platform()->keyboardKeyPressed(KEY_LEFTALT, timestamp++);
kwinApp()->platform()->pointerAxisVertical(-5, timestamp++);
QCOMPARE(window->opacity(), 0.5);
kwinApp()->platform()->pointerAxisVertical(5, timestamp++);
QCOMPARE(window->opacity(), 0.5);
kwinApp()->platform()->keyboardKeyReleased(KEY_LEFTALT, timestamp++);
workspace()->disableGlobalShortcutsForClient(false);
}
void PointerInputTest::testScrollAction()
{
// this test verifies that scroll on inactive window performs a mouse action

View file

@ -707,7 +707,7 @@ std::pair<bool, bool> performClientMouseAction(QMouseEvent *event, AbstractClien
Options::MouseCommand command = Options::MouseNothing;
bool wasAction = false;
if (static_cast<MouseEvent*>(event)->modifiersRelevantForGlobalShortcuts() == options->commandAllModifier()) {
if (!input()->pointer()->isConstrained()) {
if (!input()->pointer()->isConstrained() && !workspace()->globalShortcutsDisabled()) {
wasAction = true;
switch (event->button()) {
case Qt::LeftButton:
@ -740,8 +740,10 @@ std::pair<bool, bool> performClientWheelAction(QWheelEvent *event, AbstractClien
bool wasAction = false;
Options::MouseCommand command = Options::MouseNothing;
if (static_cast<WheelEvent*>(event)->modifiersRelevantForGlobalShortcuts() == options->commandAllModifier()) {
wasAction = true;
command = options->operationWindowMouseWheel(-1 * event->angleDelta().y());
if (!input()->pointer()->isConstrained() && !workspace()->globalShortcutsDisabled()) {
wasAction = true;
command = options->operationWindowMouseWheel(-1 * event->angleDelta().y());
}
} else {
if (action == MouseAction::ModifierAndWindow) {
command = c->getWheelCommand(Qt::Vertical, &wasAction);