Name | Modified | Size | Downloads / Week |
---|---|---|---|
Parent folder | |||
0.32.0 - Atoms, popups, and better SVG support source code.tar.gz | 2025-07-10 | 2.5 MB | |
0.32.0 - Atoms, popups, and better SVG support source code.zip | 2025-07-10 | 2.8 MB | |
README.md | 2025-07-10 | 24.5 kB | |
Totals: 3 Items | 5.4 MB | 2 |
egui is an easy-to-use immediate mode GUI for Rust that runs on both web and native.
Try it now: https://www.egui.rs/
egui development is sponsored by Rerun, a startup building an SDK for visualizing streams of multimodal data.
egui 0.32.0 changelog
This is a big egui release, with several exciting new features!
- Atoms are new layout primitives in egui, for text and images
- Popups, tooltips and menus have undergone a complete rewrite
- Much improved SVG support
- Crisper graphics (especially text!)
Let's dive in!
⚛️ Atoms
egui::Atom
is the new, indivisible building block of egui (hence the name).
It lets you mix images and text in many places where you would previously only be able to add text.
Atoms is the first step towards a more powerful layout engine in egui - more to come!
Right now an Atom
is an enum
that can be either WidgetText
, Image
, or Custom
.
The new AtomLayout
can be used within widgets to do basic layout.
The initial implementation is as minimal as possible, doing just enough to implement what Button
could do before.
There is a new IntoAtoms
trait that works with tuples of Atom
s. Each atom can be customized with the AtomExt
trait
which works on everything that implements Into<Atom>
, so e.g. RichText
or Image
.
So to create a Button
with text and image you can now do:
:::rs
let image = include_image!("my_icon.png").atom_size(Vec2::splat(12.0));
ui.button((image, "Click me!"));
Anywhere you see impl IntoAtoms
you can add any number of images and text, in any order.
As of 0.32, we have ported the Button
, Checkbox
, RadioButton
to use atoms
(meaning they support adding Atoms and are built on top of AtomLayout
).
The Button
implementation is not only more powerful now, but also much simpler, removing ~130 lines of layout math.
In combination with ui.read_response
, custom widgets are really simple now, here is a minimal button implementation:
:::rs
pub struct ALButton<'a> {
al: AtomLayout<'a>,
}
impl<'a> ALButton<'a> {
pub fn new(content: impl IntoAtoms<'a>) -> Self {
Self {
al: AtomLayout::new(content.into_atoms()).sense(Sense::click()),
}
}
}
impl<'a> Widget for ALButton<'a> {
fn ui(mut self, ui: &mut Ui) -> Response {
let Self { al } = self;
let response = ui.ctx().read_response(ui.next_auto_id());
let visuals = response.map_or(&ui.style().visuals.widgets.inactive, |response| {
ui.style().interact(&response)
});
let al = al.frame(
Frame::new()
.inner_margin(ui.style().spacing.button_padding)
.fill(visuals.bg_fill)
.stroke(visuals.bg_stroke)
.corner_radius(visuals.corner_radius),
);
al.show(ui).response
}
}
You can even use Atom::custom
to add custom content to Widgets. Here is a button in a button:
https://github.com/user-attachments/assets/8c649784-dcc5-4979-85f8-e735b9cdd090
:::rs
let custom_button_id = Id::new("custom_button");
let response = Button::new((
Atom::custom(custom_button_id, Vec2::splat(18.0)),
"Look at my mini button!",
))
.atom_ui(ui);
if let Some(rect) = response.rect(custom_button_id) {
ui.put(rect, Button::new("🔎").frame_when_inactive(false));
}
Currently, you need to use atom_ui
to get a AtomResponse
which will have the Rect
to use, but in the future
this could be streamlined, e.g. by adding a AtomKind::Callback
or by passing the Rects back with egui::Response
.
Basing our widgets on AtomLayout
also allowed us to improve Response::intrinsic_size
, which will now report the
correct size even if widgets are truncated. intrinsic_size
is the size that a non-wrapped, non-truncated,
non-justified version of the widget would have, and can be useful in advanced layout
calculations like egui_flex.
Details
- Add
AtomLayout
, abstracting layouting within widgets #5830 by @lucasmerlin - Add
Galley::intrinsic_size
and use it inAtomLayout
#7146 by @lucasmerlin
❕ Improved popups, tooltips, and menus
Introduces a new egui::Popup
api. Checkout the new demo on https://egui.rs:
https://github.com/user-attachments/assets/74e45243-7d05-4fc3-b446-2387e1412c05
We introduced a new RectAlign
helper to align a rect relative to an other rect. The Popup
will by default try to find the best RectAlign
based on the source widgets position (previously submenus would annoyingly overlap if at the edge of the window):
https://github.com/user-attachments/assets/0c5adb6b-8310-4e0a-b936-646bb4ec02f7
Tooltip
and menu
have been rewritten based on the new Popup
api. They are now compatible with each other, meaning you can just show a ui.menu_button()
in any Popup
to get a sub menu. There are now customizable MenuButton
and SubMenuButton
structs, to help with customizing your menu buttons. This means menus now also support PopupCloseBehavior
so you can remove your close_menu
calls from your click handlers!
The old tooltip and popup apis have been ported to the new api so there should be very little breaking changes. The old menu is still around but deprecated. ui.menu_button
etc now open the new menu, if you can't update to the new one immediately you can use the old buttons from the deprecated egui::menu
menu.
We also introduced ui.close()
which closes the nearest container. So you can now conveniently close Window
s, Collapsible
s, Modal
s and Popup
s from within. To use this for your own containers, call UiBuilder::closable
and then check for closing within that ui via ui.should_close()
.
Details
- Add
Popup
andTooltip
, unifying the previous behaviours #5713 by @lucasmerlin - Add
Ui::close
andResponse::should_close
#5729 by @lucasmerlin - ⚠️ Improved menu based on
egui::Popup
#5716 by @lucasmerlin - Add a toggle for the compact menu style #5777 by @s-nie
- Use the new
Popup
API for the color picker button #7137 by @lucasmerlin - ⚠️ Close popup if
Memory::keep_popup_open
isn't called #5814 by @juancampa - Fix tooltips sometimes changing position each frame #7304 by @emilk
- Change popup memory to be per-viewport #6753 by @mkalte666
- Deprecate
Memory::popup
API in favor of newPopup
API #7317 by @emilk
▲ Improved SVG support
You can render SVG in egui with
:::rs
ui.add(egui::Image::new(egui::include_image!("icon.svg"));
(Requires the use of egui_extras
, with the svg
feature enabled and a call to install_image_loaders
).
Previously this would sometimes result in a blurry SVG, epecially if the Image
was set to be dynamically scale based on the size of the Ui
that contained it. Now SVG:s are always pixel-perfect, for truly scalable graphics.
Details
- Support text in SVGs #5979 by @cernec1999
- Fix sometimes blurry SVGs #7071 by @emilk
- Fix incorrect color fringe colors on SVG:s #7069 by @emilk
- Make
Image::paint_at
pixel-perfect crisp for SVG images #7078 by @emilk
✨ Crisper graphics
Non-SVG icons are also rendered better, and text sharpness has been improved, especially in light mode.
Details
- Improve text sharpness #5838 by @emilk
- Improve text rendering in light mode #7290 by @emilk
- Improve texture filtering by doing it in gamma space #7311 by @emilk
- Make text underline and strikethrough pixel perfect crisp #5857 by @emilk
Migration guide
We have some silently breaking changes (code compiles fine but behavior changed) that require special care:
wgpu backend features
- wgpu 25 made the gles and vulkan backends optional
- We missed this, so for now you need to manually opt in to those backends. Add the following to you Cargo.toml
wgpu = "25" # enables the wgpu default features so we get the default backends
Menus close on click by default
- Previously menus would only close on click outside
- Either
- Remove the
ui.close_menu()
calls from button click handlers since they are obsolete - If the menu should stay open on clicks, change the
PopupCloseBehavior
:rs // Change this ui.menu_button("Text", |ui| { /* Menu Content */ }); // To this: MenuButton::new("Text").config( MenuConfig::default().close_behavior(PopupCloseBehavior::CloseOnClickOutside), ).ui(ui, |ui| { /* Menu Content */ });
You can also change the behavior only for a single SubMenu by usingSubMenuButton
, but by default it should be passed to any submenus when usingMenuButton
.
- Remove the
Memory::is_popup_open
api now requires calls to Memory::keep_popup_open
- The popup will immediately close if
keep_popup_open
is not called. - It's recommended to use the new
Popup
api which handles this for you. - If you can't switch to the new api for some reason, update the code to call
keep_popup_open
:rs if ui.memory(|mem| mem.is_popup_open(popup_id)) { ui.memory_mut(|mem| mem.keep_popup_open(popup_id)); // <- add this line let area_response = Area::new(popup_id).show(...) }
⭐ Other improvements
- Add
Label::show_tooltip_when_elided
#5710 by @bryceberger - Deprecate
Ui::allocate_new_ui
in favor ofUi::scope_builder
#5764 by @lucasmerlin - Add
expand_bg
to customize size of text background #5365 by @MeGaGiGaGon - Add assert messages and print bad argument values in asserts #5216 by @bircni
- Use
TextBuffer
forlayouter
inTextEdit
instead of&str
#5712 by @kernelkind - Add a
Slider::update_while_editing(bool)
API #5978 by @mbernat - Add
Scene::drag_pan_buttons
option. Allows specifying which pointer buttons pan the scene by dragging #5892 by @mitchmindtree - Add
Scene::sense
to customize howScene
responds to user input #5893 by @mitchmindtree - Rework
TextEdit
arrow navigation to handle Unicode graphemes #5812 by @MStarha ScrollArea
improvements for user configurability #5443 by @MStarha- Add
Response::clicked_with_open_in_background
#7093 by @emilk - Add
Modifiers::matches_any
#7123 by @emilk - Add
Context::format_modifiers
#7125 by @emilk - Add
OperatingSystem::is_mac
#7122 by @emilk - Support vertical-only scrolling by holding down Alt #7124 by @emilk
- Support for back-button on Android #7073 by @ardocrat
- Select all text in DragValue when gaining focus via keyboard #7107 by @Azkellas
- Add
Context::current_pass_index
#7276 by @emilk - Add
Context::cumulative_frame_nr
#7278 by @emilk - Add
Visuals::text_edit_bg_color
#7283 by @emilk - Add
Visuals::weak_text_alpha
andweak_text_color
#7285 by @emilk - Add support for scrolling via accesskit / kittest #7286 by @lucasmerlin
- Update area struct to allow force resizing #7114 by @blackberryfloat
- Add
egui::Sides
shrink_left
/shrink_right
#7295 by @lucasmerlin - Set intrinsic size for Label #7328 by @lucasmerlin
🔧 Changed
- Raise MSRV to 1.85 #6848 by @torokati44, #7279 by @emilk
- Set
hint_text
inWidgetInfo
#5724 by @bircni - Implement
Default
forThemePreference
#5702 by @MichaelGrupp - Align
available_rect
docs with the new reality after [#4590] #5701 by @podusowski - Clarify platform-specific details for
Viewport
positioning #5715 by @aspiringLich - Simplify the text cursor API #5785 by @valadaptive
- Bump accesskit to 0.19 #7040 by @valadaptive
- Better define the meaning of
SizeHint
#7079 by @emilk - Move all input-related options into
InputOptions
#7121 by @emilk Button
inherits thealt_text
of theImage
in it, if any #7136 by @emilk- Change API of
Tooltip
slightly #7151 by @emilk - Use Rust edition 2024 #7280 by @emilk
- Change
ui.disable()
to modify opacity #7282 by @emilk - Make the font atlas use a color image #7298 by @valadaptive
- Implement
BitOr
andBitOrAssign
forRect
#7319 by @lucasmerlin
🔥 Removed
- Remove things that have been deprecated for over a year #7099 by @emilk
- Remove
SelectableLabel
#7277 by @lucasmerlin
🐛 Fixed
Scene
: makescene_rect
full size on reset #5801 by @graydenshandScene
:TextEdit
selection when placed in aScene
#5791 by @karhuScene
: Set transform layer before calling user content #5884 by @mitchmindtree- Fix: transform
TextShape
underline width #5865 by @emilk - Fix missing repaint after
consume_key
#7134 by @lucasmerlin - Update
emoji-icon-font
with fix for fullwidth latin characters #7067 by @emilk - Mark all keys as released if the app loses focus #5743 by @emilk
- Fix scroll handle extending outside of
ScrollArea
#5286 by @gilbertoalexsantos - Fix
Response::clicked_elsewhere
not returningtrue
sometimes #5798 by @lucasmerlin - Fix kinetic scrolling on touch devices #5778 by @lucasmerlin
- Fix
DragValue
expansion when editing #5809 by @MStarha - Fix disabled
DragValue
eating focus, causing focus to reset #5826 by @KonaeAkira - Fix semi-transparent colors appearing too bright #5824 by @emilk
- Improve drag-to-select text (add margins) #5797 by @hankjordan
- Fix bug in pointer movement detection #5329 by @rustbasic
- Protect against NaN in hit-test code #6851 by @Skgland
- Fix image button panicking with tiny
available_space
#6900 by @lucasmerlin - Fix links and text selection in horizontal_wrapped layout #6905 by @lucasmerlin
- Fix
leading_space
sometimes being ignored during paragraph splitting #7031 by @afishhh - Fix typo in deprecation message for
ComboBox::from_id_source
#7055 by @aelmizeb - Bug fix: make sure
end_pass
is called for all loaders #7072 by @emilk - Report image alt text as text if widget contains no other text #7142 by @lucasmerlin
- Slider: move by at least the next increment when using fixed_decimals #7066 by @0x53A
- Fix crash when using infinite widgets #7296 by @emilk
- Fix
debug_assert
triggered bymenu
/intersect_ray
#7299 by @emilk - Change
Rect::area
to return zero for negative rectangles #7305 by @emilk
🚀 Performance
- Optimize editing long text by caching each paragraph #5411 by @afishhh
- Make
WidgetText
smaller and faster #6903 by @lucasmerlin
eframe 0.32.0 changelog
⭐ Added
- Add pointer events and focus handling for apps run in a Shadow DOM #5627 by @xxvvii
- MacOS: Add
movable_by_window_background
option to viewport #5412 by @jim-ec - Add macOS-specific
has_shadow
andwith_has_shadow
to ViewportBuilder #6850 by @gaelanmcmillan - Add external eventloop support #6750 by @wpbrown
🔧 Changed
- Update MSRV to 1.85 #7279 by @emilk
- Use Rust edition 2024 #7280 by @emilk
- Rename
should_propagate_event
and addshould_prevent_default
#5779 by @th0rex - Clarify platform-specific details for
Viewport
positioning #5715 by @aspiringLich - Enhance stability on Windows #5723 by @rustbasic
- Set
web-sys
min version to0.3.73
#5862 by @wareya - Bump
ron
to0.10.1
#6861 by @torokati44 - Disallow
accesskit
on Android NativeActivity, makinghello_android
working again #6855 by @podusowski - Respect and detect
prefers-color-scheme: no-preference
#7293 by @emilk
🐛 Fixed
- Mark all keys as up if the app loses focus #5743 by @emilk
- Fix text input on Android #5759 by @StratusFearMe21
- Fix text distortion on mobile devices/browsers with
glow
backend #6893 by @wareya - Workaround libpng crash on macOS by not creating
NSImage
from png data #7252 by @Wumpf - Fix incorrect window sizes for non-resizable windows on Wayland #7103 by @GoldsteinE
- Web: only consume copy/cut events if the canvas has focus #7270 by @emilk