add test for cursorFollowsFocus and add check whether cursor already within focused client
This commit is contained in:
@@ -18,3 +18,15 @@ function rectEquals(a: QmlRect, b: QmlRect) {
|
||||
a.width === b.width &&
|
||||
a.height === b.height;
|
||||
}
|
||||
|
||||
function pointEquals(a: QmlPoint, b: QmlPoint) {
|
||||
return a.x === b.x &&
|
||||
a.y === b.y;
|
||||
}
|
||||
|
||||
function rectContainsPoint(rect: QmlRect, point: QmlPoint) {
|
||||
return rect.left <= point.x &&
|
||||
rect.right >= point.x &&
|
||||
rect.top <= point.y &&
|
||||
rect.bottom >= point.y;
|
||||
}
|
||||
|
||||
@@ -103,7 +103,11 @@ class World {
|
||||
}
|
||||
|
||||
private moveCursorToFocus() {
|
||||
if (this.cursorFollowsFocus && moveCursorToFocus !== undefined) {
|
||||
if (this.cursorFollowsFocus && Workspace.activeWindow !== null) {
|
||||
const cursorAlreadyInFocus = rectContainsPoint(Workspace.activeWindow.frameGeometry, Workspace.cursorPos);
|
||||
if (cursorAlreadyInFocus) {
|
||||
return;
|
||||
}
|
||||
moveCursorToFocus.call();
|
||||
}
|
||||
}
|
||||
|
||||
36
src/tests/flows/cursorFollowsFocus.ts
Normal file
36
src/tests/flows/cursorFollowsFocus.ts
Normal file
@@ -0,0 +1,36 @@
|
||||
tests.register("Drag tiled window, untile", 10, () => {
|
||||
const config = getDefaultConfig();
|
||||
config.cursorFollowsFocus = true;
|
||||
const { qtMock, workspaceMock, world } = init(config);
|
||||
|
||||
const [client1, client2] = workspaceMock.createClients(2);
|
||||
const initialCursorPos = new MockQmlPoint(380, 20);
|
||||
Assert.assert(rectContainsPoint(client1.frameGeometry, initialCursorPos), { message: "invalid test setup" });
|
||||
workspaceMock.cursorPos = initialCursorPos.clone();
|
||||
|
||||
runOneOf(
|
||||
() => Workspace.activeWindow = client1,
|
||||
() => qtMock.fireShortcut("karousel-focus-1"),
|
||||
);
|
||||
Assert.assert(rectContainsPoint(client1.frameGeometry, Workspace.cursorPos));
|
||||
Assert.assert(!rectContainsPoint(client2.frameGeometry, Workspace.cursorPos));
|
||||
Assert.assert(pointEquals(Workspace.cursorPos, initialCursorPos), { message: "Cursor should not have been moved because it was already within the focused client" });
|
||||
|
||||
runOneOf(
|
||||
() => Workspace.activeWindow = client2,
|
||||
() => qtMock.fireShortcut("karousel-focus-2"),
|
||||
);
|
||||
Assert.assert(!rectContainsPoint(client1.frameGeometry, Workspace.cursorPos));
|
||||
Assert.assert(rectContainsPoint(client2.frameGeometry, Workspace.cursorPos));
|
||||
|
||||
runOneOf(
|
||||
() => Workspace.activeWindow = client1,
|
||||
() => qtMock.fireShortcut("karousel-focus-1"),
|
||||
);
|
||||
Assert.assert(rectContainsPoint(client1.frameGeometry, Workspace.cursorPos));
|
||||
Assert.assert(!rectContainsPoint(client2.frameGeometry, Workspace.cursorPos));
|
||||
const lastCursorPos = workspaceMock.cursorPos.clone();
|
||||
|
||||
Workspace.activeWindow = null;
|
||||
Assert.assert(pointEquals(Workspace.cursorPos, lastCursorPos), { message: "Cursor should not have been moved" });
|
||||
});
|
||||
53
src/tests/units/utils/math.ts
Normal file
53
src/tests/units/utils/math.ts
Normal file
@@ -0,0 +1,53 @@
|
||||
tests.register("math", 1, () => {
|
||||
const rect = new MockQmlRect(100, 200, 10, 20);
|
||||
const testCases: {
|
||||
rect: QmlRect,
|
||||
point: QmlPoint,
|
||||
contained: boolean,
|
||||
}[] = [
|
||||
{
|
||||
rect: rect,
|
||||
point: new MockQmlPoint(100, 200),
|
||||
contained: true,
|
||||
},
|
||||
{
|
||||
rect: rect,
|
||||
point: new MockQmlPoint(110, 220),
|
||||
contained: true,
|
||||
},
|
||||
{
|
||||
rect: rect,
|
||||
point: new MockQmlPoint(105, 205),
|
||||
contained: true,
|
||||
},
|
||||
{
|
||||
rect: rect,
|
||||
point: new MockQmlPoint(110.01, 205),
|
||||
contained: false,
|
||||
},
|
||||
{
|
||||
rect: rect,
|
||||
point: new MockQmlPoint(105, 220.01),
|
||||
contained: false,
|
||||
},
|
||||
{
|
||||
rect: rect,
|
||||
point: new MockQmlPoint(16, 205),
|
||||
contained: false,
|
||||
},
|
||||
{
|
||||
rect: rect,
|
||||
point: new MockQmlPoint(105, 16),
|
||||
contained: false,
|
||||
},
|
||||
];
|
||||
|
||||
for (const testCase of testCases) {
|
||||
const result = rectContainsPoint(testCase.rect, testCase.point);
|
||||
Assert.equal(
|
||||
result,
|
||||
testCase.contained,
|
||||
{ message: JSON.stringify(testCase) },
|
||||
);
|
||||
}
|
||||
});
|
||||
@@ -29,6 +29,15 @@ function init(config: Config) {
|
||||
|
||||
Qt = qtMock;
|
||||
Workspace = workspaceMock;
|
||||
moveCursorToFocus = {
|
||||
__brand: "QmlObject",
|
||||
call: () => {
|
||||
Assert.assert(Workspace.activeWindow !== null, { message: "moveCursorToFocus should never be called if there's no focused window" });
|
||||
const frame = Workspace.activeWindow!.frameGeometry;
|
||||
workspaceMock.cursorPos.x = Math.floor(frame.x + frame.width/2);
|
||||
workspaceMock.cursorPos.y = Math.floor(frame.y + frame.height/2);
|
||||
},
|
||||
};
|
||||
|
||||
const world = new World(config);
|
||||
return { qtMock, workspaceMock, world };
|
||||
|
||||
@@ -5,4 +5,11 @@ class MockQmlPoint {
|
||||
public x: number,
|
||||
public y: number,
|
||||
) {}
|
||||
|
||||
public clone() {
|
||||
return new MockQmlPoint(
|
||||
this.x,
|
||||
this.y,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user