Skip to content

Commit 6b68c4a

Browse files
authored
Bumped dependency versions, extended window provider with new capabilities for focus/resize/move window (#540)
1 parent 1901c4b commit 6b68c4a

File tree

8 files changed

+5688
-4552
lines changed

8 files changed

+5688
-4552
lines changed

index.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ export { centerOf, randomPointIn } from "./lib/location.function";
4242
export { OptionalSearchParameters } from "./lib/optionalsearchparameters.class";
4343
export { EasingFunction, linear } from "./lib/mouse-movement.function";
4444
export { Point } from "./lib/point.class";
45+
export { Size } from "./lib/size.class";
4546
export { Region } from "./lib/region.class";
4647
export { Window } from "./lib/window.class";
4748
export { FileType } from "./lib/file-type.enum";
@@ -63,7 +64,7 @@ const assert = new AssertClass(screen);
6364

6465
const { straightTo, up, down, left, right } = createMovementApi(
6566
providerRegistry,
66-
lineHelper
67+
lineHelper,
6768
);
6869
const { getWindows, getActiveWindow } = createWindowApi(providerRegistry);
6970

@@ -74,7 +75,7 @@ const imageResource = (fileName: string) =>
7475
loadImageResource(
7576
providerRegistry,
7677
screen.config.resourceDirectory,
77-
fileName
78+
fileName,
7879
);
7980

8081
const singleWord = (word: string): WordQuery => {

lib/provider/native/libnut-window.class.ts

Lines changed: 41 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
import libnut = require("@nut-tree/libnut");
22
import { Region } from "../../region.class";
33
import { WindowProviderInterface } from "../window-provider.interface";
4+
import { Size } from "../../size.class";
5+
import { Point } from "../../point.class";
46

57
export default class WindowAction implements WindowProviderInterface {
68
public getWindows(): Promise<number[]> {
@@ -32,8 +34,8 @@ export default class WindowAction implements WindowProviderInterface {
3234
windowRect.x,
3335
windowRect.y,
3436
windowRect.width,
35-
windowRect.height
36-
)
37+
windowRect.height,
38+
),
3739
);
3840
} catch (e) {
3941
reject(e);
@@ -50,4 +52,41 @@ export default class WindowAction implements WindowProviderInterface {
5052
}
5153
});
5254
}
55+
56+
focusWindow(windowHandle: number): Promise<boolean> {
57+
return new Promise<boolean>((resolve, reject) => {
58+
try {
59+
resolve(libnut.focusWindow(windowHandle));
60+
} catch (e) {
61+
reject(e);
62+
}
63+
});
64+
}
65+
66+
moveWindow(windowHandle: number, newOrigin: Point): Promise<boolean> {
67+
return new Promise<boolean>((resolve, reject) => {
68+
try {
69+
resolve(
70+
libnut.moveWindow(windowHandle, { x: newOrigin.x, y: newOrigin.y }),
71+
);
72+
} catch (e) {
73+
reject(e);
74+
}
75+
});
76+
}
77+
78+
resizeWindow(windowHandle: number, newSize: Size): Promise<boolean> {
79+
return new Promise<boolean>((resolve, reject) => {
80+
try {
81+
resolve(
82+
libnut.resizeWindow(windowHandle, {
83+
width: newSize.width,
84+
height: newSize.height,
85+
}),
86+
);
87+
} catch (e) {
88+
reject(e);
89+
}
90+
});
91+
}
5392
}

lib/provider/window-provider.interface.ts

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11
import { Region } from "../region.class";
2+
import { Point } from "../point.class";
3+
import { Size } from "../size.class";
24

35
/**
46
* A WindowActionProvider should provide access to a system's window system
@@ -34,4 +36,19 @@ export interface WindowProviderInterface {
3436
* @returns The {@link Region} occupied by the window addressed via its window handle
3537
*/
3638
getWindowRegion(windowHandle: number): Promise<Region>;
39+
40+
/**
41+
* {@link focusWindow} Focuses the window addressed via its window handle
42+
*/
43+
focusWindow(windowHandle: number): Promise<boolean>;
44+
45+
/**
46+
* {@link moveWindow} Moves the window addressed via its window handle to a new origin given as {@link Point}
47+
*/
48+
moveWindow(windowHandle: number, newOrigin: Point): Promise<boolean>;
49+
50+
/**
51+
* {@link resizeWindow} Resizes the window addressed via its window handle to a new {@link Size}
52+
*/
53+
resizeWindow(windowHandle: number, newSize: Size): Promise<boolean>;
3754
}

lib/size.class.spec.ts

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
import { isSize, Size } from "./size.class";
2+
3+
describe("Size", () => {
4+
it("should calculate the correct area of a Size", () => {
5+
const size = new Size(100, 100);
6+
const expected = size.width * size.height;
7+
8+
expect(size.area()).toEqual(expected);
9+
});
10+
11+
it("should return a proper string representation", () => {
12+
const size = new Size(100, 100);
13+
const expected = "(100x100)";
14+
15+
expect(size.toString()).toEqual(expected);
16+
});
17+
18+
describe("isSize typeguard", () => {
19+
it("should identify a Size object", () => {
20+
// GIVEN
21+
const s = new Size(100, 100);
22+
23+
// WHEN
24+
const result = isSize(s);
25+
26+
// THEN
27+
expect(result).toBeTruthy();
28+
});
29+
30+
it("should rule out non-size objects", () => {
31+
// GIVEN
32+
const r = "foo";
33+
34+
// WHEN
35+
const result = isSize(r);
36+
37+
// THEN
38+
expect(result).toBeFalsy();
39+
});
40+
41+
it("should rule out possible object with missing properties", () => {
42+
// GIVEN
43+
const r = {
44+
width: 100,
45+
};
46+
47+
// WHEN
48+
const result = isSize(r);
49+
50+
// THEN
51+
expect(result).toBeFalsy();
52+
});
53+
54+
it("should rule out possible object with wrong property type", () => {
55+
// GIVEN
56+
const r = {
57+
width: "foo",
58+
height: 200,
59+
};
60+
61+
// WHEN
62+
const result = isSize(r);
63+
64+
// THEN
65+
expect(result).toBeFalsy();
66+
});
67+
});
68+
});

lib/size.class.ts

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
export class Size {
2+
constructor(
3+
public width: number,
4+
public height: number,
5+
) {}
6+
7+
public area() {
8+
return this.width * this.height;
9+
}
10+
11+
public toString() {
12+
return `(${this.width}x${this.height})`;
13+
}
14+
}
15+
16+
const testSize = new Size(100, 100);
17+
const sizeKeys = Object.keys(testSize);
18+
export function isSize(possibleSize: any): possibleSize is Size {
19+
if (typeof possibleSize !== "object") {
20+
return false;
21+
}
22+
for (const key of sizeKeys) {
23+
if (!(key in possibleSize)) {
24+
return false;
25+
}
26+
const possibleSizeKeyType = typeof possibleSize[key];
27+
const sizeKeyType = typeof testSize[key as keyof typeof testSize];
28+
if (possibleSizeKeyType !== sizeKeyType) {
29+
return false;
30+
}
31+
}
32+
return true;
33+
}

lib/window.class.ts

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
11
import { Region } from "./region.class";
22
import { ProviderRegistry } from "./provider/provider-registry.class";
3+
import { Point } from "./point.class";
4+
import { Size } from "./size.class";
35

46
export class Window {
57
constructor(
68
private providerRegistry: ProviderRegistry,
7-
private windowHandle: number
9+
private windowHandle: number,
810
) {}
911

1012
get title(): Promise<string> {
@@ -14,4 +16,20 @@ export class Window {
1416
get region(): Promise<Region> {
1517
return this.providerRegistry.getWindow().getWindowRegion(this.windowHandle);
1618
}
19+
20+
async move(newOrigin: Point) {
21+
await this.providerRegistry
22+
.getWindow()
23+
.moveWindow(this.windowHandle, newOrigin);
24+
}
25+
26+
async resize(newSize: Size) {
27+
await this.providerRegistry
28+
.getWindow()
29+
.resizeWindow(this.windowHandle, newSize);
30+
}
31+
32+
async focus() {
33+
await this.providerRegistry.getWindow().focusWindow(this.windowHandle);
34+
}
1735
}

0 commit comments

Comments
 (0)