* 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.
When using option + arrow keys (Mac) or ctrl + arrow keys (Windows), you
navigate a full word.
Previously egui would ignore `.` in the text, so that `www.example.com`
would be considered a full word.
This is inconsistent with how the rest of macOS works.
With this PR, cursor navigation in `www.example.com` will move the
cursor between the dots.
This makes editing code with egui a lot nicer.
* 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.
<!--
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!
-->
* [x] I have followed the instructions in the PR template
These assertions allows col == COLS, while when col == COLS, array may
be out of bounds. In `fn init`, `for i in 0..COLS {self.insert(...`
confirms the assertions' predicate col <= COLS should be changed into
col < COLS.
---------
Co-authored-by: Emil Ernerfeldt <emil.ernerfeldt@gmail.com>
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 fixes calls to `ui.response().interact(Sense::click())` being
flakey. Since egui checks widget interactions at the beginning of the
frame, based on the responses from last frame, we need to ensure that we
always call `create_widget` on `interact` calls, otherwise there can be
a feedback loop where the `Sense` egui acts on flips back and forth
between frames.
Without the fix in `interact`, both the asserts in the new test fail.
Here is a video where I experienced the bug, showing the sense switching
every frame. Every other click would fail to be detected.
https://github.com/user-attachments/assets/6be7ca0e-b50f-4d30-bf87-bbb80c319f3b
Also note, usually it's better to use `UiBuilder::sense()` to give a Ui
some sense, but sometimes you don't have the flexibility, e.g. in a `Ui`
callback from some code external to your project.
* Closes https://github.com/emilk/egui/issues/5889
See the above issue for motivation.
To use glow instead, disable the default features of `eframe` and opt-in
to `glow`.
This also changes egui.rs to use wgpu, which means WebGPU when
available, and WebGL otherwise
This PR enables users of `egui-wgpu` to render `epaint` primitives
without having to bring in the complete `egui` crate and all it's
dependencies.
---------
Co-authored-by: Emil Ernerfeldt <emil.ernerfeldt@gmail.com>
The double negative of not undefined conflicted with the example given
in parens, This just removes the double negative to agree with the rest
of the doc line. I have *not* audited to see if this ordering actually
is strictly forced elsewhere. (Apologies for the smallest documentation
pull request ever)
* [x] I have followed the instructions in the PR template
Sometimes when moving a window, having a tooltip attached to the mouse
pointer, or scrolling a `ScrollArea`, you would see this disturbing
effect:

This is caused by us rounding many visual elements (lines, rectangles,
text, …) to physical pixels in order to keep them sharp. If the
window/tooltip itself is not rounded to a physical pixel, then you can
get this behavior.
So from now on the position of all
areas/windows/tooltips/popups/ScrollArea gets rounded to the closes
pixel.
* Unlocked by https://github.com/emilk/egui/pull/7709
* Follows https://github.com/emilk/egui/pull/7708
* Related to #202
This fixes a particular issue where resizing a window would move it, and
resizing it back would not restore it.
You can still move a window by resizing it (I didn't focus on that bug
here), but at least now the window will return to its original position
when you move back the mouse.
* Part of https://github.com/emilk/egui/issues/5889
* Closes https://github.com/emilk/egui/issues/7106
This changes the `eframe/wgpu` feature to also enable all the `default`
features of `wgpu` and `egui-wgpu`. This makes switching `eframe`
backend from `glow` to `wgpu` a lot easier.
To get the old behavior (depend on `wgpu` but you must opt-in to all its
features), use the new `wgpu_no_default_features` feature.
Selected text now gets the color of `visuals.selection.stroke.color`.
This means you can have inverted colors for selected text, like in the
new test:
<img width="154" height="46" alt="image"
src="https://github.com/user-attachments/assets/2666361d-d7e2-4d50-8e4d-2fcc128f1a81"
/>
It also means the color of selected text in labels matches that of the
text color of selected buttons.
Changed it to use labeled_by to avoid kittest finding the label when
searching for the ComboBox and also set the value so a screen reader
will know what's selected.
### Problem
Letting go of the modifier key before the last momentum-scroll events
arrive will cause the scroll direction to change. This problem can be
seen by going to egui.rs and opening the "Scene" example. Hold down
shift, start a momentum-scroll (on a Mac trackpad), then quickly let go
of shift: you'll see the scroll direction change, which feels wrong.
### Solution
Store the modifiers at the start of the event, thanks to the new `phase`
info added in
* https://github.com/emilk/egui/pull/7669
Note that this solution only works on native; not on web.
### Other
* Break out wheel/scroll handling into own file
* Simplify it a lot by deciding late on wether an input is a scroll or a
zoom
* Assume input is already smooth if there are `phase` events
<!--
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!
-->
Moves `ends_with_newline` into `PlacedRow` to avoid clones during
layout.
I don't think there was a rationale stronger than "don't change too
much" for not doing this in https://github.com/emilk/egui/pull/5411, so
I should've just done this from the start.
This was a significant part of the profile for text layout (as it cloned
almost every `Row`, even though it only needed to change a single
boolean).
Before:
<img width="757" height="250" alt="image"
src="https://github.com/user-attachments/assets/d1c2afd1-f1ec-4cf5-9d05-f5a5a78052df"
/>
After:
<img width="615" height="249" alt="image"
src="https://github.com/user-attachments/assets/c70966da-c892-4e84-adba-494d0f37f263"
/>
(note that these profiles focus solely on the top-level
`Galley::layout_inline` subtree, also don't compare sample count as the
duration of these tests was completely arbitrary)
egui_demo_lib `*text_layout*` benches:
<img width="791" height="461" alt="image"
src="https://github.com/user-attachments/assets/4f97ce84-2768-4876-9488-d42f8f358ed1"
/>
* [X] I have followed the instructions in the PR template
(As usual, the tests fail for me even on master but the failures on
master and with these changes seem the same :))
This PR adds `Plugin::on_widget_under_pointer` which gets called
whenever a widget is created whose rect contains the pointer.
The point of the hook is to capture a stack trace which can be used to
map widgets to their corresponding source code so it must be called
while the widget is being created. The obvious concern is performance
impact. However, since it's only called for rects under the cursor, the
effect seems negligible afaict. It's under `debug_assertions` just in
case.
This change is needed so we can publish the widget inspector we've been
working on. Basically a plugin that allows us to jump from any widget
back to their corresponding source code.
This video shows the plugin configured to open the corresponding code in
github, but normally it would open your local editor.
Update: [Live demo](https://membrane-io.github.io/egui/) (Firefox/Safari
not yet supported. `Cmd-I` to inspect. `Tab` to cycle filters. `Click`
to open). It will try to open a file under
`/home/runner/work/egui/egui/` so it won't work, but you get the idea.
https://github.com/user-attachments/assets/afe4d6af-7f67-44b5-be25-44f7564d9a3a
## What's next
After this gets merged I plan to publish the above plugin as its own
crate, that way we can iterate and release quickly while things are
still changing. I agree it would make sense to eventually merge it into
the main egui repo (like @emilk suggested in #4650).
* [x] I have followed the instructions in the PR template
---------
Co-authored-by: Emil Ernerfeldt <emil.ernerfeldt@gmail.com>
* Closes#7657
* [x] I have followed the instructions in the PR template
On native this uses a new "touch phase" parameter of the mouse wheel
event to know if a scroll action is done.
---------
Co-authored-by: Emil Ernerfeldt <emil.ernerfeldt@gmail.com>
`arboard` [doesn't support support iOS
yet](https://github.com/1Password/arboard/pull/103), so this PR adds iOS
to the conditions that prevent `arboard` from being enabled.
Launching an app on a physical device results in a long timeout (~8s)
while trying to connect to the X11 server (the timeout is immediate when
launching on a simulator), with the following trace:
```
egui_winit:📋 Failed to initialize arboard clipboard: Unknown error while interacting with the clipboard: X11 server connection timed out because it was unreachable
```
<!--
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!
-->
* [x] I have followed the instructions in the PR template
## Short bluesky announcement:
We just released egui 0.33.0!
Highlights:
- `egui::Plugin` a improved way to create and access egui plugins
- [kitdiff](https://github.com/rerun-io/kitdiff), a viewer for
egui_kittest image snapshots (and a general image diff tool)
- better kerning (check the diff on
[kitdiff](https://rerun-io.github.io/kitdiff/?url=https://github.com/emilk/egui/pull/7431))
https://github.com/user-attachments/assets/971f0493-6dae-42e5-8019-58b74cf5d203
## Relaese Changelog:
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](https://www.rerun.io/), a
startup building an SDK for visualizing streams of multimodal data.
# egui 0.33.0 changelog
Highlights from this release:
- `egui::Plugin` a improved way to create and access egui plugins
- [kitdiff](https://github.com/rerun-io/kitdiff), a viewer for
egui_kittest image snapshots (and a general image diff tool)
- better kerning
### Improved kerning
As a step towards using [parley](https://github.com/linebender/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` trait
We'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`.
### kitdiff, a image diff viewer
At rerun we have a ton of snapshots. Some PRs will change most of them
(e.g. [the](https://github.com/rerun-io/rerun/pull/11253/files)
[one](https://rerun-io.github.io/kitdiff/?url=https://github.com/rerun-io/rerun/pull/11253/files)
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](https://rerun-io.github.io/kitdiff/).
You can use it locally via
- `kitdiff files .` will search for .new.png and .diff.png files
- `kitdiff git` will compare the current files to the default branch
(main/master)
Or in the browser via
- going to https://rerun-io.github.io/kitdiff/ and pasting a PR or
github artifact url
- linking to kitdiff via e.g. a github workflow
`https://rerun-io.github.io/kitdiff/?url=<link_to_pr_or_artefact>`
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://rerun-io.github.io/kitdiff/?url=https://github.com/rerun-io/rerun/pull/11253/files)):
https://github.com/user-attachments/assets/74640af1-09ba-435a-9d0c-2cbeee140c8f
### Migration guide
- `egui::Mutex` now has a timeout as a simple deadlock detection
- If you use a `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
- In order to support safe areas, egui now has `viewport_rect` and
`content_rect`.
- Update all usages of `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.)
Previously, when `rect` was taller than it was wide, the spinner would
render far outside the given rectangle. Now, it always renders inside
the smaller of the two dimensions.
I noticed this when upgrading from 0.30 to 0.32. I have an image that's
significantly taller than it is wide. In 0.32, when the image is
loading, it shows the spinner. Since the spinner radius is determined
solely based on rectangle height, the spinner ends up far too wide and
covers other elements.
* [x] I have followed the instructions in the PR template