IO: rework interleaved keys<>char trickling: only trickle for keys known to be likely to input characters. (#7889, #4921, #4858)
Amend fa2b318d
. Refer to regression test "inputs_io_inputqueue" amended for IMGUI_VERSION_NUM >= 19102
This commit is contained in:
parent
fabceaf036
commit
092c88dc7b
24
imgui.cpp
24
imgui.cpp
@ -8780,8 +8780,9 @@ static int CalcRoutingScore(ImGuiID focus_scope_id, ImGuiID owner_id, ImGuiInput
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// We need this to filter some Shortcut() routes when an item e.g. an InputText() is active
|
// - We need this to filter some Shortcut() routes when an item e.g. an InputText() is active
|
||||||
// e.g. ImGuiKey_G won't be considered a shortcut when item is active, but ImGuiMod|ImGuiKey_G can be.
|
// e.g. ImGuiKey_G won't be considered a shortcut when item is active, but ImGuiMod|ImGuiKey_G can be.
|
||||||
|
// - This is also used by UpdateInputEvents() to avoid trickling in the most common case of e.g. pressing ImGuiKey_G also emitting a G character.
|
||||||
static bool IsKeyChordPotentiallyCharInput(ImGuiKeyChord key_chord)
|
static bool IsKeyChordPotentiallyCharInput(ImGuiKeyChord key_chord)
|
||||||
{
|
{
|
||||||
// Mimic 'ignore_char_inputs' logic in InputText()
|
// Mimic 'ignore_char_inputs' logic in InputText()
|
||||||
@ -8795,6 +8796,8 @@ static bool IsKeyChordPotentiallyCharInput(ImGuiKeyChord key_chord)
|
|||||||
|
|
||||||
// Return true for A-Z, 0-9 and other keys associated to char inputs. Other keys such as F1-F12 won't be filtered.
|
// Return true for A-Z, 0-9 and other keys associated to char inputs. Other keys such as F1-F12 won't be filtered.
|
||||||
ImGuiKey key = (ImGuiKey)(key_chord & ~ImGuiMod_Mask_);
|
ImGuiKey key = (ImGuiKey)(key_chord & ~ImGuiMod_Mask_);
|
||||||
|
if (key == ImGuiKey_None)
|
||||||
|
return false;
|
||||||
return g.KeysMayBeCharInput.TestBit(key);
|
return g.KeysMayBeCharInput.TestBit(key);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -9599,9 +9602,9 @@ void ImGui::UpdateInputEvents(bool trickle_fast_inputs)
|
|||||||
// Only trickle chars<>key when working with InputText()
|
// Only trickle chars<>key when working with InputText()
|
||||||
// FIXME: InputText() could parse event trail?
|
// FIXME: InputText() could parse event trail?
|
||||||
// FIXME: Could specialize chars<>keys trickling rules for control keys (those not typically associated to characters)
|
// FIXME: Could specialize chars<>keys trickling rules for control keys (those not typically associated to characters)
|
||||||
const bool trickle_interleaved_keys_and_text = (trickle_fast_inputs && g.WantTextInputNextFrame == 1);
|
const bool trickle_interleaved_nonchar_keys_and_text = (trickle_fast_inputs && g.WantTextInputNextFrame == 1);
|
||||||
|
|
||||||
bool mouse_moved = false, mouse_wheeled = false, key_changed = false, text_inputted = false;
|
bool mouse_moved = false, mouse_wheeled = false, key_changed = false, key_changed_nonchar = false, text_inputted = false;
|
||||||
int mouse_button_changed = 0x00;
|
int mouse_button_changed = 0x00;
|
||||||
ImBitArray<ImGuiKey_KeysData_SIZE> key_changed_mask;
|
ImBitArray<ImGuiKey_KeysData_SIZE> key_changed_mask;
|
||||||
|
|
||||||
@ -9653,12 +9656,19 @@ void ImGui::UpdateInputEvents(bool trickle_fast_inputs)
|
|||||||
IM_ASSERT(key != ImGuiKey_None);
|
IM_ASSERT(key != ImGuiKey_None);
|
||||||
ImGuiKeyData* key_data = GetKeyData(key);
|
ImGuiKeyData* key_data = GetKeyData(key);
|
||||||
const int key_data_index = (int)(key_data - g.IO.KeysData);
|
const int key_data_index = (int)(key_data - g.IO.KeysData);
|
||||||
if (trickle_fast_inputs && key_data->Down != e->Key.Down && (key_changed_mask.TestBit(key_data_index) || text_inputted || mouse_button_changed != 0))
|
if (trickle_fast_inputs && key_data->Down != e->Key.Down && (key_changed_mask.TestBit(key_data_index) || mouse_button_changed != 0))
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
const bool key_is_potentially_for_char_input = IsKeyChordPotentiallyCharInput(GetMergedModsFromKeys() | key);
|
||||||
|
if (trickle_interleaved_nonchar_keys_and_text && (text_inputted && !key_is_potentially_for_char_input))
|
||||||
|
break;
|
||||||
|
|
||||||
key_data->Down = e->Key.Down;
|
key_data->Down = e->Key.Down;
|
||||||
key_data->AnalogValue = e->Key.AnalogValue;
|
key_data->AnalogValue = e->Key.AnalogValue;
|
||||||
key_changed = true;
|
key_changed = true;
|
||||||
key_changed_mask.SetBit(key_data_index);
|
key_changed_mask.SetBit(key_data_index);
|
||||||
|
if (trickle_interleaved_nonchar_keys_and_text && !key_is_potentially_for_char_input)
|
||||||
|
key_changed_nonchar = true;
|
||||||
|
|
||||||
// Allow legacy code using io.KeysDown[GetKeyIndex()] with new backends
|
// Allow legacy code using io.KeysDown[GetKeyIndex()] with new backends
|
||||||
#ifndef IMGUI_DISABLE_OBSOLETE_KEYIO
|
#ifndef IMGUI_DISABLE_OBSOLETE_KEYIO
|
||||||
@ -9672,11 +9682,13 @@ void ImGui::UpdateInputEvents(bool trickle_fast_inputs)
|
|||||||
if (io.ConfigFlags & ImGuiConfigFlags_NoKeyboard)
|
if (io.ConfigFlags & ImGuiConfigFlags_NoKeyboard)
|
||||||
continue;
|
continue;
|
||||||
// Trickling Rule: Stop processing queued events if keys/mouse have been interacted with
|
// Trickling Rule: Stop processing queued events if keys/mouse have been interacted with
|
||||||
if (trickle_fast_inputs && ((key_changed && trickle_interleaved_keys_and_text) || mouse_button_changed != 0 || mouse_moved || mouse_wheeled))
|
if (trickle_fast_inputs && (mouse_button_changed != 0 || mouse_moved || mouse_wheeled))
|
||||||
|
break;
|
||||||
|
if (trickle_interleaved_nonchar_keys_and_text && key_changed_nonchar)
|
||||||
break;
|
break;
|
||||||
unsigned int c = e->Text.Char;
|
unsigned int c = e->Text.Char;
|
||||||
io.InputQueueCharacters.push_back(c <= IM_UNICODE_CODEPOINT_MAX ? (ImWchar)c : IM_UNICODE_CODEPOINT_INVALID);
|
io.InputQueueCharacters.push_back(c <= IM_UNICODE_CODEPOINT_MAX ? (ImWchar)c : IM_UNICODE_CODEPOINT_INVALID);
|
||||||
if (trickle_interleaved_keys_and_text)
|
if (trickle_interleaved_nonchar_keys_and_text)
|
||||||
text_inputted = true;
|
text_inputted = true;
|
||||||
}
|
}
|
||||||
else if (e->Type == ImGuiInputEventType_Focus)
|
else if (e->Type == ImGuiInputEventType_Focus)
|
||||||
|
2
imgui.h
2
imgui.h
@ -29,7 +29,7 @@
|
|||||||
// Library Version
|
// Library Version
|
||||||
// (Integer encoded as XYYZZ for use in #if preprocessor conditionals, e.g. '#if IMGUI_VERSION_NUM >= 12345')
|
// (Integer encoded as XYYZZ for use in #if preprocessor conditionals, e.g. '#if IMGUI_VERSION_NUM >= 12345')
|
||||||
#define IMGUI_VERSION "1.91.1 WIP"
|
#define IMGUI_VERSION "1.91.1 WIP"
|
||||||
#define IMGUI_VERSION_NUM 19101
|
#define IMGUI_VERSION_NUM 19102
|
||||||
#define IMGUI_HAS_TABLE
|
#define IMGUI_HAS_TABLE
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
Loading…
Reference in New Issue
Block a user