|
| 1 | +# GtkBackend |
| 2 | + |
| 3 | +SwiftCrossUI's native Linux backend built on Gtk 4. |
| 4 | + |
| 5 | +## Overview |
| 6 | + |
| 7 | +While Gtk isn't the preferred UI framework on every Linux distro, it's the closest thing SwiftCrossUI has to a native Linux backend for now. The Qt backend may be brought back to life at some point to cover the rest of Linux distros. |
| 8 | + |
| 9 | +For targetting older pre Gtk 4 Linux distros, see the secondary <doc:Gtk3Backend> |
| 10 | + |
| 11 | +This backend supports Linux, macOS, and Windows, but its support for macOS has a few known issues worse due to underlying Gtk issues (and its support for Windows isn't well tested). |
| 12 | + |
| 13 | +## System dependencies |
| 14 | + |
| 15 | +Before you can use `GtkBackend` you must install the required system dependencies for your platform. Here are installation instructions tailored to each supported platform; |
| 16 | + |
| 17 | +### Linux |
| 18 | + |
| 19 | +```sh |
| 20 | +# Debian-based distros |
| 21 | +sudo apt install libgtk-4-dev clang |
| 22 | + |
| 23 | +# Fedora-based distros |
| 24 | +sudo dnf install gtk4-devel clang |
| 25 | +``` |
| 26 | +Figure 1: *installing the required dependencies on Debian-based and Fedora-based Linux distros* |
| 27 | + |
| 28 | +If you run into errors related to not finding `gtk/gtk.h` when trying to build a swift-cross-ui project, try restarting your computer. This has worked in some cases (although there may be a more elegant solution). |
| 29 | + |
| 30 | +If you are on a non-Debian non-Fedora distro and the `GtkBackend` requirements end up differing significantly from the requirements stated above, please open a GitHub issue or PR so that we can improve the documentation. |
| 31 | + |
| 32 | +### macOS |
| 33 | + |
| 34 | +```sh |
| 35 | +brew install pkg-config gtk4 |
| 36 | +``` |
| 37 | +Figure 2: *installing the required dependencies using Homebrew* |
| 38 | + |
| 39 | +If you don't have Homebrew, installation instructions can be found at [brew.sh](https://brew.sh). |
| 40 | + |
| 41 | +It should also be possible to use `gtk4` installed via MacPorts, but I have not tested that. |
| 42 | + |
| 43 | +If you run into errors related to `libffi` or `FFI` when trying to build a swift-cross-ui project with `GtkBackend`, which can occur when certain older versions of the Xcode Command Line Tools are installed, try running the following command to patch libffi: |
| 44 | + |
| 45 | +```sh |
| 46 | +sed -i '' 's/-I..includedir.//g' $(brew --prefix)/Library/Homebrew/os/mac/pkgconfig/*/libffi.pc |
| 47 | +``` |
| 48 | +Figure 3: *fixing the `libffi` issue that some people face* |
| 49 | + |
| 50 | +### Windows |
| 51 | + |
| 52 | +On Windows things are a bit complicated (as usual), so we only support installation via [vcpkg](https://github.com/microsoft/vcpkg). First, install vcpkg; |
| 53 | + |
| 54 | +```sh |
| 55 | +git clone https://github.com/microsoft/vcpkg C:\vcpkg |
| 56 | +C:\vcpkg\bootstrap-vcpkg.bat |
| 57 | +``` |
| 58 | +Figure 4: *install vcpkg (requires git cli)* |
| 59 | + |
| 60 | +> Warning: It's important to install vcpkg at the root of a drive due to limitations of the Gtk build system. |
| 61 | +
|
| 62 | +**After installation, make the following changes to your environment variables:** |
| 63 | + |
| 64 | +1. Set the `PKG_CONFIG_PATH` environment variable to `C:\vcpkg\installed\x64-windows\lib\pkgconfig`. This is only required for building. |
| 65 | +2. Add `C:\vcpkg\installed\x64-windows\bin` to your `Path` environment variable. This is only required for running. |
| 66 | + |
| 67 | +With vcpkg installed, you have two options for Gtk installation; global installation, and project-local installation |
| 68 | + |
| 69 | +#### Global Gtk 4 installation (recommended) |
| 70 | + |
| 71 | +Note that the command depends on your machine's architecture; choose between Figure 5 and Figure 6 accordingly. |
| 72 | + |
| 73 | +Installation can take 45+ minutes depending on your machine. |
| 74 | + |
| 75 | +```sh |
| 76 | +C:\vcpkg\vcpkg.exe install gtk --triplet x64-windows |
| 77 | +``` |
| 78 | +Figure 5: *install Gtk 4 globally on x64 Windows* |
| 79 | + |
| 80 | +```sh |
| 81 | +C:\vcpkg\vcpkg.exe install gtk --triplet arm64-windows |
| 82 | +``` |
| 83 | +Figure 6: *install Gtk 4 globally on arm64 Windows* |
| 84 | + |
| 85 | +> Warning: Run the chosen command at the root of your drive to ensure that vcpkg doesn't run in manifest mode. |
| 86 | +
|
| 87 | +#### Project-local Gtk 4 installation (more unreliable) |
| 88 | + |
| 89 | +> Note: If the absolute path to your project contains spaces, it is possible that vcpkg will break, and installing globally will be a more reliable strategy. |
| 90 | +
|
| 91 | +To install Gtk 4 in a project-local dependency store you must setup a `vcpkg.json` manifest file and then run vcpkg, as detailed below; |
| 92 | + |
| 93 | +First `vcpkg.json` at the root of your project and make sure that it includes the `gtk` dependency as demonstrated in Figure 7. |
| 94 | + |
| 95 | +```json |
| 96 | +{ |
| 97 | + "name": "project-name", |
| 98 | + "version-string": "main", |
| 99 | + "dependencies": ["gtk"] |
| 100 | +} |
| 101 | +``` |
| 102 | +Figure 7: *an example `vcpkg.json` package manifest* |
| 103 | + |
| 104 | +```sh |
| 105 | +C:\vcpkg\vcpkg.exe install --triplet x64-windows |
| 106 | +``` |
| 107 | +Figure 8: *install the dependencies listed in your package manifest* |
| 108 | + |
| 109 | +> Warning: Replace the triplet with `arm64-windows` if you're on ARM64 |
| 110 | +
|
| 111 | +## Usage |
| 112 | + |
| 113 | +```swift |
| 114 | +... |
| 115 | + |
| 116 | +let package = Package( |
| 117 | + ... |
| 118 | + targets: [ |
| 119 | + ... |
| 120 | + .executableTarget( |
| 121 | + name: "YourApp", |
| 122 | + dependencies: [ |
| 123 | + .product(name: "SwiftCrossUI", package: "swift-cross-ui"), |
| 124 | + .product(name: "GtkBackend", package: "swift-cross-ui"), |
| 125 | + ] |
| 126 | + ) |
| 127 | + ... |
| 128 | + ] |
| 129 | + ... |
| 130 | +) |
| 131 | +``` |
| 132 | +Figure 9: *adding `GtkBackend` to an executable target* |
| 133 | + |
| 134 | +```swift |
| 135 | +import SwiftCrossUI |
| 136 | +import GtkBackend |
| 137 | + |
| 138 | +@main |
| 139 | +struct YourApp: App { |
| 140 | + // You can explicitly initialize your app's chosen backend if you desire. |
| 141 | + // This happens automatically when you import any of the built-in backends. |
| 142 | + // |
| 143 | + // var backend = GtkBackend() |
| 144 | + // |
| 145 | + // If you aren't using Swift Bundler, you may have to explicitly provide |
| 146 | + // your app's identifier for some GtkBackend features to work correctly |
| 147 | + // (such as handling custom URL schemes). |
| 148 | + // |
| 149 | + // var backend = GtkBackend(appIdentifier: "com.example.YourApp") |
| 150 | + |
| 151 | + var body: some Scene { |
| 152 | + WindowGroup { |
| 153 | + Text("Hello, World!") |
| 154 | + .padding() |
| 155 | + } |
| 156 | + } |
| 157 | +} |
| 158 | +``` |
| 159 | +Figure 10: *using `GtkBackend`* |
0 commit comments