I have just come across a similar problem although in my case it doesn’t involve long unbroken strings, but just happens with some combinations of normal text.
Here is a simple example that demonstrates the issue on linux:
import wx
import wx.stc as stc
TEXT = (
"Sunny at first, but medium level cloud increased later in the morning. "
"A weakening cold front then crossed from the west bringing thicker cloud "
"and outbreaks of rain in the early afternoon. #Weather\n"
)
class MyFrame(wx.Frame):
def __init__(self, *args, **kwds):
kwds["style"] = kwds.get("style", 0) | wx.DEFAULT_FRAME_STYLE
wx.Frame.__init__(self, *args, **kwds)
self.SetSize((500, 250))
self.SetTitle("Misaligned caret")
self.panel_1 = wx.Panel(self, wx.ID_ANY)
sizer_1 = wx.BoxSizer(wx.VERTICAL)
self.stc = stc.StyledTextCtrl(self.panel_1, wx.ID_ANY, style=wx.TE_MULTILINE)
sizer_1.Add(self.stc, 1, wx.ALL | wx.EXPAND, 8)
sizer_2 = wx.BoxSizer(wx.HORIZONTAL)
sizer_1.Add(sizer_2, 0, wx.ALIGN_CENTER_HORIZONTAL | wx.BOTTOM, 8)
self.close_button = wx.Button(self.panel_1, wx.ID_ANY, "Close")
sizer_2.Add(self.close_button, 0, wx.RIGHT, 16)
self.panel_1.SetSizer(sizer_1)
self.Layout()
self.Bind(wx.EVT_BUTTON, self.OnClose, self.close_button)
self.stc.SetMarginWidth(1, 0)
self.stc.SetUseHorizontalScrollBar(0)
self.stc.SetWrapMode(stc.STC_WRAP_WORD)
self.stc.SetText(TEXT)
def OnClose(self, _event):
self.Destroy()
class MyApp(wx.App):
def OnInit(self):
self.frame = MyFrame(None, wx.ID_ANY, "")
self.SetTopWindow(self.frame)
self.frame.Show()
return True
if __name__ == "__main__":
app = MyApp(0)
app.MainLoop()
When I run the program, I click on the bottom blank line in the STC. I then press the left-arrow key. Instead of moving to the end of the previous line, the caret appears over the middle of the letter ‘e’. Further presses of the left-arrow key cause the caret to appear over some of the other characters instead of between them. If I press the backspace key, the character that gets deleted is often not the one to the left of the caret, but the one to the left of that, which is confusing for the user.
If I re-run the program and stretch the window so that no text is wrapped, the caret does move between the characters, but the backspace/delete problem still occurs.
If I modify the TEXT variable by replacing the ‘f’ character in the word ‘first’ with another character (‘x’, say), then when I run the program again, the cursor moves correctly and the backspace key does delete the character to the left of the caret. The combination of letters that cause the problem to occur is quite specific, but this is not the only combination that I have seen cause it.
What made me notice the problem in the first place was that I was trying to underline spelling errors, but in several cases the underlining didn’t line up with the word it applied to (it was often displaced one character to the right).
I guess I will have to see if a monospace font will work, although it won’t look as good in the application I am working on.
I am running on Python 3.8.10 + wxPython 4.1.1 gtk3 (phoenix) wxWidgets 3.1.5 + Linux Mint 20.3