Skip to content

Global hotkeys unregistered after AEAssessmentSession begins on macOS #8358

Description

@OGalbert

Environment

  • NW.js version: [0.106.1]
  • OS: macOS Tahoe (26.0.0+)

Background

When NW.js enters kiosk mode on macOS, it starts an AEAssessmentSession (added in commit 8c5661a). This session starts asynchronously — assessmentSessionDidBegin fires once the OS has finished setting up the restricted environment.

We register global hotkeys via nw.App.registerGlobalHotKey() before kiosk mode is entered. After AEAssessmentSession begins, these hotkeys appear to stop firing. We can reregister the global hotkey again after the AEAssessment is activated.

The observation

After calling enterKioskMode(), previously registered global hotkeys become unresponsive. Re-registering them after a hardcoded delay of ~3 seconds restores the expected behavior:

To reproduce

// Register a global hotkey BEFORE entering kiosk mode
const shortcut = new nw.Shortcut({
    key: 'Ctrl+Shift+A',
    active: () => console.log('Hotkey fired!'),
    failed: (msg) => console.error('Hotkey registration failed:', msg)
});

nw.App.registerGlobalHotKey(shortcut);
console.log('Hotkey registered.');

// Enter kiosk mode (triggers AEAssessmentSession on macOS)
nw.Window.get().enterKioskMode();
console.log('Kiosk mode entered.');

// Result: hotkey stops firing once AEAssessmentSession initializes (~1-3s after enterKioskMode)
// Expectattion: hotkeys remaining active

To trigger the AEAssessmentSession it is required for have correct Apple Entitlements and sign the ap with those.

Typical work-around

nw.Window.get().enterKioskMode();
setTimeout(() => {
    // Re-register global hotkeys here.
    // Without this delay, hotkeys registered before kiosk mode do not fire.
    reRegisterHotkeys();
}, 3000 );

A delay of 3 seconds, which I found empirically, works.

My guess what is happening, and it would be nice to have confirmation

My guess is that when AEAssessmentSession begins, Apple's OS-level lockdown resets or invalidates the Carbon RegisterEventHotKey registrations that back nw.App.registerGlobalHotKey(). Re-registering after the session is fully active restores them.

However, I am not certain:

  • Is this actually what is happening at the NW.js / Carbon level?
  • Or is something else in the kiosk mode initialization clearing the hotkeys?

So far the the work-around satisfies our needs but at the same time I would like to understand what is exactly going on.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions