diff options
author | Jaakko Keränen <jaakko.keranen@iki.fi> | 2021-01-27 21:28:25 +0200 |
---|---|---|
committer | Jaakko Keränen <jaakko.keranen@iki.fi> | 2021-01-27 21:28:25 +0200 |
commit | eda45fcd34189e6844babde1ebc60c083b1b09da (patch) | |
tree | 40a5aa0671a59a4180913cee518735a3c72f3f5c /src | |
parent | 688fe6c5882e7493f0e2750f0ff8f20d3613e270 (diff) |
Added preference for maximum cache size
Rather than simply limiting each tab's cache to 50 most recent URLs, there is now a user-configurable maximum size. If more content is cached, the oldest/largest responses will be removed from memory.
The default maximum cache size is 10 MB.
IssueID #109
Diffstat (limited to 'src')
-rw-r--r-- | src/app.c | 42 | ||||
-rw-r--r-- | src/app.h | 18 | ||||
-rw-r--r-- | src/history.c | 43 | ||||
-rw-r--r-- | src/history.h | 2 | ||||
-rw-r--r-- | src/prefs.c | 1 | ||||
-rw-r--r-- | src/prefs.h | 1 | ||||
-rw-r--r-- | src/ui/util.c | 19 | ||||
-rw-r--r-- | src/ui/window.c | 1 |
8 files changed, 113 insertions, 14 deletions
@@ -194,6 +194,7 @@ static iString *serializePrefs_App_(const iApp *d) { | |||
194 | appendFormat_String(str, "zoom.set arg:%d\n", d->prefs.zoomPercent); | 194 | appendFormat_String(str, "zoom.set arg:%d\n", d->prefs.zoomPercent); |
195 | appendFormat_String(str, "smoothscroll arg:%d\n", d->prefs.smoothScrolling); | 195 | appendFormat_String(str, "smoothscroll arg:%d\n", d->prefs.smoothScrolling); |
196 | appendFormat_String(str, "imageloadscroll arg:%d\n", d->prefs.loadImageInsteadOfScrolling); | 196 | appendFormat_String(str, "imageloadscroll arg:%d\n", d->prefs.loadImageInsteadOfScrolling); |
197 | appendFormat_String(str, "cachesize.set arg:%d\n", d->prefs.maxCacheSize); | ||
197 | appendFormat_String(str, "decodeurls arg:%d\n", d->prefs.decodeUserVisibleURLs); | 198 | appendFormat_String(str, "decodeurls arg:%d\n", d->prefs.decodeUserVisibleURLs); |
198 | appendFormat_String(str, "linewidth.set arg:%d\n", d->prefs.lineWidth); | 199 | appendFormat_String(str, "linewidth.set arg:%d\n", d->prefs.lineWidth); |
199 | appendFormat_String(str, "prefs.biglede.changed arg:%d\n", d->prefs.bigFirstParagraph); | 200 | appendFormat_String(str, "prefs.biglede.changed arg:%d\n", d->prefs.bigFirstParagraph); |
@@ -321,6 +322,7 @@ iObjectList *listDocuments_App(void) { | |||
321 | 322 | ||
322 | static void saveState_App_(const iApp *d) { | 323 | static void saveState_App_(const iApp *d) { |
323 | iUnused(d); | 324 | iUnused(d); |
325 | trimCache_App(); | ||
324 | iFile *f = newCStr_File(concatPath_CStr(dataDir_App_, stateFileName_App_)); | 326 | iFile *f = newCStr_File(concatPath_CStr(dataDir_App_, stateFileName_App_)); |
325 | if (open_File(f, writeOnly_FileMode)) { | 327 | if (open_File(f, writeOnly_FileMode)) { |
326 | writeData_File(f, magicState_App_, 4); | 328 | writeData_File(f, magicState_App_, 4); |
@@ -503,7 +505,7 @@ const iString *debugInfo_App(void) { | |||
503 | iString *msg = collectNew_String(); | 505 | iString *msg = collectNew_String(); |
504 | format_String(msg, "# Debug information\n"); | 506 | format_String(msg, "# Debug information\n"); |
505 | appendFormat_String(msg, "## Documents\n"); | 507 | appendFormat_String(msg, "## Documents\n"); |
506 | iForEach(ObjectList, k, listDocuments_App()) { | 508 | iForEach(ObjectList, k, iClob(listDocuments_App())) { |
507 | iDocumentWidget *doc = k.object; | 509 | iDocumentWidget *doc = k.object; |
508 | appendFormat_String(msg, "### Tab %zu: %s\n", | 510 | appendFormat_String(msg, "### Tab %zu: %s\n", |
509 | childIndex_Widget(constAs_Widget(doc)->parent, k.object), | 511 | childIndex_Widget(constAs_Widget(doc)->parent, k.object), |
@@ -857,6 +859,8 @@ static iBool handlePrefsCommands_(iWidget *d, const char *cmd) { | |||
857 | isSelected_Widget(findChild_Widget(d, "prefs.ostheme"))); | 859 | isSelected_Widget(findChild_Widget(d, "prefs.ostheme"))); |
858 | postCommandf_App("decodeurls arg:%d", | 860 | postCommandf_App("decodeurls arg:%d", |
859 | isSelected_Widget(findChild_Widget(d, "prefs.decodeurls"))); | 861 | isSelected_Widget(findChild_Widget(d, "prefs.decodeurls"))); |
862 | postCommandf_App("cachesize.set arg:%d", | ||
863 | toInt_String(text_InputWidget(findChild_Widget(d, "prefs.cachesize")))); | ||
860 | postCommandf_App("proxy.gemini address:%s", | 864 | postCommandf_App("proxy.gemini address:%s", |
861 | cstr_String(text_InputWidget(findChild_Widget(d, "prefs.proxy.gemini")))); | 865 | cstr_String(text_InputWidget(findChild_Widget(d, "prefs.proxy.gemini")))); |
862 | postCommandf_App("proxy.gopher address:%s", | 866 | postCommandf_App("proxy.gopher address:%s", |
@@ -940,6 +944,33 @@ iDocumentWidget *newTab_App(const iDocumentWidget *duplicateOf, iBool switchToNe | |||
940 | return doc; | 944 | return doc; |
941 | } | 945 | } |
942 | 946 | ||
947 | void trimCache_App(void) { | ||
948 | iApp *d = &app_; | ||
949 | size_t cacheSize = 0; | ||
950 | const size_t limit = d->prefs.maxCacheSize * 1000000; | ||
951 | iObjectList *docs = listDocuments_App(); | ||
952 | iForEach(ObjectList, i, docs) { | ||
953 | cacheSize += cacheSize_History(history_DocumentWidget(i.object)); | ||
954 | } | ||
955 | init_ObjectListIterator(&i, docs); | ||
956 | iBool wasPruned = iFalse; | ||
957 | while (cacheSize > limit) { | ||
958 | iDocumentWidget *doc = i.object; | ||
959 | const size_t pruned = pruneLeastImportant_History(history_DocumentWidget(doc)); | ||
960 | if (pruned) { | ||
961 | cacheSize -= pruned; | ||
962 | wasPruned = iTrue; | ||
963 | } | ||
964 | next_ObjectListIterator(&i); | ||
965 | if (!i.value) { | ||
966 | if (!wasPruned) break; | ||
967 | wasPruned = iFalse; | ||
968 | init_ObjectListIterator(&i, docs); | ||
969 | } | ||
970 | } | ||
971 | iRelease(docs); | ||
972 | } | ||
973 | |||
943 | static iBool handleIdentityCreationCommands_(iWidget *dlg, const char *cmd) { | 974 | static iBool handleIdentityCreationCommands_(iWidget *dlg, const char *cmd) { |
944 | iApp *d = &app_; | 975 | iApp *d = &app_; |
945 | if (equal_Command(cmd, "ident.temp.changed")) { | 976 | if (equal_Command(cmd, "ident.temp.changed")) { |
@@ -1154,6 +1185,13 @@ iBool handleCommand_App(const char *cmd) { | |||
1154 | postCommandf_App("theme.changed auto:1"); | 1185 | postCommandf_App("theme.changed auto:1"); |
1155 | return iTrue; | 1186 | return iTrue; |
1156 | } | 1187 | } |
1188 | else if (equal_Command(cmd, "cachesize.set")) { | ||
1189 | d->prefs.maxCacheSize = arg_Command(cmd); | ||
1190 | if (d->prefs.maxCacheSize <= 0) { | ||
1191 | d->prefs.maxCacheSize = 0; | ||
1192 | } | ||
1193 | return iTrue; | ||
1194 | } | ||
1157 | else if (equal_Command(cmd, "proxy.gemini")) { | 1195 | else if (equal_Command(cmd, "proxy.gemini")) { |
1158 | setCStr_String(&d->prefs.geminiProxy, suffixPtr_Command(cmd, "address")); | 1196 | setCStr_String(&d->prefs.geminiProxy, suffixPtr_Command(cmd, "address")); |
1159 | return iTrue; | 1197 | return iTrue; |
@@ -1331,6 +1369,8 @@ iBool handleCommand_App(const char *cmd) { | |||
1331 | dlg, format_CStr("prefs.saturation.%d", (int) (d->prefs.saturation * 3.99f))), | 1369 | dlg, format_CStr("prefs.saturation.%d", (int) (d->prefs.saturation * 3.99f))), |
1332 | selected_WidgetFlag, | 1370 | selected_WidgetFlag, |
1333 | iTrue); | 1371 | iTrue); |
1372 | setText_InputWidget(findChild_Widget(dlg, "prefs.cachesize"), | ||
1373 | collectNewFormat_String("%d", d->prefs.maxCacheSize)); | ||
1334 | setToggle_Widget(findChild_Widget(dlg, "prefs.decodeurls"), d->prefs.decodeUserVisibleURLs); | 1374 | setToggle_Widget(findChild_Widget(dlg, "prefs.decodeurls"), d->prefs.decodeUserVisibleURLs); |
1335 | setText_InputWidget(findChild_Widget(dlg, "prefs.proxy.gemini"), &d->prefs.geminiProxy); | 1375 | setText_InputWidget(findChild_Widget(dlg, "prefs.proxy.gemini"), &d->prefs.geminiProxy); |
1336 | setText_InputWidget(findChild_Widget(dlg, "prefs.proxy.gopher"), &d->prefs.gopherProxy); | 1376 | setText_InputWidget(findChild_Widget(dlg, "prefs.proxy.gopher"), &d->prefs.gopherProxy); |
@@ -61,20 +61,20 @@ void refresh_App (void); | |||
61 | iBool isRefreshPending_App (void); | 61 | iBool isRefreshPending_App (void); |
62 | uint32_t elapsedSinceLastTicker_App (void); /* milliseconds */ | 62 | uint32_t elapsedSinceLastTicker_App (void); /* milliseconds */ |
63 | 63 | ||
64 | const iPrefs * prefs_App (void); | ||
65 | iBool forceSoftwareRender_App(void); | ||
66 | enum iColorTheme colorTheme_App (void); | ||
67 | const iString * schemeProxy_App (iRangecc scheme); | ||
68 | iBool willUseProxy_App (const iRangecc scheme); | ||
69 | |||
70 | iMimeHooks * mimeHooks_App (void); | ||
71 | iGmCerts * certs_App (void); | 64 | iGmCerts * certs_App (void); |
72 | iVisited * visited_App (void); | 65 | iVisited * visited_App (void); |
73 | iBookmarks * bookmarks_App (void); | 66 | iBookmarks * bookmarks_App (void); |
67 | iMimeHooks * mimeHooks_App (void); | ||
74 | iDocumentWidget * document_App (void); | 68 | iDocumentWidget * document_App (void); |
75 | iObjectList * listDocuments_App (void); | 69 | iObjectList * listDocuments_App (void); |
76 | iDocumentWidget * document_Command (const char *cmd); | ||
77 | iDocumentWidget * newTab_App (const iDocumentWidget *duplicateOf, iBool switchToNew); | 70 | iDocumentWidget * newTab_App (const iDocumentWidget *duplicateOf, iBool switchToNew); |
71 | void trimCache_App (void); | ||
72 | |||
73 | const iPrefs * prefs_App (void); | ||
74 | iBool forceSoftwareRender_App(void); | ||
75 | enum iColorTheme colorTheme_App (void); | ||
76 | const iString * schemeProxy_App (iRangecc scheme); | ||
77 | iBool willUseProxy_App (const iRangecc scheme); | ||
78 | 78 | ||
79 | typedef void (*iTickerFunc)(iAny *); | 79 | typedef void (*iTickerFunc)(iAny *); |
80 | 80 | ||
@@ -91,5 +91,7 @@ iLocalDef void postCommandString_App(const iString *command) { | |||
91 | } | 91 | } |
92 | } | 92 | } |
93 | 93 | ||
94 | iDocumentWidget * document_Command (const char *cmd); | ||
95 | |||
94 | void openInDefaultBrowser_App (const iString *url); | 96 | void openInDefaultBrowser_App (const iString *url); |
95 | void revealPath_App (const iString *path); | 97 | void revealPath_App (const iString *path); |
diff --git a/src/history.c b/src/history.c index 202549a9..59d515dc 100644 --- a/src/history.c +++ b/src/history.c | |||
@@ -27,6 +27,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ | |||
27 | #include <the_Foundation/mutex.h> | 27 | #include <the_Foundation/mutex.h> |
28 | #include <the_Foundation/path.h> | 28 | #include <the_Foundation/path.h> |
29 | #include <the_Foundation/stringset.h> | 29 | #include <the_Foundation/stringset.h> |
30 | #include <math.h> | ||
30 | 31 | ||
31 | static const size_t maxStack_History_ = 50; /* back/forward navigable items */ | 32 | static const size_t maxStack_History_ = 50; /* back/forward navigable items */ |
32 | 33 | ||
@@ -285,6 +286,48 @@ void setCachedResponse_History(iHistory *d, const iGmResponse *response) { | |||
285 | unlock_Mutex(d->mtx); | 286 | unlock_Mutex(d->mtx); |
286 | } | 287 | } |
287 | 288 | ||
289 | size_t cacheSize_History(const iHistory *d) { | ||
290 | size_t cached = 0; | ||
291 | lock_Mutex(d->mtx); | ||
292 | iConstForEach(Array, i, &d->recent) { | ||
293 | const iRecentUrl *url = i.value; | ||
294 | if (url->cachedResponse) { | ||
295 | cached += size_Block(&url->cachedResponse->body); | ||
296 | } | ||
297 | } | ||
298 | unlock_Mutex(d->mtx); | ||
299 | return cached; | ||
300 | } | ||
301 | |||
302 | size_t pruneLeastImportant_History(iHistory *d) { | ||
303 | size_t delta = 0; | ||
304 | size_t chosen = iInvalidPos; | ||
305 | double score = 0.0f; | ||
306 | iTime now; | ||
307 | initCurrent_Time(&now); | ||
308 | lock_Mutex(d->mtx); | ||
309 | iConstForEach(Array, i, &d->recent) { | ||
310 | const iRecentUrl *url = i.value; | ||
311 | if (url->cachedResponse) { | ||
312 | const double urlScore = | ||
313 | size_Block(&url->cachedResponse->body) * | ||
314 | pow(secondsSince_Time(&now, &url->cachedResponse->when) / 60.0, 1.25); | ||
315 | if (urlScore > score) { | ||
316 | chosen = index_ArrayConstIterator(&i); | ||
317 | score = urlScore; | ||
318 | } | ||
319 | } | ||
320 | } | ||
321 | if (chosen != iInvalidPos) { | ||
322 | iRecentUrl *url = at_Array(&d->recent, chosen); | ||
323 | delta = size_Block(&url->cachedResponse->body); | ||
324 | delete_GmResponse(url->cachedResponse); | ||
325 | url->cachedResponse = NULL; | ||
326 | } | ||
327 | unlock_Mutex(d->mtx); | ||
328 | return delta; | ||
329 | } | ||
330 | |||
288 | const iStringArray *searchContents_History(const iHistory *d, const iRegExp *pattern) { | 331 | const iStringArray *searchContents_History(const iHistory *d, const iRegExp *pattern) { |
289 | iStringArray *urls = iClob(new_StringArray()); | 332 | iStringArray *urls = iClob(new_StringArray()); |
290 | lock_Mutex(d->mtx); | 333 | lock_Mutex(d->mtx); |
diff --git a/src/history.h b/src/history.h index 4c6507e3..7c2684f1 100644 --- a/src/history.h +++ b/src/history.h | |||
@@ -56,6 +56,7 @@ iBool goForward_History (iHistory *); | |||
56 | iRecentUrl *recentUrl_History (iHistory *, size_t pos); | 56 | iRecentUrl *recentUrl_History (iHistory *, size_t pos); |
57 | iRecentUrl *mostRecentUrl_History (iHistory *); | 57 | iRecentUrl *mostRecentUrl_History (iHistory *); |
58 | iRecentUrl *findUrl_History (iHistory *, const iString *url); | 58 | iRecentUrl *findUrl_History (iHistory *, const iString *url); |
59 | size_t pruneLeastImportant_History (iHistory *); | ||
59 | 60 | ||
60 | const iStringArray * searchContents_History (const iHistory *, const iRegExp *pattern); /* chronologically ascending */ | 61 | const iStringArray * searchContents_History (const iHistory *, const iRegExp *pattern); /* chronologically ascending */ |
61 | 62 | ||
@@ -67,6 +68,7 @@ const iRecentUrl * | |||
67 | constMostRecentUrl_History (const iHistory *); | 68 | constMostRecentUrl_History (const iHistory *); |
68 | const iGmResponse * | 69 | const iGmResponse * |
69 | cachedResponse_History (const iHistory *); | 70 | cachedResponse_History (const iHistory *); |
71 | size_t cacheSize_History (const iHistory *); | ||
70 | 72 | ||
71 | iString * debugInfo_History (const iHistory *); | 73 | iString * debugInfo_History (const iHistory *); |
72 | 74 | ||
diff --git a/src/prefs.c b/src/prefs.c index 188938a2..ce32962b 100644 --- a/src/prefs.c +++ b/src/prefs.c | |||
@@ -34,6 +34,7 @@ void init_Prefs(iPrefs *d) { | |||
34 | d->smoothScrolling = iTrue; | 34 | d->smoothScrolling = iTrue; |
35 | d->loadImageInsteadOfScrolling = iFalse; | 35 | d->loadImageInsteadOfScrolling = iFalse; |
36 | d->decodeUserVisibleURLs = iTrue; | 36 | d->decodeUserVisibleURLs = iTrue; |
37 | d->maxCacheSize = 10; | ||
37 | d->font = nunito_TextFont; | 38 | d->font = nunito_TextFont; |
38 | d->headingFont = nunito_TextFont; | 39 | d->headingFont = nunito_TextFont; |
39 | d->monospaceGemini = iFalse; | 40 | d->monospaceGemini = iFalse; |
diff --git a/src/prefs.h b/src/prefs.h index 07298eac..1c3274d9 100644 --- a/src/prefs.h +++ b/src/prefs.h | |||
@@ -49,6 +49,7 @@ struct Impl_Prefs { | |||
49 | iBool loadImageInsteadOfScrolling; | 49 | iBool loadImageInsteadOfScrolling; |
50 | /* Network */ | 50 | /* Network */ |
51 | iBool decodeUserVisibleURLs; | 51 | iBool decodeUserVisibleURLs; |
52 | int maxCacheSize; /* MB */ | ||
52 | iString geminiProxy; | 53 | iString geminiProxy; |
53 | iString gopherProxy; | 54 | iString gopherProxy; |
54 | iString httpProxy; | 55 | iString httpProxy; |
diff --git a/src/ui/util.c b/src/ui/util.c index 7fc27130..91945db8 100644 --- a/src/ui/util.c +++ b/src/ui/util.c | |||
@@ -1090,7 +1090,7 @@ iWidget *makePreferences_Widget(void) { | |||
1090 | } | 1090 | } |
1091 | /* Colors. */ { | 1091 | /* Colors. */ { |
1092 | appendTwoColumnPage_(tabs, "Colors", '3', &headings, &values); | 1092 | appendTwoColumnPage_(tabs, "Colors", '3', &headings, &values); |
1093 | makeTwoColumnHeading_("PAGE CONTENTS", headings, values); | 1093 | makeTwoColumnHeading_("PAGE CONTENT", headings, values); |
1094 | for (int i = 0; i < 2; ++i) { | 1094 | for (int i = 0; i < 2; ++i) { |
1095 | const iBool isDark = (i == 0); | 1095 | const iBool isDark = (i == 0); |
1096 | const char *mode = isDark ? "dark" : "light"; | 1096 | const char *mode = isDark ? "dark" : "light"; |
@@ -1121,6 +1121,7 @@ iWidget *makePreferences_Widget(void) { | |||
1121 | } | 1121 | } |
1122 | /* Layout. */ { | 1122 | /* Layout. */ { |
1123 | appendTwoColumnPage_(tabs, "Style", '4', &headings, &values); | 1123 | appendTwoColumnPage_(tabs, "Style", '4', &headings, &values); |
1124 | makeTwoColumnHeading_("FONTS", headings, values); | ||
1124 | /* Fonts. */ { | 1125 | /* Fonts. */ { |
1125 | iWidget *fonts; | 1126 | iWidget *fonts; |
1126 | addChild_Widget(headings, iClob(makeHeading_Widget("Heading font:"))); | 1127 | addChild_Widget(headings, iClob(makeHeading_Widget("Heading font:"))); |
@@ -1140,8 +1141,7 @@ iWidget *makePreferences_Widget(void) { | |||
1140 | addChild_Widget(mono, iClob(makeToggle_Widget("prefs.mono.gopher"))), "Gopher"); | 1141 | addChild_Widget(mono, iClob(makeToggle_Widget("prefs.mono.gopher"))), "Gopher"); |
1141 | addChildFlags_Widget(values, iClob(mono), arrangeHorizontal_WidgetFlag | arrangeSize_WidgetFlag); | 1142 | addChildFlags_Widget(values, iClob(mono), arrangeHorizontal_WidgetFlag | arrangeSize_WidgetFlag); |
1142 | } | 1143 | } |
1143 | addChild_Widget(headings, iClob(makePadding_Widget(2 * gap_UI))); | 1144 | makeTwoColumnHeading_("PARAGRAPH", headings, values); |
1144 | addChild_Widget(values, iClob(makePadding_Widget(2 * gap_UI))); | ||
1145 | addChild_Widget(headings, iClob(makeHeading_Widget("Line width:"))); | 1145 | addChild_Widget(headings, iClob(makeHeading_Widget("Line width:"))); |
1146 | iWidget *widths = new_Widget(); | 1146 | iWidget *widths = new_Widget(); |
1147 | /* Line widths. */ { | 1147 | /* Line widths. */ { |
@@ -1162,10 +1162,19 @@ iWidget *makePreferences_Widget(void) { | |||
1162 | addChild_Widget(headings, iClob(makeHeading_Widget("Big 1st paragaph:"))); | 1162 | addChild_Widget(headings, iClob(makeHeading_Widget("Big 1st paragaph:"))); |
1163 | addChild_Widget(values, iClob(makeToggle_Widget("prefs.biglede"))); | 1163 | addChild_Widget(values, iClob(makeToggle_Widget("prefs.biglede"))); |
1164 | } | 1164 | } |
1165 | /* Proxies. */ { | 1165 | /* Network. */ { |
1166 | appendTwoColumnPage_(tabs, "Network", '5', &headings, &values); | 1166 | appendTwoColumnPage_(tabs, "Network", '5', &headings, &values); |
1167 | addChild_Widget(headings, iClob(makeHeading_Widget("Decode paths:"))); | 1167 | addChild_Widget(headings, iClob(makeHeading_Widget("Cache size:"))); |
1168 | iWidget *cacheGroup = new_Widget(); { | ||
1169 | iInputWidget *cache = new_InputWidget(4); | ||
1170 | setSelectAllOnFocus_InputWidget(cache, iTrue); | ||
1171 | setId_Widget(addChild_Widget(cacheGroup, iClob(cache)), "prefs.cachesize"); | ||
1172 | addChildFlags_Widget(cacheGroup, iClob(new_LabelWidget("MB", NULL)), frameless_WidgetFlag); | ||
1173 | } | ||
1174 | addChildFlags_Widget(values, iClob(cacheGroup), arrangeHorizontal_WidgetFlag | arrangeSize_WidgetFlag); | ||
1175 | addChild_Widget(headings, iClob(makeHeading_Widget("Decode URLs:"))); | ||
1168 | addChild_Widget(values, iClob(makeToggle_Widget("prefs.decodeurls"))); | 1176 | addChild_Widget(values, iClob(makeToggle_Widget("prefs.decodeurls"))); |
1177 | makeTwoColumnHeading_("PROXIES", headings, values); | ||
1169 | addChild_Widget(headings, iClob(makeHeading_Widget("Gemini proxy:"))); | 1178 | addChild_Widget(headings, iClob(makeHeading_Widget("Gemini proxy:"))); |
1170 | setId_Widget(addChild_Widget(values, iClob(new_InputWidget(0))), "prefs.proxy.gemini"); | 1179 | setId_Widget(addChild_Widget(values, iClob(new_InputWidget(0))), "prefs.proxy.gemini"); |
1171 | addChild_Widget(headings, iClob(makeHeading_Widget("Gopher proxy:"))); | 1180 | addChild_Widget(headings, iClob(makeHeading_Widget("Gopher proxy:"))); |
diff --git a/src/ui/window.c b/src/ui/window.c index 2e38512b..66994e79 100644 --- a/src/ui/window.c +++ b/src/ui/window.c | |||
@@ -397,6 +397,7 @@ static iBool handleNavBarCommands_(iWidget *navBar, const char *cmd) { | |||
397 | if (equal_Command(cmd, "document.changed")) { | 397 | if (equal_Command(cmd, "document.changed")) { |
398 | iInputWidget *url = findWidget_App("url"); | 398 | iInputWidget *url = findWidget_App("url"); |
399 | const iString *urlStr = collect_String(suffix_Command(cmd, "url")); | 399 | const iString *urlStr = collect_String(suffix_Command(cmd, "url")); |
400 | trimCache_App(); | ||
400 | visitUrl_Visited(visited_App(), urlStr, 0); | 401 | visitUrl_Visited(visited_App(), urlStr, 0); |
401 | postCommand_App("visited.changed"); /* sidebar will update */ | 402 | postCommand_App("visited.changed"); /* sidebar will update */ |
402 | setText_InputWidget(url, urlStr); | 403 | setText_InputWidget(url, urlStr); |