-
-
Notifications
You must be signed in to change notification settings - Fork 1k
Open
Description
Versions
Textual 6.6.0
Textual-serve 1.1.3
The bug
When I click a Link object in a textual app or use the App.open_path() method while running in web the link opens only partially.
- Running as a local application does not cause this issue, it works fine.
- Using webbrowser() works in both cases, but will open the link on the server side obviously.
- Using unquote or quote to manage the links does not affect the outcome.
I suspect the issue is with links that have spaces and/or special characters to resolve, as links without any of that works.
The provided code will reproduce the issue easily.
The 4 first links will all show the issue, link 5 works in all cases.
Code example to reproduce:
from textual.app import App, ComposeResult
from textual.containers import Horizontal, Vertical
from textual.widgets import Button, Link, Header
sample_links = [
"https://myrient.erista.me/files/No-Intro/Commodore%20-%20Commodore%2064/128er%20Quickload%20%28USA%2C%20Europe%29%20%28Program%29.zip",
"https://myrient.erista.me/files/No-Intro/Commodore%20-%20Commodore%2064/256K-EPROM-System%20%28Germany%29%20%28v5%29%20%28Program%29.zip",
"https://myrient.erista.me/files/No-Intro/Commodore%20-%20Commodore%2064/64%20Doctor%20%28USA%2C%20Europe%29%20%28Program%29.zip",
"https://myrient.erista.me/files/No-Intro/Commodore%20-%20Commodore%2064/Action%20Replay%20Professional%20%28Europe%29%20%28v4.2%29%20%28Program%29%20%28Unl%29.zip",
"http://ftp.uninett.no/linux/ubuntu-iso/25.04/ubuntu-25.04-desktop-amd64.iso",
]
class TUI(App):
def compose(self) -> ComposeResult:
yield Header("Demo app", id="header")
yield Vertical(
Link(sample_links[0]),
Link(sample_links[1]),
Link(sample_links[2]),
Link(sample_links[3]),
Link(sample_links[4]),
Button("Download link 1", id="download_1", variant="primary"),
Button("Download link 2", id="download_2", variant="primary"),
Button("Download link 3", id="download_3", variant="primary"),
Button("Download link 4", id="download_4", variant="primary"),
Button("Download link 5", id="download_5", variant="primary"),
)
def on_button_pressed(self, event: Button.Pressed) -> None:
if event.button.id == "download_1":
self.open_url(sample_links[0])
if event.button.id == "download_2":
self.open_url(sample_links[1])
if event.button.id == "download_3":
self.open_url(sample_links[2])
if event.button.id == "download_4":
self.open_url(sample_links[3])
if event.button.id == "download_5":
self.open_url(sample_links[4])
if __name__ == "__main__":
app = TUI()
app.run()
Textual Diagnostics
Versions
| Name | Value |
|---|---|
| Textual | 6.6.0 |
| Rich | 14.2.0 |
Python
| Name | Value |
|---|---|
| Version | 3.12.2 |
| Implementation | CPython |
| Compiler | MSC v.1937 64 bit (AMD64) |
| Executable | C:\Program Files\Python312\python.exe |
Operating System
| Name | Value |
|---|---|
| System | Windows |
| Release | 11 |
| Version | 10.0.22621 |
Terminal
| Name | Value |
|---|---|
| Terminal Application | vscode (1.106.2) |
| TERM | Not set |
| COLORTERM | truecolor |
| FORCE_COLOR | Not set |
| NO_COLOR | Not set |
Rich Console options
| Name | Value |
|---|---|
| size | width=311, height=34 |
| legacy_windows | False |
| min_width | 1 |
| max_width | 311 |
| is_terminal | True |
| encoding | utf-8 |
| max_height | 34 |
| justify | None |
| overflow | None |
| no_wrap | False |
| highlight | None |
| markup | None |
| height | None |
Metadata
Metadata
Assignees
Labels
No labels