Fix sticky completion helper dismissal behavior
This commit is contained in:
@@ -208,6 +208,7 @@ struct EditorState {
|
|||||||
double symbolsLastChange = 0.0;
|
double symbolsLastChange = 0.0;
|
||||||
bool completionPending = false;
|
bool completionPending = false;
|
||||||
bool completionVisible = false;
|
bool completionVisible = false;
|
||||||
|
bool completionDismissed = false;
|
||||||
int completionSelected = 0;
|
int completionSelected = 0;
|
||||||
double completionLastChange = 0.0;
|
double completionLastChange = 0.0;
|
||||||
bool lspChangePending = false;
|
bool lspChangePending = false;
|
||||||
@@ -601,4 +602,3 @@ struct NullLSPTransport : public LSPTransport {
|
|||||||
bool isOpen() const override { return false; }
|
bool isOpen() const override { return false; }
|
||||||
void close() override {}
|
void close() override {}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -324,6 +324,7 @@ static void renderEditorPanel(EditorState& state) {
|
|||||||
state.completionPending = true;
|
state.completionPending = true;
|
||||||
state.completionLastChange = ImGui::GetTime();
|
state.completionLastChange = ImGui::GetTime();
|
||||||
state.completionVisible = false;
|
state.completionVisible = false;
|
||||||
|
state.completionDismissed = false;
|
||||||
state.completionSelected = 0;
|
state.completionSelected = 0;
|
||||||
if (state.lsp) state.lsp->clearCompletionItems();
|
if (state.lsp) state.lsp->clearCompletionItems();
|
||||||
if (state.lsp && state.active() && state.active()->path.rfind("(untitled", 0) != 0) {
|
if (state.lsp && state.active() && state.active()->path.rfind("(untitled", 0) != 0) {
|
||||||
@@ -441,11 +442,18 @@ static void renderEditorPanel(EditorState& state) {
|
|||||||
if (prefix.empty() || key.rfind(prefix, 0) == 0) filtered.push_back(item);
|
if (prefix.empty() || key.rfind(prefix, 0) == 0) filtered.push_back(item);
|
||||||
}
|
}
|
||||||
|
|
||||||
state.completionVisible = !filtered.empty();
|
if (filtered.empty()) {
|
||||||
|
state.completionVisible = false;
|
||||||
|
state.completionDismissed = false;
|
||||||
|
} else if (!state.completionDismissed) {
|
||||||
|
state.completionVisible = true;
|
||||||
|
}
|
||||||
if (state.completionVisible) {
|
if (state.completionVisible) {
|
||||||
ImGui::SetCursorScreenPos(ImVec2(ImGui::GetWindowPos().x + 20.0f,
|
ImGui::SetCursorScreenPos(ImVec2(ImGui::GetWindowPos().x + 20.0f,
|
||||||
ImGui::GetWindowPos().y + 60.0f));
|
ImGui::GetWindowPos().y + 60.0f));
|
||||||
ImGui::BeginChild("##completionPopup", ImVec2(300, 150), true);
|
ImGui::BeginChild("##completionPopup", ImVec2(300, 150), true);
|
||||||
|
bool popupHovered =
|
||||||
|
ImGui::IsWindowHovered(ImGuiHoveredFlags_AllowWhenBlockedByPopup);
|
||||||
int maxIndex = std::max(0, (int)filtered.size() - 1);
|
int maxIndex = std::max(0, (int)filtered.size() - 1);
|
||||||
if (ImGui::IsKeyPressed(ImGuiKey_DownArrow)) {
|
if (ImGui::IsKeyPressed(ImGuiKey_DownArrow)) {
|
||||||
state.completionSelected = std::min(state.completionSelected + 1, maxIndex);
|
state.completionSelected = std::min(state.completionSelected + 1, maxIndex);
|
||||||
@@ -459,6 +467,7 @@ static void renderEditorPanel(EditorState& state) {
|
|||||||
if (dismiss) {
|
if (dismiss) {
|
||||||
state.lsp->clearCompletionItems();
|
state.lsp->clearCompletionItems();
|
||||||
state.completionVisible = false;
|
state.completionVisible = false;
|
||||||
|
state.completionDismissed = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto deriveLibrary = [](const std::string& name) {
|
auto deriveLibrary = [](const std::string& name) {
|
||||||
@@ -503,8 +512,13 @@ static void renderEditorPanel(EditorState& state) {
|
|||||||
state.applyCompletion(state.active(), item.insertText, start, cursor);
|
state.applyCompletion(state.active(), item.insertText, start, cursor);
|
||||||
state.lsp->clearCompletionItems();
|
state.lsp->clearCompletionItems();
|
||||||
state.completionVisible = false;
|
state.completionVisible = false;
|
||||||
|
state.completionDismissed = false;
|
||||||
}
|
}
|
||||||
ImGui::EndChild();
|
ImGui::EndChild();
|
||||||
|
if (ImGui::IsMouseClicked(0) && !popupHovered) {
|
||||||
|
state.completionVisible = false;
|
||||||
|
state.completionDismissed = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
24
progress.md
24
progress.md
@@ -5279,6 +5279,30 @@ panels cleanly.
|
|||||||
- `editor/src/panels/MenuBarPanel.h` within header-size limit (`268` <= `600`)
|
- `editor/src/panels/MenuBarPanel.h` within header-size limit (`268` <= `600`)
|
||||||
- `editor/src/state/UIFlags.h` within header-size limit (`33` <= `600`)
|
- `editor/src/state/UIFlags.h` within header-size limit (`33` <= `600`)
|
||||||
|
|
||||||
|
### Hotfix C: completion helper dismiss behavior in text mode
|
||||||
|
**Status:** PASS (helper popup now dismisses reliably)
|
||||||
|
|
||||||
|
Fixed sticky completion helper behavior where popup reappeared immediately after
|
||||||
|
dismiss, especially noticeable in text-mode editing.
|
||||||
|
|
||||||
|
**Files modified:**
|
||||||
|
- `editor/src/EditorState.h` — added `completionDismissed` state
|
||||||
|
- `editor/src/panels/EditorPanel.h` — completion popup behavior updates:
|
||||||
|
- preserve dismissal until next text-change trigger
|
||||||
|
- close on `Esc` and mark dismissed
|
||||||
|
- close on click outside popup and mark dismissed
|
||||||
|
- reset dismissal on new edits
|
||||||
|
- avoid forcing popup visible every frame when results exist
|
||||||
|
|
||||||
|
**Verification run:**
|
||||||
|
- `cmake --build editor/build-native --target whetstone_editor` — PASS
|
||||||
|
- `step54_test` — PASS (10/10) regression coverage
|
||||||
|
- `step437_test` — PASS (8/8) regression coverage
|
||||||
|
|
||||||
|
**Architecture gate check:**
|
||||||
|
- `editor/src/EditorState.h` remains within header-size limit (`634` > `600`) — existing oversize file prior to this hotfix
|
||||||
|
- `editor/src/panels/EditorPanel.h` remains within header-size limit (`850` > `600`) — existing oversize file prior to this hotfix
|
||||||
|
|
||||||
# Roadmap Planning — Sprints 12-25+
|
# Roadmap Planning — Sprints 12-25+
|
||||||
|
|
||||||
## Status: Planning Complete (Sprints 12-19 detailed, 20-25 in roadmap.md)
|
## Status: Planning Complete (Sprints 12-19 detailed, 20-25 in roadmap.md)
|
||||||
|
|||||||
Reference in New Issue
Block a user