diff options
author | Jaakko Keränen <jaakko.keranen@iki.fi> | 2020-12-19 07:33:34 +0200 |
---|---|---|
committer | Jaakko Keränen <jaakko.keranen@iki.fi> | 2020-12-19 07:33:34 +0200 |
commit | facdf3ca44c170aec9466b7e309a209de0c7f643 (patch) | |
tree | 662f0ba2c86c618d9cb3954f6a36ac1005534ed3 /src/ui | |
parent | b6923950df99ba6c8ca1e7234440321901fe804c (diff) |
Opening unrecognized schemes in default browser
This works if the OS supports the scheme as built-in or via some handler application.
IssueID #103
IssueID #84
Diffstat (limited to 'src/ui')
-rw-r--r-- | src/ui/documentwidget.c | 36 | ||||
-rw-r--r-- | src/ui/util.c | 5 | ||||
-rw-r--r-- | src/ui/util.h | 1 |
3 files changed, 28 insertions, 14 deletions
diff --git a/src/ui/documentwidget.c b/src/ui/documentwidget.c index 22fa29f8..3f3e453a 100644 --- a/src/ui/documentwidget.c +++ b/src/ui/documentwidget.c | |||
@@ -370,7 +370,7 @@ static void addVisible_DocumentWidget_(void *context, const iGmRun *run) { | |||
370 | if (run->audioId) { | 370 | if (run->audioId) { |
371 | pushBack_PtrArray(&d->visiblePlayers, run); | 371 | pushBack_PtrArray(&d->visiblePlayers, run); |
372 | } | 372 | } |
373 | if (run->linkId && linkFlags_GmDocument(d->doc, run->linkId) & supportedProtocol_GmLinkFlag) { | 373 | if (run->linkId) { |
374 | pushBack_PtrArray(&d->visibleLinks, run); | 374 | pushBack_PtrArray(&d->visibleLinks, run); |
375 | } | 375 | } |
376 | } | 376 | } |
@@ -2147,13 +2147,10 @@ static iBool processEvent_DocumentWidget_(iDocumentWidget *d, const SDL_Event *e | |||
2147 | const iGmRun *run = i.ptr; | 2147 | const iGmRun *run = i.ptr; |
2148 | if (run->flags & decoration_GmRunFlag && | 2148 | if (run->flags & decoration_GmRunFlag && |
2149 | visibleLinkOrdinal_DocumentWidget_(d, run->linkId) == ord) { | 2149 | visibleLinkOrdinal_DocumentWidget_(d, run->linkId) == ord) { |
2150 | const int kmods = keyMods_Sym(SDL_GetModState()); | ||
2151 | postCommandf_App("open newtab:%d url:%s", | 2150 | postCommandf_App("open newtab:%d url:%s", |
2152 | ((kmods & KMOD_PRIMARY) && (kmods & KMOD_SHIFT)) ? 1 | 2151 | openTabMode_Sym(SDL_GetModState()), |
2153 | : (kmods & KMOD_PRIMARY) ? 2 | ||
2154 | : 0, | ||
2155 | cstr_String(absoluteUrl_String( | 2152 | cstr_String(absoluteUrl_String( |
2156 | d->mod.url, linkUrl_GmDocument(d->doc, run->linkId)))); | 2153 | d->mod.url, linkUrl_GmDocument(d->doc, run->linkId)))); |
2157 | iChangeFlags(d->flags, showLinkNumbers_DocumentWidgetFlag, iFalse); | 2154 | iChangeFlags(d->flags, showLinkNumbers_DocumentWidgetFlag, iFalse); |
2158 | invalidateVisibleLinks_DocumentWidget_(d); | 2155 | invalidateVisibleLinks_DocumentWidget_(d); |
2159 | refresh_Widget(d); | 2156 | refresh_Widget(d); |
@@ -2315,7 +2312,7 @@ static iBool processEvent_DocumentWidget_(iDocumentWidget *d, const SDL_Event *e | |||
2315 | &(iMenuItem){ "Open Link in Default Browser", | 2312 | &(iMenuItem){ "Open Link in Default Browser", |
2316 | 0, | 2313 | 0, |
2317 | 0, | 2314 | 0, |
2318 | format_CStr("!open url:%s", cstr_String(linkUrl)) }); | 2315 | format_CStr("!open default:1 url:%s", cstr_String(linkUrl)) }); |
2319 | } | 2316 | } |
2320 | if (willUseProxy_App(scheme)) { | 2317 | if (willUseProxy_App(scheme)) { |
2321 | pushBackN_Array( | 2318 | pushBackN_Array( |
@@ -2437,10 +2434,10 @@ static iBool processEvent_DocumentWidget_(iDocumentWidget *d, const SDL_Event *e | |||
2437 | setFocus_Widget(NULL); | 2434 | setFocus_Widget(NULL); |
2438 | if (d->hoverLink) { | 2435 | if (d->hoverLink) { |
2439 | const iGmLinkId linkId = d->hoverLink->linkId; | 2436 | const iGmLinkId linkId = d->hoverLink->linkId; |
2437 | const int linkFlags = linkFlags_GmDocument(d->doc, linkId); | ||
2440 | iAssert(linkId); | 2438 | iAssert(linkId); |
2441 | /* Media links are opened inline by default. */ | 2439 | /* Media links are opened inline by default. */ |
2442 | if (isMediaLink_GmDocument(d->doc, linkId)) { | 2440 | if (isMediaLink_GmDocument(d->doc, linkId)) { |
2443 | const int linkFlags = linkFlags_GmDocument(d->doc, linkId); | ||
2444 | if (linkFlags & content_GmLinkFlag && linkFlags & permanent_GmLinkFlag) { | 2441 | if (linkFlags & content_GmLinkFlag && linkFlags & permanent_GmLinkFlag) { |
2445 | /* We have the content and it cannot be dismissed, so nothing | 2442 | /* We have the content and it cannot be dismissed, so nothing |
2446 | further to do. */ | 2443 | further to do. */ |
@@ -2490,15 +2487,26 @@ static iBool processEvent_DocumentWidget_(iDocumentWidget *d, const SDL_Event *e | |||
2490 | } | 2487 | } |
2491 | refresh_Widget(w); | 2488 | refresh_Widget(w); |
2492 | } | 2489 | } |
2493 | else { | 2490 | else if (linkFlags & supportedProtocol_GmLinkFlag) { |
2494 | const int kmods = keyMods_Sym(SDL_GetModState()); | ||
2495 | postCommandf_App("open newtab:%d url:%s", | 2491 | postCommandf_App("open newtab:%d url:%s", |
2496 | ((kmods & KMOD_PRIMARY) && (kmods & KMOD_SHIFT)) ? 1 | 2492 | openTabMode_Sym(SDL_GetModState()), |
2497 | : (kmods & KMOD_PRIMARY) ? 2 | ||
2498 | : 0, | ||
2499 | cstr_String(absoluteUrl_String( | 2493 | cstr_String(absoluteUrl_String( |
2500 | d->mod.url, linkUrl_GmDocument(d->doc, linkId)))); | 2494 | d->mod.url, linkUrl_GmDocument(d->doc, linkId)))); |
2501 | } | 2495 | } |
2496 | else { | ||
2497 | const iString *url = absoluteUrl_String( | ||
2498 | d->mod.url, linkUrl_GmDocument(d->doc, linkId)); | ||
2499 | makeQuestion_Widget( | ||
2500 | uiTextCaution_ColorEscape "OPEN LINK", | ||
2501 | format_CStr( | ||
2502 | "Open this link in the default browser?\n" uiTextAction_ColorEscape | ||
2503 | "%s", | ||
2504 | cstr_String(url)), | ||
2505 | (const char *[]){ "Cancel", uiTextCaution_ColorEscape "Open Link" }, | ||
2506 | (const char *[]){ | ||
2507 | "cancel", format_CStr("!open default:1 url:%s", cstr_String(url)) }, | ||
2508 | 2); | ||
2509 | } | ||
2502 | } | 2510 | } |
2503 | if (d->selectMark.start) { | 2511 | if (d->selectMark.start) { |
2504 | d->selectMark = iNullRange; | 2512 | d->selectMark = iNullRange; |
diff --git a/src/ui/util.c b/src/ui/util.c index b6378055..855f0fb3 100644 --- a/src/ui/util.c +++ b/src/ui/util.c | |||
@@ -135,6 +135,11 @@ int keyMods_Sym(int kmods) { | |||
135 | return kmods; | 135 | return kmods; |
136 | } | 136 | } |
137 | 137 | ||
138 | int openTabMode_Sym(int kmods) { | ||
139 | const int km = keyMods_Sym(kmods); | ||
140 | return ((km & KMOD_PRIMARY) && (km & KMOD_SHIFT)) ? 1 : (km & KMOD_PRIMARY) ? 2 : 0; | ||
141 | } | ||
142 | |||
138 | iRangei intersect_Rangei(iRangei a, iRangei b) { | 143 | iRangei intersect_Rangei(iRangei a, iRangei b) { |
139 | if (a.end < b.start || a.start > b.end) { | 144 | if (a.end < b.start || a.start > b.end) { |
140 | return (iRangei){ 0, 0 }; | 145 | return (iRangei){ 0, 0 }; |
diff --git a/src/ui/util.h b/src/ui/util.h index c9f464ad..a280fedb 100644 --- a/src/ui/util.h +++ b/src/ui/util.h | |||
@@ -52,6 +52,7 @@ iBool isMod_Sym (int key); | |||
52 | int normalizedMod_Sym (int key); | 52 | int normalizedMod_Sym (int key); |
53 | int keyMods_Sym (int kmods); /* shift, alt, control, or gui */ | 53 | int keyMods_Sym (int kmods); /* shift, alt, control, or gui */ |
54 | void toString_Sym (int key, int kmods, iString *str); | 54 | void toString_Sym (int key, int kmods, iString *str); |
55 | int openTabMode_Sym (int kmods); | ||
55 | 56 | ||
56 | iRangei intersect_Rangei (iRangei a, iRangei b); | 57 | iRangei intersect_Rangei (iRangei a, iRangei b); |
57 | iRangei union_Rangei (iRangei a, iRangei b); | 58 | iRangei union_Rangei (iRangei a, iRangei b); |