Skip to main content

Modules

Modules are an extension to smartviews that can access the native window and webview data used by saucer.
Thus they're a really powerful tool that can be used to implement completely new features or to alter the current behavior of saucer.

Native Header

tip

If you're using CMake, make sure you have module support enabled!
This can be achieved by setting saucer_modules to ON.
In case you're not using CMake, please refer to your package distributor on how to enable modules.

First, grab the respective native header for your platform.

#include <saucer/modules/native/webkitgtk.hpp>
// or
#include <saucer/modules/native/qt.hpp>

Setup Module

Now I'll setup a basic module by making a class that fullfulls the saucer::Module concept.

Example: Basic Module
class awesome_module
{
saucer::natives m_natives;
saucer::smartview_core *m_smartview;

public:
awesome_module(saucer::smartview_core *smartview, saucer::natives natives)
: m_natives(natives), m_smartview(smartview)
{
}

void my_awesome_feature()
{
auto [window, webview] = m_natives;

window->window->setWindowTitle("Hello from Module!");
webview->web_view->page()->setAudioMuted(true);
}
};

static_assert(saucer::Module<awesome_module>);
tip

You can use the compile time macros SAUCER_QT5, SAUCER_QT6, SAUCER_WEBKITGTK, SAUCER_WEBVIEW2 and SAUCER_WEBKIT to find out which backend is currently used.

Use Module

To use the module, extend your smartview declaration as shown in the following snippet.

int main()
{
auto app = saucer::application::acquire({
.id = "modules",
});

saucer::smartview<saucer::default_serializer, awesome_module> webview{{
.application = app,
}};

webview.set_url("https://github.com/saucer/saucer");
webview.set_dev_tools(true);

webview.module<awesome_module>().my_awesome_feature();

webview.show();
app->run();

return 0;
}

Use with Serializer

You might've noticed that our module constructor receives a smartview_core.

This is a stripped down version of the smartview you're used to and does not include all the advantages of being coupled with a serializer (namely, it does not allow seamless interoperability).

However, we can modify our module code slightly to also use the fully featured smartview.

Example: Module with smartview
class awesome_module
{
saucer::natives m_natives;
saucer::smartview_core *m_smartview;

public:
awesome_module(saucer::smartview_core *smartview, saucer::natives natives)
: m_natives(natives), m_smartview(smartview)
{
}

template <typename Serializer, typename... Modules>
awesome_module(saucer::smartview<Serializer, Modules...> *smartview, saucer::natives natives)
: m_natives(natives), m_smartview(smartview)
{
smartview->expose("module_add", [](int a, int b) { return a + b; });
}

void my_awesome_feature()
{
auto [window, webview] = m_natives;

window->window->setWindowTitle("Hello from Module!");
webview->web_view->page()->setAudioMuted(true);
}
};

static_assert(saucer::Module<awesome_module>);