From 296d5de0a4fba71a5c4db29338a60b82c9e53a88 Mon Sep 17 00:00:00 2001 From: HMH Date: Fri, 18 Oct 2024 12:08:57 +0200 Subject: [PATCH] Add debug overlay, handle more pointer events. Additionally, improved css a bit. --- src/input/autopilot_device_win.rs | 22 +++++--- src/input/uinput_device.rs | 30 ++++++++--- src/protocol.rs | 8 +++ ts/lib.ts | 89 +++++++++++++++++++++++++++++++ www/static/style.css | 72 +++++++++++++------------ www/templates/index.html | 5 ++ 6 files changed, 178 insertions(+), 48 deletions(-) diff --git a/src/input/autopilot_device_win.rs b/src/input/autopilot_device_win.rs index d573608..2b0274e 100644 --- a/src/input/autopilot_device_win.rs +++ b/src/input/autopilot_device_win.rs @@ -59,9 +59,11 @@ impl InputDevice for WindowsInput { PointerEventType::DOWN => { POINTER_FLAG_INRANGE | POINTER_FLAG_INCONTACT | POINTER_FLAG_DOWN } - PointerEventType::MOVE => POINTER_FLAG_INRANGE | POINTER_FLAG_UPDATE, + PointerEventType::MOVE | PointerEventType::OVER | PointerEventType::ENTER => { + POINTER_FLAG_INRANGE | POINTER_FLAG_UPDATE + } PointerEventType::UP => POINTER_FLAG_UP, - PointerEventType::CANCEL => { + PointerEventType::CANCEL | PointerEventType::LEAVE | PointerEventType::OUT => { POINTER_FLAG_INRANGE | POINTER_FLAG_UPDATE | POINTER_FLAG_CANCELED } }; @@ -151,9 +153,15 @@ impl InputDevice for WindowsInput { InjectSyntheticPointerInput(self.touch_device_handle, m, len as u32); match event.event_type { - PointerEventType::DOWN | PointerEventType::MOVE => {} - - PointerEventType::UP | PointerEventType::CANCEL => { + PointerEventType::DOWN + | PointerEventType::MOVE + | PointerEventType::OVER + | PointerEventType::ENTER => {} + + PointerEventType::UP + | PointerEventType::CANCEL + | PointerEventType::LEAVE + | PointerEventType::OUT => { self.multitouch_map.remove(&event.pointer_id); } } @@ -180,7 +188,7 @@ impl InputDevice for WindowsInput { } _ => {} }, - PointerEventType::MOVE => { + PointerEventType::MOVE | PointerEventType::OVER | PointerEventType::ENTER => { unsafe { SetCursorPos(screen_x, screen_y) }; } PointerEventType::UP => match event.button { @@ -195,7 +203,7 @@ impl InputDevice for WindowsInput { } _ => {} }, - PointerEventType::CANCEL => { + PointerEventType::CANCEL | PointerEventType::LEAVE | PointerEventType::OUT => { dw_flags |= MOUSEEVENTF_LEFTUP; } } diff --git a/src/input/uinput_device.rs b/src/input/uinput_device.rs index a58f708..ac412d2 100644 --- a/src/input/uinput_device.rs +++ b/src/input/uinput_device.rs @@ -305,7 +305,10 @@ impl InputDevice for UInputDevice { self.num_touch_mapping_tries += 1; } match event.event_type { - PointerEventType::DOWN | PointerEventType::MOVE => { + PointerEventType::DOWN + | PointerEventType::MOVE + | PointerEventType::OVER + | PointerEventType::ENTER => { let slot: usize; // check if this event is already assigned to one of our 10 multitouch slots if let Some(s) = self.find_slot(event.pointer_id) { @@ -413,7 +416,10 @@ impl InputDevice for UInputDevice { ); self.send(self.touch_fd, ET_SYNC, EC_SYNC_REPORT, 0); } - PointerEventType::CANCEL | PointerEventType::UP => { + PointerEventType::CANCEL + | PointerEventType::UP + | PointerEventType::LEAVE + | PointerEventType::OUT => { // remove from slot if let Some(slot) = self.find_slot(event.pointer_id) { self.send(self.touch_fd, ET_ABSOLUTE, EC_ABS_MT_SLOT, slot as i32); @@ -459,7 +465,10 @@ impl InputDevice for UInputDevice { self.num_touch_mapping_tries += 1; } match event.event_type { - PointerEventType::DOWN | PointerEventType::MOVE => { + PointerEventType::DOWN + | PointerEventType::MOVE + | PointerEventType::OVER + | PointerEventType::ENTER => { if let PointerEventType::DOWN = event.event_type { self.pen_touching = true; self.send(self.stylus_fd, ET_KEY, EC_KEY_TOUCH, 1); @@ -509,7 +518,10 @@ impl InputDevice for UInputDevice { event.tilt_y, ); } - PointerEventType::UP | PointerEventType::CANCEL => { + PointerEventType::UP + | PointerEventType::CANCEL + | PointerEventType::LEAVE + | PointerEventType::OUT => { self.send(self.stylus_fd, ET_KEY, EC_KEY_TOUCH, 0); self.send(self.stylus_fd, ET_KEY, EC_KEY_TOOL_PEN, 0); self.send(self.stylus_fd, ET_KEY, EC_KEY_TOOL_RUBBER, 0); @@ -546,7 +558,10 @@ impl InputDevice for UInputDevice { self.num_touch_mapping_tries += 1; } match event.event_type { - PointerEventType::DOWN | PointerEventType::MOVE => { + PointerEventType::DOWN + | PointerEventType::MOVE + | PointerEventType::OVER + | PointerEventType::ENTER => { if let PointerEventType::DOWN = event.event_type { match event.button { Button::PRIMARY => { @@ -574,7 +589,10 @@ impl InputDevice for UInputDevice { self.transform_y(event.y), ); } - PointerEventType::UP | PointerEventType::CANCEL => match event.button { + PointerEventType::UP + | PointerEventType::CANCEL + | PointerEventType::LEAVE + | PointerEventType::OUT => match event.button { Button::PRIMARY => self.send(self.mouse_fd, ET_KEY, EC_KEY_MOUSE_LEFT, 0), Button::SECONDARY => { self.send(self.mouse_fd, ET_KEY, EC_KEY_MOUSE_RIGHT, 0) diff --git a/src/protocol.rs b/src/protocol.rs index f58c06d..77460ed 100644 --- a/src/protocol.rs +++ b/src/protocol.rs @@ -82,6 +82,14 @@ pub enum PointerEventType { CANCEL, #[serde(rename = "pointermove")] MOVE, + #[serde(rename = "pointerover")] + OVER, + #[serde(rename = "pointerenter")] + ENTER, + #[serde(rename = "pointerleave")] + LEAVE, + #[serde(rename = "pointerout")] + OUT, } #[derive(Serialize, Deserialize, Debug)] diff --git a/ts/lib.ts b/ts/lib.ts index ecb873e..a3b3ae7 100644 --- a/ts/lib.ts +++ b/ts/lib.ts @@ -176,6 +176,16 @@ class Settings { this.save_settings(); }; + this.checks.get("enable_debug_overlay").onchange = (e) => { + let enabled = (e.target as HTMLInputElement).checked; + if (enabled) { + debug_overlay.classList.remove("hide"); + } else { + debug_overlay.classList.add("hide"); + } + this.save_settings(); + }; + this.check_aggressive_seek = this.checks.get("aggressive_seeking"); this.check_aggressive_seek.onchange = () => { this.save_settings(); @@ -306,6 +316,11 @@ class Settings { this.toggle_energysaving(true); } + if (this.checks.get("enable_debug_overlay").checked) { + debug_overlay.classList.remove("hide"); + } + + if (document.getElementById("custom_input_areas").classList.contains("hide")) { this.checks.get("enable_custom_input_areas").checked = false; } @@ -385,6 +400,8 @@ class Settings { } let settings: Settings; +let debug_overlay: HTMLElement; +let last_pointer_data: Object; class PEvent { event_type: string; @@ -683,6 +700,10 @@ class PointerHandler { video.onpointerup = (e) => this.onEvent(e, "pointerup"); video.onpointercancel = (e) => this.onEvent(e, "pointercancel"); video.onpointermove = (e) => this.onEvent(e, "pointermove"); + video.onpointerout = (e) => this.onEvent(e, "pointerout"); + video.onpointerleave = (e) => this.onEvent(e, "pointerleave"); + video.onpointerenter = (e) => this.onEvent(e, "pointerenter"); + video.onpointerover = (e) => this.onEvent(e, "pointerover"); let painter: Painter; if (!settings.checks.get("energysaving").checked) @@ -693,11 +714,19 @@ class PointerHandler { canvas.onpointerup = (e) => { this.onEvent(e, "pointerup"); painter.onstop(e); }; canvas.onpointercancel = (e) => { this.onEvent(e, "pointercancel"); painter.onstop(e); }; canvas.onpointermove = (e) => { this.onEvent(e, "pointermove"); painter.onmove(e); }; + canvas.onpointerout = (e) => { this.onEvent(e, "pointerout"); painter.onstop(e); }; + canvas.onpointerleave = (e) => { this.onEvent(e, "pointerleave"); painter.onstop(e); }; + canvas.onpointerenter = (e) => { this.onEvent(e, "pointerenter"); painter.onmove(e); }; + canvas.onpointerover = (e) => { this.onEvent(e, "pointerover"); painter.onmove(e); }; } else { canvas.onpointerdown = (e) => this.onEvent(e, "pointerdown"); canvas.onpointerup = (e) => this.onEvent(e, "pointerup"); canvas.onpointercancel = (e) => this.onEvent(e, "pointercancel"); canvas.onpointermove = (e) => this.onEvent(e, "pointermove"); + canvas.onpointerout = (e) => this.onEvent(e, "pointerout"); + canvas.onpointerleave = (e) => this.onEvent(e, "pointerleave"); + canvas.onpointerenter = (e) => this.onEvent(e, "pointerenter"); + canvas.onpointerover = (e) => this.onEvent(e, "pointerover"); } // This is a workaround for the following Safari/WebKit bug: @@ -714,6 +743,65 @@ class PointerHandler { } onEvent(event: PointerEvent, event_type: string) { + if (settings.checks.get("enable_debug_overlay").checked) { + let props = [ + "altKey", + "altitudeAngle", + "azimuthAngle", + "button", + "buttons", + "clientX", + "clientY", + "ctrlKey", + "height", + "isPrimary", + "metaKey", + "movementX", + "movementY", + "offsetX", + "offsetY", + "pageX", + "pageY", + "pointerId", + "pointerType", + "pressure", + "screenX", + "screenY", + "shiftKey", + "tangentialPressure", + "tiltX", + "tiltY", + "timeStamp", + "twist", + "type", + "width", + "x", + "y", + ]; + if (!last_pointer_data) { + last_pointer_data = {}; + for (let prop of props) { + let span_id = `prop_${prop}_span`; + let span = document.getElementById(span_id); + span = document.createElement("span"); + span.id = span_id; + debug_overlay.appendChild(span); + debug_overlay.appendChild(document.createElement("br")); + } + } + for (let prop of props) { + let span_id = `prop_${prop}_span`; + let span = document.getElementById(span_id); + let v = event[prop]; + span.textContent = `${prop}: ${v}`; + if (last_pointer_data[prop] == v) { + span.classList.remove("updated"); + } else { + span.classList.add("updated"); + last_pointer_data[prop] = v; + } + } + } if (this.pointerTypes.includes(event.pointerType)) { let rect = (event.target as HTMLElement).getBoundingClientRect(); const events = event_type === "pointermove" && typeof event.getCoalescedEvents === 'function' ? event.getCoalescedEvents() : [event]; @@ -944,6 +1032,7 @@ function init() { ); webSocket.binaryType = "arraybuffer"; + debug_overlay = document.getElementById("debug_overlay"); settings = new Settings(webSocket); let video = document.getElementById("video") as HTMLVideoElement; diff --git a/www/static/style.css b/www/static/style.css index 49b7e41..41d48cb 100644 --- a/www/static/style.css +++ b/www/static/style.css @@ -1,37 +1,15 @@ @media (prefers-color-scheme: dark) { - body, html { - background: #202020; - } - #settings { - color: #ddd; - background: #303030; - } - #handle { - background: #303030; - color: #ddd; - } - form { - background: #303030; - color: #ddd; - border: 0.5em solid #252525; + :root { + --color: #ddd; + --background-color-1: #303030; + --background-color-2: #202020; } } @media (prefers-color-scheme: light) { - body, html { - background: #fff; - } - #settings { - color: #111; - background: #eee; - } - #handle { - background: #eee; - color: #111; - } - form { - background: #eee; - color: #111; - border: 0.5em solid #f7f7f7; + :root { + --color: #111; + --background-color-1: #eee; + --background-color-2: #fff; } } main { @@ -50,6 +28,8 @@ body, html, main { padding: 0; overflow: hidden; display: flex; + color: var(--color); + background: var(--background-color-2); } video { max-width: 100%; @@ -76,10 +56,6 @@ input[type='text'] { input[type='range']::-webkit-slider-runnable-track, input[type="range"]::-moz-range-track { background-color: #00aaff; } -form, form input { - font-size: 1.4em; - display: grid; -} .container { width: 100%; height: 100%; @@ -87,6 +63,10 @@ form, form input { justify-content: center; align-items: center; } +#settings, #handle, #debug_overlay { + color: var(--color); + background: var(--background-color-1); +} #settings_scroll { overflow: auto; width: 100%; @@ -151,7 +131,7 @@ form, form input { display: block; margin-top: 0.5em; } -#settings section.hide, section label.hide, section button.hide { +#settings section.hide, section label.hide, section button.hide, #debug_overlay.hide { display: none !important; } select { @@ -205,3 +185,25 @@ label input:disabled + span { -moz-user-select: text; -ms-user-select: text; } +#debug_overlay { + --padding: 3px; + position: absolute; + top:0; + bottom: 0; + left: 0; + right: 0; + margin: auto; + width: fit-content; + height: fit-content; + z-index: 1; + pointer-events: none; + opacity: 75%; + padding: var(--padding); + border: 2px solid var(--color); + white-space: pre; + font-size: small; + text-align: center; +} +#debug_overlay span.updated { + color: darkgreen; +} diff --git a/www/templates/index.html b/www/templates/index.html index d628c92..17ab93a 100644 --- a/www/templates/index.html +++ b/www/templates/index.html @@ -18,6 +18,7 @@
+
@@ -73,6 +74,10 @@

Input

+
+ +