Skip to content

Commit 467cee7

Browse files
authored
Rewrite of the Base.getSettingsFolder() and Platform.getSettingsFolder() (#1335)
* Rewrite of the `Base.getSettingsFolder()` and `Platform.getSettingsFolder()` Rewrote both function so they fit into a single file, negating the need for hopping around when looking into what this functionality does. Also rewrote it so it is no longer generates random awt windows through the `Messages` class * Fixed issue with missing / * Added both options for overrides - Added the previous settings override in base again - Added a system property to override the settings folder within tests * Add support for portable settings detection Introduces logic to detect a preferences.txt file in the same folder as the running executable or jar. If found, settings are loaded from this location, improving portability and allowing users to override default settings without modifying system directories.
1 parent ef226c9 commit 467cee7

File tree

11 files changed

+299
-223
lines changed

11 files changed

+299
-223
lines changed

app/src/processing/app/Base.java

Lines changed: 45 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -2212,29 +2212,54 @@ static public InputStream getLibStream(String filename) throws IOException {
22122212
* something similar on Windows, a dot folder on Linux.) Removed this as a
22132213
* preference for 3.0a3 because we need this to be stable, but adding back
22142214
* for 4.0 beta 4 so that folks can do 'portable' versions again.
2215+
*
2216+
* @deprecated use processing.utils.Settings.getFolder() instead, this method will invoke AWT
22152217
*/
22162218
static public File getSettingsFolder() {
2217-
File settingsFolder = null;
2218-
2219-
try {
2220-
settingsFolder = Platform.getSettingsFolder();
2221-
2222-
// create the folder if it doesn't exist already
2223-
if (!settingsFolder.exists()) {
2224-
if (!settingsFolder.mkdirs()) {
2225-
Messages.showError("Settings issues",
2226-
"Processing cannot run because it could not\n" +
2227-
"create a folder to store your settings at\n" +
2228-
settingsFolder, null);
2229-
}
2219+
var override = getSettingsOverride();
2220+
if (override != null) {
2221+
return override;
22302222
}
2231-
} catch (Exception e) {
2232-
Messages.showTrace("An rare and unknowable thing happened",
2233-
"Could not get the settings folder. Please report:\n" +
2234-
"http://github.com/processing/processing/issues/new",
2235-
e, true);
2236-
}
2237-
return settingsFolder;
2223+
try {
2224+
return processing.utils.Settings.getFolder();
2225+
} catch (processing.utils.Settings.SettingsFolderException e) {
2226+
switch (e.getType()) {
2227+
case COULD_NOT_CREATE_FOLDER -> Messages.showError("Settings issues",
2228+
"""
2229+
Processing cannot run because it could not
2230+
create a folder to store your settings at
2231+
""" + e.getMessage(), null);
2232+
case WINDOWS_APPDATA_NOT_FOUND -> Messages.showError("Settings issues",
2233+
"""
2234+
Processing cannot run because it could not
2235+
find the AppData or LocalAppData folder on your system.
2236+
""", null);
2237+
case MACOS_LIBRARY_FOLDER_NOT_FOUND -> Messages.showError("Settings issues",
2238+
"""
2239+
Processing cannot run because it could not
2240+
find the Library folder on your system.
2241+
""", null);
2242+
case LINUX_CONFIG_FOLDER_NOT_FOUND -> Messages.showError("Settings issues",
2243+
"""
2244+
Processing cannot run because either your
2245+
XDG_CONFIG_HOME or SNAP_USER_COMMON is set
2246+
but the folder does not exist.
2247+
""", null);
2248+
case LINUX_SUDO_USER_ERROR -> Messages.showError("Settings issues",
2249+
"""
2250+
Processing cannot run because it was started
2251+
with sudo and Processing could not resolve
2252+
the original users home directory.
2253+
""", null);
2254+
default -> Messages.showTrace("An rare and unknowable thing happened",
2255+
"""
2256+
Could not get the settings folder. Please report:
2257+
http://github.com/processing/processing4/issues/new
2258+
""",
2259+
e, true);
2260+
}
2261+
}
2262+
throw new RuntimeException("Unreachable code in Base.getSettingsFolder()");
22382263
}
22392264

22402265

app/src/processing/app/Platform.java

Lines changed: 2 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@
4040
import java.util.Map;
4141

4242

43-
public class Platform {
43+
public class Platform extends processing.utils.Platform {
4444
static DefaultPlatform inst;
4545

4646
/*
@@ -136,12 +136,7 @@ static public float getSystemZoom() {
136136
}
137137

138138

139-
static public File getSettingsFolder() throws Exception {
140-
return inst.getSettingsFolder();
141-
}
142-
143-
144-
static public File getDefaultSketchbookFolder() throws Exception {
139+
static public File getDefaultSketchbookFolder() throws Exception {
145140
return inst.getDefaultSketchbookFolder();
146141
}
147142

@@ -303,28 +298,7 @@ static public int getIndex(String platformName) {
303298
// the MACOSX constant would instead read as the LINUX constant.
304299

305300

306-
/**
307-
* returns true if Processing is running on a Mac OS X machine.
308-
*/
309-
static public boolean isMacOS() {
310-
return System.getProperty("os.name").contains("Mac"); //$NON-NLS-1$ //$NON-NLS-2$
311-
}
312-
313301

314-
/**
315-
* returns true if running on windows.
316-
*/
317-
static public boolean isWindows() {
318-
return System.getProperty("os.name").contains("Windows"); //$NON-NLS-1$ //$NON-NLS-2$
319-
}
320-
321-
322-
/**
323-
* true if running on linux.
324-
*/
325-
static public boolean isLinux() {
326-
return System.getProperty("os.name").contains("Linux"); //$NON-NLS-1$ //$NON-NLS-2$
327-
}
328302

329303

330304
// . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

app/src/processing/app/Preferences.kt

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,13 @@ package processing.app
33
import androidx.compose.runtime.*
44
import kotlinx.coroutines.Dispatchers
55
import kotlinx.coroutines.launch
6+
import processing.utils.Settings
67
import java.io.File
78
import java.io.InputStream
8-
import java.nio.file.*
9-
import java.util.Properties
9+
import java.nio.file.FileSystems
10+
import java.nio.file.StandardWatchEventKinds
11+
import java.nio.file.WatchEvent
12+
import java.util.*
1013

1114

1215
const val PREFERENCES_FILE_NAME = "preferences.txt"
@@ -20,7 +23,7 @@ fun PlatformStart(){
2023
fun loadPreferences(): Properties{
2124
PlatformStart()
2225

23-
val settingsFolder = Platform.getSettingsFolder()
26+
val settingsFolder = Settings.getFolder()
2427
val preferencesFile = settingsFolder.resolve(PREFERENCES_FILE_NAME)
2528

2629
if(!preferencesFile.exists()){

app/src/processing/app/platform/DefaultPlatform.java

Lines changed: 6 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -23,24 +23,19 @@
2323

2424
package processing.app.platform;
2525

26-
import java.awt.Desktop;
27-
import java.awt.Font;
28-
import java.io.File;
29-
30-
import javax.swing.UIManager;
31-
import javax.swing.border.EmptyBorder;
32-
3326
import com.formdev.flatlaf.FlatLaf;
3427
import com.formdev.flatlaf.FlatLightLaf;
35-
import com.sun.jna.Library;
36-
import com.sun.jna.Native;
37-
3828
import processing.app.Base;
3929
import processing.app.Preferences;
4030
import processing.app.ui.Toolkit;
4131
import processing.awt.ShimAWT;
4232
import processing.core.PApplet;
4333

34+
import javax.swing.*;
35+
import javax.swing.border.EmptyBorder;
36+
import java.awt.*;
37+
import java.io.File;
38+
4439

4540
/**
4641
* Used by Base for platform-specific tweaking, for instance finding the
@@ -206,24 +201,7 @@ public void setInterfaceZoom() throws Exception {
206201
public void saveLanguage(String languageCode) { }
207202

208203

209-
/**
210-
* This function should throw an exception or return a value.
211-
* Do not return null.
212-
*/
213-
public File getSettingsFolder() throws Exception {
214-
File override = Base.getSettingsOverride();
215-
if (override != null) {
216-
return override;
217-
}
218-
219-
// If no subclass has a behavior, default to making a
220-
// ".processing" directory in the user's home directory.
221-
File home = new File(System.getProperty("user.home"));
222-
return new File(home, ".processing");
223-
}
224-
225-
226-
/**
204+
/**
227205
* @return if not overridden, a folder named "sketchbook" in user.home.
228206
* @throws Exception so that subclasses can throw a fit
229207
*/

app/src/processing/app/platform/LinuxPlatform.java

Lines changed: 3 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -22,16 +22,13 @@
2222

2323
package processing.app.platform;
2424

25-
import java.io.File;
26-
import java.awt.Desktop;
27-
import java.awt.Toolkit;
28-
2925
import processing.app.Base;
30-
import processing.app.Messages;
3126
import processing.app.Preferences;
3227
import processing.core.PApplet;
3328

3429
import javax.swing.*;
30+
import java.awt.*;
31+
import java.io.File;
3532

3633

3734
public class LinuxPlatform extends DefaultPlatform {
@@ -90,40 +87,7 @@ static public String getHomeDir(String user) throws Exception {
9087
}
9188

9289

93-
@Override
94-
public File getSettingsFolder() throws Exception {
95-
File override = Base.getSettingsOverride();
96-
if (override != null) {
97-
return override;
98-
}
99-
100-
// https://github.com/processing/processing4/issues/203
101-
// https://specifications.freedesktop.org/basedir-spec/basedir-spec-latest.html
102-
103-
File configHome = null;
104-
105-
// Check to see if the user has set a different location for their config
106-
String configHomeEnv = System.getenv("XDG_CONFIG_HOME");
107-
if (configHomeEnv != null && !configHomeEnv.isBlank()) {
108-
configHome = new File(configHomeEnv);
109-
if (!configHome.exists()) {
110-
Messages.err("XDG_CONFIG_HOME is set to " + configHomeEnv + " but does not exist.");
111-
configHome = null; // don't use non-existent folder
112-
}
113-
}
114-
String snapUserCommon = System.getenv("SNAP_USER_COMMON");
115-
if (snapUserCommon != null && !snapUserCommon.isBlank()) {
116-
configHome = new File(snapUserCommon);
117-
}
118-
// If not set properly, use the default
119-
if (configHome == null) {
120-
configHome = new File(getHomeDir(), ".config");
121-
}
122-
return new File(configHome, "processing");
123-
}
124-
125-
126-
@Override
90+
@Override
12791
public File getDefaultSketchbookFolder() throws Exception {
12892
return new File(getHomeDir(), "sketchbook");
12993
}

app/src/processing/app/platform/MacPlatform.java

Lines changed: 8 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -22,23 +22,20 @@
2222

2323
package processing.app.platform;
2424

25+
import processing.app.Base;
26+
import processing.app.Messages;
27+
import processing.app.ui.About;
28+
import processing.core.PApplet;
29+
import processing.data.StringList;
30+
31+
import javax.swing.*;
2532
import java.awt.*;
26-
import java.awt.desktop.AppReopenedEvent;
2733
import java.awt.desktop.AppReopenedListener;
2834
import java.io.File;
2935
import java.io.FileNotFoundException;
3036
import java.io.IOException;
3137
import java.net.URI;
3238

33-
import javax.swing.JMenu;
34-
import javax.swing.JMenuBar;
35-
36-
import processing.app.Base;
37-
import processing.app.Messages;
38-
import processing.app.ui.About;
39-
import processing.core.PApplet;
40-
import processing.data.StringList;
41-
4239

4340
/**
4441
* Platform handler for macOS.
@@ -112,16 +109,7 @@ public void initBase(Base base) {
112109
}
113110

114111

115-
public File getSettingsFolder() throws Exception {
116-
File override = Base.getSettingsOverride();
117-
if (override != null) {
118-
return override;
119-
}
120-
return new File(getLibraryFolder(), "Processing");
121-
}
122-
123-
124-
public File getDefaultSketchbookFolder() throws Exception {
112+
public File getDefaultSketchbookFolder() throws Exception {
125113
return new File(getDocumentsFolder(), "Processing");
126114
}
127115

@@ -144,19 +132,6 @@ public void openURL(String url) throws Exception {
144132
// . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
145133

146134

147-
// TODO I suspect this won't work much longer, since access to the user's
148-
// home directory seems verboten on more recent macOS versions [fry 191008]
149-
// However, anecdotally it seems that just using the name works,
150-
// and the localization is handled transparently. [fry 220116]
151-
// https://github.com/processing/processing4/issues/9
152-
protected String getLibraryFolder() throws FileNotFoundException {
153-
File folder = new File(System.getProperty("user.home"), "Library");
154-
if (!folder.exists()) {
155-
throw new FileNotFoundException("Folder missing: " + folder);
156-
}
157-
return folder.getAbsolutePath();
158-
}
159-
160135

161136
// TODO See above, and https://github.com/processing/processing4/issues/9
162137
protected String getDocumentsFolder() throws FileNotFoundException {

0 commit comments

Comments
 (0)