Skip to content

Commit 45e078d

Browse files
committed
Add app path customization to the GTK backend.
1 parent 2465edf commit 45e078d

File tree

3 files changed

+73
-12
lines changed

3 files changed

+73
-12
lines changed

changes/3482.bugfix.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
The GTK backend now respects XDG app path environment variables.

gtk/src/toga_gtk/paths.py

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import os
12
from pathlib import Path
23

34
from toga import App
@@ -7,14 +8,22 @@ class Paths:
78
def __init__(self, interface):
89
self.interface = interface
910

11+
def _get_root(self, envvar, default):
12+
custom_root = os.getenv(envvar)
13+
return Path(custom_root) if custom_root else Path.home() / default
14+
1015
def get_config_path(self):
11-
return Path.home() / ".config" / App.app.app_name
16+
root = self._get_root("XDG_CONFIG_HOME", ".config")
17+
return root / App.app.app_name
1218

1319
def get_data_path(self):
14-
return Path.home() / ".local/share" / App.app.app_name
20+
root = self._get_root("XDG_DATA_HOME", ".local/share")
21+
return root / App.app.app_name
1522

1623
def get_cache_path(self):
17-
return Path.home() / ".cache" / App.app.app_name
24+
root = self._get_root("XDG_CACHE_HOME", ".cache")
25+
return root / App.app.app_name
1826

1927
def get_logs_path(self):
20-
return Path.home() / ".local/state" / App.app.app_name / "log"
28+
root = self._get_root("XDG_STATE_HOME", ".local/state")
29+
return root / App.app.app_name / "log"

gtk/tests_backend/app.py

Lines changed: 59 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import os
2+
import tempfile
23
from contextlib import contextmanager
34
from pathlib import Path
45

@@ -31,16 +32,66 @@ def is_cursor_visible(self):
3132

3233
@contextmanager
3334
def prepare_paths(self, *, custom):
34-
if custom:
35-
pytest.xfail("This backend doesn't implement app path customization.")
36-
37-
yield {
38-
"config": Path.home() / ".config/testbed",
39-
"data": Path.home() / ".local/share/testbed",
40-
"cache": Path.home() / ".cache/testbed",
41-
"logs": Path.home() / ".local/state/testbed/log",
35+
# Backup environment variables for later restoration
36+
backup = {
37+
"XDG_CONFIG_HOME": os.getenv("XDG_CONFIG_HOME"),
38+
"XDG_DATA_HOME": os.getenv("XDG_DATA_HOME"),
39+
"XDG_CACHE_HOME": os.getenv("XDG_CACHE_HOME"),
40+
"XDG_STATE_HOME": os.getenv("XDG_STATE_HOME"),
4241
}
4342

43+
try:
44+
if custom:
45+
# This will be cleaned up later
46+
temp_custom_dir = tempfile.TemporaryDirectory()
47+
48+
custom_root = Path(temp_custom_dir.name)
49+
app_paths = {
50+
"config": custom_root / "config",
51+
"data": custom_root / "data",
52+
"cache": custom_root / "cache",
53+
"state": custom_root / "state",
54+
}
55+
56+
# Set the custom paths
57+
os.environ["XDG_CONFIG_HOME"] = str(app_paths["config"])
58+
os.environ["XDG_DATA_HOME"] = str(app_paths["data"])
59+
os.environ["XDG_CACHE_HOME"] = str(app_paths["cache"])
60+
os.environ["XDG_STATE_HOME"] = str(app_paths["state"])
61+
else:
62+
# Delete existing environment variables to replicate the
63+
# default state.
64+
for envvar in backup:
65+
if envvar in os.environ:
66+
del os.environ[envvar]
67+
68+
# The default paths
69+
app_paths = {
70+
"config": Path.home() / ".config",
71+
"data": Path.home() / ".local/share",
72+
"cache": Path.home() / ".cache",
73+
"state": Path.home() / ".local/state",
74+
}
75+
76+
yield {
77+
"config": app_paths["config"] / "testbed",
78+
"data": app_paths["data"] / "testbed",
79+
"cache": app_paths["cache"] / "testbed",
80+
"logs": app_paths["state"] / "testbed" / "log",
81+
}
82+
finally:
83+
# Restore environment variables
84+
for envvar, value in backup.items():
85+
if value is not None:
86+
os.environ[envvar] = value
87+
else:
88+
if envvar in os.environ:
89+
del os.environ[envvar]
90+
91+
# Clean up temporary custom directory if it was created
92+
if custom:
93+
temp_custom_dir.cleanup()
94+
4495
def unhide(self):
4596
pytest.xfail("This platform doesn't have an app level unhide.")
4697

0 commit comments

Comments
 (0)