Commit Graph

179 Commits

Author SHA1 Message Date
Pandicon 93d2144294
Save state on suspend on Android and iOS (#5601)
<!--
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!
-->

This pull request fixes a subset of #5492 by saving the application
state when the `suspended` event is received on Android. This way, even
if the user exits the app and closes it manually right after changing
some state, it will be saved since `suspended` gets fired when the app
is exited. It does not fix the `on_exit` function not being fired - this
seems to be a winit bug (the `exiting` function in the winit application
handler trait is not called on exit). Once it gets fixed, it may be
possible to remove logic introduced by this PR (however, I am not sure
how it would handle the app being killed by the system when in the
background, that would have to be tested).

I've tested the logic by:
* Leaving from the app to the home screen, then killing it from the
"recent apps" menu
 * Leaving from the app to the "recent apps" menu and killing it
 * Restarting the device while the app was running

In all of these instances, the state was saved (the last one being a
pleasant surprise). It was tested on the repository mentioned in #5492
with my forked repository as the source for eframe (I unfortunately am
not able to test it in a larger project of mine due to dependence on
"3rd party" egui libraries (like egui_notify) which do not compile along
with the master branch of eframe (different versions of egui), but I
believe it should work in the same manner in all scenarios). Tests were
conducted on a Galaxy Tab S8 running Android 14, One UI 6.1.1.

CI passed on my fork.

* [x] I have followed the instructions in the PR template
2025-01-27 08:14:49 +01:00
Joshua Holmes 97bdb2851c
Remove references to glium (#5626)
<!--
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!
-->

* Remove references to `glium` backend, because it is deprecated since
egui v0.18.0
* [x] I have followed the instructions in the PR template
2025-01-22 15:28:23 +01:00
Emil Ernerfeldt 164f56f554
Fix some clippy issues found by 1.84.0 (#5603) 2025-01-13 08:29:13 +01:00
Andreas Reich 1339639706
Fix Windows clippy issues (#5593)
These have been a lil bit annoying when running `cargo clippy
--all-features --all-targets` on windows
2025-01-11 18:05:57 +01:00
Andreas Reich 443df84a22
Extend `WgpuSetup`, `egui_kittest` now prefers software rasterizers for testing (#5506) 2025-01-08 14:24:58 +01:00
Ted de Munnik 3af907919b
Use `profiling` crate to support more profiler backends (#5150)
Hey! I am not sure if this is something that's been considered before
and decided against (I couldn't find any PR's or issues).

This change removes the internal profiling macros in library crates and
the `puffin` feature and replaces it with similar functions in the
[profiling](https://github.com/aclysma/profiling) crate. This crate
provides a layer of abstraction over various profiler instrumentation
crates and allows library users to pick their favorite (supported)
profiler.

An additional benefit for puffin users is that dependencies of egui are
included in the instrumentation output too (mainly wgpu which uses the
profiling crate), so more details might be available when profiling.

A breaking change is that instead of using the `puffin` feature on egui,
users that want to profile the crate with puffin instead have to enable
the `profile-with-puffin` feature on the profiling crate. Similarly they
could instead choose to use `profile-with-tracy` etc.

I tried to add a 'tracy' feature to egui_demo_app in order to showcase ,
however the /scripts/check.sh currently breaks on mutually exclusive
features (which this introduces), so I decided against including it for
the initial PR. I'm happy to iterate more on this if there is interest
in taking this PR though.

Screenshot showing the additional info for wgpu now available when using
puffin

![image](https://github.com/user-attachments/assets/49fc0e7e-8f88-40cb-a69e-74ca2e3f90f3)
2024-12-16 09:15:54 +01:00
Jay Oster ea89c2935e
Android support for eframe (#5318)
<!--
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
2024-12-12 19:24:26 +01:00
lucasmerlin 6c1d695fc6
Add screenshot support for eframe web (#5438)
This implements web support for taking screenshots in an eframe app (and
adds a nice demo).
It also updates the native screenshot implementation to work with the
wgpu gl backend.

The wgpu implementation is quite different than the native one because
we can't block to wait for the screenshot result, so instead I use a
channel to pass the result to a future frame asynchronously.

* Closes <https://github.com/emilk/egui/issues/5425>
* [x] I have followed the instructions in the PR template


https://github.com/user-attachments/assets/67cad40b-0384-431d-96a3-075cc3cb98fb
2024-12-12 19:17:42 +01:00
Emil Ernerfeldt a9c76ba7a6
Allow attaching custom user data to a screenshot command (#5416)
This lets users trigger a screenshot from anywhere, and then when they
get back the results they have some context about what part of their
code triggered the screenshot.
2024-12-03 10:08:55 +01:00
Emil Ernerfeldt 328422dc62
Update MSRV to Rust 1.79 (#5421)
Mostly to fix `cargo-machete` CI
2024-12-01 18:58:35 +01:00
Valentin c86d0e5918
fix accidental change of FallbackEgl to PreferEgl (#5408)
I accidentally changed this in a previous commit when I meant to only
change the comment above it.

https://github.com/emilk/egui/pull/5392#discussion_r1859383653
2024-11-30 12:56:23 +01:00
Valentin 7cee35c02a
document justification for FallbackEgl (#5392)
The previous link does not explain why we chose FallbackEgl. This is a
better link.
2024-11-26 15:23:43 +01:00
TÖRÖK Attila 67c82ed5f2
wgpu: Bump to wgpu 23.0.0 and wasm-bindgen to 0.2.95 (#5330)
Co-authored-by: Andreas Reich <r_andreas2@web.de>
2024-10-30 18:53:22 +01:00
Cody Neiman 2cd3485dd4
Update MSRV from 1.76 to 1.77 (#5322)
<!--
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.
2024-10-30 09:06:34 +01:00
Nicolas 1488ffa35a
Use `log` crate instead of `eprintln` & remove some unwraps (#5010)
<!--
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
2024-09-13 14:23:13 +02:00
Emil Ernerfeldt 66076101e1
Add `Context::request_discard` (#5059)
* 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:


![image](https://github.com/user-attachments/assets/c2c1e4a4-b7c9-4d7a-b3ad-abdd74bf449f)

### 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
2024-09-13 14:20:51 +02:00
Nicolas 1c293d4cc8
Update `glow` to 0.14 (#4952)
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>
2024-09-09 14:02:06 +02:00
Tim Straubinger b9435541df
Allow non-`static` `eframe::App` lifetime (#5060)
I love egui! Thank you Emil <3

This request specifically enables an `eframe::App` which stores a
lifetime.

In general, I believe this is necessary because `eframe::App` currently
does not seem to provide a good place to allocate and then borrow from
long-lived data between `update()` calls. To attempt to borrow such
long-lived data from a field of the `App` itself would be to create a
self-referential struct. A hacky alternative is to allocate long-lived
data with `Box::leak`, but that's a code smell and would cause problems
if a program ever creates multiple Apps.

As a more specific motivating example, I am developing with the
[inkwell](https://github.com/TheDan64/inkwell/) crate which requires
creating a `inkwell::context::Context` instance which is then borrowed
from by a bazillion things with a dedicated `'ctx` lifetime. I need such
a `inkwell::context::Context` for the duration of my `eframe::App` but I
can't store it as a field of the app. The most natural solution to me is
to simply to lift the inkwell context outside of the App and borrow from
it, but that currently fails because the AppCreator implicitly has a
`'static` lifetime requirement due to the use of `dyn` trait objects.

Here is a simpler, self-contained motivating example adapted from the
current [hello world example](https://docs.rs/eframe/latest/eframe/):

```rust
use eframe::egui;

struct LongLivedThing {
    message: String,
}

fn main() {
    let long_lived_thing = LongLivedThing {
        message: "Hello World!".to_string(),
    };

    let native_options = eframe::NativeOptions::default();
    eframe::run_native(
        "My egui App",
        native_options,
        Box::new(|cc| Ok(Box::new(MyEguiApp::new(cc, &long_lived_thing)))),
        //                                           ^^^^^^^^^^^^^^^^^
        //                                           BORROWING from long_lived_thing in App
    );
}

struct MyEguiApp<'a> {
    long_lived_thing: &'a LongLivedThing,
}

impl<'a> MyEguiApp<'a> {
    fn new(cc: &eframe::CreationContext<'_>, long_lived_thing: &'a LongLivedThing) -> Self {
        // Customize egui here with cc.egui_ctx.set_fonts and cc.egui_ctx.set_visuals.
        // Restore app state using cc.storage (requires the "persistence" feature).
        // Use the cc.gl (a glow::Context) to create graphics shaders and buffers that you can use
        // for e.g. egui::PaintCallback.
        MyEguiApp { long_lived_thing }
    }
}

impl<'a> eframe::App for MyEguiApp<'a> {
    fn update(&mut self, ctx: &egui::Context, frame: &mut eframe::Frame) {
        egui::CentralPanel::default().show(ctx, |ui| {
            ui.heading(&self.long_lived_thing.message);
        });
    }
}
```

This currently fails to compile with:
```plaintext
error[E0597]: `long_lived_thing` does not live long enough
  --> src/main.rs:16:55
   |
16 |         Box::new(|cc| Ok(Box::new(MyEguiApp::new(cc, &long_lived_thing)))),
   |         ----------------------------------------------^^^^^^^^^^^^^^^^----
   |         |        |                                    |
   |         |        |                                    borrowed value does not live long enough
   |         |        value captured here
   |         cast requires that `long_lived_thing` is borrowed for `'static`
17 |     );
18 | }
   | - `long_lived_thing` dropped here while still borrowed
   |
   = note: due to object lifetime defaults, `Box<dyn for<'a, 'b> FnOnce(&'a CreationContext<'b>) -> Result<Box<dyn App>, Box<dyn std::error::Error + Send + Sync>>>` actually means `Box<(dyn for<'a, 'b> FnOnce(&'a CreationContext<'b>) -> Result<Box<dyn App>, Box<dyn std::error::Error + Send + Sync>> + 'static)>`
```

With the added lifetimes in this request, I'm able to compile and run
this as expected on Ubuntu + Wayland. I see the CI has been emailing me
about some build failures and I'll do what I can to address those.
Currently running the check.sh script as well.

This is intended to resolve https://github.com/emilk/egui/issues/2152

<!--
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/2152
* [x] I have followed the instructions in the PR template
2024-09-03 09:29:19 +02:00
YgorSouza edea5a40b9
Remove the `directories` dependency (#4904)
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
2024-09-01 10:47:28 +02:00
rustbasic 2a6a1302b8
Fix viewport not working when minimized (#5042)
Fix: The viewport stops working when the program is minimized.   

Fix: Logically, the weird parts have been normalized.
                                                               
**Issue :**
The viewport stops working when the program is minimized.
                         
* Related #3321
* Related #3877
* Related #3985
* Closes #3972
* Closes #4772
* Related #4832 
* Closes #4892
**Solution :**
When `request_redraw()` is performed in Minimized state, the occasional
screen tearing phenomenon has disappeared.
( Probably expected to be the effect of #4814 )
To address the issue of the `Immediate Viewport` not updating in
Minimized state, we can call `request_redraw()`.
2024-09-01 10:34:48 +02:00
Nicolas 343c3d16c3
Remove wildcard imports (#5018)
<!--
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 removed (I hope so) all wildcard imports I found.

For me on my pc this improved the build time:
- for egui -5s
- for eframe -12s

* [x] I have followed the instructions in the PR template
2024-08-28 12:18:42 +02:00
VinTarZ 9f2f5f7292
Fix eframe centering on multiple monitor systems (#4919)
On multiple-monitor systems, eframe was incorrectly selecting first ones
dimensions for centering

Would also appretiate releasing 0.28.2 with fix included on crates.io
2024-08-26 15:36:30 +02:00
Emil Ernerfeldt 0513c05768
Fix CI (#5005) 2024-08-26 15:35:44 +02:00
lucasmerlin c9e00e50ad
Fix iOS build, and add iOS step to CI (#4898)
<!--
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!
-->

This PR
- adds a pipeline to check the ios build
- removes the iOS WaitUntil workaround, which doesn't seem to be
necessary anymore after the winit update (and caused the build for iOS
to fail again because of a missing self
- ~removes a iOS workaround for window size which doesn't seem necessary
anymore~
Turns out it was still needed (but you need to actually restart the app
for the issue to show up, so I didn't catch it first)
- fixes some cargo check errors in run.rs

I've done all these changes in a single PR because otherwise the
pipeline doesn't run but I can also split them in separate PRs if that
makes it easier to review
2024-08-26 09:48:12 +02:00
pm100 0c528fb862
Fix crash when changing viewport settings (#4862)
* Fixes #3959

There are two bugs racing each other here, which is why it sometimes
crashes and sometimes the app just silently exists

Bug 1
When the window is recreated a Destroyed event arrives (due to the Drop
of the old window). The code that receives this event does not look to
see if its the main viewport or a secondary one and unconditionally
closes the app. The code path for other platforms is slightly different
and does check.

I have moved the code that handles the destroy to be in the same place
and have the same behavior as the other platforms.

Bug 2

At recreate time the window and winit entries of the viewport are set to
None (forcin g them to be recreated). But the surface is still bound to
the old window, this causes the next context switch to fail. So I simply
added a viewport.gl_surface = None too,


This is my first egui PR so I hope I have not broken anything. If
nothing else I understand a little better how egui works.
2024-08-26 08:55:34 +02:00
Arthur Brussee 1f6ae49a5f
Unpin & upgrade winit to 0.30.5 (#4939)
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.
2024-08-09 09:15:14 +02:00
Tau Gärtli 2dac4a4fc6
Follow the System Theme in egui (#4860)
* Some initial progress towards #4490

This PR just moves `Theme` and the "follow system theme" settings to
egui and adds `RawInput.system_theme`.
A follow-up PR can then introduce the two separate `dark_mode_style` and
`light_mode_style` fields on `Options`.


<!--
Please read the "Making a PR" section of
[`CONTRIBUTING.md`](https://github.com/emilk/egui/blob/master/CONTRIBUTING.md)
before opening a Pull Request!

* 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


### Breaking changes

The options `follow_system_theme` and `default_theme` has been moved
from `eframe` into `egui::Options`, settable with `ctx.options_mut`

---------

Co-authored-by: Emil Ernerfeldt <emil.ernerfeldt@gmail.com>
2024-08-06 20:17:51 +02:00
Ardocrat dfbc7f0d19
Fix iOS compilation of eframe (#4851)
Fixed changed the name of function `WinitApp::get_window_winit_id` to
`WinitApp::window_id_from_viewport_id` and missed `egui::ViewportId`
import.
2024-07-31 10:18:18 +02:00
Arthur Brussee 6f2f006885
Upgrade winit to 0.30.2 (#4849)
* 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>
2024-07-31 09:43:16 +02:00
rustbasic 20359a870f
eframe: Improve `glow` context switching (#4814)
Improved `change_gl_context()`

**Before:** 
Create a new `not_current_glcontext`. 

**After:**
If `not_current_glcontext` exists, apply it. Otherwise, create it. 

This will make the program smoother when dragging, etc.
2024-07-11 11:43:21 +02:00
Jonas Wagner b283b8a560
Introduce dithering to reduce banding (#4497)
This PR introduces dithering in the egui_glow and egui_wgpu backends to
reduce banding artifacts.

It's based on the approach mentioned in #4493 with the small difference
that the amount of noise is scaled down slightly to avoid dithering
colors that can be represented exactly. This keeps flat surfaces clean.

Exaggerated dithering to show what is happening:
![Screenshot from 2024-05-14
19-09-48](https://github.com/emilk/egui/assets/293536/75782b83-9023-4cb2-99f7-a24e15fdefcc)

Subtle dithering as commited.
![Screenshot from 2024-05-14
19-13-40](https://github.com/emilk/egui/assets/293536/eb904698-a6ec-494a-952b-447e9a49bfda)

Closes #4493
2024-07-08 09:57:11 +02:00
rustbasic cd1e4c573a
Remove dead code (`EpiIntegration::frame_start`) (#4790)
`frame_start` appears to be deprecated now.
( Am I wrong? )

It would be a good idea to add `#[allow(dead_code)]` or remove
`frame_start`.
2024-07-07 08:52:14 +02:00
Emil Ernerfeldt 10571e9da5
`eframe::Result` is now short for `eframe::Result<()>` (#4706) 2024-06-25 13:31:42 +02:00
rustbasic d9c5fb04ae
Fix dragging of `custom_window_frame` example on Windows (#4656)
* Related #4592 
* Closes #4647 

Fix dragging of custom_window_frame on Windows (re-edited)
2024-06-19 16:19:41 +02:00
crumblingstatue 49cb62b1ba
Replace `directories-next` dependency with `directories` (#4661)
`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`.
2024-06-18 22:17:21 +02:00
Emil Ernerfeldt 942fe4ab31
Support returning errors when creating the app (#4565)
The closure passed to `eframe::run_native` now returns a `Result`,
allowing you to return an error during app creation, which will be
returned to the caller of `run_native`.

This means you need to wrap your `Box::new(MyApp::new(…))` in an
`Ok(…)`.

* Closes https://github.com/emilk/egui/issues/4474
2024-05-28 21:59:19 +02:00
lucasmerlin 8553e738e0
eframe: Add `NativeOptions::persistence_path` (#4423)
This allows customizing the persistence path in NativeOptions.
Previously, persistence wouldn't work with android because
directories-next doesn't support android so eframe would just fail to
find a place where it could store its config.

* Closes #4098 (android users can now specify a path that works with
android, by e.g. using app_dirs2, which supports android)
2024-05-27 18:57:39 +02:00
Oscar Gustafsson cd45d18615
Do no use the ahash reimport (#4504)
<!--
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.
2024-05-27 16:24:50 +02:00
Emil Ernerfeldt 44d65f41ac
Update `image` crate to 0.25 (#4160)
To not produce duplicating deps in Rerun
(https://github.com/rerun-io/rerun/pull/5280) I suggest we wait with
merging this until these crates have updated to `image` 0.25:
* [x] [`arboard`](https://crates.io/crates/arboard)
* [x] [`gltf`](https://crates.io/crates/gltf)
2024-05-13 13:35:15 +02:00
Avery Radmacher e06b225dab
Fix: Window position creeps between executions on scaled monitors (#4443)
<!--
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!
-->

* Closes <https://github.com/emilk/egui/issues/4442>
* Refactors active monitor detection so it can be called from multiple
locations.

Compare this gif to the one on the issue report.

![egui_window_position_no_creep](https://github.com/emilk/egui/assets/45777186/8e05d4fb-266e-48b9-9223-b65f16500a99)

### Investigation notes

- [`WindowSettings.inner_position_pixels` and
`WindowSettings.outer_position_pixels`](https://github.com/emilk/egui/blob/master/crates/egui-winit/src/window_settings.rs#L8-L12)
are stored in physical/pixel coordinates.
- `ViewportBuilder::with_position` expects to be passed a position in
_logical_ coordinates.
- Prior to this PR, the position was being passed from `WindowSettings`
to `with_position` [without any
scaling](https://github.com/emilk/egui/blob/master/crates/egui-winit/src/window_settings.rs#L61-L68).
This was the root cause of the issue.
- The fix is to first convert the position to logical coordinates,
respecting the scaling factor of the active monitor. This requires us to
first determine the active monitor, so I factored out some of the logic
in
[`clamp_pos_to_monitor`](https://github.com/emilk/egui/blob/master/crates/egui-winit/src/window_settings.rs#L130)
to find the active monitor.
2024-05-11 16:48:12 +02:00
rustbasic 27a22f991d
Fix : In Windows, the 'egui_demo_app' screen does not appear. (#4410)
* Related #4337 
* Closes #4409 

Fix : In Windows, the 'egui_demo_app' screen does not appear After the
#4337 update.

---------

Co-authored-by: Emil Ernerfeldt <emil.ernerfeldt@gmail.com>
2024-05-11 00:41:02 +02:00
Emil Ernerfeldt ded8dbd45b
Fix some clippy warning from Rust 1.78.0 (#4444) 2024-05-02 17:04:25 +02:00
Emil Ernerfeldt 2f508d6a61
Replace cargo-cranky with workspace lints (#4413)
Replace `cargo-cranky` (which has served us well) with workspace lints
2024-04-25 17:24:50 +02:00
Emil Ernerfeldt cee790681d
Update to Rust 1.76 (#4411)
Motivation: I want to replace `cargo-cranky` with workspace lints, first
available in Rust 1.74.
However, `cargo doc` would hange on `wgpu` and `wgpu-core` on 1.74 and
1.75… so now we're on 1.76.
I think this is fine - when 1.78 is released next week we're still two
versions behind the bleeding edge.

…and the branch name is just wrong 🤦
2024-04-25 15:51:01 +02:00
Mads Marquart 14194f5d3a
eframe: Use `objc2` and its framework crates (#4395)
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>
2024-04-23 17:35:12 +02:00
lopo ff8cfc2aa0
Allow users to create viewports larger than monitor on Windows & macOS (#4337)
Added clamp_size_to_monitor_size field on ViewportBuilder, which means
whether clamp the window's size to monitor's size. (default to `true`)

* Closes https://github.com/emilk/egui/issues/3389

### simple example

```rust
pub struct MyApp {}

impl MyApp {
    pub fn new() -> MyApp {
        MyApp {}
    }
}

impl eframe::App for MyApp {
    fn update(&mut self, ctx: &Context, frame: &mut eframe::Frame) {
        egui::CentralPanel::default()
            .frame(Frame::none().fill(Color32::DARK_GRAY))
            .show(ctx, |ui| {
                if ctx.input(|i| i.key_pressed(Key::Escape)) {
                    ctx.send_viewport_cmd(ViewportCommand::Close);
                }
            });
    }
}

pub fn main() {
    let option = eframe::NativeOptions {
        viewport: ViewportBuilder::default()
            .with_position([10.0, 10.0])
            .with_inner_size([3000.0, 2000.0])
            .with_clamp_size_to_monitor_size(false),
        ..Default::default()
    };

    eframe::run_native(
        "a large window app",
        option,
        Box::new(|ctx| Box::new(MyApp::new())),
    ).unwrap();
}
```

It works on my windows (with 3 monitors), but I don't have a test
environment for macos

---------

Co-authored-by: Emil Ernerfeldt <emil.ernerfeldt@gmail.com>
2024-04-22 12:44:21 +02:00
bu5hm4nn a2f1ca31a0
Add `ViewportCommand::RequestCut`, `RequestCopy` and `RequestPaste` to trigger Clipboard actions (#4035)
### Motivation
We want to offer our users a context menu with `Cut`, `Copy` and `Paste`
actions. `Paste` is not possible out of the box.

### Changes
This PR adds `ViewportCommand::RequestCut`,
`ViewportCommand::RequestCopy` and `ViewportCommand::RequestPaste`. They
are routed and handled after the example of
`ViewportCommand::Screenshot` and result in the same code being executed
as when the user uses `CTRL+V` style keyboard commands.

### Reasoning
In our last release we used an instance of
`egui_winit:📋:Clipboard` in order to get the `Paste`
functionality.

However Linux users on Wayland complained about broken clipboard
interaction (https://github.com/mikedilger/gossip/issues/617). After a
while of digging I could not find the issue although I have found
references to problems with multiple clipboards per handle before
(https://gitlab.gnome.org/GNOME/mutter/-/issues/1250) but I compared
mutter with weston and the problem occured on both.

So to solve this I set out to extend egui to access the clipboard
instance already present in egui_winit. Since there was no trivial way
to reach the instance of `egui_winit::State` I felt the best approach
was to follow the logic of the new `ViewportCommand::Screenshot`.

### Variations
It could make sense to make the introduced `enum ActionRequested` a part
of crates/egui/src/viewport.rs and to then wrap them into one single
`ViewportCommand::ActionRequest(ActionRequested)`.

### Example
```Rust
let mut text = String::new();
let response = ui.text_edit_singleline(&mut text);
if ui.button("Paste").clicked() {
    response.request_focus();
    ui.ctx().send_viewport_cmd(ViewportCommand::RequestPaste);
}
```

---------

Co-authored-by: Emil Ernerfeldt <emil.ernerfeldt@gmail.com>
2024-04-22 09:06:33 +02:00
Emil Ernerfeldt 058f4753b0 Fix typos and false positives found by new version of 'typos' 2024-04-02 09:55:13 +02:00
Emil Ernerfeldt e99bd00dec
Only avoid glow context switching on Windows (#4296)
…since it is reportedly broken on Windows

* Early-out added in https://github.com/emilk/egui/pull/4284
* Re-opens https://github.com/emilk/egui/issues/4173 😭 
* Closes https://github.com/emilk/egui/issues/4289
* Closes https://github.com/emilk/egui/pull/4290
2024-04-01 12:14:44 +02:00
rustbasic 21835c3176
Fix `ViewportCommand::InnerSize` not resizing viewport on Wayland (#4211) 2024-03-30 20:09:28 +01:00