Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions 12 Documentation/Configuration.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,18 @@ declare namespace Scheme {
*/
groupApp?: string;

/**
* @title Process name
* @description Match by the executable file name of the frontmost process (from NSRunningApplication.executableURL.lastPathComponent). Case-sensitive.
*/
processName?: string;

/**
* @title Process path
* @description Match by the absolute executable path of the frontmost process (from NSRunningApplication.executableURL.path). Case-sensitive.
*/
processPath?: string;

/**
* @title Display name
* @description Match displays by providing the display name. For example, `DELL P2415Q`.
Expand Down
10 changes: 10 additions & 0 deletions 10 Documentation/Configuration.json
Original file line number Diff line number Diff line change
Expand Up @@ -761,6 +761,16 @@
"description": "Match apps by providing the bundle ID of the parent process. For example, `org.polymc.PolyMC`.",
"title": "Parent app",
"type": "string"
},
"processName": {
"description": "Match by the executable file name of the frontmost process (from NSRunningApplication.executableURL.lastPathComponent). Case-sensitive.",
"title": "Process name",
"type": "string"
},
"processPath": {
"description": "Match by the absolute executable path of the frontmost process (from NSRunningApplication.executableURL.path). Case-sensitive.",
"title": "Process path",
"type": "string"
}
},
"type": "object"
Expand Down
39 changes: 39 additions & 0 deletions 39 Documentation/Configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -216,6 +216,45 @@ Or, to match the whole process group:
}
```

### Process (binary) matching

Some programs do not have a stable or any bundle identifier. You can match by the frontmost process's executable instead.

- processName: Match by executable name (case-sensitive). Example:

```json
{
"schemes": [
{
"if": {
"processName": "wezterm"
},
"scrolling": { "reverse": false }
}
]
}
```

- processPath: Match by absolute executable path (case-sensitive). Example:

```json
{
"schemes": [
{
"if": {
"processPath": "/Applications/WezTerm.app/Contents/MacOS/WezTerm"
},
"pointer": { "acceleration": 0.4 }
}
]
}
```

Notes
- processName/processPath compare exactly; no wildcard or regex.
- Matching is against the frontmost application process (NSRunningApplication); child processes inside a terminal are not detected as the frontmost process.
- You can still combine with device and display conditions.

## Display Matching

Display name can be provided to match a specific display.
Expand Down
14 changes: 11 additions & 3 deletions 14 LinearMouse/Model/Configuration/Configuration.swift
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,9 @@ extension Configuration {
withApp app: String? = nil,
withParentApp parentApp: String? = nil,
withGroupApp groupApp: String? = nil,
withDisplay display: String? = nil
withDisplay display: String? = nil,
withProcessName processName: String? = nil,
withProcessPath processPath: String? = nil
) -> Scheme {
// TODO: Backtrace the merge path
// TODO: Optimize the algorithm
Expand All @@ -115,6 +117,8 @@ extension Configuration {
app: app,
parentApp: parentApp,
groupApp: groupApp,
processName: processName,
processPath: processPath,
display: display
)

Expand All @@ -125,7 +129,9 @@ extension Configuration {
withApp: app,
withParentApp: parentApp,
withGroupApp: groupApp,
withDisplay: display
withDisplay: display,
withProcessName: processName,
withProcessPath: processPath
) {
scheme.merge(into: &mergedScheme)
}
Expand All @@ -143,7 +149,9 @@ extension Configuration {
withApp: pid?.bundleIdentifier,
withParentApp: pid?.parent?.bundleIdentifier,
withGroupApp: pid?.group?.bundleIdentifier,
withDisplay: display
withDisplay: display,
withProcessName: pid?.processName,
withProcessPath: pid?.processPath
)
}
}
20 changes: 19 additions & 1 deletion 20 LinearMouse/Model/Configuration/Scheme/If/If.swift
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,10 @@ extension Scheme {
var parentApp: String?
var groupApp: String?

// Match by executable instead of app bundle
var processName: String?
var processPath: String?

var display: String?
}
}
Expand All @@ -22,7 +26,9 @@ extension Scheme.If {
withApp targetApp: String? = nil,
withParentApp targetParentApp: String?,
withGroupApp targetGroupApp: String?,
withDisplay targetDisplay: String? = nil
withDisplay targetDisplay: String? = nil,
withProcessName targetProcessName: String? = nil,
withProcessPath targetProcessPath: String? = nil
) -> Bool {
if let device {
guard let targetDevice else {
Expand Down Expand Up @@ -52,6 +58,18 @@ extension Scheme.If {
}
}

if let processName {
guard processName == targetProcessName else {
return false
}
}

if let processPath {
guard processPath == targetProcessPath else {
return false
}
}

if let display {
guard let targetDisplay else {
return false
Expand Down
8 changes: 6 additions & 2 deletions 8 LinearMouse/Model/Configuration/Scheme/Scheme.swift
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,9 @@ extension Scheme {
withApp app: String? = nil,
withParentApp parentApp: String? = nil,
withGroupApp groupApp: String? = nil,
withDisplay display: String? = nil
withDisplay display: String? = nil,
withProcessName processName: String? = nil,
withProcessPath processPath: String? = nil
) -> Bool {
guard let `if` else {
return true
Expand All @@ -52,7 +54,9 @@ extension Scheme {
withApp: app,
withParentApp: parentApp,
withGroupApp: groupApp,
withDisplay: display
withDisplay: display,
withProcessName: processName,
withProcessPath: processPath
)
}
}
Expand Down
24 changes: 24 additions & 0 deletions 24 LinearMouse/Utilities/Extensions.swift
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,8 @@ extension Decimal {

extension pid_t {
private static var bundleIdentifierCache = LRUCache<Self, String>(countLimit: 16)
private static var processPathCache = LRUCache<Self, String>(countLimit: 16)
private static var processNameCache = LRUCache<Self, String>(countLimit: 16)

var bundleIdentifier: String? {
guard let bundleIdentifier = Self.bundleIdentifierCache.value(forKey: self)
Expand All @@ -82,6 +84,28 @@ extension pid_t {
return bundleIdentifier
}

var processPath: String? {
if let cached = Self.processPathCache.value(forKey: self) {
return cached
}
guard let path = NSRunningApplication(processIdentifier: self)?.executableURL?.path else {
return nil
}
Self.processPathCache.setValue(path, forKey: self)
return path
}

var processName: String? {
if let cached = Self.processNameCache.value(forKey: self) {
return cached
}
guard let name = NSRunningApplication(processIdentifier: self)?.executableURL?.lastPathComponent else {
return nil
}
Self.processNameCache.setValue(name, forKey: self)
return name
}

var parent: pid_t? {
let pid = getProcessInfo(self).ppid

Expand Down
Loading
Morty Proxy This is a proxified and sanitized view of the page, visit original site.