* Closes https://github.com/emilk/egui/issues/5605
It has been zero by default for a few months now, and I do not wish to
support it. It was always an ugly hack, and it is no longer needed.
We had a ton of issues around `TexturesDelta` that weren't properly
applied because we early-out of some function:
* https://github.com/emilk/egui/pull/8313
* https://github.com/emilk/egui/pull/8250
* https://github.com/emilk/egui/pull/8279
This PR changes texture updates, so that we always store them after
taking them out of `FullOutput` and keep the delta around until it's
actually applied (by passing &mut refs and draining instead of
iterating). So even if we add a new early return somewhere, that can't
break texture updates.
It also optimizes `TexturesDelta::append` by dropping any previous
deltas if there's a new `whole` delta or a `free`.
It also adds a debug assert that any `TexturesDelta` is empty when
dropped, as an additional safeguard in case the bug sneaks back in.
---------
Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
The three methods for showing a `Panel` are now:
* `panel.show`: always show the panel.
* `panel.show_collapsible`: show or hide the panel, with a slide
animation in between.
* `Panel::show_switched`: animate between two different panels: a
thin/collapsed one and a thick/expanded one.
* Closes https://github.com/emilk/egui/pull/7254
You can now drag-to-close a panel. Also drag-to-expand panels.
This is a breaking change: the animated panel functions now take a
`open: &mut bool` instead of `open: bool`.
This is only enabled for resizable panels
* Part of https://github.com/emilk/egui/issues/8180
So far, you've been able to move any `egui::Window` by dragging anywhere
on it. This makes sense on touch screens with thick fingers, but less so
on non-touch-screens.
With this PR, you can now control it with a new enum `WindowDrag`
A couple improvements to centered and right-aligned text edits:
- Fix text selection in centered and right aligned text edits
(ironically, this broke in #8076)
- Fix cursor movement in centered and right aligned text edits
(horizontal cursor position will be retained on vertical movement)
- Multiline text edit exceeding available width if there are atoms
- Added atoms & alignment options to text edit demo
- Improve how vertical_align and horizontal_align are applied
- Textedit atom is grow now, removing the need for the extra seperate
grow atom
- This allows us to apply the `align` on the text edit atom instead of
the whole AtomLayout
- Fixes https://github.com/emilk/egui/pull/8022
- Fixes https://github.com/emilk/egui/issues/7999
As shown in the commit, this is exactly what it contains. There was a
redundant and seemingly meaningless `.clone()` in `about.rs`, which I
removed. Was it because the function signature of `Image::new()` was
different in older versions of egui?
Co-authored-by: EtherealPsyche <EtherealPsyche@users.noreply.github.com>
<!--
Please read the "Making a PR" section of
[`CONTRIBUTING.md`](https://github.com/emilk/egui/blob/main/CONTRIBUTING.md)
before opening a Pull Request!
* Keep your PR:s small and focused.
* The PR title is what ends up in the changelog, so make it descriptive!
* If applicable, add a screenshot or gif.
* If it is a non-trivial addition, consider adding a demo for it to
`egui_demo_lib`, or a new example.
* Do NOT open PR:s from your `master` branch, as that makes it hard for
maintainers to test and add commits to your PR.
* Remember to run `cargo fmt` and `cargo clippy`.
* Open the PR as a draft until you have self-reviewed it and run
`./scripts/check.sh`.
* When you have addressed a PR comment, mark it as resolved.
Please be patient! I will review your PR, but my time is limited!
-->
Added the ability to rotate rectangles and ellipses. Similar to the
existing text implementation
* [x ] I have followed the instructions in the PR template
Following this MR https://github.com/emilk/egui/pull/7375
Without Syntect, the urrent theme selector is
`global_theme_preference_buttons`. It should be the dark_theme variable
of the local CodeTheme - same as syntect
Tested with
```sh
cargo run
# and
cargo run --features syntect
```
* [x] I have followed the instructions in the PR template
thanks for this amazing library!
* Part of https://github.com/emilk/egui/issues/5113
* Part of https://github.com/emilk/egui/issues/3524
## What
This deprecates `eframe::App::update` and replaces it with two new
functions:
```rs
pub trait App {
/// Called just before `ui`, and in the future this will
/// also be called for background apps when needed.
fn logic(&mut self, ctx: &egui::Context, frame: &mut Frame) { }
/// Show your user interface to the user.
fn ui(&mut self, ui: &mut egui::Ui, frame: &mut Frame);
…
}
```
Similarly, `Context::run` is deprecated in favor of `Context::run_ui`.
`Plugin`s are now handed a `Ui` instead of just a `Context` in
`on_begin/end_frame`.
## TODO
…either in this PR or a later one
* [x] Deprecate `App::update`
* [x] Deprecate `Context::run`
* [x] Change plugins to get a `Ui`
* [x] Update kittest
* [x] Change viewports to get UI:s (`show_viewport_immediate` etc)
- https://github.com/emilk/egui/pull/7779
## Later PRs
* [ ] Deprecate `Panel::show`
* [ ] Deprecate `CentralPanel::show`
* [ ] Deprecate `CentralPanel` ?
* Part of https://github.com/emilk/egui/issues/3524
This is a breaking change, as it changes the how embedded viewports
work.
Before it was up to the user to display a `egui::Window` if they wanted.
Now egui creates an `egui::Window` for you, so you only need to add the
contents.
To signal this change in behavior, `ViewportClass::Embedded` is gone and
is now called `ViewportClass::EmbeddedWindow`.
* Closes https://github.com/emilk/egui/issues/7647
This collects SnapshotResults within the Harness and adds a check to
enforce snapshot results are merged in case multiple Harnesses are
constructed within a test.
This should make snapshot updates via kitdiff/accept_snapshots.sh way
more useful since it should now always update all snapshots instead of
only the first one per test.
* Part of https://github.com/emilk/egui/issues/3524
Adds `Context::run_ui` as a convenience wrapper around `Context::run`.
This on the path to deprecate `run` and use a top-level `Ui` as the
entry-point for all of egui.
We're phasing out top-level panels (panels that use `Context` directly,
instead of being inside another `Ui`).
As a first step, stop using them in our demo library and application.
* Part of https://github.com/emilk/egui/issues/3524
This combines `SidePanel` and `TopBottomPanel` into a single `Panel`.
The old types are still there as type aliases, but are deprecated.
`.min_width(…)` etc are now called `.min_size(…)` etc.
Again, the old names are still there, but deprecated.
(edited by @emilk)
---------
Co-authored-by: Emil Ernerfeldt <emil.ernerfeldt@gmail.com>
This PR is a continuation of #4915 by @frederik-uni and @lucasmerlin
that introduces support for keeping egui content within the 'safe area'
on iOS (avoiding the notch / dynamic island / menu bar etc.), with the
following changes:
- `SafeArea` now wraps `MarginF32` and has been renamed to
`SafeAreaInsets` to clarify its purpose.
- `InputState::screen_rect` is now marked as deprecated in favour of
either `viewport_rect` (which contains the entire screen), or
`content_rect` (which is the viewport rect with the safe area insets
removed).
- I added some comments to the safe area insets logic pointing out the
[safe area API coming in winit
v0.31](https://github.com/rust-windowing/winit/issues/3910).
---------
Co-authored-by: frederik-uni <147479464+frederik-uni@users.noreply.github.com>
Co-authored-by: Lucas Meurer <hi@lucasmerlin.me>
Co-authored-by: Emil Ernerfeldt <emil.ernerfeldt@gmail.com>
* Closes https://github.com/rerun-io/rerun/issues/11301
This fixes a bug where a menu could get stuck, not closing at all, when
the currently open submenu stops being shown.
I also added a way to reproduce this to the demo, as well as a test
ensuring that there is no race condition in the fix.
<!--
Please read the "Making a PR" section of
[`CONTRIBUTING.md`](https://github.com/emilk/egui/blob/main/CONTRIBUTING.md)
before opening a Pull Request!
* Keep your PR:s small and focused.
* The PR title is what ends up in the changelog, so make it descriptive!
* If applicable, add a screenshot or gif.
* If it is a non-trivial addition, consider adding a demo for it to
`egui_demo_lib`, or a new example.
* Do NOT open PR:s from your `master` branch, as that makes it hard for
maintainers to test and add commits to your PR.
* Remember to run `cargo fmt` and `cargo clippy`.
* Open the PR as a draft until you have self-reviewed it and run
`./scripts/check.sh`.
* When you have addressed a PR comment, mark it as resolved.
Please be patient! I will review your PR, but my time is limited!
-->
Adds a check for `ui.is_enabled()` when displaying the SubMenu items.
There were a few places the condition could be placed, but I figured
there was simplest. The inner button will already not be able to be
clicked due to ui being disabled.
cc @lucasmerlin
* [x] I have followed the instructions in the PR template
---------
Co-authored-by: Emil Ernerfeldt <emil.ernerfeldt@gmail.com>
Fixes manually created popups (via `Popup::new`) not closing, since
widget_clicked_elsewhere was always false.
This example would never close:
```rs
let mut open = true;
eframe::run_simple_native("My egui App", options, move |ctx, _frame| {
egui::CentralPanel::default().show(ctx, |ui| {
let response = egui::Popup::new(
Id::new("popup"),
ctx.clone(),
PopupAnchor::Position(Pos2::new(10.0, 10.0)),
LayerId::new(Order::Foreground, Id::new("popup")),
)
.open(open)
.show(|ui| {
ui.label("This is a popup!");
ui.label("You can put anything in here.");
});
if let Some(response) = response {
if response.response.should_close() {
open = false;
}
}
});
})
```
I also noticed that the Color submenu in the popups example had a double
arrow (must have been broken in the atoms PR):
<img width="248" height="110" alt="Screenshot 2025-08-07 at 13 42 28"
src="https://github.com/user-attachments/assets/a4e0c267-ae71-4b2c-a1f0-f53f9662d026"
/>
Also fixed this in the PR.
* Closes #7037
* Closes#7297
This deprecates all popup-related function in `Memory`, replacing them
with the new `egui::Popup`.
The new API is nicer in all ways, so we should encourage people to use
it.
* part of https://github.com/emilk/egui/issues/7264
* removes SelectableLabel (Use `Button::selectable` instead)
* updates `Ui::selectable_value/label` with IntoAtoms support
Had to make some changes to `Button` since the SelecatbleLabel had no
frame unless selected.
I thought about this - so we have two options here:
1. adding it to `SnapshotOptions`
2. adding it to every function which I do not like as this would be a
huge breaking change
## Summary
This pull request introduces a new feature to the `SnapshotOptions`
struct in the `egui_kittest` crate, allowing users to specify a
permissible percentage of pixel differences (`diff_percentage`) before a
snapshot comparison is considered a failure. This feature provides more
flexibility in handling minor visual discrepancies during snapshot
testing.
### Additions to `SnapshotOptions`:
* Added a new field `diff_percentage` of type `Option<f64>` to the
`SnapshotOptions` struct. This field allows users to define a tolerance
for pixel differences, with a default value of `None` (interpreted as 0%
tolerance).
* Updated the `Default` implementation of `SnapshotOptions` to
initialize `diff_percentage` to `None`.
### Integration into snapshot comparison logic:
* Updated the `try_image_snapshot_options` function to handle the new
`diff_percentage` field. If a `diff_percentage` is specified, the
function calculates the percentage of differing pixels and allows the
snapshot to pass if the difference is within the specified tolerance.
[[1]](diffhunk://#diff-6f481b5866b82a4fe126b7df2e6c9669040c79d1d200d76b87f376de5dec5065R204)
[[2]](diffhunk://#diff-6f481b5866b82a4fe126b7df2e6c9669040c79d1d200d76b87f376de5dec5065R294-R301)
* Closes <https://github.com/emilk/egui/issues/5683>
* [x] I have followed the instructions in the PR template
---------
Co-authored-by: lucasmerlin <hi@lucasmerlin.me>
Co-authored-by: Emil Ernerfeldt <emil.ernerfeldt@gmail.com>