diff --git a/app/ui.js b/app/ui.js index 1ba0b19f1..aae107c67 100644 --- a/app/ui.js +++ b/app/ui.js @@ -327,6 +327,7 @@ const UI = { UI.initSetting('virtual_keyboard_visible', false); UI.initSetting('enable_ime', false); UI.initSetting('enable_webrtc', false); + UI.initSetting('webrtc_congestion_control', false); UI.initSetting('enable_hidpi', false); UI.initSetting('fallback_image_mode', false); @@ -695,6 +696,8 @@ const UI = { UI.addSettingChangeHandler('enable_ime', UI.toggleIMEMode); UI.addSettingChangeHandler('enable_webrtc'); UI.addSettingChangeHandler('enable_webrtc', UI.toggleWebRTC); + UI.addSettingChangeHandler('webrtc_congestion_control'); + UI.addSettingChangeHandler('webrtc_congestion_control', UI.updateWebRTCCongestionControl); UI.addSettingChangeHandler('enable_hidpi'); UI.addSettingChangeHandler('enable_hidpi', UI.enableHiDpi); UI.addSettingChangeHandler('enable_threading'); @@ -1905,6 +1908,10 @@ const UI = { UI.rfb.keyboard.enableIME = UI.getSetting('enable_ime'); UI.rfb.clipboardBinary = supportsBinaryClipboard() && UI.rfb.clipboardSeamless; UI.rfb.enableWebRTC = UI.getSetting('enable_webrtc'); + // WebRTC congestion control is still in development and hidden from the + // UI; force it off so a stale localStorage value can never activate it. + UI.rfb.webRTCCongestionControl = false; + UI.updateWebRTCCongestionControlAvailability(); UI.rfb.mouseButtonMapper = UI.initMouseButtonMapper(); // UI.rfb.qualityPreset = UI.getSetting(UI_SETTINGS.PRESET); if (UI.rfb.videoQuality === 5) { @@ -3144,10 +3151,32 @@ const UI = { } else { UI.rfb.enableWebRTC = false; } + UI.updateWebRTCCongestionControlAvailability(); UI.updateQuality(); } }, + // The congestion-control toggle only does anything while WebRTC media is + // active, so grey it out (disable the checkbox) whenever WebRTC is off. + // The stored preference is preserved across the disable so re-enabling + // WebRTC restores the user's choice. + updateWebRTCCongestionControlAvailability() { + // Feature still in development: keep the toggle permanently disabled + // (it is also hidden in index.html) so it cannot be activated. + const el = document.getElementById('noVNC_setting_webrtc_congestion_control'); + if (el) { + el.disabled = true; + el.checked = false; + } + }, + + updateWebRTCCongestionControl() { + // Force off while the feature is hidden; ignore any stored preference. + if (UI.rfb) { + UI.rfb.webRTCCongestionControl = false; + } + }, + enableHiDpi() { if (UI.rfb) { if (UI.getSetting('enable_hidpi')) { diff --git a/core/decoders/kasmvideo.js b/core/decoders/kasmvideo.js index b00a0d015..98458ded4 100644 --- a/core/decoders/kasmvideo.js +++ b/core/decoders/kasmvideo.js @@ -99,7 +99,33 @@ export default class KasmVideoDecoder { } _skipRect(x, y, width, height, _sock, display, _depth, frameId) { - display.clearRect(x, y, width, height, 0, frameId, false); + // Under WebRTC media the server emits skip-rects in place of + // encoded video (the payload rides the RTCPeerConnection). + // Clearing the canvas here would paint the visible area black + // during the ~1-2s ICE/SDP handshake before the first WebRTC + // frame arrives. Leave the canvas alone in that mode so the + // user sees the last image-mode frame until the