Aller au contenu
Fenêtre native

Une fenêtre native

go-widgets/window : une seule API Open/Run sur X11, Wayland, GTK4, Cocoa, Win32, Android, wasmbox et un onglet de navigateur, toutes avec CGO_ENABLED=0.

go-widgets/window ouvre une vraie fenêtre et y fait tourner un arbre de widgets : mise en page, dessin, présentation, traduction des entrées en toolkit.Event, et ainsi de suite jusqu’à la fermeture de la fenêtre.

w, err := window.Open(window.Config{Title: "Demo"})
if err != nil {
	return err
}
defer w.Close()
return w.Run(root) // root is any toolkit.Widget

Config prend aussi la taille initiale en points logiques (zéro demande une taille lisible par défaut), l’instance et la classe WM_CLASS, un Theme, et un RenderScale.

Comment Open choisit

Plateforme et environnementBack-endComment il atteint l’écran
Linux, $GO_WIDGETS_GTK définiGTK4GTK possède la fenêtre ; le framebuffer est une GtkPicture, et les contrôles natifs sont de vrais widgets GTK posés au-dessus. Exige le runtime libgtk-4.
Linux, $WAYLAND_DISPLAY définiWaylandxdg-shell sur le socket unix du compositeur
Linux, sinon $DISPLAYX11le protocole X11 de base sur le socket unix, avec MIT-SHM
macOSCocoaNSWindow et NSView via go-macos/objc (purego)
WindowsWin32un HWND de premier niveau via des appels système à user32 et gdi32, StretchDIBits
Android, $GW_ANDROID_SOCKET définihôte Androidun protocole tramé vers l’hôte Java, les pixels dans un memfd partagé
Android, sinonWayland ou X11un shell sous Termux a toujours un serveur d’affichage à contacter
js/wasm, dans wasmdeskwasmboxun client du compositeur wasmdesk
js/wasm, une page ordinaireonglet de navigateurun <canvas> de la page (Config.Canvas, par défaut "screen") via webcanvas : pas de compositeur, pas de SharedArrayBuffer, pas d’isolation cross-origin
tout le reste—window.ErrUnsupported, pour qu’une compilation croisée compile quand même

Chaque back-end est CGO_ENABLED=0. Celui de X11 est le protocole de base écrit de zéro sur le socket — pas de Xlib, pas de XCB — avec les deux ordres d’octets, le cookie Xauthority, la correspondance des keysyms, PutImage découpé en tuiles sous la taille de requête du serveur, et la voie rapide MIT-SHM, le segment partagé étant transmis par SCM_RIGHTS. Windows est atteint par les DLL du processus lui-même avec syscall.NewLazyDLL et une procédure de fenêtre syscall.NewCallback ; macOS par le runtime Objective-C avec purego.

La partie indépendante de la plateforme de chaque back-end — correspondance des événements, calculs de coordonnées, empaquetage des pixels, rectangles endommagés — vit dans un codec couvert à 100 %, sur chaque système d’exploitation. La fine couche de liaison avec la plateforme est éprouvée en conditions réelles : voir État.

Seulement ce qui a changé

Une racine qui implémente DamageRenderer (comme le fait toolkit/scene.HostRoot) signale les rectangles qu’elle a repeints, et chaque back-end sauf GTK4 ne présente que ceux-là : X11 via ShmPutImage de MIT-SHM, Wayland via les zones endommagées de wl_shm, Cocoa, Win32, Android, wasmbox et l’onglet de navigateur. La première image, un redimensionnement et un Expose X11 présentent encore toute la surface.

HiDPI

Par défaut, un pixel du framebuffer correspond à un point logique : l’interface est mise en page et peinte à une taille lisible, et le compositeur la suréchantillonne. Sous Windows, la fenêtre déclare une prise en charge du DPI par moniteur et le système met à l’échelle l’image logique vers la zone client physique. RenderScale demande un framebuffer à la résolution réelle de l’écran, ce qui n’est correct que pour une racine qui se met en page en pixels de l’appareil.

Écrans, affichage et masquage

window.Screens() liste les écrans connectés, le principal en premier, en points logiques, panneaux du bureau exclus, et peut être appelé avant Open. Le nom d’un écran est celui de la dalle elle-même ("DELL U2720Q", d’après son EDID), avec repli sur le connecteur ("HDMI-1") quand elle n’en publie aucun — et aussi quand deux dalles connectées publient le même, car un nom qui ne permet pas de les distinguer n’est pas un nom.

window.Show, Hide et Raise retirent de l’écran une fenêtre ouverte sans la fermer, puis la ramènent — ce dont a besoin une application de zone de notification.

Back-endShowHideRaise
X11MapWindowretrait ICCCM, pour qu’elle quitte la barre des tâchesmap, raise, _NET_ACTIVE_WINDOW
Waylandnouveau committampon nul et commitErrNotSupported : xdg-shell n’a pas de telle requête
macOSorderFront:orderOut:activer l’application, makeKeyAndOrderFront:
WindowsSW_SHOWNASW_HIDESW_RESTORE et SetForegroundWindow
GTK, Android, wasmbox, onglet de navigateurErrNotSupportedErrNotSupportedErrNotSupported

Le focus, c’est à la plateforme de l’accorder : avec la prévention du vol de focus, Raise peut seulement marquer la fenêtre comme demandant l’attention, sans pouvoir le savoir.

Créée le par tannevaled

Modifiée le par tannevaled