Skip to content

native-theme v0.6.0 — egui connector, gpui-kit 0.7.0, the Basic page

Choose a tag to compare

@tiborgats tiborgats released this 01 Oct 21:12
· 1539 commits to main since this release

Added

  • native-theme-egui, the egui toolkit connector (egui 0.36.2). A ThemeAtlas compiles a theme into egui's two base styles, a style per widget role and appearance variant, and a frame per container surface; install puts them into an egui::Context, and native_scope, native_set_style, role_modifier and surface_frame apply the per-widget ones through egui's own seams. Icons follow the theme's icon set and, per colour scheme, its freedesktop icon theme; the platform's typeface is installed with feature system-fonts (default); a ThemeWatcher (feature watch) rebuilds on an OS theme change. mapping.toml states where every theme value lands, and the crate's docs render it. Every border colour is painted as stated: defaults.border.opacity is already folded into it, and no connector multiplies a colour by it. The showcase, showcase-egui, is the gpui showcase's application in egui, with per-instance Widget Info generated from the manifest; with --screenshot it captures the window with its title bar on macOS and Windows (through xcap), as the gpui and iced showcases' captures do, and refuses elsewhere, where the capture scripts take the window.
  • native-theme-egui-widgets, a companion crate of the egui connector: the widgets egui's own cannot draw from a theme — a switch, a slider whose knob is not its rail, a spinner at the theme's stroke and a segmented control — and egui's links, drop-down, radio button, progress bar and expander wrapped in what the theme states for them. Everything it draws comes from the ResolvedTheme of the atlas native-theme-egui installed. Targets egui 0.36.2.
  • native-theme: font matching by family, weight and style — fonts::select_face over fonts::FaceTraits, and behind the new system-fonts feature fonts::system_face, whose SystemFace::family is the family the font database records for the face; fonts::is_macos_system_ui_family.
  • native-theme: IconId converts from any &T whose T implements IconProvider, so a loader takes a generated icon enum by reference — MaterialLoader::new(&AppIcon::PlayPause), as native-theme-build's README shows; it needed a cast to &dyn IconProvider before.
  • native-theme: SystemTheme::icon_theme_for(mode), the icon theme of either variant.
  • native-theme: icons::colorize_monochrome_svg, one colouriser for every connector.
  • native-theme: SfSymbolsLoader::color / color_opt and SegoeIconsLoader::color / color_opt draw the system sets' monochrome glyphs in a chosen colour, keeping their alpha, as FreedesktopLoader::color does for symbolic icons. Without a colour the output is unchanged (Segoe glyphs white, SF Symbols black); full-colour stock icons (SIID_*, IDI_QUESTION) ignore it.
  • native-theme-iced: the system-fonts feature (default) and system_font_family, the family iced's font database holds for the stated face — on macOS the system UI font's own name for "SF Pro".
  • Showcases: --pointer X,Y holds the pointer at a point of the window and --press holds the primary button down there, so a capture shows a control hovered or pressed where nothing can move the real pointer, as in a nested compositor. A value that is not X,Y is reported, and the showcase exits with 1.
  • Showcases: a Basic page in all three, their default page and the one every capture shows: the controls all three draw — buttons, checkboxes, radio buttons, text and a link, text fields, a drop-down, a slider, a progress bar and a tooltip — in the same order, labels and states, packed onto one screen, so the three captures compare control by control. Each page is laid out by the theme: groups and columns layout.section_gap apart and inset by layout.window_margin, headings in text_scale.section_heading, body text in defaults.line_height; buttons, text fields and the drop-down at the theme's minimum sizes (in egui per call, since the connector leaves button.min_width and input.min_height to the application; in iced through at_least and control_line_height); the link underlined where link.underline_enabled says so, and unpadded, as the theme states no padding for a link; the gpui tooltip built by the application and refined by geometry::tooltip, and the iced one padded as the theme states where all four sides agree.
  • native-theme-gpui: geometry::input_fill(n, disabled), an Input's fill from input.background_color or input.disabled_background (gpui-component fills a light-theme field with the window background, and no ThemeColor field reaches it), and geometry::link, which honours link.underline_enabled (gpui-component underlines every link at rest) and carries link.font's size and weight. The showcase applies both.
  • native-theme-gpui: geometry::button_disabled, a disabled Button's fill and label colour from button.disabled_background (or button.background_color) and button.disabled_text_color: gpui-component paints its own faded literals and then replays the caller's refinement over them, so the platform's pair arrives. The showcase applies it to its disabled Buttons (kde-breeze: #f0f0f0 and #a8a9aa; the window showed through at half opacity).
  • native-theme-iced: minimum sizes. control_line_height gives a text input's or a pick list's text the line height that makes the control input.min_height or combo_box.min_height tall inside its padding (iced has no minimum-height setter); button_content_min_size and at_least put a floor of button.min_width × button.min_height under a button's label. combo_box_padding is the pick list's padding, padding_inside_border the rule the padding helpers share.
  • native-theme: checkbox.radio_dot_diameter_px (CheckboxTheme::radio_dot_diameter), the dot a selected radio button draws, an optional size like menu.row_height: KDE 6, GNOME 8 and Windows 12 (docs/platform-facts.md §2.5: Breeze's renderRadioButton, libadwaita's bullet.svg, WinUI's RadioButtonCheckGlyphSize). macOS publishes none, so there it stays unstated and each toolkit draws its own dot. The kde-breeze, adwaita and windows-11 presets, their live presets, and the KDE and Windows readers state it.
  • native-theme-gpui: widgets::Radio draws that dot, in checkbox.indicator_color and centred in the circle, instead of gpui-component's check glyph.
  • native-theme-iced: radio(&resolved, radio(..), is_selected), a radio at the platform's indicator size and label gap in styles::radio, with the stated dot laid over iced's own (iced draws its dot at half the circle, and radio::Style has no size for it).
  • native-theme-egui-widgets: radio_button::RadioButton, egui's radio button in the checkbox role's scope with the stated dot (egui sizes its dot from the check mark's box); the egui showcase's Basic page uses it.
  • native-theme: checkbox.radio_indicator_width_px (CheckboxTheme::radio_indicator_width), the radio circle's width where it differs from the check box's indicator_width: Material 20 against its 18 (comp.radio-button icon-size, docs/platform-facts.md §2.5); KDE, GNOME, Windows and macOS size both alike, so there it is unstated and the radio is indicator_width across. gpui's widgets::Radio, the iced connector's radio and egui-widgets' RadioButton draw it.
  • native-theme: switch.unchecked_thumb_diameter_px and switch.unchecked_thumb_background (SwitchTheme), an off switch's thumb where the platform draws it apart from the on one (docs/platform-facts.md §2.21): Material 16 across in outline (#79747e, dark #938f99) against 24 in on-primary; Windows ToggleSwitchKnobFillOff, TextFillColorSecondary (#0000009e, dark #ffffffc5); GNOME dark libadwaita's $slider_color, white 80 % over the view background (#d2d2d2). Unstated, the off thumb is thumb_diameter across in thumb_background. gpui's widgets::Switch, the iced connector's switch and styles::toggler, and egui-widgets' Switch draw it; egui's thumb grows as it travels.
  • native-theme: the active tab's indicator line (docs/platform-facts.md §2.11): tab.active_indicator_color, tab.active_indicator_width_px and tab.active_indicator_side (a new enum, TabIndicatorSide::Top / Bottom). Breeze fills a TabBar_ActiveEffectSize 3 strip of Highlight along a North tab's top edge; libadwaita's GtkNotebook insets 4 of --accent-bg-color at the bottom; Material's primary tabs a 3 primary indicator at the bottom; WinUI's TabView and AppKit's NSTabView mark the active tab by fill and border alone, so there all three stay unstated. The kde-breeze, adwaita and material presets state them, the live presets the width and side, and the KDE and GNOME readers the colour (the selection background, the portal accent).
  • native-theme-gpui: widgets::TabBar draws the line across the selected tab's outer edge (TabLook::indicator, widgets::TabIndicator).
  • native-theme: button.checked_background and button.checked_text_color, a toggle button that is on (docs/platform-facts.md §2.3): Breeze's button colour mixed an eighth towards the button text (#e1e1e2, dark #43464a) in the button text; WinUI's ToggleButtonBackgroundChecked, the accent fill, in TextOnAccentFillColorPrimary; libadwaita's $button_checked_color, the pressed fill's 30 %, in the button's own text; Material's latest tonal selected-container-color secondary in on-secondary. AppKit states none, so there a toggle that is on shows the pressed pair, as every toggle did before. The KDE reader computes the pair from kdeglobals, the Windows reader the fill from the accent.
  • native-theme-gpui: geometry::button_checked, a selected Button's fill and label from the checked pair (the pressed pair where unstated); the showcases' Basic toggle On shows the checked pair in all three.
  • native-theme-iced: tab_indicator, a tab with the line stacked over it where it is active, and tab_indicator_line, the line alone; the iced showcase's tab rows use the first, its iced_aw Basic tab bar the second.
  • native-theme-egui-widgets: progress_bar::ProgressBar, egui's progress bar rounded progress_bar.border.corner_radius and outlined as progress_bar.border states (egui's draws no outline); the egui showcase's Basic page uses it.
  • native-theme-iced: pick_list_handle, the drop-down arrow as the open chevron KDE, GNOME and Windows draw — iced's own Iced-Icons chevron glyph (U+E803) at combo_box.arrow_icon_size, where Handle::Arrow is a filled triangle; the iced showcase's drop-downs use it.
  • native-theme: docs/platform-facts.md §2.10 states the progress bar's border: Breeze strokes groove and contents with a 1.001px pen, the groove in the window text at frameContrast 0.2 (#23262933, dark #fcfcfc33); libadwaita and WinUI draw none. kde-breeze states that colour and a 1px width, adwaita and windows-11 a width of 0; the KDE reader derives the colour from kdeglobals.
  • native-theme: tab.item_gap_px (TabTheme::item_gap), the space between neighbouring tabs, an optional size like toolbar.item_gap: 0 on KDE (QTabBar lays tabs edge to edge), GNOME (GtkNotebook) and Windows (TabView), none on macOS (docs/platform-facts.md §2.11). egui writes it into the tab scope's item_spacing.x; gpui's widgets::TabBar and the iced showcase's tab rows lay their tabs that far apart.
  • native-theme: checkbox.check_mark_stroke_width_px (CheckboxTheme::check_mark_stroke_width), the check mark's line: KDE 2 (Breeze's check pen, PenWidth::Frame * 2), GNOME 2 (libadwaita 1.10.0's check.svg; 1.7–1.9 draw 2.5), none on Windows (a font glyph) and macOS (docs/platform-facts.md §2.5). egui strokes its check in the checkbox scope's fg_stroke, which carries it; gpui's widgets::Checkbox paints gpui-component's own check polyline at that width; the iced showcase paints a tick at it over iced's glyph.
  • native-theme: the expander's structure (docs/platform-facts.md §2.27), KDE's expander being KWidgetsAddons' KCollapsibleGroupBox: expander.arrow_side (a new enum, ArrowSide::Leading / Trailing; KDE and macOS lead, GNOME's AdwExpanderRow and WinUI trail), arrow_gap_px (KDE 9, GNOME 9, Windows 30), content_indent_px (KDE 20, GNOME 0, Windows 16) and frame_enabled (KDE no, GNOME and Windows yes), all optional.
  • native-theme: [text_area] (TextAreaTheme), the multi-line field's padding, which differs from the single-line field's: KDE 5 (Breeze's QTextEdit frame 2 plus QTextDocument's documentMargin 4, less the frame line; measured on a real Breeze QTextEdit), GNOME 0 (GtkTextView), Windows 10 / 6 / 5 / 6 (the same TextBox), none on macOS (docs/platform-facts.md §2.29). Its border's colour, radius, width and shadow inherit input.border's; everything else of a text area is input's.
  • native-theme-egui: text_area_margin and text_area_frame, a multi-line TextEdit's margin and frame from text_area.border, as input_margin and input_frame are the single-line field's.
  • native-theme-egui-widgets: expander::Expander, an expander laid out as expander.arrow_side, arrow_gap, content_indent and frame_enabled state (egui's CollapsingHeader ties the arrow, the title and the body to one indent, always leads with the arrow and frames the header alone); egui's own CollapsingHeader where the theme states none. The egui showcase's Basic page uses it.
  • native-theme-gpui: geometry::text_area, the refinement for a multi-line Input or Textarea from text_area.border: the root padded by the rest of each stated side past the editor padding upstream gives the field in render (a side below it stays upstream's).
  • native-theme-iced: text_area_padding, a TextEditor's padding from text_area.border, iced's own 5 on a side the theme leaves unstated.
  • Showcases: the expanders follow expander.arrow_side, arrow_gap, content_indent and frame_enabled in all three, and the text areas the text area's own padding.
  • native-theme: fonts::substitute_family(family), the family a system without family draws it in: fontconfig's substitute (fc-match) on Linux, None on macOS and Windows, whose fallback has no documented source to follow.
  • native-theme-egui: a theme font family the system lacks is drawn in fonts::substitute_family's substitute, as every native Linux application gets it, instead of egui's own face; Note::FontFamilyUnavailable gains substitute, the family drawn instead.
  • native-theme-gpui: font_family, the family gpui draws a theme family in — the substitute where the system lacks it — behind the new system-fonts feature (default).
  • native-theme-gpui: widgets::Part and widgets::PartBounds: on_part_bounds on Checkbox, Radio, Switch, Slider, ProgressBar and TabBar reports the rectangle each part was painted in.
  • native-theme-egui-widgets: parts::Parts, the rectangles a widget painted its parts in.
  • Showcases: docs/showcase-elements.toml, one list of the elements the three showcases share — chrome and Basic page, each with the theme leaves it draws. Widget Info shows the hovered element from it in one format in all three: its name and state, a row per leaf with the resolved value and one line on how that toolkit applies it, in sidebar.font. --dump-layout FILE writes every listed element's rectangle, --open-menu theme opens the Theme menu for a capture, and scripts/check_showcase_parity.py compares the three showcases' dumps and captures element by element — sizes, positions and sampled colours — failing on any difference docs/showcase-exceptions.toml [parity] does not give a reason for.
  • native-theme-iced: the advanced-shaping feature (default) kerns every text of the application, as Qt, GTK, WinUI and AppKit do: it turns on iced_core's advanced-shaping, which makes Shaping::Advanced the default of every text that sets none, where iced's own default shapes ASCII text with the glyphs' advances alone (Shaping::Auto picks Basic). Cargo builds one iced_core for the application and the connector, so depending on the connector is enough; the README and crate docs say so under Kerning.
  • native-theme-gpui: icon mappings for gpui-component 0.7.0's IconName::Ban, CircleAlert and RefreshCw (Lucide ban, circle-alert, refresh-cw; Material block, error, refresh; freedesktop action-unavailable, emblem-important, view-refresh), and icon_name(IconRole::ActionRefresh) now returns RefreshCw.
  • Showcases (gpui): the Buttons page shows gpui-component's Toolbar with two labelled ToolbarGroups; the Inputs page a TimeField and an Input holding an inline token; every chart states the tooltip and guide line it draws on hover; the icon gallery has gpui-component's 104 icons.

Changed

  • native-theme: defaults.border.opacity is the share of the text colour already folded into every stated border colour — Breeze's frameContrast 0.2, libadwaita's --border-opacity 0.15, WinUI none (docs/platform-facts.md §2.1.6) — and border.color is the final line colour: no connector multiplies a colour by it. native-theme-egui no longer folds it into the strokes of defaults.border.color, which on kde-breeze faded #bcc0bf to 20 %.

  • native-theme: one disabled mechanism per platform, and connectors apply both. A disabled widget is painted in its disabled colours and faded by its disabled_opacity; the data makes the one the platform does not use an identity (docs/platform-facts.md §2.1.6). kde-breeze and windows-11 (and their live presets) state defaults.disabled_opacity = 1.0 (was 0.5 and 0.3): Breeze and WinUI dim by colour alone; so does material (was 0.38), whose disabled colours carry Material 3's per-part 0.12 and 0.38. adwaita states no disabled fills (a None disabled fill is the enabled one) and its enabled text colours as the disabled ones (defaults.disabled_text_color #2e3436 / #ffffff, was #cccccc / #4a4a4e): libadwaita dims by --disabled-opacity 50 % alone. A widget with no disabled_opacity of its own (menu, list, link) fades by the defaults'.

  • native-theme: kde-breeze's disabled colours are Breeze's Disabled palette, computed with KColorScheme 6.30.0 from [ColorEffects:Disabled] (docs/platform-facts.md §2.1.6): text #a0a1a3 / dark #686a6c (was #bcc0bf / #4d545b); button and drop-down #f0f0f0 on #a8a9aa / dark #272a2e on #6d6f72 (dark was #3a3f44 on #4d545b); text field #f3f3f3 on #aaabac / dark #131517 on #606263 (was #f0f0f0, #282c30); checkbox box #f0f0f0 / #272a2e, label #a0a1a3 / #686a6c; menu #a0a1a3 / #686a6c; list #aaabac / #606263; link #a3cae2 / #164160.

  • native-theme: kde-breeze's combo_box.arrow_icon_size_px is 10, Breeze's ArrowSize (renderArrow draws min(w, h, 10)), in the 20px arrow column arrow_area_width states (was 20). docs/platform-facts.md §2.24 records that the drop-down arrow is an open chevron on KDE, GNOME and Windows.

  • native-theme: kde-breeze's progress_bar.fill_color is Breeze's, the accent at alpha 0.7 over the window, #72c2eb / dark #3584ae (KColorUtils::overlayColors, computed with Qt 6.11.2); the KDE reader computes it from kdeglobals in Qt's own arithmetic.

  • native-theme: windows-11's list item padding is 16 left / 12 right, WinUI's DefaultListViewItemStyle Padding="16,0,12,0" (was 12 / 12, ListViewItemExpanded's); the Windows reader agrees.

  • native-theme: docs/platform-facts.md §2.26: GNOME's .card has no CSS border — its outline is a 1px box shadow at 3 % — so its border.color and border.line_width are none.

  • native-theme-egui: a Disabled cell carries its role's disabled_opacity as disabled_alpha (the defaults' for menu, list and link), which egui fades a disabled widget by on top of the disabled colours; it was 1.0. A primary button with no stated disabled fill keeps its own pair, faded.

  • native-theme-egui-widgets: the drop-down's arrow is an open chevron over egui's arrow rectangle, stroked in the state's fg_stroke, where egui fills a triangle; on kde-breeze, with its 10px arrow, the drop-down is combo_box.min_height, 32, tall (it was 34). A widget added to a disabled Ui opens its Disabled scope too. Disabled widgets are faded by their role's disabled_opacity.

  • native-theme-iced: every disabled style multiplies the alpha of each colour it emits by the widget's disabled_opacity (iced has no widget opacity): buttons, links, text fields and editors, checkboxes, togglers and iced_aw selection lists. A disabled checkbox with no stated disabled fill is its enabled box; a disabled class button (primary, danger, …) with none keeps its own pair.

  • native-theme-gpui: widgets::Checkbox, Radio, Switch and Slider fade a disabled control by its disabled_opacity (CheckboxLook, SwitchLook and SliderLook gain opacity); a disabled checkbox with no stated disabled fill is its enabled box. geometry::button_disabled and geometry::input_fill(n, true) carry disabled_opacity as the refinement's opacity, and a disabled field with no stated disabled fill takes its enabled fill (it kept gpui-component's own).

  • native-theme: kde-breeze's checkbox and radio button are Breeze's: a checked indicator is the button colour under the selection colour at Metrics::Blend_Value 0.3 (#c2e4f6, dark #2f5368), outlined in the selection colour, with its mark in the View text colour (#232629, dark #fcfcfc); an unchecked one is outlined in Breeze's separatorColor() (#c6c8c9, dark #4c4e51), and the dark one is filled with the button colour (#292c30). They were a solid accent box with a white mark. The KDE reader computes them from kdeglobals.

  • native-theme: in docs/platform-facts.md §2.5, GNOME's indicator_width is 20 — libadwaita's 14px minimum plus its 3px padding on each side, as GTK sizes it — which the adwaita preset already stated.

  • native-theme: in IconSet::SegoeIcons, ActionSearch, ActionSettings, ActionDelete and ActionPrint are the Segoe Fluent glyphs Search (U+E721), Settings (U+E713), Delete (U+E74D) and Print (U+E749), like the other action roles; they were the full-colour shell stock icons SIID_FIND, SIID_SETTINGS, SIID_DELETE and SIID_PRINTER.

  • Showcases: all three open at 1280 × 720. With --screenshot, or the new --capture for a capture another tool takes, the window opens at that size whatever size the desktop remembers for it, and every capture path fails, with the measured and the expected size, unless the capture is of a window at that size. The macOS screenshot runner's display is switched to 1920 × 1080, which no longer clamps the window to 1024px.

  • native-theme-gpui: on macOS, a family that names the system UI font — "SF Pro", or the name the live reader reports — is drawn as gpui's .SystemUIFont.

  • native-theme-gpui: geometry::tooltip carries tooltip.background_color and tooltip.border.color: gpui-component paints a tooltip with the popover's fill and the window's border, so kde-breeze's #f7f7f7 tooltip was white and adwaita's dark one light.

  • native-theme-iced: button_padding and input_padding add the border's line width to each side the theme states: the theme's padding lies inside the border, while iced lays content out from the widget's edge and paints the border over the padding, so a themed button's or field's content sat one border width closer to the edge than the platform's.

  • Showcases: the iced showcase lays its text out in the theme's line boxes: body text at defaults.line_height and text-role text at the role's line_height (iced's own is 1.3 times the size).

  • Showcases: the gpui showcase sets its section headings in the theme's section-heading role (text_scale.section_heading: size, line height and weight), as the iced showcase does; they were semibold body text (kde-breeze: 16px regular, was 13.33px semibold).

  • native-theme-iced: custom_icon_to_svg_handle and custom_icon_to_image_handle load a provider's system-set icon through FreedesktopLoader, SfSymbolsLoader or SegoeIconsLoader in color; custom_icon_to_image_handle gains that color: Option<Color> parameter, so an SF Symbol or a Segoe glyph arrives in it instead of its fixed black or white.

  • native-theme: the kde-breeze, adwaita and macos-sonoma presets state link.hover_background as transparent: the platforms draw no background under a hovered link (docs/platform-facts.md §2.28 gives none for macOS, KDE and GNOME), and the presets stated the accent at 9% alpha (#3daee918, #3584e418, #007aff18), which the iced showcase painted.

  • Development: an MSRV job in CI (the workspace floor 1.88.0, and the connectors' own floors); the egui connector in every gate that names connectors; the widget-coverage script covers egui and egui_extras; the screenshot pipeline captures the egui showcase; the scripts are named by task group (check_, update_, generate_), and pre-release-check.sh is now scripts/check_release.sh.

  • native-theme: kde-breeze states no toolbar frame (toolbar.border.line_width_px 0, Breeze's ToolBar_FrameWidth, docs/platform-facts.md §2.13); it inherited the default border's 1px.

  • native-theme-iced: combo_box_padding also centres the arrow in combo_box.arrow_area_width (docs/platform-facts.md §2.24).

  • Showcases: the Basic page holds every control all three toolkits draw, in five columns: buttons (with a toggle pair), checkboxes, radio buttons, a drop-down; text inputs (with a focused one), a text area, a slider; switches, a number input, a spinner, a segmented control, a card; typography (caption to display, a link, monospace), a separator, a progress bar, a list; icon buttons and icons, tabs, an expander and a table. The list shows three of its eight rows and the table two rows, the second selected. Where a preset's controls are too wide for five columns the page takes four, or three, counted from the theme alone in all three showcases: the most columns whose width holds combo_box.min_width, the two tabs at tab.min_width, and the page's own control widths, in the content panel less layout.window_margin and the scrollbar.groove_width a scrolling page keeps free (material: four); the fifth column's groups then end the other four. A row of controls wider than its column wraps onto a further line, the drop-down is at least combo_box.min_width wide in all three, and a page taller than its panel scrolls vertically, at rest at the top, never sideways.

  • native-theme-gpui: widgets::TabBar::wrap, tabs that wrap onto a further row where the bar is too narrow, instead of scrolling sideways.

  • native-theme-egui-widgets: segmented_control::SegmentedControl::wrap, segments that wrap onto a further line inside the one outline where the Ui is too narrow.

  • Development: scripts/check_showcase_parity.py takes a colour sample only where it is visible: inside the window and inside every ancestor the element list marks clip = true (the content panel a page scrolls in); a sample elsewhere is counted as "not visible" and left out of the comparison, while geometry is compared from the dumps, which hold off-screen elements too.

  • native-theme: kde-breeze's single-line input pads 7 horizontally and 6 vertically inside its frame line (was 6 / 3): Breeze insets a line edit's contents LineEdit_FrameWidth 6 from its outer edge, the 1px line the outermost of those, and QLineEdit sets its text 2 across and 1 down further in; a real Breeze QLineEdit measured 2026-09-28 agrees (docs/platform-facts.md §2.4). The KDE reader agrees.

  • native-theme: material's outlined text field, text area and drop-down pad 15 inside their 1px outline (the drop-down 15 leading, 11 trailing), where material-web sets their content 16 (and the arrow's 12) from the field's edge and lays the outline over that space (field/internal/_outlined-field.scss, outline-width 1; docs/platform-facts.md §2.4, §2.24, §2.29); they stated 16 and 12, which the connectors draw inside the outline, so the fields were 2px taller and wider than Material's.

  • native-theme-gpui: requires gpui-component and gpui-base 0.7.0 and gpui-pre 0.3.7 (gpui-kit 0.7.0 for the showcase). ThemeColor::chart_grid, new in gpui-component 0.7.0, takes list.grid_color, on the direct and the config path; the native Switch draws the keyboard focus ring while focused, as gpui-component 0.7.0's own switch does; geometry::toolbar sets the height to the content's (at least toolbar.bar_height), which replaces the fixed h_8 of gpui-component's new Toolbar.

  • native-theme-gpui: documented which resize handles the splitter colours reach — groups built with gpui-base's h_resizable / v_resizable, at gpui-base's 1px; not gpui-component's, Settings' divider or the dock's edges, which install gpui-component's own renderer — and that gpui_kit::init must run before the first window opens, or the window's first dialog, sheet or notification panics in gpui-component and its rem stays gpui's default (gpui_kit::open_window in the Quick start).

Fixed

  • native-theme-gpui, native-theme-iced, native-theme-egui-widgets: a disabled switch, check box or radio button on a platform that dims by opacity (GNOME, docs/platform-facts.md §2.1.6) fades as one widget over what lies under it, as libadwaita's filter: Opacity(..) does: its thumb or mark keeps its colour on the track or fill, and the whole fades over the backdrop, the window's defaults.background_color unless the caller names another. Each toolkit faded every part on its own, so the thumb showed through the faded track (adwaita's disabled switch thumb #cbdff7, dark #95a9c2; now #fcfcfd and #909092). gpui's Checkbox, Radio and Switch gain backdrop (CheckboxLook::faded_over, SwitchLook::faded_over); the iced connector gains switch_over, styles::checkbox_over and styles::toggler_over; egui-widgets' Switch and RadioButton gain backdrop, and fade::fade_as_one does the same for egui's own check box.
  • native-theme-egui-widgets: the painted Spinner arc always sweeps 240°, as the iced and gpui spinners do; egui's 240° · sin(t) shrank it to a dot twice a cycle, which a capture could catch — on adwaita, whose icon theme (adwaita-icon-theme 50.0) ships no process-working indicator, so that every connector paints the arc, the egui Basic page's spinner showed as a short tick.
  • Showcases: the egui showcase frames an open menu in popover.border's colour, line width and radius, as the gpui and iced showcases do; it framed it in defaults.border's, so material's menu had an outline Material's has not.
  • Showcases: the egui showcase's toolbar is toolbar.bar_height tall where the theme states one, its layout.container_margin padding inside that height as in the gpui and iced showcases (material: 64, it was 72).
  • native-theme: dropping a GNOME or Budgie theme subscription returns at once instead of waiting for the next portal signal.
  • native-theme-gpui: custom_icon_to_image_source draws a provider's SF Symbols and Segoe glyphs in color; they were black and white whatever color was. The provider's freedesktop icons load through FreedesktopLoader::color too.
  • Showcases (gpui): on gpui-kit 0.7.0, whose dialogs and sheets sit beside the view, the command palette's entries and the keyboard shortcuts work while a dialog or sheet has the focus (the actions are handled by a root plugin around the whole window); the capture pointer shield covers dialogs, menus and popovers, which it never covered.
  • Development: the visual-assets provenance stamp (scripts/update_provenance.sh) and the egui compatibility stamp (scripts/update_compatibility.sh, which now also runs its tests, clippy and docs) cover native-theme-egui-widgets, which the egui showcase draws with; before, a change there left both stamps fresh.
  • Showcases (egui): the theme settings' drop-down rows are truncated to the drop-down's width, the whole text on hover: the icon-theme row naming why the system's theme is unavailable could carry a reader's whole error and widen the popup far past the window, where nothing in it could be clicked.