Skip to main content

tauri_runtime/
gtk.rs

1// Copyright 2019-2024 Tauri Programme within The Commons Conservancy
2// SPDX-License-Identifier: Apache-2.0
3// SPDX-License-Identifier: MIT
4
5//! The GTK version a runtime binds to on Linux and BSD.
6//!
7//! `tauri` binds one GTK version at compile time (its `gtk3`/`gtk4` features) while the runtime is
8//! picked at run time, and the pointers crossing [`WindowDispatch::gtk_window`] and friends carry
9//! no version information. A runtime declares the version its objects belong to with
10//! [`declare_version`] so `tauri` can refuse to wrap them with mismatched bindings instead of
11//! reinterpreting a GTK 3 object as a GTK 4 one.
12//!
13//! Note that GTK 3 and GTK 4 cannot be initialized in the same process - GTK 4 aborts when it
14//! detects GTK 2/3 symbols - so a single binary can only ever run one of them.
15//!
16//! [`WindowDispatch::gtk_window`]: crate::WindowDispatch::gtk_window
17
18use std::sync::atomic::{AtomicU8, Ordering};
19
20/// GTK major version.
21#[derive(Debug, Clone, Copy, PartialEq, Eq)]
22pub enum Version {
23  /// GTK 3.
24  V3 = 3,
25  /// GTK 4.
26  V4 = 4,
27}
28
29impl std::fmt::Display for Version {
30  fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
31    match self {
32      Self::V3 => write!(f, "GTK 3"),
33      Self::V4 => write!(f, "GTK 4"),
34    }
35  }
36}
37
38static ACTIVE_VERSION: AtomicU8 = AtomicU8::new(0);
39
40/// Declares the GTK version this runtime's GTK object pointers belong to.
41///
42/// Runtimes must call this before creating any window. The last call wins; since GTK 3 and GTK 4
43/// cannot share a process, a binary that declares both is already unable to run.
44pub fn declare_version(version: Version) {
45  ACTIVE_VERSION.store(version as u8, Ordering::Relaxed);
46}
47
48/// The GTK version declared by the active runtime, or [`None`] if no runtime declared one.
49pub fn active_version() -> Option<Version> {
50  match ACTIVE_VERSION.load(Ordering::Relaxed) {
51    3 => Some(Version::V3),
52    4 => Some(Version::V4),
53    _ => None,
54  }
55}