mirror of
https://github.com/pdxlocations/contact.git
synced 2026-11-01 08:35:46 +01:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f375d788f1 | ||
|
|
4c4b8a42c5 |
No files matched your search
+24
-17
@@ -2065,34 +2065,41 @@ def refresh_pad(window: int, commit: bool = True) -> None:
|
||||
|
||||
# Clamp start_index within the pad's height
|
||||
pad_h, pad_w = pad.getmaxyx()
|
||||
if pad_h <= 0:
|
||||
if pad_h <= 0 or pad_w <= 0:
|
||||
return
|
||||
start_index = max(0, min(start_index, max(0, pad_h - 1)))
|
||||
|
||||
top = box_y + 1
|
||||
left = box_x + 1
|
||||
bottom = box_y + min(inner_h, lines) # inclusive
|
||||
right = box_x + min(inner_w, box_w - 2)
|
||||
# A resize can leave the frame larger than its pad or the screen.
|
||||
# noutrefresh requires both source and destination rectangles to fit.
|
||||
bottom = min(top + lines - 1, top + pad_h - start_index - 1, curses.LINES - 1)
|
||||
right = min(left + inner_w - 1, left + pad_w - 1, curses.COLS - 1)
|
||||
|
||||
if bottom < top or right < left:
|
||||
return
|
||||
|
||||
draw_frame_title(box, get_window_title(window))
|
||||
box.noutrefresh()
|
||||
try:
|
||||
box.noutrefresh()
|
||||
|
||||
# The frame overlaps the pad's viewport. Recompose even unchanged pad
|
||||
# rows before committing, so its text cannot flash blank between draws.
|
||||
pad.touchwin()
|
||||
pad.noutrefresh(
|
||||
start_index,
|
||||
0,
|
||||
top,
|
||||
left,
|
||||
bottom,
|
||||
right,
|
||||
)
|
||||
if commit:
|
||||
curses.doupdate()
|
||||
# The frame overlaps the pad's viewport. Recompose even unchanged pad
|
||||
# rows before committing, so its text cannot flash blank between draws.
|
||||
pad.touchwin()
|
||||
pad.noutrefresh(
|
||||
start_index,
|
||||
0,
|
||||
top,
|
||||
left,
|
||||
bottom,
|
||||
right,
|
||||
)
|
||||
if commit:
|
||||
curses.doupdate()
|
||||
except curses.error:
|
||||
# The terminal can resize again between checking bounds and drawing.
|
||||
# Let the next resize/redraw rebuild the windows instead of exiting.
|
||||
ui_state.redraw_full_ui = True
|
||||
|
||||
|
||||
def add_notification(channel_number: int) -> None:
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
[project]
|
||||
name = "contact"
|
||||
version = "1.7.3"
|
||||
version = "1.7.4"
|
||||
description = "This Python curses client for Meshtastic is a terminal-based client designed to manage device settings, enable mesh chat communication, and handle configuration backups and restores."
|
||||
authors = [
|
||||
{name = "Ben Lipsey",email = "ben@pdxlocations.com"}
|
||||
|
||||
@@ -12,6 +12,28 @@ from tests.test_support import reset_shared_state, restore_config, snapshot_conf
|
||||
|
||||
|
||||
class ContactUiTests(unittest.TestCase):
|
||||
def test_refresh_pad_clips_to_pad_and_resized_screen(self):
|
||||
for pad_size, screen_size, expected in (
|
||||
((2, 5), (24, 80), (1, 0, 1, 1, 1, 5)),
|
||||
((100, 100), (6, 8), (1, 0, 1, 1, 5, 7)),
|
||||
):
|
||||
with self.subTest(pad_size=pad_size, screen_size=screen_size), ExitStack() as stack:
|
||||
box = mock.Mock()
|
||||
box.getmaxyx.return_value = (40, 100)
|
||||
box.getbegyx.return_value = (0, 0)
|
||||
pad = mock.Mock()
|
||||
pad.getmaxyx.return_value = pad_size
|
||||
ui_state.selected_channel = 38
|
||||
stack.enter_context(mock.patch.object(contact_ui, "channel_win", box, create=True))
|
||||
stack.enter_context(mock.patch.object(contact_ui, "channel_pad", pad, create=True))
|
||||
stack.enter_context(mock.patch.object(contact_ui.curses, "LINES", screen_size[0], create=True))
|
||||
stack.enter_context(mock.patch.object(contact_ui.curses, "COLS", screen_size[1], create=True))
|
||||
contact_ui.refresh_pad(0, commit=False)
|
||||
pad.noutrefresh.assert_called_once_with(*expected)
|
||||
pad.noutrefresh.side_effect = contact_ui.curses.error("resize during refresh")
|
||||
contact_ui.refresh_pad(0, commit=False)
|
||||
self.assertTrue(ui_state.redraw_full_ui)
|
||||
|
||||
def test_f5_rebuilds_background_before_staging_after_terminal_resize(self):
|
||||
for size in ((24, 80), (50, 140)):
|
||||
with self.subTest(size=size), ExitStack() as stack:
|
||||
@@ -594,6 +616,8 @@ class ContactUiTests(unittest.TestCase):
|
||||
|
||||
def test_refresh_pad_draws_selected_channel_title_on_message_frame(self) -> None:
|
||||
self.addCleanup(mock.patch.stopall)
|
||||
mock.patch.object(contact_ui.curses, "LINES", 24, create=True).start()
|
||||
mock.patch.object(contact_ui.curses, "COLS", 80, create=True).start()
|
||||
mock.patch.object(contact_ui, "packetlog_win", mock.Mock(), create=True).start()
|
||||
ui_state.single_pane_mode = True
|
||||
ui_state.current_window = 1
|
||||
|
||||
Reference in new issue
Block a user