获得以前最前面的应用程序

时间:2014-07-13 07:40:41

标签: objective-c cocoa swift

好吧,我在这里难过。我正在编写一个小实用程序,需要在程序启动之前知道最前面的应用程序是什么。我试过这个:

var thePreviousApp:NSRunningApplication = NSWorkspace.sharedWorkspace().frontmostApplication

override func awakeFromNib()
{
    thePreviousApp = NSWorkspace.sharedWorkspace().frontmostApplication
}

当我从Xcode运行时它起作用(即它将PreviousApp设置为“Xcode”)但是当我从Finder或Launchpad运行二进制文件时,它返回我的程序的名称,而不是程序启动前最前面的程序。

为了它的价值,我可以通过将它放在AppDelegate中来获得以前的应用程序:

var thePreviousApp:NSRunningApplication = NSWorkspace.sharedWorkspace().frontmostApplication

 func applicationDidResignActive(notification: NSNotification!)
 {
    thePreviousApp = NSWorkspace.sharedWorkspace().frontmostApplication
 }

如果我启动程序,然后点击命令选项卡激活上一个程序,再点击命令选项卡激活我的程序,则前一个应用程序是正确的。

我还尝试获取runningApplications数组是NSWorkspace,然后迭代它们来检查哪个程序是“活动的”。再一次,没有骰子。同样的问题。

任何建议都将受到赞赏。

谢谢, 汤姆

4 个答案:

答案 0 :(得分:1)

对于那些想知道的人来说,这就是我最终所做的。我在AppDelegate中创建了一个名为thePreviousApp的属性。然后创建了一个观察者对象:

import Foundation
import Cocoa

class theObserver: NSObject
{
    override init() {
        super.init()
        NSWorkspace.sharedWorkspace().notificationCenter.addObserver(self, selector: "setPreviousApplication:", name: NSWorkspaceDidDeactivateApplicationNotification, object: nil)
    }

    func setPreviousApplication(notification: NSNotification!)
    {
        let theAppDelegate:AppDelegate=NSApplication.sharedApplication().delegate as AppDelegate
        theAppDelegate.thePreviousApp = notification.userInfo[NSWorkspaceApplicationKey] as NSRunningApplication
    }
}

此对象在AppDelegate中实例化。

感谢Mr.Asterico的帮助。

汤姆

答案 1 :(得分:1)

我找到了一种方法,可以在正确的zPositions中运行Application-Windows:

让windowNumbers = NSWindow.windowNumbersWithOptions(NSWindowNumberListAllSpaces | NSWindowNumberListAllApplications as NSWindowNumberListOptions)

它将返回一个带有windowNumbers的数组,并与CGWindowListCopyWindowInfos进行比较,现在它们的顺序正确。从前到后。

因为它们只是windowIds,你仍然需要在CGWindowListCopyWindowInfos数组/字典中进行查找以获取详细信息。

但它有效!它将返回比明显可见窗口更多的Windows,但您可以使用windowName!=“”和其他过滤器(如size>)过滤它们。 32x32(跳过菜单栏)

答案 2 :(得分:0)

我不知道为什么你应该做这样的事情,但我能想到的唯一方法是使用NSWorkspace通知(NSWorkspaceDidDeactivateApplicationNotification)。

您必须在该通知上注册一个对象作为观察者,然后使用通知对象获取已停用的应用程序。

使用您的代码,您始终可以获得应用程序,因为在引发applicationDidResignActive通知的同一时刻,frontmostApplication()不会更新。

答案 3 :(得分:0)

我想是一个想法是阅读最近使用过的Windows列表 至少zposition应该是有序的,因为应用程序总是被排序到前面(前面排序) 因此,您的“最后”应用应位于列表旁边。

你将从窗口列表中取出第二个程序,因为你现在位于堆栈顶部 如果你没有gui开始,例如。隐藏所有窗口,最后一个应用程序可能仍然在堆栈顶部 CGWindowListCopyWindowInfo为您提供所有正在运行的应用程序的列表,甚至包括通知中心或桌面图像和菜单栏等隐藏的应用程序。

更新:runningApplications列表是按随机顺序排列的,而不是zPositions的顺序,所以这个想法不起作用。