Repository navigation
[BUG] - DirectX capture always falls back to BitBlt on non-English Windows #171
Description
Activity
Since GitHub doesn't accept
.jsonattachments, here is the file inline.ControlR.DesktopClient.Common/Resources/Strings/cs-CZ.jsonComplete Czech translation — 93 keys, matching
en-US.jsonexactly (no missing
or extra keys). It contains no branding of ours; it's a plain translation.Embedding it needs one more line in
ControlR.DesktopClient.Common.csproj,
next to the existing one:<EmbeddedResource Include="Resources\Strings\cs-CZ.json" />
Nothing else is required.
Localization.GetLocalizationStrings()picks the
embedded resource whose name ends with{CurrentCulture}.jsonand falls back to
en-US, so there is no culture list to maintain.Please feel free to include this in the project under its MIT license — no
attribution needed. It's been in production use on Czech Windows installs.cs-CZ.json
{ "YesText": "Ano", "NoText": "Ne", "CancelText": "Zrušit", "OkText": "OK", "SubmitText": "Odeslat", "ManagedDeviceMessage": "Toto zařízení spravuje vaše organizace.", "ManagedDeviceTitle": "Spravované zařízení", "MacPermissionStaleHint": "Pokud přepnutí oprávnění nezabere, odeberte aplikaci tlačítkem „−“ v Nastavení systému a přidejte ji znovu.", "Accessibility": "Zpřístupnění", "Status": "Stav:", "GrantPermission": "Udělit oprávnění", "Granted": "Uděleno", "NotGranted": "Neuděleno", "AccessibilityPermissionDescription": "Potřebné pro vzdálené ovládání zařízení.", "ScreenRecording": "Nahrávání obrazovky", "ScreenCapturePermissionDescription": "Potřebné pro zobrazení obrazovky zařízení.", "ScreenCastPermission": "Snímání obrazovky (ScreenCast)", "ScreenCastPermissionDescription": "Potřebné pro snímání a sdílení obrazovky přes XDG Desktop Portal.", "RemoteControlPermission": "Vzdálené ovládání", "RemoteControlPermissionDescription": "Potřebné pro snímání obrazovky a simulaci vstupu přes XDG Desktop Portal.", "Notifications": "Oznámení", "NotificationPermissionDescription": "Potřebné pro zobrazování oznámení a upozornění.", "OpenSettings": "Otevřít nastavení", "LearnMore": "Zjistit více", "RemoteControlSessionEndToastMessage": "{0} se odpojil. Sdílení obrazovky skončilo.", "RemoteControlSessionToastTitle": "Relace vzdáleného ovládání", "RemoteControlSessionStartToastMessage": "{0} se připojil a nyní sdílí vaši obrazovku.", "NewChatMessageToastTitle": "Nová zpráva v chatu", "NewChatMessageToastMessage": "Máte novou zprávu od {0}.", "ChatWindowTitle": "Chat s {0}", "ChatWindowDefaultTitle": "Chat ControlR", "ChatWindowClosedSystemMessage": "Systémová zpráva: Uživatel zavřel okno chatu.", "SendMessageText": "Odeslat", "EnterMessagePlaceholder": "Napište zprávu…", "NoMessagesText": "Zatím žádné zprávy. Konverzaci zahájíte odesláním zprávy.", "CloseText": "Zavřít", "SendText": "Odeslat", "ChatSessionClosedToastTitle": "Chat ukončen", "ChatSessionClosedToastMessage": "Vzdálený uživatel ukončil chat.", "ChatMessageSendFailureTitle": "Odeslání selhalo", "ChatMessageSendFailureMessage": "Zprávu se nepodařilo odeslat", "You": "Vy", "Version": "Verze", "InstanceId": "ID instance", "Theme": "Motiv", "Auto": "Automaticky", "Light": "Světlý", "Dark": "Tmavý", "ADeviceAdministrator": "správce zařízení", "RemoteControlRequestTitle": "Žádost o vzdálené ovládání", "RemoteControlRequestMessage": "Povolit relaci vzdáleného ovládání od {0}?", "PermissionsMissingToastTitle": "Vyžadována oprávnění", "PermissionsMissingToastMessage": "Chybí potřebná oprávnění. Kliknutím je udělíte.", "MacAccessibilityPermissionRestartRequired": "Než půjde požádat o oprávnění Zpřístupnění, je nutné restartovat aplikaci.", "MacScreenCapturePermissionRestartRequired": "Než půjde požádat o oprávnění Nahrávání obrazovky, je nutné restartovat aplikaci.", "NoPermissionsRequired": "V tomto operačním systému nejsou potřeba žádná oprávnění.", "ActiveConnections": "Aktivní připojení", "AgentStatus": "Stav agenta", "AgentConnectedTooltip": "Připojeno ke službě na pozadí", "AgentDisconnectedTooltip": "Odpojeno od služby na pozadí", "Connected": "Připojeno", "Disconnected": "Odpojeno", "Connections": "Připojení", "Settings": "Nastavení", "Permissions": "Oprávnění", "Disconnect": "Odpojit", "ConfirmDisconnect": "Opravdu chcete tuto relaci vzdáleného ovládání odpojit?", "ConfirmDisconnectTitle": "Potvrzení odpojení", "NoActiveConnections": "Žádná aktivní připojení", "About": "O aplikaci", "AboutLicenseLabel": "Licence", "AboutProjectLabel": "Projekt", "AboutWebsiteLabel": "Web", "AboutSponsorLabel": "Podpora projektu", "AboutSponsorButton": "❤️ Podpořit projekt", "AboutSponsorDescription": "ControlR je zdarma, s otevřeným kódem, provozovatelný na vlastním serveru a žije z darů.", "AboutThirdPartyLicensesLabel": "Licence třetích stran", "AboutThirdPartyLicensesDescription": "ControlR používá následující otevřený software a knihovny.", "AboutLibraryAvaloniaUi": "Avalonia UI", "AboutLibrarySerilog": "Serilog", "AboutLibraryTmdsDbus": "Tmds.DBus", "AboutLibraryMicrosoftLibraries": "Knihovny Microsoftu", "AboutSourceText": "zdroj", "LinkLicenseText": "licence", "ConnectedAtLabel": "Připojeno v", "TrayShow": "Zobrazit", "TrayExit": "Ukončit", "InvalidViewModelTypeMessage": "Neplatný typ modelu zobrazení", "ViewNotFoundMessage": "Zobrazení nenalezeno: {0}", "CouldNotCreateViewMessage": "Nepodařilo se vytvořit zobrazení: {0}", "UnhandledExceptionMessage": "Došlo k neošetřené výjimce. Podrobnosti najdete v protokolu.", "UnhandledExceptionTitle": "Neošetřená výjimka", "None": "Žádné" }- changed the title
[-]DirectX capture always falls back to BitBlt on non-English Windows[/-][+][BUG] - DirectX capture always falls back to BitBlt on non-English Windows[/+]on Sep 10, 2026 @Opicka879 Nice catch! :)
Thank you for the detailed report and for the translations. I'll include these in the next release.
Reacted by Opicka879The DirectX capture fix shipped in v0.28.15.0.
I'll add the translations in the next release.
Summary
ScreenGrabberWindowsdetectsDXGI_ERROR_WAIT_TIMEOUTby matching the Englishexception message. On a localized Windows install the message is translated, the
whenfilter never matches, and the exception falls through to the next handler —which calls
SetCurrentOutputFaulted()and falls back to GDI BitBlt.The result: on any non-English Windows, DirectX capture is effectively never used,
and the "DirectX" toggle in the viewer has no observable effect.
Environment
Root cause
ControlR.DesktopClient.Windows/Services/ScreenGrabberWindows.cs:AcquireNextFrameis called with a 0 ms timeout, soDXGI_ERROR_WAIT_TIMEOUT(
0x887A0027) is returned whenever a new frame isn't already queued. That is thecommon case and not an error condition.
On Czech Windows the message reads:
which does not start with
"The timeout value has elapsed", so the filter fails.Agent log
SetCurrentOutputFaulted()marks the output faulted for 10 seconds and disposes it,so the duplication object is torn down and recreated in a loop for the whole session.
Impact
Measured on the same machine, same activity, before and after the fix:
Because BitBlt provides no dirty rectangles,
GetDirtyRegionsalso falls back to afull software pixel comparison of every frame, and the cursor-only fast path in
HandleCursorOnlyUpdateis never taken.Suggested fix
Match on the HRESULT, which is locale-independent:
We've been running this patch on Czech Windows and it resolves the issue.
Note
Three other message-text comparisons exist in the codebase, but none of them read an
OS-generated message, so they should not be affected:
ControlR.DesktopClient/Program.cs—"RenderTimer"(Avalonia)ControlR.Agent.Common/Services/AgentHubClient.cs—"canceled by client"(SignalR)ControlR.Web.Server/Hubs/AgentHub.cs—"does not exist"(server runs in a Linux container)