urwid 2.6.16__py3-none-any.whl → 3.0.1__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of urwid might be problematic. Click here for more details.
- urwid/__init__.py +1 -4
- urwid/canvas.py +19 -38
- urwid/command_map.py +4 -3
- urwid/container.py +1 -1
- urwid/decoration.py +1 -1
- urwid/display/_raw_display_base.py +8 -5
- urwid/display/_win32_raw_display.py +11 -13
- urwid/display/common.py +26 -55
- urwid/display/curses.py +1 -1
- urwid/display/escape.py +6 -8
- urwid/display/lcd.py +4 -6
- urwid/display/web.py +7 -12
- urwid/event_loop/asyncio_loop.py +33 -15
- urwid/event_loop/main_loop.py +13 -18
- urwid/event_loop/tornado_loop.py +4 -5
- urwid/event_loop/trio_loop.py +1 -1
- urwid/font.py +10 -15
- urwid/signals.py +2 -1
- urwid/str_util.py +15 -18
- urwid/text_layout.py +6 -7
- urwid/util.py +6 -17
- urwid/version.py +9 -4
- urwid/vterm.py +9 -44
- urwid/widget/__init__.py +0 -6
- urwid/widget/attr_wrap.py +8 -10
- urwid/widget/bar_graph.py +2 -7
- urwid/widget/big_text.py +9 -7
- urwid/widget/box_adapter.py +4 -4
- urwid/widget/columns.py +50 -81
- urwid/widget/container.py +29 -75
- urwid/widget/edit.py +8 -8
- urwid/widget/filler.py +6 -6
- urwid/widget/frame.py +28 -37
- urwid/widget/grid_flow.py +24 -109
- urwid/widget/line_box.py +13 -0
- urwid/widget/listbox.py +12 -50
- urwid/widget/monitored_list.py +6 -4
- urwid/widget/overlay.py +4 -37
- urwid/widget/padding.py +11 -48
- urwid/widget/pile.py +177 -156
- urwid/widget/popup.py +2 -2
- urwid/widget/progress_bar.py +0 -10
- urwid/widget/scrollable.py +24 -32
- urwid/widget/treetools.py +27 -48
- urwid/widget/widget.py +7 -124
- urwid/widget/widget_decoration.py +4 -33
- urwid/wimp.py +1 -1
- {urwid-2.6.16.dist-info → urwid-3.0.1.dist-info}/METADATA +10 -15
- urwid-3.0.1.dist-info/RECORD +74 -0
- {urwid-2.6.16.dist-info → urwid-3.0.1.dist-info}/WHEEL +1 -1
- urwid-2.6.16.dist-info/RECORD +0 -74
- {urwid-2.6.16.dist-info → urwid-3.0.1.dist-info/licenses}/COPYING +0 -0
- {urwid-2.6.16.dist-info → urwid-3.0.1.dist-info}/top_level.txt +0 -0
urwid/event_loop/main_loop.py
CHANGED
|
@@ -172,7 +172,8 @@ class MainLoop:
|
|
|
172
172
|
def _set_widget(self, widget: Widget) -> None:
|
|
173
173
|
warnings.warn(
|
|
174
174
|
f"method `{self.__class__.__name__}._set_widget` is deprecated, "
|
|
175
|
-
f"please use `{self.__class__.__name__}.widget` property"
|
|
175
|
+
f"please use `{self.__class__.__name__}.widget` property."
|
|
176
|
+
"API will be removed in version 4.0.",
|
|
176
177
|
DeprecationWarning,
|
|
177
178
|
stacklevel=2,
|
|
178
179
|
)
|
|
@@ -193,7 +194,8 @@ class MainLoop:
|
|
|
193
194
|
def _set_pop_ups(self, pop_ups: bool) -> None:
|
|
194
195
|
warnings.warn(
|
|
195
196
|
f"method `{self.__class__.__name__}._set_pop_ups` is deprecated, "
|
|
196
|
-
f"please use `{self.__class__.__name__}.pop_ups` property"
|
|
197
|
+
f"please use `{self.__class__.__name__}.pop_ups` property."
|
|
198
|
+
"API will be removed in version 4.0.",
|
|
197
199
|
DeprecationWarning,
|
|
198
200
|
stacklevel=2,
|
|
199
201
|
)
|
|
@@ -460,9 +462,7 @@ class MainLoop:
|
|
|
460
462
|
widget.mouse_event((15, 5), 'mouse press', 1, 5, 4, focus=True)
|
|
461
463
|
>>> ml._update([], [])
|
|
462
464
|
"""
|
|
463
|
-
keys
|
|
464
|
-
|
|
465
|
-
if keys:
|
|
465
|
+
if keys := self.input_filter(keys, raw):
|
|
466
466
|
self.process_input(keys)
|
|
467
467
|
if "window resize" in keys:
|
|
468
468
|
self.screen_size = None
|
|
@@ -493,19 +493,14 @@ class MainLoop:
|
|
|
493
493
|
else:
|
|
494
494
|
self.screen.set_input_timeouts(None)
|
|
495
495
|
keys, raw = self.screen.get_input(True)
|
|
496
|
-
if not keys and next_alarm:
|
|
497
|
-
|
|
498
|
-
if sec <= 0:
|
|
499
|
-
break
|
|
500
|
-
|
|
501
|
-
keys = self.input_filter(keys, raw)
|
|
496
|
+
if not keys and next_alarm and next_alarm[0] - time.time() <= 0:
|
|
497
|
+
break
|
|
502
498
|
|
|
503
|
-
if keys:
|
|
499
|
+
if keys := self.input_filter(keys, raw):
|
|
504
500
|
self.process_input(keys)
|
|
505
501
|
|
|
506
502
|
while next_alarm:
|
|
507
|
-
|
|
508
|
-
if sec > 0:
|
|
503
|
+
if (next_alarm[0] - time.time()) > 0:
|
|
509
504
|
break
|
|
510
505
|
_tm, _tie_break, callback = next_alarm
|
|
511
506
|
callback()
|
|
@@ -563,13 +558,13 @@ class MainLoop:
|
|
|
563
558
|
|
|
564
559
|
if isinstance(key, str):
|
|
565
560
|
if self._topmost_widget.selectable():
|
|
566
|
-
handled_key
|
|
567
|
-
|
|
561
|
+
if handled_key := self._topmost_widget.keypress(self.screen_size, key):
|
|
562
|
+
key = handled_key # noqa: PLW2901
|
|
563
|
+
|
|
564
|
+
else:
|
|
568
565
|
something_handled = True
|
|
569
566
|
continue
|
|
570
567
|
|
|
571
|
-
key = handled_key # noqa: PLW2901
|
|
572
|
-
|
|
573
568
|
elif is_mouse_event(key):
|
|
574
569
|
event, button, col, row = key
|
|
575
570
|
if hasattr(self._topmost_widget, "mouse_event") and self._topmost_widget.mouse_event(
|
urwid/event_loop/tornado_loop.py
CHANGED
|
@@ -155,12 +155,11 @@ class TornadoEventLoop(EventLoop):
|
|
|
155
155
|
return handle
|
|
156
156
|
|
|
157
157
|
def remove_watch_file(self, handle: int) -> bool:
|
|
158
|
-
fd
|
|
159
|
-
|
|
160
|
-
return
|
|
158
|
+
if (fd := self._watch_handles.pop(handle, None)) is not None:
|
|
159
|
+
self._loop.remove_handler(fd)
|
|
160
|
+
return True
|
|
161
161
|
|
|
162
|
-
|
|
163
|
-
return True
|
|
162
|
+
return False
|
|
164
163
|
|
|
165
164
|
def enter_idle(self, callback: Callable[[], typing.Any]) -> int:
|
|
166
165
|
"""
|
urwid/event_loop/trio_loop.py
CHANGED
urwid/font.py
CHANGED
|
@@ -29,7 +29,7 @@ from urwid.display.escape import SAFE_ASCII_DEC_SPECIAL_RE
|
|
|
29
29
|
from urwid.util import apply_target_encoding, str_util
|
|
30
30
|
|
|
31
31
|
if typing.TYPE_CHECKING:
|
|
32
|
-
from collections.abc import
|
|
32
|
+
from collections.abc import Iterator, Sequence
|
|
33
33
|
|
|
34
34
|
from typing_extensions import Literal
|
|
35
35
|
|
|
@@ -206,12 +206,10 @@ class Font(metaclass=FontRegistry):
|
|
|
206
206
|
self.canvas: dict[str, TextCanvas] = {}
|
|
207
207
|
self.utf8_required = False
|
|
208
208
|
if isinstance(self.data, str):
|
|
209
|
-
self.add_glyphs(self.
|
|
209
|
+
self.add_glyphs(self.data)
|
|
210
210
|
|
|
211
211
|
else:
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
for gdata in data:
|
|
212
|
+
for gdata in self.data:
|
|
215
213
|
self.add_glyphs(gdata)
|
|
216
214
|
|
|
217
215
|
def __repr__(self) -> str:
|
|
@@ -223,22 +221,19 @@ class Font(metaclass=FontRegistry):
|
|
|
223
221
|
|
|
224
222
|
@staticmethod
|
|
225
223
|
def _to_text(
|
|
226
|
-
obj: str
|
|
224
|
+
obj: str,
|
|
227
225
|
encoding: str = "utf-8",
|
|
228
226
|
errors: Literal["strict", "ignore", "replace"] = "strict",
|
|
229
227
|
) -> str:
|
|
228
|
+
warnings.warn(
|
|
229
|
+
"_to_text is deprecated: only text fonts are supported. API will be removed in version 4.0.",
|
|
230
|
+
DeprecationWarning,
|
|
231
|
+
stacklevel=3,
|
|
232
|
+
)
|
|
230
233
|
if isinstance(obj, str):
|
|
231
234
|
return obj
|
|
232
235
|
|
|
233
|
-
|
|
234
|
-
warnings.warn(
|
|
235
|
-
"Bytes based fonts are deprecated, please switch to the text one",
|
|
236
|
-
DeprecationWarning,
|
|
237
|
-
stacklevel=3,
|
|
238
|
-
)
|
|
239
|
-
return obj.decode(encoding, errors)
|
|
240
|
-
|
|
241
|
-
raise TypeError(f"{obj!r} is not str|bytes")
|
|
236
|
+
raise TypeError(f"{obj!r} is not str")
|
|
242
237
|
|
|
243
238
|
def add_glyphs(self, gdata: str) -> None:
|
|
244
239
|
d, utf8_required = separate_glyphs(gdata, self.height)
|
urwid/signals.py
CHANGED
|
@@ -20,6 +20,7 @@
|
|
|
20
20
|
|
|
21
21
|
from __future__ import annotations
|
|
22
22
|
|
|
23
|
+
import abc
|
|
23
24
|
import itertools
|
|
24
25
|
import typing
|
|
25
26
|
import warnings
|
|
@@ -29,7 +30,7 @@ if typing.TYPE_CHECKING:
|
|
|
29
30
|
from collections.abc import Callable, Collection, Container, Hashable, Iterable
|
|
30
31
|
|
|
31
32
|
|
|
32
|
-
class MetaSignals(
|
|
33
|
+
class MetaSignals(abc.ABCMeta):
|
|
33
34
|
"""
|
|
34
35
|
register the list of signals in the class variable signals,
|
|
35
36
|
including signals in superclasses.
|
urwid/str_util.py
CHANGED
|
@@ -29,17 +29,17 @@ import wcwidth
|
|
|
29
29
|
if typing.TYPE_CHECKING:
|
|
30
30
|
from typing_extensions import Literal
|
|
31
31
|
|
|
32
|
-
SAFE_ASCII_RE = re.compile("^[ -~]*$")
|
|
33
|
-
SAFE_ASCII_BYTES_RE = re.compile(
|
|
32
|
+
SAFE_ASCII_RE = re.compile(r"^[ -~]*$")
|
|
33
|
+
SAFE_ASCII_BYTES_RE = re.compile(rb"^[ -~]*$")
|
|
34
34
|
|
|
35
35
|
_byte_encoding: Literal["utf8", "narrow", "wide"] = "narrow"
|
|
36
36
|
|
|
37
37
|
|
|
38
38
|
def get_char_width(char: str) -> Literal[0, 1, 2]:
|
|
39
|
-
width
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
return
|
|
39
|
+
if (width := wcwidth.wcwidth(char)) >= 0:
|
|
40
|
+
return width
|
|
41
|
+
|
|
42
|
+
return 0
|
|
43
43
|
|
|
44
44
|
|
|
45
45
|
def get_width(o: int) -> Literal[0, 1, 2]:
|
|
@@ -86,10 +86,9 @@ def decode_one(text: bytes | str, pos: int) -> tuple[int, int]:
|
|
|
86
86
|
if b1 & 0xE0 == 0xC0:
|
|
87
87
|
if b2 & 0xC0 != 0x80:
|
|
88
88
|
return error
|
|
89
|
-
o
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
return o, pos + 2
|
|
89
|
+
if (o := ((b1 & 0x1F) << 6) | (b2 & 0x3F)) >= 0x80:
|
|
90
|
+
return o, pos + 2
|
|
91
|
+
return error
|
|
93
92
|
if lt < 3:
|
|
94
93
|
return error
|
|
95
94
|
if b1 & 0xF0 == 0xE0:
|
|
@@ -97,10 +96,9 @@ def decode_one(text: bytes | str, pos: int) -> tuple[int, int]:
|
|
|
97
96
|
return error
|
|
98
97
|
if b3 & 0xC0 != 0x80:
|
|
99
98
|
return error
|
|
100
|
-
o
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
return o, pos + 3
|
|
99
|
+
if (o := ((b1 & 0x0F) << 12) | ((b2 & 0x3F) << 6) | (b3 & 0x3F)) >= 0x800:
|
|
100
|
+
return o, pos + 3
|
|
101
|
+
return error
|
|
104
102
|
if lt < 4:
|
|
105
103
|
return error
|
|
106
104
|
if b1 & 0xF8 == 0xF0:
|
|
@@ -110,10 +108,9 @@ def decode_one(text: bytes | str, pos: int) -> tuple[int, int]:
|
|
|
110
108
|
return error
|
|
111
109
|
if b4 & 0xC0 != 0x80:
|
|
112
110
|
return error
|
|
113
|
-
o
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
return o, pos + 4
|
|
111
|
+
if (o := ((b1 & 0x07) << 18) | ((b2 & 0x3F) << 12) | ((b3 & 0x3F) << 6) | (b4 & 0x3F)) >= 0x10000:
|
|
112
|
+
return o, pos + 4
|
|
113
|
+
return error
|
|
117
114
|
return error
|
|
118
115
|
|
|
119
116
|
|
urwid/text_layout.py
CHANGED
|
@@ -461,7 +461,7 @@ def shift_line(
|
|
|
461
461
|
# existing shift
|
|
462
462
|
amount += segs[0][0]
|
|
463
463
|
if amount:
|
|
464
|
-
return [(amount, None)
|
|
464
|
+
return [(amount, None), *segs[1:]]
|
|
465
465
|
return segs[1:]
|
|
466
466
|
|
|
467
467
|
if amount:
|
|
@@ -581,8 +581,7 @@ def calc_pos(
|
|
|
581
581
|
if row < 0 or row >= len(layout):
|
|
582
582
|
raise ValueError("calculate_pos: out of layout row range")
|
|
583
583
|
|
|
584
|
-
pos
|
|
585
|
-
if pos is not None:
|
|
584
|
+
if (pos := calc_line_pos(text, layout[row], pref_col)) is not None:
|
|
586
585
|
return pos
|
|
587
586
|
|
|
588
587
|
rows_above = list(range(row - 1, -1, -1))
|
|
@@ -590,14 +589,14 @@ def calc_pos(
|
|
|
590
589
|
while rows_above and rows_below:
|
|
591
590
|
if rows_above:
|
|
592
591
|
r = rows_above.pop(0)
|
|
593
|
-
pos
|
|
594
|
-
if pos is not None:
|
|
592
|
+
if (pos := calc_line_pos(text, layout[r], pref_col)) is not None:
|
|
595
593
|
return pos
|
|
594
|
+
|
|
596
595
|
if rows_below:
|
|
597
596
|
r = rows_below.pop(0)
|
|
598
|
-
pos
|
|
599
|
-
if pos is not None:
|
|
597
|
+
if (pos := calc_line_pos(text, layout[r], pref_col)) is not None:
|
|
600
598
|
return pos
|
|
599
|
+
|
|
601
600
|
return 0
|
|
602
601
|
|
|
603
602
|
|
urwid/util.py
CHANGED
|
@@ -493,24 +493,13 @@ def is_mouse_press(ev: str) -> bool:
|
|
|
493
493
|
|
|
494
494
|
|
|
495
495
|
class MetaSuper(type):
|
|
496
|
-
"""
|
|
496
|
+
"""Deprecated metaclass.
|
|
497
497
|
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
raise AttributeError("Class has same name as one of its super classes")
|
|
502
|
-
|
|
503
|
-
@property
|
|
504
|
-
def _super(self):
|
|
505
|
-
warnings.warn(
|
|
506
|
-
f"`{name}.__super` was a deprecated feature for old python versions."
|
|
507
|
-
f"Please use `super()` call instead.",
|
|
508
|
-
DeprecationWarning,
|
|
509
|
-
stacklevel=3,
|
|
510
|
-
)
|
|
511
|
-
return super(cls, self)
|
|
498
|
+
Present only for code compatibility, all logic has been removed.
|
|
499
|
+
Please move to the last position in the class bases to allow future changes.
|
|
500
|
+
"""
|
|
512
501
|
|
|
513
|
-
|
|
502
|
+
__slots__ = ()
|
|
514
503
|
|
|
515
504
|
|
|
516
505
|
def int_scale(val: int, val_range: int, out_range: int) -> int:
|
|
@@ -534,7 +523,7 @@ def int_scale(val: int, val_range: int, out_range: int) -> int:
|
|
|
534
523
|
return num // dem
|
|
535
524
|
|
|
536
525
|
|
|
537
|
-
class StoppingContext(
|
|
526
|
+
class StoppingContext(contextlib.AbstractContextManager["StoppingContext"]):
|
|
538
527
|
"""Context manager that calls ``stop`` on a given object on exit. Used to
|
|
539
528
|
make the ``start`` method on `MainLoop` and `BaseScreen` optionally act as
|
|
540
529
|
context managers.
|
urwid/version.py
CHANGED
|
@@ -1,8 +1,13 @@
|
|
|
1
|
-
# file generated by
|
|
1
|
+
# file generated by setuptools-scm
|
|
2
2
|
# don't change, don't track in version control
|
|
3
|
+
|
|
4
|
+
__all__ = ["__version__", "__version_tuple__", "version", "version_tuple"]
|
|
5
|
+
|
|
3
6
|
TYPE_CHECKING = False
|
|
4
7
|
if TYPE_CHECKING:
|
|
5
|
-
from typing import Tuple
|
|
8
|
+
from typing import Tuple
|
|
9
|
+
from typing import Union
|
|
10
|
+
|
|
6
11
|
VERSION_TUPLE = Tuple[Union[int, str], ...]
|
|
7
12
|
else:
|
|
8
13
|
VERSION_TUPLE = object
|
|
@@ -12,5 +17,5 @@ __version__: str
|
|
|
12
17
|
__version_tuple__: VERSION_TUPLE
|
|
13
18
|
version_tuple: VERSION_TUPLE
|
|
14
19
|
|
|
15
|
-
__version__ = version = '
|
|
16
|
-
__version_tuple__ = version_tuple = (
|
|
20
|
+
__version__ = version = '3.0.1'
|
|
21
|
+
__version_tuple__ = version_tuple = (3, 0, 1)
|
urwid/vterm.py
CHANGED
|
@@ -35,7 +35,6 @@ import termios
|
|
|
35
35
|
import time
|
|
36
36
|
import traceback
|
|
37
37
|
import typing
|
|
38
|
-
import warnings
|
|
39
38
|
from collections import deque
|
|
40
39
|
from contextlib import suppress
|
|
41
40
|
from dataclasses import dataclass
|
|
@@ -248,8 +247,7 @@ class TermCharset:
|
|
|
248
247
|
|
|
249
248
|
def apply_mapping(self, char: bytes) -> bytes:
|
|
250
249
|
if self._sgr_mapping or self._g[self.active] == "ibmpc":
|
|
251
|
-
dec_pos
|
|
252
|
-
if dec_pos >= 0:
|
|
250
|
+
if (dec_pos := DEC_SPECIAL_CHARS.find(char.decode("cp437"))) >= 0:
|
|
253
251
|
self.current = "0"
|
|
254
252
|
return ALT_DEC_SPECIAL_CHARS[dec_pos].encode("cp437")
|
|
255
253
|
|
|
@@ -259,39 +257,6 @@ class TermCharset:
|
|
|
259
257
|
return char
|
|
260
258
|
|
|
261
259
|
|
|
262
|
-
class TermScroller(list):
|
|
263
|
-
"""
|
|
264
|
-
List subclass that handles the terminal scrollback buffer,
|
|
265
|
-
truncating it as necessary.
|
|
266
|
-
"""
|
|
267
|
-
|
|
268
|
-
SCROLLBACK_LINES = 10000
|
|
269
|
-
|
|
270
|
-
def __init__(self, iterable: Iterable[typing.Any]) -> None:
|
|
271
|
-
warnings.warn(
|
|
272
|
-
"`TermScroller` is deprecated. Please use `collections.deque` with non-zero `maxlen` instead.",
|
|
273
|
-
DeprecationWarning,
|
|
274
|
-
stacklevel=3,
|
|
275
|
-
)
|
|
276
|
-
super().__init__(iterable)
|
|
277
|
-
|
|
278
|
-
def trunc(self) -> None:
|
|
279
|
-
if len(self) >= self.SCROLLBACK_LINES:
|
|
280
|
-
self.pop(0)
|
|
281
|
-
|
|
282
|
-
def append(self, obj) -> None:
|
|
283
|
-
self.trunc()
|
|
284
|
-
super().append(obj)
|
|
285
|
-
|
|
286
|
-
def insert(self, idx: typing.SupportsIndex, obj) -> None:
|
|
287
|
-
self.trunc()
|
|
288
|
-
super().insert(idx, obj)
|
|
289
|
-
|
|
290
|
-
def extend(self, seq) -> None:
|
|
291
|
-
self.trunc()
|
|
292
|
-
super().extend(seq)
|
|
293
|
-
|
|
294
|
-
|
|
295
260
|
class TermCanvas(Canvas):
|
|
296
261
|
cacheable = False
|
|
297
262
|
|
|
@@ -489,8 +454,7 @@ class TermCanvas(Canvas):
|
|
|
489
454
|
continue
|
|
490
455
|
|
|
491
456
|
# adjust x axis of scrollback buffer to the current width
|
|
492
|
-
padding
|
|
493
|
-
if padding > 0:
|
|
457
|
+
if (padding := self.width - len(last_line)) > 0:
|
|
494
458
|
last_line += [self.empty_char()] * padding
|
|
495
459
|
else:
|
|
496
460
|
last_line = last_line[: self.width]
|
|
@@ -549,8 +513,7 @@ class TermCanvas(Canvas):
|
|
|
549
513
|
|
|
550
514
|
escbuf.append(num)
|
|
551
515
|
|
|
552
|
-
cmd_
|
|
553
|
-
if cmd_ is not None:
|
|
516
|
+
if (cmd_ := CSI_COMMANDS[char]) is not None:
|
|
554
517
|
if isinstance(cmd_, CSIAlias):
|
|
555
518
|
csi_cmd: CSICommand = CSI_COMMANDS[cmd_.alias] # type: ignore[assignment]
|
|
556
519
|
elif isinstance(cmd_, CSICommand):
|
|
@@ -699,11 +662,13 @@ class TermCanvas(Canvas):
|
|
|
699
662
|
|
|
700
663
|
# end multibyte sequence
|
|
701
664
|
self.utf8_eat_bytes = None
|
|
702
|
-
|
|
703
|
-
if
|
|
665
|
+
|
|
666
|
+
if sequence := (self.utf8_buffer + bytes([byte])).decode("utf-8", "ignore"):
|
|
667
|
+
char = sequence.encode(util.get_encoding(), "replace")
|
|
668
|
+
|
|
669
|
+
else:
|
|
704
670
|
# invalid multibyte sequence, stop processing
|
|
705
671
|
return
|
|
706
|
-
char = sequence.encode(util.get_encoding(), "replace")
|
|
707
672
|
else:
|
|
708
673
|
self.utf8_eat_bytes = None
|
|
709
674
|
char = bytes([byte])
|
|
@@ -1272,7 +1237,7 @@ class TermCanvas(Canvas):
|
|
|
1272
1237
|
for x in range(self.width):
|
|
1273
1238
|
char = self.term[y][x]
|
|
1274
1239
|
attrs = self.reverse_attrspec(char[0], undo=undo)
|
|
1275
|
-
self.term[y][x] = (attrs,
|
|
1240
|
+
self.term[y][x] = (attrs, *char[1:])
|
|
1276
1241
|
|
|
1277
1242
|
def set_mode(
|
|
1278
1243
|
self,
|
urwid/widget/__init__.py
CHANGED
|
@@ -41,9 +41,6 @@ from .solid_fill import SolidFill
|
|
|
41
41
|
from .text import Text, TextError
|
|
42
42
|
from .treetools import ParentNode, TreeListBox, TreeNode, TreeWalker, TreeWidget, TreeWidgetError
|
|
43
43
|
from .widget import (
|
|
44
|
-
BoxWidget,
|
|
45
|
-
FixedWidget,
|
|
46
|
-
FlowWidget,
|
|
47
44
|
Widget,
|
|
48
45
|
WidgetError,
|
|
49
46
|
WidgetMeta,
|
|
@@ -87,7 +84,6 @@ __all__ = (
|
|
|
87
84
|
"BigText",
|
|
88
85
|
"BoxAdapter",
|
|
89
86
|
"BoxAdapterError",
|
|
90
|
-
"BoxWidget",
|
|
91
87
|
"Button",
|
|
92
88
|
"CheckBox",
|
|
93
89
|
"CheckBoxError",
|
|
@@ -99,8 +95,6 @@ __all__ = (
|
|
|
99
95
|
"EditError",
|
|
100
96
|
"Filler",
|
|
101
97
|
"FillerError",
|
|
102
|
-
"FixedWidget",
|
|
103
|
-
"FlowWidget",
|
|
104
98
|
"Frame",
|
|
105
99
|
"FrameError",
|
|
106
100
|
"GraphVScale",
|
urwid/widget/attr_wrap.py
CHANGED
|
@@ -47,8 +47,7 @@ class AttrWrap(AttrMap):
|
|
|
47
47
|
# only include the focus_attr when it takes effect (not None)
|
|
48
48
|
d = {**super()._repr_attrs(), "attr": self.attr}
|
|
49
49
|
del d["attr_map"]
|
|
50
|
-
|
|
51
|
-
del d["focus_map"]
|
|
50
|
+
d.pop("focus_map", None)
|
|
52
51
|
if self.focus_attr is not None:
|
|
53
52
|
d["focus_attr"] = self.focus_attr
|
|
54
53
|
return d
|
|
@@ -57,8 +56,8 @@ class AttrWrap(AttrMap):
|
|
|
57
56
|
def w(self) -> Widget:
|
|
58
57
|
"""backwards compatibility, widget used to be stored as w"""
|
|
59
58
|
warnings.warn(
|
|
60
|
-
"backwards compatibility, widget used to be stored as original_widget",
|
|
61
|
-
|
|
59
|
+
"backwards compatibility, widget used to be stored as original_widget. API will be removed in version 5.0.",
|
|
60
|
+
DeprecationWarning,
|
|
62
61
|
stacklevel=2,
|
|
63
62
|
)
|
|
64
63
|
return self.original_widget
|
|
@@ -66,15 +65,15 @@ class AttrWrap(AttrMap):
|
|
|
66
65
|
@w.setter
|
|
67
66
|
def w(self, new_widget: Widget) -> None:
|
|
68
67
|
warnings.warn(
|
|
69
|
-
"backwards compatibility, widget used to be stored as original_widget",
|
|
70
|
-
|
|
68
|
+
"backwards compatibility, widget used to be stored as original_widget. API will be removed in version 5.0.",
|
|
69
|
+
DeprecationWarning,
|
|
71
70
|
stacklevel=2,
|
|
72
71
|
)
|
|
73
72
|
self.original_widget = new_widget
|
|
74
73
|
|
|
75
74
|
def get_w(self):
|
|
76
75
|
warnings.warn(
|
|
77
|
-
"backwards compatibility, widget used to be stored as original_widget",
|
|
76
|
+
"backwards compatibility, widget used to be stored as original_widget. API will be removed in version 4.0.",
|
|
78
77
|
DeprecationWarning,
|
|
79
78
|
stacklevel=2,
|
|
80
79
|
)
|
|
@@ -82,7 +81,7 @@ class AttrWrap(AttrMap):
|
|
|
82
81
|
|
|
83
82
|
def set_w(self, new_widget: Widget) -> None:
|
|
84
83
|
warnings.warn(
|
|
85
|
-
"backwards compatibility, widget used to be stored as original_widget",
|
|
84
|
+
"backwards compatibility, widget used to be stored as original_widget. API will be removed in version 4.0.",
|
|
86
85
|
DeprecationWarning,
|
|
87
86
|
stacklevel=2,
|
|
88
87
|
)
|
|
@@ -105,8 +104,7 @@ class AttrWrap(AttrMap):
|
|
|
105
104
|
attr = property(get_attr, set_attr)
|
|
106
105
|
|
|
107
106
|
def get_focus_attr(self) -> Hashable | None:
|
|
108
|
-
focus_map
|
|
109
|
-
if focus_map:
|
|
107
|
+
if focus_map := self.focus_map:
|
|
110
108
|
return focus_map[None]
|
|
111
109
|
return None
|
|
112
110
|
|
urwid/widget/bar_graph.py
CHANGED
|
@@ -269,12 +269,7 @@ class BarGraph(Widget, metaclass=BarGraphMeta):
|
|
|
269
269
|
]
|
|
270
270
|
|
|
271
271
|
# reverse the hlines to match screen ordering
|
|
272
|
-
rhl = []
|
|
273
|
-
for h in hlines:
|
|
274
|
-
rh = float(top - h) * maxrow / top - shiftr
|
|
275
|
-
if rh < 0:
|
|
276
|
-
continue
|
|
277
|
-
rhl.append(rh)
|
|
272
|
+
rhl = [rh for h in hlines if (rh := float(top - h) * maxrow / top - shiftr) >= 0]
|
|
278
273
|
|
|
279
274
|
# build a list of rows that will have hlines
|
|
280
275
|
hrows = []
|
|
@@ -562,7 +557,7 @@ def calculate_bargraph_display(bardata, top: float, bar_widths: list[int], maxro
|
|
|
562
557
|
la, ln = last[i]
|
|
563
558
|
|
|
564
559
|
if i < len(last):
|
|
565
|
-
o += [(la, ln)
|
|
560
|
+
o += [(la, ln), *last[i + 1 :]]
|
|
566
561
|
last = o
|
|
567
562
|
y_count += 1
|
|
568
563
|
|
urwid/widget/big_text.py
CHANGED
|
@@ -70,15 +70,17 @@ class BigText(Widget):
|
|
|
70
70
|
a, ak = attrib[ai]
|
|
71
71
|
ai += 1
|
|
72
72
|
ak -= 1
|
|
73
|
-
|
|
74
|
-
if
|
|
73
|
+
|
|
74
|
+
if width := self.font.char_width(ch):
|
|
75
|
+
c: TextCanvas | CompositeCanvas = self.font.render(ch)
|
|
76
|
+
if a is not None:
|
|
77
|
+
c = CompositeCanvas(c)
|
|
78
|
+
c.fill_attr(a)
|
|
79
|
+
o.append((c, None, False, width))
|
|
80
|
+
|
|
81
|
+
else:
|
|
75
82
|
# ignore invalid characters
|
|
76
83
|
continue
|
|
77
|
-
c: TextCanvas | CompositeCanvas = self.font.render(ch)
|
|
78
|
-
if a is not None:
|
|
79
|
-
c = CompositeCanvas(c)
|
|
80
|
-
c.fill_attr(a)
|
|
81
|
-
o.append((c, None, False, width))
|
|
82
84
|
if o:
|
|
83
85
|
canv = CanvasJoin(o)
|
|
84
86
|
else:
|
urwid/widget/box_adapter.py
CHANGED
|
@@ -48,8 +48,8 @@ class BoxAdapter(WidgetDecoration[WrappedWidget]):
|
|
|
48
48
|
@property
|
|
49
49
|
def box_widget(self) -> WrappedWidget:
|
|
50
50
|
warnings.warn(
|
|
51
|
-
"original stored as original_widget, keep for compatibility",
|
|
52
|
-
|
|
51
|
+
"original stored as original_widget, keep for compatibility. API will be removed in version 5.0.",
|
|
52
|
+
DeprecationWarning,
|
|
53
53
|
stacklevel=2,
|
|
54
54
|
)
|
|
55
55
|
return self.original_widget
|
|
@@ -57,8 +57,8 @@ class BoxAdapter(WidgetDecoration[WrappedWidget]):
|
|
|
57
57
|
@box_widget.setter
|
|
58
58
|
def box_widget(self, widget: WrappedWidget) -> None:
|
|
59
59
|
warnings.warn(
|
|
60
|
-
"original stored as original_widget, keep for compatibility",
|
|
61
|
-
|
|
60
|
+
"original stored as original_widget, keep for compatibility. API will be removed in version 5.0.",
|
|
61
|
+
DeprecationWarning,
|
|
62
62
|
stacklevel=2,
|
|
63
63
|
)
|
|
64
64
|
self.original_widget = widget
|