Skip to content

Commit 1c7d339

Browse files
committed
2 parents bca92b8 + 195c43f commit 1c7d339

8 files changed

Lines changed: 156 additions & 7 deletions

File tree

README.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -178,9 +178,11 @@ sudo xbps-install meson ninja pkg-config git \
178178
polkit-devel librsvg-devel libqalculate-devel libxml2-devel jemalloc-devel
179179
```
180180

181-
Vendored dependencies, with no system package needed: `Wuffs`, `tomlplusplus`,
181+
Vendored dependencies, with no system package needed: `Wuffs`,
182182
`nlohmann/json`, `Luau`, `dr_wav`, `fzy`, `stb_image_resize2`, and Material Color Utilities.
183183

184+
Dependencies that are vendored by default, with a meson option to instead use the system package: `tomlplusplus`
185+
184186
System packages required beyond the Wayland/GL stack: `libwebp` handles WebP decoding and thumbnail encoding. Wuffs
185187
handles the other supported raster image formats. `libqalculate` powers the launcher calculator (arithmetic, unit and
186188
currency conversion).

meson.build

Lines changed: 39 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -177,6 +177,15 @@ stb_dep = declare_dependency(
177177
include_directories: include_directories('third_party/stb', is_system: true),
178178
)
179179

180+
# ── Vendored: tomlplusplus (header-only) ─────────────────────────────────
181+
if get_option('system_tomlplusplus')
182+
tomlplusplus_dep = dependency('tomlplusplus')
183+
else
184+
tomlplusplus_dep = declare_dependency(
185+
include_directories: include_directories('third_party/tomlplusplus', is_system: true),
186+
)
187+
endif
188+
180189
# ── Vendored: md4c (CommonMark parser) ───────────────────────────────────────
181190
_md4c_lib = static_library('md4c',
182191
'third_party/md4c/md4c.c',
@@ -875,7 +884,6 @@ endif
875884
# ── Include directories ────────────────────────────────────────────────────────
876885
_noctalia_inc = [
877886
include_directories('src'),
878-
include_directories('third_party/tomlplusplus', is_system: true),
879887
include_directories('third_party/wuffs', is_system: true),
880888
# nlohmann is header-only and uses GCC extensions in some paths; treat as system.
881889
include_directories('third_party/nlohmann', is_system: true),
@@ -917,6 +925,7 @@ noctalia_exe = executable('noctalia',
917925
mcu_dep,
918926
libxml2_dep,
919927
stb_dep,
928+
tomlplusplus_dep,
920929
md4c_dep,
921930
libwebp_dep,
922931
luau_dep,
@@ -1057,6 +1066,17 @@ battery_hook_state_test = executable('battery_hook_state_test',
10571066

10581067
test('battery_hook_state', battery_hook_state_test)
10591068

1069+
hook_manager_test = executable('hook_manager_test',
1070+
sources: files(
1071+
'tests/hook_manager_test.cpp',
1072+
'src/hooks/hook_manager.cpp',
1073+
'src/core/log.cpp',
1074+
),
1075+
include_directories: _noctalia_inc,
1076+
)
1077+
1078+
test('hook_manager', hook_manager_test)
1079+
10601080
desktop_entry_launch_test = executable('desktop_entry_launch_test',
10611081
sources: files(
10621082
'tests/desktop_entry_launch_test.cpp',
@@ -1269,6 +1289,9 @@ plugin_manifest_test = executable('plugin_manifest_test',
12691289
'src/core/log.cpp',
12701290
),
12711291
include_directories: _noctalia_inc,
1292+
dependencies: [
1293+
tomlplusplus_dep,
1294+
],
12721295
)
12731296

12741297
test('plugin_manifest', plugin_manifest_test)
@@ -1308,7 +1331,10 @@ config_schema_roundtrip_test = executable('config_schema_roundtrip_test',
13081331
'src/core/key_chord.cpp',
13091332
),
13101333
include_directories: _noctalia_inc,
1311-
dependencies: [xkbcommon_dep],
1334+
dependencies: [
1335+
xkbcommon_dep,
1336+
tomlplusplus_dep,
1337+
],
13121338
)
13131339

13141340
test('config_schema_roundtrip', config_schema_roundtrip_test)
@@ -1327,7 +1353,10 @@ config_widget_test = executable('config_widget_test',
13271353
'src/core/key_chord.cpp',
13281354
),
13291355
include_directories: _noctalia_inc,
1330-
dependencies: [xkbcommon_dep],
1356+
dependencies: [
1357+
xkbcommon_dep,
1358+
tomlplusplus_dep,
1359+
],
13311360
)
13321361

13331362
test('config_widget', config_widget_test)
@@ -1347,7 +1376,10 @@ config_path_resolution_test = executable('config_path_resolution_test',
13471376
'src/core/key_chord.cpp',
13481377
),
13491378
include_directories: _noctalia_inc,
1350-
dependencies: [xkbcommon_dep],
1379+
dependencies: [
1380+
xkbcommon_dep,
1381+
tomlplusplus_dep,
1382+
],
13511383
)
13521384

13531385
test('config_path_resolution', config_path_resolution_test)
@@ -1373,6 +1405,9 @@ state_store_test = executable('state_store_test',
13731405
'src/core/log.cpp',
13741406
),
13751407
include_directories: _noctalia_inc,
1408+
dependencies: [
1409+
tomlplusplus_dep,
1410+
],
13761411
)
13771412

13781413
test('state_store', state_store_test)

meson_options.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,3 @@
11
option('jemalloc', type: 'feature', value: 'auto', description: 'Use jemalloc on glibc builds')
22
option('tests', type: 'feature', value: 'auto', description: 'Build unit tests (auto: on for unsanitized debug builds)')
3+
option('system_tomlplusplus', type: 'boolean', value: false, description: 'Use system tomlplusplus instead of vendored')

src/core/toml.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,5 +4,5 @@
44
#pragma GCC diagnostic ignored "-Wshadow"
55
#pragma GCC diagnostic ignored "-Wconversion"
66
#pragma GCC diagnostic ignored "-Wsign-conversion"
7-
#include <toml.hpp>
7+
#include <toml++/toml.hpp>
88
#pragma GCC diagnostic pop

src/shell/greeter/greeter_appearance_sync.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@
2222
#include <string>
2323
#include <string_view>
2424
#include <system_error>
25-
#include <toml.hpp>
25+
#include <toml++/toml.hpp>
2626
#include <vector>
2727

2828
namespace {

tests/hook_manager_test.cpp

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
#include "hooks/hook_manager.h"
2+
3+
#include <cassert>
4+
#include <cstdlib>
5+
#include <string>
6+
#include <string_view>
7+
#include <vector>
8+
9+
std::string_view hookKindKey(HookKind kind) {
10+
if (kind == HookKind::WallpaperChanged) {
11+
return "wallpaper_changed";
12+
}
13+
return "unknown";
14+
}
15+
16+
namespace {
17+
18+
const char* envOrEmpty(const char* name) {
19+
if (const char* value = std::getenv(name)) {
20+
return value;
21+
}
22+
return "";
23+
}
24+
25+
} // namespace
26+
27+
int main() {
28+
constexpr const char* kPathName = "NOCTALIA_WALLPAPER_PATH";
29+
constexpr const char* kConnectorName = "NOCTALIA_WALLPAPER_CONNECTOR";
30+
31+
::unsetenv(kPathName);
32+
::unsetenv(kConnectorName);
33+
34+
HookManager hooks;
35+
HooksConfig config;
36+
config.commands[static_cast<std::size_t>(HookKind::WallpaperChanged)] = {"record-wallpaper-hook"};
37+
hooks.reload(config);
38+
39+
std::vector<std::string> commands;
40+
std::string pathSeen;
41+
std::string connectorSeen;
42+
hooks.setCommandRunner([&](const std::string& command) {
43+
commands.push_back(command);
44+
pathSeen = envOrEmpty(kPathName);
45+
connectorSeen = envOrEmpty(kConnectorName);
46+
return true;
47+
});
48+
49+
hooks.fire(HookKind::WallpaperChanged, {{kPathName, "/tmp/noctalia test/wallpaper.png"}, {kConnectorName, "DP-1"}});
50+
51+
assert(commands.size() == 1);
52+
assert(commands[0] == "record-wallpaper-hook");
53+
assert(pathSeen == "/tmp/noctalia test/wallpaper.png");
54+
assert(connectorSeen == "DP-1");
55+
assert(std::getenv(kPathName) == nullptr);
56+
assert(std::getenv(kConnectorName) == nullptr);
57+
58+
return 0;
59+
}

tests/process_test.cpp

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,15 @@
44
#include <condition_variable>
55
#include <cstdio>
66
#include <cstdlib>
7+
#include <filesystem>
8+
#include <fstream>
9+
#include <iterator>
710
#include <mutex>
811
#include <optional>
912
#include <string>
1013
#include <string_view>
14+
#include <thread>
15+
#include <unistd.h>
1116
#include <utility>
1217

1318
namespace {
@@ -19,6 +24,19 @@ namespace {
1924
return condition;
2025
}
2126

27+
std::string shellQuote(const std::string& value) {
28+
std::string quoted = "'";
29+
for (const char ch : value) {
30+
if (ch == '\'') {
31+
quoted += "'\\''";
32+
} else {
33+
quoted += ch;
34+
}
35+
}
36+
quoted += "'";
37+
return quoted;
38+
}
39+
2240
bool capturedAsyncDeliversCallbacksAndResult() {
2341
std::mutex mutex;
2442
std::condition_variable cv;
@@ -122,6 +140,39 @@ namespace {
122140
return ok;
123141
}
124142

143+
bool detachedAsyncInheritsLaunchEnvironment() {
144+
const std::filesystem::path outPath =
145+
std::filesystem::temp_directory_path() / ("noctalia_process_env_test_" + std::to_string(::getpid()));
146+
std::error_code ec;
147+
std::filesystem::remove(outPath, ec);
148+
149+
::setenv("NOCTALIA_WALLPAPER_PATH", "/tmp/noctalia test/wallpaper.png", 1);
150+
::setenv("NOCTALIA_WALLPAPER_CONNECTOR", "DP-1", 1);
151+
152+
const std::string command = "printf '%s\\n%s' \"$NOCTALIA_WALLPAPER_PATH\" \"$NOCTALIA_WALLPAPER_CONNECTOR\" > "
153+
+ shellQuote(outPath.string());
154+
const bool launched = process::runAsync(command);
155+
::unsetenv("NOCTALIA_WALLPAPER_PATH");
156+
::unsetenv("NOCTALIA_WALLPAPER_CONNECTOR");
157+
158+
if (!expect(launched, "detached async env command did not launch")) {
159+
return false;
160+
}
161+
162+
std::string contents;
163+
for (int i = 0; i < 50; ++i) {
164+
std::ifstream in(outPath);
165+
contents.assign(std::istreambuf_iterator<char>(in), std::istreambuf_iterator<char>());
166+
if (contents == "/tmp/noctalia test/wallpaper.png\nDP-1") {
167+
break;
168+
}
169+
std::this_thread::sleep_for(std::chrono::milliseconds(20));
170+
}
171+
172+
std::filesystem::remove(outPath, ec);
173+
return expect(contents == "/tmp/noctalia test/wallpaper.png\nDP-1", "detached async env was not visible in child");
174+
}
175+
125176
bool commandExistsRejectsDirectories() {
126177
bool ok = true;
127178
ok =
@@ -142,6 +193,7 @@ int main() {
142193
ok = capturedAsyncDeliversCallbacksAndResult() && ok;
143194
ok = capturedAsyncDeliversCompletionOnly() && ok;
144195
ok = syncAppliesEnvOverrides() && ok;
196+
ok = detachedAsyncInheritsLaunchEnvironment() && ok;
145197
ok = commandExistsRejectsDirectories() && ok;
146198
return ok ? 0 : 1;
147199
}

0 commit comments

Comments
 (0)