Compare commits

..

3 commits

Author SHA1 Message Date
dece 0c1924d40a colors: use blue for blockquotes instead of cyan 2021-06-03 03:29:30 +02:00
dece 3b255c2df3 browser: handle clicks on links 2021-06-02 22:59:40 +02:00
dece 29ef4f9083 board: update for next release 2021-06-02 22:59:40 +02:00
4 changed files with 44 additions and 12 deletions

View file

@ -1,12 +1,16 @@
TODO TODO
---------------------------------------- ----------------------------------------
opt. maintain history between sessions
directory view for file scheme
search in page (ugh)
BACKLOG BACKLOG
-------------------------------------------------------------------------------- --------------------------------------------------------------------------------
click on links to open them provide a plugin interface for schemes
get/set config using command-line get/set config using command-line
async event system
download without memory buffer download without memory buffer
download in the background download in the background
download view instead of last download download view instead of last download
@ -22,13 +26,11 @@ response code 11 (if still there)
gopher? gopher?
finger? finger?
web???? web????
opt. maintain history between sessions
history (forward) (useful?) history (forward) (useful?)
search in page (ugh)
remember scroll pos in history remember scroll pos in history
identity management identity management
"previous/next" pages "previous/next" pages
directory view for file scheme configurable keybinds
@ -56,3 +58,4 @@ logging
home page home page
different rendering mode different rendering mode
preferences per site preferences per site
basic mouse support

View file

@ -8,7 +8,7 @@ from bebop.tofu import get_cert_stash_path, load_cert_stash, save_cert_stash
def main(): def main():
argparser = argparse.ArgumentParser() argparser = argparse.ArgumentParser(description="Gemini browser")
argparser.add_argument("url", nargs="?", default=None) argparser.add_argument("url", nargs="?", default=None)
argparser.add_argument("-d", "--debug", action="store_true") argparser.add_argument("-d", "--debug", action="store_true")
args = argparser.parse_args() args = argparser.parse_args()

View file

@ -25,6 +25,7 @@ from bebop.help import get_help
from bebop.history import History from bebop.history import History
from bebop.identity import load_identities from bebop.identity import load_identities
from bebop.links import Links from bebop.links import Links
from bebop.metalines import LineType
from bebop.mime import MimeType from bebop.mime import MimeType
from bebop.mouse import ButtonState from bebop.mouse import ButtonState
from bebop.navigation import ( from bebop.navigation import (
@ -238,7 +239,7 @@ class Browser:
try: try:
self.handle_mouse(*curses.getmouse()) self.handle_mouse(*curses.getmouse())
except curses.error: except curses.error:
pass logging.error(f"Failed to get mouse information.")
elif char == curses.KEY_RESIZE: elif char == curses.KEY_RESIZE:
self.handle_resize() self.handle_resize()
elif char == curses.ascii.ESC: # Can be ESC or ALT char. elif char == curses.ascii.ESC: # Can be ESC or ALT char.
@ -357,10 +358,6 @@ class Browser:
This function assumes that the URL can be from an user and thus tries a This function assumes that the URL can be from an user and thus tries a
few things to make it work. few things to make it work.
If there is no current URL (e.g. we just started) or `assume_absolute`
is True, assume it is an absolute URL. In other cases, parse it normally
and later check if it has to be used relatively to the current URL.
Arguments: Arguments:
- url: an URL string, may not be completely compliant. - url: an URL string, may not be completely compliant.
- base_url: an URL string to use as base in case `url` is relative. - base_url: an URL string to use as base in case `url` is relative.
@ -472,12 +469,44 @@ class Browser:
def handle_mouse(self, mouse_id: int, x: int, y: int, z: int, bstate: int): def handle_mouse(self, mouse_id: int, x: int, y: int, z: int, bstate: int):
"""Handle mouse events. """Handle mouse events.
Right now, only vertical scrolling is handled. Vertical scrolling is handled, and clicking on links.
""" """
if bstate & ButtonState.SCROLL_UP: if bstate & ButtonState.SCROLL_UP:
self.scroll_page_vertically(-3) self.scroll_page_vertically(-3)
elif bstate & ButtonState.SCROLL_DOWN: elif bstate & ButtonState.SCROLL_DOWN:
self.scroll_page_vertically(3) self.scroll_page_vertically(3)
elif bstate & ButtonState.LEFT_CLICKED:
self.handle_mouse_click(x, y)
def handle_mouse_click(self, x: int, y: int):
"""Handle a mouse click.
If the click is on a link (appropriate line and columns), open it.
"""
if not self.page_pad or not self.page_pad.current_page:
return
page = self.page_pad.current_page
px, py = self.page_pad.current_column, self.page_pad.current_line
line_pos = y + py
if line_pos >= len(page.metalines):
return
meta, line = page.metalines[line_pos]
if meta["type"] != LineType.LINK:
return
# "url" key is contained only in the first line of the link if its text
# is wrapped, so if the user did not click on the first line, rewind to
# get the URL.
while "url" not in meta:
line_pos -= 1
meta, line = page.metalines[line_pos]
url = meta["url"]
# The click is valid if it is on the link itself or the dimmed preview.
col_pos = x + px
if col_pos > len(line):
ch = self.page_pad.pad.instr(line_pos, col_pos, 1)
if ch == b' ':
return
self.open_url(url, base_url=self.current_url)
def handle_resize(self): def handle_resize(self):
"""Try to not make everything collapse on resizes.""" """Try to not make everything collapse on resizes."""

View file

@ -37,7 +37,7 @@ def init_colors(bg: int =-1):
curses.init_pair(ColorPair.TITLE_2, curses.COLOR_MAGENTA, bg) curses.init_pair(ColorPair.TITLE_2, curses.COLOR_MAGENTA, bg)
curses.init_pair(ColorPair.TITLE_3, curses.COLOR_MAGENTA, bg) curses.init_pair(ColorPair.TITLE_3, curses.COLOR_MAGENTA, bg)
curses.init_pair(ColorPair.PREFORMATTED, curses.COLOR_YELLOW, bg) curses.init_pair(ColorPair.PREFORMATTED, curses.COLOR_YELLOW, bg)
curses.init_pair(ColorPair.BLOCKQUOTE, curses.COLOR_CYAN, bg) curses.init_pair(ColorPair.BLOCKQUOTE, curses.COLOR_BLUE, bg)
curses.init_pair(ColorPair.LINK_PREVIEW, curses.COLOR_WHITE, bg) curses.init_pair(ColorPair.LINK_PREVIEW, curses.COLOR_WHITE, bg)
except curses.error: except curses.error:
logging.error("Failed to init colors.") logging.error("Failed to init colors.")