1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
// SPDX-License-Identifier: MPL-2.0
// SPDX-FileCopyrightText: 2026 FernTech
//! Opaque platform window/display handle wrapper.
//!
//! `ParentHandle` carries a `(RawWindowHandle, RawDisplayHandle)` pair
//! extracted from a winit window on the main thread. Native dialog
//! libraries (e.g. `rfd::AsyncFileDialog::set_parent`) consume the pair
//! to parent their OS-level UI to the Teksilo window.
//!
//! Lives in `teksilo-core` rather than `teksilo-platform` so the
//! [`WindowOps`](crate::window::WindowOps) trait, which is in core, can
//! mention it without inverting the dependency graph
//! (`core → platform` would be a layering violation; `platform → core`
//! is the established direction).
//!
//! # Thread safety
//!
//! `RawWindowHandle` and `RawDisplayHandle` are enums that include
//! raw pointers (`*mut c_void` in the AppKit/Win32/Wayland variants).
//! Rust marks raw pointers `!Send + !Sync` by default, so the enums
//! inherit that. We need this struct to cross thread boundaries
//! (main → async-std worker driving an `rfd::AsyncFileDialog` future),
//! so we add `unsafe Send + Sync` impls below.
//!
//! Safety contract: the bytes of the handle are moved between threads,
//! but every platform-specific dereference of the inner pointer
//! happens inside backend glue that arranges the correct thread
//! affinity per OS — `dispatch::Queue::main` on macOS, the D-Bus
//! thread on Linux portal, the COM apartment on Windows. Callers
//! must NOT dereference the inner handle off the main thread by hand.
use ;
/// Opaque pair of platform handles describing a parent window for a
/// native OS dialog. Construct with [`ParentHandle::from_window`] on
/// the main thread.
///
/// Implements [`HasWindowHandle`] and [`HasDisplayHandle`] so backend
/// code can hand it directly to APIs like `rfd::AsyncFileDialog::set_parent`
/// without an intermediate adapter type.
// SAFETY: We only move handle bytes between threads. Every
// platform-specific dereference of the inner pointer happens inside
// backend glue that arranges the correct thread affinity per OS.
// raw-window-handle's own design allows storage of the raw enums
// across threads — only the borrowed `WindowHandle<'_>` /
// `DisplayHandle<'_>` types are `!Send` because of their lifetimes.
unsafe
unsafe