egui icon indicating copy to clipboard operation
egui copied to clipboard

Allow eframe apps to be detached

Open rockisch opened this issue 1 year ago • 5 comments

One choice that I'm not really sure which I prefer is whether we should check for window.id() == window_id on WindowEvent events inside the on_event method or not. Since we're already exposing the window, the user could easily check that outside. However, when writing some example code, it ended up looking really bad and confusing. At the same time, people who will use this are probably people who have a good understanding of winit and GUI development in general, so maybe that's not an issue.

This gist shows how the 2 approaches would look like: https://gist.github.com/rockisch/c672345661dd5411f5611b7ab14faea0

This initial version of the PR has the check inside, but I could remove it if wanted.

rockisch avatar Sep 15 '23 03:09 rockisch

This looks very promising! Can you please add a working example too? 🙏

emilk avatar Sep 18 '23 19:09 emilk

Added a working example and fixed the CI issues (was on a Windows machine before, so I couldn't run the check.sh script)

rockisch avatar Sep 19 '23 11:09 rockisch

Btw, I went and changed one of my projects to this approach, and I noticed that although it does work, communication between the 'outer' code and the 'detached eframe app' is kinda clunky, since there's no way to access or modify the app data from the returned reference.

The way I'm doing this at the moment is by leaking a RefCell, more or less like this:

struct SharedState {
    flag: bool
}

struct MyApp {
    shared: &'static RefCell<SharedState>
}

let shared_state = Box::leak(Box::new(RefCell::new(SharedState { flag: true }))) as &_;
let detached_app = eframe::run_detached_native(
    ...,
    Box::new(|_cc| Box::new(MyApp { shared: shared_state }))
)
// 'shared_state' can be accessed and modified

How would you feel about exposing a get_app(&self) -> MyApp and get_app_mut(&mut self) -> MyApp on Detached? I took a look at the source code and I feel like I could add those with minimal changes.

rockisch avatar Sep 27 '23 01:09 rockisch

not sure I follow entirely but would this pr allow you to open a completely detached eframe, meaning you would have two separate event loops?

CoryRobertson avatar Nov 21 '23 00:11 CoryRobertson

What's the status of this PR? This would be very useful for Ruffle

Aaron1011 avatar Jan 15 '24 03:01 Aaron1011

Btw, I went and changed one of my projects to this approach, and I noticed that although it does work, communication between the 'outer' code and the 'detached eframe app' is kinda clunky, since there's no way to access or modify the app data from the returned reference.

The way I'm doing this at the moment is by leaking a RefCell, more or less like this:

struct SharedState {
    flag: bool
}

struct MyApp {
    shared: &'static RefCell<SharedState>
}

let shared_state = Box::leak(Box::new(RefCell::new(SharedState { flag: true }))) as &_;
let detached_app = eframe::run_detached_native(
    ...,
    Box::new(|_cc| Box::new(MyApp { shared: shared_state }))
)
// 'shared_state' can be accessed and modified

How would you feel about exposing a get_app(&self) -> MyApp and get_app_mut(&mut self) -> MyApp on Detached? I took a look at the source code and I feel like I could add those with minimal changes.

Is the problem that we need to give away ownership of the MyApp instance? Shouldn't the shared state be accessible when you are implementing the update method on MyApp?

Btw, if there's anyway I can contribute, I would be happy to help. Thanks for taking your time to implement this!

samyak-jain avatar Feb 27 '24 18:02 samyak-jain