PerBothner / DomTerm

DOM/JavaScript-based terminal-emulator/console

Home Page:https://domterm.org

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

qtdomterm very slow output / hang with pegged CPU

opened this issue · comments

Hi, I saw DomTerm on the libsixel page and wanted to check it out against my TUI library Jexer: https://jexer.sourceforge.io . More specifically, I wanted to try it against some sixel output captures at https://jexer.sourceforge.io/sixel.html .

I am running on Debian 10.4 (buster, current Debian stable), cloned the DomTerm repo and compiled with git head lbwebsockets and qtwebengine. Running qtdomterm, 'cat'ing any of the captures on the Jexer sixel page leads to completely unresponsive DomTerm and one pegged CPU.

So I tried just running a text-only Jexer against DomTerm, and performance is extremely slow, to the point of unusable. Easiest way to test:

  1. Download https://jexer.sourceforge.io/sixel/jexer-test.jar
  2. 'java -jar jexer-test.jar'

Move the mouse around, click on some pull-down menus, and DomTerm will get some output but then appear to either drag very slow or just outright hang.

Hm. There does seem to be a problem, but it's a bit vague. Could you pin it down to something simpler and more specific?

I did cat ~/tmp/lady-of-shalott.six and that was fine.

Seems like the selectionchange listener is being repeated triggered - presumably because the handler makes a change which triggers another event. Looking into it.

I checked in a fix.

There are still glitches, but I don't know which are "expected". Feel free to report other bugs or requests.

I read https://gitlab.com/klamonte/jexer/-/issues/75. You might find my proposal Variable-sized glyphs and local line-breaking interesting. I am planning on implementing some version of this for DomTerm.

Ah, much better!

Notes against current git head:

  • It looks like you have button-event tracking, but not any-event tracking. Is that correct?

  • 'cat'ing one of the captures at https://jexer.sourceforge.io/sixel.html (for example sixel_7x15.cap) produces a little bit of output, but then no further output, no response from DomTerm (have to kill the process), but also little to no CPU usage.

  • I ran Jexer, opened an image from the hamburger menu | Open image..., and the image sixels went way outside where they ought to. Dragged the image-containing window around and DomTerm hung and I saw a bunch of sixel output in the DomTerm window.

I can also get a similar (the same?) unresponsive / hung behavior just running 'vttest':

  • Test of cursor movements --> Dies, sometimes on the fourth screen (Test of autowrap, mixing control and print characters, at 132 columns), sometimes later.

  • Test of screen features --> Dies, sometime on the second and forth screens, sometimes later.

"Ah, much better!"

BTW - the problem was related to the cursor being hidden, which exercised a program path little tested.

"At looks like you have button-event tracking, but not any-event tracking. Is that correct?"

Dragging jexer windows with the mouse does work, so at least some mouse-motion tracking is done correctly. What are you expecting to work and doesn't?

"'cat'ing one of the captures ... produces a little bit of output, but then no further output, no response from DomTerm"

I do see a Javascript null-pointer dereference, probably because the various data structures are confused. I can and should fix this, but there is a more fundamental problem with DomTerm's sixel handling. Traditional sixel handling assumes there is a pixel-based canvas that both characters and images are painted into. DomTerm's primary data structure is the Document Object Model: A hierarchy of nested Elements and text. Specifically, an image is treated as a kind of large character, rather the way it is in a web page. This is meant for the REPL model where you "print" an image to the output, but you don't do cursor motion mixed with images, or mix multi-line-high images with text.

This can be "fixed" but it requires some thought about the semantics of mixing characters and text. See this somewhat inconclusive and heated discussion. For DomTerm it might make sense for an image to be a combination of the appropriate number of blank characters plus an overlay (a relatively-positioned image). That would probably not be difficult and would cover most uses, I hope.

The vttest issues you mention are new (a regression). I've run vttest a lot - but apparently not recently enough. I have reproduced the problems and will look into it ASAP.

Dragging jexer windows with the mouse does work, so at least some mouse-motion tracking is done correctly. What are you expecting to work and doesn't?

Any-event tracking, where the terminal reports mouse state even if no buttons are down (DECSET 1003). I use it to make the text mouse "cursor" move around.

See this somewhat inconclusive and heated discussion.

Oh yeah, been there. It was useful for me to finish up the multi-head case for Jexer. I ended up resorting to a trivial "24-bit sixel" just to have something better than sixel, but still await a "real" new protocol to emerge. My final comments following up to Egmont's "good protocol" issue are at https://gitlab.freedesktop.org/terminal-wg/specifications/-/issues/26#note_524831 .

Jexer's sixel strategy is to write all the images inside the text cell boundaries, and then write text over everything else. That way nothing about an original image has to be guaranteed by the terminal: if any part of it is getting overwritten, then all of it is getting wiped out. Jexer also only writes text-cell-high images, and never puts partial-image-over-text, but these are my choices rather than the real standard.

I fixed the vttest regressions.

There was a logic error in the implementation of any-event mouse tracking (mode 1003), which I believe I fixed. However, jexer-test sends 1002, so I had to kludge to test it. Let me know if it works as expected now.

However, jexer-test sends 1002, so I had to kludge to test it. Let me know if it works as expected now.

Jexer sends 1002 + 1003 + 1005 + 1006 in that order (and in one sequence), which allows for graceful fallback. Terminals that support all of them should end up with 1003+1006, while those that don't support 1003 would end up with 1002+1006, those that don't support 1005 would have 1003+1005, etc. It looks like in your domterm-parser.js around line 804:

        case 104 /*'h'*/:
            param = this.getParameter(0, 0);
            if (this._flagChars.indexOf('?') >= 0) {
                // DEC Private Mode Set (DECSET)
                this.set_DEC_private_mode(param, true);
            }
            else {

...should instead be more like:

        case 104 /*'h'*/:
                var numParameters = this.parameters.length;
                for (var i = 0; i < numParameters; i++) {
                    param = { ... not sure ... }
                    this.set_DEC_private_mode(param, true);
                }

...and similarly for the 'l' reset case section.

But I checked what's in git, and do have the moving cursor, so woo!

Last two items I noticed:

  • DomTerm is not quietly consuming Privacy Message (ESC ^ {stuff} ST).

  • Alt keys aren't working (e.g. Alt-X --> "ESC x"). Don't know if that is a Qt thing or not.

But it's looking much better. :)

Checked in fixes for Privacy Message and Alt+Key.

Note that latter doesn't work if you just try it in cat if the terminal Input Mode is Auto, as cat is in ICANON mode, which turns on Line-editing.

I fixed DECSET/DECRST as you suggested. Thanks.

I fixed the problem that caused sixel_7x15.cap to get an exception and hang.

However, cat-ing that file still produces messed-up output and is very slow. Producing the "right" output would require using a matching font size, but there seem to be other problems. Getting "Open image" to work is probably worth an attempt - right now it just produces bands of black. And then maybe optimizing it some if needed.

Sixel handling should work much better now.

Wow, much better! Certainly doesn't crash anymore. Still seeing the following items:

  • Sixel images appear to always be placed on the first column, rather than the current cursor position. I see this by doing a "Open image", seeing the image (woo!), but then dragging the window around leaves the images on the first column.

  • Meta keys are producing shifted keys rather than the original key. Example, Alt-x (lowercase x) produces "ESC X" rather than "ESC x".

  • Pressing Shift+Alt+x produces "X" rather than "ESC X".

  • I'm still getting ButtonEvent rather than AnyEvent. I can't remember, is AnyEvent supposed to be supported?

Despite the remaining small glitches, the performance with sixel output is really impressive. I had no idea JavaScript could pull that off.

"Certainly doesn't crash anymore."

There is an exception when I resize the window after starting jexer-test.jar. I haven't tried to debug it yet.

"Sixel images appear to always be placed on the first column,"

This was a CSS issue, which should be fixed now.

There are some glitches repainting to the right of the Sixel image. Haven't looked at that yet.

"Meta keys are producing shifted keys rather than the original key." and "Pressing Shift+Alt+x produces "X" rather than "ESC X"."

That seems to be working now. I had to make some non-local changes to key-event handling, so it is possible there might be regressions.

"I'm still getting ButtonEvent rather than AnyEvent."

I don't see the definitions of these terms in ctlseqs.html. Is the problem use of the final character 'M' which should be 'T'? That document is a little dense - as is my code in _mouseHandler - so I have to look at both carefully to see what should happen.

"I'm still getting ButtonEvent rather than AnyEvent."

I don't see the definitions of these terms in ctlseqs.html. Is the problem use of the final character 'M' which should be 'T'

Sorry, I wasn't as precise as I should have been. I mean that I request "Button-event tracking" (1002) followed by "Any-event tracking" (1003), which for a terminal that supports both would result in Any-event tracking, but I am only getting Button-event tracking. The encoding is SGR (1006) as requested.

In short: encoding is good, buttons and movement+buttons is good, I am just missing movement when there are no buttons down.

One new gremlin showed up though: control keys (e.g. Ctrl+D) have stopped working.

"One new gremlin showed up though: control keys (e.g. Ctrl+D) have stopped working."

Hm. "Works for me." At least emacs -nw and cat, both Char mode and Auto mode. Exactly what isn't working?

Could you have an old domterm process running in the background? That might also explain the missing any-event tracking.

Just in case, I pulled from git, make clean && make, and ran bin/qtdomterm. Ran 'cat', tried to input Ctrl-V Ctrl-C and got a paste from clipboard instead like Ctrl-Shift-V. It's behaving like my keyboard modifiers are wonky: Alt-{char} no longer works either.

I'm using KDE Plasma on Debian stable if that helps diagnosing.

Two things I should make clear:

  1. By default domterm is in Auto input mode. If you run cat, it is in ICANON mode, which will be in Line-editing mode. And in that mode, Ctrl-V/Ctrl-C acts the same as Ctrl-Shift-V/Ctr-Shift-C. To force Char mode, use the Input mode sub-menu (of the Terminal menu or the context (right-lick) menu). Or use Ctrl-Shift-L to cycle input modes.
  2. When you run the domterm command it becomes a daemon. If you run domterm again, it will connect to the existing daemon. So make sure you kill any existing domterm processes after recompiling.

I checked in another fix relating to Sixel handling. There still seem to be some issues but it would be easier to debug with a simpler testcase than jexer-test. Perhaps you could open new Sixel-specific issue(s)? Great if you have a simpler test-case(s), too.