NewYour coding agent can read the release notes before it upgrades.Set up the MCP server →
pub.dev · #1114 most downloaded on pub.dev
Flutter plugin to prevent screenshots, detect screen recording, and show blur/color/image overlays in the app switcher on Android, iOS, macOS, Linux, Windows, and Web.
Last release 2 months ago
08 Aug 2026
Ships unpredictably
gaps range from 8 days to 1.5 years
Nearly every release is documented
notes for 28 of 29 stable releases
2 versions withdrawn
withdrawn after publishing
4 years old
35 releases · first in 2022
Patch release: Windows screenshot prevention now actually works.
Patch release: Windows screenshot prevention now actually works.
SetWindowDisplayAffinity to the top-level window instead of the child Flutter view (#119). Display affinity is a top-level-window property and the Flutter runner reparents the view via SetParent, so previous versions silently protected nothing on Windows — screenshotOff() reported success while window content stayed fully capturable. The plugin now resolves the root ancestor on every call and re-asserts persisted prevention once the view is attached to its real top-level window, covering both the standard runner and multi-window embeddings (e.g. desktop_multi_window).window_manager's prevent-screen-capture).WDA_EXCLUDEFROMCAPTURE isn't available and the existing WDA_MONITOR fallback applies (window blacked out in captures).Full details: CHANGELOG
On pub.dev: https://pub.dev/packages/no_screenshot/versions/2.0.1
One column per quarter.
Breaking release. Two things to check before upgrading from 1.2.0:
Breaking release. Two things to check before upgrading from 1.2.0:
screenshotOff()/screenshotOn()/toggleScreenshot() own an independent claim, and an active app-switcher overlay mode holds its own claim. Protection stays engaged while either claim is held. Apps that use only one of the two APIs behave exactly as before; sequences that mix them now resolve fail-secure instead of silently dropping protection. To fully disable protection, release both claims — e.g. overlayOff() + screenshotOn() (what SecureWidget / applyOverlayMode(OverlayMode.none) do).overlayOff() — an idempotent method that deterministically disables any active app-switcher overlay mode (image, blur, or color) without needing to know the current state (#115).independent_prevention key; state written by older versions is migrated automatically (one-shot) on first launch.SecureWidget teardown, applyOverlayMode(OverlayMode.none), and applyOverlayMode(OverlayMode.secure) now clear any active overlay mode — a disposed SecureWidget(mode: OverlayMode.blur) no longer keeps showing the blur overlay in the app switcher.applyOverlayMode(OverlayMode.secure) takes the independent prevention claim before releasing the overlay's claim, so prevention stays continuously engaged across an overlay → secure transition (no transient unprotected frame).toggleScreenshot() now toggles the plugin's own independent claim rather than inspecting the current window flag. If your app sets FLAG_SECURE (or the platform equivalent) outside this plugin, use screenshotOff()/screenshotOn() explicitly instead of mixing it with toggleScreenshot().Breaking release. Two things to check before upgrading:
- Prevention is now tracked as two separate claims (released for testing in 1.3.0-beta.1, see below). Apps that use only
screenshotOff()/screenshotOn()or only the overlay-mode APIs behave exactly as before; apps that mix the two now resolve fail-secure — protection stays on until both claims are released (overlayOff()+screenshotOn()).- The minimum Flutter version is now 3.44 (Dart 3.12).
overlayOff() method, the two-claim prevention model, and the SecureWidget/applyOverlayMode overlay-teardown fixes.Beta for developer testing before the stable 1.3.0 release. Install explicitly:
Beta for developer testing before the stable 1.3.0 release. Install explicitly:
dependencies:
no_screenshot: ^1.3.0-beta.1overlayOff() — idempotently disables whichever app-switcher overlay mode is active (image, blur, or color) without needing to know the current state (#115)screenshotOff()/screenshotOn()/toggleScreenshot() own an independent claim, and an active overlay mode holds its own. Protection stays engaged while either claim is held, so mixed API sequences resolve fail-secure instead of silently dropping protection. Apps using only the plain API or only the overlay API behave exactly as before. Full delta list in the CHANGELOGSecureWidget teardown and applyOverlayMode transitions now clear overlay modes correctly (no more overlay surviving unmount or persisting across restarts), and overlay-to-secure transitions keep prevention continuously engagedIf your app mixes screenshotOff()/screenshotOn() with overlay modes, verify your protection flows — especially any sequence that previously relied on screenshotOn() or an overlay toggle-off dropping all protection. Release both claims (overlayOff() + screenshotOn()) to fully disable protection.
Please report anything unexpected on #115 or a new issue.
Beta — please test before the stable 1.3.0. This release changes how prevention state is tracked internally (details below). If your app mixes
screenshotOff()/screenshotOn()with the overlay-mode APIs, please verify your flows and report issues.
overlayOff() — an idempotent method that deterministically disables any active app-switcher overlay mode (image, blur, or color), without needing to know the current state (#115). The counterpart to the existing screenshotWithImage()/screenshotWithBlur()/screenshotWithColor() enable methods.screenshotOff()/screenshotOn()/toggleScreenshot() own an independent claim, and an active overlay mode holds its own claim. Protection stays engaged while either claim is held. No API signatures changed, and apps that use only the plain methods or only the overlay methods behave exactly as before; sequences that mix the two APIs now resolve fail-secure instead of silently dropping protection:
screenshotWithBlur() → screenshotOff() → overlayOff(): prevention now stays on (the independent claim survives; previously it was silently dropped).screenshotWithBlur() → screenshotOn(): prevention now stays on while the overlay is active (the overlay's claim survives; previously prevention dropped while the blur overlay kept showing in the app switcher).screenshotOff() → toggleScreenshotWithBlur() on/off: prevention now stays on after the overlay toggles off (previously dropped).overlayOff() + screenshotOn() (what SecureWidget/applyOverlayMode(OverlayMode.none) do).independent_prevention key; state written by older versions is migrated automatically (one-shot) on first launch.toggleScreenshot() now toggles the plugin's own independent claim rather than inspecting the current window flag. If your app sets FLAG_SECURE (or the platform equivalent) outside this plugin, do not mix that with toggleScreenshot() — use screenshotOff()/screenshotOn() explicitly.SecureWidget teardown, applyOverlayMode(OverlayMode.none), and applyOverlayMode(OverlayMode.secure) now clear any active overlay mode. Previously they only called screenshotOn(), which leaves the overlay mode active (and persisted) — so a disposed SecureWidget(mode: OverlayMode.blur) kept showing the blur overlay in the app switcher.applyOverlayMode(OverlayMode.secure) takes the independent prevention claim before releasing the overlay's claim, so prevention stays continuously engaged across an overlay → secure transition (no transient unprotected frame).Bug-fix release restoring compatibility with the latest toolchains and fixing two long-standing iOS/macOS issues.
Bug-fix release restoring compatibility with the latest toolchains and fixing two long-standing iOS/macOS issues.
screenshotOff() works even when scene lifecycle events never reach the plugin — e.g. apps migrated to the UIScene lifecycle with a custom SceneDelegate that does not subclass FlutterSceneDelegate (#105). screenshotOff()/toggleScreenshot() now return false instead of a misleading true when protection could not engage because no window is available yetscreenshotOff() returns false there; app-switcher overlays and screenshot/recording detection are unaffectedCGWindowListCreateImage (removed in the macOS 26 "Tahoe" SDK) with cacheDisplay for the blur-overlay snapshot — no Screen Recording permission required. The blur overlay on macOS now always uses the system blur material and blurRadius has no effect there; content remains fully obscured in Mission Control / the app switcher. Also fixes blur-overlay edges fading to transparent on iOS and macOS — thanks @paulanatoleclaudot-betclic (#102)Full Changelog: v1.1.0...v1.2.0
screenshotOff() works even when scene lifecycle events never reach the plugin — e.g. apps migrated to the UIScene lifecycle with a custom SceneDelegate that does not subclass FlutterSceneDelegate (#105). screenshotOff()/toggleScreenshot() now return false instead of a misleading true when protection could not engage because no window is available yet.screenshotOff() now returns false there; app-switcher overlays and screenshot/recording detection are unaffected.CGWindowListCreateImage (removed in the macOS 26 "Tahoe" SDK) with cacheDisplay for the blur-overlay snapshot, keeping the plugin compiling against the latest SDK without requiring Screen Recording permission (#109). Because Flutter renders into a CAMetalLayer that AppKit snapshots cannot capture, the blur overlay on macOS now always uses the system blur material and blurRadius has no effect there; content remains fully obscured in Mission Control / the app switcher. Also fixes blur-overlay edges fading to transparent on iOS and macOS, thanks to @paulanatoleclaudot-betclic (#102).Renamed overlay image assets on all platforms to avoid generic-name collisions ( #99 ) by @yar-tsar .
Renamed overlay image assets on all platforms to avoid generic-name collisions (#99) by @yar-tsar.
Migration — rename your overlay image files:
| Platform | Before | After |
|---|---|---|
| Android | res/drawable/image.png |
res/drawable/no_screenshot_image.png |
| iOS | Assets.xcassets/image.imageset/ |
Assets.xcassets/NoScreenshotImage.imageset/ |
| macOS | Assets.xcassets/image.imageset/ |
Assets.xcassets/NoScreenshotImage.imageset/ |
No Dart-side code changes are required — only the asset files need to be renamed.
Android 15 screen recording detection — WindowManager.addScreenRecordingCallback (API 35) provides true start/stop detection via SCREEN_RECORDING_STAT
WindowManager.addScreenRecordingCallback (API 35) provides true start/stop detection via SCREEN_RECORDING_STATE_VISIBLE / SCREEN_RECORDING_STATE_NOT_VISIBLE (#98)Activity.ScreenCaptureCallback, API <34 graceful no-opstartScreenRecordingListening() / stopScreenRecordingListening() API automatically uses the best available native API| Platform | Start | Stop |
|---|---|---|
| iOS 11+ | ✅ | ✅ |
| Android 15+ (API 35) | ✅ | ✅ |
| Android 14 (API 34) | ✅ | ❌ |
| macOS | ✅ | ✅ |
| Linux | ✅ | ✅ |
| Windows | ✅ | ✅ |
See the full CHANGELOG for details.
Add WindowManager.addScreenRecordingCallback (API 35) for true
start/stop recording detection. Falls back to ScreenCaptureCallback
on API 34 and graceful no-op below. Closes #98.
WindowManager.addScreenRecordingCallback — provides true start/stop detection with SCREEN_RECORDING_STATE_VISIBLE / SCREEN_RECORDING_STATE_NOT_VISIBLE (#98) by @fonkamloic.WindowManager.addScreenRecordingCallback, API 34 falls back to Activity.ScreenCaptureCallback, API <34 graceful no-op by @fonkamloic.fix: Pub Point analysis failure.
Deprecation Notice: Deprecated the use of the constructor NoScreenshot() in favor of the singleton NoScreenshot.instance.
didChangeAppLifecycleState. The state will now be automatically persisted using native platform SharedPreferences.NoScreenshot plugin.NoScreenshot() in favor of the singleton NoScreenshot.instance.feat(ios): Migrate to UIScene lifecycle for iOS 26+ compatibility — FlutterSceneLifeCycleDelegate conformance, deprecated UIScreen.main removed, deplo…
UIScene lifecycle for iOS 26+ compatibility — FlutterSceneLifeCycleDelegate conformance, deprecated UIScreen.main removed, deployment target bumped to iOS 13.0 / Flutter >=3.38.0. ([#97])@objc(NoScreenshotPlugin) annotation for Swift Package Manager builds — fixes "Unknown receiver 'NoScreenshotPlugin'" compilation error in GeneratedPluginRegistrant.m (#96).UIVisualEffectView blur overlay with CIGaussianBlur — the previous implementation darkened the screen instead of blurring it; now captures a window snapshot and applies a true Gaussian blur with configurable radius.Full Changelog: v0.9.1...v0.10.0
UIScene lifecycle for iOS 26+ compatibility — add FlutterSceneLifeCycleDelegate conformance so overlay show/hide logic fires under both the legacy UIApplicationDelegate and the new UIScene lifecycle; replace deprecated UIScreen.main usages; remove stale iOS 11 availability checks; bump deployment target to iOS 13.0 / Flutter >=3.38.0 by @fonkamloic.@objc(NoScreenshotPlugin) annotation for Swift Package Manager builds — fixes "Unknown receiver 'NoScreenshotPlugin'" compilation error in GeneratedPluginRegistrant.m (#96) by @fonkamloic.UIVisualEffectView blur overlay with CIGaussianBlur — the previous implementation darkened the screen instead of blurring it; now captures a window snapshot and applies a true Gaussian blur with configurable radius by @fonkamloic.fix(ios): Add @objc(NoScreenshotPlugin) annotation for Swift Package Manager builds — fixes "Unknown receiver 'NoScreenshotPlugin'" compilation error
@objc(NoScreenshotPlugin) annotation for Swift Package Manager builds — fixes "Unknown receiver 'NoScreenshotPlugin'" compilation error in GeneratedPluginRegistrant.m (#96).UIVisualEffectView blur overlay with CIGaussianBlur — the previous implementation darkened the screen instead of blurring it; now captures a window snapshot and applies a true Gaussian blur with configurable radius.Full Changelog: v0.9.1...v0.9.2
chore: add pub.dev topics to pubspec.yaml.
Swift Package Manager support — Package.swift for both iOS and macOS, with full CocoaPods backward compatibility.
Package.swift for both iOS and macOS, with full CocoaPods backward compatibility.source_files paths to reference SPM directory structure..build/ and .swiftpm/ to .gitignore and .pubignore.Package.swift for both iOS and macOS, with CocoaPods backward compatibility by @fonkamloic.source_files paths to reference SPM directory structure by @fonkamloic..build/ and .swiftpm/ to .gitignore and .pubignore by @fonkamloic.feat: added timestamp and sourceApp metadata fields to ScreenshotSnapshot — backward-compatible defaults (P8) by @fonkamloic.
timestamp and sourceApp metadata fields to ScreenshotSnapshot — backward-compatible defaults (P8) by @fonkamloic.MediaStore.Images.Media.DATE_ADDED and DISPLAY_NAME by @fonkamloic.kMDItemContentCreationDate and kMDItemCreator / detected recording app name by @fonkamloic.G_FILE_ATTRIBUTE_TIME_MODIFIED and inferred source app from filename prefix by @fonkamloic.SetWindowDisplayAffinity(WDA_EXCLUDEFROMCAPTURE) for prevention, AddClipboardFormatListener + ReadDirectoryChangesW for screenshot detection, process scanning for recording detection (P11) by @fonkamloic.onScreenshotDetected, onScreenRecordingStarted, onScreenRecordingStopped with startCallbacks() / stopCallbacks() / removeAllCallbacks() API (P15) by @fonkamloic.user-select: none CSS, visibilitychange detection (P17) by @fonkamloic.NoScreenshot.instance creating a new instance on every access — now a proper cached singleton by @fonkamloic._instancePlatform from a captured field to a getter so platform is resolved at call time by @fonkamloic.FlEventSink with fl_event_channel_send for stream event delivery by @fonkamloic.screenshotStream coverage for event channel decoding and stream caching by @fonkamloic.Nothing published for this version
feat: added SecureWidget — a declarative Flutter widget that auto-enables screenshot protection on mount and disables on unmount (P6) by @fonkamloic.
SecureWidget — a declarative Flutter widget that auto-enables screenshot protection on mount and disables on unmount (P6) by @fonkamloic.SecureNavigatorObserver — a NavigatorObserver that applies different protection levels per named route (P7) by @fonkamloic.SecureRouteConfig class for configuring per-route protection policies with OverlayMode, blurRadius, and color by @fonkamloic.OverlayMode enum (none, secure, blur, color, image) and applyOverlayMode() helper for declarative protection by @fonkamloic.screenshotWithImage(), screenshotWithBlur(), and screenshotWithColor() API methods — always enable the overlay (no toggle), safe to call repeatedly by @fonkamloic.SecureWidget (initState, dispose, didUpdateWidget, all overlay modes) by @fonkamloic.SecureNavigatorObserver (didPush, didPop, didReplace, didRemove, defaultConfig, custom params) by @fonkamloic.NoScreenshot tests for new idempotent methods by @fonkamloic.feat: added configurable blurRadius parameter to toggleScreenshotWithBlur({double blurRadius}) — defaults to 30.0, customizable per platform by @fonka
blurRadius parameter to toggleScreenshotWithBlur({double blurRadius}) — defaults to 30.0, customizable per platform by @fonkamloic.toggleScreenshotWithColor({int color}) API — solid color overlay for app switcher / recents screen across all platforms by @fonkamloic.View with the specified ARGB color by @fonkamloic.UIView with the specified background color by @fonkamloic.NSView with the specified background color by @fonkamloic.NoScreenshot tests for toggleScreenshotWithBlur with custom radius and toggleScreenshotWithColor by @fonkamloic.feat: added toggleScreenshotWithBlur() API — Gaussian blur overlay for app switcher / recents screen (P2) by @fonkamloic.
toggleScreenshotWithBlur() API — Gaussian blur overlay for app switcher / recents screen (P2) by @fonkamloic.RenderEffect.createBlurEffect() on API 31+ (zero-copy GPU blur) and RenderScript.ScriptIntrinsicBlur on API 17–30 by @fonkamloic.UIVisualEffectView with UIBlurEffect(style: .regular) by @fonkamloic.NSVisualEffectView with .hudWindow material by @fonkamloic.setState on unmounted widget — added proper dispose() and mounted check by @fonkamloic.NoScreenshot tests for toggleScreenshotWithBlur by @fonkamloic.feat: detect screen recording start/stop events across all platforms (P1) by @fonkamloic.
UIScreen.capturedDidChangeNotification (iOS 11+) — detects both start and stop by @fonkamloic.Activity.ScreenCaptureCallback (API 34+) — detects recording start; graceful no-op on pre-34 devices by @fonkamloic.NSWorkspace process monitoring — polls for known recording apps (QuickTime Player, OBS, Loom, Kap, ffmpeg, screencapture, simplescreenrecorder) by @fonkamloic./proc process scanning — polls for known recording tools (ffmpeg, obs, simplescreenrecorder, kazam, peek, recordmydesktop, vokoscreen) by @fonkamloic.isScreenRecording field to ScreenshotSnapshot — backward-compatible, defaults to false when omitted by native code by @fonkamloic.startScreenRecordingListening() and stopScreenRecordingListening() API methods — recording detection is independent of screenshot detection by @fonkamloic.isScreenRecording status display by @fonkamloic.ScreenshotSnapshot tests for screen recording detection by @fonkamloic.feat(linux): added Linux support with screenshot detection via GFileMonitor (inotify), monitoring ~/Pictures/Screenshots/, ~/Pictures/, and XDG pictur
GFileMonitor (inotify), monitoring ~/Pictures/Screenshots/, ~/Pictures/, and XDG pictures directory by @fonkamloic.GFileMonitor) — same as macOS by @fonkamloic.FLAG_SECURE-equivalent API by @fonkamloic.$XDG_DATA_HOME/no_screenshot/state.json by @fonkamloic.fix(ios): fix iOS 26 RTL layout shift by dropping ScreenProtectorKit and inlining screenshot prevention with forceLeftToRight semantics by @fonkamloic
ScreenProtectorKit and inlining screenshot prevention with forceLeftToRight semantics by @fonkamloic.EXC_BAD_ACCESS crash in _collectExistingTraitCollectionsForTraitTracking on iOS 26+ caused by circular view hierarchy by @fonkamloic.ScreenProtectorKit dependency — all iOS screenshot prevention is now inlined by @fonkamloic.screenshotPath availability — file path is only available on macOS; Android and iOS return a placeholder by @fonkamloic.fix(macos): detect clipboard-only screenshots (Cmd+Ctrl+Shift+3/4) via pasteboard polling by @fonkamloic.
screencaptureui is still running by @fonkamloic.screencaptureui process lifecycle (launch + termination) for reliable detection by @fonkamloic.NSMetadataQuery by @fonkamloic.feat(macos): added macOS support for toggleScreenshotWithImage() by @fonkamloic.
toggleScreenshotWithImage() by @fonkamloic.toggleScreenshotWithImage() API to display a custom image overlay when the app goes to the background or app switcher, preventing screenshot content exposure on both Android and iOS by @zhangyuanyuan-bear and @fonkamloic.Executors for SharedPreferences access on Android to avoid strict mode violations on startup by @qk7b in https://github.com/FlutterPlaza/no_screenshot/pull/74.toggleScreenshotWithImage tests and fixed CI codecov upload by @fonkamloic.feat: added toggleScreenshotWithImage() API to display a custom image overlay when the app goes to the background or app switcher, preventing screensh
toggleScreenshotWithImage() API to display a custom image overlay when the app goes to the background or app switcher, preventing screenshot content exposure on both Android and iOS by @zhangyuanyuan-bear and @fonkamloic.Executors for SharedPreferences access on Android to avoid strict mode violations on startup by @qk7b.feat: macos support by @fonkamloic in https://github.com/FlutterPlaza/no_screenshot/pull/51
chore: updated pkg version by @fonkamloic in https://github.com/FlutterPlaza/no_screenshot/pull/63
fix: fix screenshot state not persisting on iOS by @fonkamloic in https://github.com/FlutterPlaza/no_screenshot/pull/45
fix: fix screenshot state not persisting on iOS
Upgrade android to support AGP 8.X
Updated readme and added sample usage.
Updated readme and added sample usage.
Made NoScreenshot class a singleton
NoScreenshot class a singletonFixed issue #1Crashes app when backgrounded on iOS
Fixed broken link from pub dev analyses
Removed the non implemented override functions in android life-cycle
Specify a more current version of ScreenProtectorKit. This resolves iOS17 issues.
Package has 3 basic functionalities on android and IOS via method channel.
Package has 3 basic functionalities on android and IOS via method channel. - Disable screenshot support in app - Enable screenshot support in app - Toggle between enable and disable state
Your coding agent can read these notes before it upgrades. Set up the MCP server →