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

NoWidget: No widget under screen coordinate (x, y) crash when clicking on the terminal after new screen was recently pushed #3777

Closed
mzebrak opened this issue Nov 29, 2023 · 5 comments · Fixed by #3779

Comments

@mzebrak
Copy link

mzebrak commented Nov 29, 2023

Textual version: 0.43.0 (observable since 0.42.0, I haven't noticed it on 0.41.0)

Minimal working example to reproduce
from textual import on
from textual.app import App, ComposeResult
from textual.screen import Screen
from textual.widgets import Label, Footer, Button


class SomeScreen(Screen):
    def compose(self) -> ComposeResult:
        for i in range(50):
            yield Label(f"Label {i}")

        yield Footer()


class NoWidgetCrashApp(App):
    def compose(self) -> ComposeResult:
        yield Label("Hello, world!")
        yield Button("Click me!")
        yield Footer()

    @on(Button.Pressed)
    def push_some_screen(self) -> None:
        self.push_screen(SomeScreen())


NoWidgetCrashApp().run()

Steps:
Just launch the app, then start spamming LMB on the "Click me!" Button. When you click in the right time - right after new screen was pushed - you'll get a crash.

Video
Screencast.from.11-29-2023.08.41.29.AM.webm
@mzebrak mzebrak changed the title NoWidget: No widget under screen coordinate (x, y) crash when clicking on the terminal after new screen pushed NoWidget: No widget under screen coordinate (x, y) crash when clicking on the terminal after new screen was recently pushed Nov 29, 2023
@willmcgugan
Copy link
Collaborator

Please paste the output of textual diagnose. A copy of the traceback would also be helpful.

@Textualize Textualize deleted a comment from github-actions bot Nov 29, 2023
@mzebrak
Copy link
Author

mzebrak commented Nov 29, 2023

Please paste the output of textual diagnose. A copy of the traceback would also be helpful.

Here you go:

Traceback
╭─────────────────────────────── Traceback (most recent call last) ────────────────────────────────╮
│ /home/mzebrak/.pyenv/versions/textual-tests/lib/python3.10/site-packages/textual/drivers/linux_d │
│ river.py:242 in _run_input_thread                                                                │
│                                                                                                  │
│   239 │   │   an exception                                                                       │
│   240 │   │   """                                                                                │
│   241 │   │   try:                                                                               │
│ ❱ 242 │   │   │   self.run_input_thread()                                                        │
│   243 │   │   except BaseException as error:                                                     │
│   244 │   │   │   import rich.traceback                                                          │
│   245                                                                                            │
│                                                                                                  │
│ /home/mzebrak/.pyenv/versions/textual-tests/lib/python3.10/site-packages/textual/drivers/linux_d │
│ river.py:281 in run_input_thread                                                                 │
│                                                                                                  │
│   278 │   │   │   │   │   if mask & EVENT_READ:                                                  │
│   279 │   │   │   │   │   │   unicode_data = decode(read(fileno, 1024))                          │
│   280 │   │   │   │   │   │   for event in feed(unicode_data):                                   │
│ ❱ 281 │   │   │   │   │   │   │   self.process_event(event)                                      │
│   282 │   │   finally:                                                                           │
│   283 │   │   │   selector.close()                                                               │
│   284                                                                                            │
│                                                                                                  │
│ /home/mzebrak/.pyenv/versions/textual-tests/lib/python3.10/site-packages/textual/driver.py:63 in │
│ process_event                                                                                    │
│                                                                                                  │
│    60 │   │   """                                                                                │
│    61 │   │   event._set_sender(self._app)                                                       │
│    62 │   │   if isinstance(event, events.MouseDown):                                            │
│ ❱  63 │   │   │   self._mouse_down_widget = self._app.get_widget_at(event.x, event.y)[0]         │
│    64 │   │   │   if event.button:                                                               │
│    65 │   │   │   │   self._down_buttons.append(event.button)                                    │
│    66 │   │   elif isinstance(event, events.MouseUp):                                            │
│                                                                                                  │
│ /home/mzebrak/.pyenv/versions/textual-tests/lib/python3.10/site-packages/textual/app.py:2606 in  │
│ get_widget_at                                                                                    │
│                                                                                                  │
│   2603 │   │   Returns:                                                                          │
│   2604 │   │   │   The widget and the widget's screen region.                                    │
│   2605 │   │   """                                                                               │
│ ❱ 2606 │   │   return self.screen.get_widget_at(x, y)                                            │
│   2607 │                                                                                         │
│   2608 │   def bell(self) -> None:                                                               │
│   2609 │   │   """Play the console 'bell'.                                                       │
│                                                                                                  │
│ /home/mzebrak/.pyenv/versions/textual-tests/lib/python3.10/site-packages/textual/screen.py:289   │
│ in get_widget_at                                                                                 │
│                                                                                                  │
│    286 │   │   Returns:                                                                          │
│    287 │   │   │   Widget and screen region.                                                     │
│    288 │   │   """                                                                               │
│ ❱  289 │   │   return self._compositor.get_widget_at(x, y)                                       │
│    290 │                                                                                         │
│    291 │   def get_widgets_at(self, x: int, y: int) -> Iterable[tuple[Widget, Region]]:          │
│    292 │   │   """Get all widgets under a given coordinate.                                      │
│                                                                                                  │
│ /home/mzebrak/.pyenv/versions/textual-tests/lib/python3.10/site-packages/textual/_compositor.py: │
│ 787 in get_widget_at                                                                             │
│                                                                                                  │
│    784 │   │   │   for widget, cropped_region, region in self.layers_visible[y]:                 │
│    785 │   │   │   │   if contains(cropped_region, x, y) and widget.visible:                     │
│    786 │   │   │   │   │   return widget, region                                                 │
│ ❱  787 │   │   raise errors.NoWidget(f"No widget under screen coordinate ({x}, {y})")            │
│    788 │                                                                                         │
│    789def get_widgets_at(self, x: int, y: int) -> Iterable[tuple[Widget, Region]]:          │
│    790 │   │   """Get all widgets under a given coordinate.                                      │
╰──────────────────────────────────────────────────────────────────────────────────────────────────╯
NoWidget: No widget under screen coordinate (8, 3)

Textual Diagnostics

Versions

Name Value
Textual 0.43.0
Rich 13.5.1

Python

Name Value
Version 3.10.6
Implementation CPython
Compiler GCC 11.3.0
Executable /home/mzebrak/.pyenv/versions/3.10.6/envs/textual-tests/bin/python3.10

Operating System

Name Value
System Linux
Release 6.2.6-76060206-generic
Version #202303130630167942497222.04~4a8cde1 SMP PREEMPT_DYNAMIC Tue M

Terminal

Name Value
Terminal Application Unknown
TERM xterm-256color
COLORTERM truecolor
FORCE_COLOR Not set
NO_COLOR Not set

Rich Console options

Name Value
size width=220, height=40
legacy_windows False
min_width 1
max_width 220
is_terminal True
encoding utf-8
max_height 40
justify None
overflow None
no_wrap False
highlight None
markup None
height None

@willmcgugan
Copy link
Collaborator

Will have a hotfix shortly. Didn't manage to reproduce it here, but I can see how it could occur. Would appreciate a test when it is released.

@mzebrak
Copy link
Author

mzebrak commented Nov 29, 2023

Will have a hotfix shortly. Didn't manage to reproduce it here, but I can see how it could occur. Would appreciate a test when it is released.

Sure, just let me know.

Copy link

Don't forget to star the repository!

Follow @textualizeio for Textual updates.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants