basically label option nicely on macOS as well as fix command not being sent properly.

This commit is contained in:
CJ Pais 2025-05-15 13:42:31 -07:00
parent 5735b83cd2
commit cc4b057993
6 changed files with 150 additions and 19 deletions

BIN
bun.lockb

Binary file not shown.

View file

@ -16,6 +16,7 @@
"@tauri-apps/plugin-clipboard-manager": "~2",
"@tauri-apps/plugin-global-shortcut": "~2",
"@tauri-apps/plugin-opener": "^2",
"@tauri-apps/plugin-os": "~2",
"@tauri-apps/plugin-store": "~2",
"@tauri-apps/plugin-stronghold": "~2",
"@tauri-apps/plugin-upload": "~2",

90
src-tauri/Cargo.lock generated
View file

@ -213,7 +213,7 @@ dependencies = [
"futures-lite",
"parking",
"polling",
"rustix",
"rustix 0.38.44",
"slab",
"tracing",
"windows-sys 0.59.0",
@ -245,7 +245,7 @@ dependencies = [
"cfg-if",
"event-listener",
"futures-lite",
"rustix",
"rustix 0.38.44",
"tracing",
]
@ -272,7 +272,7 @@ dependencies = [
"cfg-if",
"futures-core",
"futures-io",
"rustix",
"rustix 0.38.44",
"signal-hook-registry",
"slab",
"windows-sys 0.59.0",
@ -1745,6 +1745,16 @@ dependencies = [
"windows-targets 0.48.5",
]
[[package]]
name = "gethostname"
version = "1.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fc257fdb4038301ce4b9cd1b3b51704509692bb3ff716a410cbd07925d9dae55"
dependencies = [
"rustix 1.0.7",
"windows-targets 0.52.6",
]
[[package]]
name = "getrandom"
version = "0.1.16"
@ -1982,6 +1992,7 @@ dependencies = [
"tauri-plugin-global-shortcut",
"tauri-plugin-macos-permissions",
"tauri-plugin-opener",
"tauri-plugin-os",
"tauri-plugin-single-instance",
"tauri-plugin-store",
"tokio",
@ -2663,6 +2674,12 @@ version = "0.4.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d26c52dbd32dccf2d10cac7725f8eae5296885fb5703b261f7d0a0739ec807ab"
[[package]]
name = "linux-raw-sys"
version = "0.9.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cd945864f07fe9f5371a27ad7b52a172b4b499999f1d97574c9fa68373937e12"
[[package]]
name = "litemap"
version = "0.7.4"
@ -3357,6 +3374,17 @@ dependencies = [
"ureq",
]
[[package]]
name = "os_info"
version = "3.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "41fc863e2ca13dc2d5c34fb22ea4a588248ac14db929616ba65c45f21744b1e9"
dependencies = [
"log",
"serde",
"windows-sys 0.52.0",
]
[[package]]
name = "pango"
version = "0.18.3"
@ -3622,7 +3650,7 @@ dependencies = [
"concurrent-queue",
"hermit-abi",
"pin-project-lite",
"rustix",
"rustix 0.38.44",
"tracing",
"windows-sys 0.59.0",
]
@ -4134,7 +4162,20 @@ dependencies = [
"bitflags 2.8.0",
"errno",
"libc",
"linux-raw-sys",
"linux-raw-sys 0.4.15",
"windows-sys 0.59.0",
]
[[package]]
name = "rustix"
version = "1.0.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c71e83d6afe7ff64890ec6b71d6a69bb8a610ab78ce364b3352876bb4c801266"
dependencies = [
"bitflags 2.8.0",
"errno",
"libc",
"linux-raw-sys 0.9.4",
"windows-sys 0.59.0",
]
@ -4684,6 +4725,15 @@ dependencies = [
"syn 2.0.96",
]
[[package]]
name = "sys-locale"
version = "0.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8eab9a99a024a169fe8a903cf9d4a3b3601109bcc13bd9e3c6fff259138626c4"
dependencies = [
"libc",
]
[[package]]
name = "system-deps"
version = "6.2.2"
@ -4973,6 +5023,24 @@ dependencies = [
"zbus",
]
[[package]]
name = "tauri-plugin-os"
version = "2.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "424f19432397850c2ddd42aa58078630c15287bbce3866eb1d90e7dbee680637"
dependencies = [
"gethostname 1.0.2",
"log",
"os_info",
"serde",
"serde_json",
"serialize-to-javascript",
"sys-locale",
"tauri",
"tauri-plugin",
"thiserror 2.0.11",
]
[[package]]
name = "tauri-plugin-single-instance"
version = "2.2.1"
@ -5106,7 +5174,7 @@ dependencies = [
"fastrand",
"getrandom 0.3.1",
"once_cell",
"rustix",
"rustix 0.38.44",
"windows-sys 0.59.0",
]
@ -5899,7 +5967,7 @@ dependencies = [
"either",
"home",
"once_cell",
"rustix",
"rustix 0.38.44",
]
[[package]]
@ -6512,8 +6580,8 @@ version = "0.13.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5d91ffca73ee7f68ce055750bf9f6eca0780b8c85eff9bc046a3b0da41755e12"
dependencies = [
"gethostname",
"rustix",
"gethostname 0.4.3",
"rustix 0.38.44",
"x11rb-protocol",
]
@ -6530,8 +6598,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e105d177a3871454f754b33bb0ee637ecaaac997446375fd3e5d43a2ed00c909"
dependencies = [
"libc",
"linux-raw-sys",
"rustix",
"linux-raw-sys 0.4.15",
"rustix 0.38.44",
]
[[package]]

View file

@ -38,6 +38,7 @@ log = "0.4.25"
tokio = "1.43.0"
vad-rs = "0.1.5"
tauri-plugin-store = "2"
tauri-plugin-os = "2"
[target.'cfg(target_os = "macos")'.dependencies]
whisper-rs = { version = "0.13.2", features = ["metal"] }

View file

@ -27,6 +27,7 @@ pub fn run() {
env_logger::init();
tauri::Builder::default()
.plugin(tauri_plugin_os::init())
.plugin(tauri_plugin_clipboard_manager::init())
.plugin(tauri_plugin_autostart::init(
MacosLauncher::LaunchAgent,

View file

@ -7,6 +7,7 @@ import {
ShortcutBindingsMap,
} from "../../lib/types";
import { invoke } from "@tauri-apps/api/core";
import { type } from "@tauri-apps/plugin-os";
import keycode from "keycode";
import ResetIcon from "../icons/ResetIcon";
@ -16,11 +17,58 @@ export const KeyboardShortcuts: React.FC = () => {
const [keyPressed, setKeyPressed] = useState<string[]>([]);
const [recordedKeys, setRecordedKeys] = useState<string[]>([]);
const [editingShortcutId, setEditingShortcutId] = useState<string | null>(
null
null,
);
const [originalBinding, setOriginalBinding] = useState<string>("");
const [isMacOS, setIsMacOS] = useState<boolean>(false);
const shortcutRefs = useRef<Map<string, HTMLDivElement | null>>(new Map());
// Check if running on macOS
useEffect(() => {
const checkOsType = async () => {
try {
const osType = type();
setIsMacOS(osType === "macos");
} catch (error) {
console.error("Error detecting OS type:", error);
setIsMacOS(false);
}
};
checkOsType();
}, []);
// Normalize modifier keys (unify left/right variants)
const normalizeKey = (key: string): string => {
// Handle left/right variants of modifier keys
if (key.startsWith("left ") || key.startsWith("right ")) {
const parts = key.split(" ");
if (parts.length === 2) {
// Return just the modifier name without left/right prefix
return parts[1];
}
}
return key;
};
// Format keys for macOS display
const formatMacOSKeys = (key: string): string => {
if (!isMacOS) return key; // Only format for macOS
const keyMap: Record<string, string> = {
alt: "option",
};
return keyMap[key.toLowerCase()] || key;
};
// Format a key combination for display
const formatKeyCombination = (combination: string): string => {
if (!isMacOS) return combination; // Only format for macOS
return combination.split("+").map(formatMacOSKeys).join(" + ");
};
useEffect(() => {
load("settings_store.json", { autoSave: false }).then((r) => {
console.log("loaded store", r);
@ -43,8 +91,11 @@ export const KeyboardShortcuts: React.FC = () => {
const handleKeyDown = (e: KeyboardEvent) => {
e.preventDefault();
const key = keycode(e).toLowerCase();
console.log("You pressed", key);
// Get the key and normalize it (unify left/right modifiers)
const rawKey = keycode(e).toLowerCase();
const key = normalizeKey(rawKey);
console.log("You pressed", rawKey, "normalized to", key);
if (!keyPressed.includes(key)) {
setKeyPressed((prev) => [...prev, key]);
@ -58,7 +109,9 @@ export const KeyboardShortcuts: React.FC = () => {
const handleKeyUp = (e: KeyboardEvent) => {
e.preventDefault();
const key = keycode(e).toLowerCase();
// Get the key and normalize it
const rawKey = keycode(e).toLowerCase();
const key = normalizeKey(rawKey);
// Remove from currently pressed keys
setKeyPressed((prev) => prev.filter((k) => k !== key));
@ -138,7 +191,14 @@ export const KeyboardShortcuts: React.FC = () => {
// Format the current shortcut keys being recorded
const formatCurrentKeys = () => {
return recordedKeys.length > 0 ? recordedKeys.join("+") : "Press keys...";
if (recordedKeys.length === 0) return "Press keys...";
if (!isMacOS) {
return recordedKeys.join("+");
}
// Map each key to its macOS-friendly name for display
return recordedKeys.map(formatMacOSKeys).join(" + ");
};
// Store references to shortcut elements
@ -185,16 +245,16 @@ export const KeyboardShortcuts: React.FC = () => {
{editingShortcutId === id ? (
<div
ref={(ref) => setShortcutRef(id, ref)}
className="px-2 py-1 text-sm font-semibold border border-logo-primary bg-logo-primary/30 rounded min-w-[100px] text-center"
className="px-2 py-1 text-sm font-semibold border border-logo-primary bg-logo-primary/30 rounded min-w-[120px] text-center"
>
{formatCurrentKeys()}
</div>
) : (
<div
className="px-2 py-1 text-sm font-semibold bg-mid-gray/10 border border-mid-gray/80 hover:bg-logo-primary/10 rounded cursor-pointer hover:border-logo-primary"
className="px-2 py-1 text-sm font-semibold bg-mid-gray/10 border border-mid-gray/80 hover:bg-logo-primary/10 rounded cursor-pointer hover:border-logo-primary"
onClick={() => startRecording(id)}
>
{binding.current_binding}
{formatKeyCombination(binding.current_binding)}
</div>
)}
<button