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
----------------------------------------
opt. maintain history between sessions
directory view for file scheme
search in page (ugh)
BACKLOG
--------------------------------------------------------------------------------
click on links to open them
provide a plugin interface for schemes
get/set config using command-line
async event system
download without memory buffer
download in the background
download view instead of last download
@ -22,13 +26,11 @@ response code 11 (if still there)
gopher?
finger?
web????
opt. maintain history between sessions
history (forward) (useful?)
search in page (ugh)
remember scroll pos in history
identity management
"previous/next" pages
directory view for file scheme
configurable keybinds
@ -56,3 +58,4 @@ logging
home page
different rendering mode
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():
argparser = argparse.ArgumentParser()
argparser = argparse.ArgumentParser(description="Gemini browser")
argparser.add_argument("url", nargs="?", default=None)
argparser.add_argument("-d", "--debug", action="store_true")
args = argparser.parse_args()

View file

@ -25,6 +25,7 @@ from bebop.help import get_help
from bebop.history import History
from bebop.identity import load_identities
from bebop.links import Links
from bebop.metalines import LineType
from bebop.mime import MimeType
from bebop.mouse import ButtonState
from bebop.navigation import (
@ -238,7 +239,7 @@ class Browser:
try:
self.handle_mouse(*curses.getmouse())
except curses.error:
pass
logging.error(f"Failed to get mouse information.")
elif char == curses.KEY_RESIZE:
self.handle_resize()
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
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:
- url: an URL string, may not be completely compliant.
- 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):
"""Handle mouse events.
Right now, only vertical scrolling is handled.
Vertical scrolling is handled, and clicking on links.
"""
if bstate & ButtonState.SCROLL_UP:
self.scroll_page_vertically(-3)
elif bstate & ButtonState.SCROLL_DOWN:
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):
"""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_3, curses.COLOR_MAGENTA, 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)
except curses.error:
logging.error("Failed to init colors.")