fix(opencode): sets input mode based on whether mouse vs keyboard is in use to prevent mouse events firing (#9449)
This commit is contained in:
@@ -85,6 +85,7 @@ export function Autocomplete(props: {
|
|||||||
index: 0,
|
index: 0,
|
||||||
selected: 0,
|
selected: 0,
|
||||||
visible: false as AutocompleteRef["visible"],
|
visible: false as AutocompleteRef["visible"],
|
||||||
|
input: "keyboard" as "keyboard" | "mouse",
|
||||||
})
|
})
|
||||||
|
|
||||||
const [positionTick, setPositionTick] = createSignal(0)
|
const [positionTick, setPositionTick] = createSignal(0)
|
||||||
@@ -128,6 +129,14 @@ export function Autocomplete(props: {
|
|||||||
return props.input().getTextRange(store.index + 1, props.input().cursorOffset)
|
return props.input().getTextRange(store.index + 1, props.input().cursorOffset)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
// When the filter changes due to how TUI works, the mousemove might still be triggered
|
||||||
|
// via a synthetic event as the layout moves underneath the cursor. This is a workaround to make sure the input mode remains keyboard so
|
||||||
|
// that the mouseover event doesn't trigger when filtering.
|
||||||
|
createEffect(() => {
|
||||||
|
filter();
|
||||||
|
setStore("input", "keyboard")
|
||||||
|
})
|
||||||
|
|
||||||
function insertPart(text: string, part: PromptInfo["parts"][number]) {
|
function insertPart(text: string, part: PromptInfo["parts"][number]) {
|
||||||
const input = props.input()
|
const input = props.input()
|
||||||
const currentCursorOffset = input.cursorOffset
|
const currentCursorOffset = input.cursorOffset
|
||||||
@@ -525,11 +534,13 @@ export function Autocomplete(props: {
|
|||||||
const isNavDown = name === "down" || (ctrlOnly && name === "n")
|
const isNavDown = name === "down" || (ctrlOnly && name === "n")
|
||||||
|
|
||||||
if (isNavUp) {
|
if (isNavUp) {
|
||||||
|
setStore("input", "keyboard")
|
||||||
move(-1)
|
move(-1)
|
||||||
e.preventDefault()
|
e.preventDefault()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if (isNavDown) {
|
if (isNavDown) {
|
||||||
|
setStore("input", "keyboard")
|
||||||
move(1)
|
move(1)
|
||||||
e.preventDefault()
|
e.preventDefault()
|
||||||
return
|
return
|
||||||
@@ -612,7 +623,17 @@ export function Autocomplete(props: {
|
|||||||
paddingRight={1}
|
paddingRight={1}
|
||||||
backgroundColor={index === store.selected ? theme.primary : undefined}
|
backgroundColor={index === store.selected ? theme.primary : undefined}
|
||||||
flexDirection="row"
|
flexDirection="row"
|
||||||
onMouseOver={() => moveTo(index)}
|
onMouseMove={() => {
|
||||||
|
setStore("input", "mouse")
|
||||||
|
}}
|
||||||
|
onMouseOver={() => {
|
||||||
|
if (store.input !== "mouse") return
|
||||||
|
moveTo(index)
|
||||||
|
}}
|
||||||
|
onMouseDown={() => {
|
||||||
|
setStore("input", "mouse")
|
||||||
|
moveTo(index)
|
||||||
|
}}
|
||||||
onMouseUp={() => select()}
|
onMouseUp={() => select()}
|
||||||
>
|
>
|
||||||
<text fg={index === store.selected ? selectedForeground(theme) : theme.text} flexShrink={0}>
|
<text fg={index === store.selected ? selectedForeground(theme) : theme.text} flexShrink={0}>
|
||||||
|
|||||||
@@ -52,6 +52,7 @@ export function DialogSelect<T>(props: DialogSelectProps<T>) {
|
|||||||
const [store, setStore] = createStore({
|
const [store, setStore] = createStore({
|
||||||
selected: 0,
|
selected: 0,
|
||||||
filter: "",
|
filter: "",
|
||||||
|
input: "keyboard" as "keyboard" | "mouse",
|
||||||
})
|
})
|
||||||
|
|
||||||
createEffect(
|
createEffect(
|
||||||
@@ -83,6 +84,14 @@ export function DialogSelect<T>(props: DialogSelectProps<T>) {
|
|||||||
return result
|
return result
|
||||||
})
|
})
|
||||||
|
|
||||||
|
// When the filter changes due to how TUI works, the mousemove might still be triggered
|
||||||
|
// via a synthetic event as the layout moves underneath the cursor. This is a workaround to make sure the input mode remains keyboard
|
||||||
|
// that the mouseover event doesn't trigger when filtering.
|
||||||
|
createEffect(() => {
|
||||||
|
filtered();
|
||||||
|
setStore("input", "keyboard")
|
||||||
|
})
|
||||||
|
|
||||||
const grouped = createMemo(() => {
|
const grouped = createMemo(() => {
|
||||||
const result = pipe(
|
const result = pipe(
|
||||||
filtered(),
|
filtered(),
|
||||||
@@ -157,12 +166,15 @@ export function DialogSelect<T>(props: DialogSelectProps<T>) {
|
|||||||
|
|
||||||
const keybind = useKeybind()
|
const keybind = useKeybind()
|
||||||
useKeyboard((evt) => {
|
useKeyboard((evt) => {
|
||||||
|
setStore("input", "keyboard")
|
||||||
|
|
||||||
if (evt.name === "up" || (evt.ctrl && evt.name === "p")) move(-1)
|
if (evt.name === "up" || (evt.ctrl && evt.name === "p")) move(-1)
|
||||||
if (evt.name === "down" || (evt.ctrl && evt.name === "n")) move(1)
|
if (evt.name === "down" || (evt.ctrl && evt.name === "n")) move(1)
|
||||||
if (evt.name === "pageup") move(-10)
|
if (evt.name === "pageup") move(-10)
|
||||||
if (evt.name === "pagedown") move(10)
|
if (evt.name === "pagedown") move(10)
|
||||||
if (evt.name === "home") moveTo(0)
|
if (evt.name === "home") moveTo(0)
|
||||||
if (evt.name === "end") moveTo(flat().length - 1)
|
if (evt.name === "end") moveTo(flat().length - 1)
|
||||||
|
|
||||||
if (evt.name === "return") {
|
if (evt.name === "return") {
|
||||||
const option = selected()
|
const option = selected()
|
||||||
if (option) {
|
if (option) {
|
||||||
@@ -259,11 +271,20 @@ export function DialogSelect<T>(props: DialogSelectProps<T>) {
|
|||||||
<box
|
<box
|
||||||
id={JSON.stringify(option.value)}
|
id={JSON.stringify(option.value)}
|
||||||
flexDirection="row"
|
flexDirection="row"
|
||||||
|
onMouseMove={() => {
|
||||||
|
setStore("input", "mouse")
|
||||||
|
}}
|
||||||
onMouseUp={() => {
|
onMouseUp={() => {
|
||||||
option.onSelect?.(dialog)
|
option.onSelect?.(dialog)
|
||||||
props.onSelect?.(option)
|
props.onSelect?.(option)
|
||||||
}}
|
}}
|
||||||
onMouseOver={() => {
|
onMouseOver={() => {
|
||||||
|
if (store.input !== "mouse") return
|
||||||
|
const index = flat().findIndex((x) => isDeepEqual(x.value, option.value))
|
||||||
|
if (index === -1) return
|
||||||
|
moveTo(index)
|
||||||
|
}}
|
||||||
|
onMouseDown={() => {
|
||||||
const index = flat().findIndex((x) => isDeepEqual(x.value, option.value))
|
const index = flat().findIndex((x) => isDeepEqual(x.value, option.value))
|
||||||
if (index === -1) return
|
if (index === -1) return
|
||||||
moveTo(index)
|
moveTo(index)
|
||||||
|
|||||||
Reference in New Issue
Block a user