- Drop simulated-controller fallback: simulation now only runs when explicitly enabled in Settings (or outside Tauri), so the app no longer claims a controller is connected when none is plugged in - Derive connection type from the kernel bus type (USB/Bluetooth) instead of an unreliable udev property - Read real battery percentage from /sys/class/power_supply; hide the field entirely when the device reports none - Remove Input mode and Firmware version fields (not obtainable) - Query virtual controller status from the backend instead of a hardcoded per-device flag - Exclude the app's own uinput virtual controller from device discovery - Rescan for controllers indefinitely while disconnected so a controller plugged in at any time is detected without restarting - Strip leftover debug instrumentation from the previous session Co-authored-by: Cursor <cursoragent@cursor.com>
45 lines
1.6 KiB
TypeScript
45 lines
1.6 KiB
TypeScript
import { listen } from "@tauri-apps/api/event";
|
|
import { invoke } from "@tauri-apps/api/core";
|
|
|
|
import type { ControllerInfo, RawInputEvent } from "@/types/controller";
|
|
import type { Profile } from "@/types/profile";
|
|
|
|
const INPUT_EVENT = "controller-input";
|
|
const READER_STATUS_EVENT = "controller-reader-status";
|
|
|
|
interface NativeInputEvent {
|
|
timestamp: number;
|
|
eventType: "button" | "axis";
|
|
code: string;
|
|
rawValue: number;
|
|
processedValue: number;
|
|
}
|
|
|
|
interface ReaderStatus {
|
|
devicePath: string;
|
|
connected: boolean;
|
|
message: string | null;
|
|
}
|
|
|
|
function toRawInputEvent(event: NativeInputEvent): RawInputEvent {
|
|
return {
|
|
timestamp: event.timestamp,
|
|
type: event.eventType,
|
|
code: event.code,
|
|
rawValue: event.rawValue,
|
|
processedValue: event.processedValue,
|
|
};
|
|
}
|
|
|
|
export const tauriControllerService = {
|
|
list: () => invoke<ControllerInfo[]>("list_devices"),
|
|
startReader: (devicePath: string) => invoke<void>("start_device_reader", { devicePath }),
|
|
applyRemappingProfile: (profile: Profile) => invoke<void>("apply_remapping_profile", { profile }),
|
|
setRemappingEnabled: (enabled: boolean) => invoke<void>("set_remapping_enabled", { enabled }),
|
|
virtualControllerActive: () => invoke<boolean>("virtual_controller_active"),
|
|
onInput: async (callback: (event: RawInputEvent) => void): Promise<() => void> =>
|
|
listen<NativeInputEvent>(INPUT_EVENT, (event) => callback(toRawInputEvent(event.payload))),
|
|
onReaderStatus: async (callback: (status: ReaderStatus) => void): Promise<() => void> =>
|
|
listen<ReaderStatus>(READER_STATUS_EVENT, (event) => callback(event.payload)),
|
|
};
|