Skip to content
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

The terminal instance cannot be rendered correctly after calling .open() for the second time. #4978

Open
1zilc opened this issue Mar 3, 2024 · 8 comments · May be fixed by #5253
Open

The terminal instance cannot be rendered correctly after calling .open() for the second time. #4978

1zilc opened this issue Mar 3, 2024 · 8 comments · May be fixed by #5253
Labels
help wanted type/bug Something is misbehaving

Comments

@1zilc
Copy link

1zilc commented Mar 3, 2024

I am new to using xtermjs. I am not sure whether the terminal instance can call the open() method multiple times. According to the official documentation and #1323, I tried it. When I removed the dom and mounted again, and used terminal.open(), xterm did not render after the second open.

Details

  • Browser and browser version: chrome 122.0.6261.94
  • OS version: macOS 14.3
  • xterm.js version: 5.4.0

Steps to reproduce

Reproduce

  1. Click the toggle button, xterm renders correctly.
  2. Click the toggle button, remove dom
  3. Click the toggle button, mount dom, xterm did not render after the second open

I'm sorry if there's something wrong with my usage

@jerch
Copy link
Member

jerch commented Mar 3, 2024

I am not very deep into the browser side of the code, @Tyriar has more insights here. Still I think it is not possible to move an already DOM-attached terminal to another DOM node by calling open again.

@Tyriar Do we need an attach/detach cycling for the DOM hooking? It never came to me before, that someone would want to move an existing terminal to another DOM node, so this might be just a wild idea of limited use. Loosely linked or more generalized to this would be support of a copy ctor like const term2 = new Terminal(term1), where the new terminal could start over in DOM-detached mode, but has inherited all VT-related settings/data. This has some intersections with the serialize addon, so might not be worth either the trouble.

@jonmcgill
Copy link

+1 to this. I have the same use case in our work application which has multiple kinds of terminals in various drawers that can be opened/closed at will.

@Tyriar
Copy link
Member

Tyriar commented Oct 15, 2024

Calling open multiple times was never really supported that well and I think can be a little finicky, but it definitely does work as that's what VS Code does in order to move the terminal around the workbench.

If we can get a repro case without React it will be a lot more clear how to action this.

@jonmcgill
Copy link

Here's a little codesandbox (no React). The Open button mounts the terminal instance to the DOM and writes a line. The Replace button removes the DOM and replaces it with a new div. Running Open again results in no line being written.

https://codesandbox.io/p/sandbox/fz8kq2?file=%2Fsrc%2Findex.ts

demo-xterm-multiple-open.mp4

@jonmcgill
Copy link

FWIW, my workaround for now has been to register when the terminal mount DOM has been changed and/or removed. If so, I dispose the terminal instance and any addons. The next time that terminal's container mounts, I re-initiate the instances and run open from a fresh terminal instance.

@akphi
Copy link

akphi commented Nov 2, 2024

Just wanted to mention that .open() works fine for [email protected]

@Tyriar
Copy link
Member

Tyriar commented Dec 12, 2024

Can't seem to debug in the code sandbox, but it's likely it's hitting this:

// If the terminal is already opened
if (this.element?.ownerDocument.defaultView && this._coreBrowserService) {
// Adjust the window if needed
if (this.element.ownerDocument.defaultView !== this._coreBrowserService.window) {
this._coreBrowserService.window = this.element.ownerDocument.defaultView;
}
return;
}

Maybe this.element?.isConnected needs to be checked too?

@Tyriar Tyriar added type/bug Something is misbehaving help wanted and removed help wanted needs more info labels Dec 12, 2024
@akphi
Copy link

akphi commented Dec 18, 2024

Can't seem to debug in the code sandbox, but it's likely it's hitting this:

// If the terminal is already opened
if (this.element?.ownerDocument.defaultView && this._coreBrowserService) {
// Adjust the window if needed
if (this.element.ownerDocument.defaultView !== this._coreBrowserService.window) {
this._coreBrowserService.window = this.element.ownerDocument.defaultView;
}
return;
}

Maybe this.element?.isConnected needs to be checked too?

@Tyriar I have tested locally for my use case, and like you suggested, adding this.element?.isConnected makes things work! Is there any other deep concerns? I have created a naive PR for the fix #5253

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
help wanted type/bug Something is misbehaving
Projects
None yet
Development

Successfully merging a pull request may close this issue.

5 participants