eframe has features for selecting between x11 and wayland. eframe does
not forward the features to glutin. This makes glutin always compile
with both backends enabled. This change forwards the feature. This
allows users of egui to compile less dependencies when they only need
one of x11, wayland.
To understand this change, read the glutin Cargo.toml [1] and the glutin
build.rs [2]. You always have to enable glutin's glx feature with the
x11 feature. The other default features (egl, wgl) stay enabled. This is
intentional so that everything continues to work as before. We could
further minimize when egl and wgl are enabled, but that is not part of
this change. There is little reason to do so because those feature
already only add dependencies when you compile glutin for the right
platform (for example wgl on windows).
[1]
https://github.com/rust-windowing/glutin/blob/v0.32.1/glutin/Cargo.toml
[2]
https://github.com/rust-windowing/glutin/blob/v0.32.1/glutin/build.rs
- fixes https://github.com/emilk/egui/issues/5359
For the test I added a `Harness::press_key` function. We should
eventually add these to kittest, probably via a trait one can implement
for the `Harness` but for now this should do.
As someone who uses "grey" instead of "gray", it is annoying that my
autocomplete can never find any of the "gray" color related things, so
this adds doc aliases for that.
* [x] I have followed the instructions in the PR template
The allows us to pass any state to the ui closure. While it is possible
to just store state in the closure itself, accessing that state after
the harness was created to e.g. read or modify it would require interior
mutability. With this change there are new `Harness::new_state`,
`Harness::run_state`, ... methods that allow passing state on each run.
This builds on top of #5301, which should be merged first
---------
Co-authored-by: Emil Ernerfeldt <emil.ernerfeldt@gmail.com>
This adds a `Harness::new_ui`, which accepts a Ui closure and shows the
ui in a central panel. One big benefit is that this allows us to add a
fit_contents method that can run the ui closure with a sizing pass and
resize the "screen" based on the content size.
I also used this to add a snapshot test for the rendering_test at
different scales.
<!--
Please read the "Making a PR" section of
[`CONTRIBUTING.md`](https://github.com/emilk/egui/blob/master/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!
-->
* [X] I have followed the instructions in the PR template
I removed the webp supported URI test given that the webp feature would
have to be enabled. I kept that webp is not supported in the other
tests.
There might need to be an additional warning in the changelog that image
support detection is now stricter.
egui never accesses the `FontDefinitions`' member fields mutably, except
in `fonts_tweak_ui` where it cloned the `FontDefinitions` object anyway.
This patch reduces system memory consumption for shared font
definitions.
And also removes some overhead from copying (e.g. for the per
`pixel_per_points` font atlas)
Also it allows to keep a copy of the font definitions outside of egui.
In my App that uses international fonts:
Before:

New:

Note: If `Arc` is not wanted, then it could ofc be abstracted away.
I know this is quite a breaking change API wise, but would like to hear
your opinion.
<!--
Please read the "Making a PR" section of
[`CONTRIBUTING.md`](https://github.com/emilk/egui/blob/master/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!
-->
The `RawInput::dropped_files` documentation referred to `NativeOptions`,
but the `drag_and_drop` option was moved to `ViewportBuilder` and is now
enabled by default.
Note that drag-and-drop is not *explicitly* enabled by default here, but
rather is enabled by default in winit. We only override winit's default
if the API consumer specifies it. It might be a good idea in general to
provide explicit defaults for everything in `ViewportBuilder` so we're
not relying on winit's behavior, but that's best left for another PR.
* Closes N/A
* [x] I have followed the instructions in the PR template
<!--
Please read the "Making a PR" section of
[`CONTRIBUTING.md`](https://github.com/emilk/egui/blob/master/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!
-->
* [X] I have followed the instructions in the PR template
I am preparing a separate PR that adds support for JXL with `jxl-oxide`,
which is unlikely to be added to the `image` crate anytime soon (more
context will be provided in that PR).
`jxl-oxide` makes use of the
[`array::each_mut`](https://doc.rust-lang.org/stable/std/primitive.array.html#method.each_mut)
API which was stabilized in 1.77, which is the motivation for this MSRV
bump.
Rust 1.77 was officially released to stable on 21 March, 2024.
This adds `egui_kittest::try_image_snapshot_options` and
`egui_kittest::image_snapshot_options`, as well as
`Harness::wgpu_snapshot_options` and
`Harness::try_wgpu_snapshot_options`
* [X] I have followed the instructions in the PR template
When mixing and matching eframe with other wgpu applications
(https://github.com/tracel-ai/burn in my case), it can be helpful to use
an existing wgpu setup to initialize eframe with. This PR changes the
WpuConfiguration (in a non-backwards compat way :/), to either take some
options how to create a wgpu setup, or an existing wgpu setup
(consisting of an instance, adapter, device and queue).
* [x] I have followed the instructions in the PR template
---------
Co-authored-by: Andreas Reich <r_andreas2@web.de>
This is controlled by the `accesskit` feature and nothing needs the
implicit `accesskit_winit` feature, so use `dep:` syntax to prevent it
from being created.
* [x] I have followed the instructions in the PR template
<!--
Please read the "Making a PR" section of
[`CONTRIBUTING.md`](https://github.com/emilk/egui/blob/master/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!
-->
Currently `Style::override_font_id` does not affect widgets with their
`TextStyle` like `Button`s, `ComboBox`es, `CheckBox`es, etc. This PR
fixes this behavior such that all widgets using default configuration of
`RichText` are affected by this setting.
* [x] I have followed the instructions in the PR template
Fix: Window::default_pos does not work
Issues: Since `default_size` is not applied to `area`,
`style.spacing.default_area_size` is applied, causing problems.
* Closes#5314
Exposed the underlying PopupCloseBehavior of ComboBox in order to allow
more control of ComboBox behavior.
This allows ComboBox to be used rather than manually managing a popup
directly, while also gaining the convenience features of ComboBox such
as popup auto-sizing.
* [x] I have followed the instructions in the PR template
`Box<str>` is an immutable heap-allocated string slice.
This PR makes it more convenient to use them in labels for example.
Before this PR
```rust
let text: Box<str> = "Hello".into();
ui.label(text.into_string());
let text_ref: &Box<str> = &"Hello".into();
ui.label(text_ref.clone().into_string());
// or
ui.label(text_ref.as_ref());
// or
ui.label(&**text_ref);
```
After this PR
```rust
let text: Box<str> = "Hello".into();
ui.label(text);
let text_ref: &Box<str> = &"Hello".into();
ui.label(text_ref);
```
* [x] I have followed the instructions in the PR template
When using fonts with an average of 50,000 characters,
'epaint texture atlas overflowed!' may be printed and cause problems.
It is necessary to expand the max value related to texture.
* Closes#5256
---------
Co-authored-by: Emil Ernerfeldt <emil.ernerfeldt@gmail.com>
Previously, all widgets would be listed in accesskit as children of the
toplevel window.
With this change, they will be reported as child of the `egui::Window`
they are in, Which should increase parseability of the ui for
screenreaders and integration tests.
Added an accesskit test to check that it is indeed working.
Co-authored-by: Wybe Westra <w.westra@kwantcontrols.nl>
Since textedit is doing the justify layout calculation itself, we need
to report the original desired_size as intrinsic size, instead of the
value passed to allocate_space.
I wonder though, is it still necessary that the TextEdit does the
justify calculation itself instead of relying on the ui layout to do it?
As far as I understand it, justify should be handled by the
ui.allocate_space call.
make it easier to add fonts.
For example if I want to add a custom FontFamily or if the user wants to
add a Chinese fallback
* [x] I have followed the instructions in the PR template
---------
Co-authored-by: Emil Ernerfeldt <emil.ernerfeldt@gmail.com>
winit::Window::inner_size returns size of safe area on iOS. use
winit::Window::outer_size on iOS
The dimensions of outer_size include the title bar and borders, but as
far as I know there is no way to actually display the title bar or
borders on iOS so it should be fine.
<!--
Please read the "Making a PR" section of
[`CONTRIBUTING.md`](https://github.com/emilk/egui/blob/master/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!
-->
* Closes#3547
* [X] I have followed the instructions in the PR template
---------
Co-authored-by: Emil Ernerfeldt <emil.ernerfeldt@gmail.com>
This shortcut was previously triggering the Undo action due to the
matches_logically method ignoring the state of the Shift key. This was
solved by simply inverting the order of the undo and redo arms, so the
undo is not matched if the shortcut corresponds to redo.
* Closes <https://github.com/emilk/egui/issues/5255>
* [x] I have followed the instructions in the PR template
<!--
Please read the "Making a PR" section of
[`CONTRIBUTING.md`](https://github.com/emilk/egui/blob/master/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!
-->
Run this code
```rs
CentralPanel::default().show(ctx, |ui| {
Sides::new().show(
ui,
|ui| {
ui.label("1");
},
|ui| {
ui.label("2");
},
);
Sides::new().show(
ui,
|ui| {
ui.label("11");
},
|ui| {
ui.label("22");
},
);
Sides::new().show(
ui,
|ui| {
ui.label("111");
},
|ui| {
ui.label("222");
},
);
});
```
Before

After

This should hopefully make it easier for egui contributors and
egui_kittest users to understand the snapshot tests
* [X] I have followed the instructions in the PR template
- closes#3491
- closes#3926
This adds a testing library to egui based on
[kittest](https://github.com/rerun-io/kittest). Kittest is a new
[AccessKit](https://github.com/AccessKit/accesskit/)-based testing
library. The api is inspired by the js
[testing-library](https://testing-library.com/) where the idea is also
to query the dom based on accessibility attributes.
We made kittest with egui in mind but it should work with any rust gui
framework with AccessKit support.
It currently has support for:
- running the egui app, frame by frame
- building the AccessKit tree
- ergonomic queries via kittest
- via e.g. get_by_name, get_by_role
- simulating events based on the accesskit node id
- creating arbitrary events based on Harness::input_mut
- rendering screenshots via wgpu
- snapshot tests with these screenshots
A simple test looks like this:
```rust
fn main() {
let mut checked = false;
let app = |ctx: &Context| {
CentralPanel::default().show(ctx, |ui| {
ui.checkbox(&mut checked, "Check me!");
});
};
let mut harness = Harness::builder().with_size(egui::Vec2::new(200.0, 100.0)).build(app);
let checkbox = harness.get_by_name("Check me!");
assert_eq!(checkbox.toggled(), Some(Toggled::False));
checkbox.click();
harness.run();
let checkbox = harness.get_by_name("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"))]
egui_kittest::image_snapshot(&egui_kittest::wgpu::TestRenderer::new().render(&harness), "readme_example");
}
```
~Since getting wgpu to run in ci is a hassle, I'm taking another shot at
creating a software renderer for egui (ideally without a huge dependency
like skia)~ (this didn't work as well as I hoped and it turns out in CI
you can just run tests on a mac runner which comes with a real GPU)
Here is a example of a failed snapshot test in ci, it will say which
snapshot failed and upload an artifact with the before / after and diff
images:
https://github.com/emilk/egui/actions/runs/11183049487/job/31090724606?pr=5166
* Closes#5224
I'm unfamiliar with wgpu, so I'd like someone to confirm, that calling
`wgpu::Texture` _after_ `wgpu::Queue::submit` is in fact the right thing
to do.
---------
Co-authored-by: Andreas Reich <r_andreas2@web.de>
Fixes#5174.
The drag velocity was not being updated unless the cursor counted as
"dragging", which only happens when it's in motion. This effectively
guarantees that the drag velocity will never be zero, even if the cursor
is not moving, and results in spurious scroll velocity being applied
when the cursor is released.
Instead, we update the velocity only when the drag is stopped, which is
when the kinetic scrolling actually needs to begin. Note that we
immediately *apply* the scroll velocity on the same frame that we first
set it, to avoid a 1-frame gap where the scroll area doesn't move.
I believe that *not* setting `scroll_stuck_to_end` and `offset_target`
when the drag is released is the correct thing to do, as they should
apply immediately once the user stops dragging. Should we maybe clear
the drag velocity instead if `scroll_stuck_to_end` is true or
`offset_target` exists?
* Closes#5174
* [x] I have followed the instructions in the PR template
This adds a new `Ui::unique_id` used in `Ui::response`.
I'll make a follow-up PR where the old `id` is renamed `stable_id`, and
deprecate `fn id` to force users to think through which `id` they want.
* Closes https://github.com/emilk/egui/issues/5190
Since ui's initial sound is a "y", it should be "a ui", not "an ui".
Replaced case-sensitively using regex `([aA])n ([uU][iI])` replacement
`$1 $2`
* [x] I have followed the instructions in the PR template
This will allow disabling the animation that occurs during
`scroll_to_row` calls. Follows the same coding style as the other scroll
options in `TableBuilder`.
---------
Co-authored-by: Emil Ernerfeldt <emil.ernerfeldt@gmail.com>
It cannot be made const with the current version of Rust, and that is
counterintuitive since it does compile-time checks, so we make that
clear in the documentation. It might be possible to make it const once
MSRV is bumped to 1.82.
* See <https://github.com/emilk/egui/issues/5160>
* [x] I have followed the instructions in the PR template
Affects `.on_hover_text(…)` with dynamic content (i.e. content that
changes over time).
* Closes https://github.com/emilk/egui/issues/5167
`.on_hover_ui` with dynamic content can still hit the shrinking problem.
The general solution depends on solving
https://github.com/emilk/egui/issues/5138 but a work-around is to add
this to your tooltips:
```diff
response.on_hover_ui(|ui| {
+ ui.set_max_width(ui.spacing().tooltip_width);
// …
});
```
* Closes https://github.com/emilk/egui/pull/5106
* Closes https://github.com/emilk/egui/issues/5084
Protect against rounding errors in egui layout code.
Say the user asks to wrap at width 200.0.
The text layout wraps, and reports that the final width was 196.0
points.
This than trickles up the `Ui` chain and gets stored as the width for a
tooltip (say).
On the next frame, this is then set as the max width for the tooltip,
and we end up calling the text layout code again, this time with a wrap
width of 196.0.
Except, somewhere in the `Ui` chain with added margins etc, a rounding
error was introduced,
so that we actually set a wrap-width of 195.9997 instead.
Now the text that fit perfectly at 196.0 needs to wrap one word earlier,
and so the text re-wraps and reports a new width of 185.0 points.
And then the cycle continues.
So this PR limits the text wrap-width to be an integer.
Related issues:
* https://github.com/emilk/egui/issues/4927
* https://github.com/emilk/egui/issues/4928
* https://github.com/emilk/egui/issues/5163
---
Pleas test this @rustbasic
A very common usability issue on egui-wgpu callbacks is that `paint`
can't access any data that doesn't strictly outlive the callback
resources' data. E.g. if the callback resources have an `Arc` to some
resource manager, you can't easily pull out resources since you
statically needed to ensure that those resource references outlived the
renderpass, whose lifetime was only constrained to the callback
resources themselves.
Wgpu 22 no longer has this restriction! Its (render/compute-)passes take
care of the lifetime of any passed resource internally. The lifetime
constraint is _still_ opt-out since it protects from a common runtime
error of adding commands/passes on the parent encoder while a previously
created pass wasn't closed yet.
This is not a concern in egui-wgpu since the paint method where we have
to access the render pass doesn't even have access to the encoder!
<!--
Please read the "Making a PR" section of
[`CONTRIBUTING.md`](https://github.com/emilk/egui/blob/master/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!
-->
* [x] I have followed the instructions in the PR template
Adds support for mipmaps in the `glow` backend.
Should be possible to implement for `wgpu` in the future as well, but
requires a custom compute kernel.
<!--
Please read the "Making a PR" section of
[`CONTRIBUTING.md`](https://github.com/emilk/egui/blob/master/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!
-->
* Closes#5053
* [x] I have followed the instructions in the PR template
This fixes#5053 by adding a Sense parameter to UiBuilder, using that in
Context::create_widget, so the Widget is registered with the right Sense
/ focusable. Additionally, I've added a ignore_focus param to
create_widget, so the focus isn't surrendered / reregistered on
Ui::interact_bg.
The example from #5053 now works correctly:
https://github.com/user-attachments/assets/a8a04b5e-7635-4e05-9ed8-e17d64910a35
<details><summary>Updated example code</summary>
<p>
```rust
ui.button("I can focus");
ui.scope_builder(
UiBuilder::new()
.sense(Sense::click())
.id_source("focus_test"),
|ui| {
ui.label("I can focus for a single frame");
let response = ui.interact_bg();
let t = if response.has_focus() {
"has focus"
} else {
"doesn't have focus"
};
ui.label(t);
},
);
ui.button("I can't focus :(");
```
</p>
</details>
---
Also, I've added `Ui::interact_scope` to make it easier to read a Ui's
response in advance, without having to know about the internals of how
the Ui Ids get created.
This makes it really easy to created interactive container elements or
custom buttons, without having to use Galleys or
Painter::add(Shape::Noop) to style based on the interaction.
<details><summary>
Example usage to create a simple button
</summary>
<p>
```rust
use eframe::egui;
use eframe::egui::{Frame, InnerResponse, Label, RichText, UiBuilder, Widget};
use eframe::NativeOptions;
use egui::{CentralPanel, Sense, WidgetInfo};
pub fn main() -> eframe::Result {
eframe::run_simple_native("focus test", NativeOptions::default(), |ctx, _frame| {
CentralPanel::default().show(ctx, |ui| {
ui.button("Regular egui Button");
custom_button(ui, |ui| {
ui.label("Custom Button");
});
if custom_button(ui, |ui| {
ui.label("You can even have buttons inside buttons:");
if ui.button("button inside button").clicked() {
println!("Button inside button clicked!");
}
})
.response
.clicked()
{
println!("Custom button clicked!");
}
});
})
}
fn custom_button<R>(
ui: &mut egui::Ui,
content: impl FnOnce(&mut egui::Ui) -> R,
) -> InnerResponse<R> {
let auto_id = ui.next_auto_id();
ui.skip_ahead_auto_ids(1);
let response = ui.interact_scope(
Sense::click(),
UiBuilder::new().id_source(auto_id),
|ui, response| {
ui.style_mut().interaction.selectable_labels = false;
let visuals = response
.map(|r| ui.style().interact(&r))
.unwrap_or(&ui.visuals().noninteractive());
let text_color = visuals.text_color();
Frame::none()
.fill(visuals.bg_fill)
.stroke(visuals.bg_stroke)
.rounding(visuals.rounding)
.inner_margin(ui.spacing().button_padding)
.show(ui, |ui| {
ui.visuals_mut().override_text_color = Some(text_color);
content(ui)
})
.inner
},
);
response
.response
.widget_info(|| WidgetInfo::new(egui::WidgetType::Button));
response
}
```
</p>
</details>
https://github.com/user-attachments/assets/281bd65f-f616-4621-9764-18fd0d07698b
---------
Co-authored-by: Emil Ernerfeldt <emil.ernerfeldt@gmail.com>
<!--
Please read the "Making a PR" section of
[`CONTRIBUTING.md`](https://github.com/emilk/egui/blob/master/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!
-->
* Closes#5121
* [x] I have followed the instructions in the PR template
This unifies the code paths in `update_texture` somewhat, so that the
texture sampler and bind group are always replaced.
Not sure whether removing and reinserting the texture from and into the
`textures` map, or creating a new bind group, has much of a performance
impact. An alternative, as described in #5121, would be to split the
functionality for updating a texture's data from updating its options,
so that we don't have to unconditionally update the bind group (or do
something like store the options to check if they're changed).
Fix: `Event::Copy` and `Event::Cut` behave as if they select the entire
text when there is no selection.
It's unexpected and disconcerting that this behavior occurs when there
is no selected area.
Fix: panic when dragging window between monitors of different
pixels_per_point
This will continue to help us as we develop `egui`.
I hope you agree with my defense of `panic`.
* Relate #3959
* Relate #4088
* Closes#4178
* Closes#4179
There is also a way to add log if necessary.
```
log::debug!("Anti-panic behavior occurs");
```
---------
Co-authored-by: Emil Ernerfeldt <emil.ernerfeldt@gmail.com>
When using a `DragValue`, there are three common modes of range clamping
that the user may want:
A) no clamping
B) clamping only user input (dragging or editing text), but leave
existing value intact
C) always clamp
The difference between mode B and C is:
```rs
let mut x = 42.0;
ui.add(DragValue::new(&mut x).range(0.0..=1.0));
// What will `x` be here?
```
With this PR, we now can get the three behaviors with:
* A): don't call `.range()` (or use `-Inf..=Inf`)
* B) call `.range()` and `.clamp_existing_to_range(false)`
* C) call `.range()`
## Slider clamping
Slider clamping is slightly different, since a slider always has a
range.
For a slider, there are these three cases to consider:
A) no clamping
B) clamp any value that the user enters, but leave existing values
intact
C) always clamp all values
Out of this, C should probably be the default.
I'm not sure what the best API is for this yet. Maybe an `enum` 🤔
I'll take a pass on that in a future PR.
## Related
* https://github.com/emilk/egui/pull/4728
* https://github.com/emilk/egui/issues/4881
* https://github.com/emilk/egui/pull/4882
Fix for a regression in 0.28
* `App::save` will now be called when the web app is hidden (e.g. goes
to a background tab)
* `App::update` will now be called when the web app is un-hidden (e.g.
becomes the foreground tab)
<!--
Please read the "Making a PR" section of
[`CONTRIBUTING.md`](https://github.com/emilk/egui/blob/master/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!
-->
- I fixed the TODO to use the `log` crate instead of `eprintln`
- Set the rust-version in the `scripts/check.sh` to the same as egui is
on
- I made xtask use anyhow to remove some unwraps
* [x] I have followed the instructions in the PR template
* Closes https://github.com/emilk/egui/issues/4976
* Part of #4378
* Implements parts of #843
### Background
Some widgets (like `Grid` and `Table`) needs to know the width of future
elements in order to properly size themselves. For instance, the width
of the first column of a grid may not be known until all rows of the
grid has been added, at which point it is too late. Therefore these
widgets store sizes from the previous frame. This leads to "first-frame
jitter", were the content is placed in the wrong place for one frame,
before being accurately laid out in subsequent frames.
### What
This PR adds the function `ctx.request_discard` which discards the
visual output and does another _pass_, i.e. calls the whole app UI code
once again (in eframe this means calling `App::update` again). This will
thus discard the shapes produced by the wrongly placed widgets, and
replace it with new shapes. Note that only the visual output is
discarded - all other output events are accumulated.
Calling `ctx.request_discard` should only be done in very rare
circumstances, e.g. when a `Grid` is first shown. Calling it every frame
will mean the UI code will become unnecessarily slow.
Two safe-guards are in place:
* `Options::max_passes` is by default 2, meaning egui will never do more
than 2 passes even if `request_discard` is called on every pass
* If multiple passes is done for multiple frames in a row, a warning
will be printed on the screen in debug builds:

### Breaking changes
A bunch of things that had "frame" in the name now has "pass" in them
instead:
* Functions called `begin_frame` and `end_frame` are now called
`begin_pass` and `end_pass`
* `FrameState` is now `PassState`
* etc
### TODO
* [x] Figure out good names for everything (`ctx.request_discard`)
* [x] Add API to query if we're gonna repeat this frame (to early-out
from expensive rendering)
* [x] Clear up naming confusion (pass vs frame) e.g. for `FrameState`
* [x] Figure out when to call this
* [x] Show warning on screen when there are several frames in a row with
multiple passes
* [x] Document
* [x] Default on or off?
* [x] Change `Context::frame_nr` name/docs
* [x] Rename `Context::begin_frame/end_frame` and deprecate the old ones
* [x] Test with Rerun
* [x] Document breaking changes
Note this will break people depending on eframe or egui-wgpu with
--no-default-features.
I don't know what to do about that to be honest.
* Closes#4914
* [x] I have followed the instructions in the PR template
---------
Co-authored-by: Andreas Reich <r_andreas2@web.de>