windowpp 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (88) hide show
  1. package/bin/windowpp.js +86 -0
  2. package/cmake/embed_assets.py +144 -0
  3. package/framework/CMakeLists.txt +176 -0
  4. package/framework/include/windowpp/windowpp.h +704 -0
  5. package/framework/src/AppData/API/AppData.ts +137 -0
  6. package/framework/src/AppData/appdata_bridge.h +138 -0
  7. package/framework/src/AppData/appdata_manager.cpp +126 -0
  8. package/framework/src/AppData/appdata_manager.h +3 -0
  9. package/framework/src/FileSystem/API/FileSystem.ts +389 -0
  10. package/framework/src/FileSystem/Linux/filesearch.cpp +148 -0
  11. package/framework/src/FileSystem/Linux/readfile.cpp +79 -0
  12. package/framework/src/FileSystem/Linux/savefile.cpp +333 -0
  13. package/framework/src/FileSystem/MacOS/filesearch.cpp +149 -0
  14. package/framework/src/FileSystem/MacOS/readfile.cpp +80 -0
  15. package/framework/src/FileSystem/MacOS/savefile.cpp +264 -0
  16. package/framework/src/FileSystem/Windows/filesearch.cpp +195 -0
  17. package/framework/src/FileSystem/Windows/readfile.cpp +122 -0
  18. package/framework/src/FileSystem/Windows/savefile.cpp +290 -0
  19. package/framework/src/FileSystem/file_index_service.cpp +262 -0
  20. package/framework/src/FileSystem/file_index_service.h +55 -0
  21. package/framework/src/FileSystem/filesystem_bridge.h +243 -0
  22. package/framework/src/FileSystem/filesystem_handler.h +93 -0
  23. package/framework/src/FileSystem/filesystem_json.h +241 -0
  24. package/framework/src/FileSystem/filesystem_search_service.cpp +414 -0
  25. package/framework/src/FileSystem/filesystem_search_service.h +94 -0
  26. package/framework/src/Input/API/Input.ts +161 -0
  27. package/framework/src/Input/Linux/linux_key_utils.h +135 -0
  28. package/framework/src/Input/MacOS/macos_key_utils.h +137 -0
  29. package/framework/src/Input/Windows/win32_key_utils.h +199 -0
  30. package/framework/src/Input/input_bridge.h +192 -0
  31. package/framework/src/Input/input_service.cpp +584 -0
  32. package/framework/src/Input/input_service.h +21 -0
  33. package/framework/src/application.cpp +29 -0
  34. package/framework/src/common/hit_test.cpp +40 -0
  35. package/framework/src/common/image_loader.cpp +24 -0
  36. package/framework/src/common/paths.cpp +75 -0
  37. package/framework/src/filedrop/filedrop.cpp +316 -0
  38. package/framework/src/filedrop/filedrop.css +421 -0
  39. package/framework/src/filedrop/filedrop.hpp +92 -0
  40. package/framework/src/filedrop/filedrop.ts +183 -0
  41. package/framework/src/platform/API/App.ts +156 -0
  42. package/framework/src/platform/API/Window.ts +249 -0
  43. package/framework/src/platform/linux/app_linux.cpp +256 -0
  44. package/framework/src/platform/linux/app_linux.h +64 -0
  45. package/framework/src/platform/linux/linux_helpers.cpp +26 -0
  46. package/framework/src/platform/linux/linux_helpers.h +19 -0
  47. package/framework/src/platform/linux/tray_linux.cpp +21 -0
  48. package/framework/src/platform/linux/tray_linux.h +26 -0
  49. package/framework/src/platform/linux/window_linux.cpp +256 -0
  50. package/framework/src/platform/linux/window_linux.h +70 -0
  51. package/framework/src/platform/macos/app_macos.h +59 -0
  52. package/framework/src/platform/macos/app_macos.mm +223 -0
  53. package/framework/src/platform/macos/macos_helpers.h +21 -0
  54. package/framework/src/platform/macos/tray_macos.h +22 -0
  55. package/framework/src/platform/macos/tray_macos.mm +53 -0
  56. package/framework/src/platform/macos/window_macos.h +74 -0
  57. package/framework/src/platform/macos/window_macos.mm +318 -0
  58. package/framework/src/platform/platform_bridge.h +514 -0
  59. package/framework/src/platform/platform_factory.cpp +33 -0
  60. package/framework/src/platform/platform_factory.h +19 -0
  61. package/framework/src/platform/win32/app_win32.cpp +572 -0
  62. package/framework/src/platform/win32/app_win32.h +83 -0
  63. package/framework/src/platform/win32/tray_win32.cpp +57 -0
  64. package/framework/src/platform/win32/tray_win32.h +30 -0
  65. package/framework/src/platform/win32/win32_helpers.h +61 -0
  66. package/framework/src/platform/win32/window_win32.cpp +267 -0
  67. package/framework/src/platform/win32/window_win32.h +79 -0
  68. package/framework/src/renderer/webgpu.h +128 -0
  69. package/framework/src/renderer/webview/include/WebView2.h +48014 -0
  70. package/framework/src/renderer/webview/include/WebView2EnvironmentOptions.h +342 -0
  71. package/framework/src/renderer/webview/webview.h +13 -0
  72. package/framework/src/renderer/webview/webview_linux.cpp +392 -0
  73. package/framework/src/renderer/webview/webview_macos.mm +388 -0
  74. package/framework/src/renderer/webview/webview_win32.cpp +688 -0
  75. package/framework/src/renderer/webview/x64/WebView2Loader.dll +0 -0
  76. package/framework/src/renderer/webview/x64/WebView2Loader.lib +0 -0
  77. package/framework/src/renderer/webview/x64/WebView2LoaderStatic.lib +0 -0
  78. package/lib/build.js +112 -0
  79. package/lib/create.js +283 -0
  80. package/lib/dev.js +155 -0
  81. package/package.json +24 -0
  82. package/scripts/publish.js +67 -0
  83. package/scripts/sync-framework.js +73 -0
  84. package/templates/solid/CMakeLists.txt +56 -0
  85. package/templates/solid/frontend/package.json +22 -0
  86. package/templates/solid/frontend/vite.config.ts +25 -0
  87. package/templates/solid/main.cpp +72 -0
  88. package/templates/solid/package.json +12 -0
@@ -0,0 +1,137 @@
1
+ export interface AppDataEntry {
2
+ name: string;
3
+ path: string;
4
+ isDir: boolean;
5
+ isSymlink: boolean;
6
+ }
7
+
8
+ export interface SeedEntry {
9
+ relative_path: string;
10
+ content: string;
11
+ overwrite?: boolean;
12
+ }
13
+
14
+ interface PendingCall {
15
+ resolve: (value: any) => void;
16
+ reject: (reason: Error) => void;
17
+ }
18
+
19
+ let callId = 0;
20
+ const pending = new Map<string, PendingCall>();
21
+
22
+ function getGlobal(): any {
23
+ if (typeof window !== 'undefined') return window;
24
+ if (typeof globalThis !== 'undefined') return globalThis;
25
+ return {};
26
+ }
27
+
28
+ const globalObject = getGlobal();
29
+ const previousResponse = globalObject.__response__;
30
+
31
+ globalObject.__response__ = function (id: string, result: any, error?: string) {
32
+ const request = pending.get(id);
33
+ if (request) {
34
+ pending.delete(id);
35
+ if (error) {
36
+ request.reject(new Error(error));
37
+ } else {
38
+ request.resolve(result);
39
+ }
40
+ return;
41
+ }
42
+
43
+ if (previousResponse) {
44
+ previousResponse(id, result, error);
45
+ }
46
+ };
47
+
48
+ function invoke<T>(method: string, params: unknown[] = []): Promise<T> {
49
+ return new Promise<T>((resolve, reject) => {
50
+ const id = String(++callId);
51
+ pending.set(id, { resolve, reject });
52
+ const payload = JSON.stringify({ id, method, params });
53
+
54
+ if (globalObject.__native_invoke__) {
55
+ globalObject.__native_invoke__(payload);
56
+ return;
57
+ }
58
+
59
+ if (globalObject.chrome?.webview?.postMessage) {
60
+ globalObject.chrome.webview.postMessage(payload);
61
+ return;
62
+ }
63
+
64
+ pending.delete(id);
65
+ reject(new Error('Native bridge not available'));
66
+ });
67
+ }
68
+
69
+ export function getRoot(): Promise<string> {
70
+ return invoke<string>('appData:getRoot');
71
+ }
72
+
73
+ export function resolve(relative = ''): Promise<string> {
74
+ return invoke<string>('appData:resolve', [relative]);
75
+ }
76
+
77
+ export function exists(relative = ''): Promise<boolean> {
78
+ return invoke<boolean>('appData:exists', [relative]);
79
+ }
80
+
81
+ export function readText(relative: string): Promise<string> {
82
+ return invoke<string>('appData:readText', [relative]);
83
+ }
84
+
85
+ export function writeText(relative: string, content: string): Promise<void> {
86
+ return invoke<void>('appData:writeText', [relative, content]);
87
+ }
88
+
89
+ export function appendText(relative: string, content: string): Promise<void> {
90
+ return invoke<void>('appData:appendText', [relative, content]);
91
+ }
92
+
93
+ export function deleteFile(relative: string): Promise<void> {
94
+ return invoke<void>('appData:deleteFile', [relative]);
95
+ }
96
+
97
+ export function createDir(relative: string, recursive = true): Promise<void> {
98
+ return invoke<void>('appData:createDir', [relative, recursive]);
99
+ }
100
+
101
+ export function removeDir(relative: string, recursive = false): Promise<void> {
102
+ return invoke<void>('appData:removeDir', [relative, recursive]);
103
+ }
104
+
105
+ export function readDir(relative = ''): Promise<AppDataEntry[]> {
106
+ return invoke<AppDataEntry[]>('appData:readDir', [relative]);
107
+ }
108
+
109
+ export function ensureDirs(dirs: string[]): Promise<void> {
110
+ return invoke<void>('appData:ensureDirs', [dirs]);
111
+ }
112
+
113
+ export function seedFile(relativePath: string, content: string, overwrite = false): Promise<void> {
114
+ return invoke<void>('appData:seedFile', [relativePath, content, overwrite]);
115
+ }
116
+
117
+ export function seedFiles(entries: SeedEntry[]): Promise<void> {
118
+ return invoke<void>('appData:seedFiles', [entries]);
119
+ }
120
+
121
+ export const appData = {
122
+ getRoot,
123
+ resolve,
124
+ exists,
125
+ readText,
126
+ writeText,
127
+ appendText,
128
+ deleteFile,
129
+ createDir,
130
+ removeDir,
131
+ readDir,
132
+ ensureDirs,
133
+ seedFile,
134
+ seedFiles,
135
+ };
136
+
137
+ export default appData;
@@ -0,0 +1,138 @@
1
+ // ============================================================================
2
+ // AppData/appdata_bridge.h
3
+ // Frontend bridge for app-scoped storage rooted in the OS-standard app-data
4
+ // directory for the current application.
5
+ // ============================================================================
6
+
7
+ #pragma once
8
+
9
+ #include <functional>
10
+ #include <string>
11
+ #include <vector>
12
+
13
+ #include "appdata_manager.h"
14
+ #include "../FileSystem/filesystem_json.h"
15
+
16
+ namespace wpp::appdata {
17
+
18
+ using EvalFn = std::function<void(const std::string& js)>;
19
+
20
+ class AppDataBridge {
21
+ public:
22
+ AppDataBridge(EvalFn eval_fn, const std::string& app_name)
23
+ : eval_(std::move(eval_fn)), manager_(app_name) {}
24
+
25
+ void dispatch(const std::string& raw) {
26
+ std::string id;
27
+ std::string method;
28
+ std::vector<wpp::fs::JsonValue> params;
29
+
30
+ try {
31
+ auto env = wpp::fs::JsonValue::parse(raw);
32
+ id = env["id"].as_string();
33
+ method = env["method"].as_string();
34
+ params = env["params"].as_array();
35
+ } catch (...) {
36
+ return;
37
+ }
38
+
39
+ if (method.rfind("appData:", 0) != 0) {
40
+ return;
41
+ }
42
+
43
+ auto reply_ok = [this, &id](const std::string& json_result) {
44
+ eval_("window.__response__(" + wpp::fs::JsonValue::to_js_argument(id) + "," + json_result + ")");
45
+ };
46
+
47
+ auto reply_err = [this, &id](const std::string& msg) {
48
+ eval_(
49
+ "window.__response__(" + wpp::fs::JsonValue::to_js_argument(id) + ",null," +
50
+ wpp::fs::JsonValue::to_js_argument(msg) + ")");
51
+ };
52
+
53
+ auto relative = [&params](size_t index) -> std::string {
54
+ if (index >= params.size()) return "";
55
+ return params[index].as_string();
56
+ };
57
+
58
+ try {
59
+ if (method == "appData:getRoot") {
60
+ reply_ok(wpp::fs::JsonValue::dump_value(manager_.root()));
61
+
62
+ } else if (method == "appData:resolve") {
63
+ reply_ok(wpp::fs::JsonValue::dump_value(manager_.path(relative(0))));
64
+
65
+ } else if (method == "appData:exists") {
66
+ reply_ok(manager_.exists(relative(0)) ? "true" : "false");
67
+
68
+ } else if (method == "appData:readText") {
69
+ reply_ok(wpp::fs::JsonValue::dump_value(manager_.read_text(relative(0))));
70
+
71
+ } else if (method == "appData:writeText") {
72
+ manager_.write_text(relative(0), relative(1));
73
+ reply_ok("null");
74
+
75
+ } else if (method == "appData:appendText") {
76
+ manager_.append_text(relative(0), relative(1));
77
+ reply_ok("null");
78
+
79
+ } else if (method == "appData:deleteFile") {
80
+ manager_.delete_file(relative(0));
81
+ reply_ok("null");
82
+
83
+ } else if (method == "appData:createDir") {
84
+ bool recursive = params.size() > 1 && params[1].as_bool();
85
+ manager_.create_dir(relative(0), recursive);
86
+ reply_ok("null");
87
+
88
+ } else if (method == "appData:removeDir") {
89
+ bool recursive = params.size() > 1 && params[1].as_bool();
90
+ manager_.remove_dir(relative(0), recursive);
91
+ reply_ok("null");
92
+
93
+ } else if (method == "appData:readDir") {
94
+ const auto entries = manager_.read_dir(relative(0));
95
+ reply_ok(wpp::fs::dirEntriesToJson(entries, &AppDataEntry::is_dir, &AppDataEntry::is_symlink));
96
+
97
+ } else if (method == "appData:ensureDirs") {
98
+ std::vector<std::string> dirs;
99
+ if (!params.empty()) {
100
+ for (const auto& value : params[0].as_array()) {
101
+ dirs.push_back(value.as_string());
102
+ }
103
+ }
104
+ manager_.ensure_dirs(dirs);
105
+ reply_ok("null");
106
+
107
+ } else if (method == "appData:seedFile") {
108
+ bool overwrite = params.size() > 2 && params[2].as_bool();
109
+ manager_.seed_file(relative(0), relative(1), overwrite);
110
+ reply_ok("null");
111
+
112
+ } else if (method == "appData:seedFiles") {
113
+ std::vector<SeedEntry> seeds;
114
+ if (!params.empty()) {
115
+ for (const auto& value : params[0].as_array()) {
116
+ seeds.push_back(SeedEntry{
117
+ value["relative_path"].as_string(),
118
+ value["content"].as_string(),
119
+ value.get_bool("overwrite", false)
120
+ });
121
+ }
122
+ }
123
+ manager_.seed_files(seeds);
124
+ reply_ok("null");
125
+ }
126
+ } catch (const std::exception& e) {
127
+ reply_err(e.what());
128
+ } catch (...) {
129
+ reply_err("Unknown error in appData bridge");
130
+ }
131
+ }
132
+
133
+ private:
134
+ EvalFn eval_;
135
+ AppDataManager manager_;
136
+ };
137
+
138
+ } // namespace wpp::appdata
@@ -0,0 +1,126 @@
1
+ #include "appdata_manager.h"
2
+ #include "../FileSystem/filesystem_handler.h"
3
+
4
+ #include <filesystem>
5
+ #include <stdexcept>
6
+
7
+ namespace wpp {
8
+
9
+ namespace {
10
+
11
+ std::filesystem::path validate_relative_path(const std::string& relative) {
12
+ if (relative.empty()) {
13
+ return {};
14
+ }
15
+
16
+ std::filesystem::path candidate = std::filesystem::path(relative).lexically_normal();
17
+ if (candidate.empty() || candidate == ".") {
18
+ return {};
19
+ }
20
+
21
+ if (candidate.is_absolute() || candidate.has_root_name() || candidate.has_root_directory()) {
22
+ throw std::invalid_argument("AppData path must be relative to the app data root");
23
+ }
24
+
25
+ for (const auto& part : candidate) {
26
+ if (part == "..") {
27
+ throw std::invalid_argument("AppData path cannot escape the app data root");
28
+ }
29
+ }
30
+
31
+ return candidate;
32
+ }
33
+
34
+ std::string join_under_root(const std::string& root, const std::string& relative) {
35
+ std::filesystem::path base = std::filesystem::u8path(root);
36
+ std::filesystem::path rel = validate_relative_path(relative);
37
+ if (rel.empty()) {
38
+ return base.u8string();
39
+ }
40
+ return (base / rel).lexically_normal().u8string();
41
+ }
42
+
43
+ } // namespace
44
+
45
+ AppDataManager::AppDataManager(const std::string& app_name)
46
+ : root_(paths::app_data_dir(app_name))
47
+ {
48
+ fs::handleCreateDir(root_, true);
49
+ }
50
+
51
+ const std::string& AppDataManager::root() const {
52
+ return root_;
53
+ }
54
+
55
+ std::string AppDataManager::path(const std::string& relative) const {
56
+ return join_under_root(root_, relative);
57
+ }
58
+
59
+ bool AppDataManager::exists(const std::string& relative) const {
60
+ return fs::handleExists(path(relative));
61
+ }
62
+
63
+ std::string AppDataManager::read_text(const std::string& relative) const {
64
+ return fs::handleReadFile(path(relative));
65
+ }
66
+
67
+ void AppDataManager::write_text(const std::string& relative,
68
+ const std::string& content) {
69
+ std::string full = path(relative);
70
+ std::filesystem::path parent = std::filesystem::u8path(full).parent_path();
71
+ if (!parent.empty()) {
72
+ fs::handleCreateDir(parent.u8string(), true);
73
+ }
74
+ fs::handleWriteFile(full, content);
75
+ }
76
+
77
+ void AppDataManager::append_text(const std::string& relative,
78
+ const std::string& content) {
79
+ std::string full = path(relative);
80
+ std::filesystem::path parent = std::filesystem::u8path(full).parent_path();
81
+ if (!parent.empty()) {
82
+ fs::handleCreateDir(parent.u8string(), true);
83
+ }
84
+ fs::handleAppendFile(full, content);
85
+ }
86
+
87
+ void AppDataManager::delete_file(const std::string& relative) {
88
+ fs::handleDeleteFile(path(relative));
89
+ }
90
+
91
+ void AppDataManager::create_dir(const std::string& relative, bool recursive) {
92
+ fs::handleCreateDir(path(relative), recursive);
93
+ }
94
+
95
+ void AppDataManager::remove_dir(const std::string& relative, bool recursive) {
96
+ fs::handleRemoveDir(path(relative), recursive);
97
+ }
98
+
99
+ std::vector<AppDataEntry> AppDataManager::read_dir(const std::string& relative) const {
100
+ std::vector<AppDataEntry> result;
101
+ for (const auto& entry : fs::handleReadDir(path(relative))) {
102
+ result.push_back(AppDataEntry{entry.name, entry.path, entry.isDir, entry.isSymlink});
103
+ }
104
+ return result;
105
+ }
106
+
107
+ void AppDataManager::ensure_dirs(const std::vector<std::string>& dirs) {
108
+ for (const auto& dir : dirs) {
109
+ create_dir(dir, true);
110
+ }
111
+ }
112
+
113
+ void AppDataManager::seed_file(const std::string& relative_path,
114
+ const std::string& content,
115
+ bool overwrite) {
116
+ if (!overwrite && exists(relative_path)) return;
117
+ write_text(relative_path, content);
118
+ }
119
+
120
+ void AppDataManager::seed_files(const std::vector<SeedEntry>& entries) {
121
+ for (const auto& entry : entries) {
122
+ seed_file(entry.relative_path, entry.content, entry.overwrite);
123
+ }
124
+ }
125
+
126
+ } // namespace wpp
@@ -0,0 +1,3 @@
1
+ #pragma once
2
+
3
+ #include <windowpp/windowpp.h>