<!--
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!
-->
Android support is "almost there". This PR pushes it just a bit further
by allowing `eframe` to be used on Android. It works by smuggling the
`AndroidApp` required by `winit` through `NativeOptions`.
The example isn't great because it doesn't leave space on the display
for Android's top status bar or the lower navigation bar. I don't know
what to do about that, yet. This is as far as I've managed to get it
working.
Another problem is that the development environment setup is completely
awful for Android unless you happen to already be a full-time Android
developer with everything configured on your build host. As a Rustacean,
this makes me very sad.
I've had some luck moving all of that mess to a container, adapted from
https://github.com/SergioRibera/docker-rust-android. It takes care of
all of the build dependencies, Android SDK, and the `cargo-apk` patches
for bugs that I hit while getting the example to work on my device. (I
also had to install an adb driver on my host and downloaded the Android
platform-tools to get access to `adb`. An alternative is exposing the
USB device to Docker. On Windows hosts, that means [installing
`usbipd`](https://learn.microsoft.com/en-us/windows/wsl/connect-usb). A
second alternative is using an `mtp` client to upload the APK as a file
with USB file transfer enabled, then manually install it through the
device's file manager.)
I'm not including the docker stuff in this PR, but here are the files
and instructions for future reference (and it will probably simplify
manual testing and CI, FWIW!)
<details><summary><code>Dockerfile</code></summary>
```dockerfile
FROM rust:1.76.0-slim
# Variable arguments
ARG JAVA_VERSION=17
ARG NDK_VERSION=25.1.8937393
ARG BUILDTOOLS_VERSION=30.0.0
ARG PLATFORM_VERSION=android-30
ARG CLITOOLS_VERSION=8512546_latest
# Install Android requirements
RUN apt-get update -yqq && \
apt-get install -y --no-install-recommends \
libcurl4-openssl-dev libssl-dev pkg-config build-essential git python3 wget zip unzip openjdk-${JAVA_VERSION}-jdk && \
apt-get clean && \
rm -rf /var/lib/apt/lists/*
# Install android targets
RUN rustup target add armv7-linux-androideabi aarch64-linux-android
# Install cargo-apk
RUN git clone -b fix/bin-targets-workspace-members https://github.com/parasyte/cargo-apk.git /tmp/cargo-apk && \
cargo install --path /tmp/cargo-apk/cargo-apk
# Generate Environment Variables
ENV JAVA_VERSION=${JAVA_VERSION}
ENV ANDROID_HOME=/opt/Android
ENV NDK_HOME=/opt/Android/ndk/${NDK_VERSION}
ENV ANDROID_NDK_ROOT=${NDK_HOME}
ENV PATH=$PATH:${ANDROID_HOME}:${ANDROID_NDK_ROOT}:${ANDROID_HOME}/build-tools/${BUILDTOOLS_VERSION}:${ANDROID_HOME}/cmdline-tools/bin
# Install command line tools
RUN mkdir -p ${ANDROID_HOME}/cmdline-tools && \
wget -qc "https://dl.google.com/android/repository/commandlinetools-linux-${CLITOOLS_VERSION}.zip" -P /tmp && \
unzip -d ${ANDROID_HOME} /tmp/commandlinetools-linux-${CLITOOLS_VERSION}.zip && \
rm -fr /tmp/commandlinetools-linux-${CLITOOLS_VERSION}.zip
# Install sdk requirements
RUN echo y | sdkmanager --sdk_root=${ANDROID_HOME} --install \
"build-tools;${BUILDTOOLS_VERSION}" "ndk;${NDK_VERSION}" "platforms;${PLATFORM_VERSION}"
# Create APK keystore for debug profile
# Adapted from caa806283d/ndk-build/src/ndk.rs (L393-L423)
RUN keytool -genkey -v -keystore ${HOME}/.android/debug.keystore -storepass android -alias androiddebugkey \
-keypass android -dname 'CN=Android Debug,O=Android,C=US' -keyalg RSA -keysize 2048 -validity 10000
# Cleanup
RUN rm -rf /tmp/*
WORKDIR /src
ENTRYPOINT [ "cargo", "apk", "build" ]
```
</details>
<details><summary><code>.dockerignore</code></summary>
```ignore
# Ignore everything, only the Dockerfile is needed to build the container
*
```
</details>
```sh
docker build -t rust-android:latest .
docker run --rm -it -v "$PWD:/src" rust-android:latest -p hello_android
adb install target/debug/apk/hello_android.apk
```
* Part of #2066
* [x] I have followed the instructions in the PR template
* Closes#686
* Closes#839
* #5370 should be merged before this
* [x] I have followed the instructions in the PR template
This adds modals to egui.
This PR
- adds a new `Modal` struct
- adds `Memory::set_modal_layer` to limit focus to a layer and above
(used by the modal struct, but could also be used by custom modal
implementations)
- adds `Memory::allows_interaction` to check if a layer is behind a
modal layer, deprecating `Layer::allows_interaction`
Current problems:
- ~When a button is focused before the modal opens, it stays focused and
you also can't hit tab to focus the next widget. Seems like focus is
"stuck" on that widget until you hit escape. This might be related to
https://github.com/emilk/egui/issues/5359~ fixed!
Possible future improvements:
- The titlebar from `window` should be made into a separate widget and
added to the modal
- The state whether the modal is open should be stored in egui
(optionally), similar to popup and menu. Ideally before this we would
refactor popup state to unify popup and menu
---------
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!
-->
* [X] I have followed the instructions in the PR template
---------
Signed-off-by: sagudev <16504129+sagudev@users.noreply.github.com>
- 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.
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.
- 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
<!--
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/4490>
* [x] I have followed the instructions in the PR template
---
Unfortunately, this PR contains a bunch of breaking changes because
`Context` no longer has one style, but two. I could try to add some of
the methods back if that's desired.
The most subtle change is probably that `style_mut` mutates both the
dark and the light style (which from the usage in egui itself felt like
the right choice but might be surprising to users).
I decided to deviate a bit from the data structure suggested in the
linked issue.
Instead of this:
```rust
pub theme: Theme, // Dark or Light
pub follow_system_theme: bool, // Change [`Self::theme`] based on `RawInput::system_theme`?
```
I decided to add a `ThemePreference` enum and track the current system
theme separately.
This has a couple of benefits:
* The user's theme choice is not magically overwritten on the next
frame.
* A widget for changing the theme preference only needs to know the
`ThemePreference` and not two values.
* Persisting the `theme_preference` is fine (as opposed to persisting
the `theme` field which may actually be the system theme).
The `small_toggle_button` currently only toggles between dark and light
(so you can never get back to following the system). I think it's easy
to improve on this in a follow-up PR :)
I made the function `pub(crate)` for now because it should eventually be
a method on `ThemePreference`, not `Theme`.
To showcase the new capabilities I added a new example that uses
different "accent" colors in dark and light mode:
<img
src="https://github.com/user-attachments/assets/0bf728c6-2720-47b0-a908-18bd250d15a6"
width="250" alt="A screenshot of egui's widget gallery demo in dark mode
using a purple accent color instead of the default blue accent">
<img
src="https://github.com/user-attachments/assets/e816b380-3e59-4f11-b841-8c20285988d6"
width="250" alt="A screenshot of egui's widget gallery demo in light
mode using a green accent color instead of the default blue accent">
---------
Co-authored-by: Emil Ernerfeldt <emil.ernerfeldt@gmail.com>
Before making this PR, I did take notice of a similar PR,
https://github.com/emilk/egui/pull/4833, but as it appears to be
abandoned, I decided to make this PR.
**Missing**
One of the checks doesn't pass as wgpu still uses glow `0.13.1`
```shell
cargo deny --all-features --log-level error --target aarch64-apple-darwin check
```
* [x] I have followed the instructions in the PR template
---------
Co-authored-by: Emil Ernerfeldt <emil.ernerfeldt@gmail.com>
eframe now has its own logic to find the storage_dir to persist the app
when the persistence feature is enabled, instead of using the
directories crate. The directory should be the same as before (verified
with a unit test).
* Closes <https://github.com/emilk/egui/issues/4884>
* [x] I have followed the instructions in the PR template
This updates winit to 0.30.5.
https://github.com/emilk/egui/pull/4849 Had to pin the version to
0.30.2, as a Winit patch changed the behavior of selecting a theme.
Winit 0.30.5 reverts this, so we could stick with `window.theme()`, but
the newly added `ActiveEventLoop::system_theme` is more like what egui
wants anyway, as individual windows can have theme overrides.
Also bump `smithay-clipboard` to prevent some now duplicate
dependencies.
This allows license checking tools to omit the OFL and UFL licenses when
`default_fonts` are turned off.
There was some discussion of versioning on the original issue; I have
chosen to label this version as `0.28.1` to match the other crates.
Happy to adjust the version as needed.
<!--
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 <https://github.com/emilk/egui/issues/2321>
* [X] I have followed the instructions in the PR template
---------
Co-authored-by: Alex Pinkus <pinkus@amazon.com>
* Closes https://github.com/emilk/egui/issues/1918
* Closes https://github.com/emilk/egui/issues/4437
* Closes https://github.com/emilk/egui/issues/4709
* [x] I have followed the instructions in the PR template
Hiya,
I need new winit for a specific fix for a android_native_actvity. There
are already two PRs, but both don't seem to have a lot of movement, or
are entirely complete:
https://github.com/emilk/egui/pull/4466
Seems to have gone stale & is missing some bits.
https://github.com/emilk/egui/pull/4702
Also seems stale (if less so), and is missing a refactor to
run_on_demand. I also *think* the accesskit integration has a mistake
and can't be enabled. I've marked them as a co-author on this as I
started from this branch. (I think! Haven't done that on git before...).
Sorry for the wall of text but just dumping some details / thoughts
here:
- There's an issue with creating child windows in winit 0.30.1 and up on
macOS. The multiple_viewports, "create immediate viewport" example
crashes on anything later 0.30.1, with a stack overflow in unsafe code.
I've create [a winit
issue](https://github.com/rust-windowing/winit/issues/3800), it *might*
already be fixed in 0.31.0 but I can't test as 0.31 will likely require
another refactoring. For now I have just pinned things to 0.30.0 exatly.
- Winit has deprecated run_on_demand, instead requiring the
ApplicationHandler interface. In 0.31.0 run_on_demand is removed. I've
refactored both the integration and the WinitApp trait to follow this
pattern. I've left user_events a bit more opaque, as it seems 0.31.0 is
doing a rework of UserEvents too.
- I've used the new lazy init approach for access kit from this branch
https://github.com/mwcampbell/egui/tree/accesskit-new-lazy-init and
marked Matt as co-author, thanks Matt!
- There was very similair but not quite the same code for run_and_return
and run_and_exit. I've merged them, but looking at the github issues
graveyard it seems vey finnicky. I *hope* this is more robust than
before but it's a bit scary.
- when receiving new_events this also used to check the redraw timing
dictionary. That doesn't seem necesarry so left this out, but that is a
slight behaviour change?
- I have reeneabled serial_windows on macOS. I wondered whether it was
fixed after this PR and does seem to be! However, even before this PR it
seems to work, so maybe winit has sorted things out before that...
Windows also works fine now without the extra hack.
- I've done a very basic test of AccessKit on Windows and screen reader
seems ok but I'm really not knowleadgable enough to say whether it's all
good or not.
- I've tested cargo tests & all examples on Windows & macOS, and ran a
basic Android app. Still, testing native platforms is wel... hard so if
anyone can test linux / iOs / older mac versions / windows 10 would
probably be a good idea!
- For consistencys sake I've made all event like functions in WinitApp
return a `Result<EventResult>`. There's quite a bit of Ok-wrapping now,
maybe too annoying? Not sure.
Thank you for having a look!
# Tested on
* [x] macOS
* [x] Windows
* [x] Wayland (thanks [SiebenCorgie](https://github.com/SiebenCorgie))
* [x] X11 (thanks
[crumblingstatue](https://github.com/crumblingstatue)!,
[SiebenCorgie](https://github.com/SiebenCorgie))
# TODO
* [x] Fix "follow system theme" not working on initial startup (winit
issue, pinning to 0.30.2 for now).
* [x] Fix `request_repaint_after`
---------
Co-authored-by: mwcampbell <mattcampbell@pobox.com>
Co-authored-by: j-axa <josef.axa@gmail.com>
Co-authored-by: DataTriny <datatriny@gmail.com>
Co-authored-by: Emil Ernerfeldt <emil.ernerfeldt@gmail.com>
The default `Plot` formatter now picks precision intelligently based on
zoom level. The width of the Y axis are is now much smaller by default,
and expands as needed.
Also deprecates `Plot::y_axis_with`; replaced with `y_axis_min_width`.
This PR adds `PopupCloseBehavior` to improve state of the
<https://github.com/emilk/egui/issues/4607>
`PopupCloseBehavior` determines when popup will be closed.
- `CloseOnClick` popup will be closed if the click happens anywhere even
in the popup's body
- `CloseOnClickAway` popup will be closed if the click happens somewhere
else but in the popup's body.
It also adds a test in the demo app which contains several popups
examples.
---
My ideas about <https://github.com/emilk/egui/issues/4607> is to make
every tooltip and popup a menu. So it will provide more control over
popups and tooltips (you will be able to close a popup by calling
something similar to the `ui.close_menu` if you need to). You won't need
to manually handle it's opening. And also will allow to have multiple
popups opened. That means you can have a popup inside a popup. And it
will also lead to the easier creation of the popups. (should we create a
tracking issue to track changes because to me it seems like a huge
amount of changes to be done?)
---
- Improvements on <https://github.com/emilk/egui/issues/4607>
This example does not use the default features from eframe in order to
avoid accesskit, which panics when run from multiple threads, so it must
manually enable the other default features in order to compile correctly
on Linux.
* Closes <https://github.com/emilk/egui/issues/4682>
`directories-next` was created because `directories` was not maintained
at the time. However, `directories` has gotten active maintainership
since, and it has received more updates than `directories-next`.
`directories` also has more recent downloads than its `next`
counterpart, so it might make sense to switch to it, to avoid
unnecessary duplicate dependencies, where a project depends transitively
on both `directories` and `directories-next`.
The main question is whether we depend on any specific behavior from
`directories-next`.
* Closes#4534
This PR:
- Introduces `Ui::stack()`, which returns the `UiStack` structure
providing information on the current `Ui` hierarchy.
- **BREAKING**: `Ui::new()` now takes a `UiStackInfo` argument, which is
used to populate some of this `Ui`'s `UiStack`'s fields.
- **BREAKING**: `Ui::child_ui()` and `Ui::child_ui_with_id_source()` now
take an `Option<UiStackInfo>` argument, which is used to populate some
of the children `Ui`'s `UiStack`'s fields.
- New `Area::kind()` builder function, to set the `UiStackKind` value of
the `Area`'s `Ui`.
- Adds a (minimalistic) demo to egui demo (in the "Misc Demos" window).
- Adds a more thorough `test_ui_stack` test/playground demo.
TODO:
- [x] benchmarks
- [x] add example to demo
Future work:
- Add `UiStackKind` and related support for more container (e.g.
`CollapsingHeader`, etc.)
- Add a tag/property system that would allow adding arbitrary data to a
stack node. This data could then be queried by nested `Ui`s. Probably
needed for #3284.
- Add support to track columnar layouts.
---------
Co-authored-by: Emil Ernerfeldt <emil.ernerfeldt@gmail.com>
* Part of https://github.com/emilk/egui/issues/4535
* Closes https://github.com/emilk/egui/issues/3974
This adds a special `sizing_pass` mode to `Ui`, in which we have no
centered or justified layouts, and everything is hidden. This is used by
`Area` to use the first frame to measure the size of its contents so
that it can then set the perfectly correct size the subsequent frames.
For menus, where buttons are justified (span the full width), this
finally the problem of auto-sizing. Before you would have to pick a
width manually, and all buttons would expand to that width. If it was
too wide, it looked weird. If it was too narrow, text would wrap. Now
all menus are exactly the width they need to be. By default menus will
wrap at `Spacing::menu_width`.
This affects all situations when you have something that should be as
small as possible, but still span the full width/height of the parent.
For instance: the `egui::Separator` widget now checks the
`ui.is_sizing_pass` flag before deciding on a size. In the sizing pass a
horizontal separator is always 0 wide, and only in subsequent passes
will it span the full width.
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.
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>
These are a replacement to the `objc` and `cocoa` crates.
This PR prevents:
- An extra copy when creating `NSData`
- A memory leak when creating `NSImage`
- A memory leak when creating `NSString`
And is generally a readability improvement.
Note that we define `NSApp` manually for now, the implementation in
`objc2-app-kit` is currently suboptimal and wouldn't allow you to check
whether the NSApplication has been created or not.
Related: https://github.com/emilk/egui/issues/4219, this should nicely
coincide with the Winit `0.30` release.
---------
Co-authored-by: Emil Ernerfeldt <emil.ernerfeldt@gmail.com>
Replaces only the cargo_deny.sh script for now. Can be expanded over
time to replace the other shell and python scripts, so only Rust is
needed to work with the repository.
Closes <https://github.com/emilk/egui/issues/2887>
Closes <https://github.com/emilk/egui/issues/4373>
---------
Co-authored-by: Emil Ernerfeldt <emil.ernerfeldt@gmail.com>