MacOS: Only activate after the application has finished launching (#1903)
* MacOS: Only activate after the application has finished launching This fixes the main menu not responding until you refocus, at least from what I can tell - though we might have to do something similar to https://github.com/linebender/druid/pull/994 to fix it fully? * MacOS: Remove activation hack * Stop unnecessarily calling `makeKeyWindow` on initially hidden windows You can't make hidden windows the key window * Add new, simpler activation hack For activating multiple windows created before the application finished launching
This commit is contained in:
parent
45aacd8407
commit
277515636d
8 changed files with 50 additions and 289 deletions
|
|
@ -13,10 +13,11 @@ use std::{
|
|||
};
|
||||
|
||||
use cocoa::{
|
||||
appkit::{NSApp, NSWindow},
|
||||
appkit::{NSApp, NSApplication, NSWindow},
|
||||
base::{id, nil},
|
||||
foundation::{NSAutoreleasePool, NSSize},
|
||||
};
|
||||
use objc::runtime::YES;
|
||||
|
||||
use crate::{
|
||||
dpi::LogicalSize,
|
||||
|
|
@ -273,6 +274,12 @@ impl AppState {
|
|||
}
|
||||
|
||||
pub fn launched() {
|
||||
unsafe {
|
||||
let ns_app = NSApp();
|
||||
window_activation_hack(ns_app);
|
||||
// TODO: Consider allowing the user to specify they don't want their application activated
|
||||
ns_app.activateIgnoringOtherApps_(YES);
|
||||
};
|
||||
HANDLER.set_ready();
|
||||
HANDLER.waker().start();
|
||||
// The menubar initialization should be before the `NewEvents` event, to allow overriding
|
||||
|
|
@ -419,3 +426,34 @@ impl AppState {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// A hack to make activation of multiple windows work when creating them before
|
||||
/// `applicationDidFinishLaunching:` / `Event::Event::NewEvents(StartCause::Init)`.
|
||||
///
|
||||
/// Alternative to this would be the user calling `window.set_visible(true)` in
|
||||
/// `StartCause::Init`.
|
||||
///
|
||||
/// If this becomes too bothersome to maintain, it can probably be removed
|
||||
/// without too much damage.
|
||||
unsafe fn window_activation_hack(ns_app: id) {
|
||||
// Get the application's windows
|
||||
// TODO: Proper ordering of the windows
|
||||
let ns_windows: id = msg_send![ns_app, windows];
|
||||
let ns_enumerator: id = msg_send![ns_windows, objectEnumerator];
|
||||
loop {
|
||||
// Enumerate over the windows
|
||||
let ns_window: id = msg_send![ns_enumerator, nextObject];
|
||||
if ns_window == nil {
|
||||
break;
|
||||
}
|
||||
// And call `makeKeyAndOrderFront` if it was called on the window in `UnownedWindow::new`
|
||||
// This way we preserve the user's desired initial visiblity status
|
||||
// TODO: Also filter on the type/"level" of the window, and maybe other things?
|
||||
if ns_window.isVisible() == YES {
|
||||
trace!("Activating visible window");
|
||||
ns_window.makeKeyAndOrderFront_(nil);
|
||||
} else {
|
||||
trace!("Skipping activating invisible window");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue