Você Não Pode Esconder uma Janela do Zoom no macOS 15
No macOS moderno, não é possível esconder com confiabilidade uma janela de captura de tela — nem de outra aplicação, nem mesmo da própria. Esta é a história técnica do remoção da função CGSSetWindowCaptureExcluded, do silencioso ignorar da função SLSSetWindowSharingState entre processos, e da razão pela qual NSWindow.sharingType = .none é uma sugestão fraca para o Zoom e o QuickTime, e não uma garantia rígida.
Um breve relato técnico sobre a construção de um aplicativo de "janela privada" que não funciona completamente.
A ideia
Como muitas pessoas, eu trabalho com uma janela do Claude aberta durante reuniões. E, como muitas pessoas, às vezes compartilho minha tela no Zoom e gostaria que aquela janela não fosse visível para todos os participantes da chamada. Não por motivos sensíveis — apenas porque está em um estado de trabalho privado.
Sabe que aplicativos como o 1Password e o Hand Mirror conseguem ocultar suas próprias janelas de gravação. Eu pensei que poderia construir uma pequena utilidade do menu-bar que me permitisse escolher qualquer aplicativo — Claude, Notas, qualquer outro — e alternar a visibilidade de suas janelas durante a gravação, mantendo-as totalmente visíveis e interativas na minha própria tela.
Projeto de fim de semana. No máximo duas horas.
Ficou mais longo. E a conclusão é: no macOS moderno, você não pode fazer isso. Não para outro aplicativo, e — como acabou se mostrando — nem de forma confiável para o próprio.
Esta é a história técnica por trás disso.
Tentativa 1: ocultar a janela de outro aplicativo
A maneira clássica de tornar uma janela do macOS invisível para gravação é NSWindow.sharingType = .none. Mas essa é uma flag por janela que só o processo proprietário pode definir nas próprias janelas. O AppKit não permite que você acesse a lista de janelas de outro aplicativo.
A solução bem conhecida, usada por anos por ferramentas como Hand Mirror e vários utilitários de bloqueio de tela, é a função privada SkyLight:
OSStatus CGSSetWindowCaptureExcluded(CGSConnectionID cid, CGWindowID wid, bool excluded);
Você percorre as janelas via CGWindowListCopyWindowInfo, filtra para o PID do aplicativo-alvo e chama essa função em cada ID da janela. Como a chamada passa pelo WindowServer (e não pelo processo proprietário), ela pode excluir qualquer janela da gravação.
Conectei isso via dlsym em /System/Library/PrivateFrameworks/SkyLight.framework/..., construí o aplicativo, o executei no macOS 15.3.1 e obtive:
[InvisibleApp] symbol not found: CGSSetWindowCaptureExcluded
[InvisibleApp] symbol not found: SLSSetWindowCaptureExcluded
A função é desaparecida. A Apple a removiu. Procurei por uma versão renomeada (SLSSetWindowExcludedFromCapture, CGSSetWindowSharingState, todas as variações óbvias). A maioria não existe, mas encontrei duas que existem:
SLSSetWindowSharingState(CGSConnectionID, CGWindowID, int sharingState)— a chamada interna queNSWindow.sharingType = .noneusa internamente. Compartilhando o estado0éNSWindowSharingNone.SLSGetWindowOwner— você recebe o ID de conexão do processo proprietário da janela.
Então, recriei o ponteiro para chamar SLSSetWindowSharingState na janela-alvo, tentando tanto minha conexão principal quanto a conexão do processo proprietário da janela.
Construí, executei, ativei, o log diz que retornou noErr, tirei uma captura de tela — o Claude ainda aparece na captura. Tentei o Zoom — o Claude ainda aparece na compartilhamento.
SLSSetWindowSharingState sucesso ao ser chamado entre processos, mas o WindowServer o ignora silenciosamente. Apenas o processo proprietário pode alterar o estado de compartilhamento da própria janela no macOS 15.
Também confirmei que a saída óbvia está fechada: DYLD_INSERT_LIBRARIES injeção no processo do Claude está bloqueada porque o Claude (como a maioria dos aplicativos modernos) possui runtime hardenado ativado e sem a disable-library-validation entidade.
Então isso está resolvido: nenhum aplicativo terceiro pode tornar a janela de outro aplicativo invisível para gravação no macOS 15. A conclusão alinha-se com o que a Apple diz que quer: o estado de gravação por janela é exclusividade do aplicativo proprietário, sem exceção.
Tentativa 2: ocultar nossa própria janela
Plano B: mudar o produto. Em vez de uma ferramenta que oculta o Claude, criei uma pequena janela de chat do meu próprio aplicativo — mesma função, forma diferente. Minha janela, meu sharingType = .none. Este é o mecanismo bem conhecido que todas as ferramentas de ocultação de captura usam, e é uma linha simples:
window.sharingType = .none
Conecte um fluxo de chat à API Anthropic Messages (ou ao CLI local para autenticação por assinatura), defina claude na janela de chat e publique. Esta é uma API clara, suportada e pública. sharingType = .none Construí. Registrei o valor real do tipo de compartilhamento em tempo de execução para garantir que o macOS o aceitasse:
Tirei uma captura de tela — a janela de chat estava corretamente ausente. ✅
[InvisibleApp] window 151526 sharingType=0
Gravei a tela com o QuickTime — a janela de chat apareceu na gravação. ❌
Compartilhei a tela no Zoom — a janela de chat era visível para o outro lado. ❌
Isso foi inesperado. O objetivo inteiro de
é tirar isso dessas fluxos. Então, construí um teste interno no aplicativo que realiza uma captura de tela usando ScreenCaptureKit (a API de captura moderna e pública), o mesmo framework que o QuickTime usa por trás. Tentei tanto a captura única ( apontar ) quanto a captura contínua ( NSWindowSharingNone ) — ambas produziram uma imagem PNG com a janela de chat corretamente excluída.SCScreenshotManager.captureImageEntão:SCStreamMétodo de captura
Oculta nossa janela?
| Cmd-Shift-3/4/5 (captura de tela do sistema) | Captura única do SCK do nosso aplicativo |
|---|---|
| Captura contínua do SCK do nosso aplicativo | ✅ |
| QuickTime “Nova Gravação de Tela” | ✅ |
| ❌ | ✅ |
| Zoom “Compartilhar Tela → Desktop” | Mesmo sistema, mesma máquina, mesma janela, mesmo |
| . A única coisa que varia é quem está fazendo a captura. | Mesmo sistema, mesma máquina, mesma janela, mesmo |
Caminhos privilegiados de captura sharingType = .noneEsta é a parte que a maioria dos engenheiros não percebe:
no macOS 15, a captura de tela não é uma única API; é pelo menos duas — uma pública e uma privada com entidades adicionais.
Extrai as entidades do QuickTime Player: Essas
chaves só podem ser concedidas pela Apple a binários de primeira parte. Você e eu não podemos solicitá-las. A notificação seria rejeitada. O App Store certamente o faria.
codesign -d --entitlements - /System/Applications/QuickTime\ Player.app
com.apple.private.screencapturekit.noprompt = true
com.apple.private.tcc.allow = [
kTCCServiceMicrophone,
kTCCServiceCamera,
kTCCServiceScreenCapture,
]
E o que elas concedem, além de pular a solicitação de permissão de captura, é a capacidade de capturar uma imagem da tela com.apple.private.* antes que o WindowServer aplique a filtragem de tipo de compartilhamento
. A janela está no framebuffer que sai — as ferramentas da Apple apenas veem tudo. O Zoom usa um caminho semelhante privilegiado. Pode ser uma extensão do kernel, uma extensão do sistema ou uma API privada obtida por ser um aplicativo de conferência bem conhecido — ainda não investiguei suficientemente para dizer qual. Mas o comportamento é o mesmo: o mecanismo padrão de exclusão não se aplica a ele.O que isso significa
Se você é um desenvolvedor terceiro e seu objetivo é “essa janela nunca deve aparecer em uma gravação de tela em qualquer Mac”,
você não pode garantir isso no macOS 15.
Sua janela é oculta de todos os caminhos de captura que você pode escrever. É oculta de Google Meet (navegador → → SCK), Microsoft Teams (SCK), OBS (SCK), todas as ferramentas terceiras conformes. Mas as ferramentas próprias da Apple e os parceiros autorizados da Apple ainda podem vê-la. A funcionalidade de “proteção de gravação” do 1Password / Hand Mirror tem a mesma limitação. As pessoas simplesmente não gravação seu cofre do 1Password com o QuickTime, então a falha passa despercebida. getDisplayMedia A resumo honesto que eu daria à Apple sobre isso:
publique uma entidade pública equivalente a
, ou comprometa que é uma garantia rígida contra com.apple.private.screencapturekit.noprompttodas NSWindow.sharingType = .none caminhos de captura. No macOS 15.3.1, não é nem isso — é uma garantia rígida contra a maioria dos caminhos e uma sugestão fraca de que ferramentas privilegiadas podem contornar. O status quo cria uma postura de segurança onde os usuários acreditam que uma janela está invisível durante a captura, quando na verdade não está, o que é pior do que nenhuma proteção. As soluções alternativas, ordenadas pela quantidade de dano que causam Para meu caso de uso — manter uma janela de chat invisível durante uma compartilhamento no Zoom — todas funcionam e nenhuma é excelente:
Compartilhe uma única janela no Zoom, não a tela inteira.
O diálogo de compartilhamento de tela tem uma aba “Janela”. O Zoom captura apenas os pixels da janela e nada mais, então meu chat — e tudo o que está na tela — está automaticamente ausente. Esta é a solução mais confiável e exige zero código. Desvantagem: os espectadores não veem o contexto da tela inteira.
- Use Meet ou Teams em vez do Zoom. Ambos respeitam
- . Isso é ótimo se você controla a ferramenta de reunião, terrível se você não controla. Coloque o chat em um espaço separado.
sharingType = .noneO Mission Control oferece múltiplos desktops. Compartilhe o Espaço 1, mantenha o chat no Espaço 2. Deslize para interagir. Lento, rompe o fluxo, mas funciona. - Use um segundo dispositivo. Um celular ou iPad ao lado do seu laptop é invulnerável a qualquer ferramenta de captura, por definição.
- Escolhi a opção 1 mais o aplicativo de chat que já construí. O chat está invisível para ~95% de caminhos de captura, e no caso do compartilhamento de tela no Zoom, simplesmente não uso o compartilhamento de tela no desktop. O que eu gostaria de ver em seguida
Uma entidade pública
que permita um aplicativo notificado declarar “essa janela do meu aplicativo está excluída de
- captura, inclusive por chamadores privilegiados”. Hoje, isso não é possível. Honestidade nas No macOS 15.3.1, não é nem isso — é uma garantia rígida contra documentações.
- As documentações fazem parecer uma garantia rígida. Na verdade, não é — pelo menos as documentações devem mencionar que ferramentas privilegiadas da Apple e aplicativos com entidades privadas podem capturar independentemente. Hoje, elas não fazem.
NSWindow.sharingTypeUma forma de inspecionar quais aplicativos em um sistema têm acesso privilegiado a captura — análoga ao “Arquivos e Pastas” na Privacidade e Segurança. Hoje não há interface para os usuários verem quem pode contornar sua privacidade. - Até que qualquer uma dessas soluções seja implementada, a recomendação prática é: assuma que qualquer janela na sua tela é capturável pelo sistema e por aplicativos de conferência principais, independentemente do que você define. Os mecanismos de exclusão são reais — funcionam contra a maioria do mundo — mas não são uma fronteira de segurança que você pode confiar contra as partes do mundo que importam mais.
Você Não Pode Ocultar uma Janela do Zoom no macOS 15 2 sharingType Você Não Pode Ocultar uma Janela do Zoom no macOS 16 1
Instale nossas extensões
Adicione ferramentas de IO ao seu navegador favorito para acesso instantâneo e pesquisa mais rápida
恵 O placar chegou!
Placar é uma forma divertida de acompanhar seus jogos, todos os dados são armazenados em seu navegador. Mais recursos serão lançados em breve!
Ferramentas essenciais
Ver tudo Novas chegadas
Ver tudoAtualizar: Nosso ferramenta mais recente foi adicionado em 26 abr, 2026
