隐藏底座图标而不隐藏菜单栏 [英] Hiding the dock icon without hiding the menu bar

查看:110
本文介绍了隐藏底座图标而不隐藏菜单栏的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用中的想法此线程以可选方式隐藏我的应用程序的停靠图标 。如果毕竟显示了停靠图标,则菜单栏也应显示。仅使用 Jiulong的答案,我才无法完成这项工作。菜单栏仍然处于隐藏状态。



因此,基本上,应用程序是代理在InfoPList中设置为 1,并且使用了以下代码:

  if(![[NSUserDefaults standardUserDefaults] boolForKey:@ LaunchAsAgentApp]){
ProcessSerialNumber psn = {0,kCurrentProcess};
TransformProcessType(& psn,kProcessTransformToForegroundApplication);
SetSystemUIMode(kUIModeNormal,0);
[[NSWorkspace sharedWorkspace] launchAppWithBundleIdentifier:@ com.apple.dock选项:NSWorkspace启动默认的其他事件参数描述符:nil launchIdentifier:nil];
[[NSApplication sharedApplication] activateIgnoringOtherApps:TRUE];
}

为什么菜单栏不显示,直到我隐藏并重新聚焦该应用程序?有没有解决办法?我发现适用于Mac应用程序的快速搜索框 没有显示启动菜单栏...






编辑:我联系了Apple,他们给了我是碳和非碳溶液。给定一个新项目,在Plist文件中将 Application is Agent设置为 YES,则可以在 AppDelegate 类中使用此代码:

  #define USE_CARBON 0 

//
//注意:NSLogDebug是在预编译的项目中定义的( .pch)file
//

@implementation AppDelegate
{
BOOL show_icon;
}

//应用程序将完成启动
-(void)applicationWillFinishLaunching:(NSNotification *)notification {
NSLogDebug();
NSURL * receiptUrl = [[NSBundle mainBundle] appStoreReceiptURL];
if(![[[NSFileManager defaultManager] fileExistsAtPath:[receiptUrl path]]){
// exit(173);
}

#if 1
show_icon = YES;
#else
NSUserDefaults * userDefaults = [NSUserDefaults standardUserDefaults];
NSString * hasDockIconDefaultsKey = @是否有Dock图标?;
//注意:每次运行时切换值(通常从用户偏好的面板设置)
show_icon = [userDefaults boolForKey:hasDockIconDefaultsKey];
[userDefaults setBool:!show_icon forKey:hasDockIconDefaultsKey];
#endif //如果1
if(show_icon){
[NSApp setActivationPolicy:NSApplicationActivationPolicyRegular];
[NSApp setPresentationOptions:NSApplicationPresentationDefault];
[NSMenu setMenuBarVisible:NO];
[NSMenu setMenuBarVisible:YES];
}

[NSApp activateIgnoringOtherApps:YES];
} // applicationWillFinishLaunching

//应用程序确实完成了启动
-(void)applicationDidFinishLaunching:(NSNotification *)aNotification {
NSLogDebug();
//在此处插入代码以初始化应用程序
if(show_icon){
#if USE_CARBON
ProcessSerialNumber psn = {0,kCurrentProcess};
OSStatus returnCode = TransformProcessType(& psn,kProcessTransformToForegroundApplication);
if(noErr!= returnCode){
NSLog(@ TransformProcessType错误:%d(0x%0X),returnCode,returnCode);
}

ProcessSerialNumber psnx = {0,kNoProcess};
GetNextProcess(& psnx);
SetFrontProcess(& psnx);
#else //如果为0
NSWorkspace * sharedWorkspace = [NSWorkspace sharedWorkspace];
NSRunningApplication * menuBarOwningApplication = [sharedWorkspace menuBarOwningApplication];
(无效)[menuBarOwningApplication activateWithOptions:NSApplicationActivateIgnoringOtherApps];
#endif
[self performSelector:@selector(setFront)withObject:nil afterDelay:0。];
}
} // applicationDidFinishLaunching

//关闭主窗口时关闭应用程序
-(BOOL)applicationShouldTerminateAfterLastWindowClosed:(NSApplication *)sender {
返回(是);
}

-(void)setFront;
{
#if USE_CARBON
ProcessSerialNumber psn = {0,kCurrentProcess};
SetFrontProcess(& psn);
#else //如果是USE_CARBON
[[NSRunningApplication currentApplication] activateWithOptions:NSApplicationActivateIgnoringOtherApps];
#endif // USE_CARBON
}

@end

请注意,我也提交了错误报告。



这是非碳解决方案的Swift版本:

  func applicationWillFinishLaunching(_通知:通知){
if showIcon {
NSApp.setActivationPolicy(.regular)
NSApp.presentationOptions = []
NSMenu.setMenuBarVisible(false)
NSMenu.setMenuBarVisible(true)
}
NSApp.activate(ignoringOtherApps:true)
}

func applicationDidFinishLaunching(_ aNotification:Notification){
NSApplication.shared.activate(ignoringOtherApps:true)
if showIcon {
让工作空间= NSWorkspace.shared
让应用程序= workspace.menuBarOwningApplication
application?.activate(选项:.activateIgnoringOtherApps)
self.perform(#selector(activate),使用:nil,afterDelay:0.0)
}
}

@objc private func activate(){
NSRunningApplication.current.activate(options:.activateIgnoringOtherApps)
}


解决方案

首先,您应该使用-[NSApplication setActivationPolicy:] 而不是 TransformProcessType()-[NSApplication setPresentationOptions:] 而不是 SetSystemUIMode() 的现代代码。如果切换到这些菜单不足以解决菜单栏不更新的问题,建议您尝试使用 -setPresentationOptions: + [NSMenu setMenuBarVisible:] 隐藏菜单栏,然后​​立即撤消该操作。



此外,尝试激活Dock放弃该业务。 / p>

因此,类似于:

  if(![[NSUserDefaults standardUserDefaults ] boolForKey:@ LaunchAsAgentApp]){
[NSApp setActivationPolicy:NSApplicationActivationPolicyRegular];
[NSApp setPresentationOptions:NSApplicationPresentationDefault]; //可能没有必要,因为它是默认的
[NSMenu setMenuBarVisible:NO]; //这两行也可能不是必需的;使用-setActivationPolicy:而不是TransformProcessType()可能就足够
[NSMenu setMenuBarVisible:YES];
}


I use the ideas in this thread to hide the dock icon of my app optionally. If the dock icon is shown after all, the menu bar should be shown too. Only with Jiulong's answer I haven't been able to make this work. The menu bar is still hidden.

So basically 'Application is agent' is set to '1' in the InfoPList, and this code is used :

if (![[NSUserDefaults standardUserDefaults] boolForKey:@"LaunchAsAgentApp"]) {   
    ProcessSerialNumber psn = { 0, kCurrentProcess };
    TransformProcessType(&psn, kProcessTransformToForegroundApplication);
    SetSystemUIMode(kUIModeNormal, 0);
    [[NSWorkspace sharedWorkspace] launchAppWithBundleIdentifier:@"com.apple.dock"    options:NSWorkspaceLaunchDefault additionalEventParamDescriptor:nil launchIdentifier:nil];
    [[NSApplication sharedApplication] activateIgnoringOtherApps:TRUE];
}

So why doesn't the menu bar show up, until I hide and refocus the app? Is there any fix for this? I saw that the 'Quick Search Box' for mac app doesn't show the menu bar upon launching either...


EDIT : I contacted Apple, and they gave me a carbon and a non-carbon solution. Given a new project with 'Application is Agent' set to 'YES' in the Plist file, then this code could be used in the AppDelegate class :

#define USE_CARBON  0

//
//  Note: NSLogDebug is defined in the projects pre-compiled (.pch) file
//

@implementation AppDelegate
{
    BOOL show_icon;
}

// Application will finish launching
- (void)applicationWillFinishLaunching:(NSNotification *)notification {
    NSLogDebug();
    NSURL *receiptUrl = [[NSBundle mainBundle] appStoreReceiptURL];
    if (![[NSFileManager defaultManager] fileExistsAtPath:[receiptUrl path]]) {
        // exit(173);
    }

#if 1
    show_icon = YES;
#else
    NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
    NSString *hasDockIconDefaultsKey = @"Has Dock Icon?";
    // note: toggles value on each run (normally set from user pref pannel)
    show_icon = [userDefaults boolForKey:hasDockIconDefaultsKey];
    [userDefaults setBool:!show_icon forKey:hasDockIconDefaultsKey];
#endif // if 1
    if (show_icon) {
        [NSApp setActivationPolicy:NSApplicationActivationPolicyRegular];
        [NSApp setPresentationOptions:NSApplicationPresentationDefault];
        [NSMenu setMenuBarVisible:NO];
        [NSMenu setMenuBarVisible:YES];
    }

    [NSApp activateIgnoringOtherApps:YES];
}   // applicationWillFinishLaunching

// Application did finish launching
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification {
    NSLogDebug();
    // Insert code here to initialize your application
    if (show_icon) {
#if USE_CARBON
        ProcessSerialNumber psn = {0, kCurrentProcess};
        OSStatus returnCode = TransformProcessType(&psn, kProcessTransformToForegroundApplication);
        if (noErr != returnCode) {
            NSLog(@"TransformProcessType error: %d (0x%0X)", returnCode, returnCode);
        }

        ProcessSerialNumber psnx = {0, kNoProcess};
        GetNextProcess(&psnx);
        SetFrontProcess(&psnx);
#else   // if 0
        NSWorkspace *sharedWorkspace = [NSWorkspace sharedWorkspace];
        NSRunningApplication * menuBarOwningApplication = [sharedWorkspace menuBarOwningApplication];
        (void) [menuBarOwningApplication activateWithOptions:NSApplicationActivateIgnoringOtherApps];
#endif
        [self performSelector:@selector(setFront) withObject:nil afterDelay:0.];
    }
}   // applicationDidFinishLaunching

// Close app when main window is closed
- (BOOL)applicationShouldTerminateAfterLastWindowClosed:(NSApplication *)sender {
    return (YES);
}

- (void)setFront;
{
#if USE_CARBON
    ProcessSerialNumber psn = {0, kCurrentProcess};
    SetFrontProcess(&psn);
#else // if USE_CARBON
    [[NSRunningApplication currentApplication] activateWithOptions:NSApplicationActivateIgnoringOtherApps];
#endif  // USE_CARBON
}

@end

Note that I filed a bug report too.

Here's a Swift version of the non-carbon solution :

func applicationWillFinishLaunching(_ notification: Notification) {
    if  showIcon {
        NSApp.setActivationPolicy(.regular)
        NSApp.presentationOptions = []
        NSMenu.setMenuBarVisible(false)
        NSMenu.setMenuBarVisible(true)
    }
    NSApp.activate(ignoringOtherApps: true)
}

func applicationDidFinishLaunching(_ aNotification: Notification) {
    NSApplication.shared.activate(ignoringOtherApps: true)
    if  showIcon {
        let workspace = NSWorkspace.shared
        let application = workspace.menuBarOwningApplication
        application?.activate(options: .activateIgnoringOtherApps)
        self.perform(#selector(activate), with: nil, afterDelay: 0.0)
    }
}

@objc private func activate() {  
    NSRunningApplication.current.activate(options: .activateIgnoringOtherApps)
}

解决方案

First, you should use -[NSApplication setActivationPolicy:] rather than TransformProcessType() and -[NSApplication setPresentationOptions:] rather than SetSystemUIMode() in modern code. If switching to those is not enough to fix the problem with the menu bar not updating, I recommend that you try using -setPresentationOptions: or +[NSMenu setMenuBarVisible:] to hide the menu bar and then immediately reverse that operation.

Also, drop that business with trying to activate the Dock.

So, something like:

if (![[NSUserDefaults standardUserDefaults] boolForKey:@"LaunchAsAgentApp"]) {
    [NSApp setActivationPolicy:NSApplicationActivationPolicyRegular];
    [NSApp setPresentationOptions:NSApplicationPresentationDefault]; // probably not necessary since it's the default
    [NSMenu setMenuBarVisible:NO]; // these two lines may not be necessary, either; using -setActivationPolicy: instead of TransformProcessType() may be enough
    [NSMenu setMenuBarVisible:YES];
}

这篇关于隐藏底座图标而不隐藏菜单栏的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆