Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 21 additions & 13 deletions crates/openlogi-agent/src/tray.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ use objc2_app_kit::{
NSWorkspaceWillSleepNotification,
};
use objc2_core_graphics::{CGDisplayIsAsleep, CGMainDisplayID};
use objc2_foundation::{NSNotification, NSString};
use objc2_foundation::{NSNotification, NSNotificationCenter, NSString};
use openlogi_core::brand::{self, DeeplinkCommand};
use openlogi_core::config::AppIcon;
use openlogi_hid::DeviceIoSignal;
Expand Down Expand Up @@ -361,9 +361,17 @@ pub fn run_app_loop(
/// emits it for maintenance DarkWake, where opening BLE HID is exactly what can
/// promote an otherwise invisible wake into a full display wake (#656).
fn install_activity_observer(signal: DeviceIoSignal) -> Retained<ActivityTarget> {
let target = ActivityTarget::new(signal);
let workspace = NSWorkspace::sharedWorkspace();
let center = workspace.notificationCenter();
install_activity_observer_on(signal, &center, &workspace)
}

fn install_activity_observer_on(
signal: DeviceIoSignal,
center: &NSNotificationCenter,
workspace: &NSWorkspace,
) -> Retained<ActivityTarget> {
let target = ActivityTarget::new(signal);
// SAFETY: AppKit exports each name as an immutable process-lifetime constant.
let system_sleep = unsafe { NSWorkspaceWillSleepNotification };
// SAFETY: AppKit exports each name as an immutable process-lifetime constant.
Expand All @@ -381,31 +389,31 @@ fn install_activity_observer(signal: DeviceIoSignal) -> Retained<ActivityTarget>
&target,
sel!(workspaceWillSleep:),
Some(system_sleep),
Some(&workspace),
Some(workspace),
);
center.addObserver_selector_name_object(
&target,
sel!(workspaceScreensDidSleep:),
Some(screen_sleep),
Some(&workspace),
Some(workspace),
);
center.addObserver_selector_name_object(
&target,
sel!(workspaceSessionDidResignActive:),
Some(session_inactive),
Some(&workspace),
Some(workspace),
);
center.addObserver_selector_name_object(
&target,
sel!(workspaceScreensDidWake:),
Some(screen_wake),
Some(&workspace),
Some(workspace),
);
center.addObserver_selector_name_object(
&target,
sel!(workspaceSessionDidBecomeActive:),
Some(session_active),
Some(&workspace),
Some(workspace),
);
}
target
Expand Down Expand Up @@ -505,10 +513,10 @@ mod tests {
#[test]
fn overlapping_suspend_sources_all_clear_before_device_io_resumes() {
let (signal, gate) = device_io_channel();
let target = install_activity_observer(signal);
target.finish_startup(false);
let workspace = NSWorkspace::sharedWorkspace();
let center = workspace.notificationCenter();
let center = NSNotificationCenter::new();
let target = install_activity_observer_on(signal, &center, &workspace);
target.finish_startup(false);

// SAFETY: AppKit exports each name as an immutable process-lifetime constant.
let system_sleep = unsafe { NSWorkspaceWillSleepNotification };
Expand Down Expand Up @@ -559,7 +567,9 @@ mod tests {
#[test]
fn startup_stays_suspended_when_the_display_is_already_asleep() {
let (signal, gate) = device_io_channel();
let target = install_activity_observer(signal);
let workspace = NSWorkspace::sharedWorkspace();
let center = NSNotificationCenter::new();
let target = install_activity_observer_on(signal, &center, &workspace);
assert!(!gate.allows_io(), "startup must fail closed");

target.finish_startup(true);
Expand All @@ -568,8 +578,6 @@ mod tests {
"an initially sleeping display must retain the suspension",
);

let workspace = NSWorkspace::sharedWorkspace();
let center = workspace.notificationCenter();
// SAFETY: AppKit exports the name as an immutable process-lifetime constant.
let screen_wake = unsafe { NSWorkspaceScreensDidWakeNotification };
// SAFETY: `workspace` is live, matches the registration filter, and
Expand Down
Loading