textual icon indicating copy to clipboard operation
textual copied to clipboard

Textual 2.0.4 plus ghostty "fakes" escape press when mouse crosses window border

Open davep opened this issue 9 months ago • 10 comments

With this code:

from textual.app import App

class WeirdEscapeApp(App[None]):

    BINDINGS = [("escape", "escape")]

    def action_escape(self) -> None:
        self.notify("Escape was pressed!")

if __name__ == "__main__":
    WeirdEscapeApp().run()

I see this effect:

https://github.com/user-attachments/assets/ac15548c-3381-43ed-beeb-1d53a7e2fbb0

Testing with Textual 1.0.0 I don't see this. On the other hand I can't recreate it with iTerm and Textual 2.0.4 (haven't had the chance to test other terminals).

While I appreciate this might be specific to a particular pretty new terminal, I thought it worth a heads-up at least.

Textual Diagnostics

Versions

Name Value
Textual 2.0.4
Rich 13.9.4

Python

Name Value
Version 3.13.2
Implementation CPython
Compiler Clang 16.0.0 (clang-1600.0.26.6)
Executable /Users/davep/temp/x/.venv/bin/python

Operating System

Name Value
System Darwin
Release 24.3.0
Version Darwin Kernel Version 24.3.0: Thu Jan 2 20:23:36 PST 2025; root:xnu-11215.81.4~3/RELEASE_ARM64_T8112

Terminal

Name Value
Terminal Application ghostty (1.1.2)
TERM xterm-256color
COLORTERM truecolor
FORCE_COLOR Not set
NO_COLOR Not set

Rich Console options

Name Value
size width=90, height=37
legacy_windows False
min_width 1
max_width 90
is_terminal False
encoding utf-8
max_height 37
justify None
overflow None
no_wrap False
highlight None
markup None
height None

davep avatar Feb 19 '25 11:02 davep

Running with TEXTUAL_DEBUG=1 might give you some clues in keys.log

willmcgugan avatar Feb 19 '25 11:02 willmcgugan

Good call; if you don't get the chance before me I'll do that when I'm next at a desk with a free moment.

davep avatar Feb 19 '25 11:02 davep

Same environment as the initial report, started the application with the mouse cursor over the window, ran up the app, slowly moved the mouse cursor diagonally towards the top edge of the window and exited over the desktop, the notification displayed.

Here's the log:

keys.log
---
FEED '\x1b[I\x1b[?2026;2$y\x1b[?2048;2$y'
character='\x1b'
sequence='\x1b['
sequence='\x1b[I'
AppFocus()
character='\x1b'
sequence='\x1b['
sequence='\x1b[?'
sequence='\x1b[?2'
sequence='\x1b[?20'
sequence='\x1b[?202'
sequence='\x1b[?2026'
sequence='\x1b[?2026;'
sequence='\x1b[?2026;2'
sequence='\x1b[?2026;2$'
sequence='\x1b[?2026;2$y'
TerminalSupportsSynchronizedOutput()
character='\x1b'
sequence='\x1b['
sequence='\x1b[?'
sequence='\x1b[?2'
sequence='\x1b[?20'
sequence='\x1b[?204'
sequence='\x1b[?2048'
sequence='\x1b[?2048;'
sequence='\x1b[?2048;2'
sequence='\x1b[?2048;2$'
sequence='\x1b[?2048;2$y'
TerminalSupportInBandWindowResize(supported=True, enabled=False)
FEED '\x1b[48;68;153;1156;1377t'
character='\x1b'
sequence='\x1b['
sequence='\x1b[4'
sequence='\x1b[48'
sequence='\x1b[48;'
sequence='\x1b[48;6'
sequence='\x1b[48;68'
sequence='\x1b[48;68;'
sequence='\x1b[48;68;1'
sequence='\x1b[48;68;15'
sequence='\x1b[48;68;153'
sequence='\x1b[48;68;153;'
sequence='\x1b[48;68;153;1'
sequence='\x1b[48;68;153;11'
sequence='\x1b[48;68;153;115'
sequence='\x1b[48;68;153;1156'
sequence='\x1b[48;68;153;1156;'
sequence='\x1b[48;68;153;1156;1'
sequence='\x1b[48;68;153;1156;13'
sequence='\x1b[48;68;153;1156;137'
sequence='\x1b[48;68;153;1156;1377'
sequence='\x1b[48;68;153;1156;1377t'
Resize(size=Size(width=153, height=68), pixel_size=Size(width=1377, height=1156))
FEED '\x1b[<35;876;251M'
character='\x1b'
sequence='\x1b['
sequence='\x1b[<'
sequence='\x1b[<3'
sequence='\x1b[<35'
sequence='\x1b[<35;'
sequence='\x1b[<35;8'
sequence='\x1b[<35;87'
sequence='\x1b[<35;876'
sequence='\x1b[<35;876;'
sequence='\x1b[<35;876;2'
sequence='\x1b[<35;876;25'
sequence='\x1b[<35;876;251'
sequence='\x1b[<35;876;251M'
MouseMove(None, x=97.22222222222223, y=14.705882352941176, delta_x=97.22222222222223, delta_y=14.705882352941176)
FEED '\x1b[<35;879;249M'
character='\x1b'
sequence='\x1b['
sequence='\x1b[<'
sequence='\x1b[<3'
sequence='\x1b[<35'
sequence='\x1b[<35;'
sequence='\x1b[<35;8'
sequence='\x1b[<35;87'
sequence='\x1b[<35;879'
sequence='\x1b[<35;879;'
sequence='\x1b[<35;879;2'
sequence='\x1b[<35;879;24'
sequence='\x1b[<35;879;249'
sequence='\x1b[<35;879;249M'
MouseMove(None, x=97.55555555555556, y=14.588235294117647, delta_x=0.3333333333333286, delta_y=-0.117647058823529)
FEED '\x1b[<35;881;247M'
character='\x1b'
sequence='\x1b['
sequence='\x1b[<'
sequence='\x1b[<3'
sequence='\x1b[<35'
sequence='\x1b[<35;'
sequence='\x1b[<35;8'
sequence='\x1b[<35;88'
sequence='\x1b[<35;881'
sequence='\x1b[<35;881;'
sequence='\x1b[<35;881;2'
sequence='\x1b[<35;881;24'
sequence='\x1b[<35;881;247'
sequence='\x1b[<35;881;247M'
MouseMove(None, x=97.77777777777777, y=14.470588235294118, delta_x=0.22222222222221433, delta_y=-0.117647058823529)
FEED '\x1b[<35;884;245M'
character='\x1b'
sequence='\x1b['
sequence='\x1b[<'
sequence='\x1b[<3'
sequence='\x1b[<35'
sequence='\x1b[<35;'
sequence='\x1b[<35;8'
sequence='\x1b[<35;88'
sequence='\x1b[<35;884'
sequence='\x1b[<35;884;'
sequence='\x1b[<35;884;2'
sequence='\x1b[<35;884;24'
sequence='\x1b[<35;884;245'
sequence='\x1b[<35;884;245M'
MouseMove(None, x=98.11111111111111, y=14.352941176470589, delta_x=0.3333333333333428, delta_y=-0.117647058823529)
FEED '\x1b[<35;889;241M'
character='\x1b'
sequence='\x1b['
sequence='\x1b[<'
sequence='\x1b[<3'
sequence='\x1b[<35'
sequence='\x1b[<35;'
sequence='\x1b[<35;8'
sequence='\x1b[<35;88'
sequence='\x1b[<35;889'
sequence='\x1b[<35;889;'
sequence='\x1b[<35;889;2'
sequence='\x1b[<35;889;24'
sequence='\x1b[<35;889;241'
sequence='\x1b[<35;889;241M'
MouseMove(None, x=98.66666666666667, y=14.117647058823529, delta_x=0.5555555555555571, delta_y=-0.23529411764705976)
FEED '\x1b[<35;893;237M'
character='\x1b'
sequence='\x1b['
sequence='\x1b[<'
sequence='\x1b[<3'
sequence='\x1b[<35'
sequence='\x1b[<35;'
sequence='\x1b[<35;8'
sequence='\x1b[<35;89'
sequence='\x1b[<35;893'
sequence='\x1b[<35;893;'
sequence='\x1b[<35;893;2'
sequence='\x1b[<35;893;23'
sequence='\x1b[<35;893;237'
sequence='\x1b[<35;893;237M'
MouseMove(None, x=99.11111111111111, y=13.882352941176471, delta_x=0.44444444444444287, delta_y=-0.235294117647058)
FEED '\x1b[<35;899;233M'
character='\x1b'
sequence='\x1b['
sequence='\x1b[<'
sequence='\x1b[<3'
sequence='\x1b[<35'
sequence='\x1b[<35;'
sequence='\x1b[<35;8'
sequence='\x1b[<35;89'
sequence='\x1b[<35;899'
sequence='\x1b[<35;899;'
sequence='\x1b[<35;899;2'
sequence='\x1b[<35;899;23'
sequence='\x1b[<35;899;233'
sequence='\x1b[<35;899;233M'
MouseMove(None, x=99.77777777777777, y=13.647058823529411, delta_x=0.6666666666666572, delta_y=-0.23529411764705976)
FEED '\x1b[<35;905;229M'
character='\x1b'
sequence='\x1b['
sequence='\x1b[<'
sequence='\x1b[<3'
sequence='\x1b[<35'
sequence='\x1b[<35;'
sequence='\x1b[<35;9'
sequence='\x1b[<35;90'
sequence='\x1b[<35;905'
sequence='\x1b[<35;905;'
sequence='\x1b[<35;905;2'
sequence='\x1b[<35;905;22'
sequence='\x1b[<35;905;229'
sequence='\x1b[<35;905;229M'
MouseMove(None, x=100.44444444444444, y=13.411764705882353, delta_x=0.6666666666666714, delta_y=-0.235294117647058)
FEED '\x1b[<35;910;225M'
character='\x1b'
sequence='\x1b['
sequence='\x1b[<'
sequence='\x1b[<3'
sequence='\x1b[<35'
sequence='\x1b[<35;'
sequence='\x1b[<35;9'
sequence='\x1b[<35;91'
sequence='\x1b[<35;910'
sequence='\x1b[<35;910;'
sequence='\x1b[<35;910;2'
sequence='\x1b[<35;910;22'
sequence='\x1b[<35;910;225'
sequence='\x1b[<35;910;225M'
MouseMove(None, x=101.0, y=13.176470588235293, delta_x=0.5555555555555571, delta_y=-0.23529411764705976)
FEED '\x1b[<35;914;221M'
character='\x1b'
sequence='\x1b['
sequence='\x1b[<'
sequence='\x1b[<3'
sequence='\x1b[<35'
sequence='\x1b[<35;'
sequence='\x1b[<35;9'
sequence='\x1b[<35;91'
sequence='\x1b[<35;914'
sequence='\x1b[<35;914;'
sequence='\x1b[<35;914;2'
sequence='\x1b[<35;914;22'
sequence='\x1b[<35;914;221'
sequence='\x1b[<35;914;221M'
MouseMove(None, x=101.44444444444444, y=12.941176470588236, delta_x=0.44444444444444287, delta_y=-0.235294117647058)
FEED '\x1b[<35;922;215M'
character='\x1b'
sequence='\x1b['
sequence='\x1b[<'
sequence='\x1b[<3'
sequence='\x1b[<35'
sequence='\x1b[<35;'
sequence='\x1b[<35;9'
sequence='\x1b[<35;92'
sequence='\x1b[<35;922'
sequence='\x1b[<35;922;'
sequence='\x1b[<35;922;2'
sequence='\x1b[<35;922;21'
sequence='\x1b[<35;922;215'
sequence='\x1b[<35;922;215M'
MouseMove(None, x=102.33333333333333, y=12.588235294117647, delta_x=0.8888888888888857, delta_y=-0.35294117647058876)
FEED '\x1b[<35;928;210M'
character='\x1b'
sequence='\x1b['
sequence='\x1b[<'
sequence='\x1b[<3'
sequence='\x1b[<35'
sequence='\x1b[<35;'
sequence='\x1b[<35;9'
sequence='\x1b[<35;92'
sequence='\x1b[<35;928'
sequence='\x1b[<35;928;'
sequence='\x1b[<35;928;2'
sequence='\x1b[<35;928;21'
sequence='\x1b[<35;928;210'
sequence='\x1b[<35;928;210M'
MouseMove(None, x=103.0, y=12.294117647058824, delta_x=0.6666666666666714, delta_y=-0.2941176470588225)
FEED '\x1b[<35;934;206M'
character='\x1b'
sequence='\x1b['
sequence='\x1b[<'
sequence='\x1b[<3'
sequence='\x1b[<35'
sequence='\x1b[<35;'
sequence='\x1b[<35;9'
sequence='\x1b[<35;93'
sequence='\x1b[<35;934'
sequence='\x1b[<35;934;'
sequence='\x1b[<35;934;2'
sequence='\x1b[<35;934;20'
sequence='\x1b[<35;934;206'
sequence='\x1b[<35;934;206M'
MouseMove(None, x=103.66666666666667, y=12.058823529411764, delta_x=0.6666666666666714, delta_y=-0.23529411764705976)
FEED '\x1b[<35;942;201M'
character='\x1b'
sequence='\x1b['
sequence='\x1b[<'
sequence='\x1b[<3'
sequence='\x1b[<35'
sequence='\x1b[<35;'
sequence='\x1b[<35;9'
sequence='\x1b[<35;94'
sequence='\x1b[<35;942'
sequence='\x1b[<35;942;'
sequence='\x1b[<35;942;2'
sequence='\x1b[<35;942;20'
sequence='\x1b[<35;942;201'
sequence='\x1b[<35;942;201M'
MouseMove(None, x=104.55555555555556, y=11.764705882352942, delta_x=0.8888888888888857, delta_y=-0.2941176470588225)
FEED '\x1b[<35;950;195M'
character='\x1b'
sequence='\x1b['
sequence='\x1b[<'
sequence='\x1b[<3'
sequence='\x1b[<35'
sequence='\x1b[<35;'
sequence='\x1b[<35;9'
sequence='\x1b[<35;95'
sequence='\x1b[<35;950'
sequence='\x1b[<35;950;'
sequence='\x1b[<35;950;1'
sequence='\x1b[<35;950;19'
sequence='\x1b[<35;950;195'
sequence='\x1b[<35;950;195M'
MouseMove(None, x=105.44444444444444, y=11.411764705882353, delta_x=0.8888888888888857, delta_y=-0.35294117647058876)
FEED '\x1b[<35;959;189M'
character='\x1b'
sequence='\x1b['
sequence='\x1b[<'
sequence='\x1b[<3'
sequence='\x1b[<35'
sequence='\x1b[<35;'
sequence='\x1b[<35;9'
sequence='\x1b[<35;95'
sequence='\x1b[<35;959'
sequence='\x1b[<35;959;'
sequence='\x1b[<35;959;1'
sequence='\x1b[<35;959;18'
sequence='\x1b[<35;959;189'
sequence='\x1b[<35;959;189M'
MouseMove(None, x=106.44444444444444, y=11.058823529411764, delta_x=1.0, delta_y=-0.35294117647058876)
FEED '\x1b[<35;968;182M'
character='\x1b'
sequence='\x1b['
sequence='\x1b[<'
sequence='\x1b[<3'
sequence='\x1b[<35'
sequence='\x1b[<35;'
sequence='\x1b[<35;9'
sequence='\x1b[<35;96'
sequence='\x1b[<35;968'
sequence='\x1b[<35;968;'
sequence='\x1b[<35;968;1'
sequence='\x1b[<35;968;18'
sequence='\x1b[<35;968;182'
sequence='\x1b[<35;968;182M'
MouseMove(None, x=107.44444444444444, y=10.647058823529411, delta_x=1.0, delta_y=-0.41176470588235325)
FEED '\x1b[<35;979;174M'
character='\x1b'
sequence='\x1b['
sequence='\x1b[<'
sequence='\x1b[<3'
sequence='\x1b[<35'
sequence='\x1b[<35;'
sequence='\x1b[<35;9'
sequence='\x1b[<35;97'
sequence='\x1b[<35;979'
sequence='\x1b[<35;979;'
sequence='\x1b[<35;979;1'
sequence='\x1b[<35;979;17'
sequence='\x1b[<35;979;174'
sequence='\x1b[<35;979;174M'
MouseMove(None, x=108.66666666666667, y=10.176470588235293, delta_x=1.2222222222222285, delta_y=-0.47058823529411775)
FEED '\x1b[<35;991;164M'
character='\x1b'
sequence='\x1b['
sequence='\x1b[<'
sequence='\x1b[<3'
sequence='\x1b[<35'
sequence='\x1b[<35;'
sequence='\x1b[<35;9'
sequence='\x1b[<35;99'
sequence='\x1b[<35;991'
sequence='\x1b[<35;991;'
sequence='\x1b[<35;991;1'
sequence='\x1b[<35;991;16'
sequence='\x1b[<35;991;164'
sequence='\x1b[<35;991;164M'
MouseMove(None, x=110.0, y=9.588235294117647, delta_x=1.3333333333333286, delta_y=-0.5882352941176467)
FEED '\x1b[<35;999;157M'
character='\x1b'
sequence='\x1b['
sequence='\x1b[<'
sequence='\x1b[<3'
sequence='\x1b[<35'
sequence='\x1b[<35;'
sequence='\x1b[<35;9'
sequence='\x1b[<35;99'
sequence='\x1b[<35;999'
sequence='\x1b[<35;999;'
sequence='\x1b[<35;999;1'
sequence='\x1b[<35;999;15'
sequence='\x1b[<35;999;157'
sequence='\x1b[<35;999;157M'
MouseMove(None, x=110.88888888888889, y=9.176470588235293, delta_x=0.8888888888888857, delta_y=-0.41176470588235325)
FEED '\x1b[<35;1004;153M'
character='\x1b'
sequence='\x1b['
sequence='\x1b[<'
sequence='\x1b[<3'
sequence='\x1b[<35'
sequence='\x1b[<35;'
sequence='\x1b[<35;1'
sequence='\x1b[<35;10'
sequence='\x1b[<35;100'
sequence='\x1b[<35;1004'
sequence='\x1b[<35;1004;'
sequence='\x1b[<35;1004;1'
sequence='\x1b[<35;1004;15'
sequence='\x1b[<35;1004;153'
sequence='\x1b[<35;1004;153M'
MouseMove(None, x=111.44444444444444, y=8.941176470588236, delta_x=0.5555555555555571, delta_y=-0.235294117647058)
FEED '\x1b[<35;1008;150M'
character='\x1b'
sequence='\x1b['
sequence='\x1b[<'
sequence='\x1b[<3'
sequence='\x1b[<35'
sequence='\x1b[<35;'
sequence='\x1b[<35;1'
sequence='\x1b[<35;10'
sequence='\x1b[<35;100'
sequence='\x1b[<35;1008'
sequence='\x1b[<35;1008;'
sequence='\x1b[<35;1008;1'
sequence='\x1b[<35;1008;15'
sequence='\x1b[<35;1008;150'
sequence='\x1b[<35;1008;150M'
MouseMove(None, x=111.88888888888889, y=8.764705882352942, delta_x=0.44444444444444287, delta_y=-0.1764705882352935)
FEED '\x1b[<35;1009;149M'
character='\x1b'
sequence='\x1b['
sequence='\x1b[<'
sequence='\x1b[<3'
sequence='\x1b[<35'
sequence='\x1b[<35;'
sequence='\x1b[<35;1'
sequence='\x1b[<35;10'
sequence='\x1b[<35;100'
sequence='\x1b[<35;1009'
sequence='\x1b[<35;1009;'
sequence='\x1b[<35;1009;1'
sequence='\x1b[<35;1009;14'
sequence='\x1b[<35;1009;149'
sequence='\x1b[<35;1009;149M'
MouseMove(None, x=112.0, y=8.705882352941176, delta_x=0.11111111111111427, delta_y=-0.05882352941176627)
FEED '\x1b[<35;1015;144M'
character='\x1b'
sequence='\x1b['
sequence='\x1b[<'
sequence='\x1b[<3'
sequence='\x1b[<35'
sequence='\x1b[<35;'
sequence='\x1b[<35;1'
sequence='\x1b[<35;10'
sequence='\x1b[<35;101'
sequence='\x1b[<35;1015'
sequence='\x1b[<35;1015;'
sequence='\x1b[<35;1015;1'
sequence='\x1b[<35;1015;14'
sequence='\x1b[<35;1015;144'
sequence='\x1b[<35;1015;144M'
MouseMove(None, x=112.66666666666667, y=8.411764705882353, delta_x=0.6666666666666714, delta_y=-0.2941176470588225)
FEED '\x1b[<35;1016;144M'
character='\x1b'
sequence='\x1b['
sequence='\x1b[<'
sequence='\x1b[<3'
sequence='\x1b[<35'
sequence='\x1b[<35;'
sequence='\x1b[<35;1'
sequence='\x1b[<35;10'
sequence='\x1b[<35;101'
sequence='\x1b[<35;1016'
sequence='\x1b[<35;1016;'
sequence='\x1b[<35;1016;1'
sequence='\x1b[<35;1016;14'
sequence='\x1b[<35;1016;144'
sequence='\x1b[<35;1016;144M'
MouseMove(None, x=112.77777777777777, y=8.411764705882353, delta_x=0.11111111111110006)
FEED '\x1b[<35;1023;138M'
character='\x1b'
sequence='\x1b['
sequence='\x1b[<'
sequence='\x1b[<3'
sequence='\x1b[<35'
sequence='\x1b[<35;'
sequence='\x1b[<35;1'
sequence='\x1b[<35;10'
sequence='\x1b[<35;102'
sequence='\x1b[<35;1023'
sequence='\x1b[<35;1023;'
sequence='\x1b[<35;1023;1'
sequence='\x1b[<35;1023;13'
sequence='\x1b[<35;1023;138'
sequence='\x1b[<35;1023;138M'
MouseMove(None, x=113.55555555555556, y=8.058823529411764, delta_x=0.7777777777777857, delta_y=-0.35294117647058876)
FEED '\x1b[<35;1028;135M'
character='\x1b'
sequence='\x1b['
sequence='\x1b[<'
sequence='\x1b[<3'
sequence='\x1b[<35'
sequence='\x1b[<35;'
sequence='\x1b[<35;1'
sequence='\x1b[<35;10'
sequence='\x1b[<35;102'
sequence='\x1b[<35;1028'
sequence='\x1b[<35;1028;'
sequence='\x1b[<35;1028;1'
sequence='\x1b[<35;1028;13'
sequence='\x1b[<35;1028;135'
sequence='\x1b[<35;1028;135M'
MouseMove(None, x=114.11111111111111, y=7.882352941176471, delta_x=0.5555555555555571, delta_y=-0.1764705882352935)
FEED '\x1b[<35;1033;131M'
character='\x1b'
sequence='\x1b['
sequence='\x1b[<'
sequence='\x1b[<3'
sequence='\x1b[<35'
sequence='\x1b[<35;'
sequence='\x1b[<35;1'
sequence='\x1b[<35;10'
sequence='\x1b[<35;103'
sequence='\x1b[<35;1033'
sequence='\x1b[<35;1033;'
sequence='\x1b[<35;1033;1'
sequence='\x1b[<35;1033;13'
sequence='\x1b[<35;1033;131'
sequence='\x1b[<35;1033;131M'
MouseMove(None, x=114.66666666666667, y=7.647058823529412, delta_x=0.5555555555555571, delta_y=-0.23529411764705888)
FEED '\x1b[<35;1036;128M'
character='\x1b'
sequence='\x1b['
sequence='\x1b[<'
sequence='\x1b[<3'
sequence='\x1b[<35'
sequence='\x1b[<35;'
sequence='\x1b[<35;1'
sequence='\x1b[<35;10'
sequence='\x1b[<35;103'
sequence='\x1b[<35;1036'
sequence='\x1b[<35;1036;'
sequence='\x1b[<35;1036;1'
sequence='\x1b[<35;1036;12'
sequence='\x1b[<35;1036;128'
sequence='\x1b[<35;1036;128M'
MouseMove(None, x=115.0, y=7.470588235294118, delta_x=0.3333333333333286, delta_y=-0.17647058823529438)
FEED '\x1b[<35;1042;123M'
character='\x1b'
sequence='\x1b['
sequence='\x1b[<'
sequence='\x1b[<3'
sequence='\x1b[<35'
sequence='\x1b[<35;'
sequence='\x1b[<35;1'
sequence='\x1b[<35;10'
sequence='\x1b[<35;104'
sequence='\x1b[<35;1042'
sequence='\x1b[<35;1042;'
sequence='\x1b[<35;1042;1'
sequence='\x1b[<35;1042;12'
sequence='\x1b[<35;1042;123'
sequence='\x1b[<35;1042;123M'
MouseMove(None, x=115.66666666666667, y=7.176470588235294, delta_x=0.6666666666666714, delta_y=-0.2941176470588234)
FEED '\x1b[<35;1047;118M'
character='\x1b'
sequence='\x1b['
sequence='\x1b[<'
sequence='\x1b[<3'
sequence='\x1b[<35'
sequence='\x1b[<35;'
sequence='\x1b[<35;1'
sequence='\x1b[<35;10'
sequence='\x1b[<35;104'
sequence='\x1b[<35;1047'
sequence='\x1b[<35;1047;'
sequence='\x1b[<35;1047;1'
sequence='\x1b[<35;1047;11'
sequence='\x1b[<35;1047;118'
sequence='\x1b[<35;1047;118M'
MouseMove(None, x=116.22222222222223, y=6.882352941176471, delta_x=0.5555555555555571, delta_y=-0.2941176470588234)
FEED '\x1b[<35;1053;112M'
character='\x1b'
sequence='\x1b['
sequence='\x1b[<'
sequence='\x1b[<3'
sequence='\x1b[<35'
sequence='\x1b[<35;'
sequence='\x1b[<35;1'
sequence='\x1b[<35;10'
sequence='\x1b[<35;105'
sequence='\x1b[<35;1053'
sequence='\x1b[<35;1053;'
sequence='\x1b[<35;1053;1'
sequence='\x1b[<35;1053;11'
sequence='\x1b[<35;1053;112'
sequence='\x1b[<35;1053;112M'
MouseMove(None, x=116.88888888888889, y=6.529411764705882, delta_x=0.6666666666666572, delta_y=-0.35294117647058876)
FEED '\x1b[<35;1054;111M'
character='\x1b'
sequence='\x1b['
sequence='\x1b[<'
sequence='\x1b[<3'
sequence='\x1b[<35'
sequence='\x1b[<35;'
sequence='\x1b[<35;1'
sequence='\x1b[<35;10'
sequence='\x1b[<35;105'
sequence='\x1b[<35;1054'
sequence='\x1b[<35;1054;'
sequence='\x1b[<35;1054;1'
sequence='\x1b[<35;1054;11'
sequence='\x1b[<35;1054;111'
sequence='\x1b[<35;1054;111M'
MouseMove(None, x=117.0, y=6.470588235294118, delta_x=0.11111111111111427, delta_y=-0.0588235294117645)
FEED '\x1b[<35;1064;100M'
character='\x1b'
sequence='\x1b['
sequence='\x1b[<'
sequence='\x1b[<3'
sequence='\x1b[<35'
sequence='\x1b[<35;'
sequence='\x1b[<35;1'
sequence='\x1b[<35;10'
sequence='\x1b[<35;106'
sequence='\x1b[<35;1064'
sequence='\x1b[<35;1064;'
sequence='\x1b[<35;1064;1'
sequence='\x1b[<35;1064;10'
sequence='\x1b[<35;1064;100'
sequence='\x1b[<35;1064;100M'
MouseMove(None, x=118.11111111111111, y=5.823529411764706, delta_x=1.1111111111111143, delta_y=-0.6470588235294121)
FEED '\x1b[<35;1070;95M'
character='\x1b'
sequence='\x1b['
sequence='\x1b[<'
sequence='\x1b[<3'
sequence='\x1b[<35'
sequence='\x1b[<35;'
sequence='\x1b[<35;1'
sequence='\x1b[<35;10'
sequence='\x1b[<35;107'
sequence='\x1b[<35;1070'
sequence='\x1b[<35;1070;'
sequence='\x1b[<35;1070;9'
sequence='\x1b[<35;1070;95'
sequence='\x1b[<35;1070;95M'
MouseMove(None, x=118.77777777777777, y=5.529411764705882, delta_x=0.6666666666666572, delta_y=-0.2941176470588234)
FEED '\x1b[<35;1073;91M'
character='\x1b'
sequence='\x1b['
sequence='\x1b[<'
sequence='\x1b[<3'
sequence='\x1b[<35'
sequence='\x1b[<35;'
sequence='\x1b[<35;1'
sequence='\x1b[<35;10'
sequence='\x1b[<35;107'
sequence='\x1b[<35;1073'
sequence='\x1b[<35;1073;'
sequence='\x1b[<35;1073;9'
sequence='\x1b[<35;1073;91'
sequence='\x1b[<35;1073;91M'
MouseMove(None, x=119.11111111111111, y=5.294117647058823, delta_x=0.3333333333333428, delta_y=-0.23529411764705888)
FEED '\x1b[<35;1077;86M'
character='\x1b'
sequence='\x1b['
sequence='\x1b[<'
sequence='\x1b[<3'
sequence='\x1b[<35'
sequence='\x1b[<35;'
sequence='\x1b[<35;1'
sequence='\x1b[<35;10'
sequence='\x1b[<35;107'
sequence='\x1b[<35;1077'
sequence='\x1b[<35;1077;'
sequence='\x1b[<35;1077;8'
sequence='\x1b[<35;1077;86'
sequence='\x1b[<35;1077;86M'
MouseMove(None, x=119.55555555555556, y=5.0, delta_x=0.44444444444444287, delta_y=-0.2941176470588234)
FEED '\x1b[<35;1081;82M'
character='\x1b'
sequence='\x1b['
sequence='\x1b[<'
sequence='\x1b[<3'
sequence='\x1b[<35'
sequence='\x1b[<35;'
sequence='\x1b[<35;1'
sequence='\x1b[<35;10'
sequence='\x1b[<35;108'
sequence='\x1b[<35;1081'
sequence='\x1b[<35;1081;'
sequence='\x1b[<35;1081;8'
sequence='\x1b[<35;1081;82'
sequence='\x1b[<35;1081;82M'
MouseMove(None, x=120.0, y=4.764705882352941, delta_x=0.44444444444444287, delta_y=-0.23529411764705888)
FEED '\x1b[<35;1086;76M'
character='\x1b'
sequence='\x1b['
sequence='\x1b[<'
sequence='\x1b[<3'
sequence='\x1b[<35'
sequence='\x1b[<35;'
sequence='\x1b[<35;1'
sequence='\x1b[<35;10'
sequence='\x1b[<35;108'
sequence='\x1b[<35;1086'
sequence='\x1b[<35;1086;'
sequence='\x1b[<35;1086;7'
sequence='\x1b[<35;1086;76'
sequence='\x1b[<35;1086;76M'
MouseMove(None, x=120.55555555555556, y=4.411764705882353, delta_x=0.5555555555555571, delta_y=-0.35294117647058787)
FEED '\x1b[<35;1091;72M'
character='\x1b'
sequence='\x1b['
sequence='\x1b[<'
sequence='\x1b[<3'
sequence='\x1b[<35'
sequence='\x1b[<35;'
sequence='\x1b[<35;1'
sequence='\x1b[<35;10'
sequence='\x1b[<35;109'
sequence='\x1b[<35;1091'
sequence='\x1b[<35;1091;'
sequence='\x1b[<35;1091;7'
sequence='\x1b[<35;1091;72'
sequence='\x1b[<35;1091;72M'
MouseMove(None, x=121.11111111111111, y=4.176470588235294, delta_x=0.5555555555555571, delta_y=-0.23529411764705888)
FEED '\x1b[<35;1096;66M'
character='\x1b'
sequence='\x1b['
sequence='\x1b[<'
sequence='\x1b[<3'
sequence='\x1b[<35'
sequence='\x1b[<35;'
sequence='\x1b[<35;1'
sequence='\x1b[<35;10'
sequence='\x1b[<35;109'
sequence='\x1b[<35;1096'
sequence='\x1b[<35;1096;'
sequence='\x1b[<35;1096;6'
sequence='\x1b[<35;1096;66'
sequence='\x1b[<35;1096;66M'
MouseMove(None, x=121.66666666666667, y=3.823529411764706, delta_x=0.5555555555555571, delta_y=-0.3529411764705883)
FEED '\x1b[<35;1100;61M'
character='\x1b'
sequence='\x1b['
sequence='\x1b[<'
sequence='\x1b[<3'
sequence='\x1b[<35'
sequence='\x1b[<35;'
sequence='\x1b[<35;1'
sequence='\x1b[<35;11'
sequence='\x1b[<35;110'
sequence='\x1b[<35;1100'
sequence='\x1b[<35;1100;'
sequence='\x1b[<35;1100;6'
sequence='\x1b[<35;1100;61'
sequence='\x1b[<35;1100;61M'
MouseMove(None, x=122.11111111111111, y=3.5294117647058822, delta_x=0.44444444444444287, delta_y=-0.2941176470588238)
FEED '\x1b[<35;1106;55M'
character='\x1b'
sequence='\x1b['
sequence='\x1b[<'
sequence='\x1b[<3'
sequence='\x1b[<35'
sequence='\x1b[<35;'
sequence='\x1b[<35;1'
sequence='\x1b[<35;11'
sequence='\x1b[<35;110'
sequence='\x1b[<35;1106'
sequence='\x1b[<35;1106;'
sequence='\x1b[<35;1106;5'
sequence='\x1b[<35;1106;55'
sequence='\x1b[<35;1106;55M'
MouseMove(None, x=122.77777777777777, y=3.176470588235294, delta_x=0.6666666666666572, delta_y=-0.3529411764705883)
FEED '\x1b[<35;1110;49M'
character='\x1b'
sequence='\x1b['
sequence='\x1b[<'
sequence='\x1b[<3'
sequence='\x1b[<35'
sequence='\x1b[<35;'
sequence='\x1b[<35;1'
sequence='\x1b[<35;11'
sequence='\x1b[<35;111'
sequence='\x1b[<35;1110'
sequence='\x1b[<35;1110;'
sequence='\x1b[<35;1110;4'
sequence='\x1b[<35;1110;49'
sequence='\x1b[<35;1110;49M'
MouseMove(None, x=123.22222222222223, y=2.823529411764706, delta_x=0.4444444444444571, delta_y=-0.35294117647058787)
FEED '\x1b[<35;1113;47M'
character='\x1b'
sequence='\x1b['
sequence='\x1b[<'
sequence='\x1b[<3'
sequence='\x1b[<35'
sequence='\x1b[<35;'
sequence='\x1b[<35;1'
sequence='\x1b[<35;11'
sequence='\x1b[<35;111'
sequence='\x1b[<35;1113'
sequence='\x1b[<35;1113;'
sequence='\x1b[<35;1113;4'
sequence='\x1b[<35;1113;47'
sequence='\x1b[<35;1113;47M'
MouseMove(None, x=123.55555555555556, y=2.7058823529411766, delta_x=0.3333333333333286, delta_y=-0.11764705882352944)
FEED '\x1b[<35;1117;42M'
character='\x1b'
sequence='\x1b['
sequence='\x1b[<'
sequence='\x1b[<3'
sequence='\x1b[<35'
sequence='\x1b[<35;'
sequence='\x1b[<35;1'
sequence='\x1b[<35;11'
sequence='\x1b[<35;111'
sequence='\x1b[<35;1117'
sequence='\x1b[<35;1117;'
sequence='\x1b[<35;1117;4'
sequence='\x1b[<35;1117;42'
sequence='\x1b[<35;1117;42M'
MouseMove(None, x=124.0, y=2.411764705882353, delta_x=0.44444444444444287, delta_y=-0.2941176470588238)
FEED '\x1b[<35;1119;39M'
character='\x1b'
sequence='\x1b['
sequence='\x1b[<'
sequence='\x1b[<3'
sequence='\x1b[<35'
sequence='\x1b[<35;'
sequence='\x1b[<35;1'
sequence='\x1b[<35;11'
sequence='\x1b[<35;111'
sequence='\x1b[<35;1119'
sequence='\x1b[<35;1119;'
sequence='\x1b[<35;1119;3'
sequence='\x1b[<35;1119;39'
sequence='\x1b[<35;1119;39M'
MouseMove(None, x=124.22222222222223, y=2.235294117647059, delta_x=0.22222222222222854, delta_y=-0.17647058823529393)
FEED '\x1b[<35;1123;35M'
character='\x1b'
sequence='\x1b['
sequence='\x1b[<'
sequence='\x1b[<3'
sequence='\x1b[<35'
sequence='\x1b[<35;'
sequence='\x1b[<35;1'
sequence='\x1b[<35;11'
sequence='\x1b[<35;112'
sequence='\x1b[<35;1123'
sequence='\x1b[<35;1123;'
sequence='\x1b[<35;1123;3'
sequence='\x1b[<35;1123;35'
sequence='\x1b[<35;1123;35M'
MouseMove(None, x=124.66666666666667, y=2.0, delta_x=0.44444444444444287, delta_y=-0.23529411764705888)
FEED '\x1b[<35;1127;31M'
character='\x1b'
sequence='\x1b['
sequence='\x1b[<'
sequence='\x1b[<3'
sequence='\x1b[<35'
sequence='\x1b[<35;'
sequence='\x1b[<35;1'
sequence='\x1b[<35;11'
sequence='\x1b[<35;112'
sequence='\x1b[<35;1127'
sequence='\x1b[<35;1127;'
sequence='\x1b[<35;1127;3'
sequence='\x1b[<35;1127;31'
sequence='\x1b[<35;1127;31M'
MouseMove(None, x=125.11111111111111, y=1.7647058823529411, delta_x=0.44444444444444287, delta_y=-0.23529411764705888)
FEED '\x1b[<35;1131;26M'
character='\x1b'
sequence='\x1b['
sequence='\x1b[<'
sequence='\x1b[<3'
sequence='\x1b[<35'
sequence='\x1b[<35;'
sequence='\x1b[<35;1'
sequence='\x1b[<35;11'
sequence='\x1b[<35;113'
sequence='\x1b[<35;1131'
sequence='\x1b[<35;1131;'
sequence='\x1b[<35;1131;2'
sequence='\x1b[<35;1131;26'
sequence='\x1b[<35;1131;26M'
MouseMove(None, x=125.55555555555556, y=1.4705882352941178, delta_x=0.44444444444444287, delta_y=-0.2941176470588234)
FEED '\x1b[<35;1135;22M'
character='\x1b'
sequence='\x1b['
sequence='\x1b[<'
sequence='\x1b[<3'
sequence='\x1b[<35'
sequence='\x1b[<35;'
sequence='\x1b[<35;1'
sequence='\x1b[<35;11'
sequence='\x1b[<35;113'
sequence='\x1b[<35;1135'
sequence='\x1b[<35;1135;'
sequence='\x1b[<35;1135;2'
sequence='\x1b[<35;1135;22'
sequence='\x1b[<35;1135;22M'
MouseMove(None, x=126.0, y=1.2352941176470589, delta_x=0.44444444444444287, delta_y=-0.23529411764705888)
FEED '\x1b[<35;1139;18M'
character='\x1b'
sequence='\x1b['
sequence='\x1b[<'
sequence='\x1b[<3'
sequence='\x1b[<35'
sequence='\x1b[<35;'
sequence='\x1b[<35;1'
sequence='\x1b[<35;11'
sequence='\x1b[<35;113'
sequence='\x1b[<35;1139'
sequence='\x1b[<35;1139;'
sequence='\x1b[<35;1139;1'
sequence='\x1b[<35;1139;18'
sequence='\x1b[<35;1139;18M'
MouseMove(None, x=126.44444444444444, y=1.0, delta_x=0.44444444444444287, delta_y=-0.23529411764705888)
FEED '\x1b[<35;1143;14M'
character='\x1b'
sequence='\x1b['
sequence='\x1b[<'
sequence='\x1b[<3'
sequence='\x1b[<35'
sequence='\x1b[<35;'
sequence='\x1b[<35;1'
sequence='\x1b[<35;11'
sequence='\x1b[<35;114'
sequence='\x1b[<35;1143'
sequence='\x1b[<35;1143;'
sequence='\x1b[<35;1143;1'
sequence='\x1b[<35;1143;14'
sequence='\x1b[<35;1143;14M'
MouseMove(None, x=126.88888888888889, y=0.7647058823529411, delta_x=0.44444444444444287, delta_y=-0.23529411764705888)
FEED '\x1b[<35;1146;10M'
character='\x1b'
sequence='\x1b['
sequence='\x1b[<'
sequence='\x1b[<3'
sequence='\x1b[<35'
sequence='\x1b[<35;'
sequence='\x1b[<35;1'
sequence='\x1b[<35;11'
sequence='\x1b[<35;114'
sequence='\x1b[<35;1146'
sequence='\x1b[<35;1146;'
sequence='\x1b[<35;1146;1'
sequence='\x1b[<35;1146;10'
sequence='\x1b[<35;1146;10M'
MouseMove(None, x=127.22222222222223, y=0.5294117647058824, delta_x=0.3333333333333428, delta_y=-0.23529411764705876)
FEED '\x1b[<35;1147;10M'
character='\x1b'
sequence='\x1b['
sequence='\x1b[<'
sequence='\x1b[<3'
sequence='\x1b[<35'
sequence='\x1b[<35;'
sequence='\x1b[<35;1'
sequence='\x1b[<35;11'
sequence='\x1b[<35;114'
sequence='\x1b[<35;1147'
sequence='\x1b[<35;1147;'
sequence='\x1b[<35;1147;1'
sequence='\x1b[<35;1147;10'
sequence='\x1b[<35;1147;10M'
MouseMove(None, x=127.33333333333333, y=0.5294117647058824, delta_x=0.11111111111110006)
FEED '\x1b[<35;1150;6M'
character='\x1b'
sequence='\x1b['
sequence='\x1b[<'
sequence='\x1b[<3'
sequence='\x1b[<35'
sequence='\x1b[<35;'
sequence='\x1b[<35;1'
sequence='\x1b[<35;11'
sequence='\x1b[<35;115'
sequence='\x1b[<35;1150'
sequence='\x1b[<35;1150;'
sequence='\x1b[<35;1150;6'
sequence='\x1b[<35;1150;6M'
MouseMove(None, x=127.66666666666667, y=0.29411764705882354, delta_x=0.3333333333333428, delta_y=-0.23529411764705882)
FEED '\x1b[<35;1156;-1M'
character='\x1b'
sequence='\x1b['
sequence='\x1b[<'
sequence='\x1b[<3'
sequence='\x1b[<35'
sequence='\x1b[<35;'
sequence='\x1b[<35;1'
sequence='\x1b[<35;11'
sequence='\x1b[<35;115'
sequence='\x1b[<35;1156'
sequence='\x1b[<35;1156;'
sequence='\x1b[<35;1156;-'
sequence='\x1b[<35;1156;-1'
sequence='\x1b[<35;1156;-1M'
Key(key='escape', character='\x1b', name='escape', is_printable=False, aliases=['escape', 'ctrl+left_square_brace'])
REISSUE '[<35;1156;-1M'
Key(key='left_square_bracket', character='[', name='left_square_bracket', is_printable=True)
Key(key='less_than_sign', character='<', name='less_than_sign', is_printable=True)
Key(key='3', character='3', name='3', is_printable=True)
Key(key='5', character='5', name='5', is_printable=True)
Key(key='semicolon', character=';', name='semicolon', is_printable=True)
Key(key='1', character='1', name='1', is_printable=True)
Key(key='1', character='1', name='1', is_printable=True)
Key(key='5', character='5', name='5', is_printable=True)
Key(key='6', character='6', name='6', is_printable=True)
Key(key='semicolon', character=';', name='semicolon', is_printable=True)
Key(key='minus', character='-', name='minus', is_printable=True)
Key(key='1', character='1', name='1', is_printable=True)
Key(key='M', character='M', name='upper_m', is_printable=True)
FEED '\x1b[113;5u'
character='\x1b'
sequence='\x1b['
sequence='\x1b[1'
sequence='\x1b[11'
sequence='\x1b[113'
sequence='\x1b[113;'
sequence='\x1b[113;5'
sequence='\x1b[113;5u'
Key(key='ctrl+q', character=None, name='ctrl_q', is_printable=False)
FEED ''

davep avatar Feb 19 '25 13:02 davep

I can't repeat that with Ghosty 1.1.2. But I can see from the logs that when you move the mouse off the terminal it generates a y coordinate of -1. I'm almost certain negative coordinates are not permitted by the spec -- and don't make any sense anyway. I think this points towards a bug on Ghostty. What version are you running?

willmcgugan avatar Feb 19 '25 15:02 willmcgugan

Actually, now I can repeat it with 1.1.2

willmcgugan avatar Feb 19 '25 15:02 willmcgugan

What version are you running?

As given in the diagnostics I included: 1.1.2.

davep avatar Feb 19 '25 15:02 davep

I think it's related to scrolling - just spotted something in Ghostty (1.1.2 too) that may be the same issue. If you focus an Input, move your cursor to near the edge of your app, scroll the mouse wheel a bit, and as you do that, move the cursor over the edge of the terminal window. You might see the input filling up like this:

Image

I'm guessing the -2 and -3 are negative x-coords in this case?

darrenburns avatar Mar 01 '25 21:03 darrenburns

I went down a bit of a rabbit hole with this!

Interestingly, xterm also reports negative coordinates when using SGR-Pixels (1016), but only when clicking and dragging outside the terminal window. You can experiment with the mouse tracking by running:

echo -ne '\033[?1003;1016h' ; cat

From what I've read, it's not clear whether this was deliberate or just an oversight. Some consider negative coordinates a definite bug as it violates the standards (see comment).


However it sounds like this behaviour in ghostty is slightly different, which only occurs when the mouse is over the window title bar, if I've understood correctly? I don't have ghostty installed (yet) to test this myself, but it sounds worth reporting this to ghostty (if it hasn't been already) to get their take.

TomJGooding avatar Mar 03 '25 13:03 TomJGooding

Interesting @TomJGooding - I also noticed (in Ghostty) if you write some text in an Input, then click and drag and move the cursor outside of the terminal window while dragging, the Input widget also fills up with the codes - which seems to align with what you said.

darrenburns avatar Mar 03 '25 13:03 darrenburns

For what it's worth, apparently urxvt also reports negative mouse coordinates when clicking and dragging outside the terminal window.

Image

Maybe old urxvt is the only other outlier, but I thought worth flagging this isn't specific only to ghostty.

TomJGooding avatar Jun 02 '25 20:06 TomJGooding

Scrolling behaviour is also very erratic. If I run uvx textual-demo and scroll down a bit, the text jumps up and down and sometimes even ends up scrolling up in effect. Could this be something similar? Scrolling through a long list of output on the command-line does not show this behaviour.

davidfokkema avatar Jun 20 '25 21:06 davidfokkema

That sounds similar to what I've seen in other terminals; pretty sure kitty shows a similar effect.

davep avatar Jun 20 '25 22:06 davep

Less pronounced, but indeed I can confirm that. iTerm scrolls flawlessly, as well as Terminal.app.

davidfokkema avatar Jun 21 '25 10:06 davidfokkema

Closed as fixed by #5926

TomJGooding avatar Sep 09 '25 19:09 TomJGooding

I hope I solved your issue!

Consider sponsoring my work to continue to maintain and develop Textual.

  • Will McGugan

github-actions[bot] avatar Sep 09 '25 19:09 github-actions[bot]