-
-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Open
Description
To reproduce, run the app below and try triple-clicking the input.
from textual.app import App
class ExampleApp(App):
def on_mount(self) -> None:
self.action_command_palette()
if __name__ == "__main__":
app = ExampleApp()
app.run()Traceback
╭──────────────────────────── Traceback (most recent call last) ────────────────────────────╮
│ /home/tom/Projects/textual/src/textual/widget.py:4208 in render_lines │
│ │
│ 4205 │ │ Returns: │
│ 4206 │ │ │ A list of list of segments. │
│ 4207 │ │ """ │
│ ❱ 4208 │ │ strips = self._styles_cache.render_widget(self, crop) │
│ 4209 │ │ return strips │
│ 4210 │ │
│ 4211 │ def get_style_at(self, x: int, y: int) -> Style: │
│ │
│ ╭────────────────── locals ──────────────────╮ │
│ │ crop = Region(x=0, y=0, width=2, height=2) │ │
│ │ self = SearchIcon() │ │
│ ╰────────────────────────────────────────────╯ │
│ │
│ /home/tom/Projects/textual/src/textual/_styles_cache.py:112 in render_widget │
│ │
│ 109 │ │ │
│ 110 │ │ base_background, background = widget.background_colors │
│ 111 │ │ styles = widget.styles │
│ ❱ 112 │ │ strips = self.render( │
│ 113 │ │ │ styles, │
│ 114 │ │ │ widget.region.size, │
│ 115 │ │ │ base_background, │
│ │
│ ╭──────────────────────────────── locals ─────────────────────────────────╮ │
│ │ background = Color(20, 31, 39) │ │
│ │ base_background = Color(20, 31, 39) │ │
│ │ border_subtitle = None │ │
│ │ border_title = None │ │
│ │ crop = Region(x=0, y=0, width=2, height=2) │ │
│ │ self = <StylesCache dirty={0, 1} width=2> │ │
│ │ styles = RenderStyles( │ │
│ │ │ SearchIcon(), │ │
│ │ │ auto_color=False, │ │
│ │ │ color=Color(0, 0, 0), │ │
│ │ │ margin=Spacing( │ │
│ │ │ │ top=1, │ │
│ │ │ │ right=0, │ │
│ │ │ │ bottom=0, │ │
│ │ │ │ left=1 │ │
│ │ │ ), │ │
│ │ │ width=Scalar( │ │
│ │ │ │ value=2.0, │ │
│ │ │ │ unit=<Unit.CELLS: 1>, │ │
│ │ │ │ percent_unit=<Unit.WIDTH: 4> │ │
│ │ │ ) │ │
│ │ ) │ │
│ │ widget = SearchIcon() │ │
│ ╰─────────────────────────────────────────────────────────────────────────╯ │
│ │
│ /home/tom/Projects/textual/src/textual/_styles_cache.py:214 in render │
│ │
│ 211 │ │ │
│ 212 │ │ for y in crop.line_range: │
│ 213 │ │ │ if is_dirty(y) or y not in self._cache: │
│ ❱ 214 │ │ │ │ strip = render_line( │
│ 215 │ │ │ │ │ styles, │
│ 216 │ │ │ │ │ y, │
│ 217 │ │ │ │ │ size, │
│ │
│ ╭─────────────────────────────────────── locals ────────────────────────────────────────╮ │
│ │ _height = 2 │ │
│ │ add_strip = <built-in method append of list object at 0x7f0487455840> │ │
│ │ ansi_theme = <rich.terminal_theme.TerminalTheme object at 0x7f04896d7ad0> │ │
│ │ background = Color(20, 31, 39) │ │
│ │ base_background = Color(20, 31, 39) │ │
│ │ border_subtitle = None │ │
│ │ border_title = None │ │
│ │ content_size = Size(width=2, height=2) │ │
│ │ crop = Region(x=0, y=0, width=2, height=2) │ │
│ │ filters = [<textual.filter.ANSIToTruecolor object at 0x7f0488612a50>] │ │
│ │ is_dirty = <built-in method __contains__ of set object at 0x7f04885b3d80> │ │
│ │ opacity = 1.0 │ │
│ │ padding = Spacing(top=0, right=0, bottom=0, left=0) │ │
│ │ render_content_line = <bound method Widget.render_line of SearchIcon()> │ │
│ │ render_line = <bound method StylesCache.render_line of <StylesCache dirty={0, │ │
│ │ 1} width=2>> │ │
│ │ self = <StylesCache dirty={0, 1} width=2> │ │
│ │ size = Size(width=2, height=2) │ │
│ │ strips = [] │ │
│ │ styles = RenderStyles( │ │
│ │ │ SearchIcon(), │ │
│ │ │ auto_color=False, │ │
│ │ │ color=Color(0, 0, 0), │ │
│ │ │ margin=Spacing(top=1, right=0, bottom=0, left=1), │ │
│ │ │ width=Scalar( │ │
│ │ │ │ value=2.0, │ │
│ │ │ │ unit=<Unit.CELLS: 1>, │ │
│ │ │ │ percent_unit=<Unit.WIDTH: 4> │ │
│ │ │ ) │ │
│ │ ) │ │
│ │ width = 2 │ │
│ │ y = 0 │ │
│ ╰───────────────────────────────────────────────────────────────────────────────────────╯ │
│ │
│ /home/tom/Projects/textual/src/textual/_styles_cache.py:441 in render_line │
│ │
│ 438 │ │ │ # Content with border and padding (C) │
│ 439 │ │ │ content_y = y - gutter.top │
│ 440 │ │ │ if content_y < content_height: │
│ ❱ 441 │ │ │ │ line = render_content_line(y - gutter.top) │
│ 442 │ │ │ │ line = line.adjust_cell_length(content_width, inner.rich_style) │
│ 443 │ │ │ else: │
│ 444 │ │ │ │ line = Strip.blank(content_width, inner.rich_style) │
│ │
│ ╭─────────────────────────────────────── locals ────────────────────────────────────────╮ │
│ │ ansi_theme = <rich.terminal_theme.TerminalTheme object at 0x7f04896d7ad0> │ │
│ │ background = Color(20, 31, 39) │ │
│ │ base_background = Color(20, 31, 39) │ │
│ │ border_bottom = '' │ │
│ │ border_bottom_color = Color(0, 255, 0) │ │
│ │ border_left = '' │ │
│ │ border_left_color = Color(0, 255, 0) │ │
│ │ border_right = '' │ │
│ │ border_right_color = Color(0, 255, 0) │ │
│ │ border_subtitle = None │ │
│ │ border_title = None │ │
│ │ border_top = '' │ │
│ │ border_top_color = Color(0, 255, 0) │ │
│ │ content_height = 2 │ │
│ │ content_size = Size(width=2, height=2) │ │
│ │ content_width = 2 │ │
│ │ content_y = 0 │ │
│ │ from_color = <bound method Style.from_color of <class 'rich.style.Style'>> │ │
│ │ gutter = Spacing(top=0, right=0, bottom=0, left=0) │ │
│ │ height = 2 │ │
│ │ inner = Style(background=Color(20, 31, 39)) │ │
│ │ opacity = 1.0 │ │
│ │ outer = Style(background=Color(20, 31, 39)) │ │
│ │ outline_bottom = '' │ │
│ │ outline_bottom_color = Color(0, 255, 0) │ │
│ │ outline_left = '' │ │
│ │ outline_left_color = Color(0, 255, 0) │ │
│ │ outline_right = '' │ │
│ │ outline_right_color = Color(0, 255, 0) │ │
│ │ outline_top = '' │ │
│ │ outline_top_color = Color(0, 255, 0) │ │
│ │ pad_bottom = 0 │ │
│ │ pad_left = 0 │ │
│ │ pad_right = 0 │ │
│ │ pad_top = 0 │ │
│ │ padding = Spacing(top=0, right=0, bottom=0, left=0) │ │
│ │ render_content_line = <bound method Widget.render_line of SearchIcon()> │ │
│ │ self = <StylesCache dirty={0, 1} width=2> │ │
│ │ size = Size(width=2, height=2) │ │
│ │ styles = RenderStyles( │ │
│ │ │ SearchIcon(), │ │
│ │ │ auto_color=False, │ │
│ │ │ color=Color(0, 0, 0), │ │
│ │ │ margin=Spacing(top=1, right=0, bottom=0, left=1), │ │
│ │ │ width=Scalar( │ │
│ │ │ │ value=2.0, │ │
│ │ │ │ unit=<Unit.CELLS: 1>, │ │
│ │ │ │ percent_unit=<Unit.WIDTH: 4> │ │
│ │ │ ) │ │
│ │ ) │ │
│ │ width = 2 │ │
│ │ y = 0 │ │
│ ╰───────────────────────────────────────────────────────────────────────────────────────╯ │
│ │
│ /home/tom/Projects/textual/src/textual/widget.py:4191 in render_line │
│ │
│ 4188 │ │ │ A rendered line. │
│ 4189 │ │ """ │
│ 4190 │ │ if self._dirty_regions: │
│ ❱ 4191 │ │ │ self._render_content() │
│ 4192 │ │ try: │
│ 4193 │ │ │ line = self._render_cache.lines[y] │
│ 4194 │ │ except IndexError: │
│ │
│ ╭────── locals ───────╮ │
│ │ self = SearchIcon() │ │
│ │ y = 0 │ │
│ ╰─────────────────────╯ │
│ │
│ /home/tom/Projects/textual/src/textual/widget.py:4177 in _render_content │
│ │
│ 4174 │ │ """Render all lines.""" │
│ 4175 │ │ width, height = self.size │
│ 4176 │ │ visual = self._render() │
│ ❱ 4177 │ │ strips = Visual.to_strips(self, visual, width, height, self.visual_style) │
│ 4178 │ │ self._render_cache = _RenderCache(self.size, strips) │
│ 4179 │ │ self._dirty_regions.clear() │
│ 4180 │
│ │
│ ╭──────── locals ────────╮ │
│ │ height = 2 │ │
│ │ self = SearchIcon() │ │
│ │ visual = Content('🔎') │ │
│ │ width = 2 │ │
│ ╰────────────────────────╯ │
│ │
│ /home/tom/Projects/textual/src/textual/visual.py:222 in to_strips │
│ │
│ 219 │ │ selection = widget.text_selection │
│ 220 │ │ if selection is not None: │
│ 221 │ │ │ selection_style: Style | None = Style.from_rich_style( │
│ ❱ 222 │ │ │ │ widget.screen.get_component_rich_style("screen--selection") │
│ 223 │ │ │ ) │
│ 224 │ │ else: │
│ 225 │ │ │ selection_style = None │
│ │
│ ╭───────────────────────────────────── locals ─────────────────────────────────────╮ │
│ │ apply_selection = True │ │
│ │ height = 2 │ │
│ │ pad = False │ │
│ │ post_style = None │ │
│ │ selection = Selection(start=None, end=None) │ │
│ │ style = Style(background=Color(20, 31, 39), foreground=Color(0, 0, 0)) │ │
│ │ visual = Content('🔎') │ │
│ │ widget = SearchIcon() │ │
│ │ width = 2 │ │
│ ╰──────────────────────────────────────────────────────────────────────────────────╯ │
│ │
│ /home/tom/Projects/textual/src/textual/widget.py:1151 in get_component_rich_style │
│ │
│ 1148 │ │ """ │
│ 1149 │ │ │
│ 1150 │ │ if names not in self._rich_style_cache: │
│ ❱ 1151 │ │ │ component_styles = self.get_component_styles(*names) │
│ 1152 │ │ │ style = component_styles.rich_style │
│ 1153 │ │ │ text_opacity = component_styles.text_opacity │
│ 1154 │ │ │ if text_opacity < 1 and style.bgcolor is not None: │
│ │
│ ╭───────────────────────── locals ─────────────────────────╮ │
│ │ names = ('screen--selection',) │ │
│ │ partial = False │ │
│ │ self = CommandPalette( │ │
│ │ │ id='--command-palette', │ │
│ │ │ classes='-ready --textual-command-palette' │ │
│ │ ) │ │
│ ╰──────────────────────────────────────────────────────────╯ │
│ │
│ /home/tom/Projects/textual/src/textual/dom.py:615 in get_component_styles │
│ │
│ 612 │ │ │
│ 613 │ │ for name in names: │
│ 614 │ │ │ if name not in self._component_styles: │
│ ❱ 615 │ │ │ │ raise KeyError(f"No {name!r} key in COMPONENT_CLASSES") │
│ 616 │ │ │ component_styles = self._component_styles[name] │
│ 617 │ │ │ styles.node = component_styles.node │
│ 618 │ │ │ styles.base.merge(component_styles.base) │
│ │
│ ╭────────────────────────── locals ───────────────────────────╮ │
│ │ name = 'screen--selection' │ │
│ │ names = ('screen--selection',) │ │
│ │ self = CommandPalette( │ │
│ │ │ id='--command-palette', │ │
│ │ │ classes='-ready --textual-command-palette' │ │
│ │ ) │ │
│ │ styles = RenderStyles( │ │
│ │ │ CommandPalette( │ │
│ │ │ │ id='--command-palette', │ │
│ │ │ │ classes='-ready --textual-command-palette' │ │
│ │ │ ) │ │
│ │ ) │ │
│ ╰─────────────────────────────────────────────────────────────╯ │
╰───────────────────────────────────────────────────────────────────────────────────────────╯
KeyError: "No 'screen--selection' key in COMPONENT_CLASSES"
Metadata
Metadata
Assignees
Labels
No labels