-
Notifications
You must be signed in to change notification settings - Fork 1.6k
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
Make terminal rendering work in popout windows #4069
Conversation
@Tyriar was wondering if you have any thoughts on this PR. I realize it's a bit invasive, I'm happy to brainstorm other approaches. The main use case that I'm looking for is to allow an application to open terminal sessions in a child/popout window (without requiring that the popout have a full copy of the app -- it should just be a rendering surface). |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@mihaip it is indeed invasive. It's just the xterm.js lib you need to load into the other side and then some tweaks to allow your app to communicate with it isn't it? That doesn't seem like that much overhead.
Beside what @Tyriar already said I also want to question that idea from a security perspective. Cross window/document handling is very hard to secure properly and might not even be possible due to pending or upcoming bugs in browser engines. For something like a terminal this is really bad to rely on, as we might open attack vectors that we cannot address/mitigate at all. Furthermore we cannot easily introduce a potential security risk in xterm.js and tell webdevs to deal with it on their own, as many webdevs simply dont care (mind you - already had some heated discussions about risky CDN usage, where ppl will tell you "I always do it that way" - very problematic mindset with a terminal component, if you ask me). |
@Tyriar there is some overhead in that the application now has to have a different chunk that is loaded independently (to avoid loading the entire bundle in the popout window) and a communication protocol/mechanism must be established with it. Each application that wishes to do this will need to replicate this setup. FWIWW other commonly used libraries (including React itself) support rendering in poput windows. @jerch Note that this PR is only intended for use in same-origin/process popout windows. This does not relax any security constraints, and should not open any attack vectors. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The only issue I have with this is how much of a pain it will be to respect this. What about instead of passing around the parent window we create a new IWindowService
like this:
interface IWindowService {
window: Window;
dpr: number;
}
dpr
is here for convenience as it's used a lot. If we go this route we could maybe create an eslint rule to prevent future occurrences of window
, as I'm sure they'll slip in unless we have some lint/compile rule to prevent it.
… windows Allows other work to be unblocked while xtermjs/xterm.js#4069 is worked through. To enable testing the popup window handling, the standalone app allows opening of SSH sessions in new windows by holding down the alt key while pressing the SSH button. Signed-off-by: Mihai Parparita <mihai@tailscale.com>
… windows Allows other work to be unblocked while xtermjs/xterm.js#4069 is worked through. To enable testing the popup window handling, the standalone app allows opening of SSH sessions in new windows by holding down the alt key while pressing the SSH button. Signed-off-by: Mihai Parparita <mihai@tailscale.com>
The |
The poput window is just a rendering surface, the termminal code still executes in the original/parent window.
Add support for the parent element (what is passed to Terminal.open) being in a different (same origin) window. Accesses to DOM APIs such as requestAnimationFrame and devicePixelRatio thus need to be scoped to the corrent window, instead of assuming that it's the same as the window/global scope where the code is running. This is done by inferring a parent window at the creation time, and then storing it in CoreBrowserService, which is already passed to most places that need it. To catch future regressions, an ESLint rule that checks for global accesses is added (it uses AST selectors via the no-restricted-syntax rule). This should also be applicable when the parent element is an iframe. Fixes xtermjs#3758
@Tyriar I've reworked this to use a service. Instead of a new I also added an ESLint check for |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Very nice, thanks for going the extra mile with the test button and lint rules 👍
xtermjs/xterm.js#4069 was merged and published (in 5.0.0-beta.58), no need for the fork added by 01e6565. Signed-off-by: Mihai Parparita <mihai@tailscale.com>
xtermjs/xterm.js#4069 was merged and published (in 5.0.0-beta.58), no need for the fork added by 01e6565. Signed-off-by: Mihai Parparita <mihai@tailscale.com>
xterm 5.0 was released a few weeks ago, and it picks up xtermjs/xterm.js#4069, which was the main reason why we were on a 5.0 beta. Signed-off-by: Mihai Parparita <mihai@tailscale.com>
xterm 5.0 was released a few weeks ago, and it picks up xtermjs/xterm.js#4069, which was the main reason why we were on a 5.0 beta. Signed-off-by: Mihai Parparita <mihai@tailscale.com>
Make terminal rendering work in popout windows
Add support for the parent element (what is passed to Terminal.open)
being in a different (same origin) window. Accesses to DOM APIs such
as requestAnimationFrame and devicePixelRatio thus need to be scoped
to the corrent window, instead of assuming that it's the same as the
window/global scope where the code is running.
This is done by inferring a parent window at the creation time, and
then storing it in CoreBrowserService, which is already passed to most
places that need it.
To catch future regressions, an ESLint rule that checks for global
accesses is added (it uses AST selectors via the no-restricted-syntax
rule).
This should also be applicable when the parent element is an iframe.
Fixes #3758