Fixed browser cursor position on scrolling

This commit is contained in:
Mark Qvist 2023-02-04 11:49:36 +01:00
parent a8d337a94e
commit dc64ab26d4
2 changed files with 75 additions and 6 deletions

View File

@ -26,13 +26,32 @@ class BrowserFrame(urwid.Frame):
elif key == "ctrl g":
nomadnet.NomadNetworkApp.get_shared_instance().ui.main_display.sub_displays.network_display.toggle_fullscreen()
elif self.get_focus() == "body":
if key == "down" or key == "up":
try:
if hasattr(self.delegate, "page_pile") and self.delegate.page_pile:
def df(loop, user_data):
st = None
nf = self.delegate.page_pile.get_focus()
if hasattr(nf, "key_timeout"):
st = nf
elif hasattr(nf, "original_widget"):
no = nf.original_widget
if hasattr(no, "original_widget"):
st = no.original_widget
else:
if hasattr(no, "key_timeout"):
st = no
if st and hasattr(st, "key_timeout") and hasattr(st, "keypress") and callable(st.keypress):
st.keypress(None, None)
nomadnet.NomadNetworkApp.get_shared_instance().ui.loop.set_alarm_in(0.25, df)
except Exception as e:
RNS.log("Error while setting up cursor timeout. The contained exception was: "+str(e), RNS.LOG_ERROR)
return super(BrowserFrame, self).keypress(size, key)
# if key == "up" and self.delegate.messagelist.top_is_visible:
# nomadnet.NomadNetworkApp.get_shared_instance().ui.main_display.frame.set_focus("header")
# elif key == "down" and self.delegate.messagelist.bottom_is_visible:
# self.set_focus("footer")
# else:
# return super(ConversationFrame, self).keypress(size, key)
else:
return super(BrowserFrame, self).keypress(size, key)
@ -80,6 +99,7 @@ class Browser:
self.link_target = None
self.frame = None
self.attr_maps = []
self.page_pile = None
self.build_display()
self.history = []
@ -219,6 +239,7 @@ class Browser:
self.browser_header = urwid.Text("")
self.browser_footer = urwid.Text("")
self.page_pile = None
self.browser_body = urwid.Filler(urwid.Text("Disconnected\n"+self.g["arrow_l"]+" "+self.g["arrow_r"], align="center"), "middle")
self.frame = BrowserFrame(self.browser_body, header=self.browser_header, footer=self.browser_footer)
@ -266,6 +287,7 @@ class Browser:
def update_display(self):
if self.status == Browser.DISCONECTED:
self.display_widget.set_attr_map({None: "inactive_text"})
self.page_pile = None
self.browser_body = urwid.Filler(urwid.Text("Disconnected\n"+self.g["arrow_l"]+" "+self.g["arrow_r"], align="center"), "middle")
self.browser_footer = urwid.Text("")
self.browser_header = urwid.Text("")
@ -314,6 +336,8 @@ class Browser:
def update_page_display(self):
pile = urwid.Pile(self.attr_maps)
pile.automove_cursor_on_scroll = True
self.page_pile = pile
self.browser_body = urwid.AttrMap(ScrollBar(Scrollable(pile, force_forward_keypress=True), thumb_char="\u2503", trough_char=" "), "scrollbar")
def identify(self):

View File

@ -107,6 +107,51 @@ class Scrollable(urwid.WidgetDecoration):
if canv_full.cursor is not None:
# Full canvas contains the cursor, but scrolled out of view
self._forward_keypress = False
# Reset cursor position on page/up down scrolling
try:
if hasattr(ow, "automove_cursor_on_scroll") and ow.automove_cursor_on_scroll:
pwi = 0
ch = 0
last_hidden = False
first_visible = False
for w,o in ow.contents:
wcanv = w.render((maxcol,))
wh = wcanv.rows()
if wh:
ch += wh
if not last_hidden and ch >= self._trim_top:
last_hidden = True
elif last_hidden:
if not first_visible:
first_visible = True
if w.selectable():
ow.focus_item = pwi
st = None
nf = ow.get_focus()
if hasattr(nf, "key_timeout"):
st = nf
elif hasattr(nf, "original_widget"):
no = nf.original_widget
if hasattr(no, "original_widget"):
st = no.original_widget
else:
if hasattr(no, "key_timeout"):
st = no
if st and hasattr(st, "key_timeout") and hasattr(st, "keypress") and callable(st.keypress):
st.keypress(None, None)
break
pwi += 1
except Exception as e:
pass
else:
# Original widget does not have a cursor, but may be selectable