Skip to content

Commit e849168

Browse files
authored
Merge pull request #4177 from Textualize/driver-signals
signals env var
2 parents 269c08a + 2536e46 commit e849168

File tree

2 files changed

+28
-8
lines changed

2 files changed

+28
-8
lines changed

CHANGELOG.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,17 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
77

88
## Unreleased
99

10+
11+
### Changed
12+
13+
- Textual now writes to stderr rather than stdout
14+
1015
### Added
1116

1217
- Added support for environment variable `TEXTUAL_ANIMATIONS` to control what animations Textual displays https://github.com/Textualize/textual/pull/4062
1318
- Add attribute `App.animation_level` to control whether animations on that app run or not https://github.com/Textualize/textual/pull/4062
1419

20+
1521
## [0.51.0] - 2024-02-15
1622

1723
### Added

src/textual/drivers/linux_driver.py

Lines changed: 22 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -42,8 +42,8 @@ def __init__(
4242
size: Initial size of the terminal or `None` to detect.
4343
"""
4444
super().__init__(app, debug=debug, size=size)
45-
self._file = sys.__stdout__
46-
self.fileno = sys.stdin.fileno()
45+
self._file = sys.__stderr__
46+
self.fileno = sys.__stdin__.fileno()
4747
self.attrs_before: list[Any] | None = None
4848
self.exit_event = Event()
4949
self._key_thread: Thread | None = None
@@ -259,7 +259,19 @@ def _request_terminal_sync_mode_support(self) -> None:
259259

260260
@classmethod
261261
def _patch_lflag(cls, attrs: int) -> int:
262-
return attrs & ~(termios.ECHO | termios.ICANON | termios.IEXTEN | termios.ISIG)
262+
"""Patch termios lflag.
263+
264+
Args:
265+
attributes: New set attributes.
266+
267+
Returns:
268+
New lflag.
269+
270+
"""
271+
# if TEXTUAL_ALLOW_SIGNALS env var is set, then allow Ctrl+C to send signals
272+
ISIG = 0 if os.environ.get("TEXTUAL_ALLOW_SIGNALS") else termios.ISIG
273+
274+
return attrs & ~(termios.ECHO | termios.ICANON | termios.IEXTEN | ISIG)
263275

264276
@classmethod
265277
def _patch_iflag(cls, attrs: int) -> int:
@@ -328,15 +340,16 @@ def _run_input_thread(self) -> None:
328340

329341
def run_input_thread(self) -> None:
330342
"""Wait for input and dispatch events."""
331-
selector = selectors.DefaultSelector()
343+
selector = selectors.SelectSelector()
332344
selector.register(self.fileno, selectors.EVENT_READ)
333345

334346
fileno = self.fileno
347+
EVENT_READ = selectors.EVENT_READ
335348

336349
def more_data() -> bool:
337350
"""Check if there is more data to parse."""
338-
EVENT_READ = selectors.EVENT_READ
339-
for key, events in selector.select(0.01):
351+
352+
for _key, events in selector.select(0.01):
340353
if events & EVENT_READ:
341354
return True
342355
return False
@@ -347,14 +360,15 @@ def more_data() -> bool:
347360
utf8_decoder = getincrementaldecoder("utf-8")().decode
348361
decode = utf8_decoder
349362
read = os.read
350-
EVENT_READ = selectors.EVENT_READ
351363

352364
try:
353365
while not self.exit_event.is_set():
354366
selector_events = selector.select(0.1)
355367
for _selector_key, mask in selector_events:
356368
if mask & EVENT_READ:
357-
unicode_data = decode(read(fileno, 1024))
369+
unicode_data = decode(
370+
read(fileno, 1024), final=self.exit_event.is_set()
371+
)
358372
for event in feed(unicode_data):
359373
self.process_event(event)
360374
finally:

0 commit comments

Comments
 (0)