Make commandline process request buffered page keys from page process

This commit is contained in:
petoncle 2023-10-29 11:48:15 +01:00
parent 6b61b69455
commit dbe5a8e8a6
3 changed files with 41 additions and 69 deletions

View file

@ -82,12 +82,7 @@ const commandline_state = {
keyEvents: new Array<MinimalKey>(), keyEvents: new Array<MinimalKey>(),
refresh_completions, refresh_completions,
state, state,
keysFromContentProcess: [], initialClInputValue: "",
consumedKeyCount: 0,
clInputFocused: false,
clInputNormalEventsReceived: false,
clInputInitialValue: "",
contentProcessKeysReceivedAfterClInputFocused: 0
} }
// first theming of commandline iframe // first theming of commandline iframe
@ -168,55 +163,38 @@ const noblur = () => setTimeout(() => commandline_state.clInput.focus(), 0)
/** @hidden **/ /** @hidden **/
export function focus() { export function focus() {
logger.debug("Called focus()")
commandline_state.clInput.focus() commandline_state.clInput.focus()
commandline_state.clInput.removeEventListener("blur", noblur) commandline_state.clInput.removeEventListener("blur", noblur)
commandline_state.clInput.addEventListener("blur", noblur) commandline_state.clInput.addEventListener("blur", noblur)
commandline_state.clInputFocused = true logger.debug("Called focus()")
Messaging.messageOwnTab("cl_input_focused", "unused") Messaging.messageOwnTab("buffered_page_keys", "").then((bufferedPageKeys : string[]) => {
const keysFromContentProcess = commandline_state.keysFromContentProcess; let clInputStillFocused = window.document.activeElement === commandline_state.clInput;
if (keysFromContentProcess.length !== 0) { logger.debug("buffered_page_keys response received", bufferedPageKeys,
logger.debug("Consuming " + JSON.stringify(keysFromContentProcess.slice(commandline_state.consumedKeyCount))); "clInputStillFocused = " + clInputStillFocused)
for (let keyIndex = commandline_state.consumedKeyCount; keyIndex < keysFromContentProcess.length; keyIndex++) { if (!clInputStillFocused)
const key = keysFromContentProcess[keyIndex];
commandline_state.clInput.value += key
clInputValueChanged()
commandline_state.consumedKeyCount++;
}
}
}
export function bufferUntilClInputFocused(bufferedClInputKeys) {
logger.debug("Command line process received content process keys: " + bufferedClInputKeys)
if (bufferedClInputKeys.length < commandline_state.keysFromContentProcess.length)
return return
commandline_state.keysFromContentProcess = bufferedClInputKeys; if (bufferedPageKeys.length !== 0) {
const keysFromContentProcess = commandline_state.keysFromContentProcess; const currentClInputValue = commandline_state.clInput.value;
if (commandline_state.clInputFocused) { // Native events are assumed to be characters added at the end of clInput.
for (let keyIndex = commandline_state.consumedKeyCount; keyIndex < keysFromContentProcess.length; keyIndex++) { const clInputNativeEventKeysReceived = commandline_state.initialClInputValue.length > currentClInputValue.length
const key = keysFromContentProcess[keyIndex]; logger.debug("Consuming buffered page keys", bufferedPageKeys,
logger.debug("Dispatching received keydown event " + key + " since clInputFocused is true," + "initialClInputValue = " + commandline_state.initialClInputValue,
" clInputNormalEventsReceived = " + commandline_state.clInputNormalEventsReceived + "currentClInputValue = " + currentClInputValue);
" contentProcessKeysReceivedAfterClInputFocused = " + commandline_state.contentProcessKeysReceivedAfterClInputFocused + if (clInputNativeEventKeysReceived) {
" clInputInitialValue = " + commandline_state.clInputInitialValue) // Insert page keys at the end.
if (!commandline_state.clInputNormalEventsReceived) { commandline_state.clInput.value += bufferedPageKeys.join("")
// Insert at the end.
commandline_state.clInput.value += key
} else { } else {
// Normal keys are assumed to always be at the end. let initialClInputValueLength = commandline_state.initialClInputValue.length;
let normalKeyCount = commandline_state.contentProcessKeysReceivedAfterClInputFocused; // Insert page keys just after the command.
let initialCommandLength = commandline_state.clInputInitialValue.length;
// Insert received key at the beginning.
commandline_state.clInput.value = commandline_state.clInput.value =
commandline_state.clInput.value.substring(0, initialCommandLength + normalKeyCount) currentClInputValue.substring(0, initialClInputValueLength)
+ key + bufferedPageKeys.join("")
+ commandline_state.clInput.value.substring(initialCommandLength + normalKeyCount) + currentClInputValue.substring(initialClInputValueLength)
commandline_state.contentProcessKeysReceivedAfterClInputFocused++;
} }
commandline_state.consumedKeyCount++; // Update completion.
clInputValueChanged() clInputValueChanged()
} }
} })
} }
/** @hidden **/ /** @hidden **/
@ -241,7 +219,6 @@ commandline_state.clInput.addEventListener(
function (keyevent: KeyboardEvent) { function (keyevent: KeyboardEvent) {
if (!keyevent.isTrusted) return if (!keyevent.isTrusted) return
logger.info("Called keydown event listener") logger.info("Called keydown event listener")
commandline_state.clInputNormalEventsReceived = true
commandline_state.keyEvents.push(minimalKeyFromKeyboardEvent(keyevent)) commandline_state.keyEvents.push(minimalKeyFromKeyboardEvent(keyevent))
const response = keyParser(commandline_state.keyEvents) const response = keyParser(commandline_state.keyEvents)
if (response.isMatch) { if (response.isMatch) {
@ -407,7 +384,7 @@ export function fillcmdline(
// 3. Stop forwarding key events from content process to command line process. // 3. Stop forwarding key events from content process to command line process.
if (trailspace) commandline_state.clInput.value = newcommand + " " if (trailspace) commandline_state.clInput.value = newcommand + " "
else commandline_state.clInput.value = newcommand else commandline_state.clInput.value = newcommand
commandline_state.clInputInitialValue = commandline_state.clInput.value commandline_state.initialClInputValue = commandline_state.clInput.value
commandline_state.isVisible = true commandline_state.isVisible = true
let result = Promise.resolve([]) let result = Promise.resolve([])
// Focus is lost for some reason. // Focus is lost for some reason.

View file

@ -193,9 +193,9 @@ function* ParserController() {
if (response.exstr) { if (response.exstr) {
exstr = response.exstr exstr = response.exstr
if (exstr.startsWith("fillcmdline ")) { // Ugh. That's ugly. I needed a way to know if this command is going to open the cmdline. if (exstr.startsWith("fillcmdline ")) { // Ugh. That's ugly. I needed a way to know if this command is going to open the cmdline.
logger.debug("Setting clInputFocused to false") logger.debug("Setting mustBufferPageKeysForClInput to true")
clInputFocused = false mustBufferPageKeysForClInput = true
bufferedClInputKeys = [] bufferedPageKeys = []
} }
break break
} else { } else {
@ -217,25 +217,27 @@ function* ParserController() {
} }
} }
} }
Messaging.addListener("cl_input_focused", () => { Messaging.addListener("buffered_page_keys", (message, sender, sendResponse) => {
logger.debug("Callback cl_input_focused") logger.debug("buffered_page_keys request received, responding with", bufferedPageKeys)
clInputFocused = true // At this point, clInput is focused and the page will not get any more keyboard events.
sendResponse(Promise.resolve(bufferedPageKeys))
mustBufferPageKeysForClInput = false
bufferedPageKeys = []
}) })
let clInputFocused: boolean = true let mustBufferPageKeysForClInput = false
let bufferedClInputKeys: string[] = [] let bufferedPageKeys: string[] = []
export const generator = ParserController() // var rather than let stops weirdness in repl. export const generator = ParserController() // var rather than let stops weirdness in repl.
generator.next() generator.next()
/** Feed keys to the ParserController */ /** Feed keys to the ParserController */
export function acceptKey(keyevent: KeyboardEvent) { export function acceptKey(keyevent: KeyboardEvent) {
logger.debug("clInputFocused = " + clInputFocused) logger.debug("mustBufferPageKeysForClInput = " + mustBufferPageKeysForClInput)
if (!clInputFocused) { if (mustBufferPageKeysForClInput) {
let isCharacterKey = keyevent.key.length == 1 let isCharacterKey = keyevent.key.length == 1
&& !keyevent.metaKey && !keyevent.ctrlKey && !keyevent.altKey && !keyevent.metaKey; && !keyevent.metaKey && !keyevent.ctrlKey && !keyevent.altKey && !keyevent.metaKey;
if (isCharacterKey) { if (isCharacterKey) {
bufferedClInputKeys.push(keyevent.key); bufferedPageKeys.push(keyevent.key);
logger.debug("Sending keyboardEvent for buffering ", bufferedClInputKeys) logger.debug("Buffering page keys for clInput", bufferedPageKeys)
Messaging.messageOwnTab("commandline_frame", "bufferUntilClInputFocused", [ bufferedClInputKeys ]);
} }
keyevent.preventDefault() keyevent.preventDefault()
keyevent.stopImmediatePropagation() keyevent.stopImmediatePropagation()

View file

@ -138,13 +138,6 @@ export function getCommandlineFns(cmdline_state: {
) )
cmdline_state.activeCompletions = undefined cmdline_state.activeCompletions = undefined
cmdline_state.isVisible = false cmdline_state.isVisible = false
console.debug("Called hide_and_clear()")
cmdline_state.keysFromContentProcess = []
cmdline_state.consumedKeyCount = 0
cmdline_state.clInputFocused = false
cmdline_state.clInputNormalEventsReceived = false
cmdline_state.clInputInitialValue = ""
cmdline_state.contentProcessKeysReceivedAfterClInputFocused = 0
}, },
/** /**