bare-pointer 0.1.1 → 0.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/index.js +57 -10
- package/lib/android.js +0 -2
- package/lib/darwin.js +18 -3
- package/lib/linux.js +14 -3
- package/lib/win32.js +25 -7
- package/package.json +3 -3
package/index.js
CHANGED
|
@@ -14,10 +14,14 @@ module.exports = class Pointer {
|
|
|
14
14
|
async down(view, x, y) {
|
|
15
15
|
if (this._view !== null) throw new Error('Pointer is already down')
|
|
16
16
|
|
|
17
|
-
|
|
17
|
+
const point = this._point(view, x, y)
|
|
18
|
+
|
|
19
|
+
await this._reach(view, point)
|
|
20
|
+
|
|
21
|
+
this._backend.down(view, ...point)
|
|
18
22
|
this._view = view
|
|
19
23
|
|
|
20
|
-
await
|
|
24
|
+
await this._frame(view)
|
|
21
25
|
}
|
|
22
26
|
|
|
23
27
|
async move(view, x, y) {
|
|
@@ -25,7 +29,7 @@ module.exports = class Pointer {
|
|
|
25
29
|
|
|
26
30
|
this._backend.move(view, ...this._point(view, x, y))
|
|
27
31
|
|
|
28
|
-
await
|
|
32
|
+
await this._frame(view)
|
|
29
33
|
}
|
|
30
34
|
|
|
31
35
|
async up() {
|
|
@@ -36,7 +40,7 @@ module.exports = class Pointer {
|
|
|
36
40
|
this._backend.up()
|
|
37
41
|
this._view = null
|
|
38
42
|
|
|
39
|
-
await
|
|
43
|
+
await this._frame(view)
|
|
40
44
|
}
|
|
41
45
|
|
|
42
46
|
async tap(view, x, y) {
|
|
@@ -44,18 +48,20 @@ module.exports = class Pointer {
|
|
|
44
48
|
|
|
45
49
|
const point = this._point(view, x, y)
|
|
46
50
|
|
|
51
|
+
await this._reach(view, point)
|
|
52
|
+
|
|
47
53
|
if (this._backend.tap) {
|
|
48
54
|
this._backend.tap(view, ...point)
|
|
49
55
|
} else {
|
|
50
56
|
this._backend.down(view, ...point)
|
|
51
57
|
|
|
52
58
|
// UIKit controls only see a press that lasts past a frame.
|
|
53
|
-
await
|
|
59
|
+
await this._frame(view)
|
|
54
60
|
|
|
55
61
|
this._backend.up()
|
|
56
62
|
}
|
|
57
63
|
|
|
58
|
-
await
|
|
64
|
+
await this._frame(view)
|
|
59
65
|
}
|
|
60
66
|
|
|
61
67
|
destroy() {
|
|
@@ -65,6 +71,51 @@ module.exports = class Pointer {
|
|
|
65
71
|
this._backend.destroy()
|
|
66
72
|
}
|
|
67
73
|
|
|
74
|
+
async _reach(view, point) {
|
|
75
|
+
if (this._backend.covered !== undefined) {
|
|
76
|
+
for (let frames = 0; this._backend.covered(view, ...point); frames++) {
|
|
77
|
+
if (frames === 60) throw new Error('The view is covered at the point')
|
|
78
|
+
|
|
79
|
+
await this._frame(view)
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
if (this._backend.hover !== undefined) {
|
|
84
|
+
this._backend.hover(view, ...point)
|
|
85
|
+
|
|
86
|
+
await this._frame(view)
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
_frame(view) {
|
|
91
|
+
const provider = new AnimationFrameProvider(view)
|
|
92
|
+
|
|
93
|
+
if (this._backend.watch === undefined) return provider.afterAnimationFrame()
|
|
94
|
+
|
|
95
|
+
return new Promise((resolve) => {
|
|
96
|
+
let ended = false
|
|
97
|
+
let unwatch = null
|
|
98
|
+
|
|
99
|
+
const request = provider.afterAnimationFrame(done)
|
|
100
|
+
|
|
101
|
+
unwatch = this._backend.watch(view, done)
|
|
102
|
+
|
|
103
|
+
if (ended) unwatch()
|
|
104
|
+
|
|
105
|
+
function done() {
|
|
106
|
+
if (ended) return
|
|
107
|
+
|
|
108
|
+
ended = true
|
|
109
|
+
|
|
110
|
+
request.cancel()
|
|
111
|
+
|
|
112
|
+
if (unwatch !== null) unwatch()
|
|
113
|
+
|
|
114
|
+
resolve()
|
|
115
|
+
}
|
|
116
|
+
})
|
|
117
|
+
}
|
|
118
|
+
|
|
68
119
|
_point(view, x, y) {
|
|
69
120
|
if (x !== undefined && y !== undefined) return [x, y]
|
|
70
121
|
|
|
@@ -73,7 +124,3 @@ module.exports = class Pointer {
|
|
|
73
124
|
return [x === undefined ? width / 2 : x, y === undefined ? height / 2 : y]
|
|
74
125
|
}
|
|
75
126
|
}
|
|
76
|
-
|
|
77
|
-
function frame(view) {
|
|
78
|
-
return new AnimationFrameProvider(view).afterAnimationFrame()
|
|
79
|
-
}
|
package/lib/android.js
CHANGED
|
@@ -30,8 +30,6 @@ module.exports = class AndroidPointer {
|
|
|
30
30
|
|
|
31
31
|
destroy() {}
|
|
32
32
|
|
|
33
|
-
// The root is not always at the origin of the window, so the view is placed
|
|
34
|
-
// by its offset from the root.
|
|
35
33
|
_dispatch(action, view, x, y) {
|
|
36
34
|
const root = view.rootView
|
|
37
35
|
const here = view.locationInWindow
|
package/lib/darwin.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
const AnimationFrameProvider = require('bare-animation-frame')
|
|
1
2
|
const AppKitApplication = require('bare-app-kit/application')
|
|
2
3
|
const AppKitEvent = require('bare-app-kit/event')
|
|
3
4
|
|
|
@@ -15,6 +16,23 @@ module.exports = class DarwinPointer {
|
|
|
15
16
|
return [width, height]
|
|
16
17
|
}
|
|
17
18
|
|
|
19
|
+
watch(view, onhidden) {
|
|
20
|
+
let request = null
|
|
21
|
+
|
|
22
|
+
check()
|
|
23
|
+
|
|
24
|
+
function check() {
|
|
25
|
+
const window = view.window
|
|
26
|
+
|
|
27
|
+
if (window === null || !window.visible) onhidden()
|
|
28
|
+
else request = AnimationFrameProvider.requestAnimationFrame(check)
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
return () => {
|
|
32
|
+
if (request !== null) request.cancel()
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
|
|
18
36
|
down(view, x, y) {
|
|
19
37
|
this._send(TYPE.LEFT_MOUSE_DOWN, view, x, y)
|
|
20
38
|
}
|
|
@@ -27,9 +45,6 @@ module.exports = class DarwinPointer {
|
|
|
27
45
|
this._window.sendEvent(this._event(TYPE.LEFT_MOUSE_UP, this._window, this._point))
|
|
28
46
|
}
|
|
29
47
|
|
|
30
|
-
// A control tracks the mouse by reading the event queue until it is released,
|
|
31
|
-
// and a press that could start a double click is held back until the event
|
|
32
|
-
// after it, so both have to go through the queue in order.
|
|
33
48
|
tap(view, x, y) {
|
|
34
49
|
const window = view.window
|
|
35
50
|
const point = view.convertPointToView(x, y, null)
|
package/lib/linux.js
CHANGED
|
@@ -10,6 +10,20 @@ module.exports = class LinuxPointer {
|
|
|
10
10
|
return [view.width, view.height]
|
|
11
11
|
}
|
|
12
12
|
|
|
13
|
+
watch(view, onhidden) {
|
|
14
|
+
const window = view.native
|
|
15
|
+
|
|
16
|
+
if (window === null || !window.visible) {
|
|
17
|
+
onhidden()
|
|
18
|
+
|
|
19
|
+
return () => {}
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
window.on('hide', onhidden)
|
|
23
|
+
|
|
24
|
+
return () => window.off('hide', onhidden)
|
|
25
|
+
}
|
|
26
|
+
|
|
13
27
|
down(view, x, y) {
|
|
14
28
|
this._move(view, x, y)
|
|
15
29
|
|
|
@@ -40,9 +54,6 @@ module.exports = class LinuxPointer {
|
|
|
40
54
|
xtest.fakeMotionEvent(this._display, xtest.CURRENT_SCREEN, point.x, point.y)
|
|
41
55
|
}
|
|
42
56
|
|
|
43
|
-
// A point in the widget becomes one in its native, then in the surface of
|
|
44
|
-
// that, which is drawn in device pixels on an X11 window that the server can
|
|
45
|
-
// place on the root.
|
|
46
57
|
_point(view, x, y) {
|
|
47
58
|
const native = view.native
|
|
48
59
|
const surface = native.surface
|
package/lib/win32.js
CHANGED
|
@@ -2,6 +2,7 @@ const Win32Interop = require('bare-win-ui/win32-interop')
|
|
|
2
2
|
const user32 = require('bare-user32')
|
|
3
3
|
|
|
4
4
|
const {
|
|
5
|
+
GA_ROOT,
|
|
5
6
|
SM_XVIRTUALSCREEN,
|
|
6
7
|
SM_YVIRTUALSCREEN,
|
|
7
8
|
SM_CXVIRTUALSCREEN,
|
|
@@ -23,13 +24,28 @@ module.exports = class Win32Pointer {
|
|
|
23
24
|
return [view.actualWidth, view.actualHeight]
|
|
24
25
|
}
|
|
25
26
|
|
|
26
|
-
|
|
27
|
-
|
|
27
|
+
covered(view, x, y) {
|
|
28
|
+
const { window, screen } = locate(view, x, y)
|
|
29
|
+
const top = user32.windowFromPoint(screen.x, screen.y)
|
|
30
|
+
|
|
31
|
+
if (top !== null && user32.getAncestor(top, GA_ROOT) === window) return false
|
|
32
|
+
|
|
33
|
+
user32.setForegroundWindow(window)
|
|
34
|
+
|
|
35
|
+
return true
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
hover(view, x, y) {
|
|
39
|
+
this._point = normalize(locate(view, x, y).screen)
|
|
40
|
+
this._send(0)
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
down() {
|
|
28
44
|
this._send(MOUSEEVENTF_LEFTDOWN)
|
|
29
45
|
}
|
|
30
46
|
|
|
31
47
|
move(view, x, y) {
|
|
32
|
-
this._point = locate(view, x, y)
|
|
48
|
+
this._point = normalize(locate(view, x, y).screen)
|
|
33
49
|
this._send(0)
|
|
34
50
|
}
|
|
35
51
|
|
|
@@ -54,8 +70,6 @@ module.exports = class Win32Pointer {
|
|
|
54
70
|
}
|
|
55
71
|
}
|
|
56
72
|
|
|
57
|
-
// An element is placed in DIPs from the XAML root, which fills the client area
|
|
58
|
-
// of its window. Absolute input divides the virtual screen into 65536 steps.
|
|
59
73
|
function locate(view, x, y) {
|
|
60
74
|
const root = view.xamlRoot
|
|
61
75
|
const scale = root.rasterizationScale
|
|
@@ -68,13 +82,17 @@ function locate(view, x, y) {
|
|
|
68
82
|
Math.round(point.y * scale)
|
|
69
83
|
)
|
|
70
84
|
|
|
85
|
+
return { window, screen }
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
function normalize(screen) {
|
|
71
89
|
const left = user32.getSystemMetrics(SM_XVIRTUALSCREEN)
|
|
72
90
|
const top = user32.getSystemMetrics(SM_YVIRTUALSCREEN)
|
|
73
91
|
const width = user32.getSystemMetrics(SM_CXVIRTUALSCREEN)
|
|
74
92
|
const height = user32.getSystemMetrics(SM_CYVIRTUALSCREEN)
|
|
75
93
|
|
|
76
94
|
return {
|
|
77
|
-
dx: Math.round(((screen.x - left) * 65536) / width),
|
|
78
|
-
dy: Math.round(((screen.y - top) * 65536) / height)
|
|
95
|
+
dx: Math.round(((screen.x - left + 0.5) * 65536) / width),
|
|
96
|
+
dy: Math.round(((screen.y - top + 0.5) * 65536) / height)
|
|
79
97
|
}
|
|
80
98
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "bare-pointer",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.2",
|
|
4
4
|
"description": "Simulated pointer input for testing Bare apps",
|
|
5
5
|
"exports": {
|
|
6
6
|
"./package": "./package.json",
|
|
@@ -51,13 +51,13 @@
|
|
|
51
51
|
"bare-app-kit": "^0.3.1",
|
|
52
52
|
"bare-ndk": "^0.3.4",
|
|
53
53
|
"bare-ui-kit-touch": "^0.1.0",
|
|
54
|
-
"bare-user32": "^0.1.
|
|
54
|
+
"bare-user32": "^0.1.1",
|
|
55
55
|
"bare-win-ui": "^0.3.7",
|
|
56
56
|
"bare-x11": "^0.1.0",
|
|
57
57
|
"bare-x11-xtest": "^0.1.0"
|
|
58
58
|
},
|
|
59
59
|
"devDependencies": {
|
|
60
|
-
"bare-gtk": "^0.4.
|
|
60
|
+
"bare-gtk": "^0.4.2",
|
|
61
61
|
"bare-native-test": "^0.1.3",
|
|
62
62
|
"bare-tap": "^1.1.0",
|
|
63
63
|
"bare-ui-kit": "^0.3.1",
|