# Jak aplikace chrání okna před snímky obrazovky: Windows, macOS a Linux v detailech
Při pokusu o snímek obrazovky Netflixu nebo Spotify místo videa uvidíte černý obdélník – to není chyba, ale záměrná ochrana prostřednictvím systémových API. Vývojáři používají příznaky jako SetWindowDisplayAffinity na Windows nebo sharingType na macOS, aby vyloučili okno z proudů zachycení obrazovky. Ale v macOS 15 Sequoia Apple narušila kompatibilitu a na Linuxu to závisí na display serveru. Prozkoumáme, jak ochrana funguje na každé platformě, kde selhává a jaké jsou obchody.
Mechanismy zachycení obrazovky ve Windows: tři hlavní API
Když aplikace jako Zoom požádá o přístup k demonstraci obrazovky, přihlásí se k proudu snímků od operačního systému. Ve Windows existují tři hlavní způsoby, jak získat tento proud, každý se svými vlastnostmi:
- GDI BitBlt od desktopového DC – nejstarší metoda, fungující od Windows 2000. Používá volání
BitBltzGetDC(NULL), které kopíruje pixely z povrchu DWM (Desktop Window Manager) do libovolného HDC. Pomalá, bez hardwarového zrychlení, ale univerzální. Používá se ve starších aplikacích a monitorovacích nástrojích. - Desktop Duplication API (DXGI) – objevila se ve Windows 8. Prostřednictvím
IDXGIOutputDuplication::AcquireNextFramevrací GPU texturu s již složeným snímkem pracovní plochy. Rychlá, hardwarově zrychlená, ale zachycuje pouze celý monitor. Používala se v klasických verzích Zoom, TeamViewer, AnyDesk a Teams. - Windows.Graphics.Capture (WGC) – moderní standard, představený ve Windows 10 1803. Podporuje zachycení celého monitoru i konkrétního okna podle HWND. Používá se v aktuálních verzích OBS, Microsoft Teams, Chromium, Zoom a systémovém Snipping Tool.
Všechny tři metody nakonec čtou data z DWM – jediného místa, kde se tvoří finální obraz obrazovky. Právě zde se aplikují mechanismy ochrany.
SetWindowDisplayAffinity: režimy a jejich chování
DWM umožňuje každému oknu nastavit atribut display affinity prostřednictvím funkce SetWindowDisplayAffinity. Tento atribut určuje, zda se okno dostane do proudů zachycení. K dispozici jsou tři hodnoty:
WDA_NONE(0x00) – okno je viditelné ve všech zachyceních (výchozí).WDA_MONITOR(0x01) – okno se zobrazuje na monitoru, ale v zachycení je nahrazeno černým obdélníkem. Funguje od Windows Vista. Právě ho používá Netflix k ochraně obsahu.WDA_EXCLUDEFROMCAPTURE(0x11) – okno je zcela vyloučeno z proudu zachycení, jako by neexistovalo. Objevil se ve Windows 10 May 2020 Update (build 19041). Přes něj je vidět obsah podkladových oken – elegantnější řešení.
Příklad v C++:
#include <windows.h>
#include <cstdio>
int main() {
HWND hwnd = GetConsoleWindow();
if (!SetWindowDisplayAffinity(hwnd, WDA_EXCLUDEFROMCAPTURE)) {
printf("SetWindowDisplayAffinity failed: %lu\n", GetLastError());
return 1;
}
printf("Okno nyní není viditelné pro zachycení. Zkus udělat snímek obrazovky.\n");
Sleep(60000);
return 0;
}
Podobně funguje v C# přes P/Invoke, v Electron přes setContentProtection(true), v Tauri přes with_content_protection(true).
Pod kapotou DWM odděluje kompoziciční potrubí: okno s WDA_EXCLUDEFROMCAPTURE se dostane pouze do potrubí pro fyzický monitor, ale ne do potrubí pro capture klienty. Obtížné to obejít na úrovni čtení pixelů.
Kompatibilita a omezení ve Windows
Test na Windows 11 23H2 ukázal, že WDA_EXCLUDEFROMCAPTURE správně funguje proti všem hlavním metodám zachycení:
- GDI BitBlt – okno chybí.
- Desktop Duplication (DXGI) – okno chybí (ve Windows 11 24H2 je zvláštnost s probuzením
AcquireNextFramepři aktualizaci skrytého okna, ale obsah se nepřenáší). - Windows.Graphics.Capture (WGC) – okno chybí.
Jediné výjimky je PrintWindow. Tato metoda obchází DWM a žádá okno, aby se vykreslilo přímo do uvedeného DC, ignoruje příznak. Nicméně většina aplikací pro demonstraci obrazovky (Zoom, Teams, Discord, OBS) PrintWindow nepoužívá.
Důležité omezení: WDA_EXCLUDEFROMCAPTURE je podporováno pouze od Windows 10 20H1 (May 2020 Update). Na starších verzích, včetně LTSC, funkce vrátí chybu ERROR_INVALID_PARAMETER. V takových případech lze použít WDA_MONITOR, ale pak bude v zachycení černý obdélník.
Existuje také nedokumentovaný atribut WCA_EXCLUDED_FROM_DDA přes SetWindowCompositionAttribute, který vylučuje okno pouze z Desktop Duplication API. V praxi není potřebný, protože WDA_EXCLUDEFROMCAPTURE řeší úkol úplněji.
macOS do 15: sharingType jako spolehlivý mechanismus
Na macOS do verze 15 se používalo vlastnost sharingType u NSWindow:
window.sharingType = .none
Dostupné hodnoty:
.readWrite– okno je dostupné pro čtení a změnu z jiných procesů (málokdy používané)..readOnly– okno je zachytitelné (výchozí)..none– okno je vyloučeno z zachycení.
Tento příznak fungoval přes WindowServer, který řídí kompozici přes Core Graphics. Do macOS 14 Sonoma včetně sharingType = .none efektivně blokoval zachycení jak přes legacy-API (CGWindowListCreateImage), tak přes nový ScreenCaptureKit (zavedený v macOS 12.3).
Electron a Tauri tento mechanismus používaly pod kapotou svých metod setContentProtection(true).
macOS 15 Sequoia: regrese v ScreenCaptureKit
S vydáním macOS 15 Sequoia Apple změnila architekturu WindowServer: nyní kompozice sbírá všechna viditelná okna do jediného framebufferu a ScreenCaptureKit zachycuje právě ten. Výsledkem je, že sharingType = .none přestal ovlivňovat proud SCStream.
Oficiální zástupce Apple potvrdil na Developer Forums: „At this time there are no public APIs for preventing screen capture“.
Důležitý detail: legacy-API (CGWindowListCreateImage) stále respektuje sharingType = .none. To vytváří rozpor v chování různých aplikací:
- Zoom (aktuální), Teams, QuickTime, systémové snímky (Cmd+Shift+3/4/5), nové verze OBS – používají ScreenCaptureKit → okno je viditelné.
- Google Chrome (
getDisplayMedia), Google Meet v Chrome, staré verze OBS – používají CoreGraphics → okno je skryté.
Jedná se o zásadní regresi pro produkty vyžadující ochranu před zachycením obrazovky. Bez soukromých API není řešení a jejich použití zaručuje odmítnutí v App Store review a riziko poruchy při aktualizacích OS. Alternativy – omezení podpory na macOS 14 a dříve, nebo behaviorální metody: automatické minimalizování okna při zahájení demonstrace, detekce aktivity SCStream přes systémové signály.
Linux: X11 vs Wayland – dva světy
Na Linuxu se situace zásadně liší v závislosti na display serveru.
X11 – architektonicky nepodporuje ochranu oken před zachycením. Jakýkoli klient s přístupem k displeji může volat XGetImage nebo XCompositeNameWindowPixmap a získat pixely jakéhokoli okna. Kompozitní rozšíření (Picom, KWin, Mutter) mohou přidávat částečnou ochranu, ale krosplatformové řešení pro WM neexistuje.
Wayland – postavený na principu izolace: klient nemůže číst cizí surface. Zachycení obrazovky je možné pouze přes xdg-desktop-portal + PipeWire a pouze s explicitním souhlasem uživatele. Ochrana oken se realizuje na úrovni protokolu – pokud okno nepřidělí přístup, nedostane se do zachycení. To činí Wayland výrazně bezpečnější než X11, ale vyžaduje od aplikací správnou implementaci protokolů.
Co je důležité
SetWindowDisplayAffinitysWDA_EXCLUDEFROMCAPTURE– de facto standard na Windows pro úplné vyloučení okna z zachycení. Funguje od Windows 10 May 2020 Update.- Na macOS 15 Sequoia
sharingType = .noneuž nefunguje proti ScreenCaptureKit – to je architektonická změna Apple bez veřejného obchodu. - Na Linuxu na X11 ochrana oken není možná podle designu protokolu; na Wayland je zajištěna na úrovni protokolu.
PrintWindowna Windows obchází ochranu, ale nepoužívá se v populárních aplikacích pro demonstraci obrazovky.- Electron a Tauri tyto API používají pod kapotou – jejich chování závisí na platformě a verzi OS.
— Editorial Team
Zatím žádné komentáře.