Tidak suka iklan? Pergi Bebas Iklan Hari ini

Anda Tidak Bisa Menyembunyikan Jendela dari Zoom di macOS 15

Diperbarui pada

Pada macOS modern, Anda tidak dapat secara andal menyembunyikan jendela dari penangkapan layar — baik dari aplikasi lain maupun dari aplikasi Anda sendiri. Ini adalah cerita teknis tentang penghapusan CGSSetWindowCaptureExcluded, pengabaian SLSSetWindowSharingState secara diam-diam antar proses, serta alasan mengapa NSWindow.sharingType = .none merupakan saran lemah bagi Zoom dan QuickTime, bukan jaminan keras.

Anda Tidak Bisa Menyembunyikan Jendela dari Zoom di macOS 15 1
IKLAN · HAPUS?

Sebuah refleksi singkat tentang pengembangan aplikasi 'window pribadi' yang tidak berjalan dengan sempurna.


Ide

Seperti banyak orang, saya bekerja dengan jendela desktop Claude terbuka selama pertemuan. Dan seperti banyak orang, saya kadang membagikan layar saya di Zoom, dan saya lebih suka jendela tersebut tidak terlihat oleh semua orang dalam pertemuan. Bukan karena ada sesuatu yang sensitif — hanya karena itu adalah keadaan kerja pribadi.

Saya tahu aplikasi seperti 1Password dan Hand Mirror dapat menyembunyikan jendela mereka dari penangkapan layar. Saya berpikir saya bisa membuat alat utilitas baris menu yang memungkinkan saya memilih apa pun aplikasi — Claude, Catatan, atau apa saja — dan mengubah keberadaan jendela tersebut tidak terlihat saat ditangkap, sambil tetap mempertahankan jendela tersebut penuh visibilitas dan interaktif di layar saya sendiri.

Proyek akhir pekan. Maksimal dua jam.

Ini memakan waktu lebih lama. Dan inti dari hal ini adalah: pada macOS modern, Anda tidak bisa melakukannya. Tidak untuk aplikasi lain, dan — ternyata — tidak dapat diandalkan bahkan untuk aplikasi Anda sendiri.

Ini adalah cerita teknis mengapa.


Upaya 1: menyembunyikan jendela aplikasi lain

Cara klasik untuk membuat jendela macOS tidak terlihat dalam penangkapan layar adalah NSWindow.sharingType = .none. Namun, ini adalah flag per-jendela yang hanya dapat diatur oleh proses pemilik pada jendela-jendela miliknya sendiri. AppKit tidak memungkinkan Anda mengakses daftar jendela aplikasi lain.

Solusi yang terkenal, yang digunakan selama bertahun-tahun oleh alat seperti Hand Mirror dan berbagai utilitas penutup layar, adalah fungsi SkyLight privat:

OSStatus CGSSetWindowCaptureExcluded(CGSConnectionID cid, CGWindowID wid, bool excluded);

Anda mengenumerasi jendela melalui CGWindowListCopyWindowInfo, menyaring ke PID aplikasi target, dan memanggil ini pada setiap ID jendela. Karena panggilan ini melalui WindowServer (bukan proses pemilik), maka jendela dapat dikecualikan dari penangkapan.

Saya menyambungkan ini melalui dlsym dalam /System/Library/PrivateFrameworks/SkyLight.framework/..., membangunnya, menjalankannya di macOS 15.3.1, dan mendapatkan:

[InvisibleApp] symbol not found: CGSSetWindowCaptureExcluded
[InvisibleApp] symbol not found: SLSSetWindowCaptureExcluded

Fungsi ini hilang. Apple menghapusnya. Saya mencari versi yang diubah (SLSSetWindowExcludedFromCapture, CGSSetWindowSharingState, semua variasi yang jelas). Sebagian besar tidak ada, tetapi saya menemukan dua yang ada:

  • SLSSetWindowSharingState(CGSConnectionID, CGWindowID, int sharingState) — panggilan bawah dasar yang NSWindow.sharingType = .none menggunakan secara internal. Berbagi status 0 adalah NSWindowSharingNone.
  • SLSGetWindowOwner — memberi Anda ID koneksi dari proses pemilik jendela.

Jadi saya membangun kembali jembatan untuk memanggil SLSSetWindowSharingState pada jendela target, mencoba koneksi utama saya dan koneksi pemilik jendela.

Membangun, menjalankan, mengaktifkan, log menyatakan bahwa itu mengembalikan noErr, mengambil screenshot — Claude masih muncul di screenshot. Mencoba Zoom — Claude masih muncul dalam bagian berbagi.

SLSSetWindowSharingState berhasil saat dipanggil lintas proses tetapi WindowServer mengabaikannya secara diam-diam. Hanya proses pemilik yang dapat mengubah status jendela miliknya sendiri pada macOS 15.

Saya juga memverifikasi bahwa jalan keluar yang jelas telah ditutup: DYLD_INSERT_LIBRARIES injeksi ke dalam proses Claude dilarang karena Claude (seperti kebanyakan aplikasi modern) memiliki runtime yang diperkuat dan tanpa disable-library-validation entitlement.

Jadi itu telah ditentukan: tidak ada aplikasi pihak ketiga yang dapat membuat jendela aplikasi lain tidak terlihat dalam penangkapan pada macOS 15. Kesimpulan ini sesuai dengan apa yang dikatakan Apple: status penangkapan per-jendela adalah hak eksklusif aplikasi pemilik, tanpa pengecualian.


Upaya 2: menyembunyikan jendela kita sendiri

Rencana B: mengubah produk. Alih-alih alat yang menyembunyikan Claude, buat jendela obrolan kecil milik saya sendiri — tugas yang sama, bentuk yang berbeda. Jendela milik saya, saya sendiri. sharingType = .noneIni adalah mekanisme yang sudah terkenal digunakan oleh setiap alat yang menyembunyikan penangkapan layar, dan itu hanya satu baris kode:

window.sharingType = .none

Hubungkan aliran obrolan ke API Anthropic Messages (atau ke CLI lokal claude untuk autentikasi berlangganan), atur sharingType = .none pada jendela obrolan, distribusikan. Ini adalah API yang jelas, didukung, dan publik.

Saya membangunnya. Saya mencatat nilai tipe penangkapan secara real-time untuk memastikan macOS menerima itu:

[InvisibleApp] window 151526 sharingType=0

Mengambil screenshot — jendela obrolan benar-benar tidak muncul. ✅

Mengambil layar dengan QuickTime — jendela obrolan muncul dalam rekaman. ❌

Membagikan layar di Zoom — jendela obrolan terlihat bagi pihak lain. ❌

Ini tidak terduga. Seluruh titik dari NSWindowSharingNone adalah untuk mengeluarkannya dari alur-alur ini. Jadi saya membangun uji internal dalam aplikasi yang melakukan penangkapan layar menggunakan ScreenCaptureKit (API penangkapan modern, publik), yang sama dengan yang digunakan QuickTime di bawah kulit. Saya mencoba penangkapan tunggal (SCScreenshotManager.captureImage) dan penangkapan berkelanjutan (SCStream) — keduanya menghasilkan PNG dengan jendela obrolan yang benar-benar dikecualikan.

Jadi:

Metode penangkapanMenyembunyikan jendela kita?
Cmd-Shift-3/4/5 (screenshot sistem)
Penangkapan tunggal oleh aplikasi kita menggunakan SCK
Penangkapan berkelanjutan oleh aplikasi kita menggunakan SCK
QuickTime “New Screen Recording”
Zoom “Share Screen → Desktop”

Sama OS, sama mesin, sama jendela, sama sharingType = .none. Satu-satunya hal yang berbeda adalah siapa yang melakukan penangkapan.


Jalur penangkapan berhak istimewa

Ini adalah bagian yang tidak disadari oleh sebagian besar insinyur: pada macOS 15, penangkapan layar bukan satu API; itu setidaknya dua — satu publik, dan satu privat dengan entitas tambahan.

Saya mengunggah entitas QuickTime Player:

codesign -d --entitlements - /System/Applications/QuickTime\ Player.app
com.apple.private.screencapturekit.noprompt    = true
com.apple.private.tcc.allow                     = [
    kTCCServiceMicrophone,
    kTCCServiceCamera,
    kTCCServiceScreenCapture,
]

Kunci-kunci ini hanya dapat diberikan oleh Apple kepada biner pertama pihak mereka sendiri. Anda dan saya tidak bisa meminta mereka. Notifikasi akan ditolak. App Store tentu saja akan menolaknya. com.apple.private.* Dan apa yang mereka berikan, selain menghindari prompt izin penangkapan, adalah kemampuan untuk menangkap gambar layar

sebelum WindowServer menerapkan penyaringan tipe penangkapan . Jendela tersebut ada di framebuffer yang dihasilkan — alat-alat Apple hanya melihat semua itu.Zoom menggunakan jalur yang serupa. Mungkin itu adalah ekstensi kernel, ekstensi sistem, atau API privat yang diperoleh karena menjadi aplikasi konferensi yang telah diberi kepercayaan panjang — saya belum menyelidiki cukup untuk menyatakan mana. Namun perilakunya sama: mekanisme penyaringan umum tidak berlaku bagi itu.

Artinya


Jika Anda adalah pengembang pihak ketiga dan tujuan Anda adalah "jendela ini tidak boleh muncul dalam rekaman layar di setiap Mac",

Anda tidak dapat memastikan hal ini pada macOS 15. Jendela Anda tersembunyi dari semua jalur penangkapan yang Anda buat sendiri. Tersembunyi dari Google Meet (browser → → SCK), Microsoft Teams (SCK), OBS (SCK), semua alat pihak ketiga yang sesuai. Namun, alat-alat Apple sendiri dan mitra konferensi yang diberi kepercayaan oleh Apple tetap dapat melihatnya. getDisplayMedia Fitur "proteksi penangkapan layar" 1Password / Hand Mirror memiliki batasan yang sama. Orang-orang hanya tidak biasa merekam 1Password mereka dengan QuickTime, sehingga kebocoran tidak terlihat.

Ringkasan yang jujur yang saya berikan kepada Apple adalah:

publikkan entitas publik yang setara dengan , atau komit bahwa com.apple.private.screencapturekit.nopromptadalah jaminan keras terhadap NSWindow.sharingType = .none semua jalur penangkapan. Pada macOS 15.3.1, ini tidak ada — itu adalah jaminan keras terhadap kebanyakan jalur dan saran lemah bahwa alat berhak istimewa dapat melaluinya. Kondisi saat ini menciptakan posisi keamanan di mana pengguna percaya bahwa jendela tidak terlihat saat penangkapan, padahal itu tidak benar, yang lebih buruk daripada tidak ada perlindungan sama sekali. Solusi pengganti, diurutkan berdasarkan seberapa besar dampaknya


Untuk kasus saya — menjaga jendela obrolan tersembunyi saat berbagi layar di Zoom — semua ini bekerja dan tidak sempurna:

Bagi hanya satu jendela di Zoom, bukan desktop.

  1. Dialog Bagi Layar memiliki tab “Window”. Zoom hanya menangkap piksel dari jendela tersebut dan tidak ada yang lain, sehingga obrolan saya — dan semua hal lain di layar — secara otomatis tidak muncul. Ini adalah solusi paling andal dan tidak membutuhkan kode. Kelemahannya: penonton tidak melihat konteks layar secara keseluruhan. Gunakan Meet atau Teams daripada Zoom.
  2. Keduanya menghormati . Ini sangat baik jika Anda mengontrol alat pertemuan, sangat buruk jika Anda tidak. sharingType = .noneLetakkan obrolan di ruang terpisah.
  3. Mission Control memberi Anda beberapa desktop. Bagikan Ruang 1, letakkan obrolan di Ruang 2. Geser untuk berinteraksi. Lambat, mengganggu alur, tetapi berhasil. Gunakan perangkat kedua.
  4. Sebuah ponsel atau iPad di samping laptop Anda tidak dapat dihentikan oleh alat penangkapan apa pun, secara definisi. Saya memilih opsi 1 ditambah aplikasi obrolan yang sudah saya bangun. Obrolan ini tidak terlihat untuk sekitar 95% dari jalur penangkapan, dan untuk kasus berbagi layar di Zoom saya hanya tidak menggunakan berbagi layar desktop.

Apa yang saya inginkan selanjutnya


Entitas publik

  • yang memungkinkan aplikasi yang telah dilakukan notarizasi menyatakan “jendela saya ini dikecualikan dari penangkapan, termasuk oleh pemanggil berhak istimewa.” Hari ini, itu tidak mungkin. jalur penangkapan. Kehadiran yang jujur dalam
  • dokumentasi. NSWindow.sharingType Dokumentasi membuatnya terdengar seperti jaminan keras. Tidak — minimal dokumentasi harus menyebutkan bahwa alat berhak istimewa Apple dan aplikasi dengan entitas privat dapat menangkap meskipun demikian. Hari ini mereka tidak menyebutkan itu. Cara untuk memeriksa
  • aplikasi mana yang memiliki akses penangkapan berhak istimewa di sistem — serupa dengan “Files and Folders” di Privasi & Keamanan. Hari ini tidak ada permukaan bagi pengguna untuk melihat siapa yang dapat melintasi privasi mereka. Sampai salah satu dari itu muncul, saran praktis adalah: asumsikan bahwa setiap jendela di layar Anda dapat ditangkap oleh sistem dan oleh aplikasi konferensi utama, terlepas dari apa

yang Anda atur. API eksklusi ini nyata — mereka bekerja terhadap sebagian besar dunia — tetapi mereka bukan batas keamanan yang dapat dipercaya terhadap bagian dunia yang paling penting. sharingType Anda Tidak Bisa Menyembunyikan Jendela dari Zoom pada macOS 15 2

Ingin bebas iklan? Bebas Iklan Hari Ini

Instal Ekstensi Kami

Tambahkan alat IO ke browser favorit Anda untuk akses instan dan pencarian lebih cepat

Ke Ekstensi Chrome Ke Ekstensi Tepi Ke Ekstensi Firefox Ke Ekstensi Opera

Papan Skor Telah Tiba!

Papan Skor adalah cara yang menyenangkan untuk melacak permainan Anda, semua data disimpan di browser Anda. Lebih banyak fitur akan segera hadir!

IKLAN · HAPUS?
IKLAN · HAPUS?
IKLAN · HAPUS?

Pojok Berita dengan Sorotan Teknologi

Terlibat

Bantu kami untuk terus menyediakan alat gratis yang berharga

Belikan aku kopi
IKLAN · HAPUS?