mirror of
https://github.com/Comfy-Org/ComfyUI_frontend.git
synced 2026-05-23 22:25:05 +00:00
feat: add Input device setting for canvas navigation
This commit is contained in:
@@ -68,19 +68,19 @@ function getFormAttrs(item: FormItem) {
|
||||
}
|
||||
switch (item.type) {
|
||||
case 'combo':
|
||||
case 'radio':
|
||||
attrs['options'] =
|
||||
case 'radio': {
|
||||
const resolvedOptions =
|
||||
typeof item.options === 'function'
|
||||
? // @ts-expect-error: Audit and deprecate usage of legacy options type:
|
||||
// (value) => [string | {text: string, value: string}]
|
||||
item.options(formValue.value)
|
||||
? item.options(formValue.value)
|
||||
: item.options
|
||||
attrs['options'] = resolvedOptions
|
||||
|
||||
if (typeof item.options?.[0] !== 'string') {
|
||||
if (typeof resolvedOptions?.[0] !== 'string') {
|
||||
attrs['optionLabel'] = 'text'
|
||||
attrs['optionValue'] = 'value'
|
||||
}
|
||||
break
|
||||
}
|
||||
}
|
||||
return attrs
|
||||
}
|
||||
|
||||
@@ -9,6 +9,7 @@ import Slider from '@/components/ui/slider/Slider.vue'
|
||||
import { LiteGraph } from '@/lib/litegraph/src/litegraph'
|
||||
import type { LinkRenderType } from '@/lib/litegraph/src/types/globalEnums'
|
||||
import { LinkMarkerShape } from '@/lib/litegraph/src/types/globalEnums'
|
||||
import { useInputDeviceDetection } from '@/platform/settings/composables/useInputDeviceDetection'
|
||||
import { useSettingStore } from '@/platform/settings/settingStore'
|
||||
import { WidgetInputBaseClass } from '@/renderer/extensions/vueNodes/widgets/components/layout'
|
||||
import { useSettingsDialog } from '@/platform/settings/composables/useSettingsDialog'
|
||||
@@ -40,6 +41,33 @@ const nodes2Enabled = computed({
|
||||
})
|
||||
|
||||
// CANVAS settings
|
||||
const inputDevice = computed({
|
||||
get: () => settingStore.get('Comfy.Graph.WheelInputMode'),
|
||||
set: (value) => settingStore.set('Comfy.Graph.WheelInputMode', value)
|
||||
})
|
||||
|
||||
const { detectedInputDevice } = useInputDeviceDetection()
|
||||
|
||||
const inputDeviceOptions = computed(() => [
|
||||
{
|
||||
value: 'auto',
|
||||
label:
|
||||
detectedInputDevice.value === 'trackpad'
|
||||
? t(
|
||||
'settings.Comfy_Graph_WheelInputMode.options.Auto-detect (Trackpad)'
|
||||
)
|
||||
: t('settings.Comfy_Graph_WheelInputMode.options.Auto-detect (Mouse)')
|
||||
},
|
||||
{
|
||||
value: 'mouse',
|
||||
label: t('settings.Comfy_Graph_WheelInputMode.options.Mouse')
|
||||
},
|
||||
{
|
||||
value: 'trackpad',
|
||||
label: t('settings.Comfy_Graph_WheelInputMode.options.Trackpad')
|
||||
}
|
||||
])
|
||||
|
||||
const gridSpacing = computed({
|
||||
get: () => settingStore.get('Comfy.SnapToGrid.GridSize'),
|
||||
set: (value) => settingStore.set('Comfy.SnapToGrid.GridSize', value)
|
||||
@@ -128,6 +156,24 @@ function openFullSettings() {
|
||||
{{ t('rightSidePanel.globalSettings.canvas') }}
|
||||
</template>
|
||||
<div class="space-y-4 px-4 py-3">
|
||||
<LayoutField :label="t('rightSidePanel.globalSettings.inputDevice')">
|
||||
<Select
|
||||
v-model="inputDevice"
|
||||
:options="inputDeviceOptions"
|
||||
:aria-label="t('rightSidePanel.globalSettings.inputDevice')"
|
||||
:class="cn(WidgetInputBaseClass, 'w-full text-xs')"
|
||||
size="small"
|
||||
:pt="{
|
||||
option: 'text-xs',
|
||||
dropdown: 'w-8',
|
||||
label: cn('min-w-[4ch] truncate', $slots.default && 'mr-5'),
|
||||
overlay: 'w-fit min-w-full'
|
||||
}"
|
||||
data-capture-wheel="true"
|
||||
option-label="label"
|
||||
option-value="value"
|
||||
/>
|
||||
</LayoutField>
|
||||
<LayoutField :label="t('rightSidePanel.globalSettings.gridSpacing')">
|
||||
<div
|
||||
:class="
|
||||
|
||||
@@ -96,6 +96,9 @@ export class CanvasPointer {
|
||||
/** Currently detected input device type */
|
||||
detectedDevice: 'mouse' | 'trackpad' = 'mouse'
|
||||
|
||||
/** Fired when {@link detectedDevice} flips between mouse and trackpad. */
|
||||
onDetectedDeviceChange?: (device: 'mouse' | 'trackpad') => void
|
||||
|
||||
/** Timestamp of last wheel event for cooldown tracking */
|
||||
lastWheelEventTime: number = 0
|
||||
|
||||
@@ -302,6 +305,7 @@ export class CanvasPointer {
|
||||
const now = performance.now()
|
||||
const timeSinceLastEvent = Math.max(0, now - this.lastWheelEventTime)
|
||||
this.lastWheelEventTime = now
|
||||
const previousDevice = this.detectedDevice
|
||||
|
||||
if (this._isHighResWheelEvent(e, now)) {
|
||||
this.detectedDevice = 'mouse'
|
||||
@@ -314,6 +318,9 @@ export class CanvasPointer {
|
||||
this.hasReceivedWheelEvent = true
|
||||
}
|
||||
|
||||
if (previousDevice !== this.detectedDevice) {
|
||||
this.onDetectedDeviceChange?.(this.detectedDevice)
|
||||
}
|
||||
return this.detectedDevice === 'trackpad'
|
||||
}
|
||||
|
||||
|
||||
@@ -3895,13 +3895,25 @@ export class LGraphCanvas implements CustomEventDispatcher<LGraphCanvasEventMap>
|
||||
|
||||
let { scale } = this.ds
|
||||
|
||||
// Detect if this is a trackpad gesture or mouse wheel
|
||||
const isTrackpad = this.pointer.isTrackpadGesture(e)
|
||||
/**
|
||||
* Resolve trackpad vs mouse mode. Honor the user's manual override when
|
||||
* set; otherwise fall back to the heuristic-based auto-detection.
|
||||
*/
|
||||
const isTrackpad =
|
||||
LiteGraph.wheelInputMode === 'mouse'
|
||||
? false
|
||||
: LiteGraph.wheelInputMode === 'trackpad'
|
||||
? true
|
||||
: this.pointer.isTrackpadGesture(e)
|
||||
const isCtrlOrMacMeta =
|
||||
e.ctrlKey || (e.metaKey && navigator.platform.includes('Mac'))
|
||||
const isZoomModifier = isCtrlOrMacMeta && !e.altKey && !e.shiftKey
|
||||
|
||||
if (isZoomModifier || LiteGraph.mouseWheelScroll === 'zoom') {
|
||||
/**
|
||||
* Wheel-to-zoom is the default for mouse, wheel-to-pan for trackpad.
|
||||
* The Ctrl/Meta modifier always forces zoom regardless of device.
|
||||
*/
|
||||
if (isZoomModifier || !isTrackpad) {
|
||||
// Zoom mode or modifier key pressed - use wheel for zoom
|
||||
if (isTrackpad) {
|
||||
// Trackpad gesture - use smooth scaling
|
||||
|
||||
@@ -321,6 +321,15 @@ export class LiteGraphGlobal {
|
||||
|
||||
mouseWheelScroll: 'panning' | 'zoom' = 'panning'
|
||||
|
||||
/**
|
||||
* Override for the auto-detection of trackpad vs mouse in wheel events.
|
||||
* "auto" preserves the existing heuristic-based detection.
|
||||
* "mouse" / "trackpad" force the corresponding formula on every event,
|
||||
* which avoids misclassification when the user switches devices mid-session.
|
||||
* @default "auto"
|
||||
*/
|
||||
wheelInputMode: 'auto' | 'mouse' | 'trackpad' = 'auto'
|
||||
|
||||
/**
|
||||
* If `true`, widget labels and values will both be truncated (proportionally to size),
|
||||
* until they fit within the widget.
|
||||
|
||||
@@ -3494,6 +3494,7 @@
|
||||
"showInfoBadges": "Show info badges",
|
||||
"showToolbox": "Show toolbox on selection",
|
||||
"nodes2": "Nodes 2.0",
|
||||
"inputDevice": "Input device",
|
||||
"gridSpacing": "Grid spacing",
|
||||
"snapNodesToGrid": "Snap nodes to grid",
|
||||
"linkShape": "Link shape",
|
||||
|
||||
@@ -128,6 +128,16 @@
|
||||
"name": "Live selection",
|
||||
"tooltip": "When enabled, nodes are selected/deselected in real-time as you drag the selection rectangle, similar to other design tools."
|
||||
},
|
||||
"Comfy_Graph_WheelInputMode": {
|
||||
"name": "Input device",
|
||||
"tooltip": "Forces the zoom formula for a specific input device. Use this if auto-detection misclassifies your device when switching between mouse and trackpad.",
|
||||
"options": {
|
||||
"Auto-detect (Mouse)": "Auto-detect (Mouse)",
|
||||
"Auto-detect (Trackpad)": "Auto-detect (Trackpad)",
|
||||
"Mouse": "Mouse",
|
||||
"Trackpad": "Trackpad"
|
||||
}
|
||||
},
|
||||
"Comfy_Graph_ZoomSpeed": {
|
||||
"name": "Canvas zoom speed"
|
||||
},
|
||||
|
||||
@@ -40,12 +40,16 @@ const props = defineProps<{
|
||||
}>()
|
||||
|
||||
const { t } = useI18n()
|
||||
const settingStore = useSettingStore()
|
||||
const settingValue = computed(() => settingStore.get(props.setting.id))
|
||||
|
||||
function translateOptions(options: (SettingOption | string)[]) {
|
||||
function translateOptions(
|
||||
options:
|
||||
| (SettingOption | string)[]
|
||||
| ((value?: unknown) => (SettingOption | string)[])
|
||||
): { text: string; value: string | number | undefined }[] {
|
||||
if (typeof options === 'function') {
|
||||
// @ts-expect-error: Audit and deprecate usage of legacy options type:
|
||||
// (value) => [string | {text: string, value: string}]
|
||||
return translateOptions(options(props.setting.value ?? ''))
|
||||
return translateOptions(options(settingValue.value))
|
||||
}
|
||||
|
||||
return options.map((option) => {
|
||||
@@ -75,9 +79,6 @@ const formItem = computed(() => {
|
||||
: undefined
|
||||
}
|
||||
})
|
||||
|
||||
const settingStore = useSettingStore()
|
||||
const settingValue = computed(() => settingStore.get(props.setting.id))
|
||||
const updateSettingValue = async <K extends keyof Settings>(
|
||||
newValue: Settings[K]
|
||||
) => {
|
||||
|
||||
11
src/platform/settings/composables/useInputDeviceDetection.ts
Normal file
11
src/platform/settings/composables/useInputDeviceDetection.ts
Normal file
@@ -0,0 +1,11 @@
|
||||
import { ref } from 'vue'
|
||||
|
||||
/**
|
||||
* Reactive snapshot of the device the canvas pointer auto-detection currently
|
||||
* believes is in use. Updated by a callback wired in useLitegraphSettings.
|
||||
*/
|
||||
const detectedInputDevice = ref<'mouse' | 'trackpad'>('mouse')
|
||||
|
||||
export function useInputDeviceDetection() {
|
||||
return { detectedInputDevice }
|
||||
}
|
||||
@@ -5,6 +5,7 @@ import {
|
||||
LGraphNode,
|
||||
LiteGraph
|
||||
} from '@/lib/litegraph/src/litegraph'
|
||||
import { useInputDeviceDetection } from '@/platform/settings/composables/useInputDeviceDetection'
|
||||
import { useSettingStore } from '@/platform/settings/settingStore'
|
||||
// eslint-disable-next-line import-x/no-restricted-paths
|
||||
import { useCanvasStore } from '@/renderer/core/canvas/canvasStore'
|
||||
@@ -141,16 +142,6 @@ export const useLitegraphSettings = () => {
|
||||
)
|
||||
})
|
||||
|
||||
watchEffect(() => {
|
||||
const navigationMode = settingStore.get('Comfy.Canvas.NavigationMode') as
|
||||
| 'standard'
|
||||
| 'legacy'
|
||||
| 'custom'
|
||||
|
||||
LiteGraph.canvasNavigationMode = navigationMode
|
||||
LiteGraph.macTrackpadGestures = navigationMode === 'standard'
|
||||
})
|
||||
|
||||
watchEffect(() => {
|
||||
const leftMouseBehavior = settingStore.get(
|
||||
'Comfy.Canvas.LeftMouseClickBehavior'
|
||||
@@ -159,10 +150,23 @@ export const useLitegraphSettings = () => {
|
||||
})
|
||||
|
||||
watchEffect(() => {
|
||||
const mouseWheelScroll = settingStore.get(
|
||||
'Comfy.Canvas.MouseWheelScroll'
|
||||
) as 'panning' | 'zoom'
|
||||
LiteGraph.mouseWheelScroll = mouseWheelScroll
|
||||
LiteGraph.wheelInputMode = settingStore.get(
|
||||
'Comfy.Graph.WheelInputMode'
|
||||
) as 'auto' | 'mouse' | 'trackpad'
|
||||
})
|
||||
|
||||
/**
|
||||
* Mirror the canvas pointer's auto-detected device onto a reactive ref so
|
||||
* settings UI can show the current detection inside the "Auto" option.
|
||||
*/
|
||||
watchEffect(() => {
|
||||
const { canvas } = canvasStore
|
||||
if (!canvas) return
|
||||
const { detectedInputDevice } = useInputDeviceDetection()
|
||||
detectedInputDevice.value = canvas.pointer.detectedDevice
|
||||
canvas.pointer.onDetectedDeviceChange = (device) => {
|
||||
detectedInputDevice.value = device
|
||||
}
|
||||
})
|
||||
|
||||
watchEffect(() => {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { LinkMarkerShape, LiteGraph } from '@/lib/litegraph/src/litegraph'
|
||||
import { isCloud, isDesktop, isNightly } from '@/platform/distribution/types'
|
||||
import { useSettingStore } from '@/platform/settings/settingStore'
|
||||
import { useInputDeviceDetection } from '@/platform/settings/composables/useInputDeviceDetection'
|
||||
import type { SettingParams } from '@/platform/settings/types'
|
||||
import type { ColorPalettes } from '@/schemas/colorPaletteSchema'
|
||||
import type { Keybinding } from '@/platform/keybindings/types'
|
||||
@@ -159,101 +159,73 @@ export const CORE_SETTINGS: SettingParams[] = [
|
||||
type: 'boolean',
|
||||
defaultValue: false
|
||||
},
|
||||
{
|
||||
id: 'Comfy.Graph.WheelInputMode',
|
||||
category: ['LiteGraph', 'Canvas Navigation', 'InputDevice'],
|
||||
name: 'Input device',
|
||||
tooltip:
|
||||
'Forces the zoom formula for a specific input device. Use this if auto-detection misclassifies your device when switching between mouse and trackpad.',
|
||||
type: 'combo',
|
||||
defaultValue: 'auto',
|
||||
sortOrder: 200,
|
||||
/**
|
||||
* Reactively label the auto option with the currently detected device.
|
||||
* The function is called inside SettingItem's `formItem` computed, so any
|
||||
* read of `detectedInputDevice.value` is tracked and refreshes the dropdown.
|
||||
*/
|
||||
options: () => {
|
||||
const { detectedInputDevice } = useInputDeviceDetection()
|
||||
const autoLabel =
|
||||
detectedInputDevice.value === 'trackpad'
|
||||
? 'Auto-detect (Trackpad)'
|
||||
: 'Auto-detect (Mouse)'
|
||||
return [
|
||||
{ value: 'auto', text: autoLabel },
|
||||
{ value: 'mouse', text: 'Mouse' },
|
||||
{ value: 'trackpad', text: 'Trackpad' }
|
||||
]
|
||||
},
|
||||
versionAdded: '1.45.0'
|
||||
},
|
||||
{
|
||||
id: 'Comfy.Canvas.NavigationMode',
|
||||
category: ['LiteGraph', 'Canvas Navigation', 'NavigationMode'],
|
||||
name: 'Navigation Mode',
|
||||
defaultValue: 'legacy',
|
||||
type: 'combo',
|
||||
sortOrder: 100,
|
||||
type: 'hidden',
|
||||
deprecated: true,
|
||||
options: [
|
||||
{ value: 'standard', text: 'Standard (New)' },
|
||||
{ value: 'legacy', text: 'Drag Navigation' },
|
||||
{ value: 'custom', text: 'Custom' }
|
||||
],
|
||||
versionAdded: '1.25.0',
|
||||
defaultsByInstallVersion: {
|
||||
'1.25.0': 'legacy'
|
||||
},
|
||||
onChange: async (val: unknown, old?: unknown) => {
|
||||
const newValue = val as string
|
||||
const oldValue = old as string | undefined
|
||||
if (!oldValue) return
|
||||
const settingStore = useSettingStore()
|
||||
|
||||
if (newValue === 'standard') {
|
||||
await settingStore.setMany({
|
||||
'Comfy.Canvas.LeftMouseClickBehavior': 'select',
|
||||
'Comfy.Canvas.MouseWheelScroll': 'panning'
|
||||
})
|
||||
} else if (newValue === 'legacy') {
|
||||
await settingStore.setMany({
|
||||
'Comfy.Canvas.LeftMouseClickBehavior': 'panning',
|
||||
'Comfy.Canvas.MouseWheelScroll': 'zoom'
|
||||
})
|
||||
}
|
||||
}
|
||||
versionAdded: '1.25.0'
|
||||
},
|
||||
{
|
||||
id: 'Comfy.Canvas.LeftMouseClickBehavior',
|
||||
category: ['LiteGraph', 'Canvas Navigation', 'LeftMouseClickBehavior'],
|
||||
name: 'Left Mouse Click Behavior',
|
||||
defaultValue: 'panning',
|
||||
defaultValue: 'select',
|
||||
type: 'radio',
|
||||
sortOrder: 50,
|
||||
sortOrder: 100,
|
||||
options: [
|
||||
{ value: 'panning', text: 'Panning' },
|
||||
{ value: 'select', text: 'Select' }
|
||||
],
|
||||
versionAdded: '1.27.4',
|
||||
onChange: async (val: unknown) => {
|
||||
const newValue = val as string
|
||||
const settingStore = useSettingStore()
|
||||
|
||||
const navigationMode = settingStore.get('Comfy.Canvas.NavigationMode')
|
||||
|
||||
if (navigationMode !== 'custom') {
|
||||
if (
|
||||
(newValue === 'select' && navigationMode === 'standard') ||
|
||||
(newValue === 'panning' && navigationMode === 'legacy')
|
||||
) {
|
||||
return
|
||||
}
|
||||
|
||||
// only set to custom if it doesn't match the preset modes
|
||||
await settingStore.set('Comfy.Canvas.NavigationMode', 'custom')
|
||||
}
|
||||
}
|
||||
versionAdded: '1.27.4'
|
||||
},
|
||||
{
|
||||
id: 'Comfy.Canvas.MouseWheelScroll',
|
||||
category: ['LiteGraph', 'Canvas Navigation', 'MouseWheelScroll'],
|
||||
name: 'Mouse Wheel Scroll',
|
||||
defaultValue: 'zoom',
|
||||
type: 'radio',
|
||||
type: 'hidden',
|
||||
deprecated: true,
|
||||
options: [
|
||||
{ value: 'panning', text: 'Panning' },
|
||||
{ value: 'zoom', text: 'Zoom in/out' }
|
||||
],
|
||||
versionAdded: '1.27.4',
|
||||
onChange: async (val: unknown) => {
|
||||
const newValue = val as string
|
||||
const settingStore = useSettingStore()
|
||||
|
||||
const navigationMode = settingStore.get('Comfy.Canvas.NavigationMode')
|
||||
|
||||
if (navigationMode !== 'custom') {
|
||||
if (
|
||||
(newValue === 'panning' && navigationMode === 'standard') ||
|
||||
(newValue === 'zoom' && navigationMode === 'legacy')
|
||||
) {
|
||||
return
|
||||
}
|
||||
|
||||
// only set to custom if it doesn't match the preset modes
|
||||
await settingStore.set('Comfy.Canvas.NavigationMode', 'custom')
|
||||
}
|
||||
}
|
||||
versionAdded: '1.27.4'
|
||||
},
|
||||
{
|
||||
id: 'Comfy.Graph.CanvasInfo',
|
||||
|
||||
@@ -57,7 +57,9 @@ export interface FormItem {
|
||||
type: SettingInputType | SettingCustomRenderer
|
||||
tooltip?: string
|
||||
attrs?: Record<string, unknown>
|
||||
options?: Array<string | SettingOption>
|
||||
options?:
|
||||
| Array<string | SettingOption>
|
||||
| ((value?: unknown) => Array<string | SettingOption>)
|
||||
}
|
||||
|
||||
export interface ISettingGroup {
|
||||
|
||||
@@ -119,7 +119,7 @@ describe('useCanvasInteractions', () => {
|
||||
describe('handleWheel', () => {
|
||||
it('should forward ctrl+wheel events to canvas in standard nav mode', () => {
|
||||
const { get } = useSettingStore()
|
||||
vi.mocked(get).mockReturnValue('standard')
|
||||
vi.mocked(get).mockReturnValue('trackpad')
|
||||
|
||||
const { handleWheel } = useCanvasInteractions()
|
||||
|
||||
@@ -134,7 +134,7 @@ describe('useCanvasInteractions', () => {
|
||||
|
||||
it('should forward all wheel events to canvas in legacy nav mode', () => {
|
||||
const { get } = useSettingStore()
|
||||
vi.mocked(get).mockReturnValue('legacy')
|
||||
vi.mocked(get).mockReturnValue('mouse')
|
||||
const { handleWheel } = useCanvasInteractions()
|
||||
|
||||
const mockEvent = createMockWheelEvent()
|
||||
@@ -146,7 +146,7 @@ describe('useCanvasInteractions', () => {
|
||||
|
||||
it('should not prevent default for regular wheel events in standard nav mode', () => {
|
||||
const { get } = useSettingStore()
|
||||
vi.mocked(get).mockReturnValue('standard')
|
||||
vi.mocked(get).mockReturnValue('trackpad')
|
||||
const { handleWheel } = useCanvasInteractions()
|
||||
|
||||
const mockEvent = createMockWheelEvent()
|
||||
@@ -157,7 +157,7 @@ describe('useCanvasInteractions', () => {
|
||||
})
|
||||
it('should forward wheel events to canvas when capture element is NOT focused', () => {
|
||||
const { get } = useSettingStore()
|
||||
vi.mocked(get).mockReturnValue('legacy')
|
||||
vi.mocked(get).mockReturnValue('mouse')
|
||||
|
||||
const captureElement = document.createElement('div')
|
||||
captureElement.setAttribute('data-capture-wheel', 'true')
|
||||
@@ -179,7 +179,7 @@ describe('useCanvasInteractions', () => {
|
||||
|
||||
it('should NOT forward wheel events when capture element IS focused', () => {
|
||||
const { get } = useSettingStore()
|
||||
vi.mocked(get).mockReturnValue('legacy')
|
||||
vi.mocked(get).mockReturnValue('mouse')
|
||||
|
||||
const captureElement = document.createElement('div')
|
||||
captureElement.setAttribute('data-capture-wheel', 'true')
|
||||
@@ -202,7 +202,7 @@ describe('useCanvasInteractions', () => {
|
||||
|
||||
it('should forward ctrl+wheel to canvas when capture element IS focused in standard mode', () => {
|
||||
const { get } = useSettingStore()
|
||||
vi.mocked(get).mockReturnValue('standard')
|
||||
vi.mocked(get).mockReturnValue('trackpad')
|
||||
|
||||
const captureElement = document.createElement('div')
|
||||
captureElement.setAttribute('data-capture-wheel', 'true')
|
||||
|
||||
@@ -15,7 +15,7 @@ export function useCanvasInteractions() {
|
||||
const { getCanvas } = canvasStore
|
||||
|
||||
const isStandardNavMode = computed(
|
||||
() => settingStore.get('Comfy.Canvas.NavigationMode') === 'standard'
|
||||
() => settingStore.get('Comfy.Graph.WheelInputMode') === 'trackpad'
|
||||
)
|
||||
|
||||
/**
|
||||
|
||||
@@ -319,6 +319,7 @@ const zSettings = z.object({
|
||||
'Comfy.Graph.DeduplicateSubgraphNodeIds': z.boolean(),
|
||||
'Comfy.Graph.LiveSelection': z.boolean(),
|
||||
'Comfy.Graph.LinkMarkers': z.nativeEnum(LinkMarkerShape),
|
||||
'Comfy.Graph.WheelInputMode': z.enum(['auto', 'mouse', 'trackpad']),
|
||||
'Comfy.Graph.ZoomSpeed': z.number(),
|
||||
'Comfy.Group.DoubleClickTitleToEdit': z.boolean(),
|
||||
'Comfy.GroupSelectedNodes.Padding': z.number(),
|
||||
|
||||
Reference in New Issue
Block a user