diff --git a/CMakeLists.txt b/CMakeLists.txt

index a3687e9c..095a279f 100644

--- a/CMakeLists.txt

+++ b/CMakeLists.txt

@@ -31,6 +31,7 @@ option (ENABLE_KERNING "Enable kerning in font renderer (slower)" ON)

option (ENABLE_RESOURCE_EMBED "Embed resources inside the executable" OFF)

option (ENABLE_WINDOWPOS_FIX "Set position after showing window (workaround for SDL bug)" OFF)

option (ENABLE_IDLE_SLEEP "While idle, sleep in the main thread instead of waiting for events" ON)

+option (ENABLE_DOWNLOAD_EDIT "Allow changing the Downloads directory" ON)



include (BuildType.cmake)

include (res/Embed.cmake)

@@ -226,6 +227,9 @@ endif ()

if (ENABLE_IDLE_SLEEP)

 target_compile_definitions (app PUBLIC LAGRANGE_IDLE_SLEEP=1)

endif ()

+if (ENABLE_DOWNLOAD_EDIT)

+ target_compile_definitions (app PUBLIC LAGRANGE_DOWNLOAD_EDIT=1)

+endif ()

target_link_libraries (app PUBLIC the_Foundation::the_Foundation)

target_link_libraries (app PUBLIC ${SDL2_LDFLAGS})

if (APPLE)

diff --git a/src/app.c b/src/app.c

index 10e6d4ee..195b3b43 100644

--- a/src/app.c

+++ b/src/app.c

@@ -83,17 +83,17 @@ static const char *dataDir_App_ = "~/AppData/Roaming/fi.skyjake.Lagrange";

#endif

#if defined (iPlatformLinux) || defined (iPlatformOther)

#define EMB_BIN "../../share/lagrange/resources.lgr"

-static const char *dataDir_App_ = "~/.config/lagrange";

+static const char *defaultDataDir_App_ = "~/.config/lagrange";

#endif

#if defined (LAGRANGE_EMB_BIN) /* specified in build config */

undef EMB_BIN

define EMB_BIN LAGRANGE_EMB_BIN

#endif

#define EMB_BIN2 "../resources.lgr" /* fallback from build/executable dir */

-static const char *prefsFileName_App_ = "prefs.cfg";

-static const char *oldStateFileName_App_ = "state.binary";

-static const char *stateFileName_App_ = "state.lgr";

-static const char *downloadDir_App_ = "~/Downloads";

+static const char *prefsFileName_App_ = "prefs.cfg";

+static const char *oldStateFileName_App_ = "state.binary";

+static const char *stateFileName_App_ = "state.lgr";

+static const char *defaultDownloadDir_App_ = "~/Downloads";



static const int idleThreshold_App_ = 1000; /* ms */



@@ -213,14 +213,42 @@ static iString *serializePrefs_App_(const iApp *d) {

 return str;

}



+static const char *dataDir_App_(void) {

+#if defined (iPlatformLinux) || defined (iPlatformOther)

+ const char *configHome = getenv("XDG_CONFIG_HOME");

+ if (configHome) {

+ return concatPath_CStr(configHome, "lagrange");

+ }

+#endif

+ return defaultDataDir_App_;

+}

+

+static const char *downloadDir_App_(void) {

+#if defined (iPlatformLinux) || defined (iPlatformOther)

+ /* Parse user-dirs.dirs using the xdg-user-dir tool. */

+ iProcess *proc = iClob(new_Process());

+ setArguments_Process(

+ proc, iClob(newStringsCStr_StringList("/usr/bin/env", "xdg-user-dir", "DOWNLOAD", NULL)));

+ if (start_Process(proc)) {

+ iString *path = collect_String(newLocal_String(collect_Block(

+ readOutputUntilClosed_Process(proc))));

+ trim_String(path);

+ if (!isEmpty_String(path)) {

+ return cstr_String(path);

+ }

+ }

+#endif

+ return defaultDownloadDir_App_;

+}

+

static const iString *prefsFileName_(void) {

- return collect_String(concatCStr_Path(&iStringLiteral(dataDir_App_), prefsFileName_App_));

+ return collectNewCStr_String(concatPath_CStr(dataDir_App_(), prefsFileName_App_));

}



static void loadPrefs_App_(iApp *d) {

 iUnused(d);

 /* Create the data dir if it doesn't exist yet. */

- makeDirs_Path(collectNewCStr_String(dataDir_App_));

+ makeDirs_Path(collectNewCStr_String(dataDir_App_()));

 iFile *f = new_File(prefsFileName_());

 if (open_File(f, readOnly_FileMode | text_FileMode)) {

     iString *str = readString_File(f);

@@ -267,8 +295,8 @@ static const char *magicTabDocument_App_ = "tabd";



static iBool loadState_App_(iApp *d) {

 iUnused(d);

- const char *oldPath = concatPath_CStr(dataDir_App_, oldStateFileName_App_);

- const char *path = concatPath_CStr(dataDir_App_, stateFileName_App_);

+ const char *oldPath = concatPath_CStr(dataDir_App_(), oldStateFileName_App_);

+ const char *path = concatPath_CStr(dataDir_App_(), stateFileName_App_);

 iFile *f = iClob(newCStr_File(fileExistsCStr_FileInfo(path) ? path : oldPath));

 if (open_File(f, readOnly_FileMode)) {

     char magic[4];

@@ -323,7 +351,7 @@ iObjectList *listDocuments_App(void) {

static void saveState_App_(const iApp *d) {

 iUnused(d);

 trimCache_App();

- iFile *f = newCStr_File(concatPath_CStr(dataDir_App_, stateFileName_App_));

+ iFile *f = newCStr_File(concatPath_CStr(dataDir_App_(), stateFileName_App_));

 if (open_File(f, writeOnly_FileMode)) {

     writeData_File(f, magicState_App_, 4);

     writeU32_File(f, latest_FileVersion); /* version */

@@ -348,7 +376,7 @@ static uint32_t checkAsleep_App_(uint32_t interval, void *param) {

#endif



static void init_App_(iApp *d, int argc, char **argv) {

- const iBool isFirstRun = !fileExistsCStr_FileInfo(cleanedPath_CStr(dataDir_App_));

+ const iBool isFirstRun = !fileExistsCStr_FileInfo(cleanedPath_CStr(dataDir_App_()));

 d->isFinishedLaunching = iFalse;

 d->launchCommands      = new_StringList();

 iZap(d->lastDropTime);

@@ -385,12 +413,12 @@ static void init_App_(iApp *d, int argc, char **argv) {

 }

#endif

 init_Prefs(&d->prefs);

- setCStr_String(&d->prefs.downloadDir, downloadDir_App_);

+ setCStr_String(&d->prefs.downloadDir, downloadDir_App_());

 d->isRunning         = iFalse;

 d->window            = NULL;

 set_Atomic(&d->pendingRefresh, iFalse);

 d->mimehooks         = new_MimeHooks();

- d->certs = new_GmCerts(dataDir_App_);

+ d->certs = new_GmCerts(dataDir_App_());

 d->visited           = new_Visited();

 d->bookmarks         = new_Bookmarks();

 d->tabEnum           = 0; /* generates unique IDs for tab pages */

@@ -405,10 +433,10 @@ static void init_App_(iApp *d, int argc, char **argv) {

#endif

 init_Keys();

 loadPrefs_App_(d);

- load_Keys(dataDir_App_);

- load_Visited(d->visited, dataDir_App_);

- load_Bookmarks(d->bookmarks, dataDir_App_);

- load_MimeHooks(d->mimehooks, dataDir_App_);

+ load_Keys(dataDir_App_());

+ load_Visited(d->visited, dataDir_App_());

+ load_Bookmarks(d->bookmarks, dataDir_App_());

+ load_MimeHooks(d->mimehooks, dataDir_App_());

 if (isFirstRun) {

     /* Create the default bookmarks for a quick start. */

     add_Bookmarks(d->bookmarks,

@@ -434,7 +462,7 @@ static void init_App_(iApp *d, int argc, char **argv) {

 }

#endif

 d->window = new_Window(d->initialWindowRect);

- init_Feeds(dataDir_App_);

+ init_Feeds(dataDir_App_());

 /* Widget state init. */

 processEvents_App(postedEventsOnly_AppEventMode);

 if (!loadState_App_(d)) {

@@ -469,13 +497,13 @@ static void init_App_(iApp *d, int argc, char **argv) {

static void deinit_App(iApp *d) {

 saveState_App_(d);

 deinit_Feeds();

- save_Keys(dataDir_App_);

+ save_Keys(dataDir_App_());

 deinit_Keys();

 savePrefs_App_(d);

 deinit_Prefs(&d->prefs);

- save_Bookmarks(d->bookmarks, dataDir_App_);

+ save_Bookmarks(d->bookmarks, dataDir_App_());

 delete_Bookmarks(d->bookmarks);

- save_Visited(d->visited, dataDir_App_);

+ save_Visited(d->visited, dataDir_App_());

 delete_Visited(d->visited);

 delete_GmCerts(d->certs);

 save_MimeHooks(d->mimehooks);

@@ -494,7 +522,7 @@ const iString *execPath_App(void) {

}



const iString *dataDir_App(void) {

- return collect_String(cleanedCStr_Path(dataDir_App_));

+ return collect_String(cleanedCStr_Path(dataDir_App_()));

}



const iString *downloadDir_App(void) {

@@ -854,8 +882,10 @@ static iBool handlePrefsCommands_(iWidget *d, const char *cmd) {

 if (equal_Command(cmd, "prefs.dismiss") || equal_Command(cmd, "preferences")) {

     setUiScale_Window(get_Window(),

                       toFloat_String(text_InputWidget(findChild_Widget(d, "prefs.uiscale"))));

+#if defined (LAGRANGE_DOWNLOAD_EDIT)

     postCommandf_App("downloads path:%s",

                      cstr_String(text_InputWidget(findChild_Widget(d, "prefs.downloads"))));

+#endif

     postCommandf_App("window.retain arg:%d",

                      isSelected_Widget(findChild_Widget(d, "prefs.retainwindow")));

     postCommandf_App("smoothscroll arg:%d",

@@ -1449,7 +1479,7 @@ iBool handleCommand_App(const char *cmd) {

     return iTrue;

 }

 else if (equal_Command(cmd, "bookmarks.changed")) {

- save_Bookmarks(d->bookmarks, dataDir_App_);

+ save_Bookmarks(d->bookmarks, dataDir_App_());

     return iFalse;

 }

 else if (equal_Command(cmd, "feeds.refresh")) {

@@ -1468,7 +1498,7 @@ iBool handleCommand_App(const char *cmd) {

     return iFalse;

 }

 else if (equal_Command(cmd, "visited.changed")) {

- save_Visited(d->visited, dataDir_App_);

+ save_Visited(d->visited, dataDir_App_());

     return iFalse;

 }

 else if (equal_Command(cmd, "ident.new")) {

diff --git a/src/ui/inputwidget.c b/src/ui/inputwidget.c

index 3f799e3c..1674040b 100644

--- a/src/ui/inputwidget.c

+++ b/src/ui/inputwidget.c

@@ -223,6 +223,7 @@ static void updateBuffered_InputWidget_(iInputWidget *d) {

}



void setText_InputWidget(iInputWidget *d, const iString *text) {

+ if (!d) return;

 if (d->inFlags & isUrl_InputWidgetFlag) {

     /* If user wants URLs encoded, also Punycode the domain. */

     if (!prefs_App()->decodeUserVisibleURLs) {

diff --git a/src/ui/util.c b/src/ui/util.c

index 4d5ed916..d64a93b6 100644

--- a/src/ui/util.c

+++ b/src/ui/util.c

@@ -1023,6 +1023,7 @@ static void makeTwoColumnHeading_(const char *title, iWidget *headings, iWidget

}



static void expandInputFieldWidth_(iInputWidget *input) {

+ if (!input) return;

 iWidget *page = as_Widget(input)->parent->parent->parent->parent; /* tabs > page > values > input */

 as_Widget(input)->rect.size.x =

     right_Rect(bounds_Widget(page)) - left_Rect(bounds_Widget(constAs_Widget(input)));

@@ -1056,8 +1057,10 @@ iWidget *makePreferences_Widget(void) {

 iWidget *headings, *values;

 /* General preferences. */ {

     appendTwoColumnPage_(tabs, "General", '1', &headings, &values);

+#if defined (LAGRANGE_DOWNLOAD_EDIT)

     addChild_Widget(headings, iClob(makeHeading_Widget("Downloads folder:")));

     setId_Widget(addChild_Widget(values, iClob(new_InputWidget(0))), "prefs.downloads");

+#endif

     addChild_Widget(headings, iClob(makeHeading_Widget("Show URL on hover:")));

     addChild_Widget(values, iClob(makeToggle_Widget("prefs.hoverlink")));

     addChild_Widget(headings, iClob(makeHeading_Widget("Smooth scrolling:")));

Proxy Information
Original URL
gemini://git.skyjake.fi/lagrange/dev/pcdiff/3190f16e20bfe03d83cead40d4dc220d619ec924
Status Code
Success (20)
Meta
text/plain
Capsule Response Time
29.235063 milliseconds
Gemini-to-HTML Time
4.877243 milliseconds

This content has been proxied by September (ba2dc).