The streaming form of write_file: the bytes go into a sibling of the target, commit puts
it in place in one step (readers see the old file or all of the new one); dropped without
commit, the sibling is removed and the target is unchanged. Checked and routed like
write_file when it is created. OS paths: an exclusive “NAME.tmp-PID-SEQ-TIME” beside the
file, fsync and rename (Linux keeps the old file’s access bits; the browser: in memory until
commit). Mounts: a “NAME.tmp-..” file of the mount, renamed by the provider (one without
rename gets the whole file written); a provider whose rename cannot replace a file
(atomic_rename() == false, content://) gets the bytes written in place at commit.
Nonblocking exclusive sidecar lock; drop releases it. All cooperating writers must lock
the same path before checking and replacing data. OS files: across processes (Windows: an
exclusive handle, Linux: flock); a mount without OS files: inside this process.
the library’s version, “MAJOR.MINOR.PATCH” (the root Cargo.toml; docs/VERSIONING.md says what a
change of each part promises). Not the app’s version: that is rt::app_version!().
the window is drawn inside its owner (a Wayland subsurface): win_get_rect / win_set_rect /
E_WINPOS use positions relative to the owner’s surface origin (px), the owner carries it
with WST_TILED: which edges touch the tiling (EDGE_* << WST_TILED_SHIFT; Wayland’s
xdg_toplevel tiled_* states, X11 the edges of a one-direction maximize); the UI keeps its
resize band off them, as from a maximized window
Android: the runtime ended (ui.quit): the activity goes and its process with it, a new start
needs a new runtime. Elsewhere nothing: there the main loop ends the program
Android: while on, the back key reaches the app as Esc (a page of the app goes back, a popup
closes; UIC_ESCAPE when nothing took it) instead of ending the activity. Elsewhere nothing:
there Esc is a key of its own
Validate a multi-format text clipboard before replacing the previous contents.
Formats must be distinct TEXT/HTML/RTF/DOCX; text and HTML are NUL-free UTF-8.
(plat-win) crash_test called from a known place (call rel32): the return address
crash_test_caller + 5 must be among CrashInfo::frames (plattest’s call chain check)
the effect of a drop: the modifier keys choose (Ctrl copy, Shift move, Ctrl+Shift link),
else the first of copy / move / link that allowed has (0: none)
(OS layers) what platform window pw takes at (x, y) px of a drag offering types with the
effects allowed (0 = copy | move) -> (accepted types, the effect); (0, 0) = refused
drag data out of the app (call while the left button is held) -> started; E_DRAG_END
(data = the effect, 0 = cancelled or refused) follows. Only the standard kinds leave
the app.
(OS layers) the lines of a URL list (text/uri-list, text/x-moz-url, UniformResourceLocator):
‘#’ lines skipped, every other line one URL; local files are left to drop_uri_list -> URLs
added (also used for the URL a browser drags)
The answer of a system file dialog that answers later (file_dialog -> FD_PENDING: only
Android’s picker and the browser’s; web.rs): None while it is open, then once (1 chosen /
0 not, index, path).
A host’s raw finger, in px of its window (Event::win as for every pointer event): this is all a
platform does for touch; pan, fling, tap, long press and what takes the finger are decided in
ui/touch.rs. Every finger goes through here, in the order they happen; a finger that goes away
without an Up gets a Cancel. The browser and Android, whose windows live in one surface, come
through jfgui_finger instead. -> false when the event was dropped
the Event of a raw finger: E_DOWN / E_MOVE / E_UP with PTR_TOUCH in its data. id: the host’s
number of this finger while it is down (a second one has another); age_ms: how old the sample
is now (the velocity needs it; 0 when the host does not know)
the calling thread’s FS base, pthread_self() and the address of errno: its thread control block
and thread-local storage (a raw clone would have 0 and the creator’s)
(bench: jfgui_WL_FEEDBACK=1 on Wayland) the commits since the last call and when each reached the
screen (wp_presentation): (time of the commit, time on the screen; 0: discarded), time_us
run the Rust closure f under the crash guard -> Ok(result), Err(ERR_FAULT) when it faulted
(info filled), Err(ERR_LIMIT) when the thread table is full (f did not run). A fault
abandons f’s frames without running destructors (what they own leaks): meant for host
code that may touch plugin memory (the loader fuzz runs lib_open / lib_sym under it).
Committed text of any length: commits of at most 4096 bytes, split between characters ->
the bytes queued (fewer: the commit queue or the event ring is full, the rest can follow
once the app took these).
a POSIX locale name or a BCP 47 tag as a BCP 47 tag: language lower case, a script title
case, a region upper case (“zh_hant_tw” -> “zh-Hant-TW”); None for “C” / “POSIX” / empty
one image on one PDF 1.4 page: objects 1 Catalog, 2 Pages, 3 Page, 4 Contents, 5 Image
(/DeviceRGB 8 bit /FlateDecode, composited over white – with PJF_SMASK and a straight
source: straight colours), 6 Info, [7 /SMask alpha]; classic xref pdf_write_image
The name under which a file the user chose stays reachable after a restart, for a list of
recent files or a session (ui.recent_add keeps this one). A document of Flatpak’s
documents portal ($XDG_RUNTIME_DIR/doc/ID/NAME) is asked for its lasting form
(Documents.Add, persistent; linux_docs.rs): <mount>/<ID>/<NAME> of the portal’s answer.
Where the portal reaches the real file that is a lasting document of it; for a document
of its own mount the portal answers that document’s own ID, so inside the sandbox the name
stays as the dialog gave it (the portal’s file dialog makes lasting documents, “Open with”
session ones). Every other name comes back unchanged: Android keeps the grant of a
content:// document and the browser the handle of a /handles/ file when the user
chooses it, and OS paths need nothing. The name must be readable under the app’s
permissions.
(§6) how the next popup() of slot slot hangs at its anchor: anchor x, y, w, h and the
popup’s natural place x, y (owner px), PA_* kind. Wayland builds the xdg_positioner from
it (the compositor flips / slides the popup to keep it on screen); X11 places it as asked.
(§6) where the platform put popup slot slot (owner px) when that is not its natural place
(Wayland: the compositor’s configure); None: where the UI asked, or not known yet
show dirty rectangles (None = everything) of the main window’s framebuffer; its pixels
outside them must be what the last present showed (the backends keep whole frames up to
date from it)
(frames handed to win_present, microseconds spent in the platform’s present paths) since
the start, all windows together: win_present itself plus the work it defers (X11: a
segment that frees up, Wayland: the frame callback, the browser and Android: the
composition and the hand-over to the host). For measurements (linuxtest –test pbench).
where a window the user moves may be (x, y; w its width; screen the area’s size; dpi for the
margin): the title bar stays on the screen, at least 48 DIP of the window at each side
like spawn_self, but the program file now at this process’s path: after an update put a
new file there, /proc/self/exe still names the old one (“PATH (deleted)”) -> 0 / -1
n pixels of src (B, G, R, A) -> n * 3 bytes of dst (R, G, B; PRW_BGR: B, G, R). Straight:
c * a / 255 + 255 - a (rounded); PRW_PREMUL: c + 255 - a; PRW_COPY / PRW_OPAQUE: c
[print_row_white]
fork; the child execs /proc/self/exe with argv[0], the arguments (at most 31) and the
current environment (exit 127 when that fails) -> 0 / -1 [plat_spawn_self]
the stack pointer is 16-byte aligned where a call could happen (the compiler relies on
it: a thread started with a misaligned stack shows here) [plattest th_raw]
(feature std) the start of a program with std, from its fn main (rt::main!, ui::main! or the
program’s own): std’s arguments and environment as a block like the initial stack, then what
glibc_main does, with rt’s panic hook first; the end through std::process::exit
0 light, 1 dark, -1 unknown: jfgui_THEME=light|dark wins, then GTK_THEME “Name:dark” or
“Name-dark”, then the settings portal’s answer at the last sys_settings (color-scheme;
GNOME’s “Default” is light; unknown before the first, e.g. in headless runs)
[plat_theme]
a title bar action as GNOME names it (GDesktopTitlebarAction): toggle-maximize (also
-horizontally / -vertically, which xdg-shell can not do: GTK treats them alike), minimize,
lower, menu, none; toggle-shade is none (no compositor shades client-side windows)
a button layout in GNOME’s button-layout syntax (GTK’s gtk-decoration-layout): the left
side, ‘:’, the right side, names separated by ‘,’. close, minimize and maximize are kept,
other names (appmenu, icon, menu, spacer) and repeats skipped; without ‘:’ everything is
the left side (as GTK reads it)
(ui touch.rs) a text field got the focus through a finger (show) or lost it: the on-screen keyboard
of window w. Windows: InputPane; Wayland: text-input follows the focus by itself (the compositor’s
keyboard); elsewhere the host’s job (Android, the browser) or nothing there is to ask (X11)
(ui touch.rs) the host’s main pointer is a finger at the start (Android; a phone’s browser:
pointer: coarse; a Windows tablet in slate posture): no scroll bars from the first frame on; the
next pointer event decides again
(ui touch.rs) a finger’s gesture reached a widget (a tap, a drag), or it did not (a scroll):
Android asks after the finger lifted whether the keyboard has to follow
move a file or folder into the trash (Windows: the recycle bin; Linux: the freedesktop
trash) -> false: it stays where it was, never deleted for good (trash.rs). Counts as
writing the path; a vfs name needs a folder mount.
pump the display until an event is queued or the deadline passes (0 = poll, u64::MAX =
forever); without a display (headless) sleep until the deadline or a wake()
[lx_wait_nodisp]
headless wait (no display): until a wake-up (E_WAKE to on_event, returns 1) or the
deadline in time_us() (0 = only poll, u64::MAX = forever; returns 0) [lx_wait_nodisp]
show the frame’s dirty rectangles (x, y, w, h; None = all) in window w; pixels outside
them must be what the last present of w showed (linux_x11_present.rs, linux_wl_present.rs)
the compositor’s window menu (move, resize, always on top, …) of window w at x, y (px of
the window); call on the press of the right button over a library-drawn title bar
(tests)
WT_PIXEL the colour the window system holds at client pixel a[0], a[1] of window w: X11
GetImage, Wayland the last shared memory buffer; -1: no way to know (Wayland on
GPU buffers: a client cannot read a window back)
WT_MOVE a[0], a[1], a[2], a[3]: the window’s rectangle; win_set_rect reports nothing back
here, the event a size change has on Windows comes from this aid
WT_DPI a[0]: the dpi as if the compositor preferred that scale (Wayland with a viewport,
else -1: X11 has one dpi for the display and no second size)
WT_SHOW a[0] = 7 minimised, 4 back: X11 through the window manager; Wayland can minimise, but
no client can undo that: 4 does what the compositor’s next activation does here
WT_POPUP_RECT popup slot w is shown: 1, else -1
WT_NOANIM, WT_FROM_POINT nothing to turn off; nobody tells a client what lies on top of its
window: it counts as ours
(tests) what the window system holds for window w: (w, h, rows of w * 4 bytes): X11 reads it
back (GetImage; also a buffer on the window), Wayland has no way to: None
(Linux, a library-drawn title bar) the window manager’s menu of the current window at
x, y (px of the window), on a right-button press: move, resize, always on top, …
call the handler of event event (“enter”, “key”, …) of interface iface
(“wl_pointer”, “wl_keyboard”, …) with decoded arguments (object id 1, udata 0), as
linuxtest –test synth does -> false when there is no such event [hcall]
the pixels of window w’s last committed buffer – what the compositor shows – as (w, h,
rows of w * 4 bytes B, G, R, x); None while damage waits (linuxtest –test pcheck)
attach a buffer id that does not exist to the main window’s surface: the compositor
answers with wl_display.error, which ends the process (linuxtest –test protoerr)
a wl_display.sync round trip: the events that arrive before its answer are dispatched
first (linuxtest –test burst: a burst of keys while it waits) -> 0 ok / -1 timeout
Write an exclusively created sibling, flush it, then replace path (a mount: its own way of
replacing a file; missing folders are created). [plat_file_write]