-
Notifications
You must be signed in to change notification settings - Fork 83
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Multiline text widget displays incorrect text in some circumstances #295
Comments
Your example code could be simplified to the bare minimum, e.g. from imgui_bundle import imgui, hello_imgui
static_text = """
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod
tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim
veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex
ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate
velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint
occaecat cupidatat non proident, sunt in culpa qui officia deserunt
mollit anim id est laborum.
"""
frame_count = 0
def gui():
global frame_count
imgui.text("Should reveal text over time.")
imgui.text("Click in the multiline text widget to see invisible and erroneous characters")
imgui.text("Then click outside the widget to see the correct text restored")
imgui.text("Code taken from demo_widgets.py")
def callback(cb_data):
bufpos = int(frame_count / 2)
cb_data.selection_start = bufpos
cb_data.selection_end = bufpos
cb_data.cursor_pos = bufpos
return 0
imgui.input_text_multiline(
"readonly_multiline",
static_text[:int(frame_count/2)],
(600, 200),
imgui.InputTextFlags_.read_only | imgui.InputTextFlags_.callback_always,
callback=callback
)
frame_count += 1
if frame_count > 2*len(static_text):
frame_count = 0
hello_imgui.run(gui, fps_idle=0) # where fps_idle=0 will let the app always run at full speed |
I initially wrote "should", but meant "could". |
And the equivalent c++ program would be: #include <imgui.h>
#include "misc/cpp/imgui_stdlib.h"
#include <hello_imgui/hello_imgui.h>
std::string static_text = R"(
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod
tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim
veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex
ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate
velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint
occaecat cupidatat non proident, sunt in culpa qui officia deserunt
mollit anim id est laborum.
)";
int frame_count = 0;
void gui()
{
ImGui::Text("Should reveal text over time.");
ImGui::Text("Click in the multiline text widget to see invisible and erroneous characters");
ImGui::Text("Then click outside the widget to see the correct text restored");
ImGui::Text("Code taken from demo_widgets.py");
auto callback = [](ImGuiInputTextCallbackData* cb_data) -> int
{
int bufpos = frame_count / 2;
cb_data->SelectionStart = bufpos;
cb_data->SelectionEnd = bufpos;
cb_data->CursorPos = bufpos;
return 0;
};
std::string subtext = static_text.substr(0, frame_count / 2);
ImGui::InputTextMultiline(
"readonly_multiline",
&subtext,
ImVec2(600, 200),
ImGuiInputTextFlags_ReadOnly | ImGuiInputTextFlags_CallbackAlways,
callback
);
frame_count++;
if (frame_count > 2 * static_text.size())
frame_count = 0;
}
int main()
{
HelloImGui::Run(gui);
}
And we observe the same issue with the C++ program, so all in all this related to Dear ImGui itself. However, let's have a deep look at those two lines: std::string subtext = static_text.substr(0, frame_count / 2);
ImGui::InputTextMultiline(
"readonly_multiline",
&subtext,
ImVec2(600, 200),
ImGuiInputTextFlags_ReadOnly | ImGuiInputTextFlags_CallbackAlways,
callback
); On each frame, you are creating a new string, and asking to display a widget to edit this string. So I have a question about your use case: are trying to use the text editor as a "scrollable long text renderer"? |
As an explanation for the behavior, that seems somewhat likely, except that the "flashing" is persistent between renders and changes modes based on unrelated activity. It's still a bug, though... I am passing a string to
It's being used as an interactive REPL console, so it's both a "scrollable long text renderer" and an interactive editable. I have it as |
The C/C++ version below does not create a string at each frame, and reuses the same char* address (aka "buffer" below). So the issue is not due to having a string whose address that changes at every frame, but it is due to the fact that this widget displays an allegedly user-editable string but which is changed at every frame. All in all, this is due to the way Dear ImGui handles text edition. Would this be considered as a bug in ImGui? I'm not sure (TBH, I doubt it would be). You may want to post this as an issue in the imgui repo, though. Repro code: #include <imgui.h>
#include "misc/cpp/imgui_stdlib.h"
#include <hello_imgui/hello_imgui.h>
std::string static_text = R"(
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod
tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim
veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex
ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate
velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint
occaecat cupidatat non proident, sunt in culpa qui officia deserunt
mollit anim id est laborum.
)";
char buffer[2048];
int frame_count = 0;
void gui()
{
ImGui::Text("Should reveal text over time.");
ImGui::Text("Click in the multiline text widget to see invisible and erroneous characters");
ImGui::Text("Then click outside the widget to see the correct text restored");
ImGui::Text("Code taken from demo_widgets.py");
auto callback = [](ImGuiInputTextCallbackData* cb_data) -> int
{
int bufpos = frame_count / 2;
cb_data->SelectionStart = bufpos;
cb_data->SelectionEnd = bufpos;
cb_data->CursorPos = bufpos;
return 0;
};
memset(buffer, 0, sizeof(buffer));
strncpy(buffer, static_text.c_str(), frame_count / 2);
ImGui::InputTextMultiline(
"readonly_multiline",
buffer,
sizeof(buffer),
ImVec2(600, 200),
ImGuiInputTextFlags_ReadOnly | ImGuiInputTextFlags_CallbackAlways,
callback
);
frame_count++;
if (frame_count > 2 * static_text.size())
frame_count = 0;
}
int main()
{
HelloImGui::Run(gui);
} |
On a second examination, since you are passing the flag Video demo of the issue v.mp4 |
Multiline text widget that is used as a combo display and editor (a REPL console, in my app) will display incorrect text (sometimes blank, sometimes garbage characters that look like a wild pointer).
Clicking inside the widget starts the erroneous display; clicking outside the widget gets back to a good display
Repro code below. I am not sure exactly what the triggering conditions are but this is a pretty minimal case that looks a lot like my actual use case.
The text was updated successfully, but these errors were encountered: