Skip to content

Commit ba1291c

Browse files
leaanthonytaliesin-aiCopilot
authored
feat(application): cross-platform system sleep/wake events (#5425)
* feat(application/mac): emit power events from NSWorkspace observers Mirrors the windows:APMSuspend / APMResumeAutomatic / APMResumeSuspend events that Wails v3 already raises from WM_POWERBROADCAST on Windows. NSWorkspace power notifications post to its own notification center (not the default NSNotificationCenter that NSApplicationDelegate uses) so the events are declared with the `!` suffix in events.txt to skip the delegate-selector auto-generation, and observers are wired by hand in application_darwin.go's init() alongside the existing theme-change observer on NSDistributedNotificationCenter. New events: - mac:ApplicationWillSleep (NSWorkspaceWillSleepNotification) - mac:ApplicationDidWake (NSWorkspaceDidWakeNotification) - mac:ApplicationScreensDidSleep (NSWorkspaceScreensDidSleepNotification) - mac:ApplicationScreensDidWake (NSWorkspaceScreensDidWakeNotification) Verification: compile + vet + existing unit tests pass on macOS, linux, windows. Runtime firing of the observers is not exercised by automated tests (same gap as the rest of the AppDelegate selectors) — to be confirmed via xbar2's #807 follow-up wiring and a manual sleep test. Motivation: xbar2 needs DidWake to force a plugin refresh sweep after sleep, addressing upstream xbar issue #807 (the most-upvoted open bug). * feat(application/linux): emit sleep/wake events via logind D-Bus Adds Linux equivalents to the mac:ApplicationDidWake / WillSleep events introduced in the previous commit, completing power-event coverage across macOS, Windows, and Linux. Implementation subscribes to org.freedesktop.login1.Manager's PrepareForSleep signal on the system bus. The signal fires twice with a boolean arg — true just before suspend (→ linux:SystemWillSleep), false on resume (→ linux:SystemDidWake). The pattern mirrors monitorThemeChanges() in the same file (goroutine + AddMatchSignal + range over Signal channel), differing only in bus (system vs session) and dispatch logic. Graceful degradation: distros without logind/elogind reachable on the system bus (Alpine, Void, some Devuan setups) log a warning and the goroutine exits — the rest of the application keeps running. This matches the existing theme-monitor behaviour for missing session bus. New events: - linux:SystemWillSleep (PrepareForSleep arg=true) - linux:SystemDidWake (PrepareForSleep arg=false) Verification: darwin build + vet + tests pass. Linux cross-compile requires a GTK toolchain not available in this environment, so runtime behaviour will be confirmed when the branch is built on Linux + a manual systemctl suspend test. The function structure is a near-copy of the existing monitorThemeChanges() so the parse-time risk is low. godbus API calls (ConnectSystemBus, WithMatchInterface, WithMatchMember, WithMatchObjectPath) verified against v5.2.2 (the version in go.mod). * feat(application): expose Common.SystemWillSleep / Common.SystemDidWake Adds two cross-platform power events so apps can listen for sleep/wake once instead of branching on OS: app.OnApplicationEvent(events.Common.SystemDidWake, …) Each platform's events_common_<os>.go map gains an entry that forwards the platform-specific event into the common one (same pattern as Common.ThemeChanged and Common.ApplicationStarted): darwin: Mac.ApplicationWillSleep → Common.SystemWillSleep Mac.ApplicationDidWake → Common.SystemDidWake windows: Windows.APMSuspend → Common.SystemWillSleep Windows.APMResumeAutomatic → Common.SystemDidWake linux: Linux.SystemWillSleep → Common.SystemWillSleep Linux.SystemDidWake → Common.SystemDidWake Notes: - Windows APMResumeSuspend is deliberately not mapped — it fires *after* APMResumeAutomatic when the wake was triggered by user input, so mapping both would double-fire Common.SystemDidWake. - Mac.ApplicationScreensDidWake / ScreensDidSleep are kept platform- specific; they fire on display power state (separate from system sleep) and have no Linux/Windows equivalent. Verified: darwin build + tests pass locally; Linux build + tests pass on lin-node1; windows cross-vet of pkg/events clean. * docs(events): document system sleep/wake events Adds documentation for the new Common.SystemWillSleep / SystemDidWake events plus the macOS Mac.ApplicationWillSleep / DidWake / ScreensDidSleep / ScreensDidWake and Linux SystemWillSleep / SystemDidWake variants. - features/events/system.mdx: code examples in the Common block + the macOS and Linux platform tabs; clarifies the Windows resume choice (APMResumeAutomatic vs APMResumeSuspend). - reference/events.mdx: adds the two common events to the application- events table. - guides/events-reference.mdx: adds rows to the Common, macOS, and Linux tables; notes the logind dependency on Linux and the screen- vs-system sleep distinction on macOS. * Apply suggestions from code review Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> * fix(events): address PR review feedback Three review issues from #5425: 1. Common-event forwarding mutated the incoming *ApplicationEvent's Id before re-queuing. Because application listeners run concurrently (see EventProcessor.dispatchEventToListeners), this could race with other listeners observing the source event. Fix: emit a fresh ApplicationEvent for the common copy, sharing only ctx. Applied uniformly to all five setupCommonEvents implementations (darwin / linux / windows / ios / android) since they all had the same pattern. 2. Linux monitorPowerEvents claimed to warn and exit on systems without logind/elogind, but AddMatchSignal would succeed on any system bus and the goroutine would block forever on a channel that never receives. Probe org.freedesktop.DBus.NameHasOwner for org.freedesktop.login1 up front and warn + return if absent. Also constrain the match rule with WithMatchSender so a hostile bus name can't spoof PrepareForSleep signals (Copilot). 3. docs/guides/events-reference.mdx Windows table omitted APMResumeAutomatic. Added it with a note distinguishing it from APMResumeSuspend (CodeRabbit). Verified: darwin + linux build/test pass; dbus-send NameHasOwner returns true for org.freedesktop.login1 on the Linux test node. --------- Co-authored-by: taliesin-ai <bot@taliesin.ai> Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
1 parent 6944537 commit ba1291c

19 files changed

Lines changed: 891 additions & 645 deletions

docs/src/content/docs/features/events/system.mdx

Lines changed: 48 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -224,6 +224,17 @@ app.Event.OnApplicationEvent(events.Common.ThemeChanged, func(e *application.App
224224
app.Event.Emit("theme-changed", isDark)
225225
})
226226

227+
// System about to suspend
228+
app.Event.OnApplicationEvent(events.Common.SystemWillSleep, func(e *application.ApplicationEvent) {
229+
flushPendingWrites()
230+
})
231+
232+
// System resumed from suspend
233+
app.Event.OnApplicationEvent(events.Common.SystemDidWake, func(e *application.ApplicationEvent) {
234+
reconnectSockets()
235+
refreshState()
236+
})
237+
227238
// File opened
228239
app.Event.OnApplicationEvent(events.Common.ApplicationOpenedWithFile, func(e *application.ApplicationEvent) {
229240
filePath := e.Context().OpenedFile()
@@ -245,6 +256,22 @@ app.Event.OnApplicationEvent(events.Common.ApplicationOpenedWithFile, func(e *ap
245256
app.Event.OnApplicationEvent(events.Mac.ApplicationWillTerminate, func(e *application.ApplicationEvent) {
246257
cleanup()
247258
})
259+
260+
// System about to sleep / resumed
261+
app.Event.OnApplicationEvent(events.Mac.ApplicationWillSleep, func(e *application.ApplicationEvent) {
262+
flushPendingWrites()
263+
})
264+
app.Event.OnApplicationEvent(events.Mac.ApplicationDidWake, func(e *application.ApplicationEvent) {
265+
refreshState()
266+
})
267+
268+
// Displays sleeping/waking — distinct from system sleep (e.g. lid lowered)
269+
app.Event.OnApplicationEvent(events.Mac.ApplicationScreensDidSleep, func(e *application.ApplicationEvent) {
270+
pauseRendering()
271+
})
272+
app.Event.OnApplicationEvent(events.Mac.ApplicationScreensDidWake, func(e *application.ApplicationEvent) {
273+
resumeRendering()
274+
})
248275
```
249276
</TabItem>
250277

@@ -254,11 +281,19 @@ app.Event.OnApplicationEvent(events.Common.ApplicationOpenedWithFile, func(e *ap
254281
app.Event.OnApplicationEvent(events.Windows.APMPowerStatusChange, func(e *application.ApplicationEvent) {
255282
app.Logger.Info("Power status changed")
256283
})
257-
284+
258285
// System suspending
259286
app.Event.OnApplicationEvent(events.Windows.APMSuspend, func(e *application.ApplicationEvent) {
260287
saveState()
261288
})
289+
290+
// System resumed. APMResumeAutomatic always fires on resume;
291+
// APMResumeSuspend fires after it when the wake was triggered by
292+
// user input. Prefer Common.SystemDidWake if you don't need to
293+
// distinguish.
294+
app.Event.OnApplicationEvent(events.Windows.APMResumeAutomatic, func(e *application.ApplicationEvent) {
295+
refreshState()
296+
})
262297
```
263298
</TabItem>
264299

@@ -268,11 +303,22 @@ app.Event.OnApplicationEvent(events.Common.ApplicationOpenedWithFile, func(e *ap
268303
app.Event.OnApplicationEvent(events.Linux.ApplicationStartup, func(e *application.ApplicationEvent) {
269304
app.Logger.Info("App starting")
270305
})
271-
306+
272307
// Theme changed
273308
app.Event.OnApplicationEvent(events.Linux.SystemThemeChanged, func(e *application.ApplicationEvent) {
274309
updateTheme()
275310
})
311+
312+
// System sleep/wake — sourced from systemd-logind's PrepareForSleep
313+
// signal on the system bus. Requires logind/elogind exposing
314+
// org.freedesktop.login1, so it may be unavailable on distros/setups
315+
// without it (Alpine, Void, some Devuan setups).
316+
app.Event.OnApplicationEvent(events.Linux.SystemWillSleep, func(e *application.ApplicationEvent) {
317+
flushPendingWrites()
318+
})
319+
app.Event.OnApplicationEvent(events.Linux.SystemDidWake, func(e *application.ApplicationEvent) {
320+
refreshState()
321+
})
276322
```
277323
</TabItem>
278324
</Tabs>

docs/src/content/docs/guides/events-reference.mdx

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -423,6 +423,8 @@ These events work on all platforms:
423423
| `common:ApplicationStarted` | Application has fully started | Initialize your app, load saved state |
424424
| `common:WindowRuntimeReady` | Wails runtime is ready | Start making Wails API calls |
425425
| `common:ThemeChanged` | System theme changed | Update app appearance |
426+
| `common:SystemWillSleep` | System is about to suspend | Flush state, close sockets |
427+
| `common:SystemDidWake` | System resumed from suspend | Reconnect, refresh stale data |
426428
| `common:WindowFocus` | Window gained focus | Resume activities, refresh data |
427429
| `common:WindowLostFocus` | Window lost focus | Pause activities, save state |
428430
| `common:WindowMinimise` | Window was minimized | Pause rendering, reduce resource usage |
@@ -443,7 +445,8 @@ Key events for Windows applications:
443445
|-------|-------------|----------|
444446
| `windows:SystemThemeChanged` | Windows theme changed | Update app colors |
445447
| `windows:APMSuspend` | System suspending | Save state, pause operations |
446-
| `windows:APMResumeSuspend` | System resumed | Restore state, refresh data |
448+
| `windows:APMResumeAutomatic` | System resumed (always fires on resume) | Restore state, refresh data |
449+
| `windows:APMResumeSuspend` | System resumed via user input (after `APMResumeAutomatic`) | Distinguish user-initiated wake |
447450
| `windows:APMPowerStatusChange` | Power status changed | Adjust performance settings |
448451

449452
#### macOS Events
@@ -455,6 +458,10 @@ Important macOS application events:
455458
| `mac:ApplicationDidBecomeActive` | App became active | Resume operations |
456459
| `mac:ApplicationDidResignActive` | App became inactive | Pause operations |
457460
| `mac:ApplicationWillTerminate` | App will quit | Final cleanup |
461+
| `mac:ApplicationWillSleep` | System about to suspend | Save state, close sockets |
462+
| `mac:ApplicationDidWake` | System resumed | Reconnect, refresh |
463+
| `mac:ApplicationScreensDidSleep` | Displays went to sleep | Pause rendering (distinct from system sleep) |
464+
| `mac:ApplicationScreensDidWake` | Displays woke | Resume rendering |
458465
| `mac:WindowDidEnterFullScreen` | Entered fullscreen | Adjust UI for fullscreen |
459466
| `mac:WindowDidExitFullScreen` | Exited fullscreen | Restore normal UI |
460467

@@ -465,6 +472,8 @@ Core Linux window events:
465472
| Event | Description | Use Case |
466473
|-------|-------------|----------|
467474
| `linux:SystemThemeChanged` | Desktop theme changed | Update app theme |
475+
| `linux:SystemWillSleep` | System about to suspend (logind) | Save state |
476+
| `linux:SystemDidWake` | System resumed (logind) | Reconnect, refresh |
468477
| `linux:WindowFocusIn` | Window gained focus | Resume activities |
469478
| `linux:WindowFocusOut` | Window lost focus | Pause activities |
470479
| `linux:WindowLoadStarted` | WebView started loading | Show loading indicator |

docs/src/content/docs/reference/events.mdx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -667,6 +667,8 @@ This mapping happens automatically in the background, so when you listen for `ev
667667
| `ApplicationStarted` | Application has finished launching | After app initialization is complete and app is ready | No |
668668
| `ApplicationLaunchedWithUrl` | Application launched with a URL | When app is launched via URL scheme | No |
669669
| `ThemeChanged` | System theme changed | When OS theme switches between light/dark mode | No |
670+
| `SystemWillSleep` | System is about to suspend | Just before the OS suspends (macOS / Windows / Linux-with-logind) | No |
671+
| `SystemDidWake` | System resumed from suspend | Immediately on resume from sleep (macOS / Windows / Linux-with-logind) | No |
670672

671673
**Usage:**
672674

v3/internal/generator/collect/known_events.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@ var knownEvents = map[string]struct{}{
1010
"common:ApplicationStarted": {},
1111
"common:ApplicationLaunchedWithUrl": {},
1212
"common:ThemeChanged": {},
13+
"common:SystemDidWake": {},
14+
"common:SystemWillSleep": {},
1315
"common:WindowClosing": {},
1416
"common:WindowDidMove": {},
1517
"common:WindowDidResize": {},
@@ -33,7 +35,9 @@ var knownEvents = map[string]struct{}{
3335
"common:WindowZoomOut": {},
3436
"common:WindowZoomReset": {},
3537
"linux:ApplicationStartup": {},
38+
"linux:SystemDidWake": {},
3639
"linux:SystemThemeChanged": {},
40+
"linux:SystemWillSleep": {},
3741
"linux:WindowDeleteEvent": {},
3842
"linux:WindowDidMove": {},
3943
"linux:WindowDidResize": {},
@@ -57,11 +61,15 @@ var knownEvents = map[string]struct{}{
5761
"mac:ApplicationDidResignActive": {},
5862
"mac:ApplicationDidUnhide": {},
5963
"mac:ApplicationDidUpdate": {},
64+
"mac:ApplicationDidWake": {},
65+
"mac:ApplicationScreensDidSleep": {},
66+
"mac:ApplicationScreensDidWake": {},
6067
"mac:ApplicationShouldHandleReopen": {},
6168
"mac:ApplicationWillBecomeActive": {},
6269
"mac:ApplicationWillFinishLaunching": {},
6370
"mac:ApplicationWillHide": {},
6471
"mac:ApplicationWillResignActive": {},
72+
"mac:ApplicationWillSleep": {},
6573
"mac:ApplicationWillTerminate": {},
6674
"mac:ApplicationWillUnhide": {},
6775
"mac:ApplicationWillUpdate": {},

v3/internal/runtime/desktop/@wailsio/runtime/src/event_types.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,11 +73,15 @@ export const Types = Object.freeze({
7373
ApplicationDidResignActive: "mac:ApplicationDidResignActive",
7474
ApplicationDidUnhide: "mac:ApplicationDidUnhide",
7575
ApplicationDidUpdate: "mac:ApplicationDidUpdate",
76+
ApplicationDidWake: "mac:ApplicationDidWake",
77+
ApplicationScreensDidSleep: "mac:ApplicationScreensDidSleep",
78+
ApplicationScreensDidWake: "mac:ApplicationScreensDidWake",
7679
ApplicationShouldHandleReopen: "mac:ApplicationShouldHandleReopen",
7780
ApplicationWillBecomeActive: "mac:ApplicationWillBecomeActive",
7881
ApplicationWillFinishLaunching: "mac:ApplicationWillFinishLaunching",
7982
ApplicationWillHide: "mac:ApplicationWillHide",
8083
ApplicationWillResignActive: "mac:ApplicationWillResignActive",
84+
ApplicationWillSleep: "mac:ApplicationWillSleep",
8185
ApplicationWillTerminate: "mac:ApplicationWillTerminate",
8286
ApplicationWillUnhide: "mac:ApplicationWillUnhide",
8387
ApplicationWillUpdate: "mac:ApplicationWillUpdate",
@@ -194,7 +198,9 @@ export const Types = Object.freeze({
194198
}),
195199
Linux: Object.freeze({
196200
ApplicationStartup: "linux:ApplicationStartup",
201+
SystemDidWake: "linux:SystemDidWake",
197202
SystemThemeChanged: "linux:SystemThemeChanged",
203+
SystemWillSleep: "linux:SystemWillSleep",
198204
WindowDeleteEvent: "linux:WindowDeleteEvent",
199205
WindowDidMove: "linux:WindowDidMove",
200206
WindowDidResize: "linux:WindowDidResize",
@@ -234,6 +240,8 @@ export const Types = Object.freeze({
234240
ApplicationStarted: "common:ApplicationStarted",
235241
ApplicationLaunchedWithUrl: "common:ApplicationLaunchedWithUrl",
236242
ThemeChanged: "common:ThemeChanged",
243+
SystemDidWake: "common:SystemDidWake",
244+
SystemWillSleep: "common:SystemWillSleep",
237245
WindowClosing: "common:WindowClosing",
238246
WindowDidMove: "common:WindowDidMove",
239247
WindowDidResize: "common:WindowDidResize",

v3/pkg/application/application_darwin.go

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,15 @@ static void init(void) {
5757
NSDistributedNotificationCenter *center = [NSDistributedNotificationCenter defaultCenter];
5858
[center addObserver:appDelegate selector:@selector(themeChanged:) name:@"AppleInterfaceThemeChangedNotification" object:nil];
5959
60+
// Workspace power notifications are posted on a separate notification
61+
// center from the default one — apps must observe NSWorkspace's centre
62+
// to receive sleep/wake events. Mirrors WM_POWERBROADCAST on Windows.
63+
NSNotificationCenter *workspaceCenter = [[NSWorkspace sharedWorkspace] notificationCenter];
64+
[workspaceCenter addObserver:appDelegate selector:@selector(workspaceWillSleep:) name:NSWorkspaceWillSleepNotification object:nil];
65+
[workspaceCenter addObserver:appDelegate selector:@selector(workspaceDidWake:) name:NSWorkspaceDidWakeNotification object:nil];
66+
[workspaceCenter addObserver:appDelegate selector:@selector(workspaceScreensDidSleep:) name:NSWorkspaceScreensDidSleepNotification object:nil];
67+
[workspaceCenter addObserver:appDelegate selector:@selector(workspaceScreensDidWake:) name:NSWorkspaceScreensDidWakeNotification object:nil];
68+
6069
// Register the custom URL scheme handler
6170
StartCustomProtocolHandler();
6271
}

v3/pkg/application/application_darwin_delegate.m

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,26 @@ - (void)themeChanged:(NSNotification *)notification {
3737
processApplicationEvent(EventApplicationDidChangeTheme, NULL);
3838
}
3939
}
40+
- (void)workspaceWillSleep:(NSNotification *)notification {
41+
if( hasListeners(EventApplicationWillSleep) ) {
42+
processApplicationEvent(EventApplicationWillSleep, NULL);
43+
}
44+
}
45+
- (void)workspaceDidWake:(NSNotification *)notification {
46+
if( hasListeners(EventApplicationDidWake) ) {
47+
processApplicationEvent(EventApplicationDidWake, NULL);
48+
}
49+
}
50+
- (void)workspaceScreensDidSleep:(NSNotification *)notification {
51+
if( hasListeners(EventApplicationScreensDidSleep) ) {
52+
processApplicationEvent(EventApplicationScreensDidSleep, NULL);
53+
}
54+
}
55+
- (void)workspaceScreensDidWake:(NSNotification *)notification {
56+
if( hasListeners(EventApplicationScreensDidWake) ) {
57+
processApplicationEvent(EventApplicationScreensDidWake, NULL);
58+
}
59+
}
4060
- (NSApplicationTerminateReply)applicationShouldTerminate:(NSApplication *)sender {
4161
if( ! shouldQuitApplication() ) {
4262
return NSTerminateCancel;

v3/pkg/application/application_linux.go

Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -180,6 +180,7 @@ func (a *linuxApp) run() error {
180180
})
181181
a.setupCommonEvents()
182182
a.monitorThemeChanges()
183+
a.monitorPowerEvents()
183184
return appRun(a.application)
184185
}
185186

@@ -275,6 +276,87 @@ func (a *linuxApp) monitorThemeChanges() {
275276
}()
276277
}
277278

279+
// monitorPowerEvents subscribes to systemd-logind's PrepareForSleep signal on
280+
// the system bus and translates it into Linux.SystemWillSleep (arg=true, just
281+
// before suspend) and Linux.SystemDidWake (arg=false, immediately on resume).
282+
// Mirrors NSWorkspace willSleep/didWake on macOS and WM_POWERBROADCAST on
283+
// Windows.
284+
//
285+
// On systems without systemd or logind/elogind reachable on the system bus
286+
// (Alpine, Void, some Devuan setups), we log a warning and exit cleanly so
287+
// the rest of the app keeps working.
288+
func (a *linuxApp) monitorPowerEvents() {
289+
go func() {
290+
defer handlePanic()
291+
conn, err := dbus.ConnectSystemBus()
292+
if err != nil {
293+
a.parent.warning(
294+
"[WARNING] Failed to connect to system bus; sleep/wake events will not fire: %v",
295+
err,
296+
)
297+
return
298+
}
299+
defer conn.Close()
300+
301+
// Probe for logind/elogind ownership of org.freedesktop.login1 on the
302+
// system bus. Without this check, AddMatchSignal would succeed on any
303+
// systemd-less distro and the goroutine would block forever on a
304+
// channel that never receives — silently masking the missing service.
305+
var hasOwner bool
306+
if err := conn.BusObject().Call(
307+
"org.freedesktop.DBus.NameHasOwner", 0, "org.freedesktop.login1",
308+
).Store(&hasOwner); err != nil {
309+
a.parent.warning(
310+
"[WARNING] Failed to probe org.freedesktop.login1; sleep/wake events will not fire: %v",
311+
err,
312+
)
313+
return
314+
}
315+
if !hasOwner {
316+
a.parent.warning(
317+
"[WARNING] systemd-logind/elogind not reachable on the system bus; sleep/wake events will not fire",
318+
)
319+
return
320+
}
321+
322+
// Constrain the sender to logind's well-known name so a hostile
323+
// connection on the system bus can't spoof PrepareForSleep signals.
324+
if err = conn.AddMatchSignal(
325+
dbus.WithMatchSender("org.freedesktop.login1"),
326+
dbus.WithMatchInterface("org.freedesktop.login1.Manager"),
327+
dbus.WithMatchMember("PrepareForSleep"),
328+
dbus.WithMatchObjectPath("/org/freedesktop/login1"),
329+
); err != nil {
330+
a.parent.warning(
331+
"[WARNING] Failed to subscribe to logind PrepareForSleep; sleep/wake events will not fire: %v",
332+
err,
333+
)
334+
return
335+
}
336+
337+
c := make(chan *dbus.Signal, 4)
338+
conn.Signal(c)
339+
340+
for v := range c {
341+
if v.Name != "org.freedesktop.login1.Manager.PrepareForSleep" {
342+
continue
343+
}
344+
if len(v.Body) < 1 {
345+
continue
346+
}
347+
willSleep, ok := v.Body[0].(bool)
348+
if !ok {
349+
continue
350+
}
351+
if willSleep {
352+
applicationEvents <- newApplicationEvent(events.Linux.SystemWillSleep)
353+
} else {
354+
applicationEvents <- newApplicationEvent(events.Linux.SystemDidWake)
355+
}
356+
}
357+
}()
358+
}
359+
278360
func newPlatformApp(parent *App) *linuxApp {
279361
name := sanitizeAppName(parent.options.Name)
280362
app := &linuxApp{

v3/pkg/application/events_common_android.go

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,11 @@ func (a *androidApp) setupCommonEvents() {
1515
sourceEvent := sourceEvent
1616
targetEvent := targetEvent
1717
a.parent.Event.OnApplicationEvent(sourceEvent, func(event *ApplicationEvent) {
18-
event.Id = uint(targetEvent)
1918
androidLogf("info", "[events_common_android.go] Forwarding Android event %d → common %d", sourceEvent, targetEvent)
20-
applicationEvents <- event
19+
applicationEvents <- &ApplicationEvent{
20+
Id: uint(targetEvent),
21+
ctx: event.ctx,
22+
}
2123
})
2224
}
2325
}

v3/pkg/application/events_common_darwin.go

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,15 +7,19 @@ import "github.com/wailsapp/wails/v3/pkg/events"
77
var commonApplicationEventMap = map[events.ApplicationEventType]events.ApplicationEventType{
88
events.Mac.ApplicationDidFinishLaunching: events.Common.ApplicationStarted,
99
events.Mac.ApplicationDidChangeTheme: events.Common.ThemeChanged,
10+
events.Mac.ApplicationWillSleep: events.Common.SystemWillSleep,
11+
events.Mac.ApplicationDidWake: events.Common.SystemDidWake,
1012
}
1113

1214
func (m *macosApp) setupCommonEvents() {
1315
for sourceEvent, targetEvent := range commonApplicationEventMap {
1416
sourceEvent := sourceEvent
1517
targetEvent := targetEvent
1618
m.parent.Event.OnApplicationEvent(sourceEvent, func(event *ApplicationEvent) {
17-
event.Id = uint(targetEvent)
18-
applicationEvents <- event
19+
applicationEvents <- &ApplicationEvent{
20+
Id: uint(targetEvent),
21+
ctx: event.ctx,
22+
}
1923
})
2024
}
2125

0 commit comments

Comments
 (0)