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/__init__.py
CHANGED
|
@@ -150,7 +150,6 @@ from .widget import (
|
|
|
150
150
|
BigText,
|
|
151
151
|
BoxAdapter,
|
|
152
152
|
BoxAdapterError,
|
|
153
|
-
BoxWidget,
|
|
154
153
|
Button,
|
|
155
154
|
CheckBox,
|
|
156
155
|
CheckBoxError,
|
|
@@ -161,8 +160,6 @@ from .widget import (
|
|
|
161
160
|
EditError,
|
|
162
161
|
Filler,
|
|
163
162
|
FillerError,
|
|
164
|
-
FixedWidget,
|
|
165
|
-
FlowWidget,
|
|
166
163
|
Frame,
|
|
167
164
|
FrameError,
|
|
168
165
|
GraphVScale,
|
|
@@ -242,7 +239,7 @@ except ImportError:
|
|
|
242
239
|
|
|
243
240
|
# OS Specific
|
|
244
241
|
if sys.platform != "win32":
|
|
245
|
-
from .vterm import TermCanvas, TermCharset, Terminal, TermModes
|
|
242
|
+
from .vterm import TermCanvas, TermCharset, Terminal, TermModes
|
|
246
243
|
|
|
247
244
|
# ZMQEventLoop cause interpreter crash on windows
|
|
248
245
|
try:
|
urwid/canvas.py
CHANGED
|
@@ -23,7 +23,6 @@ from __future__ import annotations
|
|
|
23
23
|
import contextlib
|
|
24
24
|
import dataclasses
|
|
25
25
|
import typing
|
|
26
|
-
import warnings
|
|
27
26
|
import weakref
|
|
28
27
|
from contextlib import suppress
|
|
29
28
|
|
|
@@ -244,15 +243,6 @@ class Canvas:
|
|
|
244
243
|
def widget_info(self):
|
|
245
244
|
return self._widget_info
|
|
246
245
|
|
|
247
|
-
def _get_widget_info(self):
|
|
248
|
-
warnings.warn(
|
|
249
|
-
f"Method `{self.__class__.__name__}._get_widget_info` is deprecated, "
|
|
250
|
-
f"please use property `{self.__class__.__name__}.widget_info`",
|
|
251
|
-
DeprecationWarning,
|
|
252
|
-
stacklevel=2,
|
|
253
|
-
)
|
|
254
|
-
return self.widget_info
|
|
255
|
-
|
|
256
246
|
@property
|
|
257
247
|
def text(self) -> list[bytes]:
|
|
258
248
|
"""
|
|
@@ -266,15 +256,6 @@ class Canvas:
|
|
|
266
256
|
encoding = get_encoding()
|
|
267
257
|
return tuple(line.decode(encoding) for line in self.text)
|
|
268
258
|
|
|
269
|
-
def _text_content(self):
|
|
270
|
-
warnings.warn(
|
|
271
|
-
f"Method `{self.__class__.__name__}._text_content` is deprecated, "
|
|
272
|
-
f"please use property `{self.__class__.__name__}.text`",
|
|
273
|
-
DeprecationWarning,
|
|
274
|
-
stacklevel=2,
|
|
275
|
-
)
|
|
276
|
-
return self.text
|
|
277
|
-
|
|
278
259
|
def content(
|
|
279
260
|
self,
|
|
280
261
|
trim_left: int = 0,
|
|
@@ -295,10 +276,10 @@ class Canvas:
|
|
|
295
276
|
raise NotImplementedError()
|
|
296
277
|
|
|
297
278
|
def get_cursor(self) -> tuple[int, int] | None:
|
|
298
|
-
c
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
return
|
|
279
|
+
if c := self.coords.get("cursor", None):
|
|
280
|
+
return c[:2] # trim off data part
|
|
281
|
+
|
|
282
|
+
return None
|
|
302
283
|
|
|
303
284
|
def set_cursor(self, c: tuple[int, int] | None) -> None:
|
|
304
285
|
if self.widget_info and self.cacheable:
|
|
@@ -312,10 +293,10 @@ class Canvas:
|
|
|
312
293
|
cursor = property(get_cursor, set_cursor)
|
|
313
294
|
|
|
314
295
|
def get_pop_up(self) -> tuple[int, int, tuple[Widget, int, int]] | None:
|
|
315
|
-
c
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
return
|
|
296
|
+
if c := self.coords.get("pop up", None):
|
|
297
|
+
return c
|
|
298
|
+
|
|
299
|
+
return None
|
|
319
300
|
|
|
320
301
|
def set_pop_up(self, w: Widget, left: int, top: int, overlay_width: int, overlay_height: int) -> None:
|
|
321
302
|
"""
|
|
@@ -808,7 +789,7 @@ class CompositeCanvas(Canvas):
|
|
|
808
789
|
|
|
809
790
|
if right > 0:
|
|
810
791
|
new_top_cviews.append((0, 0, right, rows, None, blank_canvas))
|
|
811
|
-
shards = [(top_rows, new_top_cviews)
|
|
792
|
+
shards = [(top_rows, new_top_cviews), *shards[1:]]
|
|
812
793
|
|
|
813
794
|
self.coords = self.translate_coords(left, 0)
|
|
814
795
|
self.shards = shards
|
|
@@ -833,7 +814,7 @@ class CompositeCanvas(Canvas):
|
|
|
833
814
|
|
|
834
815
|
if bottom > 0:
|
|
835
816
|
if orig_shards is self.shards:
|
|
836
|
-
self.shards = self.shards
|
|
817
|
+
self.shards = self.shards.copy()
|
|
837
818
|
self.shards.append((bottom, [(0, 0, cols, bottom, None, blank_canvas)]))
|
|
838
819
|
|
|
839
820
|
def overlay(self, other: CompositeCanvas, left: int, top: int) -> None:
|
|
@@ -902,11 +883,11 @@ class CompositeCanvas(Canvas):
|
|
|
902
883
|
for cv in original_cviews:
|
|
903
884
|
# cv[4] == attr_map
|
|
904
885
|
if cv[4] is None:
|
|
905
|
-
new_cviews.append(cv[:4]
|
|
886
|
+
new_cviews.append((*cv[:4], mapping, *cv[5:]))
|
|
906
887
|
else:
|
|
907
888
|
combined = mapping.copy()
|
|
908
889
|
combined.update([(k, mapping.get(v, v)) for k, v in cv[4].items()])
|
|
909
|
-
new_cviews.append(cv[:4]
|
|
890
|
+
new_cviews.append((*cv[:4], combined, *cv[5:]))
|
|
910
891
|
shards.append((num_rows, new_cviews))
|
|
911
892
|
self.shards = shards
|
|
912
893
|
|
|
@@ -1002,7 +983,7 @@ def shard_cviews_delta(cviews, other_cviews):
|
|
|
1002
983
|
continue
|
|
1003
984
|
# top-left-aligned cviews, compare them
|
|
1004
985
|
if cv[5] is other_cv[5] and cv[:5] == other_cv[:5]:
|
|
1005
|
-
yield cv[:5]
|
|
986
|
+
yield (*cv[:5], None, *cv[6:])
|
|
1006
987
|
else:
|
|
1007
988
|
yield cv
|
|
1008
989
|
other_cols += other_cv[2]
|
|
@@ -1185,19 +1166,19 @@ def shards_join(shard_lists):
|
|
|
1185
1166
|
|
|
1186
1167
|
|
|
1187
1168
|
def cview_trim_rows(cv, rows: int):
|
|
1188
|
-
return cv[:3]
|
|
1169
|
+
return (*cv[:3], rows, *cv[4:])
|
|
1189
1170
|
|
|
1190
1171
|
|
|
1191
1172
|
def cview_trim_top(cv, trim: int):
|
|
1192
|
-
return (cv[0], trim + cv[1], cv[2], cv[3] - trim
|
|
1173
|
+
return (cv[0], trim + cv[1], cv[2], cv[3] - trim, *cv[4:])
|
|
1193
1174
|
|
|
1194
1175
|
|
|
1195
1176
|
def cview_trim_left(cv, trim: int):
|
|
1196
|
-
return (cv[0] + trim, cv[1], cv[2] - trim
|
|
1177
|
+
return (cv[0] + trim, cv[1], cv[2] - trim, *cv[3:])
|
|
1197
1178
|
|
|
1198
1179
|
|
|
1199
1180
|
def cview_trim_cols(cv, cols: int):
|
|
1200
|
-
return cv[:2]
|
|
1181
|
+
return (*cv[:2], cols, *cv[3:])
|
|
1201
1182
|
|
|
1202
1183
|
|
|
1203
1184
|
def CanvasCombine(canvas_info: Iterable[tuple[Canvas, typing.Any, bool]]) -> CompositeCanvas:
|
|
@@ -1229,7 +1210,7 @@ def CanvasCombine(canvas_info: Iterable[tuple[Canvas, typing.Any, bool]]) -> Com
|
|
|
1229
1210
|
row += canv.rows()
|
|
1230
1211
|
|
|
1231
1212
|
if focus_index:
|
|
1232
|
-
children = [children[focus_index]
|
|
1213
|
+
children = [children[focus_index], *children[:focus_index], *children[focus_index + 1 :]]
|
|
1233
1214
|
|
|
1234
1215
|
combined_canvas.shards = shards
|
|
1235
1216
|
combined_canvas.children = children
|
|
@@ -1295,7 +1276,7 @@ def CanvasJoin(canvas_info: Iterable[tuple[Canvas, typing.Any, bool, int]]) -> C
|
|
|
1295
1276
|
col += composite_canvas.cols()
|
|
1296
1277
|
|
|
1297
1278
|
if focus_item:
|
|
1298
|
-
children = [children[focus_item]
|
|
1279
|
+
children = [children[focus_item], *children[:focus_item], *children[focus_item + 1 :]]
|
|
1299
1280
|
|
|
1300
1281
|
joined_canvas.shards = shards_join(shard_lists)
|
|
1301
1282
|
joined_canvas.children = children
|
urwid/command_map.py
CHANGED
|
@@ -21,6 +21,7 @@ from __future__ import annotations
|
|
|
21
21
|
|
|
22
22
|
import enum
|
|
23
23
|
import typing
|
|
24
|
+
from collections.abc import MutableMapping
|
|
24
25
|
|
|
25
26
|
if typing.TYPE_CHECKING:
|
|
26
27
|
from collections.abc import Iterator
|
|
@@ -56,7 +57,7 @@ CURSOR_MAX_RIGHT = Command.MAX_RIGHT
|
|
|
56
57
|
ACTIVATE = Command.ACTIVATE
|
|
57
58
|
|
|
58
59
|
|
|
59
|
-
class CommandMap(
|
|
60
|
+
class CommandMap(MutableMapping[str, typing.Union[str, Command, None]]):
|
|
60
61
|
"""
|
|
61
62
|
dict-like object for looking up commands from keystrokes
|
|
62
63
|
|
|
@@ -106,10 +107,10 @@ class CommandMap(typing.Mapping[str, typing.Union[str, Command, None]]):
|
|
|
106
107
|
}
|
|
107
108
|
|
|
108
109
|
def __init__(self) -> None:
|
|
109
|
-
self._command =
|
|
110
|
+
self._command = self._command_defaults.copy()
|
|
110
111
|
|
|
111
112
|
def restore_defaults(self) -> None:
|
|
112
|
-
self._command =
|
|
113
|
+
self._command = self._command_defaults.copy()
|
|
113
114
|
|
|
114
115
|
def __getitem__(self, key: str) -> str | Command | None:
|
|
115
116
|
return self._command.get(key, None)
|
urwid/container.py
CHANGED
|
@@ -53,7 +53,7 @@ __all__ = (
|
|
|
53
53
|
warnings.warn(
|
|
54
54
|
f"{__name__!r} is not expected to be imported directly. "
|
|
55
55
|
'Please use public access from "urwid" package. '
|
|
56
|
-
f"Module {__name__!r} is deprecated and will be removed in the
|
|
56
|
+
f"Module {__name__!r} is deprecated and will be removed in the version 4.0.",
|
|
57
57
|
DeprecationWarning,
|
|
58
58
|
stacklevel=3,
|
|
59
59
|
)
|
urwid/decoration.py
CHANGED
|
@@ -59,7 +59,7 @@ __all__ = (
|
|
|
59
59
|
warnings.warn(
|
|
60
60
|
f"{__name__!r} is not expected to be imported directly. "
|
|
61
61
|
'Please use public access from "urwid" package. '
|
|
62
|
-
f"Module {__name__!r} is deprecated and will be removed in the
|
|
62
|
+
f"Module {__name__!r} is deprecated and will be removed in the version 4.0.",
|
|
63
63
|
DeprecationWarning,
|
|
64
64
|
stacklevel=3,
|
|
65
65
|
)
|
|
@@ -172,7 +172,7 @@ class Screen(BaseScreen, RealTerminal):
|
|
|
172
172
|
After calling this function get_input will include mouse
|
|
173
173
|
click events along with keystrokes.
|
|
174
174
|
"""
|
|
175
|
-
enable = bool(enable)
|
|
175
|
+
enable = bool(enable)
|
|
176
176
|
if enable == self._mouse_tracking_enabled:
|
|
177
177
|
return
|
|
178
178
|
|
|
@@ -323,8 +323,8 @@ class Screen(BaseScreen, RealTerminal):
|
|
|
323
323
|
return []
|
|
324
324
|
|
|
325
325
|
fd_list: list[socket.socket | typing.IO | int] = [self._resize_pipe_rd]
|
|
326
|
-
|
|
327
|
-
if input_io is not None:
|
|
326
|
+
|
|
327
|
+
if (input_io := self._term_input_io) is not None:
|
|
328
328
|
fd_list.append(input_io)
|
|
329
329
|
return fd_list
|
|
330
330
|
|
|
@@ -641,7 +641,7 @@ class Screen(BaseScreen, RealTerminal):
|
|
|
641
641
|
a, cs, run = row[-1]
|
|
642
642
|
if run[-1:] == b" " and self.back_color_erase and not using_standout_or_underline(a):
|
|
643
643
|
whitespace_at_end = True
|
|
644
|
-
row = row[:-1]
|
|
644
|
+
row = [*row[:-1], (a, cs, run.rstrip(b" "))] # noqa: PLW2901
|
|
645
645
|
elif y == maxrow - 1 and maxcol > 1:
|
|
646
646
|
row, back, ins = self._last_row(row) # noqa: PLW2901
|
|
647
647
|
|
|
@@ -727,7 +727,10 @@ class Screen(BaseScreen, RealTerminal):
|
|
|
727
727
|
self.screen_buf = sb
|
|
728
728
|
self._screen_buf_canvas = canvas
|
|
729
729
|
|
|
730
|
-
def _last_row(
|
|
730
|
+
def _last_row(
|
|
731
|
+
self,
|
|
732
|
+
row: list[tuple[object, Literal["0", "U"] | None, bytes]],
|
|
733
|
+
) -> tuple[
|
|
731
734
|
list[tuple[object, Literal["0", "U"] | None, bytes]],
|
|
732
735
|
int,
|
|
733
736
|
tuple[object, Literal["0", "U"] | None, bytes],
|
|
@@ -94,11 +94,10 @@ class Screen(_raw_display_base.Screen):
|
|
|
94
94
|
self._dwOriginalInMode.value | _win32.ENABLE_WINDOW_INPUT | _win32.ENABLE_VIRTUAL_TERMINAL_INPUT
|
|
95
95
|
)
|
|
96
96
|
|
|
97
|
-
ok
|
|
98
|
-
if not ok:
|
|
97
|
+
if not (ok := _win32.SetConsoleMode(handle_out, dword_out_mode)):
|
|
99
98
|
raise RuntimeError(f"ConsoleMode set failed for output. Err: {ok!r}")
|
|
100
|
-
|
|
101
|
-
if not ok:
|
|
99
|
+
|
|
100
|
+
if not (ok := _win32.SetConsoleMode(handle_in, dword_in_mode)):
|
|
102
101
|
raise RuntimeError(f"ConsoleMode set failed for input. Err: {ok!r}")
|
|
103
102
|
self._alternate_buffer = alternate_buffer
|
|
104
103
|
self._next_timeout = self.max_wait
|
|
@@ -121,11 +120,11 @@ class Screen(_raw_display_base.Screen):
|
|
|
121
120
|
|
|
122
121
|
handle_out = _win32.GetStdHandle(_win32.STD_OUTPUT_HANDLE)
|
|
123
122
|
handle_in = _win32.GetStdHandle(_win32.STD_INPUT_HANDLE)
|
|
124
|
-
|
|
125
|
-
if not ok:
|
|
123
|
+
|
|
124
|
+
if not (ok := _win32.SetConsoleMode(handle_out, self._dwOriginalOutMode)):
|
|
126
125
|
raise RuntimeError(f"ConsoleMode set failed for output. Err: {ok!r}")
|
|
127
|
-
|
|
128
|
-
if not ok:
|
|
126
|
+
|
|
127
|
+
if not (ok := _win32.SetConsoleMode(handle_in, self._dwOriginalInMode)):
|
|
129
128
|
raise RuntimeError(f"ConsoleMode set failed for input. Err: {ok!r}")
|
|
130
129
|
|
|
131
130
|
super()._stop()
|
|
@@ -188,10 +187,9 @@ class Screen(_raw_display_base.Screen):
|
|
|
188
187
|
|
|
189
188
|
with selectors.DefaultSelector() as selector:
|
|
190
189
|
selector.register(fd, selectors.EVENT_READ)
|
|
191
|
-
|
|
192
|
-
while
|
|
190
|
+
|
|
191
|
+
while selector.select(0):
|
|
193
192
|
chars.extend(self._term_input_file.recv(1024))
|
|
194
|
-
input_ready = selector.select(0)
|
|
195
193
|
|
|
196
194
|
return chars
|
|
197
195
|
|
|
@@ -204,8 +202,8 @@ class Screen(_raw_display_base.Screen):
|
|
|
204
202
|
raise RuntimeError("Unexpected terminal output file")
|
|
205
203
|
handle = _win32.GetStdHandle(_win32.STD_OUTPUT_HANDLE)
|
|
206
204
|
info = _win32.CONSOLE_SCREEN_BUFFER_INFO()
|
|
207
|
-
|
|
208
|
-
if
|
|
205
|
+
|
|
206
|
+
if _win32.GetConsoleScreenBufferInfo(handle, byref(info)):
|
|
209
207
|
# Fallback will be used in case of term size could not be determined
|
|
210
208
|
y, x = info.dwSize.Y, info.dwSize.X
|
|
211
209
|
|
urwid/display/common.py
CHANGED
|
@@ -361,19 +361,21 @@ def _color_desc_88(num: int) -> str:
|
|
|
361
361
|
|
|
362
362
|
|
|
363
363
|
def _parse_color_true(desc: str) -> int | None:
|
|
364
|
-
c
|
|
365
|
-
if c is not None:
|
|
364
|
+
if (c := _parse_color_256(desc)) is not None:
|
|
366
365
|
(r, g, b) = _COLOR_VALUES_256[c]
|
|
367
366
|
return (r << 16) + (g << 8) + b
|
|
368
367
|
|
|
369
368
|
if not desc.startswith("#"):
|
|
370
369
|
return None
|
|
370
|
+
|
|
371
371
|
if len(desc) == 7:
|
|
372
372
|
h = desc[1:]
|
|
373
373
|
return int(h, 16)
|
|
374
|
+
|
|
374
375
|
if len(desc) == 4:
|
|
375
376
|
h = f"0x{desc[1]}0{desc[2]}0{desc[3]}"
|
|
376
377
|
return int(h, 16)
|
|
378
|
+
|
|
377
379
|
return None
|
|
378
380
|
|
|
379
381
|
|
|
@@ -409,16 +411,16 @@ def _parse_color_256(desc: str) -> int | None:
|
|
|
409
411
|
|
|
410
412
|
if desc.startswith("#") and len(desc) == 4:
|
|
411
413
|
# color-cube coordinates
|
|
412
|
-
rgb
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
return
|
|
414
|
+
if (rgb := int(desc[1:], 16)) >= 0:
|
|
415
|
+
b, rgb = rgb % 16, rgb // 16
|
|
416
|
+
g, r = rgb % 16, rgb // 16
|
|
417
|
+
# find the closest rgb values
|
|
418
|
+
r = _CUBE_256_LOOKUP_16[r]
|
|
419
|
+
g = _CUBE_256_LOOKUP_16[g]
|
|
420
|
+
b = _CUBE_256_LOOKUP_16[b]
|
|
421
|
+
return _CUBE_START + (r * _CUBE_SIZE_256 + g) * _CUBE_SIZE_256 + b
|
|
422
|
+
|
|
423
|
+
return None
|
|
422
424
|
|
|
423
425
|
# Only remaining possibility is gray value
|
|
424
426
|
if desc.startswith("g#"):
|
|
@@ -489,16 +491,16 @@ def _parse_color_88(desc: str) -> int | None:
|
|
|
489
491
|
|
|
490
492
|
if desc.startswith("#") and len(desc) == 4:
|
|
491
493
|
# color-cube coordinates
|
|
492
|
-
rgb
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
return
|
|
494
|
+
if (rgb := int(desc[1:], 16)) >= 0:
|
|
495
|
+
b, rgb = rgb % 16, rgb // 16
|
|
496
|
+
g, r = rgb % 16, rgb // 16
|
|
497
|
+
# find the closest rgb values
|
|
498
|
+
r = _CUBE_88_LOOKUP_16[r]
|
|
499
|
+
g = _CUBE_88_LOOKUP_16[g]
|
|
500
|
+
b = _CUBE_88_LOOKUP_16[b]
|
|
501
|
+
return _CUBE_START + (r * _CUBE_SIZE_88 + g) * _CUBE_SIZE_88 + b
|
|
502
|
+
|
|
503
|
+
return None
|
|
502
504
|
|
|
503
505
|
# Only remaining possibility is gray value
|
|
504
506
|
if desc.startswith("g#"):
|
|
@@ -704,15 +706,6 @@ class AttrSpec:
|
|
|
704
706
|
return 16
|
|
705
707
|
return 1
|
|
706
708
|
|
|
707
|
-
def _colors(self) -> int:
|
|
708
|
-
warnings.warn(
|
|
709
|
-
f"Method `{self.__class__.__name__}._colors` is deprecated, "
|
|
710
|
-
f"please use property `{self.__class__.__name__}.colors`",
|
|
711
|
-
DeprecationWarning,
|
|
712
|
-
stacklevel=2,
|
|
713
|
-
)
|
|
714
|
-
return self.colors
|
|
715
|
-
|
|
716
709
|
def __repr__(self) -> str:
|
|
717
710
|
"""
|
|
718
711
|
Return an executable python representation of the AttrSpec
|
|
@@ -785,15 +778,6 @@ class AttrSpec:
|
|
|
785
778
|
color = 0
|
|
786
779
|
self.__value = (self.__value & ~_FG_MASK) | color | flags
|
|
787
780
|
|
|
788
|
-
def _foreground(self) -> str:
|
|
789
|
-
warnings.warn(
|
|
790
|
-
f"Method `{self.__class__.__name__}._foreground` is deprecated, "
|
|
791
|
-
f"please use property `{self.__class__.__name__}.foreground`",
|
|
792
|
-
DeprecationWarning,
|
|
793
|
-
stacklevel=2,
|
|
794
|
-
)
|
|
795
|
-
return self.foreground
|
|
796
|
-
|
|
797
781
|
@property
|
|
798
782
|
def background(self) -> str:
|
|
799
783
|
"""Return the background color."""
|
|
@@ -827,15 +811,6 @@ class AttrSpec:
|
|
|
827
811
|
raise AttrSpecError(f"Unrecognised color specification in background ({background!r})")
|
|
828
812
|
self.__value = (self.__value & ~_BG_MASK) | (color << _BG_SHIFT) | flags
|
|
829
813
|
|
|
830
|
-
def _background(self) -> str:
|
|
831
|
-
warnings.warn(
|
|
832
|
-
f"Method `{self.__class__.__name__}._background` is deprecated, "
|
|
833
|
-
f"please use property `{self.__class__.__name__}.background`",
|
|
834
|
-
DeprecationWarning,
|
|
835
|
-
stacklevel=2,
|
|
836
|
-
)
|
|
837
|
-
return self.background
|
|
838
|
-
|
|
839
814
|
def get_rgb_values(self) -> tuple[int | None, int | None, int | None, int | None, int | None, int | None]:
|
|
840
815
|
"""
|
|
841
816
|
Return (fg_red, fg_green, fg_blue, bg_red, bg_green, bg_blue) color
|
|
@@ -988,13 +963,9 @@ class ScreenError(Exception):
|
|
|
988
963
|
pass
|
|
989
964
|
|
|
990
965
|
|
|
991
|
-
class
|
|
992
|
-
"""Base metaclass for abstra"""
|
|
993
|
-
|
|
994
|
-
|
|
995
|
-
class BaseScreen(metaclass=BaseMeta):
|
|
966
|
+
class BaseScreen(abc.ABC, metaclass=signals.MetaSignals):
|
|
996
967
|
"""
|
|
997
|
-
Base class for Screen classes (raw_display.Screen,
|
|
968
|
+
Base class for Screen classes (raw_display.Screen, ..., etc.)
|
|
998
969
|
"""
|
|
999
970
|
|
|
1000
971
|
signals: typing.ClassVar[list[str]] = [UPDATE_PALETTE_ENTRY, INPUT_DESCRIPTORS_CHANGED]
|
urwid/display/curses.py
CHANGED
|
@@ -124,7 +124,7 @@ class Screen(BaseScreen, RealTerminal):
|
|
|
124
124
|
After calling this function get_input will include mouse
|
|
125
125
|
click events along with keystrokes.
|
|
126
126
|
"""
|
|
127
|
-
enable = bool(enable)
|
|
127
|
+
enable = bool(enable)
|
|
128
128
|
if enable == self._mouse_tracking_enabled:
|
|
129
129
|
return
|
|
130
130
|
|
urwid/display/escape.py
CHANGED
|
@@ -216,10 +216,10 @@ class KeyqueueTrie:
|
|
|
216
216
|
root[ord(s)] = result
|
|
217
217
|
|
|
218
218
|
def get(self, keys, more_available: bool):
|
|
219
|
-
result
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
return
|
|
219
|
+
if result := self.get_recurse(self.data, keys, more_available):
|
|
220
|
+
return result
|
|
221
|
+
|
|
222
|
+
return self.read_cursor_position(keys, more_available)
|
|
223
223
|
|
|
224
224
|
def get_recurse(
|
|
225
225
|
self,
|
|
@@ -540,9 +540,7 @@ def process_keyqueue(codes: Sequence[int], more_available: bool) -> tuple[list[s
|
|
|
540
540
|
if code != 27:
|
|
541
541
|
return [f"<{code:d}>"], codes[1:]
|
|
542
542
|
|
|
543
|
-
result
|
|
544
|
-
|
|
545
|
-
if result is not None:
|
|
543
|
+
if (result := input_trie.get(codes[1:], more_available)) is not None:
|
|
546
544
|
result, remaining_codes = result
|
|
547
545
|
return [result], remaining_codes
|
|
548
546
|
|
|
@@ -553,7 +551,7 @@ def process_keyqueue(codes: Sequence[int], more_available: bool) -> tuple[list[s
|
|
|
553
551
|
return ["esc", *run], remaining_codes
|
|
554
552
|
if run[0] == "esc" or run[0].find("meta ") >= 0:
|
|
555
553
|
return ["esc", *run], remaining_codes
|
|
556
|
-
return [f"meta {run[0]}"
|
|
554
|
+
return [f"meta {run[0]}", *run[1:]], remaining_codes
|
|
557
555
|
|
|
558
556
|
return ["esc"], codes[1:]
|
|
559
557
|
|
urwid/display/lcd.py
CHANGED
|
@@ -218,10 +218,9 @@ class CFLCDScreen(LCDScreen, abc.ABC):
|
|
|
218
218
|
raise cls.MoreDataRequired
|
|
219
219
|
|
|
220
220
|
data_end = 2 + packet_len
|
|
221
|
-
crc
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
raise cls.InvalidPacket("CRC doesn't match")
|
|
221
|
+
if (crc := cls.get_crc(data[:data_end])) != (packet_crc := data[data_end : data_end + 2]):
|
|
222
|
+
raise cls.InvalidPacket(f"CRC doesn't match ({crc=}, {packet_crc=})")
|
|
223
|
+
|
|
225
224
|
return command, data[2:data_end], data[data_end + 2 :]
|
|
226
225
|
|
|
227
226
|
|
|
@@ -401,8 +400,7 @@ class CF635Screen(CFLCDScreen):
|
|
|
401
400
|
|
|
402
401
|
packet = self._read_packet()
|
|
403
402
|
|
|
404
|
-
next_repeat
|
|
405
|
-
if next_repeat:
|
|
403
|
+
if next_repeat := self.key_repeat.next_event():
|
|
406
404
|
timeout, key = next_repeat
|
|
407
405
|
if not timeout:
|
|
408
406
|
data_input.append(key)
|
urwid/display/web.py
CHANGED
|
@@ -21,6 +21,7 @@
|
|
|
21
21
|
"""
|
|
22
22
|
Urwid web application display module
|
|
23
23
|
"""
|
|
24
|
+
|
|
24
25
|
from __future__ import annotations
|
|
25
26
|
|
|
26
27
|
import dataclasses
|
|
@@ -216,7 +217,7 @@ class Screen(BaseScreen):
|
|
|
216
217
|
sys.stdout.write("Status: 503 Sever Busy\r\n\r\n")
|
|
217
218
|
sys.exit(0)
|
|
218
219
|
|
|
219
|
-
urwid_id = f"{random.randrange(10
|
|
220
|
+
urwid_id = f"{random.randrange(10**9):09d}{random.randrange(10**9):09d}" # noqa: S311
|
|
220
221
|
self.pipe_name = os.path.join(_prefs.pipe_dir, f"urwid{urwid_id}")
|
|
221
222
|
os.mkfifo(f"{self.pipe_name}.in", 0o600)
|
|
222
223
|
signal.signal(signal.SIGTERM, self._cleanup_pipe)
|
|
@@ -224,11 +225,7 @@ class Screen(BaseScreen):
|
|
|
224
225
|
self.input_fd = os.open(f"{self.pipe_name}.in", os.O_NONBLOCK | os.O_RDONLY)
|
|
225
226
|
self.input_tail = ""
|
|
226
227
|
self.content_head = (
|
|
227
|
-
"Content-type: "
|
|
228
|
-
"multipart/x-mixed-replace;boundary=ZZ\r\n"
|
|
229
|
-
"X-Urwid-ID: " + urwid_id + "\r\n"
|
|
230
|
-
"\r\n\r\n"
|
|
231
|
-
"--ZZ\r\n"
|
|
228
|
+
f"Content-type: multipart/x-mixed-replace;boundary=ZZ\r\nX-Urwid-ID: {urwid_id}\r\n\r\n\r\n--ZZ\r\n"
|
|
232
229
|
)
|
|
233
230
|
if self.update_method == "polling":
|
|
234
231
|
self.content_head = f"Content-type: text/plain\r\nX-Urwid-ID: {urwid_id}\r\n\r\n\r\n"
|
|
@@ -328,8 +325,8 @@ class Screen(BaseScreen):
|
|
|
328
325
|
if y == cy:
|
|
329
326
|
sig = (*sig, cx)
|
|
330
327
|
new_screen[sig] = [*new_screen.get(sig, []), y]
|
|
331
|
-
|
|
332
|
-
if old_line_numbers is not None:
|
|
328
|
+
|
|
329
|
+
if (old_line_numbers := self.last_screen.get(sig, None)) is not None:
|
|
333
330
|
if y in old_line_numbers:
|
|
334
331
|
old_line = y
|
|
335
332
|
else:
|
|
@@ -609,16 +606,14 @@ def daemonize(errfile: str) -> None:
|
|
|
609
606
|
"""
|
|
610
607
|
Detach process and become a daemon.
|
|
611
608
|
"""
|
|
612
|
-
|
|
613
|
-
if pid:
|
|
609
|
+
if os.fork():
|
|
614
610
|
os._exit(0)
|
|
615
611
|
|
|
616
612
|
os.setsid()
|
|
617
613
|
signal.signal(signal.SIGHUP, signal.SIG_IGN)
|
|
618
614
|
os.umask(0)
|
|
619
615
|
|
|
620
|
-
|
|
621
|
-
if pid:
|
|
616
|
+
if os.fork():
|
|
622
617
|
os._exit(0)
|
|
623
618
|
|
|
624
619
|
os.chdir("/")
|
urwid/event_loop/asyncio_loop.py
CHANGED
|
@@ -41,7 +41,6 @@ if typing.TYPE_CHECKING:
|
|
|
41
41
|
_T = typing.TypeVar("_T")
|
|
42
42
|
|
|
43
43
|
__all__ = ("AsyncioEventLoop",)
|
|
44
|
-
IS_WINDOWS = sys.platform == "win32"
|
|
45
44
|
|
|
46
45
|
|
|
47
46
|
class AsyncioEventLoop(EventLoop):
|
|
@@ -67,20 +66,37 @@ class AsyncioEventLoop(EventLoop):
|
|
|
67
66
|
def __init__(self, *, loop: asyncio.AbstractEventLoop | None = None, **kwargs) -> None:
|
|
68
67
|
super().__init__()
|
|
69
68
|
self.logger = logging.getLogger(__name__).getChild(self.__class__.__name__)
|
|
70
|
-
|
|
71
|
-
|
|
69
|
+
|
|
70
|
+
if sys.version_info[:2] < (3, 11):
|
|
72
71
|
self._event_loop_policy_altered: bool = False
|
|
73
72
|
self._original_event_loop_policy: asyncio.AbstractEventLoopPolicy | None = None
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
self.logger.debug("Set WindowsSelectorEventLoopPolicy as asyncio event loop policy")
|
|
78
|
-
asyncio.set_event_loop_policy(asyncio.WindowsSelectorEventLoopPolicy())
|
|
79
|
-
self._event_loop_policy_altered = True
|
|
73
|
+
|
|
74
|
+
if loop:
|
|
75
|
+
self._loop: asyncio.AbstractEventLoop = loop
|
|
80
76
|
else:
|
|
81
|
-
self.
|
|
77
|
+
self._original_event_loop_policy = asyncio.get_event_loop_policy()
|
|
78
|
+
if sys.platform == "win32" and not isinstance(
|
|
79
|
+
self._original_event_loop_policy, asyncio.WindowsSelectorEventLoopPolicy
|
|
80
|
+
):
|
|
81
|
+
self.logger.debug("Set WindowsSelectorEventLoopPolicy as asyncio event loop policy")
|
|
82
|
+
asyncio.set_event_loop_policy(asyncio.WindowsSelectorEventLoopPolicy())
|
|
83
|
+
self._event_loop_policy_altered = True
|
|
84
|
+
else:
|
|
85
|
+
self._event_loop_policy_altered = False
|
|
86
|
+
|
|
87
|
+
self._loop = asyncio.get_event_loop()
|
|
82
88
|
|
|
83
|
-
|
|
89
|
+
else:
|
|
90
|
+
self._runner: asyncio.Runner | None = None
|
|
91
|
+
|
|
92
|
+
if loop:
|
|
93
|
+
self._loop: asyncio.AbstractEventLoop = loop
|
|
94
|
+
else:
|
|
95
|
+
try:
|
|
96
|
+
self._loop = asyncio.get_running_loop()
|
|
97
|
+
except RuntimeError:
|
|
98
|
+
self._runner = asyncio.Runner(loop_factory=asyncio.SelectorEventLoop)
|
|
99
|
+
self._loop = self._runner.get_loop()
|
|
84
100
|
|
|
85
101
|
self._exc: BaseException | None = None
|
|
86
102
|
|
|
@@ -89,8 +105,11 @@ class AsyncioEventLoop(EventLoop):
|
|
|
89
105
|
self._idle_callbacks: dict[int, Callable[[], typing.Any]] = {}
|
|
90
106
|
|
|
91
107
|
def __del__(self) -> None:
|
|
92
|
-
if
|
|
93
|
-
|
|
108
|
+
if sys.version_info[:2] < (3, 11):
|
|
109
|
+
if self._event_loop_policy_altered:
|
|
110
|
+
asyncio.set_event_loop_policy(self._original_event_loop_policy) # Restore default event loop policy
|
|
111
|
+
elif self._runner is not None:
|
|
112
|
+
self._runner.close()
|
|
94
113
|
|
|
95
114
|
def _also_call_idle(self, callback: Callable[_Spec, _T]) -> Callable[_Spec, _T]:
|
|
96
115
|
"""
|
|
@@ -205,8 +224,7 @@ class AsyncioEventLoop(EventLoop):
|
|
|
205
224
|
return True
|
|
206
225
|
|
|
207
226
|
def _exception_handler(self, loop: asyncio.AbstractEventLoop, context):
|
|
208
|
-
exc
|
|
209
|
-
if exc:
|
|
227
|
+
if exc := context.get("exception"):
|
|
210
228
|
loop.stop()
|
|
211
229
|
|
|
212
230
|
if self._idle_asyncio_handle:
|