gtk4-rsのexampleを試す[Ubuntu 23.04 on Docker]

## この記事は

[gtk-rs/gtk4-rs](https://github.com/gtk-rs/gtk4-rs/tree/master/examples)のexamplesを１個ずつ試した際
**いくつかの例題がエラーで動かなかった**

この記事は、gtk-rsリポジトリの例題のうち、`dialog`例を動かすようにしたまでのメモ

## 【課題】 `cargo run --example dialog`が動かない

「`gtk::AlertDialog`が見つかりません」というエラーが出る

```rust:cargo run --example dialog
   Compiling hello-gtk v0.1.0 (/app/hello-gtk)
error[E0433]: failed to resolve: could not find `AlertDialog` in `gtk`
  --> examples/dialog/main.rs:48:32
   |
48 |     let question_dialog = gtk::AlertDialog::builder()
   |                                ^^^^^^^^^^^ could not find `AlertDialog` in `gtk`
   |
```

### `AlertDialog`が使えるのは`v4.10`から

[Struct gtk4::AlertDialog](https://gtk-rs.org/gtk4-rs/git/docs/gtk4/struct.AlertDialog.html)にそう書かれている

> Available on crate feature v4_10 only.

#### 寄り道～2023.08.07時点のGTK4バージョン

GTK`4.12`が最新

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/272511/5eaac51e-32c5-8dd9-20da-92890e7871e8.png)

https://gtk-rs.org/gtk4-rs/git/docs/gtk4/index.html#features-1

## LinuxマシンとGTK4バージョンはどうなっている？

エラーが出ているマシンの状態、および使用しているライブラリを調査する

### Linuxのバージョン

Ubuntu `22.04` です

```bash:cat /etc/issue
Ubuntu 22.04.3 LTS \n \l
```

### GTK4のバージョン

そのマシンで動いているGTK4のバージョンは`4.6.9`です

[GUI development with Rust and GTK 4 - Project Setup](https://gtk-rs.org/gtk4-rs/stable/latest/book/project_setup.html)

```bash:pkg-config --modversion gtk4
4.6.9
```

Dockerfileの`apt install libgtk-4-dev`でインストールしたバージョンは`4.6.9`

```bash:apt list --installed | grep libgtk-4-dev
libgtk-4-dev/jammy-updates,now 4.6.9+ds-0ubuntu0.22.04.1 amd64 [installed]
```

### ほかにインストールできるバージョンはあるか？

`4.6.9`しかない！ `4.10`がえらべない！

```bash:apt list libgtk-4-dev -a
Listing... Done
libgtk-4-dev/jammy-updates,now 4.6.9+ds-0ubuntu0.22.04.1 amd64 [installed]
libgtk-4-dev/jammy 4.6.2+ds-1ubuntu2 amd64
```

### Ubuntu packages

本家大本を見に行く
[libgtk-4-dev パッケージ](https://packages.ubuntu.com/search?keywords=libgtk-4-dev)によると、以下の対応とのこと

- ubuntu 22.04: `4.6.9`
- ubuntu 23.04: `4.10.1`

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/272511/76540dcf-8762-bbfd-95b4-5f47d2746c3d.png)

母艦のubuntuのバージョンを上げる必要がありそう（`22.04`はもう古いのか・・・）

## Dockerfileのベースイメージを変更する

Dockerfileの全容は付録に記載する

```docker
FROM ubuntu:23.04
```

Dockerfileを更新したら、`docker compose up -d --build`でビルドしなおす
ビルドがおわったら、`docker compose exec mylinux bash`でコンテナに入る

### GTK4バージョン確認

```bash:apt list --installed | grep libgtk-4-dev
libgtk-4-dev/lunar-updates,now 4.10.4+ds-0ubuntu1 amd64 [installed]
```

`4.10.4`までバージョンが上がった！

### 【課題再掲】 `cargo run --example dialog`を試す

依存関係に書いたGTKの`features = ["v4_6"]`を`features = ["v4_10"]`に修正する

```toml:Cargo.toml
[dependencies]
gtk = { version = "0.7.1", package = "gtk4", features = ["v4_10"] }
```

動いた！

![Animation2.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/272511/79b1201c-322d-491b-408e-bec403505c0c.gif)

## おわりに

## 糸冬了！！

## 付録

### Cargo.toml

- `pnet`など、不要なクレートも一部混じっている
- GTK4.10に上がったことで、不要になったクレートもあるかも

```
[dependencies]
gtk = { version = "0.7.1", package = "gtk4", features = ["v4_10"] }
default-net = "0.15"
pnet = "0.33.0"
log = "0.4.19"
env_logger = "0.10.0"
once_cell = "1.18.0"
glib = "0.18.1"
chrono = "0.4.26"
femtovg = "0.7.1"
glow = "0.12.3"
libloading = "0.8.0"
epoxy = "0.1.0"
image = "0.24.6"
glium = "0.32.1"
```

### Dockerfile

```dockerfile
FROM ubuntu:23.04

RUN apt update
RUN apt install -y \
    vim \
    curl \
    libgtk-4-dev \
    build-essential

# Rust install
ENV RUST_HOME /usr/local/lib/rust
ENV RUSTUP_HOME ${RUST_HOME}/rustup
ENV CARGO_HOME ${RUST_HOME}/cargo

RUN mkdir /usr/local/lib/rust && \
    chmod 0755 $RUST_HOME
RUN curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs > ${RUST_HOME}/rustup.sh \
    && chmod +x ${RUST_HOME}/rustup.sh \
    && ${RUST_HOME}/rustup.sh -y --default-toolchain nightly --no-modify-path
ENV PATH $PATH:$CARGO_HOME/bin

# Rust build
ENV CARGO_BUILD_TARGET_DIR=/tmp/target

RUN USER=root cargo new --bin app
WORKDIR /app
COPY ./hello-gtk/Cargo.toml Cargo.toml
COPY ./hello-gtk/Cargo.lock Cargo.lock
RUN cargo build && rm src/*.rs
```

### example実行用コード

```rust
cargo run --example basics
cargo run --example builder_pattern
cargo run --example clipboard
cargo run --example clock
cargo run --example column_view_datagrid
cargo run --example composite_template
cargo run --example confetti_snapshot_animation
cargo run --example content_provider
cargo run --example css
cargo run --example custom_application
cargo run --example custom_buildable
cargo run --example custom_editable
cargo run --example custom_layout_manager
cargo run --example custom_orientable
cargo run --example custom_paintable
cargo run --example custom_widget
cargo run --example dialog
cargo run --example entry_completion
cargo run --example entry_undo
cargo run --example expressions
cargo run --example femtovg_area
cargo run --example flow_box
cargo run --example gif_paintable
cargo run --example glium_gl_area
cargo run --example grid_packing
cargo run --example gtk_builder
cargo run --example list_box_model
cargo run --example list_view_apps_launcher
cargo run --example rotation_bin
cargo run --example scale_bin
cargo run --example search_bar
cargo run --example squares
cargo run --example squeezer_bin
cargo run --example text_viewer
cargo run --example video_player
cargo run --example virtual_methods
```