Make sure you have Gtk4 installed:
- On MacOS, do
brew install gtk4 - On Debian-based Linux systems, you can do
sudo apt install libgtk-4-dev
You can check the installation by running pkg-config --cflags gtk4 - it should succeed.
The bindings are published to Maven central, with gtk4 specifically being available at the following coordinates:
com.indoorvivants.gnome::gtk4::<version> // Scala CLI/Mill format
"com.indoorvivants.gnome" %%% "gtk4" % "<version>" // SBT format
This repository contains a very small app you can run.
$ pkg-config --cflags gtk4 | xargs -n1 > compilationFlags
$ pkg-config --libs gtk4 | xargs -n1 > linkingFlags
$ scala-cli run ./examples/src/main/scala/example.scala --native --native-compile @$PWD/compilationFlags --native-linking @$PWD/linkingFlags --dep com.indoorvivants.gnome::gtk4::0.0.4 # or change the version to latestBindings generated using sn-bindgen
GIO Resource enables bundling resources, text or binary,
within the executable. The overall process for integration with scala-native-gtk-bindings is:
- Create a
gresource.xmlfile. EG:main.gresource.xmlwithin themain/resourcesfolder. - Place other resources (UI definitions, CSS, Icons) included by the
gresource.xmlin themain/resourcesfolder. - Using
glib-compile-resourcesto generate.cfile for the resources into the generatedmanaged_resources/scala-nativefolder. - This
.cfile will be automatically compiled as part of the scala native build. - The application is now ready to access resources using
g_resource_lookup_dataand related APIs.
Aside from the glib-compile-sources, the process is automatic: The generated C will be automatically
included in the compile and the resource registration functions in the generated C will be automatically
called.
Here is an example, using the sbt build tool, of the build process and loading a resource.
In this example file will be called main.gresource.xml:
<?xml version="1.0" encoding="UTF-8"?>
<gresources>
<gresource prefix="/com/example/my-scala-native-exe">
<file>data.txt</file>
</gresource>
</gresources>With the data.txt placed alongside the main.gresource.xml. For example:
Example text for the data.txt resource.
For the project with the resources, add a task like:
Compile / resourceGenerators += Def.task {
val inputDir = (Compile / resourceDirectory).value
val input = inputDir / "main.gresource.xml"
val file = (Compile / resourceManaged).value / "scala-native" / "gresources.c"
IO.createDirectory(file.getParentFile())
val processResult = Process(
Seq(
"glib-compile-resources",
"--generate-source",
"--target",
file.toString(),
input.toString()
),
inputDir
) ! streams.value.log
assert(processResult == 0)
Seq(file)
}.taskValueThis does the following: Creates the generated source target directory; Generates the source; Propagates any errors as failures.
At this point the required steps are done! The resources are compiled into the application and are available for access. EG:
val myData =
g_resources_lookup_data(
c"/com/example/my-scala-native-exe/data.txt",
GResourceLookupFlags.G_RESOURCE_LOOKUP_FLAGS_NONE,
null
)
val myDataContents: Ptr[Byte] = g_bytes_get_data(myData, null)The bytes from g_byte_get_data are always null terminated. In this case, myDataContents is a valid
CString.
