0.20 has a bunch of bugs that will be fixed by:
* https://github.com/gfx-rs/wgpu/pull/5681
At Rerun, we don't want to wait for the wgpu 0.20.1 patch release before
we update egui, so we will temporarily downgrade to wgpu 0.19
After reverting I'll open a new PR that will update to 0.20 again, with
the intention of merging that once 0.20.1 is released.
<!--
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 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!
-->
Related to #3482
Not sure what the "best practice" is, to me it seems like one should
import from "the original location" if possible, but now it should at
least be possible to not re-export ahash without any breakage in the
egui code base (but possibly in projects using egui, so one should
probably deprecate it if one would like to go that path). It also seems
like epaint re-exports ahash.
<!--
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 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!
-->
Inspired by:
44d65f41ac/Cargo.toml (L65)
I took the liberty of removing that comment since I *think* that I got
all "relevant" ones (showing up more than once, sort of).
updates the wgpu version to 0.20 and changes the API calls accordingly.
I had to update wasm-bindgen to "0.2.92". Otherwise, I got this error
for the demo app:
```
error: failed to select a version for `wasm-bindgen`.
... required by package `js-sys v0.3.69`
... which satisfies dependency `js-sys = "^0.3.69"` of package `eframe v0.27.2 (/home/user/Projects/egui/crates/eframe)`
... which satisfies path dependency `eframe` (locked to 0.27.2) of package `confirm_exit v0.1.0 (/home/user/Projects/egui/examples/confirm_exit)`
versions that meet the requirements `^0.2.92` are: 0.2.92
all possible versions conflict with previously selected packages.
previously selected package `wasm-bindgen v0.2.90`
... which satisfies dependency `wasm-bindgen = "=0.2.90"` of package `egui_demo_app v0.27.2 (/home/user/Projects/egui/crates/egui_demo_app)`
failed to select a version for `wasm-bindgen` which could resolve this conflict
```
Why is it locked to this version right now?
I ran the tests, checked the web demo and my own projects, and
everything seems to work fine with wgpu 0.20.
---------
Co-authored-by: Andreas Reich <r_andreas2@web.de>
<!--
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.
* 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 add commits to your PR.
* Remember to run `cargo fmt` and `cargo cranky`.
* 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!
-->
`glyphon` requires the screen resolution during the `prepare` stage, and
passing that to the callback's `prepare` function seems pretty trivial.
---------
Co-authored-by: Emil Ernerfeldt <emil.ernerfeldt@gmail.com>
Exposes support in both glow and wgpu for texture wrap modes
This would be breaking for manual creations of TextureOptions but would
work with the current TextureOptions::NEAREST and LINEAR without change,
keeping those clamp to edge
I wasn't sure how best to expose the options to the user and added
consts for LINEAR_REPEAT LINEAR_MIRRORED_REPEAT NEAREST_REPEAT
NEAREST_MIRRORED_REPEAT
This does not include wrap mode clamp to border as it worked fine with
glow but with wgpu it panics due to Features
Features(ADDRESS_MODE_CLAMP_TO_BORDER) are required but not enabled on
the device, and I thought it was probably best not to try to enable that
feature, but happy to include that functionality also if that is okay to
be toggled

---------
Co-authored-by: Emil Ernerfeldt <emil.ernerfeldt@gmail.com>
* Closes https://github.com/emilk/egui/issues/3941
Workspace dependencies can be annoying.
If you don't set them to `default-features=false`, then you cannot opt
out of their default features anywhere else, and get warnings if you
try.
So you set `default-features=false`, and then you need to manually opt
in to the default features everywhere else.
Or, as in my case, don't.
I don't have the energy to do this tonight, so I'll just revert.
This should help slightly with CPU/GPU parallelism when vsync is on.
I also return the time spent on vsync, which can help users figure out
how much CPU wall-time was used on non-vsync stuff
This makes all `wgpu` features opt-in for `egui-wgpu` users.
For `eframe`, I opted to enable some `wgpu` features so users can still
use `eframe` without having to also opt-in to extra ewgpu features
(eframe is batteries-included).
Setting `desired_maximum_frame_latency` to a low value should
theoretically lead to lower latency in winit apps using `egui-wgpu`
(e.g. in `eframe` with `wgpu` backend).
* Replaces https://github.com/emilk/egui/pull/3714
* See also https://github.com/gfx-rs/wgpu/pull/4899
----
It seems like `desired_maximum_frame_latency` has no effect on my Mac. I
lowered my monitor refresh-rate to 30Hz to test, and can see no
difference between `desired_maximum_frame_latency` of `0` or `3`.
Before when experimenting with changing the global `DESIRED_NUM_FRAMES`
in `wgpu` I saw a huge difference, so I wonder what has changed.
I verified that `set_maximum_drawable_count` is being called with either
`1` or `2`, but I perceive no difference between the two.
<!--
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.
* 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 add commits to your PR.
* Remember to run `cargo fmt` and `cargo cranky`.
* 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#3759
Compiled changelog below:
- On X11, fix Xft.dpi reload during runtime.
- On X11, fix window minimize.
- On Web, fix context menu not being disabled by
with_prevent_default(true).
- On Wayland, fix WindowEvent::Destroyed not being delivered after
destroying window.
- Fix EventLoopExtRunOnDemand::run_on_demand not working for consequent
invocation
- On macOS, remove spurious error logging when handling Fn.
- On X11, fix an issue where floating point data from the server is
- misinterpreted during a drag and drop operation.
- On X11, fix a bug where focusing the window would panic.
- On macOS, fix refresh_rate_millihertz.
- On Wayland, disable Client Side Decorations when wl_subcompositor is
not supported.
- On X11, fix Xft.dpi detection from Xresources.
- On Windows, fix consecutive calls to
window.set_fullscreen(Some(Fullscreen::Borderless(None))) resulting in
losing previous window state when eventually exiting fullscreen using
window.set_fullscreen(None).
- On Wayland, fix resize being sent on focus change.
- On Windows, fix set_ime_cursor_area.
Useful when debugging, e.g. if the default choice is one of many, and
perhaps the other ones would be better.
**EDIT**: Oh, `enumerate_adapters` doesn't work on web… will fix.
* Fixes https://github.com/rerun-io/rerun/issues/4297
* tested against a very hasty and incomplete port of egui/trunk, found
[here](https://github.com/rerun-io/rerun/tree/andreas/experimental-egui-trunk)
In rare cases in can happen that the viewport returned by
`PaintCallbackInfo` is outside the bounds of the screen.
for at least [wgpu/webgpu in
particular](https://www.w3.org/TR/webgpu/#dom-gpurenderpassencoder-setviewport)
this is invalid usage, other backends might be affected as well.
Since this happened due to a float rounding error (in one repro case I
had I got (width==1126.5625) + (offset=715.4376) = 1842.0001 for a
resolution of 1842) I decided to do away with fractional values on the
viewport alltogether. They _technically_ make sense since a viewport is
only specifying the NDC to pixel coordinate conversion, but practically
this may lead to surprising sub-sampling issues.
---------
Co-authored-by: Emil Ernerfeldt <emil.ernerfeldt@gmail.com>
Introduced in the recent multi-viewports work, we accidentally recreated
the wgpu surfaces every frame. This is now fixed.
I found this while improving the profiling of `eframe`
* Closes#1044
---
(new PR description written by @emilk)
## Overview
This PR introduces the concept of `Viewports`, which on the native
eframe backend corresponds to native OS windows.
You can spawn a new viewport using `Context::show_viewport` and
`Cotext::show_viewport_immediate`.
These needs to be called every frame the viewport should be visible.
This is implemented by the native `eframe` backend, but not the web one.
## Viewport classes
The viewports form a tree of parent-child relationships.
There are different classes of viewports.
### Root vieport
The root viewport is the original viewport, and cannot be closed without
closing the application.
### Deferred viewports
These are created with `Context::show_viewport`.
Deferred viewports take a closure that is called by the integration at a
later time, perhaps multiple times.
Deferred viewports are repainted independenantly of the parent viewport.
This means communication with them need to done via channels, or
`Arc/Mutex`.
This is the most performant type of child viewport, though a bit more
cumbersome to work with compared to immediate viewports.
### Immediate viewports
These are created with `Context::show_viewport_immediate`.
Immediate viewports take a `FnOnce` closure, similar to other egui
functions, and is called immediately. This makes communication with them
much simpler than with deferred viewports, but this simplicity comes at
a cost: whenever tha parent viewports needs to be repainted, so will the
child viewport, and vice versa. This means that if you have `N`
viewports you are poentially doing `N` times as much CPU work. However,
if all your viewports are showing animations, and thus are repainting
constantly anyway, this doesn't matter.
In short: immediate viewports are simpler to use, but can waste a lot of
CPU time.
### Embedded viewports
These are not real, independenant viewports, but is a fallback mode for
when the integration does not support real viewports. In your callback
is called with `ViewportClass::Embedded` it means you need to create an
`egui::Window` to wrap your ui in, which will then be embedded in the
parent viewport, unable to escape it.
## Using the viewports
Only one viewport is active at any one time, identified wth
`Context::viewport_id`.
You can send commands to other viewports using
`Context::send_viewport_command_to`.
There is an example in
<https://github.com/emilk/egui/tree/master/examples/multiple_viewports/src/main.rs>.
## For integrations
There are several changes relevant to integrations.
* There is a [`crate::RawInput::viewport`] with information about the
current viewport.
* The repaint callback set by `Context::set_request_repaint_callback`
now points to which viewport should be repainted.
* `Context::run` now returns a list of viewports in `FullOutput` which
should result in their own independant windows
* There is a new `Context::set_immediate_viewport_renderer` for setting
up the immediate viewport integration
* If you support viewports, you need to call
`Context::set_embed_viewports(false)`, or all new viewports will be
embedded (the default behavior).
## Future work
* Make it easy to wrap child viewports in the same chrome as
`egui::Window`
* Automatically show embedded viewports using `egui::Window`
* Use the new `ViewportBuilder` in `eframe::NativeOptions`
* Automatically position new viewport windows (they currently cover each
other)
* Add a `Context` method for listing all existing viewports
Find more at https://github.com/emilk/egui/issues/3556
---
<details>
<summary>
Outdated PR description by @konkitoman
</summary>
## Inspiration
- Godot because the app always work desktop or single_window because of
embedding
- Dear ImGui viewport system
## What is a Viewport
A Viewport is a egui isolated component!
Can be used by the egui integration to create native windows!
When you create a Viewport is possible that the backend do not supports
that!
So you need to check if the Viewport was created or you are in the
normal egui context!
This is how you can do that:
```rust
if ctx.viewport_id() != ctx.parent_viewport_id() {
// In here you add the code for the viewport context, like
egui::CentralPanel::default().show(ctx, |ui|{
ui.label("This is in a native window!");
});
}else{
// In here you add the code for when viewport cannot be created!
// You cannot use CentralPanel in here because you will override the app CentralPanel
egui::Window::new("Virtual Viewport").show(ctx, |ui|{
ui.label("This is without a native window!\nThis is in a embedded viewport");
});
}
```
This PR do not support for drag and drop between Viewports!
After this PR is accepted i will begin work to intregrate the Viewport
system in `egui::Window`!
The `egui::Window` i want to behave the same on desktop and web
The `egui::Window` will be like Godot Window
## Changes and new
These are only public structs and functions!
<details>
<summary>
## New
</summary>
- `egui::ViewportId`
- `egui::ViewportBuilder`
This is like winit WindowBuilder
- `egui::ViewportCommand`
With this you can set any winit property on a viewport, when is a native
window!
- `egui::Context::new`
- `egui::Context::create_viewport`
- `egui::Context::create_viewport_sync`
- `egui::Context::viewport_id`
- `egui::Context::parent_viewport_id`
- `egui::Context::viewport_id_pair`
- `egui::Context::set_render_sync_callback`
- `egui::Context::is_desktop`
- `egui::Context::force_embedding`
- `egui::Context::set_force_embedding`
- `egui::Context::viewport_command`
- `egui::Context::send_viewport_command_to`
- `egui::Context::input_for`
- `egui::Context::input_mut_for`
- `egui::Context::frame_nr_for`
- `egui::Context::request_repaint_for`
- `egui::Context::request_repaint_after_for`
- `egui::Context::requested_repaint_last_frame`
- `egui::Context::requested_repaint_last_frame_for`
- `egui::Context::requested_repaint`
- `egui::Context::requested_repaint_for`
- `egui::Context::inner_rect`
- `egui::Context::outer_rect`
- `egui::InputState::inner_rect`
- `egui::InputState::outer_rect`
- `egui::WindowEvent`
</details>
<details>
<summary>
## Changes
</summary>
- `egui::Context::run`
Now needs the viewport that we want to render!
- `egui::Context::begin_frame`
Now needs the viewport that we want to render!
- `egui::Context::tessellate`
Now needs the viewport that we want to render!
- `egui::FullOutput`
```diff
- repaint_after
+ viewports
+ viewport_commands
```
- `egui::RawInput`
```diff
+ inner_rect
+ outer_rect
```
- `egui::Event`
```diff
+ WindowEvent
```
</details>
### Async Viewport
Async means that is independent from other viewports!
Is created by `egui::Context::create_viewport`
To be used you will need to wrap your state in `Arc<RwLock<T>>`
Look at viewports example to understand how to use it!
### Sync Viewport
Sync means that is dependent on his parent!
Is created by `egui::Context::create_viewport_sync`
This will pause the parent then render itself the resumes his parent!
#### ⚠️ This currently will make the fps/2 for every sync
viewport
### Common
#### ⚠️ Attention
You will need to do this when you render your content
```rust
ctx.create_viewport(ViewportBuilder::new("Simple Viewport"), | ctx | {
let content = |ui: &mut egui::Ui|{
ui.label("Content");
};
// This will make the content a popup if cannot create a native window
if ctx.viewport_id() != ctx.parent_viewport_id() {
egui::CentralPanel::default().show(ctx, content);
} else {
egui::Area::new("Simple Viewport").show(ctx, |ui| {
egui::Frame::popup(ui.style()).show(ui, content);
});
};
});
````
## What you need to know as egui user
### If you are using eframe
You don't need to change anything!
### If you have a manual implementation
Now `egui::run` or `egui::begin` and `egui::tessellate` will need the
current viewport id!
You cannot create a `ViewportId` only `ViewportId::MAIN`
If you make a single window app you will set the viewport id to be
`egui::ViewportId::MAIN` or see the `examples/pure_glow`
If you want to have multiples window support look at `crates/eframe`
glow or wgpu implementations!
## If you want to try this
- cargo run -p viewports
## This before was wanted to change
This will probably be in feature PR's
### egui::Window
To create a native window when embedded was set to false
You can try that in viewports example before:
[78a0ae8](78a0ae879e)
### egui popups, context_menu, tooltip
To be a native window
</details>
---------
Co-authored-by: Konkitoman <konkitoman@users.noreply.github.com>
Co-authored-by: Emil Ernerfeldt <emil.ernerfeldt@gmail.com>
Co-authored-by: Pablo Sichert <mail@pablosichert.com>