From f229e183b3ab5bf9f360349143634d62e7ceacbd Mon Sep 17 00:00:00 2001 From: Jaakko Keränen Date: Mon, 15 Feb 2021 17:47:37 +0200 Subject: Preferences: Saturation levels as percentages --- src/ui/util.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'src/ui/util.c') diff --git a/src/ui/util.c b/src/ui/util.c index b52dea2d..9a98d07b 100644 --- a/src/ui/util.c +++ b/src/ui/util.c @@ -1123,10 +1123,10 @@ iWidget *makePreferences_Widget(void) { addChild_Widget(headings, iClob(makeHeading_Widget("Saturation:"))); iWidget *sats = new_Widget(); /* Saturation levels. */ { - addRadioButton_(sats, "prefs.saturation.3", "Full", "saturation.set arg:100"); - addRadioButton_(sats, "prefs.saturation.2", "Reduced", "saturation.set arg:66"); - addRadioButton_(sats, "prefs.saturation.1", "Minimal", "saturation.set arg:33"); - addRadioButton_(sats, "prefs.saturation.0", "Monochrome", "saturation.set arg:0"); + addRadioButton_(sats, "prefs.saturation.3", "100 %%", "saturation.set arg:100"); + addRadioButton_(sats, "prefs.saturation.2", "66 %%", "saturation.set arg:66"); + addRadioButton_(sats, "prefs.saturation.1", "33 %%", "saturation.set arg:33"); + addRadioButton_(sats, "prefs.saturation.0", "0 %%", "saturation.set arg:0"); } addChildFlags_Widget(values, iClob(sats), arrangeHorizontal_WidgetFlag | arrangeSize_WidgetFlag); } -- cgit v1.2.3 From 902ccb3d65db97ad4f8d17279806b0290d7ca332 Mon Sep 17 00:00:00 2001 From: Jaakko Keränen Date: Tue, 16 Feb 2021 08:50:37 +0200 Subject: Search engine queries via the navbar Any text that doesn't look like a URL is passed onto the configured search URL as a query string. IssueID #157 --- res/about/version.gmi | 2 ++ src/app.c | 17 +++++++++++++++++ src/app.h | 1 + src/gmutil.c | 15 +++++++++++++++ src/gmutil.h | 1 + src/prefs.c | 2 ++ src/prefs.h | 1 + src/ui/util.c | 7 +++++-- src/ui/window.c | 14 ++++++++++---- 9 files changed, 54 insertions(+), 6 deletions(-) (limited to 'src/ui/util.c') diff --git a/res/about/version.gmi b/res/about/version.gmi index c255e533..ba94f7e2 100644 --- a/res/about/version.gmi +++ b/res/about/version.gmi @@ -8,7 +8,9 @@ ## 1.2 * Help is opened on first run instead of the "About Lagrange" page to make it easier to discover important Gemini links like the FAQ. +* Added search engine support: non-URL text entered in the navbar is passed onto the configured search query URL (Preferences > Network). * Short pages are centered vertically on actual page content excluding the top banner. +* Added user preference for aligning all pages to the top of the window. * Shift+Insert can be used for pasting clipboard contents into input fields. * Added keybinding (F11) for toggling fullscreen mode. On macOS, the shortcut is ⌃⌘F as before. * Added keybinding for finding text on page. diff --git a/src/app.c b/src/app.c index 3d3dc6f8..b5eb5688 100644 --- a/src/app.c +++ b/src/app.c @@ -227,6 +227,7 @@ static iString *serializePrefs_App_(const iApp *d) { appendFormat_String(str, "proxy.gopher address:%s\n", cstr_String(&d->prefs.gopherProxy)); appendFormat_String(str, "proxy.http address:%s\n", cstr_String(&d->prefs.httpProxy)); appendFormat_String(str, "downloads path:%s\n", cstr_String(&d->prefs.downloadDir)); + appendFormat_String(str, "searchurl address:%s\n", cstr_String(&d->prefs.searchUrl)); return str; } @@ -937,6 +938,8 @@ static iBool handlePrefsCommands_(iWidget *d, const char *cmd) { isSelected_Widget(findChild_Widget(d, "prefs.ostheme"))); postCommandf_App("decodeurls arg:%d", isSelected_Widget(findChild_Widget(d, "prefs.decodeurls"))); + postCommandf_App("searchurl address:%s", + cstr_String(text_InputWidget(findChild_Widget(d, "prefs.searchurl")))); postCommandf_App("cachesize.set arg:%d", toInt_String(text_InputWidget(findChild_Widget(d, "prefs.cachesize")))); postCommandf_App("proxy.gemini address:%s", @@ -1122,6 +1125,15 @@ iBool willUseProxy_App(const iRangecc scheme) { return schemeProxy_App(scheme) != NULL; } +const iString *searchQueryUrl_App(const iString *queryStringUnescaped) { + iApp *d = &app_; + if (isEmpty_String(&d->prefs.searchUrl)) { + return collectNew_String(); + } + const iString *escaped = urlEncode_String(queryStringUnescaped); + return collectNewFormat_String("%s?%s", cstr_String(&d->prefs.searchUrl), cstr_String(escaped)); +} + iBool handleCommand_App(const char *cmd) { iApp *d = &app_; if (equal_Command(cmd, "config.error")) { @@ -1292,6 +1304,10 @@ iBool handleCommand_App(const char *cmd) { } return iTrue; } + else if (equal_Command(cmd, "searchurl")) { + setCStr_String(&d->prefs.searchUrl, suffixPtr_Command(cmd, "address")); + return iTrue; + } else if (equal_Command(cmd, "proxy.gemini")) { setCStr_String(&d->prefs.geminiProxy, suffixPtr_Command(cmd, "address")); return iTrue; @@ -1474,6 +1490,7 @@ iBool handleCommand_App(const char *cmd) { setText_InputWidget(findChild_Widget(dlg, "prefs.cachesize"), collectNewFormat_String("%d", d->prefs.maxCacheSize)); setToggle_Widget(findChild_Widget(dlg, "prefs.decodeurls"), d->prefs.decodeUserVisibleURLs); + setText_InputWidget(findChild_Widget(dlg, "prefs.searchurl"), &d->prefs.searchUrl); setText_InputWidget(findChild_Widget(dlg, "prefs.proxy.gemini"), &d->prefs.geminiProxy); setText_InputWidget(findChild_Widget(dlg, "prefs.proxy.gopher"), &d->prefs.gopherProxy); setText_InputWidget(findChild_Widget(dlg, "prefs.proxy.http"), &d->prefs.httpProxy); diff --git a/src/app.h b/src/app.h index efaf0a3e..54c60d10 100644 --- a/src/app.h +++ b/src/app.h @@ -75,6 +75,7 @@ iBool forceSoftwareRender_App(void); enum iColorTheme colorTheme_App (void); const iString * schemeProxy_App (iRangecc scheme); iBool willUseProxy_App (const iRangecc scheme); +const iString * searchQueryUrl_App (const iString *queryStringUnescaped); typedef void (*iTickerFunc)(iAny *); diff --git a/src/gmutil.c b/src/gmutil.c index 0e0cccc5..32bf356f 100644 --- a/src/gmutil.c +++ b/src/gmutil.c @@ -272,6 +272,21 @@ const iString *absoluteUrl_String(const iString *d, const iString *urlMaybeRelat return absolute; } +iBool isLikelyUrl_String(const iString *d) { + /* Guess whether a human intends the string to be an URL. This is supposed to be fuzzy; + not completely per-spec: a) begins with a scheme; b) has something that looks like a + hostname */ + iRegExp *pattern = new_RegExp("^([a-z]+:)?//.*|" + "^(//)?([^/?#: ]+)([/?#:].*)$|" + "^(\\w+(\\.\\w+)+|localhost)$", + caseInsensitive_RegExpOption); + iRegExpMatch m; + init_RegExpMatch(&m); + const iBool likelyUrl = matchString_RegExp(pattern, d, &m); + iRelease(pattern); + return likelyUrl; +} + static iBool equalPuny_(const iString *d, iRangecc orig) { if (!endsWith_String(d, "-")) { return iFalse; /* This is a sufficient condition? */ diff --git a/src/gmutil.h b/src/gmutil.h index 1caf2445..26385c02 100644 --- a/src/gmutil.h +++ b/src/gmutil.h @@ -104,6 +104,7 @@ void init_Url (iUrl *, const iString *text); iRangecc urlScheme_String (const iString *); iRangecc urlHost_String (const iString *); const iString * absoluteUrl_String (const iString *, const iString *urlMaybeRelative); +iBool isLikelyUrl_String (const iString *); void punyEncodeUrlHost_String(iString *); void stripDefaultUrlPort_String(iString *); const iString * urlFragmentStripped_String(const iString *); diff --git a/src/prefs.c b/src/prefs.c index a8f34b02..f9186ab3 100644 --- a/src/prefs.c +++ b/src/prefs.c @@ -51,9 +51,11 @@ void init_Prefs(iPrefs *d) { init_String(&d->gopherProxy); init_String(&d->httpProxy); init_String(&d->downloadDir); + initCStr_String(&d->searchUrl, "gemini://gus.guru/search"); } void deinit_Prefs(iPrefs *d) { + deinit_String(&d->searchUrl); deinit_String(&d->geminiProxy); deinit_String(&d->gopherProxy); deinit_String(&d->httpProxy); diff --git a/src/prefs.h b/src/prefs.h index dcda695f..1889c338 100644 --- a/src/prefs.h +++ b/src/prefs.h @@ -48,6 +48,7 @@ struct Impl_Prefs { iBool hoverLink; iBool smoothScrolling; iBool loadImageInsteadOfScrolling; + iString searchUrl; /* Network */ iBool decodeUserVisibleURLs; int maxCacheSize; /* MB */ diff --git a/src/ui/util.c b/src/ui/util.c index 9a98d07b..553d9078 100644 --- a/src/ui/util.c +++ b/src/ui/util.c @@ -1175,6 +1175,10 @@ iWidget *makePreferences_Widget(void) { } /* Network. */ { appendTwoColumnPage_(tabs, "Network", '5', &headings, &values); + addChild_Widget(headings, iClob(makeHeading_Widget("Search URL:"))); + setId_Widget(addChild_Widget(values, iClob(new_InputWidget(0))), "prefs.searchurl"); + addChild_Widget(headings, iClob(makeHeading_Widget("Decode URLs:"))); + addChild_Widget(values, iClob(makeToggle_Widget("prefs.decodeurls"))); addChild_Widget(headings, iClob(makeHeading_Widget("Cache size:"))); iWidget *cacheGroup = new_Widget(); { iInputWidget *cache = new_InputWidget(4); @@ -1183,8 +1187,6 @@ iWidget *makePreferences_Widget(void) { addChildFlags_Widget(cacheGroup, iClob(new_LabelWidget("MB", NULL)), frameless_WidgetFlag); } addChildFlags_Widget(values, iClob(cacheGroup), arrangeHorizontal_WidgetFlag | arrangeSize_WidgetFlag); - addChild_Widget(headings, iClob(makeHeading_Widget("Decode URLs:"))); - addChild_Widget(values, iClob(makeToggle_Widget("prefs.decodeurls"))); makeTwoColumnHeading_("PROXIES", headings, values); addChild_Widget(headings, iClob(makeHeading_Widget("Gemini proxy:"))); setId_Widget(addChild_Widget(values, iClob(new_InputWidget(0))), "prefs.proxy.gemini"); @@ -1201,6 +1203,7 @@ iWidget *makePreferences_Widget(void) { resizeToLargestPage_Widget(tabs); arrange_Widget(dlg); /* Set input field sizes. */ { + expandInputFieldWidth_(findChild_Widget(tabs, "prefs.searchurl")); expandInputFieldWidth_(findChild_Widget(tabs, "prefs.downloads")); expandInputFieldWidth_(findChild_Widget(tabs, "prefs.proxy.gemini")); expandInputFieldWidth_(findChild_Widget(tabs, "prefs.proxy.gopher")); diff --git a/src/ui/window.c b/src/ui/window.c index cd813acb..563d57ae 100644 --- a/src/ui/window.c +++ b/src/ui/window.c @@ -47,6 +47,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include #include +#include #include #include #include @@ -419,9 +420,14 @@ static iBool handleNavBarCommands_(iWidget *navBar, const char *cmd) { !isFocused_Widget(findWidget_App("lookup"))) { iString *newUrl = copy_String(text_InputWidget(url)); trim_String(newUrl); - postCommandf_App( - "open url:%s", - cstr_String(absoluteUrl_String(&iStringLiteral(""), collect_String(newUrl)))); + if (!isEmpty_String(&prefs_App()->searchUrl) && !isLikelyUrl_String(newUrl)) { + postCommandf_App("open url:%s", cstr_String(searchQueryUrl_App(newUrl))); + } + else { + postCommandf_App( + "open url:%s", + cstr_String(absoluteUrl_String(&iStringLiteral(""), collect_String(newUrl)))); + } return iTrue; } } @@ -1168,7 +1174,7 @@ static iBool handleWindowEvent_Window_(iWindow *d, const SDL_WindowEvent *ev) { //updateRootSize_Window_(d, iTrue); invalidate_Window_(d); d->isMinimized = iFalse; - //printf("restored %d\n", snap_Window(d)); fflush(stdout); + printf("restored %d\n", snap_Window(d)); fflush(stdout); return iTrue; case SDL_WINDOWEVENT_MINIMIZED: d->isMinimized = iTrue; -- cgit v1.2.3