NewYour coding agent can read the release notes before it upgrades.Set up the MCP server →
crates.io · #2013 most downloaded on crates.io
Minimal 2D graphics library for GUI work
Last release 29 days ago
08 Sep 2026
Ships fairly regularly
a new release about every 5 weeks
Nearly every release is documented
notes for 48 of 48 stable releases
Nothing withdrawn
no release was ever pulled
6 years old
50 releases · first in 2021
One column per quarter.
egui is an easy-to-use immediate mode GUI for Rust that runs on both web and native.
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.
window_title_frame to window_frame when unspecified #8400 by @rustbasicDragValue #8403 by @teddytennantmin_size in TextEdit #8420 by @lucasmerlinColor32::from_rgba_unmultiplied #8427 by @Keith-Cancelegui is an easy-to-use immediate mode GUI for Rust that runs on both web and native.
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.
Sense::drag detecting drags when clicking widget above it #8396 by @lucasmerlinegui is an easy-to-use immediate mode GUI for Rust that runs on both web and native.
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.
Autocomplete, autocorrect and IMEs now work correctly on iOS and android (on eframe web)!
ScreenRecording_08-05-2026.11-48-49_1.MP4You can now reopen closed panels by dragging the handle:
Screen.Recording.2026-08-05.at.11.45.10.movPreviously, when switching themes, the window chrome (OS titlebar), stayed in the OS theme. Now, it syncs with the app theme:
Screen.Recording.2026-08-05.at.11.45.47.movBoxedWidget: dynamically dispatched widgets #8378 by @emilkWidgetText::size #8377 by @emilkLayoutJob::clear #8376 by @emilkegui::Window::title_frame #8353 by @Its-Just-Nansextra_text_line_spacing to control vertical spacing between text lines #8040 by @rustbasicsizing_pass when reopening popup #8315 by @yayModifiers from RawInput and make it a egui::Event #8336 by @lucasmerlinclip_rect_margin #8366 by @emilkTexturesDelta #8356 by @lucasmerlinGrid being widenable but not shrinkable again #8386 by @emilkThis release drastically improves the mobile keyboard experience (when using eframe web). It also adds drag-to-open panels, window chrome theme sync and a lot of small bug fixes and improvements!
Autocomplete, autocorrect and IMEs now work correctly on iOS and android (on eframe web)!
https://github.com/user-attachments/assets/b0aa1084-0755-4e47-a0b3-0ce6890aca85
You can now reopen closed panels by dragging the handle:
https://github.com/user-attachments/assets/e02895c4-248e-4e22-9694-bdfcd9839bfd
Previously, when switching themes, the window chrome (OS titlebar) stayed in the OS theme. Now, it syncs with the app theme:
https://github.com/user-attachments/assets/6b393057-fdfc-431b-b997-744bc183a8ac
BoxedWidget: dynamically dispatched widgets #8378 by @emilkWidgetText::size #8377 by @emilkLayoutJob::clear #8376 by @emilkegui::Window::title_frame #8353 by @Its-Just-Nansextra_text_line_spacing to control vertical spacing between text lines #8040 by @rustbasicsizing_pass when reopening popup #8315 by @yayModifiers from RawInput and make it a egui::Event #8336 by @lucasmerlinclip_rect_margin #8366 by @emilkTexturesDelta #8356 by @lucasmerlinGrid being widenable but not shrinkable again #8386 by @emilkRemove everything that was marked #[deprecated] #8105 by @emilk
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.
Uis to modify widget behavior based on surrounding contextThis release includes a new inspection protocol for egui. It allows reading the accesskit tree of a running app, as well
as sending events to control it. It's implemented via a new InspectionPlugin in the egui_inspection crate.
Eframe includes a new inspection feature. When enabled, you can enable inspection by launching the app with
EGUI_INSPECTION=1. This will cause the app to listen on port 5719.
The first inspection protocol consumer is egui_mcp.
It's a mcp server that allows your agent to see and use
egui apps. It can be used to have the agent use the app, reproduce bugs and verify its changes.
Install it via cargo install --git https://github.com/rerun-io/kittest_inspector egui_mcp and then add it to your
agent via claude mcp add egui egui-mcp.
There is also a plan of adding a general inspection gui using the same protocol, that can e.g. be used to step through
kittest tests frame by frame.
Here is claude using the mcp to try some of the egui demos (sped up by a lot, claude is slow):
Screen.Recording.2026-06-25.at.19.58.20.15s.movegui_inspection protocol and plugin #8234 by @lucasmerlinAs part of css like styling, we've added classes to egui. You can already
use them to e.g. modify widget behavior or styling based on surrounding context.
Add classes to the container:
ui.scope_builder(UiBuilder::new().with_class("my_container"), |ui| {
...
}); In your widget, check if we're in my_container, to e.g. change sizes or colors:
let in_container = ui.stack().iter().any(|s| s.classes.has("my_container")); Today this only works for custom widgets and ui code, but the next step will be a styling system that allows you to modify built
in widget styling based on these classes.
Classes to UiBuilder and some Widgets #7843 by @AdrienZianneIME visuals received an overhaul, they are now indicated by an underline and properly show the cursor during composition:
After-macOS-CMN-small.mp4Classes to UiBuilder and some Widgets #7843 by @AdrienZianneAtomKind::Layout, for nesting AtomLayout #8219 by @lucasmerlinAtomLayout::direction #8221 by @lucasmerlinsubpixel_binning to TextOptions and FontTweak #8072 by @emilkAtoms in Ui::small_button #8159 by @lucasmerlinegui::Window Titlebar #8154 by @lucasmerlinAsId and IdSalt #8184 by @emilkViewportBuilder::with_monitor + ViewportCommand::SetMonitor #8140 by @Le-Syl21egui::Key #8127 by @Le-Syl21AtomLayout::selectable for opt-in text selection #8224 by @akagifreeezLayoutJob::format_at_byte #8244 by @emilkatoms() helpers to get Atoms from widgets #8128 by @Nashvill375owns_ime_events on Memory #7983 by @umajhoharfrust for better kerning and ligatures #8031 by @gcaillyWindow margins and set clip_rect_margin to zero #7725 by @emilkWindow: move only by dragging title bar #8183 by @emilkPanel methods #8192 by @emilkAlphaFromCoverage to FontColorTransferFunction #8201 by @emilkDebug-formatting of Id in debug-builds #8190 by @emilkCharIndex and ByteIndex + bug fixes #8245 by @emilkGetScreenshot inspection request #8248 by @lucasmerlinFontTweak UI #8258 by @emilkFontTweak #8262 by @emilk#[deprecated] #8105 by @emilkimpl Into<f32> arguments #8194 by @emilkGrid #8170 by @lucasmerlinPanel: never overflow available width, nor max_width #8198 by @emilksubpixel_binning to TextOptions and FontTweak #8072 by @emilkLayoutJob::format_at_byte #8244 by @emilkharfrust for better kerning and ligatures #8031 by @gcaillyAlphaFromCoverage to FontColorTransferFunction #8201 by @emilkCharIndex and ByteIndex + bug fixes #8245 by @emilkFontTweak #8262 by @emilkegui is an easy-to-use immediate mode GUI for Rust that runs on both web and native.
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.
wgpu::Surface lifecycle handling #8171 by @grtlrScrollArea::scroll_to_* calls when stick_to_bottom is Active #8033 by @AmmarAbouZoregui is an easy-to-use immediate mode GUI for Rust that runs on both web and native.
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.
Context::is_pointer_over_egui and Context::egui_wants_pointer_input #8081 by @emilkTextEdit #8082 by @lucasmerlinegui is an easy-to-use immediate mode GUI for Rust that runs on both web and native.
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.
…a &mut Ui instead of Context . In eframe we've deprecated App::update replaced it with App::ui (which provides a &mut Ui instead of a &Context ).
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.
skrifaScrollAreasUi as the main entrypointThe font rendering backend was switched from ab_glyph to skrifa + vello_cpu. This enabled us support
font hinting and variations. It also paves the way for more font improvements in the future, like support for color
emojis and adding helpers for variations like RichText::bold.
Font hinting makes text more clear (look at the =):
Screen.Recording.2026-03-26.at.10.49.43.movWe now support setting variable font parameters:
Screen.Recording.2026-03-26.at.11.37.21.mp4(Unfortunately there is currently a bug with variations, meaning changing them live like this won't work in practise.
There is a draft PR to fix it, but it didn't make the release)
Ui, less Contextegui has long had a confusing overlap in responsibilities between Context and Ui.
In particular, you could add panels to either one (or both!).
In this release, we switch from having Context be the main entrypoint, and instead provide whole-app Ui.
In egui we've replaced Context::run with Context::run_ui, and changed viewports to be given a &mut Ui instead of Context.
In eframe we've deprecated App::update replaced it with App::ui (which provides a &mut Ui instead of a &Context).
In addition to this, Ui now derefs to Context, so all code like ui.ctx().input(…) can now be written ui.input(…).
This means you are much less likely to have to use naked Contexts.
Context can still be useful though, since they implement Clone and can be sent to other threads so you can call .request_repaint on them.
Context::run_ui #7736 by @emilkDeref<Target = Context> for Ui #7770 by @emilkApp::update with fn logic and fn ui #7775 by @emilkContext::style to global_style; avoid confusion w/ Ui::style #7772 by @emilkContext to avoid confusion #7773 by @emilkUi instead of Context #7779 by @emilkAs part of the above work, we have unified the panel API.
SidePanel and TopBottomPanel are deprecated, replaced by a single Panel.
Furthermore, it is now deprecated to use panels directly on Context. Use the show_inside functions instead, acting on Uis.
This unification and simplification will make it easier to maintain and improve panels going forward.
Panel to replace SidePanel and TopBottomPanel #5659 by @sharky98Panel directly on a Context #7781 by @emilkCentralPanel::show #7783 by @emilkContext::used_size and Context::available_rect #7788 by @emilkis_scrolling/is_smooth_scrolling util, checking for active scroll action #7669 by @IsseWButton::shortcut_text and right_text #7696 by @emilkScrollArea::content_margin #7722 by @emilkTypedPluginGuard and TypedPluginHandle #7780 by @apekrosViewportInfo::occluded and visible #7948 by @emilkAtom prefix/suffix support to DragValue #7949 by @lucasmerlinAtom::id, align, closure, max_size #7958 by @lucasmerlinDebugOptions::warn_if_rect_changes_id #7984 by @emilkTextEdit Atom prefix/suffix #7587 by @lucasmerlinButton::left_text #7955 by @rustbasicResponse::parent_id #8010 by @lucasmerlinContext::text_edit_focused #8014 by @emilkContext::time #8017 by @emilkUi::is_tooltip #8016 by @emilkUiStack::bg_color #8020 by @emilkegui::IdSet public #8019 by @lucasmerlinaccesskit feature and always depend on accesskit #7701 by @emilkFrameCache::get return a reference instead of cloning the cached value #7834 by @KonaeAkiraGalley::pos_from_layout_cursor pub #7864 by @dionbScrollAreas #8018 by @emilkCentralPanel::show_inside allocates space in parent #7778 by @emilkCentralPanel::show_inside_dyn to round panel_rect #7868 by @ripopovUiBuilder, to avoid wrapping passed in ids with Id::new() #7925 by @lucasmerlintruncate() and similar for os scaling other than 100% #7867 by @RndUsr123TextEdit and LayoutJob alignments #7831 by @RndUsr123horizontal_wrapping row height after using text_edit_multiline #8000 by @optozoraxVisuals::interact_cursor support in Button #7986 by @mango766Galley::pos_from_layout_cursor pub #7864 by @dionbtruncate() and similar for os scaling other than 100% #7867 by @RndUsr123egui is an easy-to-use immediate mode GUI for Rust that runs on both web and native.
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.
. as a word-splitter in text navigation #7741 by @emilkkittest: add drag-and-drop helpers #7690 by @emilkehttp to 0.6.0 #7757 by @jprochazkegui is an easy-to-use immediate mode GUI for Rust that runs on both web and native.
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.
Plugin::on_widget_under_pointer to support widget inspector #7652 by @juancampaResponse::total_drag_delta and PointerState::total_drag_delta #7708 by @emilkComboBox #7658 by @lucasmerlinprofiling::scope compile error when profiling using tracing backend #7646 by @PPakalnsui.response().interact(Sense::click()) being flakey #7713 by @lucasmerlinnative_pixels_per_point is set during app creation #7683 by @emilkDeprecated ImageButton and removed WidgetType::ImageButton #7483 by @Stelios-Kourlis
Highlights from this release:
egui::Plugin a improved way to create and access egui pluginsAs a step towards using parley for font rendering, @valadaptive has refactored the font loading and rendering code. A result of this (next to the font rendering code being much nicer now) is improved kerning. Notice how the c moved away from the k:
egui::Plugin traitWe've added a new trait-based plugin api, meant to replace Context::on_begin_pass and Context::on_end_pass.
This makes it a lot easier to handle state in your plugins. Instead of having to write to egui memory it can live right on your plugin struct.
The trait based api also makes easier to add new hooks that plugins can use. In addition to on_begin_pass and on_end_pass, the Plugin trait now has a input_hook and output_hook which you can use to inspect / modify the RawInput / FullOutput.
At rerun we have a ton of snapshots. Some PRs will change most of them (e.g. the one that updated egui and introduced the kerning improvements, ~500 snapshots changed!). If you really want to look at every changed snapshot it better be as efficient as possible, and the experience on github, fiddeling with the sliders, is kind of frustrating. In order to fix this, we've made kitdiff. You can use it locally via
kitdiff files . will search for .new.png and .diff.png fileskitdiff git will compare the current files to the default branch (main/master)
Or in the browser viahttps://rerun-io.github.io/kitdiff/?url=<link_to_pr_or_artifact>To install kitdiff run cargo install --git https://github.com/rerun-io/kitdiff
Here is a video showing the kerning changes in kitdiff (try it yourself):
https://github.com/user-attachments/assets/74640af1-09ba-435a-9d0c-2cbeee140c8f
egui::Mutex now has a timeout as a simple deadlock detection
egui::Mutex in some place where it's held for longer than a single frame, you should switch to the std mutex or parking_lot instead (egui mutexes are wrappers around parking lot)screen_rect is deprecated
viewport_rect and content_rect.screen_rect to content_rect, unless you are sure that you want to draw outside the safe area (which would mean your Ui may be covered by notches, system ui, etc.)Ui::take_available_space() helper function, which sets the Ui's minimum size to the available space #7573 by @IsseWUiBuilder::global_scope and UiBuilder::id #7372 by @Icekeyemath::fast_midpoint #7435 by @emilkhex_color macro const #7444 by @YgorSouzaSurrenderFocusOn option #7471 by @lucasmerlinMemory::move_focus #7476 by @darkwaterviewport::WindowLevel and dependents #7432 by @lkdmImageButton and removed WidgetType::ImageButton #7483 by @Stelios-KourlisUi #7386 by @lucasmerlindeadlock_detection feature #7497 by @lucasmerlinPlatformOutput #7523 by @emilklog feature #7583 by @emilkclippy::iter_over_hash_type lint #7421 by @emilkdeadlock_detection feature #7497 by @lucasmerlin0.0 if font not found in glyph_width instead of panic #7559 by @lucasmerlinlog feature #7583 by @emilkPreserve text format in truncated label tooltip #7514 #7535 by @lucasmerlin
TextEdit's in RTL layouts #5547 by @zakarumychFix: SubMenu should not display when ui is disabled #7428 by @ozwaldorf
SubMenu should not display when ui is disabled #7428 by @ozwaldorfUi::place, to place widgets without changing the cursor #7359 by @lucasmerlinAdd ComboBox::popup_style #7360 by @lucasmerlin
ComboBox::popup_style #7360 by @lucasmerlinPopup not closing #7383 by @lucasmerlinWidgetText::Text ignoring fallback font and overrides #7361 by @lucasmerlinoverride_text_color priority #7439 by @YgorSouzaThe 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 depre…
This is a big egui release, with several exciting new features!
Let's dive in!
egui::Atom is the new, indivisible building blocks of egui (hence their name).
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 Atoms. 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:
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:
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
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.
AtomLayout, abstracting layouting within widgets #5830 by @lucasmerlinGalley::intrinsic_size and use it in AtomLayout #7146 by @lucasmerlinIntroduces 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 Windows, Collapsibles, Modals and Popups from within. To use this for your own containers, call UiBuilder::closable and then check for closing within that ui via ui.should_close().
Popup and Tooltip, unifying the previous behaviours #5713 by @lucasmerlinUi::close and Response::should_close #5729 by @lucasmerlinegui::Popup #5716 by @lucasmerlinPopup API for the color picker button #7137 by @lucasmerlinMemory::keep_popup_open isn't called #5814 by @juancampaMemory::popup API in favor of new Popup API #7317 by @emilkYou can render SVG in egui with
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.
Image::paint_at pixel-perfect crisp for SVG images #7078 by @emilkNon-SVG icons are also rendered better, and text sharpness has been improved, especially in light mode.
We have some silently breaking changes (code compiles fine but behavior changed) that require special care:
ui.close_menu() calls from button click handlers since they are obsoletePopupCloseBehavior: // 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 using SubMenuButton, but by default it should be passed to any submenus when using MenuButton.Memory::is_popup_open api now requires calls to Memory::keep_popup_openkeep_popup_open is not called.Popup api which handles this for you.keep_popup_open: 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(...)
}
Label::show_tooltip_when_elided #5710 by @brycebergerUi::allocate_new_ui in favor of Ui::scope_builder #5764 by @lucasmerlinexpand_bg to customize size of text background #5365 by @MeGaGiGaGonTextBuffer for layouter in TextEdit instead of &str #5712 by @kernelkindSlider::update_while_editing(bool) API #5978 by @mbernatScene::drag_pan_buttons option. Allows specifying which pointer buttons pan the scene by dragging #5892 by @mitchmindtreeScene::sense to customize how Scene responds to user input #5893 by @mitchmindtreeTextEdit arrow navigation to handle Unicode graphemes #5812 by @MStarhaScrollArea improvements for user configurability #5443 by @MStarhaResponse::clicked_with_open_in_background #7093 by @emilkModifiers::matches_any #7123 by @emilkContext::format_modifiers #7125 by @emilkOperatingSystem::is_mac #7122 by @emilkContext::current_pass_index #7276 by @emilkContext::cumulative_frame_nr #7278 by @emilkVisuals::text_edit_bg_color #7283 by @emilkVisuals::weak_text_alpha and weak_text_color #7285 by @emilkegui::Sides shrink_left / shrink_right #7295 by @lucasmerlinhint_text in WidgetInfo #5724 by @bircniDefault for ThemePreference #5702 by @MichaelGruppavailable_rect docs with the new reality after #4590 #5701 by @podusowskiViewport positioning #5715 by @aspiringLichSizeHint #7079 by @emilkInputOptions #7121 by @emilkButton inherits the alt_text of the Image in it, if any #7136 by @emilkTooltip slightly #7151 by @emilkui.disable() to modify opacity #7282 by @emilkBitOr and BitOrAssign for Rect #7319 by @lucasmerlinSelectableLabel #7277 by @lucasmerlinScene: make scene_rect full size on reset #5801 by @graydenshandScene: TextEdit selection when placed in a Scene #5791 by @karhuScene: Set transform layer before calling user content #5884 by @mitchmindtreeTextShape underline width #5865 by @emilkconsume_key #7134 by @lucasmerlinemoji-icon-font with fix for fullwidth latin characters #7067 by @emilkScrollArea #5286 by @gilbertoalexsantosResponse::clicked_elsewhere not returning true sometimes #5798 by @lucasmerlinDragValue expansion when editing #5809 by @MStarhaDragValue eating focus, causing focus to reset #5826 by @KonaeAkiraavailable_space #6900 by @lucasmerlinleading_space sometimes being ignored during paragraph splitting #7031 by @afishhhComboBox::from_id_source #7055 by @aelmizebend_pass is called for all loaders #7072 by @emilkdebug_assert triggered by menu/intersect_ray #7299 by @emilkRect::area to return zero for negative rectangles #7305 by @emilkWidgetText smaller and faster #6903 by @lucasmerlinexpand_bg to customize size of text background #5365 by @MeGaGiGaGonGalley::intrinsic_size #7146 by @lucasmerlinemoji-icon-font with fix for fullwidth latin characters #7067 by @emilkTextShape underline width #5865 by @emilkvisual_bounding_rect for rotated text #7050 by @pmarksFix sizing bug in TextEdit::singleline #5640 by @IaVashik
This release adds the Scene container to egui. It is a pannable, zoomable canvas that can contain Widgets and child Uis. This will make it easier to e
This release adds the Scene container to egui. It is a pannable, zoomable canvas that can contain Widgets and child Uis.
This will make it easier to e.g. implement a graph editor.
The tessellator has been updated for improved rendering quality and better performance. It will produce fewer vertices
and shapes will have less overdraw. We've also defined what CornerRadius (previously Rounding) means.
We've also added a tessellator test to the demo app, where you can play around with different values to see what's produced:
https://github.com/user-attachments/assets/adf55e3b-fb48-4df0-aaa2-150ee3163684
Check the PR for more details.
CornerRadius, Margin, Shadow size reductionIn order to pave the path for more complex and customizable styling solutions, we've reduced the size of
CornerRadius, Margin and Shadow values to i8 and u8.
StrokeKind to all your Painter::rect calls #5648StrokeKind::default was removed, since the 'normal' value depends on the context #5658
StrokeKind::Inside when drawing rectanglesStrokeKind::Middle when drawing open pathsRounding to CornerRadius #5673CornerRadius, Margin and Shadow have been updated to use i8 and u8 #5563, #5567, #5568
as i8 / as u8 or as _ if you want Rust to infer the type
f32 value is bigger than 127 it will be clamped to 127RectShape parameters changed #5565
Frame now takes the Stroke width into account for its sizing, so check all views of your app to make sure they still look right.
Read the PR for more info.egui::Scene for panning/zooming a Ui #5505 by @grtlrOutputCommand for copying text and opening URL:s #5532 by @emilkContext::copy_image #5533 by @emilkWidgetType::Image and Image::alt_text #5534 by @lucasmerlinepaint::Brush for controlling RectShape texturing #5565 by @emilknohash_hasher::IsEnabled for Id #5628 by @emilk!, {, } #5548 by @Its-Just-NansRectShape::stroke_kind to control if stroke is inside/outside/centered #5647 by @emilkFrame now includes stroke width as part of padding #5575 by @emilkRounding to CornerRadius #5673 by @emilkStrokeKind when painting rectangles with strokes #5648 by @emilkprofiling crate #5494 by @lucasmerlinArea::compare_order() #5569 by @HactarCEu8 in CornerRadius, and introduce CornerRadiusF32 #5563 by @emilkMargin using i8 to reduce its size #5567 by @emilkShadow by using i8/u8 instead of f32 #5568 by @emilkResponse and Sense #5556 by @polwelepaint::Brush for controlling RectShape texturing #5565 by @emilkRectShape::stroke_kind to control if stroke is inside/outside/centered #5647 by @emilkRounding to CornerRadius #5673 by @emilkStrokeKind when painting rectangles with strokes #5648 by @emilkAdd Modal, a popup that blocks input to the rest of the application (#5358 by @lucasmerlin)
Modal, a popup that blocks input to the rest of the application (#5358 by @lucasmerlin)egui_kittestThis release welcomes a new crate to the family: egui_kittest.
egui_kittest is a testing framework for egui, allowing you to test both automation (simulated clicks and other events),
and also do screenshot testing (useful for regression tests).
egui_kittest is built using kittest, which is a general GUI testing framework that aims to work with any Rust GUI (not just egui!).
kittest uses the accessibility library AccessKit for automatation and to query the widget tree.
kittest and egui_kittest are written by @lucasmerlin.
Here's a quick example of how to use egui_kittest to test a checkbox:
use egui::accesskit::Toggled;
use egui_kittest::{Harness, kittest::Queryable};
fn main() {
let mut checked = false;
let app = |ui: &mut egui::Ui| {
ui.checkbox(&mut checked, "Check me!");
};
let mut harness = egui_kittest::Harness::new_ui(app);
let checkbox = harness.get_by_label("Check me!");
assert_eq!(checkbox.toggled(), Some(Toggled::False));
checkbox.click();
harness.run();
let checkbox = harness.get_by_label("Check me!");
assert_eq!(checkbox.toggled(), Some(Toggled::True));
// You can even render the ui and do image snapshot tests
#[cfg(all(feature = "wgpu", feature = "snapshot"))]
harness.wgpu_snapshot("readme_example");
}
Modal and Memory::set_modal_layer #5358 by @lucasmerlinUiBuilder::layer_id and remove layer_id from Ui::new #5195 by @emilkTextEdit #5203 by @bircniResponse::intrinsic_size for TextEdit #5266 by @lucasmerlinMultiTouchInfo #5247 by @lucasmerlinContext::add_font #5228 by @frederik-uniBox<str> for WidgetText, RichText #5309 by @dimtpapWindow::scroll_bar_visibility #5231 by @ZeenobitComboBox::close_behavior #5305 by @avalschpainter.line() #5291 by @bircniButton::image_tint_follows_text_color #5430 by @emilkContext::layer_transform_to_global & layer_transform_from_global #5465 by @emilkArc to reduce memory consumption #5276 by @StarStarJegui::util::cache to egui::cache; add FramePublisher #5426 by @emilkOrder::PanelResizeLine #5455 by @emilkprofiling crate to support more profiler backends #5150 by @teddemunnikScrollArea drag velocity when drag stopped #5175 by @valadaptiveViewportCommand::Visible #5244 by @rustbasicUi::new_child does not consider the sizing_pass field of UiBuilder #5262 by @zhatuokunWindow::default_pos does not work #5315 by @rustbasicSides did not apply the layout position correctly #5303 by @zhatuokunStyle::override_font_id in RichText #5310 by @MStarhaTextEdit inside a ScrollArea #3660 by @juancampaon_hover_text_at_pointer for transformed layers #5429 by @emilkArea outside its constrain_rect #5459 by @MScottMcBeeui.new_child should now respect disabled #5483 by @emilkArc to reduce memory consumption #5276 by @StarStarJRemove debug-assert triggered by with_layer_id/dnd_drag_source #5191 by @emilk
Deprecated (replaced with UiBuilder):
This release adds initial support for multi-pass layout, which is a tool to circumvent a common limitation of immediate mode.
You can use the new UiBuilder::sizing_pass (#4969) to instruct the Ui and widgets to shrink to their minimum size, then store that size.
Then call the new Context::request_discard (#5059) to discard the visual output and do another pass immediately after the current finishes.
Together, this allows more advanced layouts that is normally not possible in immediate mode.
So far this is only used by egui::Grid to hide the "first-frame jitters" that would sometimes happen before, but 3rd party libraries can also use it to do much more advanced things.
There is also a new UiBuilder for more flexible construction of Uis (#4969).
By specifying a sense for the Ui you can make it respond to clicks and drags, reading the result with the new Ui::response (#5054).
Among other things, you can use this to create buttons that contain arbitrary widgets.
0.29 also adds improve support for automatic switching between light and dark mode.
You can now set up a custom Style for both dark and light mode, and have egui follow the system preference (#4744 #4860).
There also has been several small improvements to the look of egui:
<img width="198" alt="New text selection in light mode" src="https://github.com/user-attachments/assets/bd342946-299c-44ab-bc2d-2aa8ddbca8eb"> <img width="187" alt="New text selection in dark mode" src="https://github.com/user-attachments/assets/352bed32-5150-49b9-a9f9-c7679a0d30b2">
<img width="143" alt="Old text selection in light mode" src="https://github.com/user-attachments/assets/f3cbd798-cfed-4ad4-aa3a-d7480efcfa3c"> <img width="143" alt="Old text selection in dark mode" src="https://github.com/user-attachments/assets/9925d18d-da82-4a44-8a98-ea6857ecc14f">
id_source is now called id_salt everywhere (#5025)Ui::new now takes a UiBuilder (#4969)UiBuilder):
ui.add_visible_uiui.allocate_ui_at_rectui.child_uiui.child_ui_with_id_sourceui.push_stack_infoUiBuilder for building Uis #4969 by @emilkegui::Sides for adding UI on left and right sides #5036 by @emilkUi:s: add UiBuilder::sense and Ui::response #5054 by @lucasmerlinUi::columns_const() #4764 by @v0x0gSlider::max_decimals_opt #4953 by @bircniLabel::halign #4975 by @rustbasicui.shrink_clip_rect #5068 by @emilkScrollArea::scroll_bar_rect #5070 by @emilkOptions::input_options for click-delay etc #4942 by @girtsfWidgetType::RadioGroup #5081 by @bashwith_accessibility_parent #5083 by @bashUi::with_visual_transform #5055 by @lucasmerlinSlider and DragValue compatible with NonZeroUsize etc #5105 by @emilkContext::request_discard for multi-pass layouts #5059 by @emilkFontTweak live #5125 by @emilkResponse::intrinsic_size to enable better layout in 3rd party crates #5082 by @lucasmerlinDebugOptions::show_unaligned #5165 by @emilkSlider::clamping for precise clamp control #5119 by @emilkColor32::from_rgba_unmultiplied with LUT #5088 by @YgorSouzaid_source to id_salt #5025 by @bircniId clashes by seeding auto-ids with child id #4840 by @ironpeakMargin::ui #4873 by @rustbasicscroll_to_* animations configurable #4305 by @lucasmerlinButton to correctly align contained image #4891 by @PrimmRahash re-exports #4979 by @oscargusgenerate-link-to-definition feature on docs.rs #5030 by @GuillaumeGomezMemory methods public #5046 by @bircniui.set_sizing_pass #5074 by @emilkegui::frame #5087 by @simgtlog crate instead of eprintln & remove some unwraps #5010 by @bircniEvent::Copy and Event::Cut behave as if they select the entire text when there is no selection #5115 by @rustbasicTextEdit to fix some bugs #4794 by @rustbasicstep_by #4822 by @AurevoirXavierTextEdit #4889 by @PrimmRTextEdit when clicked #4991 by @ZoxcId clash in Frame styling widget #4967 by @YgorSouzaScrollArea contents from exceeding the container size #5006 by @DouglasDwyerRawInput::take clears all events, like it says it does #5104 by @emilkDragValue range clamping #5118 by @emilkColor32::from_rgba_unmultiplied with LUT #5088 by @YgorSouzaahash re-exports #4979 by @oscargusAdd Image::uri() #4720 by @rustbasic
Style::wrap has been deprecated in favor of Style::wrap_mode
ui.stack() with info about all ancestor Uis, with optional tags #4588 by @abey79, #4617 by @emilkTextEdit #4279 by @emilkwrap/truncate functions on Label/Button/ComboBox no longer take bools as arguments. Use .wrap_mode(…) instead for more fine control (#4556)Style::wrap has been deprecated in favor of Style::wrap_mode (#4556)Ui::new and ui.child_ui now takes a new parameter for the UiStack (#4588)extra_asserts and extra_debug_asserts feature flags have been removed (#4478)Event::Scroll and handle it in egui. Use Event::MouseWheel instead (#4524)Event::Zoom is no longer emitted on ctrl+scroll. Use InputState::smooth_scroll_delta instead (#4524)ui.set_enabled and set_visible have been deprecated (#4614)DragValue::clamp_range renamed to range ((#4728)Rect + Margin, Rect - Margin etc #4277 by @emilkWindow::order #4301 by @alexparlettViewportCommand::RequestCut, RequestCopy and RequestPaste to trigger clipboard actions #4035 by @bu5hm4nnDisplay impl for Vec2, Pos2, and Rect #4428 by @tgross35Options::line_scroll_speed and scroll_zoom_speed #4532 by @emilkTextEdit::hint_text_font #4517 by @zaaarfOptions::reduce_texture_memory to free up RAM #4431 by @varphoneegui::Style #4556 by @abey79Response::show_tooltip_ui and show_tooltip_text #4580 by @emilkopacity and multiply_opacity functions to Ui and Painter #4586 by @emilkKey::Quote #4683 by @mkeeterPopupCloseBehavior #4636 by @Umatrizclamp_to_range option to DragValue, rename clamp_range to range (deprecating the former) #4728 by @WumpfStyle::number_formatter as the default used by DragValue #4740 by @emilkTextEdit an atomic widget #4276 by @emilkfn scroll2 to fn scroll #4282 by @emilkFrame::multiply_with_opacity to multiply in gamma space #4283 by @emilkUis style for popups #4325 by @alexparlettrounding into account when using Slider::trailing_fill #4308 by @rustbasicViewportBuilder::with_icon() documentation #4408 by @roccobluesinclude_image! now accepts expressions #4521 by @YgorSouzaTextEdit::return_key optional #4543 by @doonvComboBox: fix justified layout of popup if wider than parent button #4570 by @emilkArea state public #4576 by @emilkArea size #4749 by @emilkegu::menu types public #4544 by @sor-caArea/Window is now ctx.screen_rect #4590 by @emilkAreas to screen by default #4591 by @emilkGrid: set the sizing_pass flag during the initial sizing pass #4612 by @emilkDragValue and Slider now ignores whitespace #4739 by @emilkdrag_released* #4314 by @sornashex_color! macro by re-exporting color_hex crate from ecolor #4372 by @dataphractUi::allocate_painter to inherit properties from Ui #4343 by @varphonePanel incorrect size #4351 by @zhatuokunEvent::Ime #4358 by @rustbasicScrollArea and Plot when UI is disabled #4457 by @varphoneUi::scroll_with_delta only scrolling if the ScrollArea is focused #4303 by @lucasmerlinResponse::hover_pos returns incorrect positions with layer transforms #4679 by @Creative0708Area::show response #4710 by @emilkWindow scroll bars are at the window edges #4733 by @emilkTextEdit widgets from sending fake primary clicks #4751 by @AliremuRectShape::blur_width to implement shadows #4267 by @emilkRect + Margin, Rect - Margin etc #4277 by @emilkDisplay impl for Vec2, Pos2, and Rect #4428 by @tgross35epaint::util::OrderedFloat to emath::OrderedFloat #4389 by @emilkextra_asserts and extra_debug_asserts feature flags #4478 by @emilkepaint::mutex::RwLock allow ?Sized types #4485 by @crumblingstatuehex_color! macro by re-exporting color_hex crate from ecolor #4372 by @dataphractFix tooltips for non-interactive widgets #4291
TextEdit #4272Response::clicked_elsewhere takes clip rect into account #4274Response::interact_rect for Area/Window #4273ScrollArea #4309 (thanks @lucasmerlin!)Fix visual glitch on the right side of highly rounded rectangles #4244
InputState::any_touches and add InputState::has_touch_screen #4247Context::repaint_causes returning no causes #4248zoom_with_keyboard is false #4262Area or Window #4258The hit test logic (what is the user clicking on?) has been completely rewritten, and should now be much more accurate and helpful. The hit test and i
The hit test logic (what is the user clicking on?) has been completely rewritten, and should now be much more accurate and helpful.
The hit test and interaction logic is run at the start of the frame, using the widgets rects from the previous frame, but the latest mouse coordinates.
It enabled getting a Response for a widget before creating it using Context::read_response.
This will in the future unlock more powerful widget styling options.
The new hit test also allows clicking slightly outside a button and still hit it, improving the support for touch screens.
The menus have also been improved so that they both act and feel better, with no change in API. Included in this is much nicer looking shadows, supporting an offset.
<img width="580" alt="Screenshot 2024-03-26 at 17 00 23" src="https://github.com/emilk/egui/assets/1148717/f1eea39f-17a7-41ca-a983-ee142b04ef26">
Response::clicked* and Response::dragged* may lock the Context, so don't call it from a Context-locking closure.Response::clicked_by will no longer be true if clicked with keyboard. Use Response::clicked instead.Memory::focus has been renamed Memory::focusedArea::new now takes an Id by argument #4115clicked_by #4192Area::sense and improve hit-testing of buttons in menus #4234Shadow with offset, spread, and blur #4232Options::debug_paint_interactive_widgets #4018Ui::set_opacity #3965 (thanks @YgorSouza!)Response::paint_debug_info() to make it easy to visualize a widget's id and state #4056 (thanks @abey79!)ColorImage::from_gray_iter #3536 (thanks @wangxiaochuTHU!)ProgressBar and Spinner #4139 (thanks @DataTriny!)const fn for Margin, Rounding and Shadow #4080 (thanks @0Qwel!)Area an id distinct from the id of what was clicked #4114epaint: Added Shape::{scale,translate} wrappers #4090 (thanks @varphone!)Window can now be resizable in only one direction #4155EllipseShape #4122 (thanks @TheTacBanana!)HeaderResponse #4200 (thanks @Zeenobit!)TextEdit: Change margin property to egui::Margin type #3993 (thanks @bu5hm4nn!)ui.dnd_drop_zone() now returns InnerResponse. #4079 (thanks @sowbug!)Ui #4074ui.scroll_to_cursor etc #4119egui::Window from becoming larger than viewport #4199 (thanks @rustbasic!)Window title bar #3995 (thanks @varphone!)on_disabled_hover_ui respect tooltip_delay #4012 (thanks @YgorSouza!)TextEdit being too short whenever there is horizontal margin #4005 (thanks @gweisert!)Response::interact and Ui:interact_with_hovered #4013Response.interact_pointer_pos is Some on click and drag released #4014Window Frames #4009 (thanks @varphone!)Window frame with a wide border or large rounding #4032 (thanks @varphone!)ScrollArea bugs: leaking scroll target and broken animation to target offset #4174 (thanks @abey79!)Context::parent_viewport_id #4190 (thanks @rustbasic!)RepaintCause::new #4146 (thanks @valsteen!)ColorImage::from_gray_iter #3536 (thanks @wangxiaochuTHU!)Margin, Rounding and Shadow #4080 (thanks @0Qwel!)Shape::{scale,translate} wrappers #4090 (thanks @varphone!)EllipseShape #4122 (thanks @TheTacBanana!)Margin to epaint #4231Shadow with offset, spread, and blur #4232Avoid interacting twice when not required #4041 (thanks @abey79!)
Fix Window title bar incorrect handling spacing #3995 (thanks @varphone!)
Window title bar incorrect handling spacing #3995 (thanks @varphone!)on_disabled_hover_ui respect tooltip_delay #4012 (thanks @YgorSouza!)TextEdit being too short whenever there is horizontal margin #4005 (thanks @gweisert!)Response::interact and Ui:interact_with_hovered #4013Response.interact_pointer_pos is Some on click and drag released #4014Window Frames #4009 (thanks @varphone!)Always set response.hovered to false when dragging another widget #3860
response.hovered to false when dragging another widget #3860InputState::scroll_delta has been replaced by InputState::raw_scroll_delta and InputState::smooth_scroll_delta #3884Response.dragged, drag_started and clicked #3888Response and Memory #3876 (thanks @abey79!)ComboBox: add builder method for height #3001 (thanks @hinto-janai!)?, /, | #3820Response::contains_pointer #3859Align2::anchor_size #3863Context::debug_text #3864Context::on_begin_frame and on_end_frame #3886Frame API to allow picking color until after adding content #3889TextShape #3916 (thanks @StratusFearMe21!)Context::repaint_causes: file:line of what caused a repaint #3949TextureOptions::wrap_mode #3954 (thanks @CodedNil!)Spacing::menu_width #3973Response.context_menu now returns the response of the context menu, if open #3904 (thanks @AufarZakiev!)TextEdit or Label will select text to begin/end #3858stable_dt #3832Response::is_pointer_button_down_on is now false the frame the button is released #3833 (thanks @rustbasic!)request_repaint_after every frame causing immediate repaint #3978Align2::anchor_size #3863TextShape #3916 (thanks @StratusFearMe21!)rayon feature #3934Nothing published for this version
Nothing published for this version
Ignore extra SHIFT and ALT when matching modifiers #3769
Key::PlusEquals with Key::Plus and Key::Equals #3769WidgetTextGalley, WidgetTextJob, RichText::into_text_job, WidgetText::into_text_job #3727TextBuffer::replace to replace_with #3751Color32::PLACEHOLDER with widget fallback color #3727Keys for Cut Copy Paste [ ] , \ : . ; + = #3725 #3373 #3649 #3769 (thanks @MarijnS95 and @mkrueger!)Key::from_name, Key::ALL #3649Event::Key::physical_key #3649Color32::from_hex and Color32::to_hex #3570 #3777 (thanks @YgorSouza!)DragValues for RGB(A) in the color picker #2734 (thanks @IVAN-MK7!)TextEditState undoer #3479 (thanks @LoganDark!)ScrollArea: Add option to always scroll the only enabled direction #3710 (thanks @untbu!)Grid now follows style.visuals.striped if not explicitly overwritten #3723 (thanks @Wcubed!)Window, controlled by Visuals.window_highlight_topmost #3515 (thanks @GuillaumeSchmid!)serde Serialize and Deserialize for KeyboardShortcut #3694 (thanks @zeozeozeo!)Window positioning bug when bad pivot is stored in app data #3721 (thanks @abey79!)Clone for Fonts #3737ResizeDirection::East #3749 (thanks @dbuch!)CompositionEnd without a CompositionStart #3768 (thanks @FrankLeeC!)DragValue when it looses focus #3776Areas now ignore mouse input outside their bounds #3039 (thanks @fleabitdev!)pixels_per_point, not matter how small #3698 (thanks @StarStarJ!)Cmd +) on non-English keyboards #3769Color32::PLACEHOLDER with widget fallback color #3727Clone for Fonts #3737Color32::from_hex and Color32::to_hex #3570 #3777 (thanks @YgorSouza!)Fix buggy text with multiple viewports on monitors with different scales #3666
FontImage::srgba_pixels and reduce the initial font atlas texture size from 8MiB -> 1MiB #3666If you are using eframe, check out the breaking changes in the `eframe` changelog
You can now spawn multiple native windows on supported backends (e.g. eframe), using the new viewport API (#3172).
You can easily zoom any egui app using Cmd+Plus, Cmd+Minus or Cmd+0, just like in a browser (#3608).
Scrollbars are now hidden by default until you hover the ScrollArea (#3539).
zoom_factor #3608Undoer #3478 (thanks @LoganDark!)egui::Vec2b #3543Window size & other size helpers #3537 (thanks @arduano!)RawInput::viewports contains a list of all viewports. Access the current one with ctx.input(|i| i.viewport())ImageButton #3531 (thanks @chriscate!)constraint_to -> constrain_to #3438 (thanks @rinde!)#[inline] to all builder-pattern functions #3557egui::gui_zoom::zoom_with_keyboard_shortcuts is gone, replaced with Options::zoom_with_keyboard, which is true by defaultSpacing::scroll_bar_X has been moved to Spacing::scroll_bar.XContext::set_pixels_per_point now calls Context::set_zoom_level, and it may make sense for you to call that directly insteadeframe, check out the breaking changes in the eframe changelogThere are several changes relevant to integrations.
crate::RawInput::viewports with information about all active viewportsContext::set_request_repaint_callback now points to which viewport should be repaintedContext::run now returns a list of ViewportOutput in FullOutput which should result in their own independent windowsContext::set_immediate_viewport_renderer for setting up the immediate viewport integrationContext::set_embed_viewports(false), or all new viewports will be embedded (the default behavior)This release contains a simple and powerful image API:
This release contains a simple and powerful image API:
// Load from web:
ui.image("https://www.example.com/some_image.png");
// Include image in the binary using `include_bytes`:
ui.image(egui::include_image!("../assets/ferris.svg"));
// With options:
ui.add(
egui::Image::new("file://path/to/image.jpg")
.max_width(200.0)
.rounding(10.0),
);
The API is based on a plugin-system, where you can tell egui how to load the images, and from where.
egui_extras comes with loaders for you, so all you need to do is add the following to your Cargo.toml:
egui_extras = { version = "0.23", features = ["all_loaders"] }
image = { version = "0.24", features = ["jpeg", "png"] } # Add the types you want support for
And this to your code:
egui_extras::install_image_loaders(egui_ctx);
puffin feature to egui #3298trace! macro as this is more useful #3391Context::open_url and Context::copy_text #3380Area::constrain_to and Window::constrain_to #3396Memory::area_rect #3161 (thanks @tosti007!)Margin::expand_rect and shrink_rect #3214into_inner() for egui::mutex::{Mutex, RwLock} #3110 (thanks @KmolYuan!)Option<f32> instead of f32 #3240 (thanks @lucasmerlin!)Window::drag_to_scroll #3118 (thanks @KYovchevski!)CollapsingState::remove to clear stored state #3252 (thanks @dmackdev!)Context::is_context_menu_open() #3267 (thanks @dmlary!)mime field to DroppedFile #3273 (thanks @abey79!)scroll_area::State::velocity #3300 (thanks @Barugon!)Visuals::interact_cursor #3312 (thanks @zkldi!)RichText making it easier to construct layout jobs #3319 (thanks @OmegaJak!)Context::style_mut #3359std::borrow::Cow<'_, str> now implements TextBuffer #3164 (thanks @burtonageo!)DragValue: update value on each key press by default #2880 (thanks @Barugon!)RangeInclusive<f32> with emath::Rangef #3221Send + Sync for ColorPickerFn and Ui (#3148) #3233 (thanks @idanarye!)menu_image_button to use ImageButton builder #3288 (thanks @v-kat!)DragValue when only setting min_decimals #3231ScrollArea #2860 (thanks @Barugon!)ColorImage::from_gray #3166 (thanks @thomaseliot!)into_inner() for egui::mutex::{Mutex, RwLock} #3110 (thanks @KmolYuan!)ClippedShape from struct-enum to a normal struct #3225Galleys get invalidated #3024 (thanks @e00E!)Scroll bar visibility options #2729 (thanks @IVAN-MK7!)
Grid::with_row_color #2519 (thanks @imgurbot12!)Pointer::is_decidedly_dragging and could_any_button_be_click #2979TextEdit #2816 (thanks @wzid!)egui::Modifiers::contains #2989 (thanks @Wumpf!)ComboBox::show_index String with Into<TextWidget> #2790 (thanks @tosti007!)tracing with log #2928Plot::link_axis and Plot::link_cursor now take the name of the group #2410show_blocking_widget #2753 (thanks @YgorSouza!)data() read mutability #2742 (thanks @IS2511!)Response::triple_clicked in docs #2867 (thanks @ccaven!)request_repaint_after works even when called from background thread #2939"Option", not "Alt" #2981 (thanks @Wumpf!)store in TextEditState doc comment #2988 (thanks @fxdave!)enum instead of strings for demo-selector anchor #2781 (thanks @XyLyXyRR!)env_logger in all examples #2934examples/user_attention/README.mg to README.md #2948 (thanks @MAlba124!)epaint without bytemuck dependency #2913 (thanks @lunixbochs!)TextureId::Managed(0) #2998 (thanks @andersk!)Updated to be compatible with a major breaking change in AccessKit that drastically reduces memory usage when accessibility is enabled (#2678).
egui::Context now use closures for locking (#2625):
ctx.input().key_pressed(Key::A) -> ctx.input(|i| i.key_pressed(Key::A))ui.memory().toggle_popup(popup_id) -> ui.memory_mut(|mem| mem.toggle_popup(popup_id))Response::drag_started_by and Response::drag_released_by for convenience, similar to dragged and dragged_by (#2507).PointerState::*_pressed to check if the given button was pressed in this frame (#2507).Event::Key now has a repeat field that is set to true if the event was the result of a key-repeat (#2435).Slider::drag_value_speed, which lets you ask for finer precision when dragging the slider value rather than the actual slider.Memory::any_popup_open, which returns true if any popup is currently open (#2464).Plot::clamp_grid to only show grid where there is data (#2480).ScrollArea::drag_to_scroll if you want to turn off that feature.Response::on_hover_and_drag_cursor.Window::default_open (#2539).ProgressBar::fill if you want to set the fill color manually. (#2618).Button::rounding to enable round buttons (#2616).WidgetVisuals::optional_bg_color - set it to Color32::TRANSPARENT to hide button backgrounds (#2621).Context::screen_rect and Context::set_cursor_icon (#2625).Visuals::indent_has_left_vline (#2636).Response.highlight to highlight a widget (#2632).Separator::grow and Separator::shrink (#2665).Slider::trailing_fill for trailing color behind the circle like a ProgressBar (#2660).Plot.ComboBox is now controlled with Spacing::combo_width (#2621).DragValue and Slider now use the proportional font (#2638).ScrollArea is less aggressive about clipping its contents (#2665).DragValue behavior (#2649, #2650, #2688, #2638).PointerEvent::Released for drags (#2507).TextEdit's multiline flag to AccessKit (#2448).\r (Carriage Return) (#2452).button_padding style option works closer as expected with image+text buttons now (#2510).Window::pivot causing windows to move around (#2694).MSRV (Minimum Supported Rust Version) is now 1.65.0 (#2314).
1.65.0 (#2314).Context::os/Context::set_os to query/set what operating system egui believes it is running on (#2202).Button::shortcut_text for showing keyboard shortcuts in menu buttons (#2202).egui::KeyboardShortcut for showing keyboard shortcuts in menu buttons (#2202).TextureOptions with minification and magnification filters (#2224).Key::Minus and Key::Equals (#2239).egui::gui_zoom module with helpers for scaling the whole GUI of an app (#2239).spacing.menu_margin for customizing menu spacing (#2036)egui::ComboBox (#2272)Area::constrain and Window::constrain which constrains area to the screen bounds (#2270).Area::pivot and Window::pivot which controls what part of the window to position (#2303).panel_fill, window_fill and window_stroke to Visuals for your theming pleasure (#2406).egui::color has been renamed egui::ecolor (#2399).Context::set_pixels_per_point (#2239).DragValue (#2342).ScrollAreas inside each other, the inner area will now move its scroll bar so it is always visible (#2371).input.key_pressed (#2334, #2389).set_pixels_per_point each frame (#2352).ScrollArea::show_rows (#2258).plot::Line::fill (#2275).changed events in radio_value and selectable_value if the value actually changed (#2343).Grid (#2384).ComboBox::width now correctly sets the outer width (#2406).Fonts::has_glyph(s) for querying if a glyph is supported (#2202).ecolor (#2399).Added *_released & *_clicked methods for PointerState (#1582).
*_released & *_clicked methods for PointerState (#1582).PointerButton::Extra1 and PointerButton::Extra2 (#1592).egui::hex_color! to create Color32's from hex strings under the color-hex feature (#1596).deadlock_detection to detect double-lock of mutexes on the same thread (#1619).InputState::stable_dt: a more stable estimate for the delta-time in reactive mode (#1625).egui::Key (#1665).PaintCallback shapes with the WGPU backend (#1684).Context::request_repaint_after (#1694).ctrl-h now acts like backspace in TextEdit (#1812).custom_formatter method for Slider and DragValue (#1851).RawInput::has_focus which backends can set to indicate whether the UI as a whole has the keyboard focus (#1859).PointerState::button_double_clicked() and PointerState::button_triple_clicked() (#1906).custom_formatter, binary, octal, and hexadecimal to DragValue and Slider (#1953)1.61.0 (#1846).PaintCallback shapes now require the whole callback to be put in an Arc<dyn Any> with the value being a backend-specific callback type (#1684).needs_repaint in FullOutput with repaint_after. Used to force repaint after the set duration in reactive mode (#1694).Layout::left_to_right and Layout::right_to_left now takes the vertical align as an argument. Previous default was Align::Center.Vec<[f64; 2]>. The Value and Values types were removed in favor of PlotPoint and PlotPoints respectively (#1816).TextBuffer no longer needs to implement AsRef<str> (#1824).Response::changed for ui.toggle_value (#1573).ImageButton's changing background padding on hover (#1595).Plot auto-bounds bug (#1599).ScrollArea scrolling when editing an unrelated TextEdit (#1779).Slider not always generating events on change (#1854).1.61.0 (#1846).epaint::hex_color! to create Color32's from hex strings under the color-hex feature (#1596).deadlock_detection to detect double-lock of mutexes on the same thread (#1619).TextureOptions with minification and magnification filters (#2224).Change Shape::Callback from &dyn Any to &mut dyn Any to support more backends.
Shape::Callback from &dyn Any to &mut dyn Any to support more backends.Deprecated CollapsingHeader::selectable (#1538).
Shape::Callback for backend-specific painting, with an example (#1351).Frame::canvas (#1362).Context::request_repaint will now wake up UI thread, if integrations has called Context::set_request_repaint_callback (#1366).Plot::allow_scroll, Plot::allow_zoom no longer affects scrolling (#1382).Ui::push_id to resolve id clashes (#1374).ComboBox::icon (#1405).Ui::scroll_with_delta.Frame::outer_margin.Painter::hline and Painter::vline.Link and ui.link (#1506).Plot::x_grid_spacer and Plot::y_grid_spacer for custom grid spacing (#1180).Ui::spinner() shortcut method (#1494).CursorIcons for resizing columns, rows, and the eight cardinal directions.Ui::toggle_value.1.60.0 (#1467).ClippedMesh has been replaced with ClippedPrimitive (#1351).Frame::margin to Frame::inner_margin.AlphaImage to FontImage to discourage any other use for it (#1412).Id clash for Grid, Plot or ScrollArea (#1452).Checkbox and RadioButton with an empty label ("") will now take up much less space (#1456).Memory::top_most_layer with more flexible Memory::layer_ids.convert_bytemuck to bytemuck (#1467).serialize to serde (#1467).Painter::sub_region to Painter::with_clip_rect.ComboBoxes always being rendered left-aligned (#1304).Ui::add_visible sometimes leaving the Ui in a disabled state (#1436).CollapsingHeader::selectable (#1538).single_threaded/multi_threaded flags - egui is now always thread-safe (#1390).1.60.0 (#1467).Shape::Callback for backend-specific painting (#1351).TextWrapping struct containing all wrapping options.LayoutJob::wrap field containing these options.LayoutJob::wrap_width to TextWrapping::max_width.TextWrapping::max_rows to limit amount of rows the text should have.TextWrapping::break_anywhere to control should the text break at appropriate places or not.TextWrapping::overflow_character to specify what character should be used to represent clipped text.single_threaded/multi_threaded flags - epaint is now always thread-safe (#1390).Tessellator::from_options is now Tessellator::new (#1408).TessellationOptions::anti_alias to feathering (#1408).AlphaImage to FontImage to discourage any other use for it (#1412).Shape::Vec containing meshes with differing TextureIds (#1445).Shape::galley_with_color which adds the functionality of Painter::galley_with_color into the Shape enum (#1461).convert_bytemuck to bytemuck (#1467).serialize to serde (#1467).Much improved font selection (#1154):
RichText::size amd RichText::family and the new FontId.Style::text_styles.Ui::text_style_height.TextStyle::resolve.Plot::x_axis_formatter and Plot::y_axis_formatter for custom axis labels (#1130).Plot::allow_boxed_zoom(), Plot::boxed_zoom_pointer() for boxed zooming on plots (#1188).Plot::coordinates_formatter (#1235).plot::LinkedAxisGroup (#1184).Context::load_texture to convert an image into a texture which can be displayed using e.g. ui.image(texture, size) (#1110).Ui::input_mut to modify how subsequent widgets see the InputState and a convenience method InputState::consume_key for shortcuts or hotkeys (#1212).Ui::add_visible and Ui::add_visible_ui.CollapsingHeader::icon to override the default open/close icon using a custom function. (1147).ui.data(), ctx.data(), ctx.options() and ctx.tessellation_options() (#1175).Response::on_hover_text_at_pointer as a convenience akin to Response::on_hover_text (1179).tracing crate for logging warnings (#1192).ui.weak(text).Slider::step_by (1225).Context::move_to_top and Context::top_most_layer for managing the layer on the top (#1242).TextEdit (#1243).Ui::scroll_to_rect (1252).Context::input and Ui::input now locks a mutex. This can lead to a dead-lock is used in an if let binding!
if let Some(pos) = ui.input().pointer.latest_pos() and similar must now be rewritten on two lines.if let .*input.CtxRef to Context (#1050).Context can now be cloned and stored between frames (#1050).Ui::visible to Ui::is_visible.Event::Text into Event::Text and Event::Paste (#1058).Style::body_text_style with more generic Style::text_styles (#1154).TextStyle is no longer Copy (#1154).TextEdit::text_style with TextEdit::font (#1154).Plot::highlight now takes a bool argument (#1159).ScrollArea::show now returns a ScrollAreaOutput, so you might need to add .inner after the call to it (#1166).corner_radius: f32 with rounding: Rounding, allowing per-corner rounding settings (#1206).margin: Vec2 with margin: Margin, allowing for different margins on opposing sides (#1219).Plot::custom_label_func to Plot::label_formatter (#1235).Areas::layer_id_at ignores non-interatable layers (i.e. Tooltips) (#1240).ScrollAreas will not shrink below a certain minimum size, set by min_scrolled_width/min_scrolled_height (1255).Output has now been renamed PlatformOutput and Context::run now returns the new FullOutput (#1292).FontImage has been replaced by TexturesDelta (found in FullOutput), describing what textures were loaded and freed each frame (#1110).RawInput::max_texture_side which should be filled in with e.g. GL_MAX_TEXTURE_SIZE (#1154).Orientation was not public, although fields using this type were (#1130).Context::set_pixels_per_point before the first frame will now work.TextStyle with FontId which lets you pick any font size and font family.Fonts::font_image with font_image_delta for partial font atlas updates.ImageData and TextureManager for loading images into textures (#1110).Shape::dashed_line_many (#1027).corner_radius: f32 with rounding: Rounding, allowing per-corner rounding settings (#1206).Added context menus: See Ui::menu_button and Response::context_menu (#543).
Ui::menu_button and Response::context_menu (#543).Label, Button etc) now supports rich text (#855).TextEdit (#848).Slider::new(…).vertical() (#875).Button::image_and_text (#832).CollapsingHeader::open to control if it is open or collapsed (#1006).egui::widgets::color_picker::color_picker_color32 to show the color picker.1.56.0.ui.add(Button::new("…").text_color(…)) is now ui.button(RichText::new("…").color(…)) (same for Label )(#855).show method that has to be used to add items to and show the plot (#766).menu::menu(ui, ...) is now ui.menu_button(...) (#543)CtxRef::begin_frame and end_frame with CtxRef::run (#872).scroll_delta and zoom_delta in RawInput with Event::Scroll and Event::Zoom.Memory data buckets (data, data_temp, id_data and id_data_temp) into a single Memory::data, with a new interface (#836).Ui::__test with egui::__run_test_ui (#872).ComboBox and other popups getting clipped to parent window (#885).egui::math (use egui::emath instead).egui::paint (use egui::epaint instead).Deprecated: max_rect_finite, available_size_before_wrap_finite and available_rect_before_wrap_finite.
<img src="media/egui-0.15-code-editor.gif">
ScrollArea and Window (opt-in).TextEdit::layouter: Add custom text layout for e.g. syntax highlighting or WYSIWYG.Fonts::layout_job: New text layout engine allowing mixing fonts, colors and styles, with underlining and strikethrough.ui.add_enabled(bool, widget) to easily add a possibly disabled widget.ui.add_enabled_ui(bool, |ui| …) to create a possibly disabled UI section."serialize" separately from "persistence".egui::widgets::global_dark_light_mode_buttons to easily add buttons for switching the egui theme.TextEdit can now be used to show text which can be selected and copied, but not edited.Memory::caches for caching things from one frame to the next.Ui it is in.Hyperlink will now word-wrap just like a Label.Uis must now have a finite max_rect.
max_rect_finite, available_size_before_wrap_finite and available_rect_before_wrap_finite.Painter/Fonts: text layout now expect a color when creating a Galley. You may override that color with Painter::galley_with_color.1.54.0.DragValues no longer show a tooltip when hovered. Change with Style::explanation_tooltips.ScrollArea will auto-shrink to content size unless told otherwise using ScrollArea::auto_shrink.Slider's clamp_to_range is set to true.TextEdit::enabled to TextEdit::interactive.ui.label (and friends) now take impl ToString as argument instead of impl Into<Label>.TextEdit in justified layouts.Button::enabled with ui.add_enabled.Fonts::layout_job: New text layout engine allowing mixing fonts, colors and styles, with underlining and strikethrough.CircleShape, PathShape, RectShape and TextShape used in enum Shape.TextShape)."convert_bytemuck" feature.Panels can now be added to any Ui.
Ui.show_background and show_axes methods to Plot.Grid::num_columns: allow the last column to take up the rest of the space of the parent Ui.RawInput).CollapsingHeader can now optionally be selectable.TextEdit will now clip text that doesn't fit in it, and scroll.Area::show, ComboBox::show_ui, ComboBox::combo_box_with_label, Window::show, popup::*, menu::menu.pixels_per_point is changed.lost_focus for TextEdit.Area.Plot's min_auto_bounds could be ignored after the first call to Plot::ui.More plot items: Arrows, Polygons, Text, Images.
SidePanel::right and Panel::bottom).Panel.ScrollArea::show_rows for efficient scrolling of huge UI:s.ScrollArea::enable_scrolling to allow freezing scrolling when editing TextEdit widgets within itUi::set_visible as a way to hide widgets.Style::override_text_style to easily change the text style of everything in a Ui (or globally).TextStyle on checkboxes, radio buttons and SelectableLabel.cint feature.extra_asserts and extra_debug_asserts to enable additional checks.TextEdit now supports edits on a generic buffer using TextBuffer.Context::set_debug_on_hover and egui::trace!(ui)Curve to Line.TopPanel::top is now TopBottomPanel::top.SidePanel::left no longer takes the default width by argument, but by a builder call.SidePanel::left is resizable by default.Added anchors to windows and areas so you can put a window in e.g. the top right corner.
Label::sense(Sense::click()).Response::request_focus and Response::surrender_focus.TextEdit::code_editor (VERY basic).egui::Memory.Response::on_disabled_hover_text to show tooltip for disabled widgets.eframe web) trackpad-pinch gesture.eframe web on mobile devices,
and should work with egui_glium for certain touch devices/screens.Memory::has_focus public (again).Plot must now be given a name that is unique within its scope.screen_reader option is turned on.ui.wrap to ui.scope.DragValues.egui_demo_libDeprecated combo_box_with_label in favor of new ComboBox.
DragValues.Window and Area to a specified area using drag_bounds(rect).ui.set_row_height.DebugOptions::show_widgets to debug layouting by hovering widgets.ComboBox to more easily customize combo boxes.Slider::new and DragValue::new to replace old type-specific constructors.TextEdit::password to hide input characters.ui.advance_cursor is now called ui.add_space.kb_focus is now just called focus.combo_box_with_label in favor of new ComboBox.Slider and DragValue (Slider::f32, DragValue::usize etc).Added egui::Plot to plot some 2D data.
<img src="media/egui-0.10-plot.gif" width="50%">
egui::plot::Plot to plot some 2D data.Ui::hyperlink_to(label, url)."°" works like a unit).Context::set_pixels_per_point to control the scale of the UI.Response::changed() to query if e.g. a slider was dragged, text was entered or a checkbox was clicked.DragValue and Slider (except 128-bit).Slider will now show the value display by default, unless turned off with .show_value(false).Slider value is now a DragValue which when dragged can pick values outside of the slider range (unless clamp_to_range is set).Added support for secondary and middle mouse buttons.
<img src="media/0.9.0-disabled.gif" width="50%">
Label methods for code, strong, strikethrough, underline and italics.ui.group(|ui| { … }) to visually group some widgets within a frame.Ui helpers for doing manual layout (ui.put, ui.allocate_ui_at_rect and more).ui.set_enabled(false) to disable all widgets in a Ui (grayed out and non-interactive).TextEdit::hint_text for showing a weak hint text when empty.egui::popup::popup_below_widget: show a popup area below another widget.Slider::clamp_to_range(bool): if set, clamp the incoming and outgoing values to the slider range.ui.spacing(), ui.spacing_mut(), ui.visuals(), ui.visuals_mut().ctx.set_visuals().Style::wrap.Grid::max_col_width.\n characters.mouse has been renamed pointer everywhere (to make it clear it includes touches too).Response are now methods, so if ui.button("…").clicked { is now if ui.button("…").clicked() {.Response::active is now gone. You can use response.dragged() or response.clicked() instead.DragValue::range is now called clamp_range and also clamps incoming values.Triangles to Mesh.struct ClippedMesh(Rect, Mesh).Mesh::split_to_u16 now returns a 16-bit indexed Mesh16.Added a simple grid layout (Grid).
<img src="media/widget_gallery_0.8.0.gif" width="50%">
Grid).ui.allocate_at_least and ui.allocate_exact_size.InputState::key_down.Window::current_pos to position a window.PaintCmd to Shape.(Rect, Shape) with tuple-struct ClippedShape."serde" to "persistence".math and paint into separate crates emath and epaint.Image and ImageButton will no longer stretch to fill a justified layout.Your coding agent can read these notes before it upgrades. Set up the MCP server →