Skip to content

Commit cfe2424

Browse files
authored
WindowDidMove / WindowDidResize events for Linux and Windows
* [linux] emit system specific event for theme change Code was incorrectly emitting the `events.Common.ThemeChanged` event instead of the OS Specific `events.Linux.SystemThemeChanged` event. It is the reponsibility of the code in events_common_linux.go to map it to the common variety. * [linux] implement WindowDidMove * [linux] implement debounce for WindowDidMove * [example] listen for events.Common.WindowDidMove * [windows] move WindowDidMove mapper outside of DnD guard * WindowDidResize implementation * windows: WindowDidResize * chore: changelog update * events.Common.WindowDidMove and events.Common.WindowDidResize
1 parent ed88987 commit cfe2424

File tree

13 files changed

+768
-659
lines changed

13 files changed

+768
-659
lines changed

Diff for: mkdocs-website/docs/en/changelog.md

+2
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
1818
## [Unreleased]
1919

2020
### Added
21+
- [linux] WindowDidMove / WindowDidResize events in [#3580](https://github.com/wailsapp/wails/pull/3580)
22+
- [windows] WindowDidResize event in (https://github.com/wailsapp/wails/pull/3580)
2123
- [darwin] add Event ApplicationShouldHandleReopen to be able to handle dock icon click by @5aaee9 in [#2991](https://github.com/wailsapp/wails/pull/2991)
2224
- [darwin] add getPrimaryScreen/getScreens to impl by @tmclane in [#2618](https://github.com/wailsapp/wails/pull/2618)
2325
- [darwin] add option for showing the toolbar in fullscreen mode on macOS by [@fbbdev](https://github.com/fbbdev) in [#3282](https://github.com/wailsapp/wails/pull/3282)

Diff for: v3/examples/window/main.go

+18-1
Original file line numberDiff line numberDiff line change
@@ -164,13 +164,30 @@ func main() {
164164
SetRelativePosition(rand.Intn(1000), rand.Intn(800)).
165165
SetURL("https://wails.io").
166166
Show()
167-
w.On(events.Windows.WindowDidMove, func(event *application.WindowEvent) {
167+
w.On(events.Common.WindowDidMove, func(event *application.WindowEvent) {
168168
x, y := w.AbsolutePosition()
169169
fmt.Printf("WindowDidMove event triggered. New position: (%d, %d)\n", x, y)
170170
})
171171
windowCounter++
172172
})
173+
myMenu.Add("New WebviewWindow (Listen to Resize)").
174+
OnClick(func(ctx *application.Context) {
175+
w := app.NewWebviewWindowWithOptions(application.WebviewWindowOptions{
176+
Windows: application.WindowsWindow{
177+
DisableMenu: true,
178+
},
179+
}).
180+
SetTitle("WebviewWindow "+strconv.Itoa(windowCounter)).
181+
SetRelativePosition(rand.Intn(1000), rand.Intn(800)).
182+
SetURL("https://wails.io").
183+
Show()
184+
w.On(events.Common.WindowDidResize, func(event *application.WindowEvent) {
185+
width, height := w.Size()
173186

187+
fmt.Printf("WindowDidResize event triggered. New size: (%d, %d)\n", width, height)
188+
})
189+
windowCounter++
190+
})
174191
myMenu.Add("New WebviewWindow (Hides on Close one time)").
175192
SetAccelerator("CmdOrCtrl+H").
176193
OnClick(func(ctx *application.Context) {

Diff for: v3/internal/runtime/desktop/@wailsio/runtime/src/event_types.js

+4
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ export const EventTypes = {
2727
WindowDragLeave: "windows:WindowDragLeave",
2828
WindowDragOver: "windows:WindowDragOver",
2929
WindowDidMove: "windows:WindowDidMove",
30+
WindowDidResize: "windows:WindowDidResize",
3031
},
3132
Mac: {
3233
ApplicationDidBecomeActive: "mac:ApplicationDidBecomeActive",
@@ -158,6 +159,8 @@ export const EventTypes = {
158159
SystemThemeChanged: "linux:SystemThemeChanged",
159160
WindowLoadChanged: "linux:WindowLoadChanged",
160161
WindowDeleteEvent: "linux:WindowDeleteEvent",
162+
WindowDidMove: "linux:WindowDidMove",
163+
WindowDidResize: "linux:WindowDidResize",
161164
WindowFocusIn: "linux:WindowFocusIn",
162165
WindowFocusOut: "linux:WindowFocusOut",
163166
ApplicationStartup: "linux:ApplicationStartup",
@@ -185,5 +188,6 @@ export const EventTypes = {
185188
WindowRuntimeReady: "common:WindowRuntimeReady",
186189
ThemeChanged: "common:ThemeChanged",
187190
WindowDidMove: "common:WindowDidMove",
191+
WindowDidResize: "common:WindowDidResize",
188192
},
189193
};

Diff for: v3/internal/runtime/desktop/@wailsio/runtime/types/event_types.d.ts

+4
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ export declare const EventTypes: {
2727
WindowDragLeave: string,
2828
WindowDragOver: string,
2929
WindowDidMove: string,
30+
WindowDidResize: string,
3031
},
3132
Mac: {
3233
ApplicationDidBecomeActive: string,
@@ -158,6 +159,8 @@ export declare const EventTypes: {
158159
SystemThemeChanged: string,
159160
WindowLoadChanged: string,
160161
WindowDeleteEvent: string,
162+
WindowDidMove: string,
163+
WindowDidResize: string,
161164
WindowFocusIn: string,
162165
WindowFocusOut: string,
163166
ApplicationStartup: string,
@@ -185,5 +188,6 @@ export declare const EventTypes: {
185188
WindowRuntimeReady: string,
186189
ThemeChanged: string,
187190
WindowDidMove: string,
191+
WindowDidResize: string,
188192
},
189193
};

Diff for: v3/pkg/application/application_linux.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -173,7 +173,7 @@ func (a *linuxApp) monitorThemeChanges() {
173173

174174
if theme != a.theme {
175175
a.theme = theme
176-
event := newApplicationEvent(events.Common.ThemeChanged)
176+
event := newApplicationEvent(events.Linux.SystemThemeChanged)
177177
event.Context().setIsDarkMode(a.isDarkMode())
178178
applicationEvents <- event
179179
}

Diff for: v3/pkg/application/linux_cgo.go

+31
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@ typedef struct WindowEvent {
5959
// exported below
6060
void activateLinux(gpointer data);
6161
extern void emit(WindowEvent* data);
62+
extern gboolean handleConfigureEvent(GtkWidget*, GdkEventConfigure*, uintptr_t);
6263
extern gboolean handleDeleteEvent(GtkWidget*, GdkEvent*, uintptr_t);
6364
extern gboolean handleFocusEvent(GtkWidget*, GdkEvent*, uintptr_t);
6465
extern void handleLoadChanged(WebKitWebView*, WebKitLoadEvent, uintptr_t);
@@ -1198,6 +1199,35 @@ func emit(we *C.WindowEvent) {
11981199
}
11991200
}
12001201

1202+
//export handleConfigureEvent
1203+
func handleConfigureEvent(widget *C.GtkWidget, event *C.GdkEventConfigure, data C.uintptr_t) C.gboolean {
1204+
window := globalApplication.getWindowForID(uint(data))
1205+
if window != nil {
1206+
lw, ok := window.(*WebviewWindow).impl.(*linuxWebviewWindow)
1207+
if !ok {
1208+
return C.gboolean(1)
1209+
}
1210+
if lw.lastX != int(event.x) || lw.lastY != int(event.y) {
1211+
lw.moveDebouncer(func() {
1212+
processWindowEvent(C.uint(data), C.uint(events.Linux.WindowDidMove))
1213+
})
1214+
}
1215+
1216+
if lw.lastWidth != int(event.width) || lw.lastHeight != int(event.height) {
1217+
lw.resizeDebouncer(func() {
1218+
processWindowEvent(C.uint(data), C.uint(events.Linux.WindowDidResize))
1219+
})
1220+
}
1221+
1222+
lw.lastX = int(event.x)
1223+
lw.lastY = int(event.y)
1224+
lw.lastWidth = int(event.width)
1225+
lw.lastHeight = int(event.height)
1226+
}
1227+
1228+
return C.gboolean(1)
1229+
}
1230+
12011231
//export handleDeleteEvent
12021232
func handleDeleteEvent(widget *C.GtkWidget, event *C.GdkEvent, data C.uintptr_t) C.gboolean {
12031233
processWindowEvent(C.uint(data), C.uint(events.Linux.WindowDeleteEvent))
@@ -1237,6 +1267,7 @@ func (w *linuxWebviewWindow) setupSignalHandlers(emit func(e events.WindowEventT
12371267
C.signal_connect(unsafe.Pointer(w.window), c.String("delete-event"), C.handleDeleteEvent, winID)
12381268
C.signal_connect(unsafe.Pointer(w.window), c.String("focus-out-event"), C.handleFocusEvent, winID)
12391269
C.signal_connect(wv, c.String("load-changed"), C.handleLoadChanged, winID)
1270+
C.signal_connect(unsafe.Pointer(w.window), c.String("configure-event"), C.handleConfigureEvent, winID)
12401271

12411272
contentManager := C.webkit_web_view_get_user_content_manager(w.webKitWebView())
12421273
C.signal_connect(unsafe.Pointer(contentManager), c.String("script-message-received::external"), C.sendMessageToBackend, nil)

Diff for: v3/pkg/application/webview_window_darwin.go

+3
Original file line numberDiff line numberDiff line change
@@ -1236,6 +1236,9 @@ func (w *macosWebviewWindow) run() {
12361236
w.parent.On(events.Mac.WindowDidResignMain, func(_ *WindowEvent) {
12371237
w.parent.emit(events.Common.WindowLostFocus)
12381238
})
1239+
w.parent.On(events.Mac.WindowDidResize, func(_ *WindowEvent) {
1240+
w.parent.emit(events.Common.WindowDidResize)
1241+
})
12391242

12401243
if options.HTML != "" {
12411244
w.setHTML(options.HTML)

Diff for: v3/pkg/application/webview_window_linux.go

+23
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,19 @@ package application
55
import "C"
66
import (
77
"fmt"
8+
"time"
89

10+
"github.com/bep/debounce"
911
"github.com/wailsapp/wails/v3/internal/assetserver"
1012
"github.com/wailsapp/wails/v3/internal/capabilities"
1113
"github.com/wailsapp/wails/v3/internal/runtime"
1214
"github.com/wailsapp/wails/v3/pkg/events"
1315
)
1416

17+
const (
18+
windowDidMoveDebounceMS = 200
19+
)
20+
1521
type dragInfo struct {
1622
XRoot int
1723
YRoot int
@@ -35,6 +41,9 @@ type linuxWebviewWindow struct {
3541
lastX, lastY int
3642
gtkmenu pointer
3743
ctxMenuOpened bool
44+
45+
moveDebouncer func(func())
46+
resizeDebouncer func(func())
3847
}
3948

4049
var (
@@ -200,6 +209,13 @@ func (w *linuxWebviewWindow) run() {
200209
w.on(eventId)
201210
}
202211

212+
if w.moveDebouncer == nil {
213+
w.moveDebouncer = debounce.New(time.Duration(windowDidMoveDebounceMS) * time.Millisecond)
214+
}
215+
if w.resizeDebouncer == nil {
216+
w.resizeDebouncer = debounce.New(time.Duration(windowDidMoveDebounceMS) * time.Millisecond)
217+
}
218+
203219
// Register the capabilities
204220
globalApplication.capabilities = capabilities.NewCapabilities()
205221

@@ -292,6 +308,13 @@ func (w *linuxWebviewWindow) run() {
292308
w.parent.On(events.Linux.WindowDeleteEvent, func(e *WindowEvent) {
293309
w.parent.emit(events.Common.WindowClosing)
294310
})
311+
w.parent.On(events.Linux.WindowDidMove, func(e *WindowEvent) {
312+
w.parent.emit(events.Common.WindowDidMove)
313+
})
314+
w.parent.On(events.Linux.WindowDidResize, func(e *WindowEvent) {
315+
w.parent.emit(events.Common.WindowDidResize)
316+
})
317+
295318
w.parent.RegisterHook(events.Linux.WindowLoadChanged, func(e *WindowEvent) {
296319
w.execJS(runtime.Core())
297320
})

Diff for: v3/pkg/application/webview_window_windows.go

+11-5
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,6 @@ package application
55
import (
66
"errors"
77
"fmt"
8-
"github.com/wailsapp/wails/v3/internal/assetserver"
9-
"github.com/wailsapp/wails/v3/internal/runtime"
108
"net/url"
119
"strconv"
1210
"strings"
@@ -18,8 +16,10 @@ import (
1816

1917
"github.com/bep/debounce"
2018
"github.com/wailsapp/go-webview2/webviewloader"
19+
"github.com/wailsapp/wails/v3/internal/assetserver"
2120
"github.com/wailsapp/wails/v3/internal/assetserver/webview"
2221
"github.com/wailsapp/wails/v3/internal/capabilities"
22+
"github.com/wailsapp/wails/v3/internal/runtime"
2323

2424
"github.com/samber/lo"
2525

@@ -1024,6 +1024,7 @@ func (w *windowsWebviewWindow) WndProc(msg uint32, wparam, lparam uintptr) uintp
10241024
InvokeSync(func() {
10251025
w.chromium.Resize()
10261026
})
1027+
w.parent.emit(events.Windows.WindowDidResize)
10271028
})
10281029
} else {
10291030
w.chromium.Resize()
@@ -1418,9 +1419,6 @@ func (w *windowsWebviewWindow) setupChromium() {
14181419
w.dropTarget.OnOver = func() {
14191420
w.parent.emit(events.Windows.WindowDragOver)
14201421
}
1421-
w.parent.On(events.Windows.WindowDidMove, func(e *WindowEvent) {
1422-
w.parent.emit(events.Common.WindowDidMove)
1423-
})
14241422
// Enumerate all the child windows for this window and register them as drop targets
14251423
w32.EnumChildWindows(w.hwnd, func(hwnd w32.HWND, lparam w32.LPARAM) w32.LRESULT {
14261424
// Check if the window class is "Chrome_RenderWidgetHostHWND"
@@ -1438,6 +1436,14 @@ func (w *windowsWebviewWindow) setupChromium() {
14381436

14391437
}
14401438

1439+
// event mapping
1440+
w.parent.On(events.Windows.WindowDidMove, func(e *WindowEvent) {
1441+
w.parent.emit(events.Common.WindowDidMove)
1442+
})
1443+
w.parent.On(events.Windows.WindowDidResize, func(e *WindowEvent) {
1444+
w.parent.emit(events.Common.WindowDidResize)
1445+
})
1446+
14411447
// We will get round to this
14421448
//if chromium.HasCapability(edge.AllowExternalDrop) {
14431449
// err := chromium.AllowExternalDrag(w.parent.options.EnableDragAndDrop)

0 commit comments

Comments
 (0)