-
Notifications
You must be signed in to change notification settings - Fork 815
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
Enable AppFocus
and AppBlur
in terminal emulators
#4265
Conversation
This enables support for receiving and handling FocusIn and FocusOut sequences, and turns then into AppFocus and AppBlur events.
src/textual/_xterm_parser.py
Outdated
@@ -20,6 +20,8 @@ | |||
) | |||
_re_bracketed_paste_start = re.compile(r"^\x1b\[200~$") | |||
_re_bracketed_paste_end = re.compile(r"^\x1b\[201~$") | |||
_re_focusin = re.compile(r"^\x1b\[I$") |
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.
It doesn't look like this needs to be a regex. Could it not be a simple string?
Ditto for the bracketed paste stuff. Unless I'm missing something, it looks like they could also just be strings.
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.
I was going to ask you that very question in the morning, oddly enough. Couldn't for the life of me see why the bracketed paste checking used a regex but followed the pattern with a mental note to ask why it was done that way (although looking at fe151a7 it seems I'd have been asking the wrong person anyway).
If there was no reason I'll make them simple strings; makes way more sense to me.
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.
Probably just following a pattern. But yeah, let's go with strings. And if you wouldn't mind changing the bracketed paste ones while you are there...
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.
Will do.
While the terminal window didn't have focus, anything can could happen. The widget could be removed, the screen could change, etc. So by the time AppFocus happens the widget might not be one to focus any more. Initially I was just making it the focused widget anyway and letting the focus-handling code do what it needed to do. Sending focus to a widget that isn't part of the DOM any more isn't exactly a breaking problem; but... One issue is that you can end up with App.focused saying that a widget is focused that isn't in the DOM any more. We don't want that. So here I'm a bit more defensive. This changes things so that we check that the widget's screen is still the screen that's in play. If the widget has been removed it won't have a parent and so can't find its screen. All of this means that if the screen has changed *or* if the widget has been removed, we're covered.
These tests don't test the actual act of blurring or focusing the application (that's kind of hard to do in tests, really). What it does do is test that widget focus does the right thing after each of those app-level events.
Remove the text so say they're only for textual-web, but make it clear textual-web is supported, as are any other terminals that support the required sequences.
Co-authored-by: TomJGooding <[email protected]> Co-authored-by: Will McGugan <[email protected]>
While the application is in an AppBlur state, it's possible that some code could have been running that updated what's focused. It doesn't make sense to have Textual itself override the dev's choice to have focus be somewhere else (perhaps the result of some long-running background process, that they've tabbed away from, and when they tab back they expect to be in a specific control). So here I tweak the code that restores the focused widget so that it only restores if it's still the case that nothing has focus.
AppFocus
and AppBlur
in terminal emulatorsAppFocus
and AppBlur
in terminal emulators
Adding for future reference if someone comes looking: this is also supported by |
This enables support for receiving and handling FocusIn and FocusOut sequences, and turns then into
AppFocus
andAppBlur
events. Support for enabling this is added to both the "Linux" and Windows drivers. From now on, when a terminal emulator window that supports it sends the FocusIn and FocusOut sequences the app will receiveAppFocus
andAppBlur
.An automatic effect of this now is that, when the window loses focus, focus will be removed from the widget that has focus. This was already an established feature of Textual applications running via textual-web; it just now extends it to the drivers used on GNU/Linux, macOS and Windows.
The
AppFocus
andAppBlur
events could be useful too.Screen.Recording.2024-03-07.at.11.56.32.mov
It should be noted that this is technically a breaking change.
Implements #4263 (which in turn stems from #4259).
It also fixes a problem with the current implementation of
AppFocus
andAppBlur
that is mentioned in a comment in #4263.A natural question is going to be, how widely supported is this? So far the following have been tested and shown to support this:
It has been noted by @TomJGooding that iTerm2 has a setting for turning this off1; when turned off the enable/disable sequence appears to be swallowed and ignored.
It would appear that vterm under Emacs doesn't support this, but running my test app had the same effect as running it under iTerm with support turned off (that is, the enable/disable sequences seem to be swallowed and ignored).
NOTE: This is marked as and should be treated as a breaking change. This can potentially affect application styling in a way that would not have been an issue before. For example, before this change, this application would always look the same no matter if the terminal emulator it was within had focus or not:
from now on the layout of the application will look very different when focus moves away form the window.
Footnotes
Because of course it does! What doesn't iTerm have a setting for?!? ↩