on xenial help sign in
merge lp:~lukas-kde/unity8/eatDecorationMouseEvents
commit81938ca39bd7e14258df6eb37e41424fbe98f724 authorLukáš Tinkl <lukas.tinkl@canonical.com> dateMon 20 Jun 2016, 12:37 (10 years ago) parentee3aa6eeba93a7
7 files changed+148−10
qml/Launcher/LauncherPanel.qml+3−1 qml/Panel/IndicatorsMenu.qml+3−1 qml/Stages/DesktopSpread.qml+2 qml/Stages/WindowDecoration.qml+6−4 tests/qmltests/Launcher/tst_Launcher.qml+23−3 tests/qmltests/Panel/tst_IndicatorsMenu.qml+29−1 tests/qmltests/Stages/tst_DesktopStage.qml+82
qml/Launcher/LauncherPanel.qml+3−1
@@ -1,5 +1,5 @@
11/*
2− * Copyright (C) 2013 Canonical, Ltd.
2+ * Copyright (C) 2013-2016 Canonical, Ltd.
33 *
44 * This program is free software; you can redistribute it and/or modify
55 * it under the terms of the GNU General Public License as published by
@@ -69,7 +69,9 @@ Rectangle {
6969 MouseArea {
7070 id: mouseEventEater
7171 anchors.fill: parent
72+ acceptedButtons: Qt.AllButtons
7273 hoverEnabled: true
74+ onWheel: wheel.accepted = true;
7375 }
7476
7577 Column {
qml/Panel/IndicatorsMenu.qml+3−1
@@ -1,5 +1,5 @@
11/*
2− * Copyright (C) 2014 Canonical, Ltd.
2+ * Copyright (C) 2014-2016 Canonical, Ltd.
33 *
44 * This program is free software; you can redistribute it and/or modify
55 * it under the terms of the GNU General Public License as published by
@@ -80,6 +80,8 @@ Showable {
8080 MouseArea {
8181 anchors.fill: parent
8282 hoverEnabled: true
83+ acceptedButtons: Qt.AllButtons
84+ onWheel: wheel.accepted = true;
8385 }
8486
8587 MenuContent {
qml/Stages/DesktopSpread.qml+2
@@ -132,6 +132,8 @@ FocusScope {
132132 anchors.fill: parent
133133 visible: spreadBackground.visible
134134 enabled: visible
135+ acceptedButtons: Qt.AllButtons
136+ onWheel: wheel.accepted = true;
135137 }
136138
137139 Item {
qml/Stages/WindowDecoration.qml+6−4
@@ -28,10 +28,9 @@ MouseArea {
2828 property alias title: titleLabel.text
2929 property alias maximizeButtonShown: buttons.maximizeButtonShown
3030 property bool active: false
31+ acceptedButtons: Qt.AllButtons // prevent leaking unhandled mouse events
3132 property alias overlayShown: buttons.overlayShown
3233
33− hoverEnabled: true
34−
3534 signal closeClicked()
3635 signal minimizeClicked()
3736 signal maximizeClicked()
@@ -39,7 +38,7 @@ MouseArea {
3938 signal maximizeVerticallyClicked()
4039
4140 onDoubleClicked: {
42− if (maximizeButtonShown) {
41+ if (maximizeButtonShown && mouse.button == Qt.LeftButton) {
4342 root.maximizeClicked();
4443 }
4544 }
@@ -52,7 +51,7 @@ MouseArea {
5251 }
5352
5453 onPressedChanged: {
55− if (pressed) {
54+ if (pressed && pressedButtons == Qt.LeftButton) {
5655 var pos = mapToItem(root.target, mouseX, mouseY);
5756 priv.distanceX = pos.x;
5857 priv.distanceY = pos.y;
@@ -75,6 +74,9 @@ MouseArea {
7574 }
7675 }
7776
77+ // do not let unhandled wheel event pass thru the decoration
78+ onWheel: wheel.accepted = true;
79+
7880 Rectangle {
7981 anchors.fill: parent
8082 anchors.bottomMargin: -radius
tests/qmltests/Launcher/tst_Launcher.qml+23−3
@@ -1,5 +1,5 @@
11/*
2− * Copyright 2013-2014 Canonical Ltd.
2+ * Copyright 2013-2016 Canonical Ltd.
33 *
44 * This program is free software; you can redistribute it and/or modify
55 * it under the terms of the GNU General Public License as published by
@@ -210,6 +210,11 @@ Rectangle {
210210 target: LauncherModel
211211 }
212212
213+ SignalSpy {
214+ id: clickThroughSpy
215+ target: clickThroughTester
216+ }
217+
213218 Item {
214219 id: fakeDismissTimer
215220 property bool running: false
@@ -231,6 +236,8 @@ Rectangle {
231236
232237 property Item launcher: launcherLoader.status === Loader.Ready ? launcherLoader.item : null
233238 function cleanup() {
239+ signalSpy.clear();
240+ clickThroughSpy.clear();
234241 launcherLoader.active = false;
235242 // Loader.status might be Loader.Null and Loader.item might be null but the Loader
236243 // item might still be alive. So if we set Loader.active back to true
@@ -925,7 +932,6 @@ Rectangle {
925932
926933 var quickListEntry = findChild(quickList, "quickListEntry" + data.index)
927934
928− signalSpy.clear();
929935 signalSpy.signalName = "quickListTriggered"
930936
931937 mouseClick(quickListEntry)
@@ -1218,7 +1224,6 @@ Rectangle {
12181224 launcher.openForKeyboardNavigation();
12191225 waitForRendering(launcher);
12201226
1221− signalSpy.clear();
12221227 signalSpy.signalName = "quickListTriggered"
12231228
12241229 keyClick(Qt.Key_Down); // Down to launcher item 0
@@ -1311,5 +1316,20 @@ Rectangle {
13111316 compare(surfacePipRepeater.model, Math.min(3, LauncherModel.get(i).surfaceCount))
13121317 }
13131318 }
1319+
1320+ function test_preventMouseEventsThru() {
1321+ dragLauncherIntoView();
1322+ var launcherPanel = findChild(launcher, "launcherPanel");
1323+ tryCompare(launcherPanel, "visible", true);
1324+
1325+ clickThroughSpy.signalName = "wheel";
1326+ mouseWheel(launcherPanel, launcherPanel.width/2, launcherPanel.height/2, 10, 10);
1327+ tryCompare(clickThroughSpy, "count", 0);
1328+
1329+ clickThroughSpy.clear();
1330+ clickThroughSpy.signalName = "clicked";
1331+ mouseWheel(launcherPanel, launcherPanel.width/2, launcherPanel.height/2, Qt.RightButton);
1332+ tryCompare(clickThroughSpy, "count", 0);
1333+ }
13141334 }
13151335}
tests/qmltests/Panel/tst_IndicatorsMenu.qml+29−1
@@ -1,5 +1,5 @@
11/*
2− * Copyright 2013-2014 Canonical Ltd.
2+ * Copyright 2013-2016 Canonical Ltd.
33 *
44 * This program is free software; you can redistribute it and/or modify
55 * it under the terms of the GNU General Public License as published by
@@ -27,6 +27,16 @@ IndicatorTest {
2727 width: units.gu(80)
2828 height: units.gu(71)
2929
30+ SignalSpy {
31+ id: clickThroughSpy
32+ target: clickThroughTester
33+ }
34+
35+ MouseArea {
36+ id: clickThroughTester
37+ anchors.fill: root
38+ }
39+
3040 RowLayout {
3141 anchors.fill: parent
3242 anchors.margins: units.gu(1)
@@ -112,6 +122,10 @@ IndicatorTest {
112122 indicatorsMenu.verticalVelocityThreshold = 0.5
113123 }
114124
125+ function cleanup() {
126+ clickThroughSpy.clear();
127+ }
128+
115129 function get_indicator_item(index) {
116130 var indicatorItem = findChild(indicatorsMenu, root.originalModelData[index]["identifier"] + "-panelItem");
117131 verify(indicatorItem !== null);
@@ -257,5 +271,19 @@ IndicatorTest {
257271
258272 touchRelease(indicatorsMenu, nextItemMappedPositionX, indicatorsMenu.openedHeight / 3);
259273 }
274+
275+ function test_preventMouseEventsThru() {
276+ indicatorsMenu.show();
277+ tryCompare(indicatorsMenu, "fullyOpened", true);
278+
279+ clickThroughSpy.signalName = "wheel";
280+ mouseWheel(indicatorsMenu, indicatorsMenu.width/2, indicatorsMenu.height/2, 10, 10);
281+ tryCompare(clickThroughSpy, "count", 0);
282+
283+ clickThroughSpy.clear();
284+ clickThroughSpy.signalName = "clicked";
285+ mouseClick(indicatorsMenu, indicatorsMenu.width/2, indicatorsMenu.height/2, Qt.RightButton);
286+ tryCompare(clickThroughSpy, "count", 0);
287+ }
260288 }
261289}
tests/qmltests/Stages/tst_DesktopStage.qml+82
@@ -89,6 +89,13 @@ Item {
8989 topLevelSurfaceList: topSurfaceList
9090 }
9191 }
92+
93+ MouseArea {
94+ id: clickThroughTester
95+ anchors.fill: desktopStageLoader.item
96+ acceptedButtons: Qt.AllButtons
97+ hoverEnabled: true
98+ }
9299 }
93100
94101 Rectangle {
@@ -140,6 +147,11 @@ Item {
140147 }
141148 }
142149
150+ SignalSpy {
151+ id: mouseEaterSpy
152+ target: clickThroughTester
153+ }
154+
143155 UnityTestCase {
144156 id: testCase
145157 name: "DesktopStage"
@@ -179,6 +191,7 @@ Item {
179191 desktopStageLoader.active = true;
180192 tryCompare(desktopStageLoader, "status", Loader.Ready);
181193
194+ mouseEaterSpy.clear();
182195 }
183196
184197 function waitUntilAppSurfaceShowsUp(surfaceId) {
@@ -703,5 +716,74 @@ Item {
703716 dialerDelegate.surface.setMaximumHeight(0);
704717 tryCompare(dialerMaximizeButton, "visible", true);
705718 }
719+
720+ function test_canMoveWindowWithLeftMouseButtonOnly_data() {
721+ return [
722+ {tag: "left mouse button", button: Qt.LeftButton },
723+ {tag: "right mouse button", button: Qt.RightButton },
724+ {tag: "middle mouse button", button: Qt.MiddleButton }
725+ ]
726+ }
727+
728+ function test_canMoveWindowWithLeftMouseButtonOnly(data) {
729+ var appDelegate = startApplication("dialer-app");
730+ verify(appDelegate);
731+
732+ var posBefore = Qt.point(appDelegate.x, appDelegate.y);
733+
734+ mousePress(appDelegate, appDelegate.width / 2, units.gu(1), data.button);
735+ mouseMove(appDelegate, appDelegate.width / 2, -units.gu(100), undefined /* delay */, data.button);
736+
737+ var posAfter = Qt.point(appDelegate.x, appDelegate.y);
738+
739+ tryCompareFunction(function(){return posBefore == posAfter;}, data.button !== Qt.LeftButton ? true : false);
740+ }
741+
742+ function test_preventMouseEventsThruDesktopSpread() {
743+ var spread = findChild(desktopStage, "spread");
744+ verify(spread);
745+ spread.show();
746+ tryCompareFunction( function(){ return spread.ready }, true );
747+
748+ mouseEaterSpy.signalName = "wheel";
749+ mouseWheel(spread, spread.width/2, spread.height/2, 10, 10);
750+ tryCompare(mouseEaterSpy, "count", 0);
751+
752+ mouseEaterSpy.clear();
753+ mouseEaterSpy.signalName = "clicked";
754+ mouseClick(spread, spread.width/2, spread.height/2, Qt.RightButton);
755+ tryCompare(mouseEaterSpy, "count", 0);
756+
757+ spread.cancel();
758+ }
759+
760+ function test_eatWindowDecorationMouseEvents_data() {
761+ return [
762+ {tag: "left mouse click", signalName: "clicked", button: Qt.LeftButton },
763+ {tag: "right mouse click", signalName: "clicked", button: Qt.RightButton },
764+ {tag: "middle mouse click", signalName: "clicked", button: Qt.MiddleButton },
765+ {tag: "mouse wheel", signalName: "wheel", button: Qt.MiddleButton },
766+ {tag: "double click (RMB)", signalName: "doubleClicked", button: Qt.RightButton },
767+ ]
768+ }
769+
770+ function test_eatWindowDecorationMouseEvents(data) {
771+ var dialerAppDelegate = startApplication("dialer-app");
772+ verify(dialerAppDelegate);
773+ var decoration = findChild(dialerAppDelegate, "appWindowDecoration");
774+ verify(decoration);
775+
776+ mouseEaterSpy.signalName = data.signalName;
777+ if (data.signalName === "wheel") {
778+ mouseWheel(decoration, decoration.width/2, decoration.height/2, 20, 20);
779+ } else if (data.signalName === "clicked") {
780+ mouseClick(decoration, decoration.width/2, decoration.height/2, data.button);
781+ } else {
782+ mouseDoubleClick(decoration, decoration.width/2, decoration.height/2, data.button);
783+ tryCompare(dialerAppDelegate, "maximized", false);
784+ }
785+
786+ tryCompare(mouseEaterSpy, "count", 0);
787+ }
706788 }
707789}