Git Product home page Git Product logo

surge-applescript's Introduction

Surge-AppleScript

Surge 是知名的 Mac & iOS 网络分析及代理工具

但是高频功能总是需要点击菜单,并不高效。囿于当前还没有官方接口可资利用,我们可以采用 macOS 原生操纵 App 界面元素的方法,将这些功能绑定到全局快捷键或者融入到个人工作流中

需要给 Keyboard Maestro Engine 赋予辅助功能权限,其它工具同

辅助功能权限

1. 调用菜单中已绑定快捷键的功能

最简单的,是调用菜单中已经存在的快捷键,这只需要先展开菜单,然后模拟按键即可

但这第一步用常规的方法时却遇到问题,在 AppleScript 中用 click 动作并不能点开该菜单:

tell application "System Events"
	tell process "Surge"
		click menu bar item 1 of menu bar 2 -- 无效
	end tell
end tell

经过研究,发现可以用 perform action "AXShowMenu" 解决,于是最终脚本如下:

tell application "System Events"
	tell process "Surge"
		tell menu bar item 1 of menu bar 2
			perform action "AXShowMenu"
			keystroke "d" using command down -- 模拟按下 ⌘+D,对应「控制台」功能
		end tell
	end tell
end tell

2. 点选菜单中的功能

关于 AppleScript 的 UI 操作,Surge 相比其它 App,有两点比较特殊,容易踩坑:

  1. 必须先展开菜单栏,才能获取菜单元素
  2. 如果还有子菜单,要逐层展开,不能只用一次 click 直击目标菜单项

第一个问题之前已经解决了,第二个问题只要逐次点击即可:

tell application "System Events"
	tell process "Surge"
		tell menu bar item 1 of menu bar 2
			perform action "AXShowMenu"
			tell menu item "策略组名称" of menu 1 to {click, click menu item "节点名称" of menu 1} -- 点选「某策略组 -> 某节点」
		end tell
	end tell
end tell

自然,前述模拟按下快捷键调用的功能,也可以换用此方式实现

3. 例外:出站模式

虽然已经解决了一些前置问题,但是特殊情况总是存在的

同样具有子菜单,「策略组 -> 节点」、「切换配置」,都可以用前面的方式操作,唯独「出站模式」,其子菜单项,再次不响应 click 动作。这次不可用 perform action "AXShowMenu" 解决,尝试使用其它预定义的 action(如 AXPress、AXPick 等)也不奏效,只能换其它思路

3.1 第三方工具辅助点击

一个想法是,用第三方工具,帮我们完成这最后一步模拟鼠标点击的操作,那么我们需要的,就只是目标菜单项的坐标,这很容易:

tell application "System Events"
	tell process "Surge"
		tell menu bar item 1 of menu bar 2
			perform action "AXShowMenu"
			tell menu item 1 of menu 1 -- menu item 1 是菜单第一项,即「出站模式」
				click
				position of menu item 1 of menu 1 -- menu item 1 是子菜单第一项,即「直连」,因为分割线的缘故,「全局」和「规则」分别对应 menu item 3 和 5
			end tell
		end tell
	end tell
end tell

而这个「第三方工具」,其实 Keyboard Maestro 就可以胜任,如图:

获取菜单项坐标并点击

3.2 系统原生框架编程

当然还有一个愿望:原生实现最好

思路还是一样的:替代 Click,用更「底层」的方式模拟点击操作

联合使用 Objective-C,也是可以做到的,只是有些破坏 AppleScript 使用自然语义编程通俗易懂的优点。下面用 JXA(AppleScript 孪生兄弟)给出一个实现:

// Objective-C Bridge
ObjC.import('AppKit');

// 获取鼠标原始坐标
var event = $.CGEventCreate($());
var orig = $.CGEventGetLocation(event);
$.CFRelease(event);

// 展开菜单。注意:JavaScript 中下标从 0 开始
var menu = Application('System Events').processes.Surge.menuBars[1].menuBarItems[0];
menu.actions.AXShowMenu.perform();
// 获取目标菜单项的坐标并点击。注意:最后一个 menuItems 的索引应为 0、2、4,对应「直连」、「全局」、「规则」
clickMouse(...menu.menus[0].menuItems[0].click().menus[0].menuItems[4].position());

// 恢复鼠标原始坐标
moveMouse(orig.x, orig.y);

// 点击鼠标
function clickMouse(x, y) {
	let event = $.CGEventCreateMouseEvent($(), $.kCGEventLeftMouseDown, $.CGPointMake(x, y), $.kCGMouseButtonLeft);
	$.CGEventPost($.kCGHIDEventTap, event);
	// 少许延迟
	delay(0.1)
	$.CGEventSetType(event, $.kCGEventLeftMouseUp);
	$.CGEventPost($.kCGHIDEventTap, event);
	$.CFRelease(event);
}

// 移动鼠标
function moveMouse(x, y) {
	let event = $.CGEventCreateMouseEvent($(), $.kCGEventMouseMoved, $.CGPointMake(x, y), $.kCGMouseButtonLeft);
	$.CGEventPost($.kCGHIDEventTap, event);
	$.CFRelease(event);
}

JXA 在 Shell 中的调用方式是 osascript -l JavaScript xxx.js;在 Keyboard Maestro 中是:

JXA 联合 ObjC 框架

surge-applescript's People

Contributors

jayqizone avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar

surge-applescript's Issues

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.