-
-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathplatform.go
More file actions
306 lines (256 loc) · 9.48 KB
/
Copy pathplatform.go
File metadata and controls
306 lines (256 loc) · 9.48 KB
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
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
// Copyright 2026 The gogpu Authors
// SPDX-License-Identifier: MIT
package gpucontext
// PlatformProvider provides OS integration features.
//
// This interface enables UI frameworks (like gogpu/ui) to access platform
// capabilities such as clipboard, cursor management, and system accessibility
// preferences.
//
// Implementations:
// - gogpu.App implements PlatformProvider via platform-specific code
// - NullPlatformProvider provides no-op defaults for testing
//
// PlatformProvider is optional. Not all WindowProviders support platform
// integration (e.g., headless or embedded systems).
// Use type assertion to check availability:
//
// if pp, ok := provider.(gpucontext.PlatformProvider); ok {
// pp.SetCursor(gpucontext.CursorPointer)
// }
//
// Note: This interface is designed for gogpu <-> ui integration.
// The rendering library (gg) does NOT use this interface.
type PlatformProvider interface {
// ClipboardRead reads text content from the system clipboard.
// Returns empty string and nil error if clipboard is empty or not text.
ClipboardRead() (string, error)
// ClipboardWrite writes text content to the system clipboard.
ClipboardWrite(text string) error
// SetCursor changes the mouse cursor shape.
// The cursor is typically reset to CursorDefault at the start of each frame.
SetCursor(cursor CursorShape)
// DarkMode returns true if the system dark mode is active.
// Used for automatic theme switching.
DarkMode() bool
// ReduceMotion returns true if the user prefers reduced animation.
// Used to disable or simplify animations for accessibility.
ReduceMotion() bool
// HighContrast returns true if the user needs high contrast mode.
// Used to adjust colors and borders for accessibility.
HighContrast() bool
// FontScale returns the user's font size preference multiplier.
// 1.0 = default system font size. Used to scale Sp (scale-independent pixels).
FontScale() float32
// SubpixelLayout returns the display's subpixel arrangement for LCD text rendering.
// Used by 2D graphics libraries (gg) to enable ClearType-quality font rendering.
// Returns SubpixelNone when subpixel info is unavailable or on HiDPI displays
// where subpixels are too small to be visible.
SubpixelLayout() SubpixelLayout
// FontSmoothing returns the OS text anti-aliasing mode.
// Used by text rendering pipelines to select between aliased, grayscale, and
// subpixel anti-aliasing. The result reflects the system-wide user preference
// (ClearType on Windows, font smoothing on macOS/Linux).
FontSmoothing() FontSmoothing
}
// SubpixelLayout describes the physical arrangement of RGB subpixels on a display.
// Used for LCD/ClearType font rendering to achieve sharper text by exploiting
// the subpixel structure. Qt6 (QPlatformScreen), Wayland (wl_output.geometry),
// and DRM/KMS (drmModeConnector) all expose this as a display property.
type SubpixelLayout int
const (
// SubpixelNone means no subpixel information is available or applicable.
// Text rendering falls back to grayscale anti-aliasing.
// Used on HiDPI displays where subpixels are too small to exploit.
SubpixelNone SubpixelLayout = iota
// SubpixelRGB is horizontal RGB ordering (most common: Windows LCD, most external monitors).
SubpixelRGB
// SubpixelBGR is horizontal BGR ordering (some Samsung and older displays).
SubpixelBGR
// SubpixelVRGB is vertical RGB ordering (rare, some rotated displays).
SubpixelVRGB
// SubpixelVBGR is vertical BGR ordering (rare).
SubpixelVBGR
)
// String returns the subpixel layout name for debugging.
func (s SubpixelLayout) String() string {
switch s {
case SubpixelNone:
return stringNone
case SubpixelRGB:
return "RGB"
case SubpixelBGR:
return "BGR"
case SubpixelVRGB:
return "VRGB"
case SubpixelVBGR:
return "VBGR"
default:
return "Unknown"
}
}
// FontSmoothing describes the OS text anti-aliasing mode.
// This is distinct from SubpixelLayout: FontSmoothing tells you HOW the text
// is anti-aliased (aliased / grayscale / subpixel), while SubpixelLayout tells
// you the physical subpixel arrangement (RGB / BGR / etc.) when subpixel AA
// is active.
//
// Detection sources by platform:
// - Windows: SPI_GETFONTSMOOTHING + SPI_GETFONTSMOOTHINGTYPE
// - macOS: always Grayscale (Mojave+ disabled subpixel AA system-wide)
// - Linux: Xft.antialias + Xft.rgba from RESOURCE_MANAGER / fontconfig
// - Browser: always Grayscale (browser controls text rendering)
type FontSmoothing int
const (
// FontSmoothingNone means smoothing is disabled — render aliased (bitmap-style) text.
FontSmoothingNone FontSmoothing = iota
// FontSmoothingGrayscale means grayscale anti-aliasing (no subpixel exploitation).
FontSmoothingGrayscale
// FontSmoothingSubpixel means LCD subpixel anti-aliasing (ClearType on Windows).
FontSmoothingSubpixel
)
// String returns the font smoothing mode name for debugging.
func (f FontSmoothing) String() string {
switch f {
case FontSmoothingNone:
return stringNone
case FontSmoothingGrayscale:
return "Grayscale"
case FontSmoothingSubpixel:
return "Subpixel"
default:
return "Unknown"
}
}
// CursorShape represents the mouse cursor shape.
//
// These values cover the most common cursor shapes across platforms
// (Windows, macOS, Linux). They map directly to platform-specific
// cursor constants.
//
// For applications that need cursor changes:
//
// if pp, ok := provider.(gpucontext.PlatformProvider); ok {
// pp.SetCursor(gpucontext.CursorText) // I-beam for text input
// }
type CursorShape int
const (
// CursorDefault is the standard arrow cursor.
CursorDefault CursorShape = iota
// CursorPointer is the hand cursor for clickable elements.
CursorPointer
// CursorText is the I-beam cursor for text input areas.
CursorText
// CursorCrosshair is the crosshair cursor for precise selection.
CursorCrosshair
// CursorMove is the four-arrow cursor for movable elements.
CursorMove
// CursorResizeNS is the north-south resize cursor.
CursorResizeNS
// CursorResizeEW is the east-west resize cursor.
CursorResizeEW
// CursorResizeNWSE is the NW-SE diagonal resize cursor.
CursorResizeNWSE
// CursorResizeNESW is the NE-SW diagonal resize cursor.
CursorResizeNESW
// CursorNotAllowed is the circle-with-line cursor for forbidden actions.
CursorNotAllowed
// CursorWait is the busy/wait cursor.
CursorWait
// CursorNone hides the cursor.
CursorNone
)
// String returns the cursor shape name for debugging.
func (c CursorShape) String() string {
switch c {
case CursorDefault:
return "Default"
case CursorPointer:
return "Pointer"
case CursorText:
return "Text"
case CursorCrosshair:
return "Crosshair"
case CursorMove:
return "Move"
case CursorResizeNS:
return "ResizeNS"
case CursorResizeEW:
return "ResizeEW"
case CursorResizeNWSE:
return "ResizeNWSE"
case CursorResizeNESW:
return "ResizeNESW"
case CursorNotAllowed:
return "NotAllowed"
case CursorWait:
return "Wait"
case CursorNone:
return stringNone
default:
return "Unknown"
}
}
// CursorMode controls how the mouse cursor behaves within the window.
//
// This follows the pattern established by SDL_SetRelativeMouseMode and
// SDL_SetWindowMouseGrab, providing three modes that cover the common
// use cases for games and interactive applications.
type CursorMode int
const (
// CursorModeNormal is the default mode: cursor is visible and moves freely.
CursorModeNormal CursorMode = iota
// CursorModeLocked hides the cursor and confines it to the window.
// Mouse movement is reported as relative deltas (DeltaX/DeltaY on PointerEvent).
// The cursor is warped to the window center on each frame.
// Equivalent to SDL_SetRelativeMouseMode(SDL_TRUE).
CursorModeLocked
// CursorModeConfined keeps the cursor visible but confines it to the window bounds.
// Equivalent to SDL_SetWindowMouseGrab(SDL_TRUE).
CursorModeConfined
)
// String returns the cursor mode name for debugging.
func (m CursorMode) String() string {
switch m {
case CursorModeNormal:
return "Normal"
case CursorModeLocked:
return "Locked"
case CursorModeConfined:
return "Confined"
default:
return "Unknown"
}
}
// NullPlatformProvider implements PlatformProvider with no-op behavior.
// Used for testing and platforms without OS integration.
//
// Default return values:
// - ClipboardRead: "", nil
// - ClipboardWrite: nil
// - SetCursor: no-op
// - DarkMode: false
// - ReduceMotion: false
// - HighContrast: false
// - FontScale: 1.0
type NullPlatformProvider struct{}
// ClipboardRead returns empty string and nil error.
func (NullPlatformProvider) ClipboardRead() (string, error) { return "", nil }
// ClipboardWrite does nothing and returns nil.
func (NullPlatformProvider) ClipboardWrite(string) error { return nil }
// SetCursor does nothing.
func (NullPlatformProvider) SetCursor(CursorShape) {}
// DarkMode returns false.
func (NullPlatformProvider) DarkMode() bool { return false }
// ReduceMotion returns false.
func (NullPlatformProvider) ReduceMotion() bool { return false }
// HighContrast returns false.
func (NullPlatformProvider) HighContrast() bool { return false }
// FontScale returns 1.0.
func (NullPlatformProvider) FontScale() float32 { return 1.0 }
// SubpixelLayout returns SubpixelNone (grayscale AA).
func (NullPlatformProvider) SubpixelLayout() SubpixelLayout { return SubpixelNone }
// FontSmoothing returns FontSmoothingGrayscale (safe default).
func (NullPlatformProvider) FontSmoothing() FontSmoothing { return FontSmoothingGrayscale }
// Ensure NullPlatformProvider implements PlatformProvider.
var _ PlatformProvider = NullPlatformProvider{}