mirror of
https://github.com/kunkundi/crossdesk.git
synced 2026-11-13 20:25:53 +08:00
[feat] activate existing window on duplicate launches, refs #119
This commit is contained in:
1 parent
34eb2b1fe3
commit
02c3952be0
12 files changed
+819
-28
No files matched your search
@@ -33,6 +33,7 @@ class MacTray {
|
||||
|
||||
void MinimizeToTray();
|
||||
void RemoveTrayIcon();
|
||||
bool TakeReopenRequest();
|
||||
|
||||
private:
|
||||
std::unique_ptr<MacTrayImpl> impl_;
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
#include <SDL3/SDL.h>
|
||||
|
||||
#import <Cocoa/Cocoa.h>
|
||||
#import <CoreServices/CoreServices.h>
|
||||
|
||||
#include "localization.h"
|
||||
|
||||
@@ -16,6 +17,8 @@
|
||||
- (void)showMainWindow:(id)sender;
|
||||
- (void)openSettings:(id)sender;
|
||||
- (void)exitApplication:(id)sender;
|
||||
- (void)reopenApplication:(NSAppleEventDescriptor *)event
|
||||
withReply:(NSAppleEventDescriptor *)reply;
|
||||
@end
|
||||
|
||||
namespace crossdesk {
|
||||
@@ -28,6 +31,7 @@ struct MacTrayImpl {
|
||||
language_index(language_index_value),
|
||||
target([[CrossDeskMacTrayTarget alloc] initWithOwner:this]) {
|
||||
EnsureStatusItem();
|
||||
InstallReopenHandler();
|
||||
}
|
||||
|
||||
explicit MacTrayImpl(std::function<void()> show_window_callback,
|
||||
@@ -43,9 +47,13 @@ struct MacTrayImpl {
|
||||
language_index(language_index_value),
|
||||
target([[CrossDeskMacTrayTarget alloc] initWithOwner:this]) {
|
||||
EnsureStatusItem();
|
||||
InstallReopenHandler();
|
||||
}
|
||||
|
||||
~MacTrayImpl() {
|
||||
[[NSAppleEventManager sharedAppleEventManager]
|
||||
removeEventHandlerForEventClass:kCoreEventClass
|
||||
andEventID:kAEReopenApplication];
|
||||
RemoveTrayIcon();
|
||||
target = nil;
|
||||
}
|
||||
@@ -156,7 +164,28 @@ struct MacTrayImpl {
|
||||
[NSApp activateIgnoringOtherApps:YES];
|
||||
}
|
||||
|
||||
void RequestReopen() { reopen_requested = true; }
|
||||
bool TakeReopenRequest() {
|
||||
if (!reopen_handler_ready) {
|
||||
// AppKit may replace handlers even after its did-finish-launching
|
||||
// notification. The first GUI tick runs after finishLaunching returns.
|
||||
InstallReopenHandler();
|
||||
reopen_handler_ready = true;
|
||||
}
|
||||
return std::exchange(reopen_requested, false);
|
||||
}
|
||||
|
||||
private:
|
||||
void InstallReopenHandler() {
|
||||
// Finder/Dock normally sends a reopen Apple event instead of launching a
|
||||
// second process. Queue it for the UI tick, just like the IPC notification.
|
||||
[[NSAppleEventManager sharedAppleEventManager]
|
||||
setEventHandler:target
|
||||
andSelector:@selector(reopenApplication:withReply:)
|
||||
forEventClass:kCoreEventClass
|
||||
andEventID:kAEReopenApplication];
|
||||
}
|
||||
|
||||
void EnsureStatusItem() {
|
||||
if (status_item) {
|
||||
return;
|
||||
@@ -265,6 +294,8 @@ struct MacTrayImpl {
|
||||
int language_index = 0;
|
||||
NSStatusItem *status_item = nil;
|
||||
CrossDeskMacTrayTarget *target = nil;
|
||||
bool reopen_requested = false;
|
||||
bool reopen_handler_ready = false;
|
||||
};
|
||||
|
||||
MacTray::MacTray(::SDL_Window *app_window, const std::string &tooltip,
|
||||
@@ -285,8 +316,12 @@ MacTray::MacTray(std::function<void()> show_window,
|
||||
MacTray::~MacTray() = default;
|
||||
|
||||
void MacActivateWindow(void *appkit_view) {
|
||||
// IPC/Finder activation bypasses the tray's ShowWindow(), including when
|
||||
// MinimizeToTray() previously removed the app from the Dock.
|
||||
[NSApp setActivationPolicy:NSApplicationActivationPolicyRegular];
|
||||
NSView *view = (__bridge NSView *)appkit_view;
|
||||
NSWindow *window = [view window];
|
||||
[window deminiaturize:nil];
|
||||
[NSApp activateIgnoringOtherApps:YES];
|
||||
[window makeKeyAndOrderFront:nil];
|
||||
}
|
||||
@@ -295,6 +330,8 @@ void MacTray::MinimizeToTray() { impl_->MinimizeToTray(); }
|
||||
|
||||
void MacTray::RemoveTrayIcon() { impl_->RemoveTrayIcon(); }
|
||||
|
||||
bool MacTray::TakeReopenRequest() { return impl_->TakeReopenRequest(); }
|
||||
|
||||
} // namespace crossdesk
|
||||
|
||||
@implementation CrossDeskMacTrayTarget {
|
||||
@@ -317,6 +354,13 @@ void MacTray::RemoveTrayIcon() { impl_->RemoveTrayIcon(); }
|
||||
owner_->ShowMenu();
|
||||
}
|
||||
|
||||
- (void)reopenApplication:(NSAppleEventDescriptor *)event
|
||||
withReply:(NSAppleEventDescriptor *)reply {
|
||||
(void)event;
|
||||
(void)reply;
|
||||
if (owner_) owner_->RequestReopen();
|
||||
}
|
||||
|
||||
- (void)exitApplication:(id)sender {
|
||||
(void)sender;
|
||||
if (owner_) {
|
||||
|
||||
Reference in new issue
Block a user