github go-gui-org/go-gui v0.95.0

one hour ago

Added

  • PNG, JPEG and GIF bytes can be registered directly as images (#1228).
    RegisterEncodedImage decodes bytes from go:embed, a network response or
    another in-memory source and returns a Src for ImageCfg and
    DrawContext.Image. It uses the same immutable, content-keyed registry as
    UseImage, without requiring a temporary file. The image stays registered
    until DropImage, outside the registry's memory budget, so a Src saved at
    startup keeps drawing however many other images are registered; a repeat call
    for the same key returns without decoding again. A GIF decodes to its first
    frame, and GIF support no longer depends on PDF export importing its decoder.
    The showcase Image guide now sets every image source side by side, with what
    each asks of the app, and corrects its format list: BMP and WebP decode only
    when the app imports their decoder. examples/embedded_image shows one scene
    embedded as PNG, JPEG and GIF.

  • Window state and placement: minimize, maximize, restore, fullscreen, resize,
    move (#1171, #1220).
    An app could not change its own window, so a frameless
    title bar could not offer minimize and maximize buttons, and a media player
    could not go fullscreen. Window.Minimize, Maximize, Restore,
    SetFullscreen, SetWindowSize, SetPosition and Position now do this on
    Windows, macOS, X11 and Wayland. IsMaximized and IsFullscreen report what
    the OS confirmed, including a change the user made through the OS, and a view
    reading them redraws when the state changes. Fullscreen ignores MaxWidth and
    MaxHeight, works on a FixedSize window, and returns a maximized window to
    maximized. Called before backend.Run, these apply as the window opens.
    Position is in OS desktop units. Wayland cannot place a window or bring back
    a minimized one, so SetPosition is a no-op there, Position reports no
    position, and Restore only undoes a maximize. On the web SetFullscreen
    puts the whole page in fullscreen; browsers allow it only from a click, tap or
    key press handler, and iPhone Safari has no page fullscreen. On iOS it hides
    the status bar and lets the home indicator fade out; the view keeps its size,
    and IsFullscreen turns true once the window fills the screen, which a
    windowed iPad does not. On Android it hides the status and navigation bars:
    the app's host polls the new PendingFullscreen bridge call and answers
    through FullscreenChanged, as GoGuiFullscreen.kt in
    examples/android_demo does; a host without them leaves SetFullscreen
    without effect, and IsFullscreen is false in multi-window mode.

  • Safe area: Window.SafeAreaPadding (#1171). On a phone the notch, the
    status bar and the home bar cover the edges of the window, and an app had no
    way to know how far. Window.SafeAreaPadding returns that space along each
    edge as a Padding, so Padding: w.SafeAreaPadding() keeps content clear of
    it. It is opt-in: nothing in the framework lays itself out by it, so existing
    apps draw as before. While the soft keyboard is up, the bottom edge shrinks by
    SoftKeyboardInset, because the keyboard already covers the home bar: an app
    that pads for both counts it once. iOS, Android and web report it; desktop is
    always zero. On web it is non-zero only when the page's viewport meta has
    viewport-fit=cover. An Android app adds the SafeAreaInsets bridge call and
    the inset listener from examples/android_demo to its host; without them the
    safe area stays zero. examples/ios_demo and examples/android_demo use it.
    Backends report through gui.DispatchSafeArea.

  • InputCfg.MaxLength sets an Input's rune budget (#1187). An edit that
    would take the text past it is refused whole: a typed character or an IME
    commit sounds the reject cue, and a paste also reaches OnPasteRejected. 0
    takes the default, now 1,048,576 runes. A field built for a short note can set
    a small budget and say so when a paste is refused; a field for an API response
    or a log can leave it unset. Text the app sets past the budget is shown in
    full, and the field takes only edits that do not grow it.

  • Slovak (sk-SK) locale (#1209). Adds Slovak number, date, time, currency
    and user-facing UI string formatting to the built-in locale registry.

  • TitlebarDark switches the window frame on macOS (#1207). A window
    followed the macOS light/dark setting whatever theme the app pinned, so a dark
    go-gui app on a light desktop sat in a light frame. Window.TitlebarDark now
    pins that window's appearance: the frame, the title, the window buttons and a
    vibrancy backdrop switch with it. Dialogs and the menu bar keep the system's
    setting. FollowSystemAppearance already calls it, and an app that pins its
    theme with SetTheme calls TitlebarDark(theme.TitlebarDark) to match. A
    window whose app never calls TitlebarDark follows the system, as before.
    With SetWindowVibrancy, macOS draws a dark window's title bar clear, as it
    already did on a dark desktop.

  • TitlebarDark switches the window caption on Windows (#1201). Windows
    draws every window's caption light until the app opts in, whatever the system
    setting, so a dark go-gui app sat under a light caption. Window.TitlebarDark
    now sets the dark or light caption for that window and repaints it at once.
    FollowSystemAppearance already calls it, so a following window's caption now
    switches with the desktop setting; an app that pins its theme with SetTheme
    calls TitlebarDark(theme.TitlebarDark) to match. Unlike on Wayland, the
    setting is per window. It needs Windows 10 version 1809 or later. With "Show
    accent color on title bars" turned on, the active caption keeps the accent
    color and only the inactive one shows the variant. A window whose app never
    calls TitlebarDark keeps the light caption.

  • TitlebarDark before Run is applied when the backend attaches (#1201).
    It was dropped, as no platform was attached yet. The window now stores the
    last variant asked for and applies it on attach, like SetWindowOpacity. On
    Windows that is before the window shows, so calling FollowSystemAppearance
    or TitlebarDark before Run gives the right caption from the first frame.
    From OnInit, which runs once the window shows, Windows animates the caption
    from light to dark as the window opens. While a window follows the system
    appearance and the OS reports a setting, that setting wins on attach.

Changed

  • BREAKING: LookupImage returns a MemImage (#1230). It returned
    (w, h int, pix []byte, ok bool) and now returns (MemImage, bool), where
    MemImage holds W, H, Pix and the registration's Serial. The pixels
    and the serial come from one locked lookup, so a backend can never pair one
    registration's pixels with another's serial. Migration:
    w, h, pix, ok := gui.LookupImage(src) becomes
    mi, ok := gui.LookupImage(src), then mi.W, mi.H and mi.Pix. Backends
    also gain ImageSerial, ImageRegistryGen and IsMemImage to release stale
    textures; apps do not need them.

  • BREAKING: 34 orphaned types are no longer exported (#1235). Nothing public
    produced or accepted them, so no program could do anything with a value: the
    25 per-widget style structs BadgeStyle, BreadcrumbStyle, ComboboxStyle,
    CommandPaletteStyle, DatePickerStyle, ExpandPanelStyle, InputStyle,
    InspectorStyle, ListBoxStyle, MenubarStyle, ProgressBarStyle,
    RadioStyle, RectangleStyle, SelectStyle, SeparatorStyle,
    SkeletonStyle, SliderStyle, SplitterStyle, SwitchStyle,
    TabControlStyle, TableStyle, ToastStyle, ToggleStyle, TooltipStyle
    and TreeStyle (#735 made the Theme fields private and the With*Style
    methods went with them; only the type names survived), plus ViewState,
    BoundedStack, BlinkCursorAnimation, BoundedDiagramCache,
    DiagramCacheEntry, CompiledInputMask, MaskEditResult and
    markdown.CodeLanguage. Migration: delete any declaration that spells one of
    these names; it was dead code. DialogStyle, MarkdownStyle,
    ScrollbarStyle, DataGridStyle and ColorPickerStyle stay public because
    they have entry points. The export gate had not flagged the orphans because
    each carried a keep marker claiming signature reachability, which stopped
    being true in #735; all 96 such markers are gone and tools/exportaudit now
    computes reachability itself (the reach class from #1221), so a marker can
    no longer outlive the fact it asserts.

  • BREAKING: a titled container with a fixed or filling height has less room
    for its content (#1238).
    A group box now reserves room for its title inside
    its bounds (see the next entry). A box whose Height is fixed, or that fills
    its parent, keeps its size, so its content area shrinks by the title's band:
    about 9 px at the default title size, two thirds of the title's font size in
    general, and more when the top padding is under half the title's height or the
    title has more than one line. A titled Circle of fixed size draws its circle
    that much smaller. Content sized to fit such a box can now be clipped or
    scroll. Migration: add the band to Height, or let the content shrink.

  • A group box makes room for its title, and an unset TitleBG hides the
    border behind it (#1238).
    The title used to stick out above the box by half
    its height, over whatever sat there, and covered the first child when the top
    padding was small. The box now reserves the title's room: its border is drawn
    half the title's line height below its top edge (about 9 px at the default
    title size; the band follows the title's font size), and its content starts
    below the title. A box sized by its content is that much taller; see the
    BREAKING entry before this one for fixed heights. The title is then inside the
    box, where a scroll view, a clipping parent or a RotatedBox no longer cuts
    it, and in a right-to-left box it sits at the right edge with the same inset.
    A rounded corner wider than that inset moves the title past its curve, onto
    the straight part of the border. A title with a newline gets room for every
    line, its first line on the border. A titled Circle draws its circle below
    the band, so the title sits on the line the circle's top touches. The border
    of any Circle now rings the circle drawn; one wider than tall stroked a
    rounded box around it. TitleBG no longer has to be set to the parent's
    color: unset, the patch under the title takes the color drawn under the
    border, the box's own fill or what is behind it, so the border line no longer
    runs through the title by default. Over a gradient or shader fill, a
    ColorFilter, a blurred fill or a see-through floating panel no one color
    matches; there an unset TitleBG draws no patch, as before. Over a sibling
    drawn underneath, as in a Stack, the patch takes the container's color; set
    TitleBG there. ColorTransparent turns the patch off. A disabled box no
    longer dims the patch, which let the border show through the title.

  • An Input holds 1,048,576 runes by default, and app-set text is no longer
    cut (#1187).
    The budget was 65,536 runes, below a typical API response, and
    text an app set past it was cut silently when the view was built, so the next
    keystroke committed the cut text. Large text now costs little (chunked layout,
    byte-indexed edits, delta undo), so the default is sixteen times larger, and
    app-set text past any budget shows whole. PreTextChange and
    PostCommitNormalize output is capped at the field's MaxLength. A field
    larger than 64 KiB gets no platform spell checking, and its accessible name
    carries the first 65,536 runes.

  • Hovering the libdecor titlebar no longer redraws the window on Wayland
    (#1203).
    On GNOME and other compositors where go-gui draws the frame through
    libdecor, the frame shows only with a commit of the window's surface. Each
    time libdecor redrew it on its own (a button highlight as the pointer crossed
    the titlebar, a new title, an output change), go-gui rendered and swapped a
    whole frame of unchanged content to make that commit. The window now commits
    the buffer it already shows. A frame already due, such as one after a resize
    or a scale change, still makes the commit, and so does the first frame.

  • Input undo keeps the edits, not copies of the text (#1187). Each undo
    step held a full copy of the field, up to fifty of them, and every keystroke
    converted the whole text to runes and back. A step now holds only the bytes an
    edit replaced, and an edit splices the text once: a keystroke in a 1 MiB field
    allocates one copy of it instead of a rune slice and a memento. Two behaviours
    follow. When the app or PostCommitNormalize replaces the field's text,
    Ctrl+Z drops the history instead of bringing back an old copy over the new
    text. An edit that leaves the text as it was, such as a PreTextChange that
    hands back the current text, no longer adds a step that undoes nothing.

Fixed

  • Popups and tooltips are drawn over the knobs, tracks and swatches of the
    color widgets, and those parts stay inside a scroll view (#1244).
    The knobs
    of ColorPicker, ColorPlane, ColorWheel and ColorChannelSlider, the
    slider tracks and the color of a ColorSwatch were floating children, so they
    were drawn in the popup layers. The knobs were painted over every Select or
    Combobox list, menu, context menu and tooltip, and the tracks and the swatch
    color over those that came earlier in the tree, also inside a dialog or a
    floating panel. In a scroll view they showed outside it once the widget was
    scrolled partly out of view, over a header or below the view. In a turned or
    scaled container (Transform) or a RotatedBox they did not turn with their
    widget and were drawn beside it. These parts are now drawn with the rest of
    their widget, in its layer, inside its clips and under its transform. A
    ColorPicker looks the same as before, except under a theme with less padding
    than half a marker (Theme.WithPadding(false)): there it now keeps that much
    padding, so its markers stay inside it. A ColorPlane or ColorWheel used on
    its own is now one MarkerSize (16 by default) wider and taller than its
    Size: it keeps half a marker of room on every side, because its marker can
    sit on its edge, and a scroll view it sits flush in would otherwise cut that
    marker in half. A ColorChannelSlider given a length shorter than its thumb
    now takes the thumb's length: before, its thumb stuck out past it and moved
    backward as the value grew.

  • A tooltip no longer opens for a widget that a dialog or a popup covers
    (#1243).
    WithTooltip opened its tooltip whenever the pointer was inside
    the widget's box, even when a modal dialog, an open Select list or a menu
    lay over the widget at that point, so the tooltip showed on top of the dialog
    or the list. Now it opens only when the topmost thing drawn under the pointer
    belongs to the widget. A popup covers the widget everywhere, also on its
    padding and between its items. A tooltip that is showing when a dialog or a
    popup opens over its widget closes in that frame, and the part of a widget
    that a scroll view hides no longer opens it. When tooltips are nested, the
    tooltip of the topmost widget under the pointer shows: on a button inside a
    card, the button's, also when the pointer comes to it from the card. A wrapper
    that leaves the view while hovered no longer comes back with its tooltip open.

  • Android: reopening an app after Back no longer shows a blank screen
    (#1246).
    Android can close an app's screen (its activity) and open a new one
    while the app keeps running. This happens after Back on Android 11 and
    earlier, after finish(), and after a configuration change that the manifest
    does not handle. The demo's Kotlin code called android.CleanUp when the old
    screen closed. That destroyed the Go window, so the new screen showed only the
    background. The call also ran at an unpredictable moment, and could even
    destroy the new screen's backend. Now the Go window lives as long as the app's
    process. A new screen reuses it, with the app's view and state, and go-gui
    rebuilds the graphics resources for it. android.CleanUp is deprecated and
    does nothing. So an app whose Kotlin code was copied from the demo is fixed by
    updating go-gui; it can also delete the call from onDestroy. One change for
    apps: w.Ctx() is no longer cancelled when a screen closes.

  • Tooltips, dropdowns and menus are drawn over group-box titles, and a title
    scrolls out of view with its box (#1238).
    A group-box title was two floating
    children, so it was drawn in the popup layers: a tooltip, a Select or
    Combobox list, a menu or a context menu that opened earlier in the tree was
    painted under it, and the title escaped every clip, showing over a header or
    below a footer once its box scrolled out of a viewport. The container now
    draws its title itself, after its content and in its parent's clip. A title
    under a view transform turns and scales with its box instead of staying
    behind, a disabled ancestor dims it like the rest of the box, and a box an
    overflowing row hides no longer draws its title.

  • ClipContents on a Circle clips to the circle (#1238). The mask took
    the container's corner radius (6 px by default), so it was a rounded square
    around the circle, and a filled child or an image painted past the circle at
    its corners. It is now the circle drawn, inside its border: the same circle
    the fill, the border and the clip radius use.

  • Dropping an in-memory image frees its GPU texture, and a key registered
    again draws its new pixels (#1230).
    DropImage removed the image from the
    registry, but GL, Metal, iOS, Android and web kept the uploaded texture until
    enough other images pushed it out, so an app that showed and dropped large
    images could hold up to 128 of them on the GPU per window, about 2 GiB at
    2048×2048. Registering the same key again, after a drop or at a new size, drew
    the old pixels. Every registration now carries a serial and every removal
    (drop, budget eviction, re-registration) moves a counter; each backend checks
    its cached textures when the counter moves and deletes the stale ones on its
    own render thread, and a draw that sees a new serial uploads again. A frame
    with no removal costs one atomic load. A dropped mem: source draws nothing:
    it no longer reaches the file loader, which logged an error and took a second
    cache slot, and on web it no longer panics. Textures of images that stay
    registered are still bounded by count; a byte budget is #1239.

  • FormIssueError and FormIssueWarning are back (#1235). The #230 sweep
    deleted the two FormIssueKind values because only the showcase forms guide
    referenced them, so the validator code that guide shows did not compile. A
    validator can tag an issue again and an app's summary can tell a warning from
    an error.

  • The API the 2026-08 unexport sweep took private is public again (#1221).
    Commit a80087e (#230) unexported 1,835 identifiers by reference count and
    missed that a struct handed to the app is public by shape. A custom
    DataGridDataSource could not fill GridDataCapabilities, read
    GridDataRequest.Page or return GridDataResult.NextCursor; the ORM adapter
    had no reachable constructor; MarkdownStyle hid 31 of its 45 fields and
    FormSummaryState its issues; the ErrTest* sentinels, the lifecycle
    Event* constants, the Vibrancy* materials and most of the audio
    package's music and channel controls were gone; and the enum types behind
    exported Cfg fields (FloatAttach, SizingType, DockNodeKind,
    RenderKind, …) could not be named. All of these, plus the scroll, command
    palette, dock tree, color, print and table helpers that had no replacement,
    are exported again under their original names, and the two alias repairs in
    datagrid go with them. tools/exportaudit gained a reach class, a type
    closure from each package's exported functions, constants and variables, so
    payload fields, enum members and methods on reachable types pass the gate on
    their own and only orphans fail (docs/specs/exportaudit-surface-policy.md).

  • PDF export no longer loses parts of the window after a rounded rectangle
    (#1231).
    Each rounded rectangle left a graphics state open in the PDF, so
    the next clip change ended that state instead of the clip it meant to end.
    Clips piled up and cut later content out of the page: the showcase's whole
    detail panel exported blank, its text present but invisible, and an opacity
    set earlier came back on later text. Rounded rectangles are now drawn without
    opening a graphics state.

  • PDF export prints rich text in each run's own font (#1231). Markdown and
    other rich text printed every run in Helvetica, fitted to the run's width on
    screen. A code run is monospace, so narrow tokens such as if or ( came out
    several times too large and overlapped the lines around them. Each run now
    prints in its own family and weight, so code prints in Courier and bold text
    in bold. Menlo and Monaco, the macOS monospace families, now count as
    monospace too. In all PDF text, a font name with Pango's Heavy weight
    (Inter Heavy) now prints bold, and Oblique prints slanted like Italic.

  • PDF export no longer writes Inf for huge geometry (#1231). A coordinate,
    size, radius, line width or font size was scaled to the page in float32, so a
    huge but finite value could overflow to infinity when the page scale is above
    1, and the PDF then held Inf, which readers reject. The scaling now runs in
    float64.

  • Android: the soft keyboard height no longer comes out short on Android 15
    (#1171).
    The demo host subtracted the navigation bar from the keyboard, but
    from Android 15 the view reaches under that bar, so the reported height was 24
    dp short on a Pixel 7 and a field padded by it ended up under the keyboard.
    The host now measures the keyboard against where the view really ends. An app
    host copied from examples/android_demo needs the same change in its inset
    listener.

  • A GIF whose first frame covers only part of its canvas draws at full size
    (#1228).
    A GIF image file used only its first frame's own rectangle, so a
    frame placed at an offset or smaller than the canvas was stretched over the
    whole image. The frame now sits at its offset on the full canvas, and the
    uncovered area is transparent, as in a browser. RegisterEncodedImage decodes
    GIFs the same way.

  • iOS apps launch when built with the iOS 27 SDK (#1225). UIKit now refuses
    to start an app without the scene life cycle, so every go-gui iOS app built
    with that SDK died at launch with no Go panic. The backend now creates its
    window in a UIWindowSceneDelegate, so apps need no Info.plist change.
    Scenes date from iOS 13, so the iOS 15 floor does not move.

  • A window resized while unfocused learns its new size (#1220). gui dropped
    EventResized on an unfocused window along with the input events, so a window
    resized in the background kept its old size until the next resize: a tiling
    window manager moving a background window, or an app calling
    Window.SetWindowSize from a tray. Layout then used the stale size.

  • Window.Show no longer un-maximizes a window on Windows (#1220). Show
    restored the window whatever its state, so a tray "Show Window" on a maximized
    window dropped it back to its normal size. It now restores only a minimized
    window, and otherwise raises it as it is.

  • Built-in locales translate the Lightness label and the source-changed status
    (#1210).
    The ar-SA, de-DE, es-ES, fr-FR, he-IL, ja-JP, ko-KR,
    pt-BR and zh-CN bundles lacked the lightness and source_changed keys,
    so an HSL color field and its lightness slider, and the DataGrid CRUD status
    after a source change, showed English in those locales. The bundles and the
    Showcase copies now carry both, and a test fails when a bundled locale omits
    or blanks any widget string, or an en-US default is blank. Custom bundles
    still fall back to en-US for an omitted key.

  • A scrollable in a Splitter or DockLayout pane scrolls to its end
    (#1214).
    A pane got its size only after the frame had clamped the scroll
    offsets and applied the scroll requests, so a scrollable inside it was
    measured at size zero first. When its rows were containers rather than plain
    text, that early measure gave a scroll range too short for the content. The
    wheel, ScrollVerticalTo and ScrollVerticalToPct then stopped short of the
    end, and the last rows could not be scrolled into view. In a nested splitter
    or a DockLayout the list did not scroll at all. The same early pass also
    dropped ScrollAnchor corrections and left ScrollToEnd and the other index
    scrolls short on a ListBox. Panes are now sized before anything is
    positioned or scrolled, so a scrollable in a pane has the same scroll range as
    one outside a splitter. Panes are also laid out once per frame instead of
    twice, which saves an allocation per DockLayout. A DockLayout with no
    Root no longer covers itself with the translucent drop-zone overlay. The new
    examples/splitter_scroll compares a pane with a plain Row.

  • A Fit container inside a Canvas sizes to its content (#1216). The passes
    that size a Fit container from its children did not reach below a Canvas, so
    a Fit container there, at any depth, came out 0×0: its background and border
    did not draw, a button in it had no frame, and nothing in it could be clicked.
    Its text still drew, which hid the cause. Fit containers below a Canvas now
    size as they do in a Row or Column, and a Fit Canvas encloses them. A
    Fill child of a Canvas, which was also 0×0, now takes its content's size,
    including a Fill Canvas nested in a Canvas; a Canvas still does not
    stretch it. Three buttons in the examples could not be clicked because of it:
    the minesweeper reset button, the snake start button and the 2048 "Try again"
    button. The calculator's title bar had no height.

  • A wheel notch moves one notch when a correction lands mid-ease (#1190). A
    discrete mouse wheel eases toward its target over several frames. When a
    scroll anchor, measured list rows or long text moved the offset during that
    ease, the target stayed where it was, so the ease travelled the correction on
    screen as well and one notch jumped much further than the next. The target now
    moves with the content. An ease to an offset, such as ScrollAnchorReveal,
    keeps its target.

  • Arrow keys in a password field move one character (#1187). A password
    field draws bullets, and its arrow, Home, End and vertical moves were taken on
    the bullets with the caret of the hidden text, whose characters are other byte
    lengths: End then Left put the caret about a third of the way into an ASCII
    password, not before its last character. The moves now map the caret onto the
    bullets and back.

  • A click in an Input ends the undo run (#1187). Typing, clicking
    elsewhere and typing again made one undo step, so one Ctrl+Z took back the
    typing on both sides of the click. A click now ends the run, as arrow keys and
    drags already did.

  • Text and Input draw text longer than 10,240 bytes (#1190). go-glyph
    shapes one layout at a time and refuses text past its 10,240-byte budget, and
    a text shape shaped its whole text as one layout, so a longer Text or
    Input kept its box and scrollbar but drew no glyph. Text is now laid out in
    chunks of whole paragraphs, a paragraph longer than the budget is cut at the
    line breaks a whole-paragraph layout also has, and only the chunks in view are
    drawn. The chunks persist per widget across frames: an edit re-shapes the
    chunk it touched and a rebuild re-shapes nothing, where every rebuild and
    every keystroke used to re-shape the whole field. Above 64 KB the chunks not
    yet shown start with estimated heights; when one scrolls into view, the scroll
    offset absorbs the measured difference, so the lines on screen and the caret
    stay where they were. A rotated or transformed long text turns as one block,
    and a content transition's fade draws long texts chunk by chunk too. A
    gradient text stays continuous up to 10,240 bytes, as before, and past that
    draws in its plain colour; so does a shimmer. Rebuilding a gradient, transform
    or font features each frame no longer re-shapes the text. Typing in an Input
    past one chunk no longer shapes the whole text to measure it, which at 10 KB
    was most of what a key cost. A box that fits a long multi-line text is as wide
    as its longest line. docs/specs/large-text-input.md records the design and
    the alternatives.

What's Changed

Features

Bug fixes

  • fix(android): keep the window when an activity ends (#1246) by @ollex in #1247

Other changes

  • feat(gl): TitlebarDark switches the caption on Windows (#1201) by @ollex in #1202
  • fix(wayland): commit libdecor's frame redraws without rendering (#1203) by @ollex in #1204
  • test(gui): keep the animation loop out of the FlipPanel tests (#1205) by @ollex in #1206
  • feat(metal): TitlebarDark pins the window appearance on macOS (#1207) by @ollex in #1208
  • Add Slovak locale by @SladkyCitron in #1209
  • Update Slovak locale strings by @SladkyCitron in #1211
  • fix(gui): close an InputDate calendar once focus or a press leaves the field (#1212) by @ollex in #1213
  • fix(gui): size Splitter and DockLayout panes before scrolling (#1214) by @ollex in #1215
  • fix(gui): measure the children of a Canvas (#1216) by @ollex in #1217
  • fix(gui): translate lightness and source_changed in every locale (#1210) by @ollex in #1219
  • test(gui): keep the theme-fade tests off the animation loop by @ollex in #1223
  • feat(gui): window state and placement on desktop (#1220) by @ollex in #1224
  • fix(ios): adopt the UIScene life cycle by @ollex in #1225
  • feat(gui): Window.SafeAreaPadding on iOS, Android and web (#1171) by @ollex in #1227
  • feat(gui): add RegisterEncodedImage for PNG, JPEG and GIF bytes (#1228) by @ollex in #1229
  • docs: show the CONTRIBUTING.md blockquote as three lines by @ollex in #1233
  • fix(gui): re-export the API the #230 sweep took private (#1221) by @ollex in #1234
  • fix(gui): PDF export loses the panel after rounded rects and garbles code (#1231) by @ollex in #1232
  • refactor(gui)!: unexport 34 orphaned types and drop stale reachability markers (#1235) by @ollex in #1237
  • fix(gui)!: release GPU textures of dropped and re-registered mem images (#1230) by @ollex in #1240
  • fix(gui)!: draw group-box titles with their container, under popups (#1238) by @ollex in #1241
  • fix(gui): keep a tooltip shut under a dialog or a popup (#1243) by @ollex in #1248
  • fix(gui): popups cover the knobs, tracks and swatch of color widgets (#1244) by @ollex in #1249
  • Spike/large text input by @ollex in #1250
  • changelog: add v0.95.0 by @ollex in #1251

New Contributors

Full Changelog: v0.94.0...v0.95.0

Don't miss a new go-gui release

NewReleases is sending notifications on new releases.