=> e8f06bd0985ce2c9ac5ef02525672a426d559d18
[1mdiff --git a/po/en.po b/po/en.po[m [1mindex 61d7d3f7..49f78eb8 100644[m [1m--- a/po/en.po[m [1m+++ b/po/en.po[m [36m@@ -854,6 +854,10 @@[m [mmsgstr "Bookmark Link…"[m msgid "link.download"[m msgstr "Download Linked File"[m [m [32m+[m[32m# Shows where a local file is using the Finder.[m [32m+[m[32mmsgid "menu.reveal.macos"[m [32m+[m[32mmsgstr "Show in Finder"[m [32m+[m msgid "link.file.delete"[m msgstr "Delete File"[m [m [1mdiff --git a/res/lang/cs.bin b/res/lang/cs.bin[m [1mindex ec75dc3a..1c30a0a9 100644[m Binary files a/res/lang/cs.bin and b/res/lang/cs.bin differ [1mdiff --git a/res/lang/de.bin b/res/lang/de.bin[m [1mindex 96fd003f..bf05a72e 100644[m Binary files a/res/lang/de.bin and b/res/lang/de.bin differ [1mdiff --git a/res/lang/en.bin b/res/lang/en.bin[m [1mindex 26e3c36a..bd858ade 100644[m Binary files a/res/lang/en.bin and b/res/lang/en.bin differ [1mdiff --git a/res/lang/eo.bin b/res/lang/eo.bin[m [1mindex 2df0e6b8..cc829562 100644[m Binary files a/res/lang/eo.bin and b/res/lang/eo.bin differ [1mdiff --git a/res/lang/es.bin b/res/lang/es.bin[m [1mindex be919a78..f62291f1 100644[m Binary files a/res/lang/es.bin and b/res/lang/es.bin differ [1mdiff --git a/res/lang/es_MX.bin b/res/lang/es_MX.bin[m [1mindex d88b3386..f6f88d6c 100644[m Binary files a/res/lang/es_MX.bin and b/res/lang/es_MX.bin differ [1mdiff --git a/res/lang/fi.bin b/res/lang/fi.bin[m [1mindex 5dba618c..e69245be 100644[m Binary files a/res/lang/fi.bin and b/res/lang/fi.bin differ [1mdiff --git a/res/lang/fr.bin b/res/lang/fr.bin[m [1mindex 830bbc72..7be665e5 100644[m Binary files a/res/lang/fr.bin and b/res/lang/fr.bin differ [1mdiff --git a/res/lang/gl.bin b/res/lang/gl.bin[m [1mindex 4df0c57c..8c1fdf24 100644[m Binary files a/res/lang/gl.bin and b/res/lang/gl.bin differ [1mdiff --git a/res/lang/hu.bin b/res/lang/hu.bin[m [1mindex f4c826c8..b06c8676 100644[m Binary files a/res/lang/hu.bin and b/res/lang/hu.bin differ [1mdiff --git a/res/lang/ia.bin b/res/lang/ia.bin[m [1mindex 6a18bd7d..4c3b403d 100644[m Binary files a/res/lang/ia.bin and b/res/lang/ia.bin differ [1mdiff --git a/res/lang/ie.bin b/res/lang/ie.bin[m [1mindex 84cc2cd7..5e431c29 100644[m Binary files a/res/lang/ie.bin and b/res/lang/ie.bin differ [1mdiff --git a/res/lang/isv.bin b/res/lang/isv.bin[m [1mindex 1a31a1f7..54cc6774 100644[m Binary files a/res/lang/isv.bin and b/res/lang/isv.bin differ [1mdiff --git a/res/lang/pl.bin b/res/lang/pl.bin[m [1mindex a003ce03..cf6a6b23 100644[m Binary files a/res/lang/pl.bin and b/res/lang/pl.bin differ [1mdiff --git a/res/lang/ru.bin b/res/lang/ru.bin[m [1mindex 807e032d..87c82a7d 100644[m Binary files a/res/lang/ru.bin and b/res/lang/ru.bin differ [1mdiff --git a/res/lang/sk.bin b/res/lang/sk.bin[m [1mindex 33c83c09..3ac6e18c 100644[m Binary files a/res/lang/sk.bin and b/res/lang/sk.bin differ [1mdiff --git a/res/lang/sr.bin b/res/lang/sr.bin[m [1mindex 7c4c8de1..5c66460d 100644[m Binary files a/res/lang/sr.bin and b/res/lang/sr.bin differ [1mdiff --git a/res/lang/tok.bin b/res/lang/tok.bin[m [1mindex 601b07f3..19b6d9df 100644[m Binary files a/res/lang/tok.bin and b/res/lang/tok.bin differ [1mdiff --git a/res/lang/tr.bin b/res/lang/tr.bin[m [1mindex 8cbaa556..9a8babc9 100644[m Binary files a/res/lang/tr.bin and b/res/lang/tr.bin differ [1mdiff --git a/res/lang/uk.bin b/res/lang/uk.bin[m [1mindex 48adc59b..ebcb11be 100644[m Binary files a/res/lang/uk.bin and b/res/lang/uk.bin differ [1mdiff --git a/res/lang/zh_Hans.bin b/res/lang/zh_Hans.bin[m [1mindex 759e618a..ab4b338a 100644[m Binary files a/res/lang/zh_Hans.bin and b/res/lang/zh_Hans.bin differ [1mdiff --git a/res/lang/zh_Hant.bin b/res/lang/zh_Hant.bin[m [1mindex 2bfc817b..f166156f 100644[m Binary files a/res/lang/zh_Hant.bin and b/res/lang/zh_Hant.bin differ [1mdiff --git a/src/app.c b/src/app.c[m [1mindex b0b36783..e5f9a41c 100644[m [1m--- a/src/app.c[m [1m+++ b/src/app.c[m [36m@@ -55,6 +55,7 @@[m [mSOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */[m #include[m #include [m #include [m [32m+[m[32m#include [m #include [m #include [m #include [m [36m@@ -119,6 +120,7 @@[m [mstatic const int idleThreshold_App_ = 1000; /* ms */[m struct Impl_App {[m iCommandLine args;[m iString * execPath;[m [32m+[m[32m iStringSet * tempFilesPendingDeletion;[m iMimeHooks * mimehooks;[m iGmCerts * certs;[m iVisited * visited;[m [36m@@ -735,6 +737,7 @@[m [mstatic void init_App_(iApp *d, int argc, char **argv) {[m #endif[m d->isDarkSystemTheme = iTrue; /* will be updated by system later on, if supported */[m d->isSuspended = iFalse;[m [32m+[m[32m d->tempFilesPendingDeletion = new_StringSet();[m init_CommandLine(&d->args, argc, argv);[m /* Where was the app started from? We ask SDL first because the command line alone [m cannot be relied on (behavior differs depending on OS). */ {[m [36m@@ -1005,8 +1008,13 @@[m [mstatic void deinit_App(iApp *d) {[m #endif[m deinit_SortedArray(&d->tickers);[m deinit_Periodic(&d->periodic);[m [31m- deinit_Lang();[m [32m+[m[32m deinit_Lang();[m[41m [m iRecycle();[m [32m+[m[32m /* Delete all temporary files created while running. */[m [32m+[m[32m iConstForEach(StringSet, tmp, d->tempFilesPendingDeletion) {[m [32m+[m[32m remove(cstr_String(tmp.value));[m [32m+[m[32m }[m [32m+[m[32m iRelease(d->tempFilesPendingDeletion);[m }[m [m const iString *execPath_App(void) {[m [36m@@ -1082,6 +1090,17 @@[m [mconst iString *downloadPathForUrl_App(const iString *url, const iString *mime) {[m return collect_String(savePath);[m }[m [m [32m+[m[32mconst iString *temporaryPathForUrl_App(const iString *url, const iString *mime) {[m [32m+[m[32m iApp *d = &app_;[m [32m+[m[32m iString *tmpPath = collectNewCStr_String(tmpnam(NULL));[m [32m+[m[32m const iRangecc tmpDir = dirName_Path(tmpPath);[m [32m+[m[32m set_String([m [32m+[m[32m tmpPath,[m [32m+[m[32m collect_String(concat_Path(collectNewRange_String(tmpDir), fileNameForUrl_App(url, mime))));[m [32m+[m[32m insert_StringSet(d->tempFilesPendingDeletion, tmpPath); /* deleted in `deinit_App` */[m [32m+[m[32m return tmpPath;[m [32m+[m[32m}[m [32m+[m const iString *debugInfo_App(void) {[m extern char **environ; /* The environment variables. */[m iApp *d = &app_;[m [36m@@ -2687,7 +2706,9 @@[m [miBool handleCommand_App(const char *cmd) {[m }[m #endif[m else if (equal_Command(cmd, "downloads.open")) {[m [31m- postCommandf_App("open url:%s", cstrCollect_String(makeFileUrl_String(downloadDir_App())));[m [32m+[m[32m postCommandf_App("open newtab:%d url:%s",[m [32m+[m[32m argLabel_Command(cmd, "newtab"),[m [32m+[m[32m cstrCollect_String(makeFileUrl_String(downloadDir_App())));[m return iTrue;[m }[m else if (equal_Command(cmd, "ca.file")) {[m [36m@@ -2718,6 +2739,19 @@[m [miBool handleCommand_App(const char *cmd) {[m }[m return iTrue;[m }[m [32m+[m[32m else if (equal_Command(cmd, "reveal")) {[m [32m+[m[32m const iString *path = NULL;[m [32m+[m[32m if (hasLabel_Command(cmd, "path")) {[m [32m+[m[32m path = suffix_Command(cmd, "path");[m [32m+[m[32m }[m [32m+[m[32m else if (hasLabel_Command(cmd, "url")) {[m [32m+[m[32m path = collect_String(localFilePathFromUrl_String(suffix_Command(cmd, "url")));[m [32m+[m[32m }[m [32m+[m[32m if (path) {[m [32m+[m[32m revealPath_App(path);[m [32m+[m[32m }[m [32m+[m[32m return iTrue;[m [32m+[m[32m }[m else if (equal_Command(cmd, "open")) {[m const char *urlArg = suffixPtr_Command(cmd, "url");[m if (!urlArg) {[m [36m@@ -2726,9 +2760,8 @@[m [miBool handleCommand_App(const char *cmd) {[m if (findWidget_App("prefs")) {[m postCommand_App("prefs.dismiss"); [m }[m [31m- iString *url = collectNewCStr_String(urlArg);[m [31m- const iBool noProxy = argLabel_Command(cmd, "noproxy") != 0;[m [31m- const iBool fromSidebar = argLabel_Command(cmd, "fromsidebar") != 0;[m [32m+[m[32m iString *url = collectNewCStr_String(urlArg);[m [32m+[m[32m const iBool noProxy = argLabel_Command(cmd, "noproxy") != 0;[m iUrl parts;[m init_Url(&parts, url);[m if (equal_Rangecc(parts.scheme, "about") && equal_Rangecc(parts.path, "command") &&[m [36m@@ -3354,26 +3387,11 @@[m [mvoid openInDefaultBrowser_App(const iString *url) {[m [m void revealPath_App(const iString *path) {[m #if defined (iPlatformAppleDesktop)[m [31m- const char *scriptPath = concatPath_CStr(dataDir_App_(), "revealfile.scpt");[m [31m- iFile *f = newCStr_File(scriptPath);[m [31m- if (open_File(f, writeOnly_FileMode | text_FileMode)) {[m [31m- /* AppleScript to select a specific file. */[m [31m- write_File(f, collect_Block(newCStr_Block("on run argv\n"[m [31m- " tell application \"Finder\"\n"[m [31m- " activate\n"[m [31m- " reveal POSIX file (item 1 of argv) as text\n"[m [31m- " end tell\n"[m [31m- "end run\n")));[m [31m- close_File(f);[m [31m- iProcess *proc = new_Process();[m [31m- setArguments_Process([m [31m- proc,[m [31m- iClob(newStringsCStr_StringList([m [31m- "/usr/bin/osascript", scriptPath, cstr_String(path), NULL)));[m [31m- start_Process(proc);[m [31m- iRelease(proc);[m [31m- }[m [31m- iRelease(f);[m [32m+[m[32m iProcess *proc = new_Process();[m [32m+[m[32m setArguments_Process([m [32m+[m[32m proc, iClob(newStringsCStr_StringList("/usr/bin/open", "-R", cstr_String(path), NULL)));[m [32m+[m[32m start_Process(proc);[m [32m+[m[32m iRelease(proc);[m #elif defined (iPlatformLinux) || defined (iPlatformHaiku)[m iFileInfo *inf = iClob(new_FileInfo(path));[m iRangecc target;[m [1mdiff --git a/src/app.h b/src/app.h[m [1mindex 0c336e65..d15e1f21 100644[m [1m--- a/src/app.h[m [1m+++ b/src/app.h[m [36m@@ -111,6 +111,7 @@[m [mconst iString * schemeProxy_App (iRangecc scheme);[m iBool willUseProxy_App (const iRangecc scheme);[m const iString * searchQueryUrl_App (const iString *queryStringUnescaped);[m const iString * fileNameForUrl_App (const iString *url, const iString *mime);[m [32m+[m[32mconst iString * temporaryPathForUrl_App(const iString *url, const iString *mime); /* deleted before quitting */[m const iString * downloadPathForUrl_App(const iString *url, const iString *mime);[m [m typedef void (*iTickerFunc)(iAny *);[m [1mdiff --git a/src/gmcerts.c b/src/gmcerts.c[m [1mindex 8f7bf181..7b05103b 100644[m [1m--- a/src/gmcerts.c[m [1m+++ b/src/gmcerts.c[m [36m@@ -654,7 +654,7 @@[m [mvoid importIdentity_GmCerts(iGmCerts *d, iTlsCertificate *cert, const iString *n[m }[m [m static const char *certPath_GmCerts_(const iGmCerts *d, const iGmIdentity *identity) {[m [31m- if (!(identity->flags & (temporary_GmIdentityFlag | imported_GmIdentityFlag))) {[m [32m+[m[32m if (!(identity->flags & temporary_GmIdentityFlag)) {[m const char *finger = cstrCollect_String(hexEncode_Block(&identity->fingerprint));[m return concatPath_CStr(cstr_String(&d->saveDir), format_CStr("idents/%s", finger));[m }[m [1mdiff --git a/src/ui/certlistwidget.c b/src/ui/certlistwidget.c[m [1mindex 31d8bac6..5a1c481b 100644[m [1m--- a/src/ui/certlistwidget.c[m [1m+++ b/src/ui/certlistwidget.c[m [36m@@ -97,17 +97,21 @@[m [mstatic void updateContextMenu_CertListWidget_(iCertListWidget *d) {[m pushBack_Array(items, &(iMenuItem){ format_CStr("```%s", cstr_String(docUrl)) });[m firstIndex = 1;[m }[m [31m- pushBackN_Array(items, (iMenuItem[]){[m [32m+[m[32m const iMenuItem ctxItems[] = {[m { person_Icon " ${ident.use}", 0, 0, "ident.use arg:1" },[m { close_Icon " ${ident.stopuse}", 0, 0, "ident.use arg:0" },[m { close_Icon " ${ident.stopuse.all}", 0, 0, "ident.use arg:0 clear:1" },[m { "---", 0, 0, NULL },[m { edit_Icon " ${menu.edit.notes}", 0, 0, "ident.edit" },[m { "${ident.fingerprint}", 0, 0, "ident.fingerprint" },[m [32m+[m[32m#if defined (iPlatformAppleDesktop)[m [32m+[m[32m { magnifyingGlass_Icon " ${menu.reveal.macos}", 0, 0, "ident.reveal" },[m [32m+[m[32m#endif[m { export_Icon " ${ident.export}", 0, 0, "ident.export" },[m { "---", 0, 0, NULL },[m { delete_Icon " " uiTextCaution_ColorEscape "${ident.delete}", 0, 0, "ident.delete confirm:1" },[m [31m- }, 9);[m [32m+[m[32m };[m [32m+[m[32m pushBackN_Array(items, ctxItems, iElemCount(ctxItems));[m /* Used URLs. */[m const iGmIdentity *ident = menuIdentity_CertListWidget_(d);[m if (ident) {[m [36m@@ -244,7 +248,7 @@[m [mstatic iBool processEvent_CertListWidget_(iCertListWidget *d, const SDL_Event *e[m if (ident) {[m const iString *crtPath = certificatePath_GmCerts(certs_App(), ident);[m if (crtPath) {[m [31m- revealPath_App(crtPath);[m [32m+[m[32m postCommandf_App("reveal path:%s", cstr_String(crtPath));[m }[m }[m return iTrue;[m [1mdiff --git a/src/ui/documentwidget.c b/src/ui/documentwidget.c[m [1mindex 3771dd6c..9e5e6ea3 100644[m [1m--- a/src/ui/documentwidget.c[m [1m+++ b/src/ui/documentwidget.c[m [36m@@ -4125,16 +4125,16 @@[m [mstatic iBool handleCommand_DocumentWidget_(iDocumentWidget *d, const char *cmd)[m }[m else if (!isEmpty_Block(&d->sourceContent)) {[m if (argLabel_Command(cmd, "extview")) {[m [31m- iString *tmpPath = collectNewCStr_String(tmpnam(NULL));[m [31m- const iRangecc tmpDir = dirName_Path(tmpPath);[m [31m- set_String([m [31m- tmpPath,[m [31m- collect_String(concat_Path(collectNewRange_String(tmpDir),[m [31m- fileNameForUrl_App(d->mod.url, &d->sourceMime))));[m [31m- if (saveToFile_(tmpPath, &d->sourceContent, iFalse)) {[m [31m- /* TODO: Remember this temporary path and delete it when quitting the app. */[m [31m- postCommandf_Root(w->root, "!open default:1 url:%s",[m [31m- cstrCollect_String(makeFileUrl_String(tmpPath)));[m [32m+[m[32m if (equalCase_Rangecc(urlScheme_String(d->mod.url), "file")) {[m [32m+[m[32m /* Already a file so just open it directly. */[m [32m+[m[32m postCommandf_Root(w->root, "!open default:1 url:%s", cstr_String(d->mod.url));[m [32m+[m[32m }[m [32m+[m[32m else {[m [32m+[m[32m const iString *tmpPath = temporaryPathForUrl_App(d->mod.url, &d->sourceMime);[m [32m+[m[32m if (saveToFile_(tmpPath, &d->sourceContent, iFalse)) {[m [32m+[m[32m postCommandf_Root(w->root, "!open default:1 url:%s",[m [32m+[m[32m cstrCollect_String(makeFileUrl_String(tmpPath)));[m [32m+[m[32m }[m }[m }[m else {[m [36m@@ -4484,11 +4484,6 @@[m [mstatic iBool processMediaEvents_DocumentWidget_(iDocumentWidget *d, const SDL_Ev[m ev->type != SDL_MOUSEMOTION) {[m return iFalse;[m }[m [31m- if (ev->type == SDL_MOUSEBUTTONDOWN || ev->type == SDL_MOUSEBUTTONUP) {[m [31m- if (ev->button.button != SDL_BUTTON_LEFT) {[m [31m- return iFalse;[m [31m- }[m [31m- }[m if (d->grabbedPlayer) {[m /* Updated in the drag. */[m return iFalse;[m [36m@@ -4496,9 +4491,23 @@[m [mstatic iBool processMediaEvents_DocumentWidget_(iDocumentWidget *d, const SDL_Ev[m const iInt2 mouse = init_I2(ev->button.x, ev->button.y);[m iConstForEach(PtrArray, i, &d->view.visibleMedia) {[m const iGmRun *run = i.ptr;[m [32m+[m[32m if (run->mediaType == download_MediaType) {[m [32m+[m[32m iDownloadUI ui;[m [32m+[m[32m init_DownloadUI(&ui, media_GmDocument(d->view.doc), mediaId_GmRun(run).id,[m [32m+[m[32m runRect_DocumentView_(&d->view, run));[m [32m+[m[32m if (processEvent_DownloadUI(&ui, ev)) {[m [32m+[m[32m return iTrue;[m [32m+[m[32m }[m [32m+[m[32m continue;[m [32m+[m[32m }[m if (run->mediaType != audio_MediaType) {[m continue;[m }[m [32m+[m[32m if (ev->type == SDL_MOUSEBUTTONDOWN || ev->type == SDL_MOUSEBUTTONUP) {[m [32m+[m[32m if (ev->button.button != SDL_BUTTON_LEFT) {[m [32m+[m[32m return iFalse;[m [32m+[m[32m }[m [32m+[m[32m }[m /* TODO: move this to mediaui.c */[m const iRect rect = runRect_DocumentView_(&d->view, run);[m iPlayer * plr = audioPlayer_Media(media_GmDocument(d->view.doc), mediaId_GmRun(run));[m [36m@@ -4842,6 +4851,9 @@[m [mstatic iBool processEvent_DocumentWidget_(iDocumentWidget *d, const SDL_Event *e[m iChangeFlags(d->flags, noHoverWhileScrolling_DocumentWidgetFlag, iFalse);[m return iTrue;[m }[m [32m+[m[32m if (processMediaEvents_DocumentWidget_(d, ev)) {[m [32m+[m[32m return iTrue;[m [32m+[m[32m }[m if (ev->type == SDL_MOUSEBUTTONDOWN) {[m if (ev->button.button == SDL_BUTTON_X1) {[m postCommand_Root(w->root, "navigate.back");[m [36m@@ -4923,6 +4935,23 @@[m [mstatic iBool processEvent_DocumentWidget_(iDocumentWidget *d, const SDL_Event *e[m if (deviceType_App() == phone_AppDeviceType) {[m removeN_Array(&items, size_Array(&items) - 2, iInvalidSize);[m }[m [32m+[m[32m if (equalCase_Rangecc(scheme, "file")) {[m [32m+[m[32m pushBack_Array(&items, &(iMenuItem){ "---" });[m [32m+[m[32m pushBack_Array(&items,[m [32m+[m[32m &(iMenuItem){ export_Icon " ${menu.open.external}",[m [32m+[m[32m 0,[m [32m+[m[32m 0,[m [32m+[m[32m format_CStr("!open default:1 url:%s",[m [32m+[m[32m cstr_String(linkUrl)) });[m [32m+[m[32m#if defined (iPlatformAppleDesktop)[m [32m+[m[32m pushBack_Array(&items,[m [32m+[m[32m &(iMenuItem){ "${menu.reveal.macos}",[m [32m+[m[32m 0,[m [32m+[m[32m 0,[m [32m+[m[32m format_CStr("!reveal url:%s",[m [32m+[m[32m cstr_String(linkUrl)) });[m [32m+[m[32m#endif[m [32m+[m[32m }[m[41m [m }[m else if (!willUseProxy_App(scheme)) {[m pushBack_Array([m [36m@@ -4959,7 +4988,8 @@[m [mstatic iBool processEvent_DocumentWidget_(iDocumentWidget *d, const SDL_Event *e[m cstr_String(linkUrl)) },[m },[m 3);[m [31m- if (isNative && d->contextLink->mediaType != download_MediaType) {[m [32m+[m[32m if (isNative && d->contextLink->mediaType != download_MediaType &&[m [32m+[m[32m !equalCase_Rangecc(scheme, "file")) {[m pushBackN_Array(&items, (iMenuItem[]){[m { "---" },[m { download_Icon " ${link.download}", 0, 0, "document.downloadlink" },[m [36m@@ -4979,6 +5009,7 @@[m [mstatic iBool processEvent_DocumentWidget_(iDocumentWidget *d, const SDL_Event *e[m }[m if (equalCase_Rangecc(scheme, "file")) {[m /* Local files may be deleted. */[m [32m+[m[32m pushBack_Array(&items, &(iMenuItem){ "---" });[m pushBack_Array([m &items,[m &(iMenuItem){ delete_Icon " " uiTextCaution_ColorEscape[m [36m@@ -5052,9 +5083,6 @@[m [mstatic iBool processEvent_DocumentWidget_(iDocumentWidget *d, const SDL_Event *e[m processContextMenuEvent_Widget(d->menu, ev, {});[m }[m }[m [31m- if (processMediaEvents_DocumentWidget_(d, ev)) {[m [31m- return iTrue;[m [31m- }[m if (processEvent_Banner(d->banner, ev)) {[m return iTrue;[m }[m [1mdiff --git a/src/ui/linkinfo.c b/src/ui/linkinfo.c[m [1mindex cb48c7ea..5102f9b3 100644[m [1m--- a/src/ui/linkinfo.c[m [1m+++ b/src/ui/linkinfo.c[m [36m@@ -92,7 +92,7 @@[m [mvoid infoText_LinkInfo(const iGmDocument *doc, iGmLinkId linkId, iString *text_o[m appendRange_String(text_out, (iRangecc){ parts.path.start, constEnd_String(url) });[m }[m else if (scheme != gemini_GmLinkScheme) {[m [31m- appendCStr_String(text_out, globe_Icon " ");[m [32m+[m[32m appendCStr_String(text_out, scheme == file_GmLinkScheme ? "" : globe_Icon " ");[m append_String(text_out, url);[m }[m else {[m [1mdiff --git a/src/ui/mediaui.c b/src/ui/mediaui.c[m [1mindex 1c828194..2aec568f 100644[m [1m--- a/src/ui/mediaui.c[m [1m+++ b/src/ui/mediaui.c[m [36m@@ -238,6 +238,44 @@[m [mvoid init_DownloadUI(iDownloadUI *d, const iMedia *media, uint16_t mediaId, iRec[m /*----------------------------------------------------------------------------------------------*/[m [m iBool processEvent_DownloadUI(iDownloadUI *d, const SDL_Event *ev) {[m [32m+[m[32m if (ev->type == SDL_MOUSEBUTTONDOWN || ev->type == SDL_MOUSEBUTTONUP) {[m [32m+[m[32m const iInt2 mouse = init_I2(ev->button.x, ev->button.y);[m [32m+[m[32m if (!contains_Rect(d->bounds, mouse)) {[m [32m+[m[32m return iFalse;[m [32m+[m[32m }[m [32m+[m[32m float bytesPerSecond;[m [32m+[m[32m const iString *path;[m [32m+[m[32m iBool isFinished;[m [32m+[m[32m downloadStats_Media(d->media, (iMediaId){ download_MediaType, d->mediaId },[m [32m+[m[32m &path, &bytesPerSecond, &isFinished);[m [32m+[m[32m if (isFinished) {[m [32m+[m[32m if (ev->button.button == SDL_BUTTON_RIGHT && ev->type == SDL_MOUSEBUTTONDOWN) {[m [32m+[m[32m const iMenuItem items[] = {[m [32m+[m[32m /* Items related to the file */[m [32m+[m[32m { openTab_Icon " ${menu.opentab}",[m [32m+[m[32m 0,[m [32m+[m[32m 0,[m [32m+[m[32m format_CStr("!open newtab:1 url:%s",[m [32m+[m[32m cstrCollect_String(makeFileUrl_String(path))) },[m [32m+[m[32m#if defined (iPlatformAppleDesktop)[m [32m+[m[32m { "${menu.reveal.macos}",[m [32m+[m[32m 0,[m [32m+[m[32m 0,[m [32m+[m[32m format_CStr("!reveal path:%s", cstr_String(path)) },[m [32m+[m[32m#endif[m [32m+[m[32m { "---" },[m [32m+[m[32m /* Generic items */[m [32m+[m[32m { "${menu.downloads}", 0, 0, "downloads.open newtab:1" },[m [32m+[m[32m };[m [32m+[m[32m openMenu_Widget(makeMenu_Widget(get_Root()->widget, items, iElemCount(items)),[m [32m+[m[32m mouse);[m [32m+[m[32m return iTrue;[m [32m+[m[32m }[m [32m+[m[32m else if (ev->button.button == SDL_BUTTON_LEFT && ev->type == SDL_MOUSEBUTTONUP) {[m [32m+[m[32m postCommandf_App("open default:1 url:%s", cstrCollect_String(makeFileUrl_String(path)));[m [32m+[m[32m }[m [32m+[m[32m }[m [32m+[m[32m }[m return iFalse;[m }[m [m
text/gemini; charset=utf-8
This content has been proxied by September (3851b).