From 2063b220fdeb901c3f5c78c71c70f04f4c593a7e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=AA=A0=E8=AA=A0-ChengCheng?= <37478187+TW527E@users.noreply.github.com> Date: Thu, 8 Oct 2026 21:18:27 +0800 Subject: [PATCH] Allow bypassing bundle-less apps such as Minecraft Java games like Minecraft run as a bare `java` executable with no bundle identifier, so ShiftIME never recognized them as the foreground app and they could not be added to the bypass list. Fall back to the executable path as the identifier and point users to the menu bar item for them. Co-Authored-By: Claude Opus 5.5 --- Sources/ShiftIME/ForegroundApplicationInfo.swift | 4 +++- Sources/ShiftIME/PreferencesWindowController.swift | 5 +++-- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/Sources/ShiftIME/ForegroundApplicationInfo.swift b/Sources/ShiftIME/ForegroundApplicationInfo.swift index 3a079af..cbd0f61 100644 --- a/Sources/ShiftIME/ForegroundApplicationInfo.swift +++ b/Sources/ShiftIME/ForegroundApplicationInfo.swift @@ -2,13 +2,15 @@ import AppKit import ShiftIMECore struct ForegroundApplicationInfo { + /// The bundle ID, or the executable path for bundle-less processes such as + /// Java games (Minecraft runs as a bare `java` binary). let bundleIdentifier: String let localizedName: String /// Classified once per activation so the event tap only reads a Bool. let isRemoteOrGame: Bool init?(runningApplication: NSRunningApplication) { - guard let bundleIdentifier = runningApplication.bundleIdentifier, + guard let bundleIdentifier = runningApplication.bundleIdentifier ?? runningApplication.executableURL?.path, bundleIdentifier != Bundle.main.bundleIdentifier else { return nil } diff --git a/Sources/ShiftIME/PreferencesWindowController.swift b/Sources/ShiftIME/PreferencesWindowController.swift index 8a3ae71..6c8e524 100644 --- a/Sources/ShiftIME/PreferencesWindowController.swift +++ b/Sources/ShiftIME/PreferencesWindowController.swift @@ -101,7 +101,7 @@ final class PreferencesWindowController: NSWindowController, NSWindowDelegate, N let bypassTitle = NSTextField(labelWithString: "應用程式快捷鍵放行") bypassTitle.font = .systemFont(ofSize: 13, weight: .semibold) - let bypassNote = NSTextField(wrappingLabelWithString: "可分別決定每個 App 是否略過 Shift 輸入法切換及 Shift + Space 全/半形切換。新加入的 App 預設兩項都放行。自動模式會對常見遠端軟體及遊戲放行兩項快捷鍵。") + let bypassNote = NSTextField(wrappingLabelWithString: "可分別決定每個 App 是否略過 Shift 輸入法切換及 Shift + Space 全/半形切換。新加入的 App 預設兩項都放行。自動模式會對常見遠端軟體及遊戲放行兩項快捷鍵。Minecraft 等 Java 遊戲沒有 App 檔,請在遊戲執行時從選單列圖標加入。") bypassNote.font = .systemFont(ofSize: 12) bypassNote.textColor = .secondaryLabelColor let excludedAppsTitle = NSTextField(labelWithString: "應用程式列表") @@ -216,7 +216,8 @@ final class PreferencesWindowController: NSWindowController, NSWindowDelegate, N let bundleIdentifier = excludedBundleIDs[row] guard let keyPath = bypassKeyPath(for: tableColumn) else { let label = NSTextField(labelWithString: displayName(for: bundleIdentifier)) - label.lineBreakMode = .byTruncatingTail + // Middle truncation keeps both ends of executable paths readable. + label.lineBreakMode = .byTruncatingMiddle label.toolTip = bundleIdentifier return label }