Revert change to winit event loop in egui_glium (#756)

* Revert change to winit event loop in egui_glium

This reverts https://github.com/emilk/egui/pull/631

Fixes https://github.com/emilk/egui/issues/755

* Add example of file dialogs and file drag-and-drop

* fix ci
This commit is contained in:
Emil Ernerfeldt 2021-09-30 18:53:41 +02:00 committed by GitHub
parent 5539dbe620
commit 3e1db880dc
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
8 changed files with 377 additions and 88 deletions

View file

@ -82,7 +82,7 @@ jobs:
profile: minimal
toolchain: 1.54.0
override: true
- run: sudo apt-get install libxcb-render0-dev libxcb-shape0-dev libxcb-xfixes0-dev libspeechd-dev libxkbcommon-dev libssl-dev
- run: sudo apt-get install libxcb-render0-dev libxcb-shape0-dev libxcb-xfixes0-dev libspeechd-dev libxkbcommon-dev libssl-dev libgtk-3-dev # libgtk-3-dev is used by rfd
- uses: actions-rs/cargo@v1
with:
command: test
@ -115,7 +115,7 @@ jobs:
toolchain: 1.54.0
override: true
- run: rustup component add clippy
- run: sudo apt-get install libspeechd-dev
- run: sudo apt-get install libspeechd-dev libgtk-3-dev # libgtk-3-dev is used by rfd
- uses: actions-rs/cargo@v1
with:
command: clippy

214
Cargo.lock generated
View file

@ -1,5 +1,7 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
version = 3
[[package]]
name = "ab_glyph"
version = "0.2.11"
@ -85,6 +87,24 @@ dependencies = [
"winapi",
]
[[package]]
name = "anyhow"
version = "1.0.44"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "61604a8f862e1d5c3229fdd78f8b02c68dcf73a4c4b05fd636d12240aaa242c1"
[[package]]
name = "atk-sys"
version = "0.14.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "badcf670157c84bb8b1cf6b5f70b650fed78da2033c9eed84c4e49b11cbe83ea"
dependencies = [
"glib-sys",
"gobject-sys",
"libc",
"system-deps",
]
[[package]]
name = "atomic_refcell"
version = "0.1.7"
@ -236,6 +256,16 @@ version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c4872d67bab6358e59559027aa3b9157c53d9358c51423c17554809a8858e0f8"
[[package]]
name = "cairo-sys-rs"
version = "0.14.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d7c9c3928781e8a017ece15eace05230f04b647457d170d2d9641c94a444ff80"
dependencies = [
"libc",
"system-deps",
]
[[package]]
name = "calloop"
version = "0.6.5"
@ -276,6 +306,15 @@ dependencies = [
"nom 6.2.1",
]
[[package]]
name = "cfg-expr"
version = "0.8.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b412e83326147c2bb881f8b40edfbf9905b9b8abaebd0e47ca190ba62fda8f0e"
dependencies = [
"smallvec",
]
[[package]]
name = "cfg-if"
version = "0.1.10"
@ -785,6 +824,7 @@ dependencies = [
"egui_web",
"epi",
"image",
"rfd",
]
[[package]]
@ -989,6 +1029,36 @@ version = "0.3.55"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8f5f3913fa0bfe7ee1fd8248b6b9f42a5af4b9d65ec2dd2c3c26132b950ecfc2"
[[package]]
name = "gdk-pixbuf-sys"
version = "0.14.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f097c0704201fbc8f69c1762dc58c6947c8bb188b8ed0bc7e65259f1894fe590"
dependencies = [
"gio-sys",
"glib-sys",
"gobject-sys",
"libc",
"system-deps",
]
[[package]]
name = "gdk-sys"
version = "0.14.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0e091b3d3d6696949ac3b3fb3c62090e5bfd7bd6850bef5c3c5ea701de1b1f1e"
dependencies = [
"cairo-sys-rs",
"gdk-pixbuf-sys",
"gio-sys",
"glib-sys",
"gobject-sys",
"libc",
"pango-sys",
"pkg-config",
"system-deps",
]
[[package]]
name = "getrandom"
version = "0.2.3"
@ -1006,6 +1076,19 @@ version = "0.24.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0e4075386626662786ddb0ec9081e7c7eeb1ba31951f447ca780ef9f5d568189"
[[package]]
name = "gio-sys"
version = "0.14.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c0a41df66e57fcc287c4bcf74fc26b884f31901ea9792ec75607289b456f48fa"
dependencies = [
"glib-sys",
"gobject-sys",
"libc",
"system-deps",
"winapi",
]
[[package]]
name = "gl_generator"
version = "0.14.0"
@ -1017,6 +1100,16 @@ dependencies = [
"xml-rs",
]
[[package]]
name = "glib-sys"
version = "0.14.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1c1d60554a212445e2a858e42a0e48cece1bd57b311a19a9468f70376cf554ae"
dependencies = [
"libc",
"system-deps",
]
[[package]]
name = "glium"
version = "0.30.2"
@ -1111,6 +1204,35 @@ dependencies = [
"gl_generator",
]
[[package]]
name = "gobject-sys"
version = "0.14.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "aa92cae29759dae34ab5921d73fff5ad54b3d794ab842c117e36cafc7994c3f5"
dependencies = [
"glib-sys",
"libc",
"system-deps",
]
[[package]]
name = "gtk-sys"
version = "0.14.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8c14c8d3da0545785a7c5a120345b3abb534010fb8ae0f2ef3f47c027fba303e"
dependencies = [
"atk-sys",
"cairo-sys-rs",
"gdk-pixbuf-sys",
"gdk-sys",
"gio-sys",
"glib-sys",
"gobject-sys",
"libc",
"pango-sys",
"system-deps",
]
[[package]]
name = "half"
version = "1.7.1"
@ -1123,6 +1245,15 @@ version = "0.11.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ab5ef0d4909ef3724cc8cce6ccc8572c5c817592e9285f5464f8e86f8bd3726e"
[[package]]
name = "heck"
version = "0.3.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6d621efb26863f0e9924c6ac577e8275e5e6b77455db64ffa6c65c904e9e132c"
dependencies = [
"unicode-segmentation",
]
[[package]]
name = "hermit-abi"
version = "0.1.19"
@ -1700,6 +1831,18 @@ dependencies = [
"ttf-parser 0.12.3",
]
[[package]]
name = "pango-sys"
version = "0.14.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2367099ca5e761546ba1d501955079f097caa186bb53ce0f718dca99ac1942fe"
dependencies = [
"glib-sys",
"gobject-sys",
"libc",
"system-deps",
]
[[package]]
name = "parking_lot"
version = "0.11.2"
@ -1916,6 +2059,29 @@ version = "0.6.25"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f497285884f3fcff424ffc933e56d7cbca511def0c9831a7f9b5f6153e3cc89b"
[[package]]
name = "rfd"
version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "84b4745feef3bc92e709042c78d205e9a566ec46e18c58d4fac458e6fc12627e"
dependencies = [
"block",
"dispatch",
"glib-sys",
"gobject-sys",
"gtk-sys",
"js-sys",
"lazy_static",
"objc",
"objc-foundation",
"objc_id",
"raw-window-handle",
"wasm-bindgen",
"wasm-bindgen-futures",
"web-sys",
"winapi",
]
[[package]]
name = "ring"
version = "0.16.20"
@ -2182,6 +2348,24 @@ version = "0.9.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6446ced80d6c486436db5c078dde11a9f73d42b57fb273121e160b84f63d894c"
[[package]]
name = "strum"
version = "0.21.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "aaf86bbcfd1fa9670b7a129f64fc0c9fcbbfe4f1bc4210e9e98fe71ffc12cde2"
[[package]]
name = "strum_macros"
version = "0.21.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d06aaeeee809dbc59eb4556183dd927df67db1540de5be8d3ec0b6636358a5ec"
dependencies = [
"heck",
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "syn"
version = "1.0.77"
@ -2215,6 +2399,24 @@ dependencies = [
"yaml-rust",
]
[[package]]
name = "system-deps"
version = "3.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "480c269f870722b3b08d2f13053ce0c2ab722839f472863c3e2d61ff3a1c2fa6"
dependencies = [
"anyhow",
"cfg-expr",
"heck",
"itertools",
"pkg-config",
"strum",
"strum_macros",
"thiserror",
"toml",
"version-compare",
]
[[package]]
name = "takeable-option"
version = "0.5.0"
@ -2357,6 +2559,12 @@ dependencies = [
"tinyvec",
]
[[package]]
name = "unicode-segmentation"
version = "1.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8895849a949e7845e06bd6dc1aa51731a103c42707010a5b591c0038fb73385b"
[[package]]
name = "unicode-width"
version = "0.1.9"
@ -2415,6 +2623,12 @@ version = "0.8.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f1bddf1187be692e79c5ffeab891132dfb0f236ed36a43c7ed39f1165ee20191"
[[package]]
name = "version-compare"
version = "0.0.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1c18c859eead79d8b95d09e4678566e8d70105c4e7b251f707a03df32442661b"
[[package]]
name = "version_check"
version = "0.9.3"

View file

@ -1,6 +1,8 @@
# Changelog for eframe
All notable changes to the `eframe` and `epi` crates.
NOTE: [`egui_web`](egui_web/CHANGELOG.md), [`egui-winit`](egui-winit/CHANGELOG.md) and [`egui_glium`](egui_glium/CHANGELOG.md) have their own changelogs!
## Unreleased
* `Frame` now provides `set_decorations` to set whether to show window decorations.

View file

@ -36,6 +36,7 @@ egui_web = { version = "0.14.0", path = "../egui_web", default-features = false
[dev-dependencies]
image = { version = "0.23", default-features = false, features = ["png"] }
rfd = "0.5.0"
[features]
default = ["default_fonts"]

View file

@ -0,0 +1,100 @@
use eframe::{egui, epi};
#[derive(Default)]
struct MyApp {
dropped_files: Vec<egui::DroppedFile>,
picked_path: Option<String>,
}
impl epi::App for MyApp {
fn name(&self) -> &str {
"Native file dialogs and drag-and-drop files"
}
fn update(&mut self, ctx: &egui::CtxRef, _frame: &mut epi::Frame<'_>) {
egui::CentralPanel::default().show(ctx, |ui| {
ui.label("Drag-and-drop files onto the window!");
if cfg!(target_os = "macos") {
// Awaiting fix of winit bug: https://github.com/rust-windowing/winit/pull/2027
} else if ui.button("Open file…").clicked() {
if let Some(path) = rfd::FileDialog::new().pick_file() {
self.picked_path = Some(path.display().to_string());
}
}
if let Some(picked_path) = &self.picked_path {
ui.horizontal(|ui| {
ui.label("Picked file:");
ui.monospace(picked_path);
});
}
// Show dropped files (if any):
if !self.dropped_files.is_empty() {
ui.group(|ui| {
ui.label("Dropped files:");
for file in &self.dropped_files {
let mut info = if let Some(path) = &file.path {
path.display().to_string()
} else if !file.name.is_empty() {
file.name.clone()
} else {
"???".to_owned()
};
if let Some(bytes) = &file.bytes {
info += &format!(" ({} bytes)", bytes.len());
}
ui.label(info);
}
});
}
});
self.detect_files_being_dropped(ctx);
}
}
impl MyApp {
fn detect_files_being_dropped(&mut self, ctx: &egui::CtxRef) {
use egui::*;
// Preview hovering files:
if !ctx.input().raw.hovered_files.is_empty() {
let mut text = "Dropping files:\n".to_owned();
for file in &ctx.input().raw.hovered_files {
if let Some(path) = &file.path {
text += &format!("\n{}", path.display());
} else if !file.mime.is_empty() {
text += &format!("\n{}", file.mime);
} else {
text += "\n???";
}
}
let painter =
ctx.layer_painter(LayerId::new(Order::Foreground, Id::new("file_drop_target")));
let screen_rect = ctx.input().screen_rect();
painter.rect_filled(screen_rect, 0.0, Color32::from_black_alpha(192));
painter.text(
screen_rect.center(),
Align2::CENTER_CENTER,
text,
TextStyle::Heading,
Color32::WHITE,
);
}
// Collect dropped files:
if !ctx.input().raw.dropped_files.is_empty() {
self.dropped_files = ctx.input().raw.dropped_files.clone();
}
}
}
fn main() {
let options = eframe::NativeOptions::default();
eframe::run_native(Box::new(MyApp::default()), options);
}

View file

@ -61,6 +61,6 @@ pub fn start_web(canvas_id: &str, app: Box<dyn epi::App>) -> Result<(), wasm_bin
/// Call from `fn main` like this: `eframe::run_native(Box::new(MyEguiApp::default()))`
#[cfg(not(target_arch = "wasm32"))]
pub fn run_native(app: Box<dyn epi::App>, native_options: epi::NativeOptions) {
pub fn run_native(app: Box<dyn epi::App>, native_options: epi::NativeOptions) -> ! {
egui_glium::run(app, &native_options)
}

View file

@ -1,5 +1,4 @@
# Changelog for egui_glium
All notable changes to the `egui_glium` integration will be noted in this file.
@ -10,6 +9,7 @@ All notable changes to the `egui_glium` integration will be noted in this file.
* Increase scroll speed.
* Restore window position on startup without flickering.
* A lot of the code has been moved to the new library [`egui-winit`](https://github.com/emilk/egui/tree/master/egui-winit).
* Fix reactive mode on windows.
## 0.14.0 - 2021-08-24

View file

@ -160,12 +160,12 @@ fn load_icon(icon_data: epi::IconData) -> Option<glutin::window::Icon> {
// ----------------------------------------------------------------------------
/// Run an egui app
pub fn run(mut app: Box<dyn epi::App>, native_options: &epi::NativeOptions) {
pub fn run(mut app: Box<dyn epi::App>, native_options: &epi::NativeOptions) -> ! {
#[allow(unused_mut)]
let mut storage = create_storage(app.name());
let window_settings = deserialize_window_settings(&storage);
let mut event_loop = glutin::event_loop::EventLoop::with_user_event();
let event_loop = glutin::event_loop::EventLoop::with_user_event();
let icon = native_options.icon_data.clone().and_then(load_icon);
let display = create_display(&*app, native_options, &window_settings, icon, &event_loop);
@ -191,6 +191,8 @@ pub fn run(mut app: Box<dyn epi::App>, native_options: &epi::NativeOptions) {
let mut previous_frame_time = None;
let mut is_focused = true;
#[cfg(feature = "persistence")]
let mut last_auto_save = Instant::now();
@ -220,68 +222,8 @@ pub fn run(mut app: Box<dyn epi::App>, native_options: &epi::NativeOptions) {
// eprintln!("Warmed up in {} ms", warm_up_start.elapsed().as_millis())
}
let mut is_focused = true;
let mut running = true;
let mut repaint_asap = true;
while running {
use glium::glutin::platform::run_return::EventLoopExtRunReturn as _;
event_loop.run_return(|event, _, control_flow| {
use glium::glutin::event_loop::ControlFlow;
*control_flow = ControlFlow::Wait;
match event {
// Platform-dependent event handlers to workaround a winit bug
// See: https://github.com/rust-windowing/winit/issues/987
// See: https://github.com/rust-windowing/winit/issues/1619
glutin::event::Event::RedrawEventsCleared if cfg!(windows) => {
*control_flow = ControlFlow::Exit; // Time to redraw
}
glutin::event::Event::RedrawRequested(_) if !cfg!(windows) => {
*control_flow = ControlFlow::Exit; // Time to redraw
}
glutin::event::Event::MainEventsCleared => {
if repaint_asap {
*control_flow = ControlFlow::Exit; // Time to redraw
} else {
// Winit uses up all the CPU of one core when returning ControlFlow::Wait.
// Sleeping here helps, but still uses 1-3% of CPU :(
if is_focused || !egui.egui_input().hovered_files.is_empty() {
std::thread::sleep(std::time::Duration::from_millis(10));
} else {
std::thread::sleep(std::time::Duration::from_millis(50));
}
}
}
glutin::event::Event::WindowEvent { event, .. } => {
if egui.is_quit_event(&event) {
*control_flow = ControlFlow::Exit;
running = false;
}
if let glutin::event::WindowEvent::Focused(new_focused) = event {
is_focused = new_focused;
}
egui.on_event(&event);
// TODO: ask egui if the events warrants a repaint instead of repainting on each event.
display.gl_window().window().request_redraw();
repaint_asap = true;
}
glutin::event::Event::UserEvent(RequestRepaintEvent) => {
display.gl_window().window().request_redraw();
*control_flow = ControlFlow::Exit; // Time to redraw
}
_ => (),
}
});
repaint_asap = false;
if running {
event_loop.run(move |event, _, control_flow| {
let mut redraw = || {
if !is_focused {
// On Mac, a minimized Window uses up all CPU: https://github.com/emilk/egui/issues/325
// We can't know if we are minimized: https://github.com/rust-windowing/winit/issues/208
@ -349,11 +291,13 @@ pub fn run(mut app: Box<dyn epi::App>, native_options: &epi::NativeOptions) {
let _ = display.gl_window().window().drag_window();
}
if quit {
running = false;
*control_flow = if quit {
glutin::event_loop::ControlFlow::Exit
} else if needs_repaint {
display.gl_window().window().request_redraw();
repaint_asap = true;
glutin::event_loop::ControlFlow::Poll
} else {
glutin::event_loop::ControlFlow::Wait
};
}
@ -376,11 +320,30 @@ pub fn run(mut app: Box<dyn epi::App>, native_options: &epi::NativeOptions) {
last_auto_save = now;
}
}
}
};
match event {
// Platform-dependent event handlers to workaround a winit bug
// See: https://github.com/rust-windowing/winit/issues/987
// See: https://github.com/rust-windowing/winit/issues/1619
glutin::event::Event::RedrawEventsCleared if cfg!(windows) => redraw(),
glutin::event::Event::RedrawRequested(_) if !cfg!(windows) => redraw(),
glutin::event::Event::WindowEvent { event, .. } => {
if egui.is_quit_event(&event) {
*control_flow = glium::glutin::event_loop::ControlFlow::Exit;
}
if let glutin::event::WindowEvent::Focused(new_focused) = event {
is_focused = new_focused;
}
egui.on_event(&event);
display.gl_window().window().request_redraw(); // TODO: ask egui if the events warrants a repaint instead
}
glutin::event::Event::LoopDestroyed => {
app.on_exit();
#[cfg(feature = "persistence")]
if let Some(storage) = &mut storage {
if app.persist_native_window() {
@ -397,3 +360,12 @@ pub fn run(mut app: Box<dyn epi::App>, native_options: &epi::NativeOptions) {
storage.flush();
}
}
glutin::event::Event::UserEvent(RequestRepaintEvent) => {
display.gl_window().window().request_redraw();
}
_ => (),
}
});
}