diff --git a/docs/advanced/modules.mdx b/docs/advanced/modules.mdx index 22cfe3d..673d71b 100644 --- a/docs/advanced/modules.mdx +++ b/docs/advanced/modules.mdx @@ -87,8 +87,14 @@ To use the module, extend your `smartview` declaration as shown in the following ```cpp int main() { + auto app = saucer::application::acquire({ + .id = "modules", + }); + // green-start - saucer::smartview webview; + saucer::smartview webview{{ + .application = app, + }}; // green-end webview.set_url("https://github.com/saucer/saucer"); @@ -99,7 +105,7 @@ int main() // green-end webview.show(); - webview.run(); + app->run(); return 0; } diff --git a/docs/advanced/schemes.mdx b/docs/advanced/schemes.mdx index 880f466..348b463 100644 --- a/docs/advanced/schemes.mdx +++ b/docs/advanced/schemes.mdx @@ -11,13 +11,19 @@ To add a new custom scheme, you must register the scheme-name **before creating int main() { + // green saucer::webview::register_scheme("demo"); - saucer::smartview smartview; - // ... + auto app = saucer::application::acquire({ + .id = "scheme-demo", + }); - smartview.show(); - smartview.run(); + saucer::smartview smartview{{ + .application = app, + }}; + + smartview.show(); + app->run(); return 0; } @@ -26,26 +32,34 @@ int main() ## Handle Scheme After registering a scheme it can be handled per-instance. To do so, call `webview.handle_scheme("name", )`. -The callback will receive a `const saucer::request &` and should return either a `saucer::response` or an error. +The callback will receive a `const saucer::scheme::request &` and should return either a `saucer::scheme::response` or an error. The given request data contains various information on the requested resource, such as the url, request method, body and headers. ```cpp title="Example: Handle Scheme" -#include #include +#include int main() { + // green saucer::webview::register_scheme("demo"); - saucer::smartview smartview; + + auto app = saucer::application::acquire({ + .id = "scheme-demo", + }); + + saucer::smartview smartview{{ + .application = app, + }}; // green-start smartview.handle_scheme("demo", - [](const saucer::request &req) -> saucer::scheme_handler::result_type + [](const saucer::scheme::request &req) -> saucer::scheme::handler::result_type { std::println("Requested: \"{}\" ({})", req.url(), req.method()); - return saucer::response{ + return saucer::scheme::response{ .data = saucer::make_stash("Hello from scheme handler!"), .mime = "text/html", }; @@ -55,7 +69,7 @@ int main() // green-end smartview.show(); - smartview.run(); + app->run(); return 0; } diff --git a/docs/common-pitfalls.cpp b/docs/common-pitfalls.cpp index 276c2e8..155f77a 100644 --- a/docs/common-pitfalls.cpp +++ b/docs/common-pitfalls.cpp @@ -3,7 +3,13 @@ int main() { - saucer::smartview webview; + auto app = saucer::application::acquire({ + .id = "pitfalls", + }); + + saucer::smartview webview{{ + .application = app, + }}; webview.set_size(500, 600); webview.set_title("Hello World!"); @@ -13,13 +19,13 @@ int main() webview.expose( "add_random", [&](float number) { - auto random = webview.eval("Math.random()").get(); + auto random = webview.evaluate("Math.random()").get(); return number + random; }, - true); + saucer::launch::async); webview.show(); - webview.run(); + app->run(); return 0; } @@ -27,7 +33,14 @@ int main() // begin: execution-order-fixed int main() { - saucer::smartview webview; + auto app = saucer::application::acquire({ + .id = "pitfalls", + }); + + saucer::smartview webview{{ + .application = app, + }}; + webview.set_size(500, 600); webview.set_title("Hello World!"); @@ -37,16 +50,16 @@ int main() webview.expose( "add_random", [&](float number) { - auto random = webview.eval("Math.random()").get(); + auto random = webview.evaluate("Math.random()").get(); return number + random; }, - true); - + saucer::launch::async); // green webview.set_url("https://github.com"); webview.show(); - webview.run(); + + app->run(); return 0; } @@ -54,12 +67,19 @@ int main() // begin: run-blocking int main() { - saucer::smartview webview; + auto app = saucer::application::acquire({ + .id = "pitfalls", + }); + + saucer::smartview webview{{ + .application = app, + }}; + webview.set_size(500, 600); webview.set_title("Hello World!"); webview.show(); - webview.run(); + app->run(); webview.set_url("https://github.com"); @@ -69,7 +89,14 @@ int main() // begin: run-blocking-fixed int main() { - saucer::smartview webview; + auto app = saucer::application::acquire({ + .id = "pitfalls", + }); + + saucer::smartview webview{{ + .application = app, + }}; + webview.set_size(500, 600); webview.set_title("Hello World!"); @@ -77,7 +104,7 @@ int main() webview.set_url("https://github.com"); webview.show(); - webview.run(); + app->run(); // red webview.set_url("https://github.com"); @@ -85,44 +112,3 @@ int main() return 0; } // end: run-blocking-fixed -// begin: static-init -saucer::smartview webview; - -int main() -{ - webview.set_size(500, 600); - webview.set_title("Hello World!"); - - webview.set_url("https://github.com"); - - webview.show(); - webview.run(); - - return 0; -} -// end: static-init -// begin: static-init-fixed -// red -saucer::smartview webview; -// green -std::unique_ptr> webview; - -int main() -{ - // green - webview = std::make_unique>(); - - webview->set_size(500, 600); - webview->set_title("Hello World!"); - - webview->set_url("https://github.com"); - - webview->show(); - webview->run(); - - // green - webview.reset(); - - return 0; -} -// end: static-init-fixed diff --git a/docs/common-pitfalls.mdx b/docs/common-pitfalls.mdx index 249ec90..1472abb 100644 --- a/docs/common-pitfalls.mdx +++ b/docs/common-pitfalls.mdx @@ -43,7 +43,7 @@ They may contain useful information, like in this case, that run is potentially ```cpp template -[[sc::may_block]] static void run(); +[[sc::may_block]] void run() const; ``` ::: @@ -56,17 +56,3 @@ The fix for this should be obvious: {getCode('run-blocking-fixed')} - -## Static Initialization - -Certain backends are not compatible with static initialization, thus you should make sure that all saucer instances live within the scope of `main`. - - - {getCode('static-init')} - - -In case you need a global instance consider using a smart-pointer instead: - - - {getCode('static-init-fixed')} - diff --git a/docs/custom-types.cpp b/docs/custom-types.cpp index 894afb1..20d7bae 100644 --- a/docs/custom-types.cpp +++ b/docs/custom-types.cpp @@ -18,7 +18,14 @@ struct glz::meta int main() { - saucer::smartview smartview; + auto app = saucer::application::acquire({ + .id = "hello-world", + }); + + saucer::smartview smartview{{ + .application = app, + }}; + smartview.set_title("Hello World!"); // highlight-next-line @@ -28,7 +35,8 @@ int main() smartview.set_url("https://google.com"); smartview.show(); - smartview.run(); + + app->run(); return 0; } diff --git a/docs/embedding.mdx b/docs/embedding.mdx index aec63e6..2a44f1b 100644 --- a/docs/embedding.mdx +++ b/docs/embedding.mdx @@ -96,7 +96,14 @@ To serve the files simply call `serve` and specify the file name. int main() { - saucer::smartview smartview; + auto app = saucer::application::acquire({ + .id = "embedding", + }); + + saucer::smartview smartview{{ + .application = app, + }}; + smartview.set_title("Hello World!"); smartview.expose("add_ten", [](int i) @@ -112,7 +119,7 @@ int main() smartview.serve("index.html"); smartview.show(); - smartview.run(); + app->run(); return 0; } @@ -131,7 +138,13 @@ The example below demonstrates how to embed a file that will load the given reso int main() { - saucer::smartview smartview; + auto app = saucer::application::acquire({ + .id = "embedding", + }); + + saucer::smartview smartview{{ + .application = app, + }}; smartview.embed({{"index.html", saucer::embedded_file{ .content = saucer::stash<>::lazy( @@ -146,7 +159,7 @@ int main() smartview.serve("index.html"); smartview.show(); - smartview.run(); + app->run(); return 0; } diff --git a/docs/events.mdx b/docs/events.mdx index 0af356c..a02a438 100644 --- a/docs/events.mdx +++ b/docs/events.mdx @@ -15,12 +15,12 @@ import minimize from './events/minimize.cpp'; import focus from './events/focus.cpp'; import decorated from './events/decorated.cpp'; -import urlChanged from './events/url-changed.cpp'; -import loadFinished from './events/load-finished.cpp'; -import loadStarted from './events/load-started.cpp'; +import navigate from './events/navigate.cpp'; +import navigated from './events/navigated.cpp'; +import load from './events/load.cpp'; import domReady from './events/dom-ready.cpp'; -import titleChanged from './events/title-changed.cpp'; -import iconChanged from './events/icon-changed.cpp'; +import title from './events/title.cpp'; +import favicon from './events/favicon.cpp'; # Events @@ -84,61 +84,58 @@ smartview.clear(saucer::window_event::resize); - - Called when the Window is resized. + + Called when the Window decorations change.
- {resize.split('\n')[0]} + {decorated.split('\n')[0]} - {resize.split('\n').slice(2).join('\n')} + {decorated.split('\n').slice(2).join('\n')}
- - Called when the Window is closed. + + Called when the Window is maximized or restored after being maximized.
- {closed.split('\n')[0]} + {maximize.split('\n')[0]} - {closed.split('\n').slice(2).join('\n')} + {maximize.split('\n').slice(2).join('\n')}
- - Called when the Window is about to be closed. + + Called when the Window is minimized or restored after being minimized.
- - Returning true from within the callback prevents the close. - - {close.split('\n')[0]} + {minimize.split('\n')[0]} - {close.split('\n').slice(2).join('\n')} + {minimize.split('\n').slice(2).join('\n')}
- - Called when the Window is maximized or restored after being maximized. + + Called when the Window is closed.
- {maximize.split('\n')[0]} + {closed.split('\n')[0]} - {maximize.split('\n').slice(2).join('\n')} + {closed.split('\n').slice(2).join('\n')}
- - Called when the Window is minimized or restored after being minimized. + + Called when the Window is resized.
- {minimize.split('\n')[0]} + {resize.split('\n')[0]} - {minimize.split('\n').slice(2).join('\n')} + {resize.split('\n').slice(2).join('\n')}
@@ -153,61 +150,67 @@ smartview.clear(saucer::window_event::resize);
- - Called when the Window decorations change. + + Called when the Window is about to be closed.
+ + Returning saucer::policy::block from within the callback prevents the close. + - {decorated.split('\n')[0]} + {close.split('\n')[0]} - {decorated.split('\n').slice(2).join('\n')} + {close.split('\n').slice(2).join('\n')}
- - Called when a new URL is loaded. + + Called when the DOM Content loaded.
- {urlChanged.split('\n')[0]} + {domReady.split('\n')[0]} - {urlChanged.split('\n').slice(2).join('\n')} + {domReady.split('\n').slice(2).join('\n')}
- - Called when a webpage finished loading. + + Called when a new URL was loaded.
- {loadFinished.split('\n')[0]} + {navigated.split('\n')[0]} - {loadFinished.split('\n').slice(2).join('\n')} + {navigated.split('\n').slice(2).join('\n')}
- - Called when a webpage starts loading. + + Called when the URL is about to change.
+ + Returning saucer::policy::block from within the callback prevents the navigation. + - {loadStarted.split('\n')[0]} + {navigate.split('\n')[0]} - {loadStarted.split('\n').slice(2).join('\n')} + {navigate.split('\n').slice(2).join('\n')}
- - Called when the DOM Content loaded. + + Called when the favicon changes.
- {domReady.split('\n')[0]} + {favicon.split('\n')[0]} - {domReady.split('\n').slice(2).join('\n')} + {favicon.split('\n').slice(2).join('\n')}
@@ -215,21 +218,21 @@ smartview.clear(saucer::window_event::resize); Called when the document title changes.
- {titleChanged.split('\n')[0]} + {title.split('\n')[0]} - {titleChanged.split('\n').slice(2).join('\n')} + {title.split('\n').slice(2).join('\n')}
- - Called when the favicon changes. + + Called when the web-page load progresses.
- {iconChanged.split('\n')[0]} + {load.split('\n')[0]} - {iconChanged.split('\n').slice(2).join('\n')} + {load.split('\n').slice(2).join('\n')}
diff --git a/docs/events/close.cpp b/docs/events/close.cpp index cd9d1a9..87fd146 100644 --- a/docs/events/close.cpp +++ b/docs/events/close.cpp @@ -1,7 +1,7 @@ -std::function +std::function smartview.on([]() { std::println("Preventing a close!"); - return true; + return saucer::policy::block; }); diff --git a/docs/events/icon-changed.cpp b/docs/events/favicon.cpp similarity index 53% rename from docs/events/icon-changed.cpp rename to docs/events/favicon.cpp index 3f17a3c..efbe87d 100644 --- a/docs/events/icon-changed.cpp +++ b/docs/events/favicon.cpp @@ -1,6 +1,6 @@ std::function -smartview.on([](const saucer::icon& icon) +smartview.on([](const saucer::icon& icon) { std::println("Favicon changed!"); }); diff --git a/docs/events/load-finished.cpp b/docs/events/load-finished.cpp deleted file mode 100644 index bf1b7cf..0000000 --- a/docs/events/load-finished.cpp +++ /dev/null @@ -1,6 +0,0 @@ -std::function - -smartview.on([]() -{ - std::println("Web-Page finished loading!"); -}); diff --git a/docs/events/load-started.cpp b/docs/events/load-started.cpp deleted file mode 100644 index dca860d..0000000 --- a/docs/events/load-started.cpp +++ /dev/null @@ -1,6 +0,0 @@ -std::function - -smartview.on([]() -{ - std::println("Web-Page started loading!"); -}); diff --git a/docs/events/load.cpp b/docs/events/load.cpp new file mode 100644 index 0000000..1ff2dd6 --- /dev/null +++ b/docs/events/load.cpp @@ -0,0 +1,6 @@ +std::function + +smartview.on([](const saucer::state& state) +{ + std::println("Loading progressed"); +}); diff --git a/docs/events/navigate.cpp b/docs/events/navigate.cpp new file mode 100644 index 0000000..6cf2b9e --- /dev/null +++ b/docs/events/navigate.cpp @@ -0,0 +1,12 @@ +std::function + +smartview.on([](const saucer::navigation& nav) +{ + if (!nav.new_window()) + { + return; + } + + auto new_window = /*...*/; + new_window->set_url(nav.url()); +}); diff --git a/docs/events/navigated.cpp b/docs/events/navigated.cpp new file mode 100644 index 0000000..903f31e --- /dev/null +++ b/docs/events/navigated.cpp @@ -0,0 +1,6 @@ +std::function + +smartview.on([](const std::string& url) +{ + std::println("Navigated: {}", url); +}); diff --git a/docs/events/title-changed.cpp b/docs/events/title.cpp similarity index 57% rename from docs/events/title-changed.cpp rename to docs/events/title.cpp index 435e51e..f101183 100644 --- a/docs/events/title-changed.cpp +++ b/docs/events/title.cpp @@ -1,6 +1,6 @@ std::function -smartview.on([](const std::string& title) +smartview.on([](const std::string& title) { std::println("Document Title changed: {}", title); }); diff --git a/docs/events/url-changed.cpp b/docs/events/url-changed.cpp deleted file mode 100644 index 4ea1e32..0000000 --- a/docs/events/url-changed.cpp +++ /dev/null @@ -1,6 +0,0 @@ -std::function - -smartview.on([](const std::string& url) -{ - std::println("New URL loaded: {}", url); -}); diff --git a/docs/frameless.mdx b/docs/frameless.mdx index b27d631..86ce665 100644 --- a/docs/frameless.mdx +++ b/docs/frameless.mdx @@ -33,7 +33,14 @@ You can use the `set_decorations` method to remove the window frame. int main() { - saucer::smartview smartview; + auto app = saucer::application::acquire({ + .id = "frameless", + }); + + saucer::smartview smartview{{ + .application = app, + }}; + smartview.set_title("Hello World!"); // green-start @@ -47,7 +54,8 @@ int main() smartview.set_url("https://google.com"); smartview.show(); - smartview.run(); + + app->run(); return 0; } diff --git a/docs/getting-started/basic-app.cmake b/docs/getting-started/basic-app.cmake index 7085a67..631f6bc 100644 --- a/docs/getting-started/basic-app.cmake +++ b/docs/getting-started/basic-app.cmake @@ -6,6 +6,7 @@ project(your_awesome_app LANGUAGES CXX VERSION 1.0) # -------------------------------------------------------------------------------------------------------- add_executable(${PROJECT_NAME} "main.cpp") + target_compile_features(${PROJECT_NAME} PRIVATE cxx_std_23) set_target_properties(${PROJECT_NAME} PROPERTIES CXX_STANDARD 23 CXX_EXTENSIONS OFF CXX_STANDARD_REQUIRED ON) diff --git a/docs/getting-started/basic-app.mdx b/docs/getting-started/basic-app.mdx index 9f05edc..05f72ef 100644 --- a/docs/getting-started/basic-app.mdx +++ b/docs/getting-started/basic-app.mdx @@ -1,5 +1,5 @@ --- -sidebar_position: 3 +sidebar_position: 4 --- import { VersionedCode } from '../../src/components/CodeBlock'; @@ -31,7 +31,16 @@ Now that you've setup your CMakeLists you can go ahead and create your first bas int main() { // highlight-start - saucer::smartview smartview; // Instantiate smartview + auto app = saucer::application::acquire({ // Instantiate application + .id = "hello-world", // Choose a suitable ID for your program + }); +// highlight-end + +// highlight-start + saucer::smartview smartview{{ // Instantiate smartview + .application = app, + }}; + smartview.set_title("Hello World!"); // Set the window title to "Hello World!" // highlight-end @@ -46,7 +55,8 @@ int main() // highlight-start smartview.set_url("https://google.com"); // Navigate to google.com smartview.show(); // Show the smartview - smartview.run(); // And finally enter the run-loop. + + app->run(); // And finally enter the run-loop. // highlight-end return 0; diff --git a/docs/getting-started/cmake.mdx b/docs/getting-started/cmake.mdx index 1cac111..03cc1aa 100644 --- a/docs/getting-started/cmake.mdx +++ b/docs/getting-started/cmake.mdx @@ -16,26 +16,17 @@ Define the backend to use. By default, the most appropriate for your platform wi ## Modules -```cmake -option(saucer_modules "Enable smartview modules" ON) +```cmake title="Example: Enable Modules" +set(saucer_modules ON) ``` -This option is used to enable module support for saucer. While all the headers required to use modules are always included, +Enable module support for saucer. While all the headers required to use modules are always included, this option is used to ensure proper library and header visibility so that you can use the underlying platform internals without issues. -## Polyfills - -```cmake -option(saucer_polyfill "Enable polyfills. Mainly used for macOS" OFF) -``` - -Use third-party polyfills in case your standard library is missing `std::move_only_function` and `std::jthread`. -This option is always used on MacOS as libc++ is lacking behind in terms of C++23 library features. - ## MSVC-Hack -```cmake -option(saucer_msvc_hack "Fix mutex crashes on mismatching runtimes" OFF) +```cmake title="Example: Enable MSVC Hack" +set(saucer_msvc_hack ON) ``` :::note diff --git a/docs/getting-started/typescript.mdx b/docs/getting-started/typescript.mdx new file mode 100644 index 0000000..c75950d --- /dev/null +++ b/docs/getting-started/typescript.mdx @@ -0,0 +1,28 @@ +--- +sidebar_position: 3 +--- + +import Tabs from '@theme/Tabs'; +import TabItem from '@theme/TabItem'; + +# TypeScript + +When using [TypeScript](https://www.typescriptlang.org/) for your frontend you may want to install the [types](https://github.com/saucer/types) package. + + + + ```bash + npm i -D @saucer-dev/types + ``` + + + ```bash + pnpm i -D @saucer-dev/types + ``` + + + ```bash + yarn add @saucer-dev/types --dev + ``` + + diff --git a/docs/interoperability.mdx b/docs/interoperability.mdx index d58c563..e5acf5b 100644 --- a/docs/interoperability.mdx +++ b/docs/interoperability.mdx @@ -60,7 +60,7 @@ There is no exception handling for exposed functions. You need to make sure to h All async methods are executed by saucers internal thread-pool. By default the thread-pool size is determined by a call to `std::thread::hardware_concurrency()`. -You can specify the amount of threads used in the `saucer::options` taken by the smartview constructor. +You can specify the amount of threads used in the `saucer::preferences` taken by the smartview constructor. ```cpp title="Example: Custom Thread Count" saucer::smartview{{.threads = 1}}; diff --git a/docs/portability.mdx b/docs/portability.mdx index f64791e..4f7ed8d 100644 --- a/docs/portability.mdx +++ b/docs/portability.mdx @@ -10,10 +10,10 @@ Saucer tries its best to make all backends behave the same, however, there are c - * There is no way to specify a status code for custom schemes, thus the user specified one in `saucer::response` is ignored + * There is no way to specify a status code for custom schemes, thus the user specified one in `saucer::scheme::response` is ignored * Usage of JS `fetch` with custom schemes (and embedded files for that matter) is only possible since Qt 6.6 - * `saucer::response::headers` are only respected from Qt 6.7 onwards - * `saucer::request::content()` is only available from Qt 6.7 onwards + * `saucer::scheme::::response::headers` are only respected from Qt 6.7 onwards + * `saucer::scheme::request::content()` is only available from Qt 6.7 onwards * Force-Dark is only available from Qt 6.7 onwards @@ -30,7 +30,7 @@ Saucer tries its best to make all backends behave the same, however, there are c
- The `saucer::options::storage_path` may behave unexpected on macOS. + The `saucer::preferences::storage_path` may behave unexpected on macOS. WKWebView does not offer any way to store webview data to a specific file, instead it associates the data with a UUID through some opaque means. Thus a UUID derived from the provided `storage_path` is given to WKWebView. @@ -42,7 +42,7 @@ Saucer tries its best to make all backends behave the same, however, there are c ## Browser Flags -It is possible to pass certain browser flags to the underlying webview through `saucer::options::browser_flags`. +It is possible to pass certain browser flags to the underlying webview through `saucer::preferences::browser_flags`. For all Chromium based webviews (Qt, WebView2) these can be usual chromium flags. For WebKit based backends (WebKitGtk, WKWebView) these flags behave slightly different. @@ -53,7 +53,10 @@ WebKitGtk accepts browser-flags as key-value pairs in the following form: `prope A list of available properties can be found [in the webkitgtk documentation](https://webkitgtk.org/reference/webkitgtk/stable/class.Settings.html#properties). ```cpp title="Example: Disable JavaScript" -saucer::webview webview{{ .browser_flags = { "enable-javascript=false" } }}; +saucer::webview webview{{ + .application = app, + .browser_flags = {"enable-javascript=false"}, +}}; ``` ### WKWebView Flags @@ -62,7 +65,9 @@ The WebKit backend also accepts browser-flags as key-value pairs. The available properties are all those of the [`WKWebViewConfiguration`](https://developer.apple.com/documentation/webkit/wkwebviewconfiguration?language=objc) and it's members. ```cpp title="Example: WebKit Browser-Flags" -saucer::webview webview{ - {.browser_flags = {"upgradeKnownHostsToHTTPS=true", "defaultWebpagePreferences.allowsContentJavaScript=false", - "preferences.minimumFontSize=10", "applicationNameForUserAgent=\"Saucer App\""}}}; +saucer::webview webview{{ + .application = app, + .browser_flags = {"upgradeKnownHostsToHTTPS=true", "defaultWebpagePreferences.allowsContentJavaScript=false", + "preferences.minimumFontSize=10", "applicationNameForUserAgent=\"Saucer App\""}, +}}; ``` diff --git a/package.json b/package.json index 26302d9..de3f8a9 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "saucer-docs", - "version": "3.0.0", + "version": "4.0.0", "private": true, "scripts": { "docusaurus": "docusaurus", diff --git a/src/css/custom.css b/src/css/custom.css index cf4fbc1..c07cb60 100644 --- a/src/css/custom.css +++ b/src/css/custom.css @@ -89,7 +89,7 @@ } nav .navbar__items:nth-child(1) a:nth-of-type(2)::after { - content: "v3.x"; + content: "v4.x"; padding-top: 0.2rem; padding-bottom: 0.2rem; diff --git a/src/pages/example.cpp b/src/pages/example.cpp index 8bcd5ed..e8ef504 100644 --- a/src/pages/example.cpp +++ b/src/pages/example.cpp @@ -2,7 +2,13 @@ int main() { - saucer::smartview webview; + auto app = saucer::application::acquire({ + .id = "example", + }); + + saucer::smartview webview{{ + .application = app, + }}; webview.set_size(900, 700); webview.set_title("Hello World!"); @@ -19,7 +25,7 @@ int main() webview.set_file("index.html"); webview.show(); - webview.run(); + app->run(); return 0; }