【问题标题】:Trigger an apple script / automator when an application comes to focus in mac当应用程序在 mac 中聚焦时触发苹果脚本/自动器
【发布时间】:2021-02-05 03:11:25
【问题描述】:

我想根据应用程序自动化键盘布局。我在远程使用 Windows VM 我不想创建一个脚本,它可以:

  1. 在应用程序切换到 Windows VM 时更改键盘布局
  2. 将其更改回与所有其他应用程序一起使用的正常布局。

我很难找到有关应用程序焦点更改的触发事件。是否可以通过自动机完成?

或者,请提出其他解决方案来解决问题。

【问题讨论】:

  • 也许是 NSWorkspaceNSWorkspaceDidActivateApplicationNotificationNSWorkspaceDidDeactivateApplicationNotification 通过一些 AppleScriptObjC 通知?

标签: macos applescript automator


【解决方案1】:

假设您只有两种键盘布局,您可以使用以下脚本应用程序。

首先,您需要打开系统偏好设置并查看键盘➔快捷方式➔输入源;查看“选择上一个输入源”的键盘快捷键是什么,确保已单击它,然后将其复制到标记位置的脚本中。我将我的设置为 comd-ctrl-space (^⌘ ),但您的可能不同。您还应该检查“Windows VM”是否是应用程序的正确名称:在 Finder 中找到应用程序,选择它并键入 ⌘I 打开“获取信息”窗口,然后查看“名称和扩展名”文本框。

现在执行以下操作

  1. 在脚本编辑器中复制以下脚本
  2. 将其保存为保持打开的应用程序
    • 从左下角的“格式”菜单中选择“应用程序”
    • 点击“运行处理程序后保持打开”复选框
  3. 打开系统偏好设置并执行以下操作
    • 将应用添加到安全和隐私中的辅助功能部分➔隐私(以便它可以发送键盘快捷键)
    • 将应用添加到用户和组中您帐户的登录项部分(以便在登录时自动启动)

然后您可以运行它并进行测试。该应用程序在后台等待接收应用程序已激活或停用的通知,然后它检查应用程序名称并在 Window VM 应用程序出现或消失时触发键盘快捷键以切换输入源。

use AppleScript version "2.4"
use framework "AppKit"
use scripting additions

property NSWorkspace : class "NSWorkspace"

on run
    set workSp to NSWorkspace's sharedWorkspace()
    set notifCent to workSp's notificationCenter()
    tell notifCent to addObserver:me selector:"appHasActivated:" |name|:"NSWorkspaceDidActivateApplicationNotification" object:(missing value)
    tell notifCent to addObserver:me selector:"appHasDeactivated:" |name|:"NSWorkspaceDidDeactivateApplicationNotification" object:(missing value)
end run

on idle
    -- we don't use the idle loop, so tell the system to check in once an hour
    return 3600
end idle

on appHasActivated:notif
    set targetApp to (notif's userInfo's valueForKey:"NSWorkspaceApplicationKey")
    set targetAppName to (targetApp's localizedName) as text
    if targetAppName is "Windows VM" then
        tell application "System Events"
            tell process "Windows VM"
                -- change this line to match your 'Select previous input source' keyboard shortcut
                keystroke space using {command down, control down}
            end tell
        end tell
    end if
end appHasActivated:

on appHasDeactivated:notif
    set targetApp to (notif's userInfo's valueForKey:"NSWorkspaceApplicationKey")
    set targetAppName to (targetApp's localizedName) as text
    if targetAppName is "Windows VM" then
        tell application "System Events"
            tell process targetAppName
                -- change this line to match your 'Select previous input source' keyboard shortcut
                keystroke space using {command down, control down}
            end tell
        end tell
    end if
end appHasDeactivated:

一旦你对它感到满意,你可以在终端中运行以下命令:

defaults write '/path/to/$name.app/Contents/Info.plist' LSUIElement -bool yes

这会将应用程序变成后台代理,它永远不会占据前台并且在 Dock 中是不可见的。这样你就可以忘记它了。

【讨论】:

  • 谢谢特德。按预期工作。你能给我推荐一种材料来提高我的 AppleScript 技能吗?
  • @ArunDoss:我建议你开始MacOSXAutomation。对于初学者和中级 AppleScripters 来说,这是一个很好的概述,其中包含一些更强大的东西。之后,您可以查看macscripter.net 的论坛,那里是高级用户隐藏的地方。但实际上,学习任何脚本语言的最佳方法是为自己设置一个项目并不断失败,直到成功为止。
  • @ArunDoss:哦,天哪!苹果自己的AppleScript Language Guide,必备。 Apple 曾经提供可下载的 pdf 版本,但我现在找不到了。
  • 我个人使用EventScripts 和从this answer 中的代码 创建的二进制文件,它允许传递命令行参数。我测试了您的代码,发现它很容易不同步,因为它只是使用系统事件键盘快捷键进行切换。如果它使用 AppleScriptObjC 通过参数执行更改而不是使用 System Events 切换,我会对此表示赞同。
  • Ted Wrigley,我并没有刻意批评您的回答,坦率地说,当我说“如果它使用 AppleScriptObjC 来执行带有参数的更改,我会对此表示赞同” vs 切换 系统事件。”,这是 IMO 建设性的批评。您的答案是 good 答案,只是不够 good IMO 和 better 答案本来可以避免 System Events键盘快捷键。实际上,在您发布您的答案之前,我已经开始写答案,但是因为其他事情而分心,显然从未发布过,也许我会。
猜你喜欢
  • 1970-01-01
  • 2013-07-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-04-04
  • 2014-11-11
  • 1970-01-01
  • 2017-12-26
相关资源
最近更新 更多