Cocoa - 以编程方式去前台/后台 [英] Cocoa - go to foreground/background programmatically

查看:469
本文介绍了Cocoa - 以编程方式去前台/后台的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个应用程序LSUIElement设置为1.它有一个内置的编辑器,所以我希望应用程序出现在Cmd + Tab周期中,当编辑器打开。

   - (void)stepIntoForeground 
{
if(NSAppKitVersionNumber if(counter == 0){
ProcessSerialNumber psn = {0,kCurrentProcess};
OSStatus osstatus = TransformProcessType(& psn,kProcessTransformToForegroundApplication);
if(osstatus == 0){
++ counter;
} else {
// ...
}
}
}
- (void)stepIntoBackground
{
if (NSAppKitVersionNumber if(counter == 0)return;

if(counter == 1){
ProcessSerialNumber psn = {0,kCurrentProcess};
OSStatus osstatus = TransformProcessType(& psn,kProcessTransformToUIElementApplication);
if(osstatus == 0){
--counter;
} else {
// ..
}
}
}

问题是:




  • 还有一个Dock图标>
  • 还有Menu,这也不是什么大问题,但它们并不总是出现。



有什么方法可以禁用菜单或使它总是出现在前台?先感谢。

解决方案

这是我们的做法。
(Works 10.7 +)


  1. 请勿在应用程式中使用LSBackgroundOnly NOR LSUIElement

  2. 添加并初始化您的菜单和NSStatusBar菜单

  3. 应用程序初始化后,但尚未显示任何窗口,您可能希望显示第一个窗口。我们使用applicationDidFinishLaunching。




    • 如果您不希望在应用初始化后显示任何窗口,请使用



      [NSApp setActivationPolicy:NSApplicationActivationPolicyProhibited];



      否则非常正确



      [NSApp setActivationPolicy:NSApplicationActivationPolicyAccessory];


    • 如果您应该在应用初始化完成后打开任何窗口,而不是只显示主窗口



  4. 保持您的窗口列表(fe使用窗口控制器)


  5. 如果最后一个窗口关闭,请调用



    [NSApp setActivationPolicy:NSApplicationActivationPolicyProhibited];



    在10.9你可以使用, / p>

    [NSApp setActivationPolicy:NSApplicationActivationPolicyAccessory];


  6. p>下次显示第一个窗口时,调用



    [NSApp setActivationPolicy:NSApplicationActivationPolicyRegular];



    [NSApp activateIgnoringOtherApps:YES];



    [[self window] makeKeyAndOrderFront:nil];


如果最后一个应用程序窗口关闭只有您的NSStatusBar元素保持。


$。如果至少一个应用程序窗口可见,您将有菜单,与状态信号的dock图标和cmd + tab元素。 b $ b

已知问题:




  • 第一步很重要,因为如果没有系统模态对话框(fe您的应用程序从网上下载并被隔离,首次启动时可能会出现确认对话框,具体取决于您的安全设置)。您的第一个应用程序窗口显示后,您的应用程序可能不会拥有您的菜单。
    正常的应用程序(步骤1)开始将解决这个问题,但会导致另一个小的,你的应用程序图标可能会出现一会儿在停靠在启动时,即使你想启动没有任何窗口显示。


  • 在NSApplicationActivationPolicyRegular和NSApplicationActivationPolicyAccessory之间进行更改(或者,我们可以处理这个问题, NSApplicationActivationPolicyProhibited在OSes下面10.9)将杀死状态栏菜单元素的工具提示,工具提示将最初显示,但不会在第二次调用NSApplicationActivationPolicyAccessory - > NSApplicationActivationPolicyProhibited
    后我们找不到一个工作的解决方法为此和报告到苹果作为错误。



I have an application with LSUIElement set to 1. It has a built-in editor, so I want the application to appear in Cmd+Tab cycle when the editor is open.

    -(void)stepIntoForeground
    {
        if (NSAppKitVersionNumber < NSAppKitVersionNumber10_7) return;
        if (counter == 0) {
            ProcessSerialNumber psn = {0, kCurrentProcess};
            OSStatus osstatus = TransformProcessType(&psn, kProcessTransformToForegroundApplication);
            if (osstatus == 0) {
                ++counter;
            } else {
                //...
            }
        }
    }
    -(void)stepIntoBackground
    {
        if (NSAppKitVersionNumber < NSAppKitVersionNumber10_7) return;
        if (counter == 0) return;

        if (counter == 1) {
            ProcessSerialNumber psn = {0, kCurrentProcess};
            OSStatus osstatus = TransformProcessType(&psn, kProcessTransformToUIElementApplication);
            if (osstatus == 0) {
                --counter;
            } else {
                //..
            }
        }
    }

The problems are:

  • there's also a Dock icon (not a big deal);
  • there's also Menu, that is not a big deal too, but they appear not always.

Is there any way to disable menu at all or to make it appear always in foreground? Thanks in advance.

解决方案

This is how we do it. (Works 10.7+)

  1. DO NOT USE LSBackgroundOnly NOR LSUIElement in the app plist
  2. Add and init your menu and NSStatusBar menu
  3. After app initialized but not yet shown any window take a place where you might want to show the first window if any. We use applicationDidFinishLaunching.

    • If you do not want to show any window yet after app initialized use

      [NSApp setActivationPolicy:NSApplicationActivationPolicyProhibited];

      on 10.9 you can use at last the otherwise much correct

      [NSApp setActivationPolicy:NSApplicationActivationPolicyAccessory];

    • If you should open any window after app init finished than simply show the main window

  4. Maintain your list of windows (f.e use window controllers)

  5. If last window closed, call

    [NSApp setActivationPolicy:NSApplicationActivationPolicyProhibited];

    on 10.9 you can use at last the otherwise much correct

    [NSApp setActivationPolicy:NSApplicationActivationPolicyAccessory];

  6. When your first window shown next time, call

    [NSApp setActivationPolicy:NSApplicationActivationPolicyRegular];

    [NSApp activateIgnoringOtherApps:YES];

    [[self window] makeKeyAndOrderFront:nil];

This should do the trick, if at least one app window is visible you will have menu, dock icon with state signaled, and cmd+tab element with your app, if last app window closed only your NSStatusBar element stays.

Known issues:

  • The first step is important because without that if a system modal dialog suspend your startup (f.e. your app is downloaded from the net and become quarantined a confirmation dialog might appear at first startup depending on your security settings) your menubar might not be owned by your app after your first app window shown. Starting as normal app (step 1.) would solve this problem, but will cause another small one, your app icon might appear for a moment in the dock at startup even if you would like to startup without any window shown. (but we can deal with this, not owning the menubar was a bigger problem for us, so we choose this instead)

  • Changing between NSApplicationActivationPolicyRegular and NSApplicationActivationPolicyAccessory (or NSApplicationActivationPolicyProhibited on OSes bellow 10.9) will kill your tooltip of status bar menu element, the tooltip will be shown initially but will not ever after the second call of NSApplicationActivationPolicyAccessory -> NSApplicationActivationPolicyProhibited We could not found a working workaround for this and reported to Apple as a bug.

这篇关于Cocoa - 以编程方式去前台/后台的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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