fix keyboard capturing to limit it a bit + default to canvas mode for everything
This commit is contained in:
@@ -122,6 +122,7 @@ import { createSharedUiSettingsSaver, loadSharedUiSettings } from "./shared-ui-s
|
|||||||
let whepClient = null;
|
let whepClient = null;
|
||||||
let p2pClient = null;
|
let p2pClient = null;
|
||||||
let webrtcActive = false;
|
let webrtcActive = false;
|
||||||
|
const CANVAS_TRANSPORT_PREF_VERSION = 1;
|
||||||
|
|
||||||
function getWebrtcMode() {
|
function getWebrtcMode() {
|
||||||
return webrtcMode ? String(webrtcMode.value || "off") : "off";
|
return webrtcMode ? String(webrtcMode.value || "off") : "off";
|
||||||
@@ -178,7 +179,7 @@ import { createSharedUiSettingsSaver, loadSharedUiSettings } from "./shared-ui-s
|
|||||||
savedDisplay = Number.isFinite(Number(settings.display)) ? Number(settings.display) : savedDisplay;
|
savedDisplay = Number.isFinite(Number(settings.display)) ? Number(settings.display) : savedDisplay;
|
||||||
setSelectValue(backstageResolutionSelect, settings.resolution);
|
setSelectValue(backstageResolutionSelect, settings.resolution);
|
||||||
setSelectValue(targetFpsSelect, settings.targetFps);
|
setSelectValue(targetFpsSelect, settings.targetFps);
|
||||||
setSelectValue(webrtcMode, settings.webrtcMode);
|
setSelectValue(webrtcMode, settings.transportPreferenceVersion === CANVAS_TRANSPORT_PREF_VERSION ? settings.webrtcMode : "off");
|
||||||
if (qualitySlider && settings.quality !== undefined) qualitySlider.value = String(settings.quality);
|
if (qualitySlider && settings.quality !== undefined) qualitySlider.value = String(settings.quality);
|
||||||
if (mouseCtrl && typeof settings.mouse === "boolean") mouseCtrl.checked = settings.mouse;
|
if (mouseCtrl && typeof settings.mouse === "boolean") mouseCtrl.checked = settings.mouse;
|
||||||
if (kbdCtrl && typeof settings.keyboard === "boolean") kbdCtrl.checked = settings.keyboard;
|
if (kbdCtrl && typeof settings.keyboard === "boolean") kbdCtrl.checked = settings.keyboard;
|
||||||
@@ -206,6 +207,7 @@ import { createSharedUiSettingsSaver, loadSharedUiSettings } from "./shared-ui-s
|
|||||||
quality: Number(qualitySlider?.value || 90),
|
quality: Number(qualitySlider?.value || 90),
|
||||||
preferH264: !!prefersH264,
|
preferH264: !!prefersH264,
|
||||||
webrtcMode: getWebrtcMode(),
|
webrtcMode: getWebrtcMode(),
|
||||||
|
transportPreferenceVersion: CANVAS_TRANSPORT_PREF_VERSION,
|
||||||
mouse: !!mouseCtrl?.checked,
|
mouse: !!mouseCtrl?.checked,
|
||||||
keyboard: !!kbdCtrl?.checked,
|
keyboard: !!kbdCtrl?.checked,
|
||||||
clipboardSync: !!clipboardSyncCtrl?.checked,
|
clipboardSync: !!clipboardSyncCtrl?.checked,
|
||||||
|
|||||||
@@ -11,6 +11,12 @@ function isEditableTarget(container) {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function hasCaptureFocus(container) {
|
||||||
|
if (!container) return true;
|
||||||
|
const el = document.activeElement;
|
||||||
|
return !!el && (el === container || container.contains(el));
|
||||||
|
}
|
||||||
|
|
||||||
const SYSTEM_KEY_CODES = [
|
const SYSTEM_KEY_CODES = [
|
||||||
"Escape",
|
"Escape",
|
||||||
"Tab",
|
"Tab",
|
||||||
@@ -43,9 +49,39 @@ export function createKeyboardCapture({ container, sendKeyDown, sendKeyUp, onTex
|
|||||||
let enabled = false;
|
let enabled = false;
|
||||||
const pressed = new Map();
|
const pressed = new Map();
|
||||||
|
|
||||||
|
function setCaptureFlag(active) {
|
||||||
|
if (active) window[CAPTURE_FLAG] = true;
|
||||||
|
else delete window[CAPTURE_FLAG];
|
||||||
|
}
|
||||||
|
|
||||||
|
function refreshCaptureState() {
|
||||||
|
if (!enabled) {
|
||||||
|
setCaptureFlag(false);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (hasCaptureFocus(container)) {
|
||||||
|
setCaptureFlag(true);
|
||||||
|
tryLock();
|
||||||
|
} else {
|
||||||
|
setCaptureFlag(false);
|
||||||
|
tryUnlock();
|
||||||
|
releaseAll();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function shouldCapture() {
|
||||||
|
if (!enabled) return false;
|
||||||
|
if (!hasCaptureFocus(container)) {
|
||||||
|
refreshCaptureState();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (isEditableTarget(container)) return false;
|
||||||
|
setCaptureFlag(true);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
function handleDown(e) {
|
function handleDown(e) {
|
||||||
if (!enabled) return;
|
if (!shouldCapture()) return;
|
||||||
if (isEditableTarget(container)) return;
|
|
||||||
pressed.set(e.code || e.key, { key: e.key, code: e.code });
|
pressed.set(e.code || e.key, { key: e.key, code: e.code });
|
||||||
if (onTextInput && !e.ctrlKey && !e.metaKey && !e.altKey && typeof e.key === "string" && e.key.length === 1) {
|
if (onTextInput && !e.ctrlKey && !e.metaKey && !e.altKey && typeof e.key === "string" && e.key.length === 1) {
|
||||||
onTextInput(e);
|
onTextInput(e);
|
||||||
@@ -57,8 +93,7 @@ export function createKeyboardCapture({ container, sendKeyDown, sendKeyUp, onTex
|
|||||||
}
|
}
|
||||||
|
|
||||||
function handleUp(e) {
|
function handleUp(e) {
|
||||||
if (!enabled) return;
|
if (!shouldCapture()) return;
|
||||||
if (isEditableTarget(container)) return;
|
|
||||||
pressed.delete(e.code || e.key);
|
pressed.delete(e.code || e.key);
|
||||||
if (onTextInput && !e.ctrlKey && !e.metaKey && !e.altKey && typeof e.key === "string" && e.key.length === 1) {
|
if (onTextInput && !e.ctrlKey && !e.metaKey && !e.altKey && typeof e.key === "string" && e.key.length === 1) {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
@@ -77,34 +112,35 @@ export function createKeyboardCapture({ container, sendKeyDown, sendKeyUp, onTex
|
|||||||
|
|
||||||
function handleBlur() { releaseAll(); }
|
function handleBlur() { releaseAll(); }
|
||||||
function handleVisibility() { if (document.visibilityState === "hidden") releaseAll(); }
|
function handleVisibility() { if (document.visibilityState === "hidden") releaseAll(); }
|
||||||
function handleContextMenu(e) { if (enabled && !isEditableTarget(container)) e.preventDefault(); }
|
function handleContextMenu(e) { if (shouldCapture()) e.preventDefault(); }
|
||||||
function handleFullscreenChange() {
|
function handleFocusChange() { setTimeout(refreshCaptureState, 0); }
|
||||||
if (enabled) tryLock();
|
function handleFullscreenChange() { refreshCaptureState(); }
|
||||||
}
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
isEnabled() { return enabled; },
|
isEnabled() { return enabled; },
|
||||||
enable() {
|
enable() {
|
||||||
if (enabled) return;
|
if (enabled) return;
|
||||||
enabled = true;
|
enabled = true;
|
||||||
window[CAPTURE_FLAG] = true;
|
refreshCaptureState();
|
||||||
window.addEventListener("keydown", handleDown, { capture: true });
|
window.addEventListener("keydown", handleDown, { capture: true });
|
||||||
window.addEventListener("keyup", handleUp, { capture: true });
|
window.addEventListener("keyup", handleUp, { capture: true });
|
||||||
window.addEventListener("blur", handleBlur);
|
window.addEventListener("blur", handleBlur);
|
||||||
window.addEventListener("contextmenu", handleContextMenu, { capture: true });
|
window.addEventListener("contextmenu", handleContextMenu, { capture: true });
|
||||||
|
document.addEventListener("focusin", handleFocusChange);
|
||||||
|
document.addEventListener("focusout", handleFocusChange);
|
||||||
document.addEventListener("visibilitychange", handleVisibility);
|
document.addEventListener("visibilitychange", handleVisibility);
|
||||||
document.addEventListener("fullscreenchange", handleFullscreenChange);
|
document.addEventListener("fullscreenchange", handleFullscreenChange);
|
||||||
tryLock();
|
|
||||||
if (container) try { container.focus({ preventScroll: true }); } catch {}
|
|
||||||
},
|
},
|
||||||
disable() {
|
disable() {
|
||||||
if (!enabled) return;
|
if (!enabled) return;
|
||||||
enabled = false;
|
enabled = false;
|
||||||
delete window[CAPTURE_FLAG];
|
setCaptureFlag(false);
|
||||||
window.removeEventListener("keydown", handleDown, { capture: true });
|
window.removeEventListener("keydown", handleDown, { capture: true });
|
||||||
window.removeEventListener("keyup", handleUp, { capture: true });
|
window.removeEventListener("keyup", handleUp, { capture: true });
|
||||||
window.removeEventListener("blur", handleBlur);
|
window.removeEventListener("blur", handleBlur);
|
||||||
window.removeEventListener("contextmenu", handleContextMenu, { capture: true });
|
window.removeEventListener("contextmenu", handleContextMenu, { capture: true });
|
||||||
|
document.removeEventListener("focusin", handleFocusChange);
|
||||||
|
document.removeEventListener("focusout", handleFocusChange);
|
||||||
document.removeEventListener("visibilitychange", handleVisibility);
|
document.removeEventListener("visibilitychange", handleVisibility);
|
||||||
document.removeEventListener("fullscreenchange", handleFullscreenChange);
|
document.removeEventListener("fullscreenchange", handleFullscreenChange);
|
||||||
tryUnlock();
|
tryUnlock();
|
||||||
|
|||||||
@@ -124,6 +124,7 @@ import { createSharedUiSettingsSaver, loadSharedUiSettings } from "./shared-ui-s
|
|||||||
let lastRemoteCursor = null;
|
let lastRemoteCursor = null;
|
||||||
let remoteCursorShape = null;
|
let remoteCursorShape = null;
|
||||||
let remoteCursorImageUrl = "";
|
let remoteCursorImageUrl = "";
|
||||||
|
const CANVAS_TRANSPORT_PREF_VERSION = 1;
|
||||||
function getWebrtcMode() {
|
function getWebrtcMode() {
|
||||||
return webrtcMode ? String(webrtcMode.value || "off") : "off";
|
return webrtcMode ? String(webrtcMode.value || "off") : "off";
|
||||||
}
|
}
|
||||||
@@ -483,7 +484,7 @@ import { createSharedUiSettingsSaver, loadSharedUiSettings } from "./shared-ui-s
|
|||||||
: savedStreamProfile);
|
: savedStreamProfile);
|
||||||
setSelectValue(streamProfileSelect, savedStreamProfile);
|
setSelectValue(streamProfileSelect, savedStreamProfile);
|
||||||
setSelectValue(bitrateSelect, settings.bitrateMbps);
|
setSelectValue(bitrateSelect, settings.bitrateMbps);
|
||||||
setSelectValue(webrtcMode, settings.webrtcMode);
|
setSelectValue(webrtcMode, settings.transportPreferenceVersion === CANVAS_TRANSPORT_PREF_VERSION ? settings.webrtcMode : "off");
|
||||||
setSelectValue(audioTransport, settings.audioTransport);
|
setSelectValue(audioTransport, settings.audioTransport);
|
||||||
setSelectValue(recordMode, settings.recordMode);
|
setSelectValue(recordMode, settings.recordMode);
|
||||||
setSelectValue(recordFps, settings.recordFps);
|
setSelectValue(recordFps, settings.recordFps);
|
||||||
@@ -519,6 +520,7 @@ import { createSharedUiSettingsSaver, loadSharedUiSettings } from "./shared-ui-s
|
|||||||
bitrateMbps: Number(bitrateSelect?.value || 0),
|
bitrateMbps: Number(bitrateSelect?.value || 0),
|
||||||
preferH264: !!prefersH264,
|
preferH264: !!prefersH264,
|
||||||
webrtcMode: getWebrtcMode(),
|
webrtcMode: getWebrtcMode(),
|
||||||
|
transportPreferenceVersion: CANVAS_TRANSPORT_PREF_VERSION,
|
||||||
mouse: !!mouseCtrl?.checked,
|
mouse: !!mouseCtrl?.checked,
|
||||||
keyboard: !!kbdCtrl?.checked,
|
keyboard: !!kbdCtrl?.checked,
|
||||||
cursor: !!cursorCtrl?.checked,
|
cursor: !!cursorCtrl?.checked,
|
||||||
|
|||||||
Reference in New Issue
Block a user