summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--res/about/version.gmi1
-rw-r--r--src/app.c8
-rw-r--r--src/gmdocument.c10
-rw-r--r--src/prefs.c12
-rw-r--r--src/prefs.h50
-rw-r--r--src/ui/documentwidget.c44
-rw-r--r--src/ui/keys.c67
-rw-r--r--src/ui/keys.h1
-rw-r--r--src/ui/util.c2
9 files changed, 131 insertions, 64 deletions
diff --git a/res/about/version.gmi b/res/about/version.gmi
index 3679a465..f3d40e76 100644
--- a/res/about/version.gmi
+++ b/res/about/version.gmi
@@ -7,6 +7,7 @@
7# Release notes 7# Release notes
8 8
9## 0.10 9## 0.10
10* Added option to load inline images when pressing Space or ↓. If an image link is visible, the image will be loaded instead of scrolling. This option is disabled by default.
10* Added an option to use a proxy server for Gemini requests. 11* Added an option to use a proxy server for Gemini requests.
11* Added a keybinding to activate keyboard link navigation mode (default is "F"). 12* Added a keybinding to activate keyboard link navigation mode (default is "F").
12* Clearing and resetting keybindings via a context menu. 13* Clearing and resetting keybindings via a context menu.
diff --git a/src/app.c b/src/app.c
index f2741ee6..b53666c8 100644
--- a/src/app.c
+++ b/src/app.c
@@ -183,6 +183,7 @@ static iString *serializePrefs_App_(const iApp *d) {
183 appendFormat_String(str, "prefs.mono.gopher.changed arg:%d\n", d->prefs.monospaceGopher); 183 appendFormat_String(str, "prefs.mono.gopher.changed arg:%d\n", d->prefs.monospaceGopher);
184 appendFormat_String(str, "zoom.set arg:%d\n", d->prefs.zoomPercent); 184 appendFormat_String(str, "zoom.set arg:%d\n", d->prefs.zoomPercent);
185 appendFormat_String(str, "smoothscroll arg:%d\n", d->prefs.smoothScrolling); 185 appendFormat_String(str, "smoothscroll arg:%d\n", d->prefs.smoothScrolling);
186 appendFormat_String(str, "imageloadscroll arg:%d\n", d->prefs.loadImageInsteadOfScrolling);
186 appendFormat_String(str, "linewidth.set arg:%d\n", d->prefs.lineWidth); 187 appendFormat_String(str, "linewidth.set arg:%d\n", d->prefs.lineWidth);
187 appendFormat_String(str, "prefs.biglede.changed arg:%d\n", d->prefs.bigFirstParagraph); 188 appendFormat_String(str, "prefs.biglede.changed arg:%d\n", d->prefs.bigFirstParagraph);
188 appendFormat_String(str, "prefs.sideicon.changed arg:%d\n", d->prefs.sideIcon); 189 appendFormat_String(str, "prefs.sideicon.changed arg:%d\n", d->prefs.sideIcon);
@@ -746,6 +747,8 @@ static iBool handlePrefsCommands_(iWidget *d, const char *cmd) {
746 isSelected_Widget(findChild_Widget(d, "prefs.retainwindow"))); 747 isSelected_Widget(findChild_Widget(d, "prefs.retainwindow")));
747 postCommandf_App("smoothscroll arg:%d", 748 postCommandf_App("smoothscroll arg:%d",
748 isSelected_Widget(findChild_Widget(d, "prefs.smoothscroll"))); 749 isSelected_Widget(findChild_Widget(d, "prefs.smoothscroll")));
750 postCommandf_App("imageloadscroll arg:%d",
751 isSelected_Widget(findChild_Widget(d, "prefs.imageloadscroll")));
749 postCommandf_App("ostheme arg:%d", 752 postCommandf_App("ostheme arg:%d",
750 isSelected_Widget(findChild_Widget(d, "prefs.ostheme"))); 753 isSelected_Widget(findChild_Widget(d, "prefs.ostheme")));
751 postCommandf_App("proxy.gemini address:%s", 754 postCommandf_App("proxy.gemini address:%s",
@@ -956,6 +959,10 @@ iBool handleCommand_App(const char *cmd) {
956 d->prefs.smoothScrolling = arg_Command(cmd); 959 d->prefs.smoothScrolling = arg_Command(cmd);
957 return iTrue; 960 return iTrue;
958 } 961 }
962 else if (equal_Command(cmd, "imageloadscroll")) {
963 d->prefs.loadImageInsteadOfScrolling = arg_Command(cmd);
964 return iTrue;
965 }
959 else if (equal_Command(cmd, "forcewrap.toggle")) { 966 else if (equal_Command(cmd, "forcewrap.toggle")) {
960 d->prefs.forceLineWrap = !d->prefs.forceLineWrap; 967 d->prefs.forceLineWrap = !d->prefs.forceLineWrap;
961 updateSize_DocumentWidget(document_App()); 968 updateSize_DocumentWidget(document_App());
@@ -1153,6 +1160,7 @@ iBool handleCommand_App(const char *cmd) {
1153 setText_InputWidget(findChild_Widget(dlg, "prefs.downloads"), &d->prefs.downloadDir); 1160 setText_InputWidget(findChild_Widget(dlg, "prefs.downloads"), &d->prefs.downloadDir);
1154 setToggle_Widget(findChild_Widget(dlg, "prefs.hoveroutline"), d->prefs.hoverOutline); 1161 setToggle_Widget(findChild_Widget(dlg, "prefs.hoveroutline"), d->prefs.hoverOutline);
1155 setToggle_Widget(findChild_Widget(dlg, "prefs.smoothscroll"), d->prefs.smoothScrolling); 1162 setToggle_Widget(findChild_Widget(dlg, "prefs.smoothscroll"), d->prefs.smoothScrolling);
1163 setToggle_Widget(findChild_Widget(dlg, "prefs.imageloadscroll"), d->prefs.loadImageInsteadOfScrolling);
1156 setToggle_Widget(findChild_Widget(dlg, "prefs.ostheme"), d->prefs.useSystemTheme); 1164 setToggle_Widget(findChild_Widget(dlg, "prefs.ostheme"), d->prefs.useSystemTheme);
1157 setToggle_Widget(findChild_Widget(dlg, "prefs.retainwindow"), d->prefs.retainWindowSize); 1165 setToggle_Widget(findChild_Widget(dlg, "prefs.retainwindow"), d->prefs.retainWindowSize);
1158 setText_InputWidget(findChild_Widget(dlg, "prefs.uiscale"), 1166 setText_InputWidget(findChild_Widget(dlg, "prefs.uiscale"),
diff --git a/src/gmdocument.c b/src/gmdocument.c
index 923c20c9..62a0ba55 100644
--- a/src/gmdocument.c
+++ b/src/gmdocument.c
@@ -1366,8 +1366,14 @@ enum iColorId linkColor_GmDocument(const iGmDocument *d, iGmLinkId linkId, enum
1366} 1366}
1367 1367
1368iBool isMediaLink_GmDocument(const iGmDocument *d, iGmLinkId linkId) { 1368iBool isMediaLink_GmDocument(const iGmDocument *d, iGmLinkId linkId) {
1369 return (linkFlags_GmDocument(d, linkId) & 1369 const iString *dstUrl = absoluteUrl_String(&d->url, linkUrl_GmDocument(d, linkId));
1370 (imageFileExtension_GmLinkFlag | audioFileExtension_GmLinkFlag)) != 0; 1370 const iRangecc scheme = urlScheme_String(dstUrl);
1371 if (equalCase_Rangecc(scheme, "gemini") || equalCase_Rangecc(scheme, "gopher") ||
1372 willUseProxy_App(scheme)) {
1373 return (linkFlags_GmDocument(d, linkId) &
1374 (imageFileExtension_GmLinkFlag | audioFileExtension_GmLinkFlag)) != 0;
1375 }
1376 return iFalse;
1371} 1377}
1372 1378
1373const iString *title_GmDocument(const iGmDocument *d) { 1379const iString *title_GmDocument(const iGmDocument *d) {
diff --git a/src/prefs.c b/src/prefs.c
index 80b11c30..dc2bd601 100644
--- a/src/prefs.c
+++ b/src/prefs.c
@@ -24,21 +24,23 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */
24 24
25void init_Prefs(iPrefs *d) { 25void init_Prefs(iPrefs *d) {
26 d->dialogTab = 0; 26 d->dialogTab = 0;
27 d->theme = dark_ColorTheme;
28 d->useSystemTheme = iTrue; 27 d->useSystemTheme = iTrue;
28 d->theme = dark_ColorTheme;
29 d->retainWindowSize = iTrue; 29 d->retainWindowSize = iTrue;
30 d->uiScale = 1.0f; /* default set elsewhere */
30 d->zoomPercent = 100; 31 d->zoomPercent = 100;
32 d->sideIcon = iTrue;
33 d->hoverOutline = iFalse;
31 d->smoothScrolling = iTrue; 34 d->smoothScrolling = iTrue;
32 d->forceLineWrap = iFalse; 35 d->loadImageInsteadOfScrolling = iFalse;
33 d->quoteIcon = iTrue;
34 d->font = nunito_TextFont; 36 d->font = nunito_TextFont;
35 d->headingFont = nunito_TextFont; 37 d->headingFont = nunito_TextFont;
36 d->monospaceGemini = iFalse; 38 d->monospaceGemini = iFalse;
37 d->monospaceGopher = iFalse; 39 d->monospaceGopher = iFalse;
38 d->lineWidth = 40; 40 d->lineWidth = 40;
39 d->bigFirstParagraph = iTrue; 41 d->bigFirstParagraph = iTrue;
40 d->sideIcon = iTrue; 42 d->forceLineWrap = iFalse;
41 d->hoverOutline = iFalse; 43 d->quoteIcon = iTrue;
42 d->docThemeDark = colorfulDark_GmDocumentTheme; 44 d->docThemeDark = colorfulDark_GmDocumentTheme;
43 d->docThemeLight = white_GmDocumentTheme; 45 d->docThemeLight = white_GmDocumentTheme;
44 d->saturation = 1.0f; 46 d->saturation = 1.0f;
diff --git a/src/prefs.h b/src/prefs.h
index 33ce8b41..a3993629 100644
--- a/src/prefs.h
+++ b/src/prefs.h
@@ -33,31 +33,37 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */
33iDeclareType(Prefs) 33iDeclareType(Prefs)
34 34
35struct Impl_Prefs { 35struct Impl_Prefs {
36 int dialogTab; 36 /* UI state */
37 iBool retainWindowSize; 37 int dialogTab;
38 float uiScale; 38 /* Window */
39 int zoomPercent; 39 iBool useSystemTheme;
40 iBool smoothScrolling;
41 iBool useSystemTheme;
42 enum iColorTheme theme; 40 enum iColorTheme theme;
43 iString geminiProxy; 41 iBool retainWindowSize;
44 iString gopherProxy; 42 float uiScale;
45 iString httpProxy; 43 int zoomPercent;
46 iString downloadDir; 44 iBool sideIcon;
47 /* Content */ 45 /* Behavior */
48 enum iTextFont font; 46 iString downloadDir;
49 enum iTextFont headingFont; 47 iBool hoverOutline;
50 iBool monospaceGemini; 48 iBool smoothScrolling;
51 iBool monospaceGopher; 49 iBool loadImageInsteadOfScrolling;
52 int lineWidth; 50 /* Network */
53 iBool bigFirstParagraph; 51 iString geminiProxy;
54 iBool forceLineWrap; 52 iString gopherProxy;
55 iBool quoteIcon; 53 iString httpProxy;
56 iBool sideIcon; 54 /* Style */
57 iBool hoverOutline; 55 enum iTextFont font;
56 enum iTextFont headingFont;
57 iBool monospaceGemini;
58 iBool monospaceGopher;
59 int lineWidth;
60 iBool bigFirstParagraph;
61 iBool forceLineWrap;
62 iBool quoteIcon;
63 /* Colors */
58 enum iGmDocumentTheme docThemeDark; 64 enum iGmDocumentTheme docThemeDark;
59 enum iGmDocumentTheme docThemeLight; 65 enum iGmDocumentTheme docThemeLight;
60 float saturation; 66 float saturation;
61}; 67};
62 68
63iDeclareTypeConstruction(Prefs) 69iDeclareTypeConstruction(Prefs)
diff --git a/src/ui/documentwidget.c b/src/ui/documentwidget.c
index 59f5a92c..0fc969ba 100644
--- a/src/ui/documentwidget.c
+++ b/src/ui/documentwidget.c
@@ -1151,10 +1151,8 @@ static iMediaRequest *findMediaRequest_DocumentWidget_(const iDocumentWidget *d,
1151 1151
1152static iBool requestMedia_DocumentWidget_(iDocumentWidget *d, iGmLinkId linkId) { 1152static iBool requestMedia_DocumentWidget_(iDocumentWidget *d, iGmLinkId linkId) {
1153 if (!findMediaRequest_DocumentWidget_(d, linkId)) { 1153 if (!findMediaRequest_DocumentWidget_(d, linkId)) {
1154 pushBack_ObjectList( 1154 const iString *imageUrl = absoluteUrl_String(d->mod.url, linkUrl_GmDocument(d->doc, linkId));
1155 d->media, 1155 pushBack_ObjectList(d->media, iClob(new_MediaRequest(d, linkId, imageUrl)));
1156 iClob(new_MediaRequest(
1157 d, linkId, absoluteUrl_String(d->mod.url, linkUrl_GmDocument(d->doc, linkId)))));
1158 invalidate_DocumentWidget_(d); 1156 invalidate_DocumentWidget_(d);
1159 return iTrue; 1157 return iTrue;
1160 } 1158 }
@@ -1235,6 +1233,22 @@ static void allocVisBuffer_DocumentWidget_(const iDocumentWidget *d) {
1235 } 1233 }
1236} 1234}
1237 1235
1236static iBool fetchNextUnfetchedImage_DocumentWidget_(iDocumentWidget *d) {
1237 iConstForEach(PtrArray, i, &d->visibleLinks) {
1238 const iGmRun *run = i.ptr;
1239 if (run->linkId && !run->imageId && ~run->flags & decoration_GmRunFlag) {
1240 const int linkFlags = linkFlags_GmDocument(d->doc, run->linkId);
1241 if (isMediaLink_GmDocument(d->doc, run->linkId) &&
1242 ~linkFlags & content_GmLinkFlag && ~linkFlags & permanent_GmLinkFlag ) {
1243 if (requestMedia_DocumentWidget_(d, run->linkId)) {
1244 return iTrue;
1245 }
1246 }
1247 }
1248 }
1249 return iFalse;
1250}
1251
1238static iBool handleCommand_DocumentWidget_(iDocumentWidget *d, const char *cmd) { 1252static iBool handleCommand_DocumentWidget_(iDocumentWidget *d, const char *cmd) {
1239 iWidget *w = as_Widget(d); 1253 iWidget *w = as_Widget(d);
1240 if (equal_Command(cmd, "window.resized") || equal_Command(cmd, "font.changed")) { 1254 if (equal_Command(cmd, "window.resized") || equal_Command(cmd, "font.changed")) {
@@ -1572,13 +1586,16 @@ static iBool handleCommand_DocumentWidget_(iDocumentWidget *d, const char *cmd)
1572 return iTrue; 1586 return iTrue;
1573 } 1587 }
1574 else if (equal_Command(cmd, "scroll.page") && document_App() == d) { 1588 else if (equal_Command(cmd, "scroll.page") && document_App() == d) {
1575 if (argLabel_Command(cmd, "repeat")) { 1589 const int dir = arg_Command(cmd);
1576 /* TODO: Adjust scroll animation to be linear during repeated scroll? */ 1590 if (!argLabel_Command(cmd, "repeat") && prefs_App()->loadImageInsteadOfScrolling &&
1591 dir > 0) {
1592 if (fetchNextUnfetchedImage_DocumentWidget_(d)) {
1593 return iTrue;
1594 }
1577 } 1595 }
1578 smoothScroll_DocumentWidget_(d, 1596 smoothScroll_DocumentWidget_(d,
1579 arg_Command(cmd) * 1597 dir * (0.5f * height_Rect(documentBounds_DocumentWidget_(d)) -
1580 (0.5f * height_Rect(documentBounds_DocumentWidget_(d)) - 1598 0 * lineHeight_Text(paragraph_FontId)),
1581 0 * lineHeight_Text(paragraph_FontId)),
1582 smoothDuration_DocumentWidget_); 1599 smoothDuration_DocumentWidget_);
1583 return iTrue; 1600 return iTrue;
1584 } 1601 }
@@ -1599,8 +1616,15 @@ static iBool handleCommand_DocumentWidget_(iDocumentWidget *d, const char *cmd)
1599 return iTrue; 1616 return iTrue;
1600 } 1617 }
1601 else if (equal_Command(cmd, "scroll.step") && document_App() == d) { 1618 else if (equal_Command(cmd, "scroll.step") && document_App() == d) {
1619 const int dir = arg_Command(cmd);
1620 if (!argLabel_Command(cmd, "repeat") && prefs_App()->loadImageInsteadOfScrolling &&
1621 dir > 0) {
1622 if (fetchNextUnfetchedImage_DocumentWidget_(d)) {
1623 return iTrue;
1624 }
1625 }
1602 smoothScroll_DocumentWidget_(d, 1626 smoothScroll_DocumentWidget_(d,
1603 3 * lineHeight_Text(paragraph_FontId) * arg_Command(cmd), 1627 3 * lineHeight_Text(paragraph_FontId) * dir,
1604 smoothDuration_DocumentWidget_); 1628 smoothDuration_DocumentWidget_);
1605 return iTrue; 1629 return iTrue;
1606 } 1630 }
diff --git a/src/ui/keys.c b/src/ui/keys.c
index 5b88bfcf..ea874343 100644
--- a/src/ui/keys.c
+++ b/src/ui/keys.c
@@ -56,25 +56,46 @@ static void clear_Keys_(iKeys *d) {
56 } 56 }
57} 57}
58 58
59enum iBindFlag {
60 argRepeat_BindFlag = iBit(1),
61};
62
59/* TODO: This indirection could be used for localization, although all UI strings 63/* TODO: This indirection could be used for localization, although all UI strings
60 would need to be similarly handled. */ 64 would need to be similarly handled. */
61static const struct { int id; iMenuItem bind; } defaultBindings_[] = { 65static const struct { int id; iMenuItem bind; int flags; } defaultBindings_[] = {
62 { 1, { "Jump to top", SDLK_HOME, 0, "scroll.top" } }, 66 { 1, { "Jump to top", SDLK_HOME, 0, "scroll.top" }, 0 },
63 { 2, { "Jump to bottom", SDLK_END, 0, "scroll.bottom" } }, 67 { 2, { "Jump to bottom", SDLK_END, 0, "scroll.bottom" }, 0 },
64 { 10, { "Scroll up", SDLK_UP, 0, "scroll.step arg:-1" } }, 68 { 10, { "Scroll up", SDLK_UP, 0, "scroll.step arg:-1" }, argRepeat_BindFlag },
65 { 11, { "Scroll down", SDLK_DOWN, 0, "scroll.step arg:1" } }, 69 { 11, { "Scroll down", SDLK_DOWN, 0, "scroll.step arg:1" }, argRepeat_BindFlag },
66 { 20, { "Scroll up half a page", SDLK_PAGEUP, 0, "scroll.page arg:-1" } }, 70 { 20, { "Scroll up half a page", SDLK_PAGEUP, 0, "scroll.page arg:-1" }, argRepeat_BindFlag },
67 { 21, { "Scroll down half a page", SDLK_PAGEDOWN, 0, "scroll.page arg:1" } }, 71 { 21, { "Scroll down half a page", SDLK_PAGEDOWN, 0, "scroll.page arg:1" }, argRepeat_BindFlag },
68 { 30, { "Go back", navigateBack_KeyShortcut, "navigate.back" } }, 72 { 30, { "Go back", navigateBack_KeyShortcut, "navigate.back" }, 0 },
69 { 31, { "Go forward", navigateForward_KeyShortcut, "navigate.forward" } }, 73 { 31, { "Go forward", navigateForward_KeyShortcut, "navigate.forward" }, 0 },
70 { 32, { "Go to parent directory", navigateParent_KeyShortcut, "navigate.parent" } }, 74 { 32, { "Go to parent directory", navigateParent_KeyShortcut, "navigate.parent" }, 0 },
71 { 33, { "Go to site root", navigateRoot_KeyShortcut, "navigate.root" } }, 75 { 33, { "Go to site root", navigateRoot_KeyShortcut, "navigate.root" }, 0 },
72 { 40, { "Open link via keyboard", 'f', 0, "document.linkkeys"} }, 76 { 40, { "Open link via keyboard", 'f', 0, "document.linkkeys" }, 0 },
73 /* The following cannot currently be changed (built-in duplicates). */ 77 /* The following cannot currently be changed (built-in duplicates). */
74 { 1000, { NULL, SDLK_SPACE, KMOD_SHIFT, "scroll.page arg:-1" } }, 78 { 1000, { NULL, SDLK_SPACE, KMOD_SHIFT, "scroll.page arg:-1" }, argRepeat_BindFlag },
75 { 1001, { NULL, SDLK_SPACE, 0, "scroll.page arg:1" } }, 79 { 1001, { NULL, SDLK_SPACE, 0, "scroll.page arg:1" }, argRepeat_BindFlag },
76}; 80};
77 81
82static iBinding *findId_Keys_(iKeys *d, int id) {
83 iForEach(Array, i, &d->bindings) {
84 iBinding *bind = i.value;
85 if (bind->id == id) {
86 return bind;
87 }
88 }
89 return NULL;
90}
91
92static void setFlags_Keys_(int id, int bindFlags) {
93 iBinding *bind = findId_Keys_(&keys_, id);
94 if (bind) {
95 bind->flags = bindFlags;
96 }
97}
98
78static void bindDefaults_(void) { 99static void bindDefaults_(void) {
79 iForIndices(i, defaultBindings_) { 100 iForIndices(i, defaultBindings_) {
80 const int id = defaultBindings_[i].id; 101 const int id = defaultBindings_[i].id;
@@ -83,6 +104,7 @@ static void bindDefaults_(void) {
83 if (bind.label) { 104 if (bind.label) {
84 setLabel_Keys(id, bind.label); 105 setLabel_Keys(id, bind.label);
85 } 106 }
107 setFlags_Keys_(id, defaultBindings_[i].flags);
86 } 108 }
87} 109}
88 110
@@ -95,16 +117,6 @@ static iBinding *find_Keys_(iKeys *d, int key, int mods) {
95 return NULL; 117 return NULL;
96} 118}
97 119
98static iBinding *findId_Keys_(iKeys *d, int id) {
99 iForEach(Array, i, &d->bindings) {
100 iBinding *bind = i.value;
101 if (bind->id == id) {
102 return bind;
103 }
104 }
105 return NULL;
106}
107
108static iBinding *findCommand_Keys_(iKeys *d, const char *command) { 120static iBinding *findCommand_Keys_(iKeys *d, const char *command) {
109 /* Note: O(n) */ 121 /* Note: O(n) */
110 iForEach(Array, i, &d->bindings) { 122 iForEach(Array, i, &d->bindings) {
@@ -259,7 +271,12 @@ iBool processEvent_Keys(const SDL_Event *ev) {
259 if (ev->type == SDL_KEYDOWN) { 271 if (ev->type == SDL_KEYDOWN) {
260 const iBinding *bind = find_Keys_(d, ev->key.keysym.sym, keyMods_Sym(ev->key.keysym.mod)); 272 const iBinding *bind = find_Keys_(d, ev->key.keysym.sym, keyMods_Sym(ev->key.keysym.mod));
261 if (bind) { 273 if (bind) {
262 postCommandString_App(&bind->command); 274 if (ev->key.repeat && (bind->flags & argRepeat_BindFlag)) {
275 postCommandf_App("%s repeat:1", cstr_String(&bind->command));
276 }
277 else {
278 postCommandString_App(&bind->command);
279 }
263 return iTrue; 280 return iTrue;
264 } 281 }
265 } 282 }
diff --git a/src/ui/keys.h b/src/ui/keys.h
index 0cd97e2a..1e676c59 100644
--- a/src/ui/keys.h
+++ b/src/ui/keys.h
@@ -52,6 +52,7 @@ iDeclareType(Binding)
52 52
53struct Impl_Binding { 53struct Impl_Binding {
54 int id; 54 int id;
55 int flags;
55 int key; 56 int key;
56 int mods; 57 int mods;
57 iString command; 58 iString command;
diff --git a/src/ui/util.c b/src/ui/util.c
index 85d3562f..559c5381 100644
--- a/src/ui/util.c
+++ b/src/ui/util.c
@@ -1013,6 +1013,8 @@ iWidget *makePreferences_Widget(void) {
1013 addChild_Widget(values, iClob(makeToggle_Widget("prefs.hoveroutline"))); 1013 addChild_Widget(values, iClob(makeToggle_Widget("prefs.hoveroutline")));
1014 addChild_Widget(headings, iClob(makeHeading_Widget("Smooth scrolling:"))); 1014 addChild_Widget(headings, iClob(makeHeading_Widget("Smooth scrolling:")));
1015 addChild_Widget(values, iClob(makeToggle_Widget("prefs.smoothscroll"))); 1015 addChild_Widget(values, iClob(makeToggle_Widget("prefs.smoothscroll")));
1016 addChild_Widget(headings, iClob(makeHeading_Widget("Load image on scroll:")));
1017 addChild_Widget(values, iClob(makeToggle_Widget("prefs.imageloadscroll")));
1016 } 1018 }
1017 /* Window. */ { 1019 /* Window. */ {
1018 appendTwoColumnPage_(tabs, "Window", '2', &headings, &values); 1020 appendTwoColumnPage_(tabs, "Window", '2', &headings, &values);