-#endif
-
-#ifdef _WIN32
-int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrevInst, LPSTR lpCmdLine,
- int nCmdShow) {
- (void)hInst;
- (void)hPrevInst;
- (void)lpCmdLine;
- (void)nCmdShow;
-#else
-int main(void) {
-#endif
- webview_t w = webview_create(0, NULL);
- webview_set_title(w, "Basic Example");
- webview_set_size(w, 480, 320, WEBVIEW_HINT_NONE);
- webview_set_html(w, "Thanks for using webview!");
- webview_run(w);
- webview_destroy(w);
- return 0;
-}
-```
-
-### Building the Example
-
-Build the project:
-
-```sh
-cmake -G Ninja -B build -S . -D CMAKE_BUILD_TYPE=Release
-cmake --build build
-```
-
-Find the executable in the `build/bin` directory.
-
-### Building Amalgamated Library
-
-An amalgamated library can be built when building the project using CMake, or the `amalgamate.py` script can be invoked directly.
-
-The latter is described below.
-
-```sh
-python3 scripts/amalgamate/amalgamate.py --base core --search include --output webview_amalgamation.h src
-```
-
-See `python3 scripts/amalgamate/amalgamate.py --help` for script usage.
-
-### Non-CMake Usage
-
-Here's an example for invoking GCC/Clang-like compilers directly. Use the `main.cc` file from the previous example.
-
-Place either the amalgamated `webview.h` header or all of the individual files into `libs/webview`, and `WebView2.h` from [MS WebView2][ms-webview2-sdk] into `libs`.
-
-Build the project on your chosen platform.
-
-
- macOS
- c++ main.cc -O2 --std=c++11 -Ilibs -framework WebKit -ldl -o example
-
-
-
- Linux
- c++ main.cc -O2 --std=c++11 -Ilibs $(pkg-config --cflags --libs gtk+-3.0 webkit2gtk-4.1) -ldl -o example
-
-
-
- Windows
- c++ main.cc -O2 --std=c++14 -static -mwindows -Ilibs -ladvapi32 -lole32 -lshell32 -lshlwapi -luser32 -lversion -o example
-
-
-## Customization
-
-### CMake Targets
-
-The following CMake targets are available:
-
-Name | Description
----- | -----------
-`webview::core` | Headers for C++.
-`webview::core_shared` | Shared library for C.
-`webview::core_static` | Static library for C.
-
-Special targets for on-demand checks and related tasks:
-
-Name | Description
----- | -----------
-`webview_format_check` | Check files with clang-format.
-`webview_reformat` | Reformat files with clang-format.
-
-### CMake Options
-
-The following boolean options can be used when building the webview project standalone or when building it as part of your project (e.g. with FetchContent).
-
-Option | Description
------- | -----------
-`WEBVIEW_BUILD` | Enable building
-`WEBVIEW_BUILD_AMALGAMATION` | Build amalgamated library
-`WEBVIEW_BUILD_DOCS` | Build documentation
-`WEBVIEW_BUILD_EXAMPLES` | Build examples
-`WEBVIEW_BUILD_SHARED_LIBRARY` | Build shared libraries
-`WEBVIEW_BUILD_STATIC_LIBRARY` | Build static libraries
-`WEBVIEW_BUILD_TESTS` | Build tests
-`WEBVIEW_ENABLE_CHECKS` | Enable checks
-`WEBVIEW_ENABLE_CLANG_FORMAT` | Enable clang-format
-`WEBVIEW_ENABLE_CLANG_TIDY` | Enable clang-tidy
-`WEBVIEW_ENABLE_PACKAGING` | Enable packaging
-`WEBVIEW_INSTALL_DOCS` | Install documentation
-`WEBVIEW_INSTALL_TARGETS` | Install targets
-`WEBVIEW_IS_CI` | Initialized by the `CI` environment variable
-`WEBVIEW_PACKAGE_AMALGAMATION` | Package amalgamated library
-`WEBVIEW_PACKAGE_DOCS` | Package documentation
-`WEBVIEW_PACKAGE_HEADERS` | Package headers
-`WEBVIEW_PACKAGE_LIB` | Package compiled libraries
-`WEBVIEW_STRICT_CHECKS` | Make checks strict
-`WEBVIEW_STRICT_CLANG_FORMAT` | Make clang-format check strict
-`WEBVIEW_STRICT_CLANG_TIDY` | Make clang-tidy check strict
-`WEBVIEW_USE_COMPAT_MINGW` | Use compatibility helper for MinGW
-`WEBVIEW_USE_STATIC_MSVC_RUNTIME` | Use static runtime library (MSVC)
-
-> [!NOTE]
-> Checks are *enabled* by default, but aren't *enforced* by default for local development (controlled by the `WEBVIEW_IS_CI` option).
-
-Non-boolean options:
-
-Option | Description
------- | -----------
-`WEBVIEW_CLANG_FORMAT_EXE` | Path of the `clang-format` executable.
-`WEBVIEW_CLANG_TIDY_EXE` | Path of the `clang-tidy` executable.
-
-### Package Consumer Options
-
-These options can be used when when using the webview CMake package.
-
-#### Linux-specific Options
-
-Option | Description
------- | -----------
-`WEBVIEW_WEBKITGTK_API` | WebKitGTK API to interface with, e.g. `6.0`, `4.1` (recommended) or `4.0`. This will also automatically decide the GTK version. Uses the latest recommended API by default if available, or the latest known and available API. Note that there can be major differences between API versions that can affect feature availability. See webview API documentation for details on feature availability.
-
-#### Windows-specific Options
-
-Option | Description
------- | -----------
-`WEBVIEW_MSWEBVIEW2_VERSION` | MS WebView2 version, e.g. `1.0.1150.38`.
-`WEBVIEW_USE_BUILTIN_MSWEBVIEW2`| Use built-in MS WebView2.
-
-### Compile-time Options
-
-These options can be specified as preprocessor macros to modify the build, but are not needed when using CMake.
-
-#### C API Linkage
-
-Name | Description
----- | -----------
-`WEBVIEW_API` | Controls C API linkage, symbol visibility and whether it's a shared library. By default this is `inline` for C++ and `extern` for C.
-`WEBVIEW_BUILD_SHARED` | Modifies `WEBVIEW_API` for building a shared library.
-`WEBVIEW_SHARED` | Modifies `WEBVIEW_API` for using a shared library.
-`WEBVIEW_STATIC` | Modifies `WEBVIEW_API` for building or using a static library.
-
-#### Backend Selection
-
-Name | Description
----- | -----------
-`WEBVIEW_GTK` | Compile the GTK/WebKitGTK backend.
-`WEBVIEW_COCOA` | Compile the Cocoa/WebKit backend.
-`WEBVIEW_EDGE` | Compile the Win32/WebView2 backend.
-
-#### Windows-specific Options
-
-Option | Description
------- | -----------
-`WEBVIEW_MSWEBVIEW2_BUILTIN_IMPL` | Enables (`1`) or disables (`0`) the built-in implementation of the WebView2 loader. Enabling this avoids the need for `WebView2Loader.dll` but if the DLL is present then the DLL takes priority. This option is enabled by default.
-`WEBVIEW_MSWEBVIEW2_EXPLICIT_LINK`| Enables (`1`) or disables (`0`) explicit linking of `WebView2Loader.dll`. Enabling this avoids the need for import libraries (`*.lib`). This option is enabled by default if `WEBVIEW_MSWEBVIEW2_BUILTIN_IMPL` is enabled.
-
-## MinGW-w64 Requirements
-
-In order to build this library using MinGW-w64 on Windows then it must support C++14 and have an up-to-date Windows SDK.
-
-Distributions that are known to be compatible:
-
-* [LLVM MinGW](https://github.com/mstorsjo/llvm-mingw)
-* [MSYS2](https://www.msys2.org/)
-* [WinLibs](https://winlibs.com/)
-
-## MS WebView2 Loader
-
-Linking the WebView2 loader part of the Microsoft WebView2 SDK is not a hard requirement when using our webview library, and neither is distributing `WebView2Loader.dll` with your app.
-
-If, however, `WebView2Loader.dll` is loadable at runtime, e.g. from the executable's directory, then it will be used; otherwise our minimalistic implementation will be used instead.
-
-Should you wish to use the official loader then remember to distribute it along with your app unless you link it statically. Linking it statically is possible with Visual C++ but not MinGW-w64.
-
-Here are some of the noteworthy ways our implementation of the loader differs from the official implementation:
-
-* Does not support configuring WebView2 using environment variables such as `WEBVIEW2_BROWSER_EXECUTABLE_FOLDER`.
-* Microsoft Edge Insider (preview) channels are not supported.
-
-[Customization options](#Customization) can be used to change how the library integrates the WebView2 loader.
-
-## Thread Safety
-
-Since library functions generally do not have thread safety guarantees, `webview_dispatch()` (C) / `webview::dispatch()` (C++) can be used to schedule code to execute on the main/GUI thread and thereby make that execution safe in multi-threaded applications.
-
-`webview_return()` (C) / `webview::resolve()` (C++) uses `*dispatch()` internally and is therefore safe to call from another thread.
-
-The main/GUI thread should be the thread that calls `webview_run()` (C) / `webview::run()` (C++).
-
-## Development
-
-This project uses the CMake build system.
-
-### Development Dependencies
-
-In addition to the dependencies mentioned earlier in this document for developing *with* the webview library, the following are used during development *of* the webview library.
-
-* Amalgamation:
- * Python >= 3.9
-* Checks:
- * `clang-format`
- * `clang-tidy`
-* Documentation:
- * Doxygen
- * Graphvis
-
-### Building
-
-```sh
-cmake -G "Ninja Multi-Config" -B build -S .
-cmake --build build --config CONFIG
-```
-
-Replace `CONFIG` with one of `Debug`, `Release`, or `Profile`. Use `Profile` to enable code coverage (GCC/Clang).
-
-Run tests:
-
-```sh
-ctest --test-dir build --build-config CONFIG
-```
-
-Generate test coverage report:
-
-```sh
-gcovr
-```
-
-Find the coverage report in `build/coverage`.
-
-### Packaging
-
-Run this after building the `Debug` and `Release` configs of the project:
-
-```sh
-cd build
-cpack -G External -C "Debug;Release" --config CPackConfig.cmake
+```bash
+bun install
```
-### Cross-compilation
-
-See CMake toolchain files in the `cmake/toolchains` directory.
-
-For example, this targets Windows x64 on Linux with POSIX threads:
-
-```sh
-cmake -G "Ninja Multi-Config" -B build -S . -D CMAKE_TOOLCHAIN_FILE=cmake/toolchains/x86_64-w64-mingw32.cmake -D WEBVIEW_TOOLCHAIN_EXECUTABLE_SUFFIX=-posix
-cmake --build build --config CONFIG
-```
-
-## Limitations
-
-### Browser Features
-
-Since a browser engine is not a full web browser it may not support every feature you may expect from a browser. If you find that a feature does not work as expected then please consult with the browser engine's documentation and [open an issue][issues-new] if you think that the library should support it.
+To run:
-For example, the library does not attempt to support user interaction features like `alert()`, `confirm()` and `prompt()` and other non-essential features like `console.log()`.
-
-## Bindings
-
-Language | Project
----------- | -------
-Ada | [thechampagne/webview-ada](https://github.com/thechampagne/webview-ada)
-Bun | [tr1ckydev/webview-bun](https://github.com/tr1ckydev/webview-bun)
-C# | [webview/webview_csharp](https://github.com/webview/webview_csharp)
-C3 | [thechampagne/webview-c3](https://github.com/thechampagne/webview-c3)
-Crystal | [naqvis/webview](https://github.com/naqvis/webview)
-D | [thechampagne/webview-d](https://github.com/thechampagne/webview-d), [ronnie-w/webviewd](https://github.com/ronnie-w/webviewd)
-Deno | [webview/webview_deno](https://github.com/webview/webview_deno)
-Go | [webview/webview_go][webview_go]
-Harbour | [EricLendvai/Harbour_WebView](https://github.com/EricLendvai/Harbour_WebView)
-Haskell | [lettier/webviewhs](https://github.com/lettier/webviewhs)
-Janet | [janet-lang/webview](https://github.com/janet-lang/webview)
-Java | [webview/webview_java](https://github.com/webview/webview_java)
-Kotlin | [Winterreisender/webviewko](https://github.com/Winterreisender/webviewko)
-MoonBit | [justjavac/moonbit-webview](https://github.com/justjavac/moonbit-webview)
-Nim | [oskca/webview](https://github.com/oskca/webview), [neroist/webview](https://github.com/neroist/webview)
-Node.js | [Winterreisender/webview-nodejs](https://github.com/Winterreisender/webview-nodejs)
-Odin | [thechampagne/webview-odin](https://github.com/thechampagne/webview-odin)
-Pascal | [PierceNg/fpwebview](http://github.com/PierceNg/fpwebview)
-Python | [congzhangzh/webview_python](https://github.com/congzhangzh/webview_python),[zserge/webview-python](https://github.com/zserge/webview-python)
-PHP | [0hr/php-webview](https://github.com/0hr/php-webview), [KingBes/pebview](https://github.com/KingBes/pebview), [happystraw/php-ext-webview](https://github.com/happystraw/php-ext-webview)
-Ring | [ysdragon/webview](https://github.com/ysdragon/webview)
-Ruby | [Maaarcocr/webview_ruby](https://github.com/Maaarcocr/webview_ruby)
-Rust | [Boscop/web-view](https://github.com/Boscop/web-view)
-Swift | [jakenvac/SwiftWebview](https://github.com/jakenvac/SwiftWebview)
-V | [malisipi/mui](https://github.com/malisipi/mui/tree/main/webview), [ttytm/webview](https://github.com/ttytm/webview)
-Vala | [taozuhong/webview-vala](https://github.com/taozuhong/webview-vala)
-Zig | [thechampagne/webview-zig](https://github.com/thechampagne/webview-zig), [happystraw/zig-webview](https://github.com/happystraw/zig-webview)
-
-If you wish to add bindings to the list, feel free to submit a pull request or [open an issue][issues-new].
-
-## Generating Bindings
-
-You can generate bindings for the library by yourself using the included SWIG interface (`webview.i`).
-
-Here are some examples to get you started. Unix-style command lines are used for conciseness.
-
-```sh
-mkdir -p build/bindings/{python,csharp,java,ruby}
-swig -c++ -python -outdir build/bindings/python -o build/bindings/python/python_wrap.cpp webview.i
-swig -c++ -csharp -outdir build/bindings/csharp -o build/bindings/csharp/csharp_wrap.cpp webview.i
-swig -c++ -java -outdir build/bindings/java -o build/bindings/java/java_wrap.cpp webview.i
-swig -c++ -ruby -outdir build/bindings/ruby -o build/bindings/ruby/ruby_wrap.cpp webview.i
+```bash
+bun run index.ts
```
-## License
-
-Code is distributed under MIT license, feel free to use it in your proprietary projects as well.
-
-[examples]: https://github.com/webview/webview/tree/master/examples
-[gtk]: https://gtk.org/
-[issues]: https://github.com/webview/docs/issues
-[issues-new]: https://github.com/webview/webview/issues/new
-[webkit]: https://webkit.org/
-[webkitgtk]: https://webkitgtk.org/
-[webview]: https://github.com/webview/webview
-[webview_go]: https://github.com/webview/webview_go
-[webview.dev]: https://webview.dev
-[ms-webview2]: https://developer.microsoft.com/en-us/microsoft-edge/webview2/
-[ms-webview2-sdk]: https://www.nuget.org/packages/Microsoft.Web.WebView2
-[ms-webview2-rt]: https://developer.microsoft.com/en-us/microsoft-edge/webview2/
-[win32-api]: https://docs.microsoft.com/en-us/windows/win32/apiindex/windows-api-list
+This project was created using `bun init` in bun v1.2.14. [Bun](https://bun.sh) is a fast all-in-one JavaScript runtime.
diff --git a/bun.lock b/bun.lock
new file mode 100644
index 000000000..040996f66
--- /dev/null
+++ b/bun.lock
@@ -0,0 +1,25 @@
+{
+ "lockfileVersion": 1,
+ "workspaces": {
+ "": {
+ "name": "/app",
+ "devDependencies": {
+ "@types/bun": "latest",
+ },
+ "peerDependencies": {
+ "typescript": "^5",
+ },
+ },
+ },
+ "packages": {
+ "@types/bun": ["@types/bun@1.3.11", "", { "dependencies": { "bun-types": "1.3.11" } }, "sha512-5vPne5QvtpjGpsGYXiFyycfpDF2ECyPcTSsFBMa0fraoxiQyMJ3SmuQIGhzPg2WJuWxVBoxWJ2kClYTcw/4fAg=="],
+
+ "@types/node": ["@types/node@25.5.0", "", { "dependencies": { "undici-types": "~7.18.0" } }, "sha512-jp2P3tQMSxWugkCUKLRPVUpGaL5MVFwF8RDuSRztfwgN1wmqJeMSbKlnEtQqU8UrhTmzEmZdu2I6v2dpp7XIxw=="],
+
+ "bun-types": ["bun-types@1.3.11", "", { "dependencies": { "@types/node": "*" } }, "sha512-1KGPpoxQWl9f6wcZh57LvrPIInQMn2TQ7jsgxqpRzg+l0QPOFvJVH7HmvHo/AiPgwXy+/Thf6Ov3EdVn1vOabg=="],
+
+ "typescript": ["typescript@5.9.3", "", { "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" } }, "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw=="],
+
+ "undici-types": ["undici-types@7.18.2", "", {}, "sha512-AsuCzffGHJybSaRrmr5eHr81mwJU3kjw6M+uprWvCXiNeN9SOGwQ3Jn8jb8m3Z6izVgknn1R0FTCEAP2QrLY/w=="],
+ }
+}
diff --git a/cmake/clang_format.cmake b/cmake/clang_format.cmake
deleted file mode 100644
index b74c02223..000000000
--- a/cmake/clang_format.cmake
+++ /dev/null
@@ -1,37 +0,0 @@
-file(TO_CMAKE_PATH "${BINARY_DIR}" BINARY_DIR)
-file(TO_CMAKE_PATH "${SOURCE_DIR}" SOURCE_DIR)
-
-file(GLOB_RECURSE TEMP_FILES
- ${SOURCE_DIR}/*.h
- ${SOURCE_DIR}/*.hh
- ${SOURCE_DIR}/*.hpp
- ${SOURCE_DIR}/*.hxx
- ${SOURCE_DIR}/*.c
- ${SOURCE_DIR}/*.cc
- ${SOURCE_DIR}/*.cpp
- ${SOURCE_DIR}/*.cxx)
-
-set(FILES)
-foreach(FILE IN LISTS TEMP_FILES)
- file(TO_CMAKE_PATH "${FILE}" FILE)
- if(NOT FILE MATCHES "^${BINARY_DIR}(/|$)")
- list(APPEND FILES "${FILE}")
- endif()
-endforeach()
-
-if(CMD STREQUAL "check")
- set(ARGS "--dry-run")
-elseif(CMD STREQUAL "reformat")
- set(ARGS "-i")
-endif()
-
-if(STRICT)
- list(APPEND ARGS "--Werror")
-endif()
-
-execute_process(COMMAND "${CLANG_FORMAT_EXE}" ${ARGS} ${FILES}
- RESULT_VARIABLE RESULT)
-
-if(NOT RESULT EQUAL 0 AND (STRICT OR NOT RESULT EQUAL 1))
- message(FATAL_ERROR "clang-format check failed.")
-endif()
diff --git a/cmake/extract_version.cmake b/cmake/extract_version.cmake
deleted file mode 100644
index 0951095be..000000000
--- a/cmake/extract_version.cmake
+++ /dev/null
@@ -1,6 +0,0 @@
-# Extracts the library's version number and prints it to stdout.
-
-include("${CMAKE_CURRENT_LIST_DIR}/internal.cmake")
-webview_extract_version()
-# Need this workaround because message() prints to stderr
-execute_process(COMMAND ${CMAKE_COMMAND} -E echo "${WEBVIEW_VERSION}")
diff --git a/cmake/internal.cmake b/cmake/internal.cmake
deleted file mode 100644
index fe1392918..000000000
--- a/cmake/internal.cmake
+++ /dev/null
@@ -1,365 +0,0 @@
-set(WEBVIEW_CURRENT_CMAKE_DIR "${CMAKE_CURRENT_LIST_DIR}")
-include("${WEBVIEW_CURRENT_CMAKE_DIR}/webview.cmake")
-
-# Needed when we need the project directory before calling project()
-set(WEBVIEW_ROOT_DIR "${WEBVIEW_CURRENT_CMAKE_DIR}/..")
-
-macro(webview_init)
- include(CheckCXXSourceCompiles)
- include(CMakeDependentOption)
- include(CMakePackageConfigHelpers)
- include(GNUInstallDirs)
-
- list(APPEND CMAKE_MODULE_PATH "${WEBVIEW_CURRENT_CMAKE_DIR}/modules")
-
- enable_language(C CXX)
-
- webview_options()
- webview_internal_options()
-
- # Version 0.x of the library can't guarantee backward compatibility.
- if(WEBVIEW_VERSION_NUMBER VERSION_LESS 1.0)
- set(WEBVIEW_VERSION_COMPATIBILITY "${WEBVIEW_VERSION_MAJOR}.${WEBVIEW_VERSION_MINOR}")
- else()
- set(WEBVIEW_VERSION_COMPATIBILITY "${WEBVIEW_VERSION_NUMBER}")
- endif()
-
- # Hide symbols by default
- set(CMAKE_CXX_VISIBILITY_PRESET hidden)
- set(CMAKE_VISIBILITY_INLINES_HIDDEN YES)
-
- # Use debug postfix to separate debug/release binaries for the library
- set(CMAKE_DEBUG_POSTFIX d)
-
- if(WEBVIEW_IS_TOP_LEVEL_BUILD)
- # Add custom build types
- if(CMAKE_CONFIGURATION_TYPES)
- list(APPEND CMAKE_CONFIGURATION_TYPES Profile)
- list(REMOVE_DUPLICATES CMAKE_CONFIGURATION_TYPES)
- set(CMAKE_CONFIGURATION_TYPES "${CMAKE_CONFIGURATION_TYPES}" CACHE STRING "" FORCE)
- endif()
-
- # Use custom compiler/linker flags for the "Profile" build type
- if((CMAKE_C_COMPILER_ID MATCHES "((^GNU)|Clang)$") AND (CMAKE_CXX_COMPILER_ID MATCHES "((^GNU)|Clang)$"))
- set(CMAKE_C_FLAGS_PROFILE "-g -O0 -fprofile-arcs -ftest-coverage")
- set(CMAKE_CXX_FLAGS_PROFILE "-g -O0 -fprofile-arcs -ftest-coverage")
- set(CMAKE_EXE_LINKER_FLAGS_PROFILE "-fprofile-arcs")
- set(CMAKE_SHARED_LINKER_FLAGS_PROFILE "-fprofile-arcs")
- elseif(MSVC)
- # MSVC isn't supported but warnings are emitted if these variables are undefined
- set(CMAKE_C_FLAGS_PROFILE "/Od")
- set(CMAKE_CXX_FLAGS_PROFILE "/Od")
- set(CMAKE_EXE_LINKER_FLAGS_PROFILE "")
- set(CMAKE_SHARED_LINKER_FLAGS_PROFILE "")
- endif()
-
- # Default language standards
- # All of CMAKE__STANDARD, CMAKE__REQUIRED and CMAKE__EXTENSIONS must be set
- # Note that we also use the cxx_std_11 compile feature for consumers
- set(CMAKE_C_STANDARD 99 CACHE STRING "")
- set(CMAKE_C_STANDARD_REQUIRED YES)
- set(CMAKE_C_EXTENSIONS NO)
- set(CMAKE_CXX_STANDARD 11 CACHE STRING "")
- set(CMAKE_CXX_STANDARD_REQUIRED YES)
- set(CMAKE_CXX_EXTENSIONS NO)
-
- # Enable output of compile commands
- set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
-
- # Enable compile warnings
- if(MSVC)
- add_compile_options(/W4)
- else()
- add_compile_options(-Wall -Wextra -Wpedantic)
- endif()
-
- # Set default build type for single-config generators
- get_property(IS_MULTI_CONFIG GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG)
- if(NOT IS_MULTI_CONFIG AND NOT CMAKE_BUILD_TYPE)
- set(CMAKE_BUILD_TYPE Release CACHE STRING "" FORCE)
- endif()
-
- if(WEBVIEW_USE_STATIC_MSVC_RUNTIME AND MSVC AND NOT CMAKE_MSVC_RUNTIME_LIBRARY)
- # Use static MSVC runtime library
- set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreaded$<$:Debug>")
- endif()
-
- webview_set_install_rpath()
-
- if(WEBVIEW_ENABLE_CHECKS AND WEBVIEW_ENABLE_CLANG_FORMAT)
- # Allow skipping clang-format outside of CI environment
-
- webview_find_clang_format(${WEBVIEW_IS_CI})
-
- if(WEBVIEW_CLANG_FORMAT_FOUND)
- add_custom_target(webview_format_check ALL
- COMMAND ${CMAKE_COMMAND}
- -D CMD=check
- -D "BINARY_DIR=${PROJECT_BINARY_DIR}"
- -D "SOURCE_DIR=${PROJECT_SOURCE_DIR}"
- -D "CLANG_FORMAT_EXE=${WEBVIEW_CLANG_FORMAT_EXE}"
- -D "STRICT=$,$>"
- -P "${WEBVIEW_CURRENT_CMAKE_DIR}/clang_format.cmake"
- COMMENT "Checking files with clang-format..."
- VERBATIM)
- add_custom_target(webview_reformat
- COMMAND ${CMAKE_COMMAND}
- -D CMD=reformat
- -D "BINARY_DIR=${PROJECT_BINARY_DIR}"
- -D "SOURCE_DIR=${PROJECT_SOURCE_DIR}"
- -D "CLANG_FORMAT_EXE=${WEBVIEW_CLANG_FORMAT_EXE}"
- -P "${WEBVIEW_CURRENT_CMAKE_DIR}/clang_format.cmake"
- COMMENT "Reformatting files with clang-format..."
- VERBATIM)
- else()
- message(WARNING "Skipping clang-format checks as clang-format was not found")
- endif()
- endif()
-
- if(WEBVIEW_ENABLE_CHECKS AND WEBVIEW_ENABLE_CLANG_TIDY)
- if((CMAKE_C_COMPILER_ID MATCHES "Clang$") AND (CMAKE_CXX_COMPILER_ID MATCHES "Clang$"))
- # Allow skipping clang-tidy outside of CI environment
-
- webview_find_clang_tidy(${WEBVIEW_IS_CI})
-
- if(WEBVIEW_CLANG_TIDY_FOUND)
- set(WEBVIEW_CLANG_TIDY_ARGS)
- if(WEBVIEW_STRICT_CHECKS AND WEBVIEW_STRICT_CLANG_TIDY)
- list(APPEND WEBVIEW_CLANG_TIDY_ARGS "--warnings-as-errors=*")
- endif()
-
- set(CMAKE_C_CLANG_TIDY "${WEBVIEW_CLANG_TIDY_EXE}" ${WEBVIEW_CLANG_TIDY_ARGS})
- set(CMAKE_CXX_CLANG_TIDY "${WEBVIEW_CLANG_TIDY_EXE}" ${WEBVIEW_CLANG_TIDY_ARGS})
- else()
- message(WARNING "Skipping clang-tidy checks as clang-tidy was not found: ${WEBVIEW_CLANG_TIDY_EXE_HINT}")
- endif()
- else()
- # Skip check when clang isn't used with clang-tidy to avoid errors due to unsupported compiler flags
- # such as -fno-keep-inline-dllexport (tested GCC 14, Clang-Tidy 18)
- message(WARNING "Skipping clang-tidy checks with non-clang compiler.")
- endif()
- endif()
- endif()
-
- if(WEBVIEW_BUILD)
- webview_find_dependencies()
- endif()
-endmacro()
-
-function(webview_find_clang_format REQUIRED)
- if(WEBVIEW_CLANG_FORMAT_EXE)
- set(WEBVIEW_CLANG_FORMAT_FOUND TRUE PARENT_SCOPE)
- return()
- endif()
- set(CLANG_FORMAT_EXE_HINT "clang-format")
- set(FIND_ARGS WEBVIEW_CLANG_FORMAT_EXE "${CLANG_FORMAT_EXE_HINT}")
- if(REQUIRED)
- list(APPEND FIND_ARGS REQUIRED)
- endif()
- find_program(${FIND_ARGS})
- if(WEBVIEW_CLANG_FORMAT_EXE)
- set(WEBVIEW_CLANG_FORMAT_FOUND TRUE PARENT_SCOPE)
- else()
- set(WEBVIEW_CLANG_FORMAT_FOUND FALSE PARENT_SCOPE)
- endif()
-endfunction()
-
-function(webview_find_clang_tidy REQUIRED)
- if(WEBVIEW_CLANG_TIDY_EXE)
- set(WEBVIEW_CLANG_TIDY_FOUND TRUE PARENT_SCOPE)
- return()
- endif()
- # Using WEBVIEW_TOOLCHAIN_EXECUTABLE_SUFFIX here because we pair clang-tidy with the clang compiler
- set(WEBVIEW_CLANG_TIDY_EXE_HINT "clang-tidy${WEBVIEW_TOOLCHAIN_EXECUTABLE_SUFFIX}")
- set(FIND_ARGS WEBVIEW_CLANG_TIDY_EXE "${WEBVIEW_CLANG_TIDY_EXE_HINT}")
- if(REQUIRED)
- list(APPEND FIND_ARGS REQUIRED)
- endif()
- find_program(${FIND_ARGS})
- if(WEBVIEW_CLANG_TIDY_EXE)
- set(WEBVIEW_CLANG_TIDY_FOUND TRUE PARENT_SCOPE)
- else()
- set(WEBVIEW_CLANG_TIDY_FOUND FALSE PARENT_SCOPE)
- endif()
-endfunction()
-
-function(webview_find_doxygen REQUIRED)
- if(REQUIRED)
- list(APPEND FIND_ARGS REQUIRED)
- endif()
- list(APPEND FIND_ARGS COMPONENTS dot)
- find_package(Doxygen ${FIND_ARGS})
- set(Doxygen_FOUND "${Doxygen_FOUND}" PARENT_SCOPE)
- set(Doxygen_FOUND_EXECUTABLE "${Doxygen_FOUND_EXECUTABLE}" PARENT_SCOPE)
-endfunction()
-
-function(webview_find_python3 REQUIRED)
- if(REQUIRED)
- list(APPEND FIND_ARGS REQUIRED)
- endif()
- find_package(Python3 ${FIND_ARGS})
- set(Python3_FOUND "${Python3_FOUND}" PARENT_SCOPE)
- set(Python3_EXECUTABLE "${Python3_EXECUTABLE}" PARENT_SCOPE)
-endfunction()
-
-macro(webview_extract_version)
- file(READ "${WEBVIEW_ROOT_DIR}/core/include/webview/version.h" WEBVIEW_H_CONTENT)
-
- if(NOT DEFINED WEBVIEW_VERSION_MAJOR)
- string(REGEX MATCH "#define WEBVIEW_VERSION_MAJOR ([0-9]+)" WEBVIEW_VERSION_MAJOR_MATCH "${WEBVIEW_H_CONTENT}")
- set(WEBVIEW_VERSION_MAJOR "${CMAKE_MATCH_1}")
- endif()
-
- if(NOT DEFINED WEBVIEW_VERSION_MINOR)
- string(REGEX MATCH "#define WEBVIEW_VERSION_MINOR ([0-9]+)" WEBVIEW_VERSION_MINOR_MATCH "${WEBVIEW_H_CONTENT}")
- set(WEBVIEW_VERSION_MINOR "${CMAKE_MATCH_1}")
- endif()
-
- if(NOT DEFINED WEBVIEW_VERSION_PATCH)
- string(REGEX MATCH "#define WEBVIEW_VERSION_PATCH ([0-9]+)" WEBVIEW_VERSION_PATCH_MATCH "${WEBVIEW_H_CONTENT}")
- set(WEBVIEW_VERSION_PATCH "${CMAKE_MATCH_1}")
- endif()
-
- if(NOT DEFINED WEBVIEW_VERSION_PRE_RELEASE)
- string(REGEX MATCH "#define WEBVIEW_VERSION_PRE_RELEASE \"([^\"]*)\"" WEBVIEW_VERSION_PRE_RELEASE_MATCH "${WEBVIEW_H_CONTENT}")
- set(WEBVIEW_VERSION_PRE_RELEASE "${CMAKE_MATCH_1}")
- endif()
-
- if(NOT DEFINED WEBVIEW_VERSION_BUILD_METADATA)
- string(REGEX MATCH "#define WEBVIEW_VERSION_BUILD_METADATA \"([^\"]*)\"" WEBVIEW_VERSION_BUILD_METADATA_MATCH "${WEBVIEW_H_CONTENT}")
- set(WEBVIEW_VERSION_BUILD_METADATA "${CMAKE_MATCH_1}")
- endif()
-
- set(WEBVIEW_VERSION_NUMBER "${WEBVIEW_VERSION_MAJOR}.${WEBVIEW_VERSION_MINOR}.${WEBVIEW_VERSION_PATCH}")
- set(WEBVIEW_VERSION "${WEBVIEW_VERSION_NUMBER}${WEBVIEW_VERSION_PRE_RELEASE}${WEBVIEW_VERSION_BUILD_METADATA}")
-endmacro()
-
-macro(webview_install_targets)
- # Install headers
- install(DIRECTORY "${WEBVIEW_ROOT_DIR}/core/include/webview"
- DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}"
- COMPONENT webview_headers)
-
- # Install modules
- install(DIRECTORY "${WEBVIEW_CURRENT_CMAKE_DIR}/modules"
- DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/webview"
- COMPONENT webview_cmake)
-
- # Install targets
- list(APPEND WEBVIEW_INSTALL_TARGET_NAMES webview_core_headers)
-
- if(WEBVIEW_BUILD_SHARED_LIBRARY)
- list(APPEND WEBVIEW_INSTALL_TARGET_NAMES webview_core_shared)
- endif()
-
- if(WEBVIEW_BUILD_STATIC_LIBRARY)
- list(APPEND WEBVIEW_INSTALL_TARGET_NAMES webview_core_static)
- endif()
-
- if(CMAKE_SYSTEM_NAME STREQUAL "Windows" AND WEBVIEW_USE_COMPAT_MINGW)
- list(APPEND WEBVIEW_INSTALL_TARGET_NAMES webview_compat_mingw)
- endif()
-
- install(TARGETS ${WEBVIEW_INSTALL_TARGET_NAMES}
- COMPONENT webview_libraries_runtime_release
- CONFIGURATIONS Release
- RUNTIME
- DESTINATION "${CMAKE_INSTALL_BINDIR}"
- LIBRARY
- DESTINATION "${CMAKE_INSTALL_LIBDIR}"
- NAMELINK_COMPONENT webview_trash
- ARCHIVE
- DESTINATION "${CMAKE_INSTALL_LIBDIR}"
- COMPONENT webview_trash)
-
- install(TARGETS ${WEBVIEW_INSTALL_TARGET_NAMES}
- EXPORT webview_targets
- COMPONENT webview_libraries
- RUNTIME
- DESTINATION "${CMAKE_INSTALL_BINDIR}"
- LIBRARY
- DESTINATION "${CMAKE_INSTALL_LIBDIR}"
- ARCHIVE
- DESTINATION "${CMAKE_INSTALL_LIBDIR}")
-
- install(EXPORT webview_targets
- DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/webview"
- NAMESPACE webview::
- FILE webview-targets.cmake
- COMPONENT webview_cmake)
-
- export(EXPORT webview_targets FILE "${CMAKE_CURRENT_BINARY_DIR}/webview-targets.cmake")
-
- # Install package config
- configure_package_config_file(
- "${WEBVIEW_CURRENT_CMAKE_DIR}/webview-config.cmake.in"
- "${CMAKE_CURRENT_BINARY_DIR}/webview-config.cmake"
- INSTALL_DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/webview"
- NO_SET_AND_CHECK_MACRO
- NO_CHECK_REQUIRED_COMPONENTS_MACRO)
-
- write_basic_package_version_file(
- "${CMAKE_CURRENT_BINARY_DIR}/webview-config-version.cmake"
- VERSION "${WEBVIEW_VERSION_COMPATIBILITY}"
- COMPATIBILITY SameMinorVersion)
-
- install(
- FILES
- "${WEBVIEW_CURRENT_CMAKE_DIR}/webview.cmake"
- "${CMAKE_CURRENT_BINARY_DIR}/webview-config.cmake"
- "${CMAKE_CURRENT_BINARY_DIR}/webview-config-version.cmake"
- DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/webview"
- COMPONENT webview_cmake)
-endmacro()
-
-macro(webview_internal_options)
- if(CMAKE_CURRENT_SOURCE_DIR STREQUAL CMAKE_SOURCE_DIR)
- set(WEBVIEW_IS_TOP_LEVEL_BUILD TRUE)
- endif()
-
- if(NOT DEFINED WEBVIEW_IS_CI)
- set(WEBVIEW_IS_CI FALSE)
- if("$ENV{CI}" MATCHES "^(1|true|TRUE)$")
- set(WEBVIEW_IS_CI TRUE)
- endif()
- endif()
-
- option(WEBVIEW_BUILD "Enable building" ON)
- cmake_dependent_option(WEBVIEW_BUILD_AMALGAMATION "Build amalgamated library" ON "WEBVIEW_BUILD;WEBVIEW_IS_TOP_LEVEL_BUILD" OFF)
- option(WEBVIEW_BUILD_DOCS "Build documentation" ${WEBVIEW_IS_TOP_LEVEL_BUILD})
- option(WEBVIEW_BUILD_TESTS "Build tests" ${WEBVIEW_IS_TOP_LEVEL_BUILD})
- option(WEBVIEW_BUILD_EXAMPLES "Build examples" ${WEBVIEW_IS_TOP_LEVEL_BUILD})
- option(WEBVIEW_INSTALL_DOCS "Install documentation" ${WEBVIEW_IS_TOP_LEVEL_BUILD})
- option(WEBVIEW_INSTALL_TARGETS "Install targets" ${WEBVIEW_IS_TOP_LEVEL_BUILD})
- option(WEBVIEW_BUILD_SHARED_LIBRARY "Build shared libraries" ON)
- option(WEBVIEW_BUILD_STATIC_LIBRARY "Build static libraries" ON)
- option(WEBVIEW_USE_COMPAT_MINGW "Use compatibility helper for MinGW" ${WEBVIEW_IS_TOP_LEVEL_BUILD})
- option(WEBVIEW_USE_STATIC_MSVC_RUNTIME "Use static runtime library (MSVC)" OFF)
- option(WEBVIEW_ENABLE_CHECKS "Enable checks" ${WEBVIEW_IS_TOP_LEVEL_BUILD})
- option(WEBVIEW_ENABLE_CLANG_FORMAT "Enable clang-format" ${WEBVIEW_ENABLE_CHECKS})
- option(WEBVIEW_ENABLE_CLANG_TIDY "Enable clang-tidy" ${WEBVIEW_ENABLE_CHECKS})
- option(WEBVIEW_ENABLE_PACKAGING "Enable packaging" ${WEBVIEW_IS_TOP_LEVEL_BUILD})
- option(WEBVIEW_STRICT_CHECKS "Make checks strict" ${WEBVIEW_IS_CI})
- cmake_dependent_option(WEBVIEW_PACKAGE_AMALGAMATION "Package amalgamated library" ON WEBVIEW_ENABLE_PACKAGING OFF)
- cmake_dependent_option(WEBVIEW_PACKAGE_DOCS "Package documentation" ON WEBVIEW_ENABLE_PACKAGING OFF)
- cmake_dependent_option(WEBVIEW_PACKAGE_HEADERS "Package headers" ON WEBVIEW_ENABLE_PACKAGING OFF)
- cmake_dependent_option(WEBVIEW_PACKAGE_LIB "Package compiled libraries" ON WEBVIEW_ENABLE_PACKAGING OFF)
- option(WEBVIEW_STRICT_CLANG_FORMAT "Make clang-format check strict" ${WEBVIEW_STRICT_CHECKS})
- option(WEBVIEW_STRICT_CLANG_TIDY "Make clang-tidy check strict" ${WEBVIEW_STRICT_CHECKS})
-endmacro()
-
-macro(webview_set_install_rpath)
- if(CMAKE_SYSTEM_NAME STREQUAL "Darwin" OR CMAKE_SYSTEM_NAME STREQUAL "Linux")
- # RPATH/RUNPATH
- if(CMAKE_SYSTEM_NAME STREQUAL "Darwin")
- set(RPATH_BASE @loader_path)
- else()
- set(RPATH_BASE $ORIGIN)
- endif()
-
- file(RELATIVE_PATH RPATH_SUBDIR
- "${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_INSTALL_BINDIR}"
- "${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_INSTALL_LIBDIR}")
- set(CMAKE_INSTALL_RPATH "${RPATH_BASE}" "${RPATH_BASE}/${RPATH_SUBDIR}")
- endif()
-endmacro()
diff --git a/cmake/modules/FindMSWebView2.cmake b/cmake/modules/FindMSWebView2.cmake
deleted file mode 100644
index 5f4b8470c..000000000
--- a/cmake/modules/FindMSWebView2.cmake
+++ /dev/null
@@ -1,20 +0,0 @@
-if(DEFINED MSWebView2_ROOT)
- find_path(MSWebView2_INCLUDE_DIR WebView2.h
- PATHS
- "${MSWebView2_ROOT}/build/native"
- "${MSWebView2_ROOT}"
- PATH_SUFFIXES include
- NO_CMAKE_FIND_ROOT_PATH)
-endif()
-
-include(FindPackageHandleStandardArgs)
-find_package_handle_standard_args(MSWebView2 REQUIRED_VARS MSWebView2_INCLUDE_DIR)
-
-if(MSWebView2_FOUND)
- if(NOT TARGET MSWebView2::headers)
- add_library(MSWebView2::headers INTERFACE IMPORTED)
- set_target_properties(MSWebView2::headers PROPERTIES
- INTERFACE_INCLUDE_DIRECTORIES "${MSWebView2_INCLUDE_DIR}")
- target_compile_features(MSWebView2::headers INTERFACE cxx_std_11)
- endif()
-endif()
diff --git a/cmake/toolchains/arm64-windows-msvc.cmake b/cmake/toolchains/arm64-windows-msvc.cmake
deleted file mode 100644
index d18504cb0..000000000
--- a/cmake/toolchains/arm64-windows-msvc.cmake
+++ /dev/null
@@ -1,7 +0,0 @@
-set(CMAKE_SYSTEM_NAME Windows)
-set(CMAKE_SYSTEM_PROCESSOR ARM64)
-
-set(CMAKE_C_COMPILER cl)
-set(CMAKE_CXX_COMPILER cl)
-
-set(CMAKE_GENERATOR_PLATFORM ARM64 CACHE INTERNAL "")
diff --git a/cmake/toolchains/host-gnu.cmake b/cmake/toolchains/host-gnu.cmake
deleted file mode 100644
index 64968bf01..000000000
--- a/cmake/toolchains/host-gnu.cmake
+++ /dev/null
@@ -1,2 +0,0 @@
-set(CMAKE_C_COMPILER "gcc${WEBVIEW_TOOLCHAIN_EXECUTABLE_SUFFIX}")
-set(CMAKE_CXX_COMPILER "g++${WEBVIEW_TOOLCHAIN_EXECUTABLE_SUFFIX}")
diff --git a/cmake/toolchains/host-llvm.cmake b/cmake/toolchains/host-llvm.cmake
deleted file mode 100644
index 15d7c10ac..000000000
--- a/cmake/toolchains/host-llvm.cmake
+++ /dev/null
@@ -1,2 +0,0 @@
-set(CMAKE_C_COMPILER "clang${WEBVIEW_TOOLCHAIN_EXECUTABLE_SUFFIX}")
-set(CMAKE_CXX_COMPILER "clang++${WEBVIEW_TOOLCHAIN_EXECUTABLE_SUFFIX}")
diff --git a/cmake/toolchains/i686-w64-mingw32.cmake b/cmake/toolchains/i686-w64-mingw32.cmake
deleted file mode 100644
index 437f14a59..000000000
--- a/cmake/toolchains/i686-w64-mingw32.cmake
+++ /dev/null
@@ -1,12 +0,0 @@
-set(CMAKE_SYSTEM_NAME Windows)
-set(CMAKE_SYSTEM_PROCESSOR i686)
-
-set(CMAKE_SYSROOT /usr/i686-w64-mingw32)
-set(CMAKE_C_COMPILER "i686-w64-mingw32-gcc${WEBVIEW_TOOLCHAIN_EXECUTABLE_SUFFIX}")
-set(CMAKE_CXX_COMPILER "i686-w64-mingw32-g++${WEBVIEW_TOOLCHAIN_EXECUTABLE_SUFFIX}")
-set(CMAKE_RANLIB i686-w64-mingw32-ranlib)
-set(CMAKE_RC_COMPILER i686-w64-mingw32-windres)
-
-set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
-set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
-set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
diff --git a/cmake/toolchains/i686-windows-msvc.cmake b/cmake/toolchains/i686-windows-msvc.cmake
deleted file mode 100644
index c1eb59915..000000000
--- a/cmake/toolchains/i686-windows-msvc.cmake
+++ /dev/null
@@ -1,7 +0,0 @@
-set(CMAKE_SYSTEM_NAME Windows)
-set(CMAKE_SYSTEM_PROCESSOR x86)
-
-set(CMAKE_C_COMPILER cl)
-set(CMAKE_CXX_COMPILER cl)
-
-set(CMAKE_GENERATOR_PLATFORM Win32 CACHE INTERNAL "")
diff --git a/cmake/toolchains/universal-macos-llvm.cmake b/cmake/toolchains/universal-macos-llvm.cmake
deleted file mode 100644
index 70cf0e509..000000000
--- a/cmake/toolchains/universal-macos-llvm.cmake
+++ /dev/null
@@ -1,6 +0,0 @@
-set(CMAKE_SYSTEM_NAME Darwin)
-
-set(CMAKE_C_COMPILER "clang${WEBVIEW_TOOLCHAIN_EXECUTABLE_SUFFIX}")
-set(CMAKE_CXX_COMPILER "clang++${WEBVIEW_TOOLCHAIN_EXECUTABLE_SUFFIX}")
-
-set(CMAKE_OSX_ARCHITECTURES "arm64;x86_64" CACHE INTERNAL "")
diff --git a/cmake/toolchains/x86_64-msys2-gnu-ucrt64.cmake b/cmake/toolchains/x86_64-msys2-gnu-ucrt64.cmake
deleted file mode 100644
index 4e40c10c4..000000000
--- a/cmake/toolchains/x86_64-msys2-gnu-ucrt64.cmake
+++ /dev/null
@@ -1,7 +0,0 @@
-set(CMAKE_SYSTEM_NAME Windows)
-set(CMAKE_SYSTEM_PROCESSOR x86_64)
-
-set(CMAKE_C_COMPILER "gcc${WEBVIEW_TOOLCHAIN_EXECUTABLE_SUFFIX}")
-set(CMAKE_CXX_COMPILER "g++${WEBVIEW_TOOLCHAIN_EXECUTABLE_SUFFIX}")
-
-set(MSYSTEM ucrt64 CACHE INTERNAL "")
diff --git a/cmake/toolchains/x86_64-msys2-llvm-clang64.cmake b/cmake/toolchains/x86_64-msys2-llvm-clang64.cmake
deleted file mode 100644
index ac5d98f21..000000000
--- a/cmake/toolchains/x86_64-msys2-llvm-clang64.cmake
+++ /dev/null
@@ -1,7 +0,0 @@
-set(CMAKE_SYSTEM_NAME Windows)
-set(CMAKE_SYSTEM_PROCESSOR x86_64)
-
-set(CMAKE_C_COMPILER "clang${WEBVIEW_TOOLCHAIN_EXECUTABLE_SUFFIX}")
-set(CMAKE_CXX_COMPILER "clang++${WEBVIEW_TOOLCHAIN_EXECUTABLE_SUFFIX}")
-
-set(MSYSTEM clang64 CACHE INTERNAL "")
diff --git a/cmake/toolchains/x86_64-w64-mingw32.cmake b/cmake/toolchains/x86_64-w64-mingw32.cmake
deleted file mode 100644
index 89b862309..000000000
--- a/cmake/toolchains/x86_64-w64-mingw32.cmake
+++ /dev/null
@@ -1,12 +0,0 @@
-set(CMAKE_SYSTEM_NAME Windows)
-set(CMAKE_SYSTEM_PROCESSOR x86_64)
-
-set(CMAKE_SYSROOT /usr/x86_64-w64-mingw32)
-set(CMAKE_C_COMPILER "x86_64-w64-mingw32-gcc${WEBVIEW_TOOLCHAIN_EXECUTABLE_SUFFIX}")
-set(CMAKE_CXX_COMPILER "x86_64-w64-mingw32-g++${WEBVIEW_TOOLCHAIN_EXECUTABLE_SUFFIX}")
-set(CMAKE_RANLIB x86_64-w64-mingw32-ranlib)
-set(CMAKE_RC_COMPILER x86_64-w64-mingw32-windres)
-
-set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
-set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
-set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
diff --git a/cmake/toolchains/x86_64-windows-msvc.cmake b/cmake/toolchains/x86_64-windows-msvc.cmake
deleted file mode 100644
index b1e2f2be4..000000000
--- a/cmake/toolchains/x86_64-windows-msvc.cmake
+++ /dev/null
@@ -1,7 +0,0 @@
-set(CMAKE_SYSTEM_NAME Windows)
-set(CMAKE_SYSTEM_PROCESSOR AMD64)
-
-set(CMAKE_C_COMPILER cl)
-set(CMAKE_CXX_COMPILER cl)
-
-set(CMAKE_GENERATOR_PLATFORM x64 CACHE INTERNAL "")
diff --git a/cmake/webview-config.cmake.in b/cmake/webview-config.cmake.in
deleted file mode 100644
index 932aca184..000000000
--- a/cmake/webview-config.cmake.in
+++ /dev/null
@@ -1,10 +0,0 @@
-@PACKAGE_INIT@
-
-include(CMakeFindDependencyMacro)
-include("${CMAKE_CURRENT_LIST_DIR}/webview.cmake")
-list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}/modules")
-
-webview_options()
-webview_find_dependencies()
-
-include("${CMAKE_CURRENT_LIST_DIR}/webview-targets.cmake")
diff --git a/cmake/webview.cmake b/cmake/webview.cmake
deleted file mode 100644
index e2a6acb0a..000000000
--- a/cmake/webview.cmake
+++ /dev/null
@@ -1,92 +0,0 @@
-macro(webview_options)
- if(CMAKE_SYSTEM_NAME STREQUAL "Windows")
- set(WEBVIEW_MSWEBVIEW2_VERSION "1.0.1150.38" CACHE STRING "MS WebView2 version")
- option(WEBVIEW_USE_BUILTIN_MSWEBVIEW2 "Use built-in MS WebView2" ON)
- endif()
-endmacro()
-
-macro(webview_find_dependencies)
- if(CMAKE_SYSTEM_NAME STREQUAL "Darwin")
- list(APPEND WEBVIEW_DEPENDENCIES "-framework WebKit" dl)
- elseif(CMAKE_SYSTEM_NAME STREQUAL "Windows")
- if(WEBVIEW_USE_BUILTIN_MSWEBVIEW2)
- find_package(MSWebView2 QUIET)
- if(NOT MSWebView2_FOUND)
- webview_fetch_mswebview2(${WEBVIEW_MSWEBVIEW2_VERSION})
- endif()
- find_package(MSWebView2 REQUIRED)
- if(MSWebView2_FOUND)
- list(APPEND WEBVIEW_DEPENDENCIES MSWebView2::headers)
- endif()
- endif()
- list(APPEND WEBVIEW_DEPENDENCIES advapi32 ole32 shell32 shlwapi user32 version)
- else()
- find_package(PkgConfig REQUIRED)
-
- # List of preferred WebkitGTK modules (from most to least preferred)
- set(WEBVIEW_WEBKITGTK_PREFERRED_API_LIST webkit2gtk-4.1)
- # List of known WebkitGTK modules (from higher to lower version)
- set(WEBVIEW_WEBKITGTK_KNOWN_API_LIST webkitgtk-6.0 webkit2gtk-4.1 webkit2gtk-4.0)
-
- # Try to find specific WebKitGTK API
- if(NOT "${WEBVIEW_WEBKITGTK_API}" STREQUAL "")
- if(WEBVIEW_WEBKITGTK_API VERSION_EQUAL 6.0)
- pkg_check_modules(WEBVIEW_WEBKITGTK REQUIRED IMPORTED_TARGET webkitgtk-6.0)
- elseif(WEBVIEW_WEBKITGTK_API VERSION_EQUAL 4.1)
- pkg_check_modules(WEBVIEW_WEBKITGTK REQUIRED IMPORTED_TARGET webkit2gtk-4.1)
- elseif(WEBVIEW_WEBKITGTK_API VERSION_EQUAL 4.0)
- pkg_check_modules(WEBVIEW_WEBKITGTK REQUIRED IMPORTED_TARGET webkit2gtk-4.0)
- else()
- message(FATAL_ERROR "Unsupported WebKitGTK API: ${WEBVIEW_WEBKITGTK_API}")
- endif()
- endif()
-
- if("${WEBVIEW_WEBKITGTK_MODULE_NAME}" STREQUAL "")
- # Try to find a preferred WebKitGTK API
- pkg_search_module(WEBVIEW_WEBKITGTK IMPORTED_TARGET ${WEBVIEW_WEBKITGTK_PREFERRED_API_LIST})
- if (NOT WEBVIEW_WEBKITGTK_FOUND)
- message(STATUS "Trying to find any WebKitGTK API")
- pkg_search_module(WEBVIEW_WEBKITGTK REQUIRED IMPORTED_TARGET ${WEBVIEW_WEBKITGTK_KNOWN_API_LIST})
- endif()
- else()
- pkg_check_modules(WEBVIEW_WEBKITGTK REQUIRED IMPORTED_TARGET "${WEBVIEW_WEBKITGTK_MODULE_NAME}")
- endif()
-
- if("${WEBVIEW_WEBKITGTK_MODULE_NAME}" STREQUAL "webkitgtk-6.0")
- set(WEBVIEW_WEBKITGTK_API 6.0)
- elseif("${WEBVIEW_WEBKITGTK_MODULE_NAME}" STREQUAL "webkit2gtk-4.1")
- set(WEBVIEW_WEBKITGTK_API 4.1)
- elseif("${WEBVIEW_WEBKITGTK_MODULE_NAME}" STREQUAL "webkit2gtk-4.0")
- set(WEBVIEW_WEBKITGTK_API 4.0)
- else()
- message(FATAL_ERROR "Couldn't find any supported WebKitGTK API")
- endif()
-
- # Find matching GTK module
- if("${WEBVIEW_WEBKITGTK_API}" VERSION_GREATER_EQUAL 6.0)
- pkg_check_modules(WEBVIEW_GTK REQUIRED IMPORTED_TARGET gtk4)
- elseif("${WEBVIEW_WEBKITGTK_API}" VERSION_LESS 5.0)
- pkg_check_modules(WEBVIEW_GTK REQUIRED IMPORTED_TARGET gtk+-3.0)
- endif()
-
- list(APPEND WEBVIEW_DEPENDENCIES PkgConfig::WEBVIEW_WEBKITGTK PkgConfig::WEBVIEW_GTK dl)
- endif()
-endmacro()
-
-function(webview_fetch_mswebview2 VERSION)
- cmake_policy(PUSH)
- # Avoid warning related to FetchContent and DOWNLOAD_EXTRACT_TIMESTAMP
- if(POLICY CMP0135)
- cmake_policy(SET CMP0135 NEW)
- endif()
- if(NOT COMMAND FetchContent_Declare)
- include(FetchContent)
- endif()
- set(FC_NAME microsoft_web_webview2)
- FetchContent_Declare(${FC_NAME}
- URL "https://www.nuget.org/api/v2/package/Microsoft.Web.WebView2/${VERSION}")
- FetchContent_MakeAvailable(${FC_NAME})
- set(MSWebView2_ROOT "${${FC_NAME}_SOURCE_DIR}")
- set(MSWebView2_ROOT "${MSWebView2_ROOT}" PARENT_SCOPE)
- cmake_policy(POP)
-endfunction()
diff --git a/compatibility/CMakeLists.txt b/compatibility/CMakeLists.txt
deleted file mode 100644
index 29567e055..000000000
--- a/compatibility/CMakeLists.txt
+++ /dev/null
@@ -1,3 +0,0 @@
-if(WEBVIEW_USE_COMPAT_MINGW)
- add_subdirectory(mingw)
-endif()
diff --git a/compatibility/mingw/CMakeLists.txt b/compatibility/mingw/CMakeLists.txt
deleted file mode 100644
index 048680622..000000000
--- a/compatibility/mingw/CMakeLists.txt
+++ /dev/null
@@ -1,14 +0,0 @@
-# Compatibility target for MinGW that can be used to work around missing
-# "EventToken.h" header (used by MS WebView2) when targetting Windows.
-
-if(CMAKE_SYSTEM_NAME STREQUAL "Windows")
- add_library(webview_compat_mingw INTERFACE)
- add_library(webview::compat_mingw ALIAS webview_compat_mingw)
- set_target_properties(webview_compat_mingw PROPERTIES
- EXPORT_NAME compat_mingw)
- target_include_directories(
- webview_compat_mingw
- INTERFACE
- "$"
- "$")
-endif()
diff --git a/compatibility/mingw/include/EventToken.h b/compatibility/mingw/include/EventToken.h
deleted file mode 100644
index 3099e66ba..000000000
--- a/compatibility/mingw/include/EventToken.h
+++ /dev/null
@@ -1,25 +0,0 @@
-#ifndef WEBVIEW_COMPAT_EVENTTOKEN_H
-#define WEBVIEW_COMPAT_EVENTTOKEN_H
-#ifdef _WIN32
-
-// This compatibility header provides types used by MS WebView2. This header can
-// be used as an alternative to the "EventToken.h" header normally provided by
-// the Windows SDK. Depending on the MinGW distribution, this header may not be
-// present, or it may be present with the name "eventtoken.h". The letter casing
-// matters when cross-compiling on a system with case-sensitive file names.
-
-#ifndef __eventtoken_h__
-
-#ifdef __cplusplus
-#include
-#else
-#include
-#endif
-
-typedef struct EventRegistrationToken {
- int64_t value;
-} EventRegistrationToken;
-#endif // __eventtoken_h__
-
-#endif // _WIN32
-#endif // WEBVIEW_COMPAT_EVENTTOKEN_H
diff --git a/core/CMakeLists.txt b/core/CMakeLists.txt
deleted file mode 100644
index 5c2083c73..000000000
--- a/core/CMakeLists.txt
+++ /dev/null
@@ -1,94 +0,0 @@
-# Core header library
-add_library(webview_core_headers INTERFACE)
-add_library(webview::core ALIAS webview_core_headers)
-target_include_directories(
- webview_core_headers
- INTERFACE
- "$"
- "$")
-target_link_libraries(webview_core_headers INTERFACE ${WEBVIEW_DEPENDENCIES})
-# Note that we also use CMAKE_CXX_STANDARD which can override this
-target_compile_features(webview_core_headers INTERFACE cxx_std_11)
-set_target_properties(webview_core_headers PROPERTIES
- EXPORT_NAME core)
-
-if(CMAKE_SYSTEM_NAME STREQUAL "Windows" AND WEBVIEW_USE_COMPAT_MINGW)
- target_link_libraries(webview_core_headers INTERFACE webview::compat_mingw)
-endif()
-
-# Core shared library
-if(WEBVIEW_BUILD_SHARED_LIBRARY)
- add_library(webview_core_shared SHARED)
- add_library(webview::core_shared ALIAS webview_core_shared)
- target_sources(webview_core_shared PRIVATE src/webview.cc)
- target_link_libraries(webview_core_shared PUBLIC webview_core_headers)
- set_target_properties(webview_core_shared PROPERTIES
- OUTPUT_NAME webview
- VERSION "${WEBVIEW_VERSION_NUMBER}"
- SOVERSION "${WEBVIEW_VERSION_COMPATIBILITY}"
- EXPORT_NAME core_shared)
- target_compile_definitions(webview_core_shared
- INTERFACE WEBVIEW_SHARED
- PRIVATE WEBVIEW_BUILD_SHARED)
-endif()
-
-# Core static library
-if(WEBVIEW_BUILD_STATIC_LIBRARY)
- # Change .lib file name for MSVC because otherwise it would be the same for shared and static
- if(MSVC)
- set(STATIC_LIBRARY_OUTPUT_NAME webview_static)
- else()
- set(STATIC_LIBRARY_OUTPUT_NAME webview)
- endif()
-
- add_library(webview_core_static STATIC)
- add_library(webview::core_static ALIAS webview_core_static)
- target_sources(webview_core_static PRIVATE src/webview.cc)
- target_link_libraries(webview_core_static PUBLIC webview_core_headers)
- set_target_properties(webview_core_static PROPERTIES
- OUTPUT_NAME "${STATIC_LIBRARY_OUTPUT_NAME}"
- POSITION_INDEPENDENT_CODE ON
- EXPORT_NAME core_static)
- target_compile_definitions(webview_core_static PUBLIC WEBVIEW_STATIC)
-endif()
-
-if(WEBVIEW_BUILD_TESTS)
- add_subdirectory(tests)
-endif()
-
-if(WEBVIEW_BUILD_AMALGAMATION)
- webview_find_python3(${WEBVIEW_IS_CI})
- if(Python3_FOUND)
- webview_find_clang_format(${WEBVIEW_IS_CI})
- if(WEBVIEW_CLANG_FORMAT_EXE)
- file(GLOB_RECURSE HEADER_FILES CONFIGURE_DEPENDS include/**)
- file(GLOB_RECURSE SOURCE_FILES CONFIGURE_DEPENDS src/**)
- set(AMALGAMATION_STAMP_FILE "${CMAKE_CURRENT_BINARY_DIR}/amalgamation/webview.h.stamp")
-
- add_custom_command(
- OUTPUT "${AMALGAMATION_STAMP_FILE}"
- COMMAND "${CMAKE_COMMAND}" -E touch "${AMALGAMATION_STAMP_FILE}"
- COMMAND ${Python3_EXECUTABLE}
- "${PROJECT_SOURCE_DIR}/scripts/amalgamate/amalgamate.py"
- --clang-format-exe "${WEBVIEW_CLANG_FORMAT_EXE}"
- --base "${CMAKE_CURRENT_SOURCE_DIR}"
- --search include
- --output "${CMAKE_CURRENT_BINARY_DIR}/amalgamation/webview.h"
- ${SOURCE_FILES}
- DEPENDS ${HEADER_FILES} ${SOURCE_FILES}
- COMMENT "Building amalgamation..."
- VERBATIM)
-
- add_custom_target(webview_amalgamate ALL
- DEPENDS "${AMALGAMATION_STAMP_FILE}")
-
- install(FILES "${CMAKE_CURRENT_BINARY_DIR}/amalgamation/webview.h"
- DESTINATION .
- COMPONENT webview_amalgamation)
- else()
- message(WARNING "Skipping amalgamation as clang-format was not found")
- endif()
- else()
- message(WARNING "Skipping amalgamation as Python 3 was not found")
- endif()
-endif()
diff --git a/core/include/webview.h b/core/include/webview.h
deleted file mode 100644
index c84d8ed5a..000000000
--- a/core/include/webview.h
+++ /dev/null
@@ -1,15 +0,0 @@
-/**
- * @file webview.h
- *
- * @deprecated This header file is deprecated. Use `webview/webview.h` instead.
- *
- * This file is provided for backward-compatibility with existing code
- * such as `#include "webview.h"`.
- */
-
-#ifndef WEBVIEW_ROOT_H
-#define WEBVIEW_ROOT_H
-
-#include "webview/webview.h"
-
-#endif // WEBVIEW_ROOT_H
diff --git a/core/include/webview/api.h b/core/include/webview/api.h
deleted file mode 100644
index aecc050e0..000000000
--- a/core/include/webview/api.h
+++ /dev/null
@@ -1,251 +0,0 @@
-/*
- * MIT License
- *
- * Copyright (c) 2017 Serge Zaitsev
- * Copyright (c) 2022 Steffen André Langnes
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
-#ifndef WEBVIEW_API_H
-#define WEBVIEW_API_H
-
-#include "errors.h"
-#include "macros.h"
-#include "types.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/**
- * Creates a new webview instance.
- *
- * @param debug Enable developer tools if supported by the backend.
- * @param window Optional native window handle, i.e. @c GtkWindow pointer
- * @c NSWindow pointer (Cocoa) or @c HWND (Win32). If non-null,
- * the webview widget is embedded into the given window, and the
- * caller is expected to assume responsibility for the window as
- * well as application lifecycle. If the window handle is null,
- * a new window is created and both the window and application
- * lifecycle are managed by the webview instance.
- * @remark Win32: The function also accepts a pointer to @c HWND (Win32) in the
- * window parameter for backward compatibility.
- * @remark Win32/WebView2: @c CoInitializeEx should be called with
- * @c COINIT_APARTMENTTHREADED before attempting to call this function
- * with an existing window. Omitting this step may cause WebView2
- * initialization to fail.
- * @return @c NULL on failure. Creation can fail for various reasons such
- * as when required runtime dependencies are missing or when window
- * creation fails.
- * @retval WEBVIEW_ERROR_MISSING_DEPENDENCY
- * May be returned if WebView2 is unavailable on Windows.
- */
-WEBVIEW_API webview_t webview_create(int debug, void *window);
-
-/**
- * Destroys a webview instance and closes the native window.
- *
- * @param w The webview instance.
- */
-WEBVIEW_API webview_error_t webview_destroy(webview_t w);
-
-/**
- * Runs the main loop until it's terminated.
- *
- * @param w The webview instance.
- */
-WEBVIEW_API webview_error_t webview_run(webview_t w);
-
-/**
- * Stops the main loop. It is safe to call this function from another
- * background thread.
- *
- * @param w The webview instance.
- */
-WEBVIEW_API webview_error_t webview_terminate(webview_t w);
-
-/**
- * Schedules a function to be invoked on the thread with the run/event loop.
- *
- * Since library functions generally do not have thread safety guarantees,
- * this function can be used to schedule code to execute on the main/GUI
- * thread and thereby make that execution safe in multi-threaded applications.
- *
- * @param w The webview instance.
- * @param fn The function to be invoked.
- * @param arg An optional argument passed along to the callback function.
- */
-WEBVIEW_API webview_error_t webview_dispatch(webview_t w,
- void (*fn)(webview_t w, void *arg),
- void *arg);
-
-/**
- * Returns the native handle of the window associated with the webview instance.
- * The handle can be a @c GtkWindow pointer (GTK), @c NSWindow pointer (Cocoa)
- * or @c HWND (Win32).
- *
- * @param w The webview instance.
- * @return The handle of the native window.
- */
-WEBVIEW_API void *webview_get_window(webview_t w);
-
-/**
- * Get a native handle of choice.
- *
- * @param w The webview instance.
- * @param kind The kind of handle to retrieve.
- * @return The native handle or @c NULL.
- * @since 0.11
- */
-WEBVIEW_API void *webview_get_native_handle(webview_t w,
- webview_native_handle_kind_t kind);
-
-/**
- * Updates the title of the native window.
- *
- * @param w The webview instance.
- * @param title The new title.
- */
-WEBVIEW_API webview_error_t webview_set_title(webview_t w, const char *title);
-
-/**
- * Updates the size of the native window.
- *
- * Remarks:
- * - Subsequent calls to this function may behave inconsistently across
- * different versions of GTK and windowing systems (X11/Wayland).
- * - Using WEBVIEW_HINT_MAX for setting the maximum window size is not
- * supported with GTK 4 because X11-specific functions such as
- * gtk_window_set_geometry_hints were removed. This option has no effect
- * when using GTK 4.
- *
- * @param w The webview instance.
- * @param width New width.
- * @param height New height.
- * @param hints Size hints.
- */
-WEBVIEW_API webview_error_t webview_set_size(webview_t w, int width, int height,
- webview_hint_t hints);
-
-/**
- * Navigates webview to the given URL. URL may be a properly encoded data URI.
- *
- * Example:
- * @code{.c}
- * webview_navigate(w, "https://github.com/webview/webview");
- * webview_navigate(w, "data:text/html,%3Ch1%3EHello%3C%2Fh1%3E");
- * webview_navigate(w, "data:text/html;base64,PGgxPkhlbGxvPC9oMT4=");
- * @endcode
- *
- * @param w The webview instance.
- * @param url URL.
- */
-WEBVIEW_API webview_error_t webview_navigate(webview_t w, const char *url);
-
-/**
- * Load HTML content into the webview.
- *
- * Example:
- * @code{.c}
- * webview_set_html(w, "Hello
");
- * @endcode
- *
- * @param w The webview instance.
- * @param html HTML content.
- */
-WEBVIEW_API webview_error_t webview_set_html(webview_t w, const char *html);
-
-/**
- * Injects JavaScript code to be executed immediately upon loading a page.
- * The code will be executed before @c window.onload.
- *
- * @param w The webview instance.
- * @param js JS content.
- */
-WEBVIEW_API webview_error_t webview_init(webview_t w, const char *js);
-
-/**
- * Evaluates arbitrary JavaScript code.
- *
- * Use bindings if you need to communicate the result of the evaluation.
- *
- * @param w The webview instance.
- * @param js JS content.
- */
-WEBVIEW_API webview_error_t webview_eval(webview_t w, const char *js);
-
-/**
- * Binds a function pointer to a new global JavaScript function.
- *
- * Internally, JS glue code is injected to create the JS function by the
- * given name. The callback function is passed a request identifier,
- * a request string and a user-provided argument. The request string is
- * a JSON array of the arguments passed to the JS function.
- *
- * @param w The webview instance.
- * @param name Name of the JS function.
- * @param fn Callback function.
- * @param arg User argument.
- * @retval WEBVIEW_ERROR_DUPLICATE
- * A binding already exists with the specified name.
- */
-WEBVIEW_API webview_error_t webview_bind(webview_t w, const char *name,
- void (*fn)(const char *id,
- const char *req, void *arg),
- void *arg);
-
-/**
- * Removes a binding created with webview_bind().
- *
- * @param w The webview instance.
- * @param name Name of the binding.
- * @retval WEBVIEW_ERROR_NOT_FOUND No binding exists with the specified name.
- */
-WEBVIEW_API webview_error_t webview_unbind(webview_t w, const char *name);
-
-/**
- * Responds to a binding call from the JS side.
- *
- * This function is safe to call from another thread.
- *
- * @param w The webview instance.
- * @param id The identifier of the binding call. Pass along the value received
- * in the binding handler (see webview_bind()).
- * @param status A status of zero tells the JS side that the binding call was
- * successful; any other value indicates an error.
- * @param result The result of the binding call to be returned to the JS side.
- * This must either be a valid JSON value or an empty string for
- * the primitive JS value @c undefined.
- */
-WEBVIEW_API webview_error_t webview_return(webview_t w, const char *id,
- int status, const char *result);
-
-/**
- * Get the library's version information.
- *
- * @since 0.10
- */
-WEBVIEW_API const webview_version_info_t *webview_version(void);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif // WEBVIEW_API_H
diff --git a/core/include/webview/c_api_impl.hh b/core/include/webview/c_api_impl.hh
deleted file mode 100644
index 8ee1d942d..000000000
--- a/core/include/webview/c_api_impl.hh
+++ /dev/null
@@ -1,258 +0,0 @@
-/*
- * MIT License
- *
- * Copyright (c) 2017 Serge Zaitsev
- * Copyright (c) 2022 Steffen André Langnes
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
-#ifndef WEBVIEW_C_API_IMPL_HH
-#define WEBVIEW_C_API_IMPL_HH
-
-#if defined(__cplusplus) && !defined(WEBVIEW_HEADER)
-
-#include "backends.hh"
-#include "errors.h"
-#include "errors.hh"
-#include "json_deprecated.hh"
-#include "macros.h"
-#include "types.h"
-#include "version.h"
-
-namespace webview {
-namespace detail {
-
-// The library's version information.
-constexpr const webview_version_info_t library_version_info{
- {WEBVIEW_VERSION_MAJOR, WEBVIEW_VERSION_MINOR, WEBVIEW_VERSION_PATCH},
- WEBVIEW_VERSION_NUMBER,
- WEBVIEW_VERSION_PRE_RELEASE,
- WEBVIEW_VERSION_BUILD_METADATA};
-
-template
-webview_error_t api_filter(WorkFn &&do_work, ResultFn &&put_result) noexcept {
- try {
- auto result = do_work();
- if (result.ok()) {
- put_result(result.value());
- return WEBVIEW_ERROR_OK;
- }
- return result.error().code();
- } catch (const exception &e) {
- return e.error().code();
- } catch (...) {
- return WEBVIEW_ERROR_UNSPECIFIED;
- }
-}
-
-template
-webview_error_t api_filter(WorkFn &&do_work) noexcept {
- try {
- auto result = do_work();
- if (result.ok()) {
- return WEBVIEW_ERROR_OK;
- }
- return result.error().code();
- } catch (const exception &e) {
- return e.error().code();
- } catch (...) {
- return WEBVIEW_ERROR_UNSPECIFIED;
- }
-}
-
-inline webview *cast_to_webview(void *w) {
- if (!w) {
- throw exception{WEBVIEW_ERROR_INVALID_ARGUMENT,
- "Cannot cast null pointer to webview instance"};
- }
- return static_cast(w);
-}
-
-} // namespace detail
-} // namespace webview
-
-WEBVIEW_API webview_t webview_create(int debug, void *wnd) {
- using namespace webview::detail;
- webview::webview *w{};
- auto err = api_filter(
- [=]() -> webview::result {
- return new webview::webview{static_cast(debug), wnd};
- },
- [&](webview::webview *w_) { w = w_; });
- if (err == WEBVIEW_ERROR_OK) {
- return w;
- }
- return nullptr;
-}
-
-WEBVIEW_API webview_error_t webview_destroy(webview_t w) {
- using namespace webview::detail;
- return api_filter([=]() -> webview::noresult {
- delete cast_to_webview(w);
- return {};
- });
-}
-
-WEBVIEW_API webview_error_t webview_run(webview_t w) {
- using namespace webview::detail;
- return api_filter([=] { return cast_to_webview(w)->run(); });
-}
-
-WEBVIEW_API webview_error_t webview_terminate(webview_t w) {
- using namespace webview::detail;
- return api_filter([=] { return cast_to_webview(w)->terminate(); });
-}
-
-WEBVIEW_API webview_error_t webview_dispatch(webview_t w,
- void (*fn)(webview_t, void *),
- void *arg) {
- using namespace webview::detail;
- if (!fn) {
- return WEBVIEW_ERROR_INVALID_ARGUMENT;
- }
- return api_filter(
- [=] { return cast_to_webview(w)->dispatch([=]() { fn(w, arg); }); });
-}
-
-WEBVIEW_API void *webview_get_window(webview_t w) {
- using namespace webview::detail;
- void *window = nullptr;
- auto err = api_filter([=] { return cast_to_webview(w)->window(); },
- [&](void *value) { window = value; });
- if (err == WEBVIEW_ERROR_OK) {
- return window;
- }
- return nullptr;
-}
-
-WEBVIEW_API void *webview_get_native_handle(webview_t w,
- webview_native_handle_kind_t kind) {
- using namespace webview::detail;
- void *handle{};
- auto err = api_filter(
- [=]() -> webview::result {
- auto *w_ = cast_to_webview(w);
- switch (kind) {
- case WEBVIEW_NATIVE_HANDLE_KIND_UI_WINDOW:
- return w_->window();
- case WEBVIEW_NATIVE_HANDLE_KIND_UI_WIDGET:
- return w_->widget();
- case WEBVIEW_NATIVE_HANDLE_KIND_BROWSER_CONTROLLER:
- return w_->browser_controller();
- default:
- return webview::error_info{WEBVIEW_ERROR_INVALID_ARGUMENT};
- }
- },
- [&](void *handle_) { handle = handle_; });
- if (err == WEBVIEW_ERROR_OK) {
- return handle;
- }
- return nullptr;
-}
-
-WEBVIEW_API webview_error_t webview_set_title(webview_t w, const char *title) {
- using namespace webview::detail;
- if (!title) {
- return WEBVIEW_ERROR_INVALID_ARGUMENT;
- }
- return api_filter([=] { return cast_to_webview(w)->set_title(title); });
-}
-
-WEBVIEW_API webview_error_t webview_set_size(webview_t w, int width, int height,
- webview_hint_t hints) {
- using namespace webview::detail;
- return api_filter(
- [=] { return cast_to_webview(w)->set_size(width, height, hints); });
-}
-
-WEBVIEW_API webview_error_t webview_navigate(webview_t w, const char *url) {
- using namespace webview::detail;
- if (!url) {
- return WEBVIEW_ERROR_INVALID_ARGUMENT;
- }
- return api_filter([=] { return cast_to_webview(w)->navigate(url); });
-}
-
-WEBVIEW_API webview_error_t webview_set_html(webview_t w, const char *html) {
- using namespace webview::detail;
- if (!html) {
- return WEBVIEW_ERROR_INVALID_ARGUMENT;
- }
- return api_filter([=] { return cast_to_webview(w)->set_html(html); });
-}
-
-WEBVIEW_API webview_error_t webview_init(webview_t w, const char *js) {
- using namespace webview::detail;
- if (!js) {
- return WEBVIEW_ERROR_INVALID_ARGUMENT;
- }
- return api_filter([=] { return cast_to_webview(w)->init(js); });
-}
-
-WEBVIEW_API webview_error_t webview_eval(webview_t w, const char *js) {
- using namespace webview::detail;
- if (!js) {
- return WEBVIEW_ERROR_INVALID_ARGUMENT;
- }
- return api_filter([=] { return cast_to_webview(w)->eval(js); });
-}
-
-WEBVIEW_API webview_error_t webview_bind(webview_t w, const char *name,
- void (*fn)(const char *id,
- const char *req, void *arg),
- void *arg) {
- using namespace webview::detail;
- if (!name || !fn) {
- return WEBVIEW_ERROR_INVALID_ARGUMENT;
- }
- return api_filter([=] {
- return cast_to_webview(w)->bind(
- name,
- [=](const std::string &seq, const std::string &req, void *arg_) {
- fn(seq.c_str(), req.c_str(), arg_);
- },
- arg);
- });
-}
-
-WEBVIEW_API webview_error_t webview_unbind(webview_t w, const char *name) {
- using namespace webview::detail;
- if (!name) {
- return WEBVIEW_ERROR_INVALID_ARGUMENT;
- }
- return api_filter([=] { return cast_to_webview(w)->unbind(name); });
-}
-
-WEBVIEW_API webview_error_t webview_return(webview_t w, const char *id,
- int status, const char *result) {
- using namespace webview::detail;
- if (!id || !result) {
- return WEBVIEW_ERROR_INVALID_ARGUMENT;
- }
- return api_filter(
- [=] { return cast_to_webview(w)->resolve(id, status, result); });
-}
-
-WEBVIEW_API const webview_version_info_t *webview_version(void) {
- return &webview::detail::library_version_info;
-}
-
-#endif // defined(__cplusplus) && !defined(WEBVIEW_HEADER)
-#endif // WEBVIEW_C_API_IMPL_HH
diff --git a/core/include/webview/detail/backends/cocoa_webkit.hh b/core/include/webview/detail/backends/cocoa_webkit.hh
deleted file mode 100755
index 1a0a2c6c7..000000000
--- a/core/include/webview/detail/backends/cocoa_webkit.hh
+++ /dev/null
@@ -1,626 +0,0 @@
-/*
- * MIT License
- *
- * Copyright (c) 2017 Serge Zaitsev
- * Copyright (c) 2022 Steffen André Langnes
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
-#ifndef WEBVIEW_BACKENDS_COCOA_WEBKIT_HH
-#define WEBVIEW_BACKENDS_COCOA_WEBKIT_HH
-
-#if defined(__cplusplus) && !defined(WEBVIEW_HEADER)
-
-#include "../../macros.h"
-
-#if defined(WEBVIEW_PLATFORM_DARWIN) && defined(WEBVIEW_COCOA)
-
-//
-// ====================================================================
-//
-// This implementation uses Cocoa WKWebView backend on macOS. It is
-// written using ObjC runtime and uses WKWebView class as a browser runtime.
-// You should pass "-framework Webkit" flag to the compiler.
-//
-// ====================================================================
-//
-
-#include "../../types.hh"
-#include "../engine_base.hh"
-#include "../platform/darwin/cocoa/cocoa.hh"
-#include "../platform/darwin/objc/objc.hh"
-#include "../platform/darwin/webkit/webkit.hh"
-#include "../user_script.hh"
-
-#include
-#include
-#include
-#include
-#include
-
-#include
-
-namespace webview {
-namespace detail {
-
-class user_script::impl {
-public:
- impl(id script) : m_script{objc::retain(script)} {}
-
- ~impl() { objc::release(m_script); }
-
- impl(const impl &) = delete;
- impl &operator=(const impl &) = delete;
- impl(impl &&) = delete;
- impl &operator=(impl &&) = delete;
-
- id get_native() const { return m_script; }
-
-private:
- id m_script{};
-};
-
-// Encapsulate backend in its own namespace to avoid polluting the parent
-// namespace when pulling in commonly-used symbols from other namespaces.
-// Since those commmon symbols are used a lot, this reduces the overall
-// noise in the code.
-namespace cocoa_webkit {
-
-using namespace cocoa;
-using namespace webkit;
-
-class cocoa_wkwebview_engine : public engine_base {
-public:
- cocoa_wkwebview_engine(bool debug, void *window)
- : engine_base{!window}, m_app{NSApplication_get_sharedApplication()} {
- window_init(window);
- window_settings(debug);
- dispatch_size_default();
- }
-
- cocoa_wkwebview_engine(const cocoa_wkwebview_engine &) = delete;
- cocoa_wkwebview_engine &operator=(const cocoa_wkwebview_engine &) = delete;
- cocoa_wkwebview_engine(cocoa_wkwebview_engine &&) = delete;
- cocoa_wkwebview_engine &operator=(cocoa_wkwebview_engine &&) = delete;
-
- virtual ~cocoa_wkwebview_engine() {
- objc::autoreleasepool arp;
- if (m_window) {
- if (m_webview) {
- if (auto ui_delegate{WKWebView_get_UIDelegate(m_webview)}) {
- WKWebView_set_UIDelegate(m_webview, nullptr);
- objc::release(ui_delegate);
- }
- objc::release(m_webview);
- m_webview = nullptr;
- }
- if (m_widget) {
- if (m_widget == NSWindow_get_contentView(m_window)) {
- NSWindow_set_contentView(m_window, nullptr);
- }
- objc::release(m_widget);
- m_widget = nullptr;
- }
- if (owns_window()) {
- // Replace delegate to avoid callbacks and other bad things during
- // destruction.
- NSWindow_set_delegate(m_window, nullptr);
- NSWindow_close(m_window);
- on_window_destroyed(true);
- }
- m_window = nullptr;
- }
- if (m_window_delegate) {
- objc::release(m_window_delegate);
- m_window_delegate = nullptr;
- }
- if (m_app_delegate) {
- NSApplication_set_delegate(m_app, nullptr);
- // Make sure to release the delegate we created.
- objc::release(m_app_delegate);
- m_app_delegate = nullptr;
- }
- if (owns_window()) {
- // Needed for the window to close immediately.
- deplete_run_loop_event_queue();
- }
- // TODO: Figure out why m_manager is still alive after the autoreleasepool
- // has been drained.
- }
-
-protected:
- result window_impl() override {
- if (m_window) {
- return m_window;
- }
- return error_info{WEBVIEW_ERROR_INVALID_STATE};
- }
-
- result widget_impl() override {
- if (m_widget) {
- return m_widget;
- }
- return error_info{WEBVIEW_ERROR_INVALID_STATE};
- }
-
- result browser_controller_impl() override {
- if (m_webview) {
- return m_webview;
- }
- return error_info{WEBVIEW_ERROR_INVALID_STATE};
- }
-
- noresult terminate_impl() override {
- stop_run_loop();
- return {};
- }
-
- noresult run_impl() override {
- NSApplication_run(m_app);
- return {};
- }
-
- noresult dispatch_impl(std::function f) override {
- dispatch_async_f(dispatch_get_main_queue(), new dispatch_fn_t(f),
- (dispatch_function_t)([](void *arg) {
- auto f = static_cast(arg);
- (*f)();
- delete f;
- }));
- return {};
- }
-
- noresult set_title_impl(const std::string &title) override {
- NSWindow_set_title(m_window, title);
- return {};
- }
- noresult set_size_impl(int width, int height, webview_hint_t hints) override {
- objc::autoreleasepool arp;
-
- auto style = static_cast(
- NSWindowStyleMaskTitled | NSWindowStyleMaskClosable |
- NSWindowStyleMaskMiniaturizable);
- if (hints != WEBVIEW_HINT_FIXED) {
- style =
- static_cast(style | NSWindowStyleMaskResizable);
- }
- NSWindow_set_styleMask(m_window, style);
-
- if (hints == WEBVIEW_HINT_MIN) {
- NSWindow_set_contentMinSize(m_window, NSSizeMake(width, height));
- } else if (hints == WEBVIEW_HINT_MAX) {
- NSWindow_set_contentMaxSize(m_window, NSSizeMake(width, height));
- } else {
- auto rect{NSWindow_get_frame(m_window)};
- NSWindow_setFrame(m_window,
- NSRectMake(rect.origin.x, rect.origin.y, width, height),
- true, false);
- }
- NSWindow_center(m_window);
-
- return window_show();
- }
- noresult navigate_impl(const std::string &url) override {
- objc::autoreleasepool arp;
-
- WKWebView_loadRequest(
- m_webview, NSURLRequest_requestWithURL(NSURL_URLWithString(url)));
-
- return {};
- }
- noresult set_html_impl(const std::string &html) override {
- objc::autoreleasepool arp;
- WKWebView_loadHTMLString(m_webview, NSString_stringWithUTF8String(html),
- nullptr);
- return {};
- }
- noresult eval_impl(const std::string &js) override {
- objc::autoreleasepool arp;
- // URI is null before content has begun loading.
- auto nsurl{WKWebView_get_URL(m_webview)};
- if (!nsurl) {
- return {};
- }
- WKWebView_evaluateJavaScript(m_webview, NSString_stringWithUTF8String(js),
- nullptr);
- return {};
- }
-
- user_script add_user_script_impl(const std::string &js) override {
- objc::autoreleasepool arp;
- auto wk_script{WKUserScript_withSource(
- NSString_stringWithUTF8String(js),
- WKUserScriptInjectionTimeAtDocumentStart, true)};
- // Script is retained when added.
- WKUserContentController_addUserScript(m_manager, wk_script);
- user_script script{
- js, user_script::impl_ptr{new user_script::impl{wk_script},
- [](user_script::impl *p) { delete p; }}};
- return script;
- }
-
- void remove_all_user_scripts_impl(
- const std::list & /*scripts*/) override {
- objc::autoreleasepool arp;
- // Removing scripts decreases the retain count of each script.
- WKUserContentController_removeAllUserScripts(m_manager);
- }
-
- bool are_user_scripts_equal_impl(const user_script &first,
- const user_script &second) override {
- auto *wk_first = first.get_impl().get_native();
- auto *wk_second = second.get_impl().get_native();
- return wk_first == wk_second;
- }
-
-private:
- id create_app_delegate() {
- objc::autoreleasepool arp;
- constexpr auto class_name = "WebviewAppDelegate";
- // Avoid crash due to registering same class twice
- auto cls = objc_lookUpClass(class_name);
- if (!cls) {
- // Note: Avoid registering the class name "AppDelegate" as it is the
- // default name in projects created with Xcode, and using the same name
- // causes objc_registerClassPair to crash.
- cls =
- objc_allocateClassPair(objc::get_class("NSResponder"), class_name, 0);
- class_addProtocol(cls, objc_getProtocol("NSTouchBarProvider"));
- class_addMethod(
- cls,
- objc::selector("applicationShouldTerminateAfterLastWindowClosed:"),
- (IMP)(+[](id, SEL, id) -> BOOL { return NO; }), "c@:@");
- class_addMethod(cls, objc::selector("applicationDidFinishLaunching:"),
- (IMP)(+[](id self, SEL, id notification) {
- auto app{NSNotification_get_object(notification)};
- auto w = get_associated_webview(self);
- w->on_application_did_finish_launching(self, app);
- }),
- "v@:@");
- objc_registerClassPair(cls);
- }
- return objc::Class_new(cls);
- }
- id create_script_message_handler() {
- objc::autoreleasepool arp;
- constexpr auto class_name = "WebviewWKScriptMessageHandler";
- // Avoid crash due to registering same class twice
- auto cls = objc_lookUpClass(class_name);
- if (!cls) {
- cls =
- objc_allocateClassPair(objc::get_class("NSResponder"), class_name, 0);
- class_addProtocol(cls, objc_getProtocol("WKScriptMessageHandler"));
- class_addMethod(
- cls, objc::selector("userContentController:didReceiveScriptMessage:"),
- (IMP)(+[](id self, SEL, id, id msg) {
- auto w = get_associated_webview(self);
- w->on_message(
- NSString_get_UTF8String(WKScriptMessage_get_body(msg)));
- }),
- "v@:@@");
- objc_registerClassPair(cls);
- }
- auto instance{objc::Class_new(cls)};
- set_associated_webview(instance, this);
- return instance;
- }
- static id create_webkit_ui_delegate() {
- objc::autoreleasepool arp;
- constexpr auto class_name = "WebviewWKUIDelegate";
- // Avoid crash due to registering same class twice
- auto cls = objc_lookUpClass(class_name);
- if (!cls) {
- cls = objc_allocateClassPair(objc::get_class("NSObject"), class_name, 0);
- class_addProtocol(cls, objc_getProtocol("WKUIDelegate"));
- class_addMethod(
- cls,
- objc::selector("webView:runOpenPanelWithParameters:initiatedByFrame:"
- "completionHandler:"),
- (IMP)(+[](id, SEL, id, id parameters, id, id completion_handler) {
- auto allows_multiple_selection{
- WKOpenPanelParameters_get_allowsMultipleSelection(parameters)};
- auto allows_directories{
- WKOpenPanelParameters_get_allowsDirectories(parameters)};
-
- // Show a panel for selecting files.
- auto panel{NSOpenPanel_openPanel()};
- NSOpenPanel_set_canChooseFiles(panel, true);
- NSOpenPanel_set_canChooseDirectories(panel, allows_directories);
- NSOpenPanel_set_allowsMultipleSelection(panel,
- allows_multiple_selection);
- auto modal_response{NSSavePanel_runModal(panel)};
-
- // Get the URLs for the selected files. If the modal was canceled
- // then we pass null to the completion handler to signify
- // cancellation.
- id urls{modal_response == NSModalResponseOK
- ? NSOpenPanel_get_URLs(panel)
- : nullptr};
-
- // Invoke the completion handler block.
- auto sig{NSMethodSignature_signatureWithObjCTypes("v@?@")};
- auto invocation{NSInvocation_invocationWithMethodSignature(sig)};
- NSInvocation_set_target(invocation, completion_handler);
- NSInvocation_setArgument(invocation, &urls, 1);
- NSInvocation_invoke(invocation);
- }),
- "v@:@@@@");
- objc_registerClassPair(cls);
- }
- return objc::Class_new(cls);
- }
- static id create_window_delegate() {
- objc::autoreleasepool arp;
- constexpr auto class_name = "WebviewNSWindowDelegate";
- // Avoid crash due to registering same class twice
- auto cls = objc_lookUpClass(class_name);
- if (!cls) {
- cls = objc_allocateClassPair(objc::get_class("NSObject"), class_name, 0);
- class_addProtocol(cls, objc_getProtocol("NSWindowDelegate"));
- class_addMethod(cls, objc::selector("windowWillClose:"),
- (IMP)(+[](id self, SEL, id notification) {
- auto window{NSNotification_get_object(notification)};
- auto w = get_associated_webview(self);
- w->on_window_will_close(self, window);
- }),
- "v@:@");
- objc_registerClassPair(cls);
- }
- return objc::Class_new(cls);
- }
- static cocoa_wkwebview_engine *get_associated_webview(id object) {
- objc::autoreleasepool arp;
- if (id assoc_obj{objc_getAssociatedObject(object, "webview")}) {
- cocoa_wkwebview_engine *w{};
- NSValue_getValue(assoc_obj, &w, sizeof(w));
- return w;
- }
- return nullptr;
- }
- static void set_associated_webview(id object, cocoa_wkwebview_engine *w) {
- objc::autoreleasepool arp;
- objc_setAssociatedObject(object, "webview", NSValue_valueWithPointer(w),
- OBJC_ASSOCIATION_RETAIN);
- }
- static bool is_app_bundled() noexcept {
- auto bundle = NSBundle_get_mainBundle();
- if (!bundle) {
- return false;
- }
- auto bundle_path = NSBundle_get_bundlePath(bundle);
- auto bundled =
- NSString_hasSuffix(bundle_path, NSString_stringWithUTF8String(".app"));
- return !!bundled;
- }
- void on_application_did_finish_launching(id /*delegate*/, id app) {
- // See comments related to application lifecycle in create_app_delegate().
- if (owns_window()) {
- // Stop the main run loop so that we can return
- // from the constructor.
- stop_run_loop();
- }
-
- // Activate the app if it is not bundled.
- // Bundled apps launched from Finder are activated automatically but
- // otherwise not. Activating the app even when it has been launched from
- // Finder does not seem to be harmful but calling this function is rarely
- // needed as proper activation is normally taken care of for us.
- // Bundled apps have a default activation policy of
- // NSApplicationActivationPolicyRegular while non-bundled apps have a
- // default activation policy of NSApplicationActivationPolicyProhibited.
- if (!is_app_bundled()) {
- // "setActivationPolicy:" must be invoked before
- // "activateIgnoringOtherApps:" for activation to work.
- NSApplication_setActivationPolicy(app,
- NSApplicationActivationPolicyRegular);
- // Activate the app regardless of other active apps.
- // This can be obtrusive so we only do it when necessary.
- NSApplication_activateIgnoringOtherApps(app, true);
- }
-
- window_init_proceed();
- }
- void on_window_will_close(id /*delegate*/, id /*window*/) {
- // Widget destroyed along with window.
- m_widget = nullptr;
- m_webview = nullptr;
- m_window = nullptr;
- dispatch([this] { on_window_destroyed(); });
- }
- void window_settings(bool debug) {
- objc::autoreleasepool arp;
-
- auto config{objc::autorelease(WKWebViewConfiguration_new())};
-
- m_manager = WKWebViewConfiguration_get_userContentController(config);
-
- auto preferences = WKWebViewConfiguration_get_preferences(config);
- auto yes_value = NSNumber_numberWithBool(true);
-
- if (debug) {
- NSObject_setValue_forKey(
- preferences, yes_value,
- NSString_stringWithUTF8String("developerExtrasEnabled"));
- }
-
- NSObject_setValue_forKey(
- preferences, yes_value,
- NSString_stringWithUTF8String("fullScreenEnabled"));
-
-#if defined(__has_builtin)
-#if __has_builtin(__builtin_available)
- if (__builtin_available(macOS 10.13, *)) {
- NSObject_setValue_forKey(
- preferences, yes_value,
- NSString_stringWithUTF8String("javaScriptCanAccessClipboard"));
- NSObject_setValue_forKey(
- preferences, yes_value,
- NSString_stringWithUTF8String("DOMPasteAllowed"));
- }
-#else
-#error __builtin_available not supported by compiler
-#endif
-#else
-#error __has_builtin not supported by compiler
-#endif
-
- auto ui_delegate = create_webkit_ui_delegate();
- m_webview =
- objc::retain(WKWebView_withFrame(CGRectMake(0, 0, 0, 0), config));
- // Autoresizing mask is needed to prevent the Web Inspector pane from
- // pushing the main web view out of bounds
- auto autoresizing_mask{static_cast(
- NSViewWidthSizable | NSViewMaxXMargin | NSViewHeightSizable |
- NSViewMaxYMargin)};
- NSView_set_autoresizingMask(m_webview, autoresizing_mask);
- set_associated_webview(ui_delegate, this);
- WKWebView_set_UIDelegate(m_webview, ui_delegate);
-
- if (debug) {
- // Explicitly make WKWebView inspectable via Safari on OS versions that
- // disable the feature by default (macOS 13.3 and later) and support
- // enabling it. According to Apple, the behavior on older OS versions is
- // for content to always be inspectable in "debug builds".
- // Testing shows that this is true for macOS 12.6 but somehow not 10.15.
- // https://webkit.org/blog/13936/enabling-the-inspection-of-web-content-in-apps/
- WKWebView_set_inspectable(m_webview, true);
- }
-
- auto script_message_handler =
- objc::autorelease(create_script_message_handler());
- WKUserContentController_addScriptMessageHandler(
- m_manager, script_message_handler,
- NSString_stringWithUTF8String("__webview__"));
-
- add_init_script("function(message) {\n\
- return window.webkit.messageHandlers.__webview__.postMessage(message);\n\
-}");
- set_up_widget();
- NSWindow_set_contentView(m_window, m_widget);
- if (owns_window()) {
- NSWindow_makeKeyAndOrderFront(m_window);
- }
- }
- void set_up_widget() {
- objc::autoreleasepool arp;
- // Create a new view that can contain both the web view and the Web Inspector pane
- m_widget = objc::retain(NSView_withFrame(NSRectMake(0, 0, 0, 0)));
- // Autoresizing is needed because the Web Inspector pane is a sibling of the web view
- NSView_set_autoresizesSubviews(m_widget, true);
- NSView_addSubview(m_widget, m_webview);
- NSView_set_frame(m_webview, NSView_get_bounds(m_widget));
- }
- void stop_run_loop() {
- objc::autoreleasepool arp;
- // Request the run loop to stop. This doesn't immediately stop the loop.
- NSApplication_stop(m_app);
- // The run loop will stop after processing an NSEvent.
- auto event{NSEvent_otherEventWithType(
- NSEventTypeApplicationDefined, NSPointMake(0, 0),
- NSEventModifierFlags{}, 0, 0, nullptr, 0, 0, 0)};
- NSApplication_postEvent(m_app, event, true);
- }
- static bool get_and_set_is_first_instance() noexcept {
- static std::atomic_bool first{true};
- bool temp = first;
- if (temp) {
- first = false;
- }
- return temp;
- }
- void window_init(void *window) {
- objc::autoreleasepool arp;
-
- m_window = static_cast(window);
- if (!owns_window()) {
- return;
- }
-
- // Skip application setup if this isn't the first instance of this class
- // because the launch event is only sent once.
- if (!get_and_set_is_first_instance()) {
- window_init_proceed();
- return;
- }
-
- m_app_delegate = create_app_delegate();
- set_associated_webview(m_app_delegate, this);
- NSApplication_set_delegate(m_app, m_app_delegate);
-
- // Start the main run loop so that the app delegate gets the
- // NSApplicationDidFinishLaunchingNotification notification after the run
- // loop has started in order to perform further initialization.
- // We need to return from this constructor so this run loop is only
- // temporary.
- NSApplication_run(m_app);
- }
- void window_init_proceed() {
- objc::autoreleasepool arp;
-
- m_window = objc::retain(NSWindow_withContentRect(
- NSRectMake(0, 0, 0, 0), NSWindowStyleMaskTitled, NSBackingStoreBuffered,
- false));
- m_window_delegate = create_window_delegate();
- set_associated_webview(m_window_delegate, this);
- NSWindow_set_delegate(m_window, m_window_delegate);
- on_window_created();
- }
-
- noresult window_show() {
- objc::autoreleasepool arp;
- if (m_is_window_shown) {
- return {};
- }
- m_is_window_shown = true;
- return {};
- }
-
- void run_event_loop_while(std::function fn) override {
- objc::autoreleasepool arp;
- while (fn()) {
- objc::autoreleasepool arp2;
- if (auto event{NSApplication_nextEventMatchingMask(
- m_app, NSEventMaskAny, nullptr,
- NSRunLoopMode::NSDefaultRunLoopMode(), true)}) {
- NSApplication_sendEvent(m_app, event);
- }
- }
- }
-
- id m_app{};
- id m_app_delegate{};
- id m_window_delegate{};
- id m_window{};
- id m_widget{};
- id m_webview{};
- id m_manager{};
- bool m_is_window_shown{};
-};
-
-} // namespace cocoa_webkit
-} // namespace detail
-
-using browser_engine = detail::cocoa_webkit::cocoa_wkwebview_engine;
-
-} // namespace webview
-
-#endif // defined(WEBVIEW_PLATFORM_DARWIN) && defined(WEBVIEW_COCOA)
-#endif // defined(__cplusplus) && !defined(WEBVIEW_HEADER)
-#endif // WEBVIEW_BACKENDS_COCOA_WEBKIT_HH
diff --git a/core/include/webview/detail/backends/gtk_webkitgtk.hh b/core/include/webview/detail/backends/gtk_webkitgtk.hh
deleted file mode 100644
index 06d83e1d7..000000000
--- a/core/include/webview/detail/backends/gtk_webkitgtk.hh
+++ /dev/null
@@ -1,355 +0,0 @@
-/*
- * MIT License
- *
- * Copyright (c) 2017 Serge Zaitsev
- * Copyright (c) 2022 Steffen André Langnes
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
-#ifndef WEBVIEW_BACKENDS_GTK_WEBKITGTK_HH
-#define WEBVIEW_BACKENDS_GTK_WEBKITGTK_HH
-
-#if defined(__cplusplus) && !defined(WEBVIEW_HEADER)
-
-#include "../../macros.h"
-
-#if defined(WEBVIEW_PLATFORM_LINUX) && defined(WEBVIEW_GTK)
-
-//
-// ====================================================================
-//
-// This implementation uses webkit2gtk backend. It requires GTK and
-// WebKitGTK libraries. Proper compiler flags can be retrieved via:
-//
-// pkg-config --cflags --libs gtk4 webkitgtk-6.0
-// pkg-config --cflags --libs gtk+-3.0 webkit2gtk-4.1
-// pkg-config --cflags --libs gtk+-3.0 webkit2gtk-4.0
-//
-// ====================================================================
-//
-
-#include "../../errors.hh"
-#include "../../types.hh"
-#include "../engine_base.hh"
-#include "../platform/linux/gtk/compat.hh"
-#include "../platform/linux/webkitgtk/compat.hh"
-#include "../platform/linux/webkitgtk/dmabuf.hh"
-#include "../user_script.hh"
-
-#include
-#include
-#include
-#include
-
-#include
-
-#if GTK_MAJOR_VERSION >= 4
-
-#include
-#include
-
-#elif GTK_MAJOR_VERSION >= 3
-
-#include
-#include
-
-#endif
-
-#include
-#include
-
-namespace webview {
-namespace detail {
-
-class user_script::impl {
-public:
- impl(WebKitUserScript *script) : m_script{script} {
- webkit_user_script_ref(script);
- }
-
- ~impl() { webkit_user_script_unref(m_script); }
-
- impl(const impl &) = delete;
- impl &operator=(const impl &) = delete;
- impl(impl &&) = delete;
- impl &operator=(impl &&) = delete;
-
- WebKitUserScript *get_native() const { return m_script; }
-
-private:
- WebKitUserScript *m_script{};
-};
-
-class gtk_webkit_engine : public engine_base {
-public:
- gtk_webkit_engine(bool debug, void *window) : engine_base{!window} {
- window_init(window);
- window_settings(debug);
- dispatch_size_default();
- }
-
- gtk_webkit_engine(const gtk_webkit_engine &) = delete;
- gtk_webkit_engine &operator=(const gtk_webkit_engine &) = delete;
- gtk_webkit_engine(gtk_webkit_engine &&) = delete;
- gtk_webkit_engine &operator=(gtk_webkit_engine &&) = delete;
-
- virtual ~gtk_webkit_engine() {
- if (m_window) {
- if (owns_window()) {
- // Disconnect handlers to avoid callbacks invoked during destruction.
- g_signal_handlers_disconnect_by_data(GTK_WINDOW(m_window), this);
- gtk_window_close(GTK_WINDOW(m_window));
- on_window_destroyed(true);
- } else {
- gtk_compat::window_remove_child(GTK_WINDOW(m_window),
- GTK_WIDGET(m_webview));
- }
- }
- if (m_webview) {
- g_object_unref(m_webview);
- }
- if (owns_window()) {
- // Needed for the window to close immediately.
- deplete_run_loop_event_queue();
- }
- }
-
-protected:
- result window_impl() override {
- if (m_window) {
- return m_window;
- }
- return error_info{WEBVIEW_ERROR_INVALID_STATE};
- }
-
- result widget_impl() override {
- if (m_webview) {
- return m_webview;
- }
- return error_info{WEBVIEW_ERROR_INVALID_STATE};
- }
-
- result browser_controller_impl() override {
- if (m_webview) {
- return m_webview;
- }
- return error_info{WEBVIEW_ERROR_INVALID_STATE};
- }
-
- noresult run_impl() override {
- m_stop_run_loop = false;
- while (!m_stop_run_loop) {
- g_main_context_iteration(nullptr, TRUE);
- }
- return {};
- }
-
- noresult terminate_impl() override {
- return dispatch_impl([&] { m_stop_run_loop = true; });
- }
-
- noresult dispatch_impl(std::function f) override {
- g_idle_add_full(G_PRIORITY_HIGH_IDLE, (GSourceFunc)([](void *fn) -> int {
- (*static_cast(fn))();
- return G_SOURCE_REMOVE;
- }),
- new std::function(f),
- [](void *fn) { delete static_cast(fn); });
- return {};
- }
-
- noresult set_title_impl(const std::string &title) override {
- gtk_window_set_title(GTK_WINDOW(m_window), title.c_str());
- return {};
- }
-
- noresult set_size_impl(int width, int height, webview_hint_t hints) override {
- gtk_window_set_resizable(GTK_WINDOW(m_window), hints != WEBVIEW_HINT_FIXED);
- if (hints == WEBVIEW_HINT_NONE || hints == WEBVIEW_HINT_FIXED) {
- gtk_compat::window_set_size(GTK_WINDOW(m_window), width, height);
- } else if (hints == WEBVIEW_HINT_MIN) {
- gtk_widget_set_size_request(m_window, width, height);
- } else if (hints == WEBVIEW_HINT_MAX) {
- gtk_compat::window_set_max_size(GTK_WINDOW(m_window), width, height);
- } else {
- return error_info{WEBVIEW_ERROR_INVALID_ARGUMENT, "Invalid hint"};
- }
- return window_show();
- }
-
- noresult navigate_impl(const std::string &url) override {
- webkit_web_view_load_uri(WEBKIT_WEB_VIEW(m_webview), url.c_str());
- return {};
- }
-
- noresult set_html_impl(const std::string &html) override {
- webkit_web_view_load_html(WEBKIT_WEB_VIEW(m_webview), html.c_str(),
- nullptr);
- return {};
- }
-
- noresult eval_impl(const std::string &js) override {
- // URI is null before content has begun loading.
- if (!webkit_web_view_get_uri(WEBKIT_WEB_VIEW(m_webview))) {
- return {};
- }
-#if (WEBKIT_MAJOR_VERSION == 2 && WEBKIT_MINOR_VERSION >= 40) || \
- WEBKIT_MAJOR_VERSION > 2
- webkit_web_view_evaluate_javascript(WEBKIT_WEB_VIEW(m_webview), js.c_str(),
- static_cast(js.size()), nullptr,
- nullptr, nullptr, nullptr, nullptr);
-#else
- webkit_web_view_run_javascript(WEBKIT_WEB_VIEW(m_webview), js.c_str(),
- nullptr, nullptr, nullptr);
-#endif
- return {};
- }
-
- user_script add_user_script_impl(const std::string &js) override {
- auto *wk_script = webkit_user_script_new(
- js.c_str(), WEBKIT_USER_CONTENT_INJECT_TOP_FRAME,
- WEBKIT_USER_SCRIPT_INJECT_AT_DOCUMENT_START, nullptr, nullptr);
- webkit_user_content_manager_add_script(m_user_content_manager, wk_script);
- user_script script{
- js, user_script::impl_ptr{new user_script::impl{wk_script},
- [](user_script::impl *p) { delete p; }}};
- webkit_user_script_unref(wk_script);
- return script;
- }
-
- void remove_all_user_scripts_impl(
- const std::list & /*scripts*/) override {
- webkit_user_content_manager_remove_all_scripts(m_user_content_manager);
- }
-
- bool are_user_scripts_equal_impl(const user_script &first,
- const user_script &second) override {
- auto *wk_first = first.get_impl().get_native();
- auto *wk_second = second.get_impl().get_native();
- return wk_first == wk_second;
- }
-
-private:
-#if GTK_MAJOR_VERSION >= 4
- static char *get_string_from_js_result(JSCValue *r) {
- return jsc_value_to_string(r);
- }
-#else
- static char *get_string_from_js_result(WebKitJavascriptResult *r) {
- char *s;
-#if (WEBKIT_MAJOR_VERSION == 2 && WEBKIT_MINOR_VERSION >= 22) || \
- WEBKIT_MAJOR_VERSION > 2
- JSCValue *value = webkit_javascript_result_get_js_value(r);
- s = jsc_value_to_string(value);
-#else
- JSGlobalContextRef ctx = webkit_javascript_result_get_global_context(r);
- JSValueRef value = webkit_javascript_result_get_value(r);
- JSStringRef js = JSValueToStringCopy(ctx, value, nullptr);
- size_t n = JSStringGetMaximumUTF8CStringSize(js);
- s = g_new(char, n);
- JSStringGetUTF8CString(js, s, n);
- JSStringRelease(js);
-#endif
- return s;
- }
-#endif
-
- void window_init(void *window) {
- m_window = static_cast(window);
- if (owns_window()) {
- if (!gtk_compat::init_check()) {
- throw exception{WEBVIEW_ERROR_UNSPECIFIED, "GTK init failed"};
- }
- m_window = gtk_compat::window_new();
- on_window_created();
- auto on_window_destroy = +[](GtkWidget *, gpointer arg) {
- auto *w = static_cast(arg);
- w->m_window = nullptr;
- w->on_window_destroyed();
- };
- g_signal_connect(G_OBJECT(m_window), "destroy",
- G_CALLBACK(on_window_destroy), this);
- }
- webkit_dmabuf::apply_webkit_dmabuf_workaround();
- // Initialize webview widget
- m_webview = webkit_web_view_new();
- g_object_ref_sink(m_webview);
- WebKitUserContentManager *manager = m_user_content_manager =
- webkit_web_view_get_user_content_manager(WEBKIT_WEB_VIEW(m_webview));
- webkitgtk_compat::connect_script_message_received(
- manager, "__webview__",
- [this](WebKitUserContentManager *, const std::string &r) {
- on_message(r);
- });
- webkitgtk_compat::user_content_manager_register_script_message_handler(
- manager, "__webview__");
- add_init_script("function(message) {\n\
- return window.webkit.messageHandlers.__webview__.postMessage(message);\n\
-}");
- }
-
- void window_settings(bool debug) {
- WebKitSettings *settings =
- webkit_web_view_get_settings(WEBKIT_WEB_VIEW(m_webview));
- webkit_settings_set_javascript_can_access_clipboard(settings, true);
- if (debug) {
- webkit_settings_set_enable_write_console_messages_to_stdout(settings,
- true);
- webkit_settings_set_enable_developer_extras(settings, true);
- }
- }
-
- noresult window_show() {
- if (m_is_window_shown) {
- return {};
- }
- gtk_compat::window_set_child(GTK_WINDOW(m_window), GTK_WIDGET(m_webview));
- gtk_compat::widget_set_visible(GTK_WIDGET(m_webview), true);
-
- if (owns_window()) {
- gtk_widget_grab_focus(GTK_WIDGET(m_webview));
- gtk_compat::widget_set_visible(GTK_WIDGET(m_window), true);
- }
- m_is_window_shown = true;
- return {};
- }
-
- void run_event_loop_while(std::function fn) override {
- while (fn()) {
- g_main_context_iteration(nullptr, TRUE);
- }
- }
-
- GtkWidget *m_window{};
- GtkWidget *m_webview{};
- WebKitUserContentManager *m_user_content_manager{};
- bool m_stop_run_loop{};
- bool m_is_window_shown{};
-};
-
-} // namespace detail
-
-using browser_engine = detail::gtk_webkit_engine;
-
-} // namespace webview
-
-#endif // defined(WEBVIEW_PLATFORM_LINUX) && defined(WEBVIEW_GTK)
-#endif // defined(__cplusplus) && !defined(WEBVIEW_HEADER)
-#endif // WEBVIEW_BACKENDS_GTK_WEBKITGTK_HH
diff --git a/core/include/webview/detail/backends/win32_edge.hh b/core/include/webview/detail/backends/win32_edge.hh
deleted file mode 100644
index 316a9d5c3..000000000
--- a/core/include/webview/detail/backends/win32_edge.hh
+++ /dev/null
@@ -1,909 +0,0 @@
-/*
- * MIT License
- *
- * Copyright (c) 2017 Serge Zaitsev
- * Copyright (c) 2022 Steffen André Langnes
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
-#ifndef WEBVIEW_BACKENDS_WIN32_EDGE_HH
-#define WEBVIEW_BACKENDS_WIN32_EDGE_HH
-
-#if defined(__cplusplus) && !defined(WEBVIEW_HEADER)
-
-#include "../../macros.h"
-
-#if defined(WEBVIEW_PLATFORM_WINDOWS) && defined(WEBVIEW_EDGE)
-
-//
-// ====================================================================
-//
-// This implementation uses Win32 API to create a native window. It
-// uses Edge/Chromium webview2 backend as a browser engine.
-//
-// ====================================================================
-//
-
-#include "../../errors.hh"
-#include "../../types.hh"
-#include "../engine_base.hh"
-#include "../native_library.hh"
-#include "../platform/windows/com_init_wrapper.hh"
-#include "../platform/windows/dpi.hh"
-#include "../platform/windows/iid.hh"
-#include "../platform/windows/reg_key.hh"
-#include "../platform/windows/theme.hh"
-#include "../platform/windows/version.hh"
-#include "../platform/windows/webview2/loader.hh"
-#include "../user_script.hh"
-#include "../utility/string.hh"
-
-#include
-#include
-#include
-#include
-#include
-#include
-
-#ifndef WIN32_LEAN_AND_MEAN
-#define WIN32_LEAN_AND_MEAN
-#endif
-
-#include
-
-#include
-#include
-#include
-
-#ifdef _MSC_VER
-#pragma comment(lib, "ole32.lib")
-#pragma comment(lib, "shell32.lib")
-#pragma comment(lib, "shlwapi.lib")
-#pragma comment(lib, "user32.lib")
-#pragma comment(lib, "version.lib")
-#endif
-
-namespace webview {
-namespace detail {
-
-using msg_cb_t = std::function;
-
-class webview2_com_handler
- : public ICoreWebView2CreateCoreWebView2EnvironmentCompletedHandler,
- public ICoreWebView2CreateCoreWebView2ControllerCompletedHandler,
- public ICoreWebView2WebMessageReceivedEventHandler,
- public ICoreWebView2PermissionRequestedEventHandler {
- using webview2_com_handler_cb_t =
- std::function;
-
-public:
- webview2_com_handler(HWND hwnd, msg_cb_t msgCb, webview2_com_handler_cb_t cb)
- : m_window(hwnd), m_msgCb(msgCb), m_cb(cb) {}
-
- virtual ~webview2_com_handler() = default;
- webview2_com_handler(const webview2_com_handler &other) = delete;
- webview2_com_handler &operator=(const webview2_com_handler &other) = delete;
- webview2_com_handler(webview2_com_handler &&other) = delete;
- webview2_com_handler &operator=(webview2_com_handler &&other) = delete;
-
- ULONG STDMETHODCALLTYPE AddRef() { return ++m_ref_count; }
- ULONG STDMETHODCALLTYPE Release() {
- if (m_ref_count > 1) {
- return --m_ref_count;
- }
- delete this;
- return 0;
- }
- HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, LPVOID *ppv) {
- using namespace mswebview2::cast_info;
-
- if (!ppv) {
- return E_POINTER;
- }
-
- // All of the COM interfaces we implement should be added here regardless
- // of whether they are required.
- // This is just to be on the safe side in case the WebView2 Runtime ever
- // requests a pointer to an interface we implement.
- // The WebView2 Runtime must at the very least be able to get a pointer to
- // ICoreWebView2CreateCoreWebView2EnvironmentCompletedHandler when we use
- // our custom WebView2 loader implementation, and observations have shown
- // that it is the only interface requested in this case. None have been
- // observed to be requested when using the official WebView2 loader.
-
- if (cast_if_equal_iid(this, riid, controller_completed, ppv) ||
- cast_if_equal_iid(this, riid, environment_completed, ppv) ||
- cast_if_equal_iid(this, riid, message_received, ppv) ||
- cast_if_equal_iid(this, riid, permission_requested, ppv)) {
- return S_OK;
- }
-
- return E_NOINTERFACE;
- }
- HRESULT STDMETHODCALLTYPE Invoke(HRESULT res, ICoreWebView2Environment *env) {
- if (SUCCEEDED(res)) {
- res = env->CreateCoreWebView2Controller(m_window, this);
- if (SUCCEEDED(res)) {
- return S_OK;
- }
- }
- try_create_environment();
- return S_OK;
- }
- HRESULT STDMETHODCALLTYPE Invoke(HRESULT res,
- ICoreWebView2Controller *controller) {
- if (FAILED(res)) {
- // See try_create_environment() regarding
- // HRESULT_FROM_WIN32(ERROR_INVALID_STATE).
- // The result is E_ABORT if the parent window has been destroyed already.
- switch (res) {
- case HRESULT_FROM_WIN32(ERROR_INVALID_STATE):
- case E_ABORT:
- return S_OK;
- }
- try_create_environment();
- return S_OK;
- }
-
- ICoreWebView2 *webview;
- ::EventRegistrationToken token;
- controller->get_CoreWebView2(&webview);
- webview->add_WebMessageReceived(this, &token);
- webview->add_PermissionRequested(this, &token);
-
- m_cb(controller, webview);
- return S_OK;
- }
- HRESULT STDMETHODCALLTYPE
- Invoke(ICoreWebView2 * /*sender*/,
- ICoreWebView2WebMessageReceivedEventArgs *args) {
- LPWSTR message{};
- auto res = args->TryGetWebMessageAsString(&message);
- if (SUCCEEDED(res)) {
- m_msgCb(narrow_string(message));
- }
-
- CoTaskMemFree(message);
- return S_OK;
- }
- HRESULT STDMETHODCALLTYPE
- Invoke(ICoreWebView2 * /*sender*/,
- ICoreWebView2PermissionRequestedEventArgs *args) {
- COREWEBVIEW2_PERMISSION_KIND kind;
- args->get_PermissionKind(&kind);
- if (kind == COREWEBVIEW2_PERMISSION_KIND_CLIPBOARD_READ) {
- args->put_State(COREWEBVIEW2_PERMISSION_STATE_ALLOW);
- }
- return S_OK;
- }
-
- // Set the function that will perform the initiating logic for creating
- // the WebView2 environment.
- void set_attempt_handler(std::function attempt_handler) noexcept {
- m_attempt_handler = attempt_handler;
- }
-
- // Retry creating a WebView2 environment.
- // The initiating logic for creating the environment is defined by the
- // caller of set_attempt_handler().
- void try_create_environment() noexcept {
- // WebView creation fails with HRESULT_FROM_WIN32(ERROR_INVALID_STATE) if
- // a running instance using the same user data folder exists, and the
- // Environment objects have different EnvironmentOptions.
- // Source: https://docs.microsoft.com/en-us/microsoft-edge/webview2/reference/win32/icorewebview2environment?view=webview2-1.0.1150.38
- if (m_attempts < m_max_attempts) {
- ++m_attempts;
- auto res = m_attempt_handler();
- if (SUCCEEDED(res)) {
- return;
- }
- // Not entirely sure if this error code only applies to
- // CreateCoreWebView2Controller so we check here as well.
- if (res == HRESULT_FROM_WIN32(ERROR_INVALID_STATE)) {
- return;
- }
- // Wait for m_sleep_ms before trying again.
- Sleep(m_sleep_ms);
- try_create_environment();
- return;
- }
- // Give up.
- m_cb(nullptr, nullptr);
- }
-
-private:
- HWND m_window;
- msg_cb_t m_msgCb;
- webview2_com_handler_cb_t m_cb;
- std::atomic m_ref_count{1};
- std::function m_attempt_handler;
- unsigned int m_max_attempts = 60;
- unsigned int m_sleep_ms = 200;
- unsigned int m_attempts = 0;
-};
-
-class webview2_user_script_added_handler
- : public ICoreWebView2AddScriptToExecuteOnDocumentCreatedCompletedHandler {
-public:
- using callback_fn = std::function;
-
- webview2_user_script_added_handler(callback_fn cb) : m_cb{cb} {}
-
- virtual ~webview2_user_script_added_handler() = default;
- webview2_user_script_added_handler(
- const webview2_user_script_added_handler &other) = delete;
- webview2_user_script_added_handler &
- operator=(const webview2_user_script_added_handler &other) = delete;
- webview2_user_script_added_handler(
- webview2_user_script_added_handler &&other) = delete;
- webview2_user_script_added_handler &
- operator=(webview2_user_script_added_handler &&other) = delete;
-
- ULONG STDMETHODCALLTYPE AddRef() { return ++m_ref_count; }
- ULONG STDMETHODCALLTYPE Release() {
- if (m_ref_count > 1) {
- return --m_ref_count;
- }
- delete this;
- return 0;
- }
-
- HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, LPVOID *ppv) {
- using namespace mswebview2::cast_info;
-
- if (!ppv) {
- return E_POINTER;
- }
-
- if (cast_if_equal_iid(this, riid,
- add_script_to_execute_on_document_created_completed,
- ppv)) {
- return S_OK;
- }
-
- return E_NOINTERFACE;
- }
-
- HRESULT STDMETHODCALLTYPE Invoke(HRESULT res, LPCWSTR id) {
- m_cb(res, id);
- return S_OK;
- }
-
-private:
- callback_fn m_cb;
- std::atomic m_ref_count{1};
-};
-
-class user_script::impl {
-public:
- impl(const std::wstring &id, const std::wstring &code)
- : m_id{id}, m_code{code} {}
-
- impl(const impl &) = delete;
- impl &operator=(const impl &) = delete;
- impl(impl &&) = delete;
- impl &operator=(impl &&) = delete;
-
- const std::wstring &get_id() const { return m_id; }
- const std::wstring &get_code() const { return m_code; }
-
-private:
- std::wstring m_id;
- std::wstring m_code;
-};
-
-class win32_edge_engine : public engine_base {
-public:
- win32_edge_engine(bool debug, void *window) : engine_base{!window} {
- window_init(window);
- window_settings(debug);
- dispatch_size_default();
- }
-
- virtual ~win32_edge_engine() {
- if (m_com_handler) {
- m_com_handler->Release();
- m_com_handler = nullptr;
- }
- if (m_webview) {
- m_webview->Release();
- m_webview = nullptr;
- }
- if (m_controller) {
- m_controller->Release();
- m_controller = nullptr;
- }
- // Replace wndproc to avoid callbacks and other bad things during
- // destruction.
- auto wndproc = reinterpret_cast(
- +[](HWND hwnd, UINT msg, WPARAM wp, LPARAM lp) -> LRESULT {
- return DefWindowProcW(hwnd, msg, wp, lp);
- });
- if (m_widget) {
- SetWindowLongPtrW(m_widget, GWLP_WNDPROC, wndproc);
- }
- if (m_window && owns_window()) {
- SetWindowLongPtrW(m_window, GWLP_WNDPROC, wndproc);
- }
- if (m_widget) {
- DestroyWindow(m_widget);
- m_widget = nullptr;
- }
- if (m_window) {
- if (owns_window()) {
- DestroyWindow(m_window);
- on_window_destroyed(true);
- }
- m_window = nullptr;
- }
- if (owns_window()) {
- // Not strictly needed for windows to close immediately but aligns
- // behavior across backends.
- deplete_run_loop_event_queue();
- }
- // We need the message window in order to deplete the event queue.
- if (m_message_window) {
- SetWindowLongPtrW(m_message_window, GWLP_WNDPROC, wndproc);
- DestroyWindow(m_message_window);
- m_message_window = nullptr;
- }
- }
-
- win32_edge_engine(const win32_edge_engine &other) = delete;
- win32_edge_engine &operator=(const win32_edge_engine &other) = delete;
- win32_edge_engine(win32_edge_engine &&other) = delete;
- win32_edge_engine &operator=(win32_edge_engine &&other) = delete;
-
-protected:
- noresult run_impl() override {
- MSG msg;
- while (GetMessageW(&msg, nullptr, 0, 0) > 0) {
- TranslateMessage(&msg);
- DispatchMessageW(&msg);
- }
- return {};
- }
- result window_impl() override {
- if (m_window) {
- return m_window;
- }
- return error_info{WEBVIEW_ERROR_INVALID_STATE};
- }
- result widget_impl() override {
- if (m_widget) {
- return m_widget;
- }
- return error_info{WEBVIEW_ERROR_INVALID_STATE};
- }
- result browser_controller_impl() override {
- if (m_controller) {
- return m_controller;
- }
- return error_info{WEBVIEW_ERROR_INVALID_STATE};
- }
- noresult terminate_impl() override {
- PostQuitMessage(0);
- return {};
- }
- noresult dispatch_impl(dispatch_fn_t f) override {
- PostMessageW(m_message_window, WM_APP, 0, (LPARAM) new dispatch_fn_t(f));
- return {};
- }
-
- noresult set_title_impl(const std::string &title) override {
- SetWindowTextW(m_window, widen_string(title).c_str());
- return {};
- }
-
- noresult set_size_impl(int width, int height, webview_hint_t hints) override {
- auto style = GetWindowLong(m_window, GWL_STYLE);
- if (hints == WEBVIEW_HINT_FIXED) {
- style &= ~(WS_THICKFRAME | WS_MAXIMIZEBOX);
- } else {
- style |= (WS_THICKFRAME | WS_MAXIMIZEBOX);
- }
- SetWindowLong(m_window, GWL_STYLE, style);
-
- if (hints == WEBVIEW_HINT_MAX) {
- m_maxsz.x = width;
- m_maxsz.y = height;
- } else if (hints == WEBVIEW_HINT_MIN) {
- m_minsz.x = width;
- m_minsz.y = height;
- } else {
- auto dpi = get_window_dpi(m_window);
- m_dpi = dpi;
- auto scaled_size =
- scale_size(width, height, get_default_window_dpi(), dpi);
- auto frame_size =
- make_window_frame_size(m_window, scaled_size.cx, scaled_size.cy, dpi);
- SetWindowPos(m_window, nullptr, 0, 0, frame_size.cx, frame_size.cy,
- SWP_NOZORDER | SWP_NOACTIVATE | SWP_NOMOVE |
- SWP_FRAMECHANGED);
- }
- return window_show();
- }
-
- noresult navigate_impl(const std::string &url) override {
- auto wurl = widen_string(url);
- m_webview->Navigate(wurl.c_str());
- return {};
- }
-
- noresult eval_impl(const std::string &js) override {
- // TODO: Skip if no content has begun loading yet. Can't check with
- // ICoreWebView2::get_Source because it returns "about:blank".
- auto wjs = widen_string(js);
- m_webview->ExecuteScript(wjs.c_str(), nullptr);
- return {};
- }
-
- noresult set_html_impl(const std::string &html) override {
- m_webview->NavigateToString(widen_string(html).c_str());
- return {};
- }
-
- user_script add_user_script_impl(const std::string &js) override {
- auto wjs = widen_string(js);
- std::wstring script_id;
- bool done{};
- webview2_user_script_added_handler handler{[&](HRESULT res, LPCWSTR id) {
- if (SUCCEEDED(res)) {
- script_id = id;
- }
- done = true;
- }};
- auto res =
- m_webview->AddScriptToExecuteOnDocumentCreated(wjs.c_str(), &handler);
- if (SUCCEEDED(res)) {
- // We want to guard against executing the default `set_size` prematurely
- set_default_size_guard(true);
- // Sadly we need to pump the event loop in order to get the script ID.
- run_event_loop_while([&] { return !done; });
- // The user's `set_size` may have been executed from the depleted event queue,
- // and if so, guard against putting the default `set_size` back onto the queue.
- if (!m_is_window_shown) {
- set_default_size_guard(false);
- dispatch_size_default();
- }
- }
- // TODO: There's a non-zero chance that we didn't get the script ID.
- // We need to convey the error somehow.
- return user_script{
- js, user_script::impl_ptr{new user_script::impl{script_id, wjs},
- [](user_script::impl *p) { delete p; }}};
- }
-
- void
- remove_all_user_scripts_impl(const std::list &scripts) override {
- for (const auto &script : scripts) {
- const auto &id = script.get_impl().get_id();
- m_webview->RemoveScriptToExecuteOnDocumentCreated(id.c_str());
- }
- }
-
- bool are_user_scripts_equal_impl(const user_script &first,
- const user_script &second) override {
- const auto &first_id = first.get_impl().get_id();
- const auto &second_id = second.get_impl().get_id();
- return first_id == second_id;
- }
-
-private:
- void window_init(void *window) {
- if (!is_webview2_available()) {
- throw exception{WEBVIEW_ERROR_MISSING_DEPENDENCY,
- "WebView2 is unavailable"};
- }
-
- HINSTANCE hInstance = GetModuleHandle(nullptr);
-
- if (owns_window()) {
- m_com_init = {COINIT_APARTMENTTHREADED};
- enable_dpi_awareness();
-
- HICON icon = (HICON)LoadImage(
- hInstance, IDI_APPLICATION, IMAGE_ICON, GetSystemMetrics(SM_CXICON),
- GetSystemMetrics(SM_CYICON), LR_DEFAULTCOLOR);
-
- // Create a top-level window.
- WNDCLASSEXW wc;
- ZeroMemory(&wc, sizeof(WNDCLASSEX));
- wc.cbSize = sizeof(WNDCLASSEX);
- wc.hInstance = hInstance;
- wc.lpszClassName = L"webview";
- wc.hIcon = icon;
- wc.lpfnWndProc = (WNDPROC)(+[](HWND hwnd, UINT msg, WPARAM wp,
- LPARAM lp) -> LRESULT {
- win32_edge_engine *w{};
-
- if (msg == WM_NCCREATE) {
- auto *lpcs{reinterpret_cast(lp)};
- w = static_cast(lpcs->lpCreateParams);
- w->m_window = hwnd;
- SetWindowLongPtrW(hwnd, GWLP_USERDATA, reinterpret_cast(w));
- enable_non_client_dpi_scaling_if_needed(hwnd);
- apply_window_theme(hwnd);
- } else {
- w = reinterpret_cast(
- GetWindowLongPtrW(hwnd, GWLP_USERDATA));
- }
-
- if (!w) {
- return DefWindowProcW(hwnd, msg, wp, lp);
- }
-
- switch (msg) {
- case WM_SIZE:
- w->resize_widget();
- break;
- case WM_CLOSE:
- DestroyWindow(hwnd);
- break;
- case WM_DESTROY:
- w->m_window = nullptr;
- SetWindowLongPtrW(hwnd, GWLP_USERDATA, 0);
- w->on_window_destroyed();
- break;
- case WM_GETMINMAXINFO: {
- auto lpmmi = (LPMINMAXINFO)lp;
- if (w->m_maxsz.x > 0 && w->m_maxsz.y > 0) {
- lpmmi->ptMaxSize = w->m_maxsz;
- lpmmi->ptMaxTrackSize = w->m_maxsz;
- }
- if (w->m_minsz.x > 0 && w->m_minsz.y > 0) {
- lpmmi->ptMinTrackSize = w->m_minsz;
- }
- } break;
- case 0x02E4 /*WM_GETDPISCALEDSIZE*/: {
- auto dpi = static_cast(wp);
- auto *size{reinterpret_cast(lp)};
- *size = w->get_scaled_size(w->m_dpi, dpi);
- return TRUE;
- }
- case 0x02E0 /*WM_DPICHANGED*/: {
- // Windows 10: The size we get here is exactly what we supplied to WM_GETDPISCALEDSIZE.
- // Windows 11: The size we get here is NOT what we supplied to WM_GETDPISCALEDSIZE.
- // Due to this difference, don't use the suggested bounds.
- auto dpi = static_cast(HIWORD(wp));
- w->on_dpi_changed(dpi);
- break;
- }
- case WM_SETTINGCHANGE: {
- auto *area = reinterpret_cast(lp);
- if (area) {
- w->on_system_setting_change(area);
- }
- break;
- }
- case WM_ACTIVATE:
- if (LOWORD(wp) != WA_INACTIVE) {
- w->focus_webview();
- }
- break;
- default:
- return DefWindowProcW(hwnd, msg, wp, lp);
- }
- return 0;
- });
- RegisterClassExW(&wc);
-
- CreateWindowW(L"webview", L"", WS_OVERLAPPEDWINDOW, CW_USEDEFAULT,
- CW_USEDEFAULT, 0, 0, nullptr, nullptr, hInstance, this);
- if (!m_window) {
- throw exception{WEBVIEW_ERROR_INVALID_STATE, "Window is null"};
- }
- on_window_created();
-
- m_dpi = get_window_dpi(m_window);
- } else {
- m_window = IsWindow(static_cast(window))
- ? static_cast(window)
- : *(static_cast(window));
- m_dpi = get_window_dpi(m_window);
- }
- // Create a window that WebView2 will be embedded into.
- WNDCLASSEXW widget_wc{};
- widget_wc.cbSize = sizeof(WNDCLASSEX);
- widget_wc.hInstance = hInstance;
- widget_wc.lpszClassName = L"webview_widget";
- widget_wc.lpfnWndProc = (WNDPROC)(+[](HWND hwnd, UINT msg, WPARAM wp,
- LPARAM lp) -> LRESULT {
- win32_edge_engine *w{};
-
- if (msg == WM_NCCREATE) {
- auto *lpcs{reinterpret_cast(lp)};
- w = static_cast(lpcs->lpCreateParams);
- w->m_widget = hwnd;
- SetWindowLongPtrW(hwnd, GWLP_USERDATA, reinterpret_cast(w));
- } else {
- w = reinterpret_cast(
- GetWindowLongPtrW(hwnd, GWLP_USERDATA));
- }
-
- if (!w) {
- return DefWindowProcW(hwnd, msg, wp, lp);
- }
-
- switch (msg) {
- case WM_SIZE:
- w->resize_webview();
- break;
- case WM_DESTROY:
- w->m_widget = nullptr;
- SetWindowLongPtrW(hwnd, GWLP_USERDATA, 0);
- break;
- default:
- return DefWindowProcW(hwnd, msg, wp, lp);
- }
- return 0;
- });
- RegisterClassExW(&widget_wc);
- CreateWindowExW(WS_EX_CONTROLPARENT, L"webview_widget", nullptr, WS_CHILD,
- 0, 0, 0, 0, m_window, nullptr, hInstance, this);
- if (!m_widget) {
- throw exception{WEBVIEW_ERROR_INVALID_STATE, "Widget window is null"};
- }
-
- // Create a message-only window for internal messaging.
- WNDCLASSEXW message_wc{};
- message_wc.cbSize = sizeof(WNDCLASSEX);
- message_wc.hInstance = hInstance;
- message_wc.lpszClassName = L"webview_message";
- message_wc.lpfnWndProc = (WNDPROC)(+[](HWND hwnd, UINT msg, WPARAM wp,
- LPARAM lp) -> LRESULT {
- win32_edge_engine *w{};
-
- if (msg == WM_NCCREATE) {
- auto *lpcs{reinterpret_cast(lp)};
- w = static_cast(lpcs->lpCreateParams);
- w->m_message_window = hwnd;
- SetWindowLongPtrW(hwnd, GWLP_USERDATA, reinterpret_cast(w));
- } else {
- w = reinterpret_cast(
- GetWindowLongPtrW(hwnd, GWLP_USERDATA));
- }
-
- if (!w) {
- return DefWindowProcW(hwnd, msg, wp, lp);
- }
-
- switch (msg) {
- case WM_APP:
- if (auto f = (dispatch_fn_t *)(lp)) {
- (*f)();
- delete f;
- }
- break;
- case WM_DESTROY:
- w->m_message_window = nullptr;
- SetWindowLongPtrW(hwnd, GWLP_USERDATA, 0);
- break;
- default:
- return DefWindowProcW(hwnd, msg, wp, lp);
- }
- return 0;
- });
- RegisterClassExW(&message_wc);
- CreateWindowExW(0, L"webview_message", nullptr, 0, 0, 0, 0, 0, HWND_MESSAGE,
- nullptr, hInstance, this);
- if (!m_message_window) {
- throw exception{WEBVIEW_ERROR_INVALID_STATE, "Message window is null"};
- }
- }
-
- void window_settings(bool debug) {
- auto cb =
- std::bind(&win32_edge_engine::on_message, this, std::placeholders::_1);
- embed(m_widget, debug, cb).ensure_ok();
- }
-
- noresult window_show() {
- if (owns_window() && !m_is_window_shown) {
- ShowWindow(m_window, SW_SHOW);
- UpdateWindow(m_window);
- SetFocus(m_window);
- m_is_window_shown = true;
- }
- return {};
- }
- noresult embed(HWND wnd, bool debug, msg_cb_t cb) {
- std::atomic_flag flag = ATOMIC_FLAG_INIT;
- flag.test_and_set();
-
- wchar_t currentExePath[MAX_PATH];
- GetModuleFileNameW(nullptr, currentExePath, MAX_PATH);
- wchar_t *currentExeName = PathFindFileNameW(currentExePath);
-
- wchar_t dataPath[MAX_PATH];
- if (!SUCCEEDED(
- SHGetFolderPathW(nullptr, CSIDL_APPDATA, nullptr, 0, dataPath))) {
- return error_info{WEBVIEW_ERROR_UNSPECIFIED, "SHGetFolderPathW failed"};
- }
- wchar_t userDataFolder[MAX_PATH];
- PathCombineW(userDataFolder, dataPath, currentExeName);
-
- m_com_handler = new webview2_com_handler(
- wnd, cb,
- [&](ICoreWebView2Controller *controller, ICoreWebView2 *webview) {
- if (!controller || !webview) {
- flag.clear();
- return;
- }
- controller->AddRef();
- webview->AddRef();
- m_controller = controller;
- m_webview = webview;
- flag.clear();
- });
-
- m_com_handler->set_attempt_handler([&] {
- return m_webview2_loader.create_environment_with_options(
- nullptr, userDataFolder, nullptr, m_com_handler);
- });
- m_com_handler->try_create_environment();
-
- // Pump the message loop until WebView2 has finished initialization.
- bool got_quit_msg = false;
- MSG msg;
- while (flag.test_and_set() && GetMessageW(&msg, nullptr, 0, 0) >= 0) {
- if (msg.message == WM_QUIT) {
- got_quit_msg = true;
- break;
- }
- TranslateMessage(&msg);
- DispatchMessageW(&msg);
- }
- if (got_quit_msg) {
- return error_info{WEBVIEW_ERROR_CANCELED};
- }
- if (!m_controller || !m_webview) {
- return error_info{WEBVIEW_ERROR_INVALID_STATE};
- }
- ICoreWebView2Settings *settings = nullptr;
- auto res = m_webview->get_Settings(&settings);
- if (res != S_OK) {
- return error_info{WEBVIEW_ERROR_UNSPECIFIED, "get_Settings failed"};
- }
- res = settings->put_AreDevToolsEnabled(debug ? TRUE : FALSE);
- if (res != S_OK) {
- return error_info{WEBVIEW_ERROR_UNSPECIFIED,
- "put_AreDevToolsEnabled failed"};
- }
- res = settings->put_IsStatusBarEnabled(FALSE);
- if (res != S_OK) {
- return error_info{WEBVIEW_ERROR_UNSPECIFIED,
- "put_IsStatusBarEnabled failed"};
- }
- add_init_script("function(message) {\n\
- return window.chrome.webview.postMessage(message);\n\
-}");
- resize_webview();
- m_controller->put_IsVisible(TRUE);
- ShowWindow(m_widget, SW_SHOW);
- UpdateWindow(m_widget);
- if (owns_window()) {
- focus_webview();
- }
- return {};
- }
-
- void resize_widget() {
- if (m_widget) {
- RECT r{};
- if (GetClientRect(GetParent(m_widget), &r)) {
- MoveWindow(m_widget, r.left, r.top, r.right - r.left, r.bottom - r.top,
- TRUE);
- }
- }
- }
-
- void resize_webview() {
- if (m_widget && m_controller) {
- RECT bounds{};
- if (GetClientRect(m_widget, &bounds)) {
- m_controller->put_Bounds(bounds);
- }
- }
- }
-
- void focus_webview() {
- if (m_controller) {
- m_controller->MoveFocus(COREWEBVIEW2_MOVE_FOCUS_REASON_PROGRAMMATIC);
- }
- }
-
- bool is_webview2_available() const noexcept {
- LPWSTR version_info = nullptr;
- auto res = m_webview2_loader.get_available_browser_version_string(
- nullptr, &version_info);
- // The result will be equal to HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND)
- // if the WebView2 runtime is not installed.
- auto ok = SUCCEEDED(res) && version_info;
- if (version_info) {
- CoTaskMemFree(version_info);
- }
- return ok;
- }
-
- void on_dpi_changed(int dpi) {
- auto scaled_size = get_scaled_size(m_dpi, dpi);
- auto frame_size =
- make_window_frame_size(m_window, scaled_size.cx, scaled_size.cy, dpi);
- SetWindowPos(m_window, nullptr, 0, 0, frame_size.cx, frame_size.cy,
- SWP_NOZORDER | SWP_NOACTIVATE | SWP_NOMOVE | SWP_FRAMECHANGED);
- m_dpi = dpi;
- }
-
- SIZE get_size() const {
- RECT bounds;
- GetClientRect(m_window, &bounds);
- auto width = bounds.right - bounds.left;
- auto height = bounds.bottom - bounds.top;
- return {width, height};
- }
-
- SIZE get_scaled_size(int from_dpi, int to_dpi) const {
- auto size = get_size();
- return scale_size(size.cx, size.cy, from_dpi, to_dpi);
- }
-
- void on_system_setting_change(const wchar_t *area) {
- // Detect light/dark mode change in system.
- if (lstrcmpW(area, L"ImmersiveColorSet") == 0) {
- apply_window_theme(m_window);
- }
- }
-
- void run_event_loop_while(std::function fn) override {
- MSG msg;
- while (fn() && GetMessageW(&msg, nullptr, 0, 0) > 0) {
- TranslateMessage(&msg);
- DispatchMessageW(&msg);
- }
- }
-
- // The app is expected to call CoInitializeEx before
- // CreateCoreWebView2EnvironmentWithOptions.
- // Source: https://docs.microsoft.com/en-us/microsoft-edge/webview2/reference/win32/webview2-idl#createcorewebview2environmentwithoptions
- com_init_wrapper m_com_init;
- HWND m_window = nullptr;
- HWND m_widget = nullptr;
- HWND m_message_window = nullptr;
- POINT m_minsz = POINT{0, 0};
- POINT m_maxsz = POINT{0, 0};
- DWORD m_main_thread = GetCurrentThreadId();
- ICoreWebView2 *m_webview = nullptr;
- ICoreWebView2Controller *m_controller = nullptr;
- webview2_com_handler *m_com_handler = nullptr;
- mswebview2::loader m_webview2_loader;
- int m_dpi{};
- bool m_is_window_shown{};
-};
-
-} // namespace detail
-
-using browser_engine = detail::win32_edge_engine;
-
-} // namespace webview
-
-#endif // defined(WEBVIEW_PLATFORM_WINDOWS) && defined(WEBVIEW_EDGE)
-#endif // defined(__cplusplus) && !defined(WEBVIEW_HEADER)
-#endif // WEBVIEW_BACKENDS_WIN32_EDGE_HH
diff --git a/core/include/webview/detail/basic_result.hh b/core/include/webview/detail/basic_result.hh
deleted file mode 100644
index 578d4b6fc..000000000
--- a/core/include/webview/detail/basic_result.hh
+++ /dev/null
@@ -1,119 +0,0 @@
-/*
- * MIT License
- *
- * Copyright (c) 2017 Serge Zaitsev
- * Copyright (c) 2022 Steffen André Langnes
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
-#ifndef WEBVIEW_DETAIL_BASIC_RESULT_HH
-#define WEBVIEW_DETAIL_BASIC_RESULT_HH
-
-#if defined(__cplusplus) && !defined(WEBVIEW_HEADER)
-
-#include "exceptions.hh"
-#include "optional.hh"
-
-#include
-
-namespace webview {
-namespace detail {
-
-template
-class basic_result {
-public:
- using value_type = Value;
- using error_type = Error;
- using exception_type = Exception;
-
- basic_result() : basic_result(value_type{}) {}
-
- basic_result(const value_type &value) : m_value{value} {}
- basic_result(value_type &&value) : m_value{std::forward(value)} {}
-
- basic_result(const error_type &error) : m_error{error} {}
- basic_result(error_type &&error) : m_error{std::forward(error)} {}
-
- bool ok() const { return has_value() && !has_error(); }
- bool has_value() const { return m_value.has_value(); }
- bool has_error() const { return m_error.has_value(); }
-
- void ensure_ok() {
- if (!ok()) {
- throw exception_type{error()};
- }
- }
-
- const value_type &value() const {
- if (!has_value()) {
- throw bad_access{};
- }
- return m_value.get();
- }
-
- const error_type &error() const {
- if (!has_error()) {
- throw bad_access{};
- }
- return m_error.get();
- }
-
-private:
- optional m_value;
- optional m_error;
-};
-
-template
-class basic_result {
-public:
- using value_type = void;
- using error_type = Error;
- using exception_type = Exception;
-
- basic_result() = default;
-
- basic_result(error_type &&error) : m_error{std::forward(error)} {}
-
- bool ok() const { return !has_error(); }
-
- bool has_error() const { return m_error.has_value(); }
-
- void ensure_ok() {
- if (!ok()) {
- throw exception_type{error()};
- }
- }
-
- const error_type &error() const {
- if (!has_error()) {
- throw bad_access{};
- }
- return m_error.get();
- }
-
-private:
- optional m_error;
-};
-
-} // namespace detail
-} // namespace webview
-
-#endif // defined(__cplusplus) && !defined(WEBVIEW_HEADER)
-#endif // WEBVIEW_DETAIL_BASIC_RESULT_HH
diff --git a/core/include/webview/detail/engine_base.hh b/core/include/webview/detail/engine_base.hh
deleted file mode 100644
index 01c8d29f5..000000000
--- a/core/include/webview/detail/engine_base.hh
+++ /dev/null
@@ -1,382 +0,0 @@
-/*
- * MIT License
- *
- * Copyright (c) 2017 Serge Zaitsev
- * Copyright (c) 2022 Steffen André Langnes
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
-#ifndef WEBVIEW_DETAIL_ENGINE_BASE_HH
-#define WEBVIEW_DETAIL_ENGINE_BASE_HH
-
-#if defined(__cplusplus) && !defined(WEBVIEW_HEADER)
-
-#include "../errors.hh"
-#include "../types.h"
-#include "../types.hh"
-#include "json.hh"
-#include "user_script.hh"
-
-#include
-#include
-#include
-#include