Browser Password Fields in Monterey+ breaks app hotkey activation

I have an Objective-C App that has worked perfectly until Monterey was released. The app is activated and displays a window when it’s hotkey is typed. The problem is that—starting in Monterey—if the cursor is in an html Password field of ANY website in ANY browser, the app’s window does not display. After many many hours of debugging, I have determined that the problem is that in this case, [NSApp activateIgnoringOtherApps:YES] never activates the app, and that [myWindow makeKeyAndOrderFront:nil] does nothing. In this case, if I display a window using [NSApp runModalForWindow:myWindow], the window does display, but is not key until it is clicked, at which point the app activates.

Note that everything works properly with the cursor in any browser field other than a Password field, or in any other app. It also works with the cursor anywhere in MacOS versions 10.12 through 11.

Is this is some kind of new security feature? Is this a bug or is there a workaround for this? I there a low-level non-Cocoa way to activate an app?

I tried SetFrontProcess to activate the app. It does not work either if the cursor is in a Password dfield.

Have you tried this on macOS 14? It’s quite possible that it’s ever worse (from your perspective :-) over there. See the discussion of the NSApplication.yield(to:) method in AppKit Release Notes for macOS 14 and WWDC 2023 Session 10054 What’s new in AppKit.

Does this only affect web browsers? Or is it tied to secure input mode? If you do this in Terminal:

% sudo -k -s
Password:

do you see the problem there as well?

In the above example, I’m using -k to ignore any cached credential so sudo always prompts for your password. In Terminal, the cursor changes to a little lock icon to indicate that you’re in secure input mode.

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

My app has LSUIElement set to YES. If I change that to NO, there is a Dock tile for the app. If I click on the dock tile while in secure input mode, the app does become actove. So I now it can bw made active (the dock can do it) . But how can I programatically make it active when neither [NSApp activateIgnoringOtherApps:YES] (pre macOS14) nor [NSApp activate] (macOS 14) work?

So I now it can bw made active (the dock can do it).

Keep in mind that the Dock is part of macOS and thus has access to functionality that’s not available to apps.

As explained in that WWDC talk, Apple is trying to tidy up the app switching behaviour of macOS. The current behaviour is particularly problematic when apps yank themselves to the front while you’re typing into a password field, so I’m not 100% surprised by the behaviour you’re seeing.

I’m not sure if there’s any way to resolve this. Let me ask you more about the big picture here. You wrote:

the app’s window does not display.

Doesn’t display at all? Or doesn’t come to the front? Or doesn’t become the key window?

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

The app's window does not display at all. The issue not that it is behind something. If I display the window with [NSApp runModalForWindow:window], it does display--on top--but is not key, If I then click on it it becomes key. I just did that as a test, as I do not want to run modally.

I suspect that you might be hitting a limitation for which there is no good workaround right now (r. 118404381). The issue is that the system code that prevents apps stealing keyboard focus is not aware that your app is being driven by a user action.

However, I’m not 100% certain that’s the case. It might be worthwhile for you to open a DTS tech support incident so our AppKit specialist can take a more in-depth look.

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

Thanks for your help. I came up with a kludgey partial workaround, which I offer here in case it helps somebody else.

Instead of:

[window makeKeyAndOrderFront:self];

I coded:

NSTimer *stopModalTimer = [NSTimer scheduledTimerWithTimeInterval:.25 target:NSApp selector:@selector(stopModal) userInfo:nil repeats:NO];
[[NSRunLoop currentRunLoop] addTimer:stopModalTimer forMode:NSModalPanelRunLoopMode];
[NSApp runModalForWindow:window];

This displays the window then turns off modal mode. However, the window is not key until clicked on.

Browser Password Fields in Monterey+ breaks app hotkey activation
 
 
Q