fix: Implement DPI Scaling Support (#601)
This commit is contained in:
@@ -216,8 +216,35 @@ export function useTauriDpi() {
|
||||
return new imported.LogicalPosition(x, y)
|
||||
}
|
||||
|
||||
async function getScaleFactor(): Promise<number> {
|
||||
const imported = await tauriDpiApi.value
|
||||
if (!imported) {
|
||||
throw new Error('Tauri DPI API not available')
|
||||
}
|
||||
|
||||
const monitor = await imported.currentMonitor()
|
||||
return monitor?.scaleFactor ?? 1
|
||||
}
|
||||
|
||||
function convertPhysicalToLogical(physicalX: number, physicalY: number, scaleFactor: number): { x: number, y: number } {
|
||||
return {
|
||||
x: physicalX / scaleFactor,
|
||||
y: physicalY / scaleFactor,
|
||||
}
|
||||
}
|
||||
|
||||
function convertLogicalToPhysical(logicalX: number, logicalY: number, scaleFactor: number): { x: number, y: number } {
|
||||
return {
|
||||
x: logicalX * scaleFactor,
|
||||
y: logicalY * scaleFactor,
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
createLogicalPosition,
|
||||
getScaleFactor,
|
||||
convertPhysicalToLogical,
|
||||
convertLogicalToPhysical,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,17 +1,42 @@
|
||||
import type { AiriTamagotchiEvents } from './tauri'
|
||||
|
||||
import { createSharedComposable } from '@vueuse/core'
|
||||
import { ref } from 'vue'
|
||||
import { ref, watch } from 'vue'
|
||||
|
||||
import { useTauriEvent } from './tauri'
|
||||
import { useTauriDpi, useTauriEvent } from './tauri'
|
||||
|
||||
export const useRdevMouse = createSharedComposable(() => {
|
||||
const mouseX = ref(0)
|
||||
const mouseY = ref(0)
|
||||
const logicalMouseX = ref(0)
|
||||
const logicalMouseY = ref(0)
|
||||
const scaleFactor = ref(1)
|
||||
|
||||
const { listen } = useTauriEvent<AiriTamagotchiEvents>()
|
||||
const { getScaleFactor } = useTauriDpi()
|
||||
|
||||
// Update scale factor when DPI changes
|
||||
async function updateScaleFactor() {
|
||||
try {
|
||||
const newScaleFactor = await getScaleFactor()
|
||||
scaleFactor.value = newScaleFactor
|
||||
}
|
||||
catch (error) {
|
||||
console.warn('Failed to get scale factor, using default 1.0:', error)
|
||||
scaleFactor.value = 1
|
||||
}
|
||||
}
|
||||
|
||||
// Convert physical coordinates to logical coordinates
|
||||
watch([mouseX, mouseY, scaleFactor], ([x, y, scale]) => {
|
||||
const logical = convertPhysicalToLogical(x, y, scale)
|
||||
logicalMouseX.value = logical.x
|
||||
logicalMouseY.value = logical.y
|
||||
})
|
||||
|
||||
async function setup() {
|
||||
await updateScaleFactor()
|
||||
|
||||
await listen('tauri-plugins:tauri-plugin-rdev:mousemove', (event) => {
|
||||
if (event.payload.event_type.MouseMove) {
|
||||
const { x, y } = event.payload.event_type.MouseMove
|
||||
@@ -19,6 +44,11 @@ export const useRdevMouse = createSharedComposable(() => {
|
||||
mouseY.value = y
|
||||
}
|
||||
})
|
||||
|
||||
// Listen for scale changes (when window moves between monitors with different DPI)
|
||||
await listen('tauri://scale-change', () => {
|
||||
updateScaleFactor()
|
||||
})
|
||||
}
|
||||
|
||||
setup()
|
||||
@@ -26,5 +56,8 @@ export const useRdevMouse = createSharedComposable(() => {
|
||||
return {
|
||||
mouseX,
|
||||
mouseY,
|
||||
logicalMouseX,
|
||||
logicalMouseY,
|
||||
scaleFactor,
|
||||
}
|
||||
})
|
||||
|
||||
@@ -30,7 +30,7 @@ const windowControlStore = useWindowControlStore()
|
||||
const resourcesStore = useResourcesStore()
|
||||
const mcpStore = useMcpStore()
|
||||
const { getPosition } = useTauriWindow()
|
||||
const { mouseX, mouseY } = useRdevMouse()
|
||||
const { logicalMouseX, logicalMouseY } = useRdevMouse()
|
||||
|
||||
const { listen } = useTauriEvent<AiriTamagotchiEvents>()
|
||||
const { invoke } = useTauriCore()
|
||||
@@ -55,7 +55,7 @@ watch(shouldShowSetup, () => {
|
||||
}, { immediate: true })
|
||||
|
||||
// Handle mouse pass-through based on WebGL pixel alpha.
|
||||
watchThrottled([mouseX, mouseY], ([x, y]) => {
|
||||
watchThrottled([logicalMouseX, logicalMouseY], ([x, y]) => {
|
||||
requestAnimationFrame(() => {
|
||||
const canvas = widgetStageRef.value?.canvasElement()
|
||||
if (!canvas)
|
||||
|
||||
Reference in New Issue
Block a user