Skip to content
/ kvmd Public

Commit e014cbc

Browse files
committed
pikvm/pikvm#858, pikvm/pikvm#1249: Added slow typing mode for /api/hid/print
1 parent adbd4f2 commit e014cbc

File tree

7 files changed

+42
-14
lines changed

7 files changed

+42
-14
lines changed

kvmd/apps/kvmd/api/hid.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -123,7 +123,8 @@ async def __print_handler(self, req: Request) -> Response:
123123
if limit > 0:
124124
text = text[:limit]
125125
symmap = self.__ensure_symmap(req.query.get("keymap", self.__default_keymap_name))
126-
self.__hid.send_key_events(text_to_web_keys(text, symmap), no_ignore_keys=True)
126+
slow = valid_bool(req.query.get("slow", False))
127+
await self.__hid.send_key_events(text_to_web_keys(text, symmap), no_ignore_keys=True, slow=slow)
127128
return make_json_response()
128129

129130
def __ensure_symmap(self, keymap_name: str) -> dict[int, dict[int, str]]:
@@ -250,7 +251,7 @@ async def __events_send_key_handler(self, req: Request) -> Response:
250251
state = valid_bool(req.query["state"])
251252
self.__hid.send_key_event(key, state)
252253
else:
253-
self.__hid.send_key_events([(key, True), (key, False)])
254+
await self.__hid.send_key_events([(key, True), (key, False)], slow=True)
254255
return make_json_response()
255256

256257
@exposed_http("POST", "/hid/events/send_mouse_button")

kvmd/apps/kvmd/snapshoter.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -123,7 +123,7 @@ async def __wakeup(self) -> None:
123123

124124
if self.__wakeup_key:
125125
logger.info("Waking up using key %r ...", self.__wakeup_key)
126-
self.__hid.send_key_events(
126+
await self.__hid.send_key_events(
127127
keys=[(self.__wakeup_key, True), (self.__wakeup_key, False)],
128128
no_ignore_keys=True,
129129
)

kvmd/plugins/hid/__init__.py

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -137,9 +137,17 @@ def set_connected(self, connected: bool) -> None:
137137

138138
# =====
139139

140-
def send_key_events(self, keys: Iterable[tuple[str, bool]], no_ignore_keys: bool=False) -> None:
140+
async def send_key_events(
141+
self,
142+
keys: Iterable[tuple[str, bool]],
143+
no_ignore_keys: bool=False,
144+
slow: bool=False,
145+
) -> None:
146+
141147
for (key, state) in keys:
142148
if no_ignore_keys or key not in self.__ignore_keys:
149+
if slow:
150+
await asyncio.sleep(0.02)
143151
self.send_key_event(key, state)
144152

145153
def send_key_event(self, key: str, state: bool) -> None:

web/kvm/index.html

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -728,11 +728,11 @@
728728
</table>
729729
<table class="kv">
730730
<tr>
731-
<td>Ask paste confirmation:</td>
731+
<td>Slow typing:</td>
732732
<td align="right">
733733
<div class="switch-box">
734-
<input checked type="checkbox" id="hid-pak-ask-switch">
735-
<label for="hid-pak-ask-switch"><span class="switch-inner"></span><span class="switch"></span></label>
734+
<input type="checkbox" id="hid-pak-slow-switch">
735+
<label for="hid-pak-slow-switch"><span class="switch-inner"></span><span class="switch"></span></label>
736736
</div>
737737
</td>
738738
</tr>
@@ -745,6 +745,15 @@
745745
</div>
746746
</td>
747747
</tr>
748+
<tr>
749+
<td>Ask paste confirmation:</td>
750+
<td align="right">
751+
<div class="switch-box">
752+
<input checked type="checkbox" id="hid-pak-ask-switch">
753+
<label for="hid-pak-ask-switch"><span class="switch-inner"></span><span class="switch"></span></label>
754+
</div>
755+
</td>
756+
</tr>
748757
</table>
749758
<div class="feature-disabled" id="stream-ocr">
750759
<hr><br>

web/kvm/navbar-text.pug

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,11 @@ li(id="text-dropdown" class="right")
1818
select(id="hid-pak-keymap-selector")
1919
table(class="kv")
2020
tr
21-
+menu_switch_notable("hid-pak-ask-switch", "Ask paste confirmation", true, true)
21+
+menu_switch_notable("hid-pak-slow-switch", "Slow typing", true, false)
2222
tr
2323
+menu_switch_notable("hid-pak-secure-switch", "Hide input text", true, false)
24+
tr
25+
+menu_switch_notable("hid-pak-ask-switch", "Ask paste confirmation", true, true)
2426
div(id="stream-ocr" class="feature-disabled")
2527
hr
2628
br

web/share/js/kvm/paste.js

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ export function Paste(__recorder) {
3434

3535
var __init__ = function() {
3636
tools.storage.bindSimpleSwitch($("hid-pak-ask-switch"), "hid.pak.ask", true);
37+
tools.storage.bindSimpleSwitch($("hid-pak-slow-switch"), "hid.pak.slow", false);
3738
tools.storage.bindSimpleSwitch($("hid-pak-secure-switch"), "hid.pak.secure", false, function(value) {
3839
$("hid-pak-text").style.setProperty("-webkit-text-security", (value ? "disc" : "none"));
3940
});
@@ -67,10 +68,11 @@ export function Paste(__recorder) {
6768
tools.el.setEnabled($("hid-pak-keymap-selector"), false);
6869

6970
let keymap = $("hid-pak-keymap-selector").value;
71+
let slow = $("hid-pak-slow-switch").checked;
7072

7173
tools.debug(`HID: paste-as-keys ${keymap}: ${text}`);
7274

73-
tools.httpPost("/api/hid/print", {"limit": 0, "keymap": keymap}, function(http) {
75+
tools.httpPost("/api/hid/print", {"limit": 0, "keymap": keymap, "slow": slow}, function(http) {
7476
tools.el.setEnabled($("hid-pak-text"), true);
7577
tools.el.setEnabled($("hid-pak-button"), true);
7678
tools.el.setEnabled($("hid-pak-keymap-selector"), true);
@@ -80,7 +82,7 @@ export function Paste(__recorder) {
8082
} else if (http.status !== 200) {
8183
wm.error("HID paste error", http.responseText);
8284
} else if (http.status === 200) {
83-
__recorder.recordPrintEvent(text, keymap);
85+
__recorder.recordPrintEvent(text, keymap, slow);
8486
}
8587
}, text, "text/plain");
8688
};

web/share/js/kvm/recorder.js

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -67,8 +67,8 @@ export function Recorder() {
6767
__recordEvent(event);
6868
};
6969

70-
self.recordPrintEvent = function(text, keymap) {
71-
__recordEvent({"event_type": "print", "event": {"text": text, "keymap": keymap}});
70+
self.recordPrintEvent = function(text, keymap, slow) {
71+
__recordEvent({"event_type": "print", "event": {"text": text, "keymap": keymap, "slow": slow}});
7272
};
7373

7474
self.recordAtxButtonEvent = function(button) {
@@ -159,9 +159,12 @@ export function Recorder() {
159159

160160
} else if (event.event_type === "print") {
161161
__checkType(event.event.text, "string", "Non-string print text");
162-
if (event.event.keymap) {
162+
if (event.event.keymap !== undefined) {
163163
__checkType(event.event.keymap, "string", "Non-string keymap");
164164
}
165+
if (event.event.slow !== undefined) {
166+
__checkType(event.event.slow, "boolean", "Non-bool slow");
167+
}
165168

166169
} else if (event.event_type === "key") {
167170
__checkType(event.event.key, "string", "Non-string key code");
@@ -284,9 +287,12 @@ export function Recorder() {
284287

285288
} else if (event.event_type === "print") {
286289
let params = {"limit": 0};
287-
if (event.event.keymap) {
290+
if (event.event.keymap !== undefined) {
288291
params["keymap"] = event.event.keymap;
289292
}
293+
if (event.event.slow !== undefined) {
294+
params["slow"] = event.event.slow;
295+
}
290296
tools.httpPost("/api/hid/print", params, function(http) {
291297
if (http.status === 413) {
292298
wm.error("Too many text for paste!");

0 commit comments

Comments
 (0)