Skip to content

Commit 1a7f9ff

Browse files
authored
Merge pull request #4401 from Textualize/more-inline-fix
More inline fix
2 parents fe24cc2 + 916b66a commit 1a7f9ff

File tree

6 files changed

+63
-25
lines changed

6 files changed

+63
-25
lines changed

CHANGELOG.md

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,16 @@ All notable changes to this project will be documented in this file.
55
The format is based on [Keep a Changelog](http://keepachangelog.com/)
66
and this project adheres to [Semantic Versioning](http://semver.org/).
77

8+
## [0.56.1] - 2024-04-07
9+
10+
### Fixed
11+
12+
- Fixed flicker when non-current screen updates https://github.com/Textualize/textual/pull/4401
13+
14+
### Changed
15+
16+
- Removed additional line at the end of an inline app https://github.com/Textualize/textual/pull/4401
17+
818
## [0.56.0] - 2024-04-06
919

1020
### Added
@@ -1843,6 +1853,7 @@ https://textual.textualize.io/blog/2022/11/08/version-040/#version-040
18431853
- New handler system for messages that doesn't require inheritance
18441854
- Improved traceback handling
18451855

1856+
[0.56.1]: https://github.com/Textualize/textual/compare/v0.56.0...v0.56.1
18461857
[0.56.0]: https://github.com/Textualize/textual/compare/v0.55.1...v0.56.0
18471858
[0.55.1]: https://github.com/Textualize/textual/compare/v0.55.0...v0.55.1
18481859
[0.55.0]: https://github.com/Textualize/textual/compare/v0.54.0...v0.55.0

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[tool.poetry]
22
name = "textual"
3-
version = "0.56.0"
3+
version = "0.56.1"
44
homepage = "https://github.com/Textualize/textual"
55
repository = "https://github.com/Textualize/textual"
66
documentation = "https://textual.textualize.io/"

src/textual/_compositor.py

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -148,8 +148,9 @@ def __rich_repr__(self) -> rich.repr.Result:
148148
class InlineUpdate(CompositorUpdate):
149149
"""A renderable to write an inline update."""
150150

151-
def __init__(self, strips: list[Strip]) -> None:
151+
def __init__(self, strips: list[Strip], clear: bool = False) -> None:
152152
self.strips = strips
153+
self.clear = clear
153154

154155
def __rich_console__(
155156
self, console: Console, options: ConsoleOptions
@@ -175,14 +176,15 @@ def render_segments(self, console: Console) -> str:
175176
append(strip.render(console))
176177
if not last:
177178
append("\n")
178-
append("\n\x1b[J") # Clear down
179+
if self.clear:
180+
append("\n\x1b[J") # Clear down
179181
if len(self.strips) > 1:
180-
append(
181-
f"\x1b[{len(self.strips)}A\r"
182-
) # Move cursor back to original position
182+
back_lines = len(self.strips) if self.clear else len(self.strips) - 1
183+
append(f"\x1b[{back_lines}A\r") # Move cursor back to original position
183184
else:
184185
append("\r")
185186
append("\x1b[6n") # Query new cursor position
187+
186188
return "".join(sequences)
187189

188190

@@ -336,6 +338,9 @@ def __init__(self) -> None:
336338
# Mapping of line numbers on to lists of widget and regions
337339
self._layers_visible: list[list[tuple[Widget, Region, Region]]] | None = None
338340

341+
# Size of previous inline update
342+
self._previous_inline_height: int | None = None
343+
339344
@classmethod
340345
def _regions_to_spans(
341346
cls, regions: Iterable[Region]
@@ -1030,7 +1035,13 @@ def render_inline(
10301035
A renderable.
10311036
"""
10321037
visible_screen_stack.set([] if screen_stack is None else screen_stack)
1033-
return InlineUpdate(self.render_strips(size))
1038+
strips = self.render_strips(size)
1039+
clear = (
1040+
self._previous_inline_height is not None
1041+
and len(strips) < self._previous_inline_height
1042+
)
1043+
self._previous_inline_height = len(strips)
1044+
return InlineUpdate(strips, clear=clear)
10341045

10351046
def render_full_update(self) -> LayoutUpdate:
10361047
"""Render a full update.

src/textual/command.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -430,6 +430,10 @@ class CommandPalette(_SystemModalScreen[CallbackType]):
430430
"""
431431

432432
DEFAULT_CSS = """
433+
CommandPalette:inline {
434+
/* If the command palette is invoked in inline mode, we may need additional lines. */
435+
min-height: 20;
436+
}
433437
CommandPalette {
434438
background: $background 30%;
435439
align-horizontal: center;

src/textual/drivers/linux_inline_driver.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -207,6 +207,17 @@ def on_terminal_resize(signum, stack) -> None:
207207
self._key_thread = Thread(target=self._run_input_thread)
208208
send_size_event()
209209
self._key_thread.start()
210+
self._request_terminal_sync_mode_support()
211+
self._enable_bracketed_paste()
212+
213+
def _request_terminal_sync_mode_support(self) -> None:
214+
"""Writes an escape sequence to query the terminal support for the sync protocol."""
215+
# Terminals should ignore this sequence if not supported.
216+
# Apple terminal doesn't, and writes a single 'p' in to the terminal,
217+
# so we will make a special case for Apple terminal (which doesn't support sync anyway).
218+
if os.environ.get("TERM_PROGRAM", "") != "Apple_Terminal":
219+
self.write("\033[?2026$p")
220+
self.flush()
210221

211222
@classmethod
212223
def _patch_lflag(cls, attrs: int) -> int:

src/textual/screen.py

Lines changed: 19 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -673,24 +673,25 @@ def _compositor_refresh(self) -> None:
673673
"""Perform a compositor refresh."""
674674

675675
app = self.app
676-
if app.is_inline:
677-
app._display(
678-
self,
679-
self._compositor.render_inline(
680-
app.size.with_height(app._get_inline_height()),
681-
screen_stack=app._background_screens,
682-
),
683-
)
684-
self._dirty_widgets.clear()
685-
self._compositor._dirty_regions.clear()
686676

687-
elif self is app.screen:
688-
# Top screen
689-
update = self._compositor.render_update(
690-
screen_stack=app._background_screens
691-
)
692-
app._display(self, update)
693-
self._dirty_widgets.clear()
677+
if self is app.screen:
678+
if app.is_inline:
679+
app._display(
680+
self,
681+
self._compositor.render_inline(
682+
app.size.with_height(app._get_inline_height()),
683+
screen_stack=app._background_screens,
684+
),
685+
)
686+
self._dirty_widgets.clear()
687+
self._compositor._dirty_regions.clear()
688+
else:
689+
# Top screen
690+
update = self._compositor.render_update(
691+
screen_stack=app._background_screens
692+
)
693+
app._display(self, update)
694+
self._dirty_widgets.clear()
694695
elif self in self.app._background_screens and self._compositor._dirty_regions:
695696
# Background screen
696697
app.screen.refresh(*self._compositor._dirty_regions)
@@ -892,7 +893,7 @@ def _get_inline_height(self, size: Size) -> int:
892893
inline_height = max(inline_height, int(min_height.resolve(size, size)))
893894
if max_height is not None:
894895
inline_height = min(inline_height, int(max_height.resolve(size, size)))
895-
inline_height = min(self.app.size.height - 1, inline_height)
896+
inline_height = min(self.app.size.height, inline_height)
896897
return inline_height
897898

898899
def _screen_resized(self, size: Size):

0 commit comments

Comments
 (0)