|
13 | 13 | #include "scripting/plugin_bindings.h" |
14 | 14 | #include "scripting/plugin_state_store.h" |
15 | 15 | #include "scripting/script_api_context.h" |
| 16 | +#include "system/app_identity.h" |
| 17 | +#include "system/desktop_entry.h" |
| 18 | +#include "system/icon_resolver.h" |
16 | 19 | #include "system/terminal_launch.h" |
17 | 20 | #include "time/time_format.h" |
18 | 21 | #include "util/file_utils.h" |
@@ -321,6 +324,37 @@ namespace { |
321 | 324 | return 1; |
322 | 325 | } |
323 | 326 |
|
| 327 | + // appIconPath(appIdOrIconName, sizePx?) -> absolute icon file path or nil. |
| 328 | + // Same resolution the native taskbar uses: desktop-entry lookup (id / |
| 329 | + // StartupWMClass) for the icon name, then the XDG icon-theme resolver. |
| 330 | + // Unmatched inputs are treated as raw icon names so plugins can also |
| 331 | + // resolve themed icons directly. |
| 332 | + int luau_appIconPath(lua_State* L) { |
| 333 | + size_t len = 0; |
| 334 | + const char* appId = luaL_checklstring(L, 1, &len); |
| 335 | + const int targetSize = luaL_optinteger(L, 2, 0); |
| 336 | + |
| 337 | + std::string iconName; |
| 338 | + const auto entries = desktopEntriesSnapshot(); |
| 339 | + if (const auto entry = app_identity::findDesktopEntry(std::string_view(appId, len), *entries); |
| 340 | + entry.has_value() && !entry->icon.empty()) { |
| 341 | + iconName = entry->icon; |
| 342 | + } else { |
| 343 | + iconName.assign(appId, len); |
| 344 | + } |
| 345 | + |
| 346 | + // One resolver (and icon-path cache) per script worker thread; the theme |
| 347 | + // plan it reads is shared across threads and mutex-guarded in IconResolver. |
| 348 | + static thread_local IconResolver resolver; |
| 349 | + const std::string& path = resolver.resolve(iconName, targetSize); |
| 350 | + if (path.empty()) { |
| 351 | + lua_pushnil(L); |
| 352 | + return 1; |
| 353 | + } |
| 354 | + lua_pushlstring(L, path.data(), path.size()); |
| 355 | + return 1; |
| 356 | + } |
| 357 | + |
324 | 358 | int luau_setWallpaperEnabled(lua_State* L) { |
325 | 359 | size_t len = 0; |
326 | 360 | const char* connector = luaL_checklstring(L, 1, &len); |
@@ -1137,6 +1171,7 @@ namespace { |
1137 | 1171 | {"portalAvailable", luau_portalAvailable}, |
1138 | 1172 | {"focusedOutputName", luau_focusedOutputName}, |
1139 | 1173 | {"outputs", luau_outputs}, |
| 1174 | + {"appIconPath", luau_appIconPath}, |
1140 | 1175 | {"setWallpaperEnabled", luau_setWallpaperEnabled}, |
1141 | 1176 | {"setWallpaper", luau_setWallpaper}, |
1142 | 1177 | {"togglePanel", luau_togglePanel}, |
|
0 commit comments