5
0
mirror of https://github.com/wailsapp/wails.git synced 2025-05-02 23:51:44 +08:00

Add Content Protection feature.

This commit is contained in:
Lea Anthony 2025-04-27 08:02:24 +10:00
parent 2bc2549160
commit a5a73d1d9f
No known key found for this signature in database
GPG Key ID: 33DAF7BB90A58405
10 changed files with 82 additions and 5 deletions

View File

@ -75,13 +75,14 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Add method `Close` on `sqlite` service to close the DB manually by [@fbbdev](https://github.com/fbbdev) in [#4067](https://github.com/wailsapp/wails/pull/4067) - Add method `Close` on `sqlite` service to close the DB manually by [@fbbdev](https://github.com/fbbdev) in [#4067](https://github.com/wailsapp/wails/pull/4067)
- Add cancellation support for query methods on `sqlite` service by [@fbbdev](https://github.com/fbbdev) in [#4067](https://github.com/wailsapp/wails/pull/4067) - Add cancellation support for query methods on `sqlite` service by [@fbbdev](https://github.com/fbbdev) in [#4067](https://github.com/wailsapp/wails/pull/4067)
- Add prepared statement support to `sqlite` service with JS bindings by [@fbbdev](https://github.com/fbbdev) in [#4067](https://github.com/wailsapp/wails/pull/4067) - Add prepared statement support to `sqlite` service with JS bindings by [@fbbdev](https://github.com/fbbdev) in [#4067](https://github.com/wailsapp/wails/pull/4067)
- Gin support by [Lea Anthony](https://github.com/leaanthony) in [PR](https://github.com/wailsapp/wails/pull/3537) based on the original work of [@AnalogJ](https://github.com/AnalogJ) in PR[https://github.com/wailsapp/wails/pull/3537] - Gin support by [Lea Anthony](https://github.com/leaanthony) in [PR](https://github.com/wailsapp/wails/pull/3537) based on the original work of [@AnalogJ](https://github.com/AnalogJ) in this [PR](https://github.com/wailsapp/wails/pull/3537)
- Fix auto save and password auto save always enabled by [@oSethoum](https://github.com/osethoum) in [#4134](https://github.com/wailsapp/wails/pull/4134) - Fix auto save and password auto save always enabled by [@oSethoum](https://github.com/osethoum) in [#4134](https://github.com/wailsapp/wails/pull/4134)
- Add `SetMenu()` on window to allow for setting a menu on a window by [@leaanthony](https://github.com/leaanthony) - Add `SetMenu()` on window to allow for setting a menu on a window by [@leaanthony](https://github.com/leaanthony)
- Add Notification support by [@popaprozac] in [#4098](https://github.com/wailsapp/wails/pull/4098) - Add Notification support by [@popaprozac] in [#4098](https://github.com/wailsapp/wails/pull/4098)
-  Add File Association support for mac by [@wimaha](https://github.com/wimaha) in [#4177](https://github.com/wailsapp/wails/pull/4177) -  Add File Association support for mac by [@wimaha](https://github.com/wimaha) in [#4177](https://github.com/wailsapp/wails/pull/4177)
- Add `wails3 tool version` for semantic version bumping by [@leaanthony](https://github.com/leaanthony) - Add `wails3 tool version` for semantic version bumping by [@leaanthony](https://github.com/leaanthony)
- Add systray hide/show on Windows by [@leaanthony](https://github.com/leaanthony) - Add systray hide/show on Windows by [@leaanthony](https://github.com/leaanthony)
- Add Content Protection on Windows/Mac by [@leaanthony](https://github.com/leaanthony) based on the original work of [@Taiterbase](https://github.com/Taiterbase) in this [PR](https://github.com/wailsapp/wails/pull/4241)
### Fixed ### Fixed

View File

@ -118,6 +118,18 @@ func main() {
windowCounter++ windowCounter++
}) })
if runtime.GOOS != "linux" { if runtime.GOOS != "linux" {
myMenu.Add("New WebviewWindow (Content Protection Enabled)").
OnClick(func(ctx *application.Context) {
app.NewWebviewWindowWithOptions(application.WebviewWindowOptions{
MinimiseButtonState: application.ButtonDisabled,
ContentProtectionEnabled: true,
}).
SetTitle("WebviewWindow "+strconv.Itoa(windowCounter)).
SetRelativePosition(rand.Intn(1000), rand.Intn(800)).
SetURL("https://wails.io").
Show()
windowCounter++
})
myMenu.Add("New WebviewWindow (Disable Minimise)"). myMenu.Add("New WebviewWindow (Disable Minimise)").
OnClick(func(ctx *application.Context) { OnClick(func(ctx *application.Context) {
app.NewWebviewWindowWithOptions(application.WebviewWindowOptions{ app.NewWebviewWindowWithOptions(application.WebviewWindowOptions{

View File

@ -109,6 +109,7 @@ type (
hideMenuBar() hideMenuBar()
toggleMenuBar() toggleMenuBar()
setMenu(menu *Menu) setMenu(menu *Menu)
setContentProtection(enabled bool)
} }
) )
@ -486,6 +487,15 @@ func (w *WebviewWindow) SetResizable(b bool) Window {
return w return w
} }
func (w *WebviewWindow) SetContentProtection(b bool) Window {
if w.impl == nil {
w.options.ContentProtectionEnabled = b
} else {
w.impl.setContentProtection(b)
}
return w
}
// Resizable returns true if the window is resizable. // Resizable returns true if the window is resizable.
func (w *WebviewWindow) Resizable() bool { func (w *WebviewWindow) Resizable() bool {
return !w.options.DisableResize return !w.options.DisableResize

View File

@ -811,6 +811,18 @@ static void setIgnoreMouseEvents(void *nsWindow, bool ignore) {
[window setIgnoresMouseEvents:ignore]; [window setIgnoresMouseEvents:ignore];
} }
static void setContentProtection(void *nsWindow, bool enabled) {
NSWindow *window = (__bridge NSWindow *)nsWindow;
if( ! [window respondsToSelector:@selector(setSharingType:)]) {
return;
}
if( enabled ) {
[window setSharingType:NSWindowSharingReadOnly];
} else {
[window setSharingType:NSWindowSharingNone];
}
*/ */
import "C" import "C"
import ( import (
@ -1406,6 +1418,10 @@ func (w *macosWebviewWindow) setIgnoreMouseEvents(ignore bool) {
C.setIgnoreMouseEvents(w.nsWindow, C.bool(ignore)) C.setIgnoreMouseEvents(w.nsWindow, C.bool(ignore))
} }
func (w *macosWebviewWindow) setContentProtection(enabled bool) {
C.setContectProtection(w.nsWindow, C.bool(enabled))
}
func (w *macosWebviewWindow) cut() { func (w *macosWebviewWindow) cut() {
} }

View File

@ -412,6 +412,7 @@ func (w *linuxWebviewWindow) setIgnoreMouseEvents(ignore bool) {
w.ignoreMouse(w.ignoreMouseEvents) w.ignoreMouse(w.ignoreMouseEvents)
} }
func (w *linuxWebviewWindow) showMenuBar() {} func (w *linuxWebviewWindow) showMenuBar() {}
func (w *linuxWebviewWindow) hideMenuBar() {} func (w *linuxWebviewWindow) hideMenuBar() {}
func (w *linuxWebviewWindow) toggleMenuBar() {} func (w *linuxWebviewWindow) toggleMenuBar() {}
func (w *linuxWebviewWindow) setContentProtection(enabled bool) {}

View File

@ -139,6 +139,9 @@ type WebviewWindowOptions struct {
// IgnoreMouseEvents will ignore mouse events in the window (Windows + Mac only) // IgnoreMouseEvents will ignore mouse events in the window (Windows + Mac only)
IgnoreMouseEvents bool IgnoreMouseEvents bool
// ContentProtectionEnabled specifies whether content protection is enabled, preventing screen capture and recording.
ContentProtectionEnabled bool
} }
type RGBA struct { type RGBA struct {

View File

@ -347,6 +347,9 @@ func (w *windowsWebviewWindow) run() {
globalApplication.fatal("unable to create window") globalApplication.fatal("unable to create window")
} }
// Process ContentProtection
w.setContentProtection(w.parent.options.ContentProtectionEnabled)
// Ensure correct window size in case the scale factor of current screen is different from the initial one. // Ensure correct window size in case the scale factor of current screen is different from the initial one.
// This could happen when using the default window position and the window launches on a secondary monitor. // This could happen when using the default window position and the window launches on a secondary monitor.
currentScreen, _ := w.getScreen() currentScreen, _ := w.getScreen()
@ -2086,3 +2089,11 @@ func (w *windowsWebviewWindow) hideMenuBar() {
w32.SetMenu(w.hwnd, 0) w32.SetMenu(w.hwnd, 0)
} }
} }
func (w *windowsWebviewWindow) setContentProtection(enabled bool) {
var affinity uint32 = w32.WDA_EXCLUDEFROMCAPTURE
if !enabled {
affinity = w32.WDA_NONE
}
w32.SetWindowDisplayAffinity(w.hwnd, affinity)
}

View File

@ -85,4 +85,5 @@ type Window interface {
ZoomOut() ZoomOut()
ZoomReset() Window ZoomReset() Window
SetMenu(menu *Menu) SetMenu(menu *Menu)
SetContentProtection(protection bool) Window
} }

View File

@ -178,7 +178,8 @@ var (
procRedrawWindow = moduser32.NewProc("RedrawWindow") procRedrawWindow = moduser32.NewProc("RedrawWindow")
procRegisterWindowMessageW = moduser32.NewProc("RegisterWindowMessageW") procRegisterWindowMessageW = moduser32.NewProc("RegisterWindowMessageW")
procSetWindowDisplayAffinity = user32.NewProc("SetWindowDisplayAffinity")
mainThread HANDLE mainThread HANDLE
) )

21
v3/pkg/w32/wda.go Normal file
View File

@ -0,0 +1,21 @@
//go:build windows
package w32
const (
WDA_NONE = 0x00000000
WDA_MONITOR = 0x00000001
WDA_EXCLUDEFROMCAPTURE = 0x00000011 // windows 10 2004+
)
func SetWindowDisplayAffinity(hwnd uintptr, affinity uint32) bool {
if affinity == WDA_EXCLUDEFROMCAPTURE && !IsWindowsVersionAtLeast(10, 0, 19041) {
// for older windows versions, use WDA_MONITOR
affinity = WDA_MONITOR
}
ret, _, _ := procSetWindowDisplayAffinity.Call(
hwnd,
uintptr(affinity),
)
return ret != 0
}