From c9b1a0d3e42d27ec2786103ec3bc812a5d38da6c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jaakko=20Ker=C3=A4nen?= Date: Sat, 14 Nov 2020 12:40:17 +0200 Subject: [PATCH 1/1] Navigating to parent directory or site root Added keyboard shortcuts for navigating up to the parent directory and to the site root. Clicking the top banner also navigates to the site root. IssueID #29 --- src/ui/documentwidget.c | 70 ++++++++++++++++++++++++++++++----------- src/ui/keys.h | 4 +++ src/ui/util.c | 6 ++++ src/ui/window.c | 4 +-- 4 files changed, 64 insertions(+), 20 deletions(-) diff --git a/src/ui/documentwidget.c b/src/ui/documentwidget.c index c71758be..3fc7e841 100644 --- a/src/ui/documentwidget.c +++ b/src/ui/documentwidget.c @@ -225,6 +225,8 @@ void init_DocumentWidget(iDocumentWidget *d) { #endif addAction_Widget(w, navigateBack_KeyShortcut, "navigate.back"); addAction_Widget(w, navigateForward_KeyShortcut, "navigate.forward"); + addAction_Widget(w, navigateParent_KeyShortcut, "navigate.parent"); + addAction_Widget(w, navigateRoot_KeyShortcut, "navigate.root"); } void deinit_DocumentWidget(iDocumentWidget *d) { @@ -259,13 +261,6 @@ static void requestUpdated_DocumentWidget_(iAnyObject *obj) { } } -#if 0 -static void requestTimedOut_DocumentWidget_(iAnyObject *obj) { - iDocumentWidget *d = obj; - postCommandf_App("document.request.timeout doc:%p request:%p", d, d->request); -} -#endif - static void requestFinished_DocumentWidget_(iAnyObject *obj) { iDocumentWidget *d = obj; postCommand_Widget(obj, "document.request.finished doc:%p request:%p", d, d->request); @@ -301,6 +296,16 @@ static iRect documentBounds_DocumentWidget_(const iDocumentWidget *d) { return rect; } +static iRect siteBannerRect_DocumentWidget_(const iDocumentWidget *d) { + const iGmRun *banner = siteBanner_GmDocument(d->doc); + if (!banner) { + return zero_Rect(); + } + const iRect docBounds = documentBounds_DocumentWidget_(d); + const iInt2 origin = addY_I2(topLeft_Rect(docBounds), -value_Anim(&d->scrollY)); + return moved_Rect(banner->visBounds, origin); +} + static int forceBreakWidth_DocumentWidget_(const iDocumentWidget *d) { if (equalCase_Rangecc(urlScheme_String(d->mod.url), "gopher")) { return documentWidth_DocumentWidget_(d); @@ -1397,13 +1402,6 @@ static iBool handleCommand_DocumentWidget_(iDocumentWidget *d, const char *cmd) postCommandf_App("document.changed url:%s", cstr_String(d->mod.url)); return iFalse; } -#if 0 - else if (equal_Command(cmd, "document.request.timeout") && - pointerLabel_Command(cmd, "request") == d->request) { - cancel_GmRequest(d->request); - return iFalse; - } -#endif else if (equal_Command(cmd, "media.updated") || equal_Command(cmd, "media.finished")) { return handleMediaCommand_DocumentWidget_(d, cmd); } @@ -1528,6 +1526,32 @@ static iBool handleCommand_DocumentWidget_(iDocumentWidget *d, const char *cmd) goForward_History(d->mod.history); return iTrue; } + else if (equal_Command(cmd, "navigate.parent") && document_App() == d) { + iUrl parts; + init_Url(&parts, d->mod.url); + /* Remove the last path segment. */ + if (size_Range(&parts.path) > 1) { + if (parts.path.end[-1] == '/') { + parts.path.end--; + } + while (parts.path.end > parts.path.start) { + if (parts.path.end[-1] == '/') break; + parts.path.end--; + } + postCommandf_App( + "open url:%s", + cstr_Rangecc((iRangecc){ constBegin_String(d->mod.url), parts.path.end })); + } + return iTrue; + } + else if (equal_Command(cmd, "navigate.root") && document_App() == d) { + iUrl parts; + init_Url(&parts, d->mod.url); + postCommandf_App( + "open url:%s/", + cstr_Rangecc((iRangecc){ constBegin_String(d->mod.url), parts.path.start })); + return iTrue; + } else if (equalWidget_Command(cmd, w, "scroll.moved")) { init_Anim(&d->scrollY, arg_Command(cmd)); updateVisible_DocumentWidget_(d); @@ -1922,11 +1946,15 @@ static iBool processEvent_DocumentWidget_(iDocumentWidget *d, const SDL_Event *e } else if (ev->type == SDL_MOUSEMOTION) { iChangeFlags(d->flags, noHoverWhileScrolling_DocumentWidgetFlag, iFalse); + const iInt2 mpos = init_I2(ev->motion.x, ev->motion.y); if (isVisible_Widget(d->menu)) { setCursor_Window(get_Window(), SDL_SYSTEM_CURSOR_ARROW); } + else if (contains_Rect(siteBannerRect_DocumentWidget_(d), mpos)) { + setCursor_Window(get_Window(), SDL_SYSTEM_CURSOR_HAND); + } else { - updateHover_DocumentWidget_(d, init_I2(ev->motion.x, ev->motion.y)); + updateHover_DocumentWidget_(d, mpos); } updateOutlineOpacity_DocumentWidget_(d); } @@ -2006,11 +2034,13 @@ static iBool processEvent_DocumentWidget_(iDocumentWidget *d, const SDL_Event *e (iMenuItem[]){ { "Go Back", navigateBack_KeyShortcut, "navigate.back" }, { "Go Forward", navigateForward_KeyShortcut, "navigate.forward" }, + { "Go to Parent", navigateParent_KeyShortcut, "navigate.parent" }, + { "Go to Root", navigateRoot_KeyShortcut, "navigate.root" }, + { "---", 0, 0, NULL }, { "Reload Page", reload_KeyShortcut, "navigate.reload" }, { "---", 0, 0, NULL }, - { "Copy Page URL", 0, 0, "document.copylink" }, - { "---", 0, 0, NULL } }, - 6); + { "Copy Page URL", 0, 0, "document.copylink" } }, + 8); if (isEmpty_Range(&d->selectMark)) { pushBackN_Array( &items, @@ -2144,6 +2174,10 @@ static iBool processEvent_DocumentWidget_(iDocumentWidget *d, const SDL_Event *e d->selectMark = iNullRange; refresh_Widget(w); } + /* Clicking on the top/side banner navigates to site root. */ + if (contains_Rect(siteBannerRect_DocumentWidget_(d), pos_Click(&d->click))) { + postCommand_Widget(d, "navigate.root"); + } } return iTrue; case double_ClickResult: diff --git a/src/ui/keys.h b/src/ui/keys.h index a4c8f348..5bc9141c 100644 --- a/src/ui/keys.h +++ b/src/ui/keys.h @@ -32,6 +32,8 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ # define nextTab_KeyShortcut SDLK_RIGHTBRACKET, KMOD_SHIFT | KMOD_PRIMARY # define navigateBack_KeyShortcut SDLK_LEFT, KMOD_PRIMARY # define navigateForward_KeyShortcut SDLK_RIGHT, KMOD_PRIMARY +# define navigateParent_KeyShortcut SDLK_UP, KMOD_PRIMARY +# define navigateRoot_KeyShortcut SDLK_UP, KMOD_SHIFT | KMOD_PRIMARY # define byWord_KeyModifier KMOD_ALT # define byLine_KeyModifier KMOD_PRIMARY #else @@ -40,6 +42,8 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ # define nextTab_KeyShortcut SDLK_PAGEDOWN, KMOD_PRIMARY # define navigateBack_KeyShortcut SDLK_LEFT, KMOD_ALT # define navigateForward_KeyShortcut SDLK_RIGHT, KMOD_ALT +# define navigateParent_KeyShortcut SDLK_UP, KMOD_ALT +# define navigateRoot_KeyShortcut SDLK_UP, KMOD_SHIFT | KMOD_ALT # define byWord_KeyModifier KMOD_CTRL # define byLine_KeyModifier 0 #endif diff --git a/src/ui/util.c b/src/ui/util.c index ae3ddb18..bf044c03 100644 --- a/src/ui/util.c +++ b/src/ui/util.c @@ -92,6 +92,12 @@ void toString_Sym(int key, int kmods, iString *str) { else if (key == SDLK_RIGHT) { appendChar_String(str, 0x2192); } + else if (key == SDLK_UP) { + appendChar_String(str, 0x2191); + } + else if (key == SDLK_DOWN) { + appendChar_String(str, 0x2193); + } else if (key < 128 && (isalnum(key) || ispunct(key))) { appendChar_String(str, upper_Char(key)); } diff --git a/src/ui/window.c b/src/ui/window.c index 115dd04b..a69dd7db 100644 --- a/src/ui/window.c +++ b/src/ui/window.c @@ -146,6 +146,8 @@ static const iMenuItem viewMenuItems[] = { { "---", 0, 0, NULL }, { "Go Back", SDLK_LEFTBRACKET, KMOD_PRIMARY, "navigate.back" }, { "Go Forward", SDLK_RIGHTBRACKET, KMOD_PRIMARY, "navigate.forward" }, + { "Go to Parent", navigateParent_KeyShortcut, "navigate.parent" }, + { "Go to Root", navigateRoot_KeyShortcut, "navigate.root" }, { "Reload Page", reload_KeyShortcut, "navigate.reload" }, { "---", 0, 0, NULL }, { "Zoom In", SDLK_EQUALS, KMOD_PRIMARY, "zoom.delta arg:10" }, @@ -473,14 +475,12 @@ static void setupUserInterface_Window(iWindow *d) { /* Global keyboard shortcuts. */ { addAction_Widget(d->root, prevTab_KeyShortcut, "tabs.prev"); addAction_Widget(d->root, nextTab_KeyShortcut, "tabs.next"); -#if !defined (iHaveNativeMenus) addAction_Widget(d->root, 'l', KMOD_PRIMARY, "navigate.focus"); addAction_Widget(d->root, 'f', KMOD_PRIMARY, "focus.set id:find.input"); addAction_Widget(d->root, '1', KMOD_PRIMARY, "sidebar.mode arg:0 toggle:1"); addAction_Widget(d->root, '2', KMOD_PRIMARY, "sidebar.mode arg:1 toggle:1"); addAction_Widget(d->root, '3', KMOD_PRIMARY, "sidebar.mode arg:2 toggle:1"); addAction_Widget(d->root, '4', KMOD_PRIMARY, "sidebar.mode arg:3 toggle:1"); -#endif } } -- 2.34.1