diff --git a/mkdocs-website/docs/en/changelog.md b/mkdocs-website/docs/en/changelog.md index 10bb194bb..299dc9ec0 100644 --- a/mkdocs-website/docs/en/changelog.md +++ b/mkdocs-website/docs/en/changelog.md @@ -22,8 +22,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## v3.0.0-alpha.6 - 2024-07-30 -### Fixed -- Module issues +### Fixed +- Module issues ## v3.0.0-alpha.5 - 2024-07-30 @@ -47,6 +47,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Implement `setIcon` on linux by [@abichinger](https://github.com/abichinger) in [#3354](https://github.com/wailsapp/wails/pull/3354) - Add flag `-port` to dev command and support environment variable `WAILS_VITE_PORT` by [@abichinger](https://github.com/abichinger) in [#3429](https://github.com/wailsapp/wails/pull/3429) - Add tests for bound method calls by [@abichinger](https://github.com/abichinger) in [#3431](https://github.com/wailsapp/wails/pull/3431) +- [windows] add `SetIgnoreMouseEvents` for already created window by [@bruxaodev](https://github.com/bruxaodev) in [#3667](https://github.com/wailsapp/wails/pull/3667) ### Fixed diff --git a/v3/examples/ignore-mouse/README.md b/v3/examples/ignore-mouse/README.md new file mode 100644 index 000000000..596d2c015 --- /dev/null +++ b/v3/examples/ignore-mouse/README.md @@ -0,0 +1,19 @@ +# Window Example + +This example is a demonstration of how to disable or enable mouse events. + +## Running the example + +To run the example, simply run the following command: + +```bash +go run . +``` + +# Status + +| Platform | Status | +|----------|---------| +| Mac | | +| Windows | Working | +| Linux | | diff --git a/v3/examples/ignore-mouse/main.go b/v3/examples/ignore-mouse/main.go new file mode 100644 index 000000000..869fdd9c5 --- /dev/null +++ b/v3/examples/ignore-mouse/main.go @@ -0,0 +1,36 @@ +package main + +import ( + "log" + + "github.com/wailsapp/wails/v3/pkg/application" +) + +func main() { + app := application.New(application.Options{ + Name: "WebviewWindow Demo", + Description: "A demo of the WebviewWindow API", + Assets: application.AlphaAssets, + Mac: application.MacOptions{ + ApplicationShouldTerminateAfterLastWindowClosed: false, + }, + }) + + window := app.NewWebviewWindowWithOptions(application.WebviewWindowOptions{ + Width: 800, + Height: 600, + Title: "Ignore Mouse Example", + URL: "https://wails.io", + IgnoreMouseEvents: false, + }) + + window.SetIgnoreMouseEvents(true) + log.Println("IgnoreMouseEvents set", window.IsIgnoreMouseEvents()) + + err := app.Run() + + if err != nil { + log.Fatal(err) + } + +} diff --git a/v3/examples/window/main.go b/v3/examples/window/main.go index 7f699e68b..de7faab99 100644 --- a/v3/examples/window/main.go +++ b/v3/examples/window/main.go @@ -217,7 +217,7 @@ func main() { Show() windowCounter++ }) - myMenu.Add("New Frameless WebviewWindow"). + myMenu.Add("New WebviewWindow (Frameless)"). SetAccelerator("CmdOrCtrl+F"). OnClick(func(ctx *application.Context) { app.NewWebviewWindowWithOptions(application.WebviewWindowOptions{ @@ -231,23 +231,21 @@ func main() { }).Show() windowCounter++ }) - if runtime.GOOS != "linux" { - myMenu.Add("New WebviewWindow (ignores mouse events)"). - SetAccelerator("CmdOrCtrl+F"). - OnClick(func(ctx *application.Context) { - app.NewWebviewWindowWithOptions(application.WebviewWindowOptions{ - HTML: "
", - X: rand.Intn(1000), - Y: rand.Intn(800), - IgnoreMouseEvents: true, - BackgroundType: application.BackgroundTypeTransparent, - Mac: application.MacWindow{ - InvisibleTitleBarHeight: 50, - }, - }).Show() - windowCounter++ - }) - } + myMenu.Add("New WebviewWindow (Ignores mouse events)"). + SetAccelerator("CmdOrCtrl+F"). + OnClick(func(ctx *application.Context) { + app.NewWebviewWindowWithOptions(application.WebviewWindowOptions{ + HTML: "", + X: rand.Intn(1000), + Y: rand.Intn(800), + IgnoreMouseEvents: true, + BackgroundType: application.BackgroundTypeTransparent, + Mac: application.MacWindow{ + InvisibleTitleBarHeight: 50, + }, + }).Show() + windowCounter++ + }) if runtime.GOOS == "darwin" { myMenu.Add("New WebviewWindow (MacTitleBarHiddenInset)"). OnClick(func(ctx *application.Context) { diff --git a/v3/pkg/application/webview_window.go b/v3/pkg/application/webview_window.go index 3ecb19f90..2e95368b2 100644 --- a/v3/pkg/application/webview_window.go +++ b/v3/pkg/application/webview_window.go @@ -90,6 +90,8 @@ type ( setMinimiseButtonState(state ButtonState) setMaximiseButtonState(state ButtonState) setCloseButtonState(state ButtonState) + isIgnoreMouseEvents() bool + setIgnoreMouseEvents(ignore bool) } ) @@ -1232,3 +1234,21 @@ func (w *WebviewWindow) addMenuBinding(a *accelerator, menuItem *MenuItem) { defer w.menuBindingsLock.Unlock() w.menuBindings[a.String()] = menuItem } + +func (w *WebviewWindow) IsIgnoreMouseEvents() bool { + if w.impl == nil && !w.isDestroyed() { + return false + } + return InvokeSyncWithResult(w.impl.isIgnoreMouseEvents) +} + +func (w *WebviewWindow) SetIgnoreMouseEvents(ignore bool) Window { + w.options.IgnoreMouseEvents = ignore + if w.impl == nil && !w.isDestroyed() { + return w + } + InvokeSync(func() { + w.impl.setIgnoreMouseEvents(ignore) + }) + return w +} diff --git a/v3/pkg/application/webview_window_darwin.go b/v3/pkg/application/webview_window_darwin.go index 52e9c1526..874756b32 100644 --- a/v3/pkg/application/webview_window_darwin.go +++ b/v3/pkg/application/webview_window_darwin.go @@ -689,12 +689,6 @@ static void windowShowMenu(void *window, void *menu, int x, int y) { [nsMenu popUpMenuPositioningItem:nil atLocation:point inView:webView]; } -// windowIgnoreMouseEvents makes the window ignore mouse events -static void windowIgnoreMouseEvents(void *window, bool ignore) { - WebviewWindow* nsWindow = (WebviewWindow*)window; - [nsWindow setIgnoresMouseEvents:ignore]; -} - // Make the given window frameless static void windowSetFrameless(void *window, bool frameless) { WebviewWindow* nsWindow = (WebviewWindow*)window; @@ -772,6 +766,16 @@ void windowFocus(void *window) { [nsWindow makeKeyWindow]; } +static bool isIgnoreMouseEvents(void *nsWindow) { + NSWindow *window = (__bridge NSWindow *)nsWindow; + return [window ignoresMouseEvents]; +} + +static void setIgnoreMouseEvents(void *nsWindow, bool ignore) { + NSWindow *window = (__bridge NSWindow *)nsWindow; + [window setIgnoresMouseEvents:ignore]; +} + */ import "C" import ( @@ -1159,9 +1163,8 @@ func (w *macosWebviewWindow) run() { w.setMaximiseButtonState(options.MaximiseButtonState) w.setCloseButtonState(options.CloseButtonState) - if options.IgnoreMouseEvents { - C.windowIgnoreMouseEvents(w.nsWindow, C.bool(true)) - } + // Ignore mouse events if requested + w.setIgnoreMouseEvents(options.IgnoreMouseEvents) titleBarOptions := macOptions.TitleBar if !w.parent.options.Frameless { @@ -1302,3 +1305,11 @@ func (w *macosWebviewWindow) setMaximiseButtonState(state ButtonState) { func (w *macosWebviewWindow) setCloseButtonState(state ButtonState) { C.setCloseButtonState(w.nsWindow, C.int(state)) } + +func (w *macosWebviewWindow) isIgnoreMouseEvents() bool { + return bool(C.isIgnoreMouseEvents(w.nsWindow)) +} + +func (w *macosWebviewWindow) setIgnoreMouseEvents(ignore bool) { + C.setIgnoreMouseEvents(w.nsWindow, C.bool(ignore)) +} diff --git a/v3/pkg/application/webview_window_linux.go b/v3/pkg/application/webview_window_linux.go index 9965984fd..cb7c7744f 100644 --- a/v3/pkg/application/webview_window_linux.go +++ b/v3/pkg/application/webview_window_linux.go @@ -42,8 +42,9 @@ type linuxWebviewWindow struct { gtkmenu pointer ctxMenuOpened bool - moveDebouncer func(func()) - resizeDebouncer func(func()) + moveDebouncer func(func()) + resizeDebouncer func(func()) + ignoreMouseEvents bool } var ( @@ -280,9 +281,8 @@ func (w *linuxWebviewWindow) run() { case WindowStateNormal: } - //if w.parent.options.IgnoreMouseEvents { - // windowIgnoreMouseEvents(w.window, w.webview, true) - //} + // Ignore mouse events if requested + w.setIgnoreMouseEvents(options.IgnoreMouseEvents) startURL, err := assetserver.GetStartURL(w.parent.options.URL) if err != nil { @@ -369,3 +369,17 @@ func (w *linuxWebviewWindow) setMaximiseButtonState(state ButtonState) {} // SetCloseButtonState is unsupported on Linux func (w *linuxWebviewWindow) setCloseButtonState(state ButtonState) {} + +func (w *linuxWebviewWindow) isIgnoreMouseEvents() bool { + return w.ignoreMouseEvents +} + +func (w *linuxWebviewWindow) setIgnoreMouseEvents(ignore bool) { + w.ignoreMouseEvents = ignore + + if ignore { + C.gtk_widget_set_events((*C.GtkWidget)(unsafe.Pointer(w.window)), C.GDK_ENTER_NOTIFY_MASK|C.GDK_LEAVE_NOTIFY_MASK) + } else { + C.gtk_widget_set_events((*C.GtkWidget)(unsafe.Pointer(w.window)), C.GDK_ALL_EVENTS_MASK) + } +} diff --git a/v3/pkg/application/webview_window_windows.go b/v3/pkg/application/webview_window_windows.go index 0631a1875..c5893b691 100644 --- a/v3/pkg/application/webview_window_windows.go +++ b/v3/pkg/application/webview_window_windows.go @@ -279,6 +279,8 @@ func (w *windowsWebviewWindow) run() { w.setResizable(!options.DisableResize) + w.setIgnoreMouseEvents(options.IgnoreMouseEvents) + if options.Frameless { // Inform the application of the frame change this is needed to trigger the WM_NCCALCSIZE event. // => https://learn.microsoft.com/en-us/windows/win32/dwm/customframe#removing-the-standard-frame @@ -1761,3 +1763,18 @@ func (w *windowsWebviewWindow) setCloseButtonState(state ButtonState) { func (w *windowsWebviewWindow) setGWLStyle(style int) { w32.SetWindowLong(w.hwnd, w32.GWL_STYLE, uint32(style)) } + +func (w *windowsWebviewWindow) isIgnoreMouseEvents() bool { + exStyle := w32.GetWindowLong(w.hwnd, w32.GWL_EXSTYLE) + return exStyle&w32.WS_EX_TRANSPARENT != 0 +} + +func (w *windowsWebviewWindow) setIgnoreMouseEvents(ignore bool) { + exStyle := w32.GetWindowLong(w.hwnd, w32.GWL_EXSTYLE) + if ignore { + exStyle |= w32.WS_EX_LAYERED | w32.WS_EX_TRANSPARENT + } else { + exStyle &^= w32.WS_EX_TRANSPARENT + } + w32.SetWindowLong(w.hwnd, w32.GWL_EXSTYLE, uint32(exStyle)) +} diff --git a/v3/pkg/application/window.go b/v3/pkg/application/window.go index 4970b1bb7..6d41aa5ee 100644 --- a/v3/pkg/application/window.go +++ b/v3/pkg/application/window.go @@ -36,6 +36,7 @@ type Window interface { Info(message string, args ...any) IsFocused() bool IsFullscreen() bool + IsIgnoreMouseEvents() bool IsMaximised() bool IsMinimised() bool HandleKeyEvent(acceleratorString string) @@ -63,6 +64,7 @@ type Window interface { SetMinSize(minWidth, minHeight int) Window SetRelativePosition(x, y int) Window SetResizable(b bool) Window + SetIgnoreMouseEvents(ignore bool) Window SetSize(width, height int) Window SetTitle(title string) Window SetURL(s string) Window