Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions clippy.toml
Original file line number Diff line number Diff line change
Expand Up @@ -39,9 +39,9 @@ disallowed-methods = [
# but we cannot disable them all here (because of e.g. https://github.com/rust-lang/rust-clippy/issues/10406)
# so we do that in `clipppy_wasm.toml` instead.

{ path = "std::env::temp_dir", readon = "Use the tempfile crate instead" },
{ path = "std::env::temp_dir", reason = "Use the tempfile crate instead" },
{ path = "std::panic::catch_unwind", reason = "We compile with `panic = abort" },
{ path = "std::thread::spawn", readon = "Use `std::thread::Builder` and name the thread" },
{ path = "std::thread::spawn", reason = "Use `std::thread::Builder` and name the thread" },
]

# https://rust-lang.github.io/rust-clippy/master/index.html#disallowed_names
Expand Down
5 changes: 3 additions & 2 deletions crates/eframe/src/native/glow_integration.rs
Original file line number Diff line number Diff line change
Expand Up @@ -548,7 +548,7 @@ impl GlowWinitRunning<'_> {
let Some(egui_winit) = viewport.egui_winit.as_mut() else {
return Ok(EventResult::Wait);
};
let mut raw_input = egui_winit.take_egui_input(window);
let mut raw_input = egui_winit.take_egui_input();
let viewport_ui_cb = viewport.viewport_ui_cb.clone();

self.integration.pre_update();
Expand Down Expand Up @@ -1049,6 +1049,7 @@ impl GlutinWindowContext {

// Tell egui right away about native_pixels_per_point etc,
// so that the app knows about it during app creation:
// TODO: update_viewport_info could take care of this right?
let pixels_per_point = egui_winit::pixels_per_point(egui_ctx, window);

egui_ctx.input_mut(|i| {
Expand Down Expand Up @@ -1474,7 +1475,7 @@ fn render_immediate_viewport(
};
egui_winit::update_viewport_info(&mut viewport.info, egui_ctx, window, false);

let mut raw_input = egui_winit.take_egui_input(window);
let mut raw_input = egui_winit.take_egui_input();
raw_input.viewports = glutin
.viewports
.iter()
Expand Down
5 changes: 3 additions & 2 deletions crates/eframe/src/native/wgpu_integration.rs
Original file line number Diff line number Diff line change
Expand Up @@ -205,6 +205,7 @@ impl<'app> WgpuWinitApp<'app> {
{
// Tell egui right away about native_pixels_per_point etc,
// so that the app knows about it during app creation:
// TODO: update_viewport_info could take care of this right?
let pixels_per_point = egui_winit::pixels_per_point(&egui_ctx, &window);

egui_ctx.input_mut(|i| {
Expand Down Expand Up @@ -616,7 +617,7 @@ impl WgpuWinitRunning<'_> {
let Some(egui_winit) = egui_winit.as_mut() else {
return Ok(EventResult::Wait);
};
let mut raw_input = egui_winit.take_egui_input(window);
let mut raw_input = egui_winit.take_egui_input();

integration.pre_update();

Expand Down Expand Up @@ -1006,7 +1007,7 @@ fn render_immediate_viewport(
};
egui_winit::update_viewport_info(&mut viewport.info, egui_ctx, window, false);

let mut input = egui_winit.take_egui_input(window);
let mut input = egui_winit.take_egui_input();
input.viewports = viewports
.iter()
.map(|(id, viewport)| (*id, viewport.info.clone()))
Expand Down
170 changes: 89 additions & 81 deletions crates/egui-winit/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,19 +32,9 @@ use winit::{
window::{CursorGrabMode, Window, WindowButtons, WindowLevel},
};

pub fn screen_size_in_pixels(window: &Window) -> egui::Vec2 {
let size = if cfg!(target_os = "ios") {
// `outer_size` Includes the area behind the "dynamic island".
// It is up to the eframe user to make sure the dynamic island doesn't cover anything important.
// That will be easier once https://github.com/rust-windowing/winit/pull/3890 lands
window.outer_size()
} else {
window.inner_size()
};
egui::vec2(size.width as f32, size.height as f32)
}

/// Calculate the `pixels_per_point` for a given window, given the current egui zoom factor
///
/// Only use this during startup when a [`WindowEvent::ScaleFactorChanged`] was not yet delivered!
pub fn pixels_per_point(egui_ctx: &egui::Context, window: &Window) -> f32 {
let native_pixels_per_point = window.scale_factor() as f32;
let egui_zoom_factor = egui_ctx.zoom_factor();
Expand Down Expand Up @@ -231,30 +221,30 @@ impl State {
/// You need to set [`egui::RawInput::viewports`] yourself though.
/// Use [`update_viewport_info`] to update the info for each
/// viewport.
pub fn take_egui_input(&mut self, window: &Window) -> egui::RawInput {
pub fn take_egui_input(&mut self) -> egui::RawInput {
profiling::function_scope!();

self.egui_input.time = Some(self.start_time.elapsed().as_secs_f64());

// On Windows, a minimized window will have 0 width and height.
// See: https://github.com/rust-windowing/winit/issues/208
// This solves an issue where egui window positions would be changed when minimizing on Windows.
let screen_size_in_pixels = screen_size_in_pixels(window);
let screen_size_in_points =
screen_size_in_pixels / pixels_per_point(&self.egui_ctx, window);
// // On Windows, a minimized window will have 0 width and height.
// // See: https://github.com/rust-windowing/winit/issues/208
// // This solves an issue where egui window positions would be changed when minimizing on Windows.
// let screen_size_in_pixels = screen_size_in_pixels(window);
// let screen_size_in_points =
// screen_size_in_pixels / pixels_per_point(&self.egui_ctx, window);

self.egui_input.screen_rect = (screen_size_in_points.x > 0.0
&& screen_size_in_points.y > 0.0)
.then(|| Rect::from_min_size(Pos2::ZERO, screen_size_in_points));
// self.egui_input.screen_rect = (screen_size_in_points.x > 0.0
// && screen_size_in_points.y > 0.0)
// .then(|| Rect::from_min_size(Pos2::ZERO, screen_size_in_points));

// Tell egui which viewport is now active:
self.egui_input.viewport_id = self.viewport_id;

self.egui_input
.viewports
.entry(self.viewport_id)
.or_default()
.native_pixels_per_point = Some(window.scale_factor() as f32);
// self.egui_input
// .viewports
// .entry(self.viewport_id)
// .or_default()
// .native_pixels_per_point = Some(window.scale_factor() as f32);

self.egui_input.take()
}
Expand Down Expand Up @@ -300,6 +290,33 @@ impl State {
.or_default()
.native_pixels_per_point = Some(native_pixels_per_point);

// TODO: Also update screen_rect!

EventResponse {
repaint: true,
consumed: false,
}
}
WindowEvent::Resized(size) => {
// TODO: This event doesn't deliver outer size
// let size = if cfg!(target_os = "ios") {
// // `outer_size` Includes the area behind the "dynamic island".
// // It is up to the eframe user to make sure the dynamic island doesn't cover anything important.
// // That will be easier once https://github.com/rust-windowing/winit/pull/3890 lands
// window.outer_size()
// } else {
// window.inner_size()
// };
let screen_size_in_pixels = egui::vec2(size.width as f32, size.height as f32);
let screen_size_in_points = screen_size_in_pixels / self.pixels_per_point();

// On Windows, a minimized window will have 0 width and height.
// See: https://github.com/rust-windowing/winit/issues/208
// This solves an issue where egui window positions would be changed when minimizing on Windows.
self.egui_input.screen_rect = (screen_size_in_points.x > 0.0
&& screen_size_in_points.y > 0.0)
.then(|| Rect::from_min_size(Pos2::ZERO, screen_size_in_points));

EventResponse {
repaint: true,
consumed: false,
Expand All @@ -313,14 +330,14 @@ impl State {
}
}
WindowEvent::MouseWheel { delta, phase, .. } => {
self.on_mouse_wheel(window, *delta, *phase);
self.on_mouse_wheel(*delta, *phase);
EventResponse {
repaint: true,
consumed: self.egui_ctx.wants_pointer_input(),
}
}
WindowEvent::CursorMoved { position, .. } => {
self.on_cursor_moved(window, *position);
self.on_cursor_moved(*position);
EventResponse {
repaint: true,
consumed: self.egui_ctx.is_using_pointer(),
Expand All @@ -336,7 +353,7 @@ impl State {
}
// WindowEvent::TouchpadPressure {device_id, pressure, stage, .. } => {} // TODO(emilk)
WindowEvent::Touch(touch) => {
self.on_touch(window, touch);
self.on_touch(touch);
let consumed = match touch.phase {
winit::event::TouchPhase::Started
| winit::event::TouchPhase::Ended
Expand Down Expand Up @@ -505,7 +522,6 @@ impl State {
| WindowEvent::CursorEntered { .. }
| WindowEvent::Destroyed
| WindowEvent::Occluded(_)
| WindowEvent::Resized(_)
| WindowEvent::Moved(_)
| WindowEvent::TouchpadPressure { .. }
| WindowEvent::CloseRequested => EventResponse {
Expand Down Expand Up @@ -546,11 +562,9 @@ impl State {
}

WindowEvent::PanGesture { delta, phase, .. } => {
let pixels_per_point = pixels_per_point(&self.egui_ctx, window);

self.egui_input.events.push(egui::Event::MouseWheel {
unit: egui::MouseWheelUnit::Point,
delta: Vec2::new(delta.x, delta.y) / pixels_per_point,
delta: Vec2::new(delta.x, delta.y) / self.pixels_per_point(),
phase: to_egui_touch_phase(*phase),
modifiers: self.egui_input.modifiers,
});
Expand Down Expand Up @@ -640,17 +654,9 @@ impl State {
}
}

fn on_cursor_moved(
&mut self,
window: &Window,
pos_in_pixels: winit::dpi::PhysicalPosition<f64>,
) {
let pixels_per_point = pixels_per_point(&self.egui_ctx, window);

let pos_in_points = egui::pos2(
pos_in_pixels.x as f32 / pixels_per_point,
pos_in_pixels.y as f32 / pixels_per_point,
);
fn on_cursor_moved(&mut self, pos_in_pixels: winit::dpi::PhysicalPosition<f64>) {
let pos_in_points =
egui::pos2(pos_in_pixels.x as f32, pos_in_pixels.y as f32) / self.pixels_per_point();
self.pointer_pos_in_points = Some(pos_in_points);

if self.simulate_touch_screen {
Expand All @@ -674,18 +680,14 @@ impl State {
}
}

fn on_touch(&mut self, window: &Window, touch: &winit::event::Touch) {
let pixels_per_point = pixels_per_point(&self.egui_ctx, window);

fn on_touch(&mut self, touch: &winit::event::Touch) {
// Emit touch event
self.egui_input.events.push(egui::Event::Touch {
device_id: egui::TouchDeviceId(egui::epaint::util::hash(touch.device_id)),
id: egui::TouchId::from(touch.id),
phase: to_egui_touch_phase(touch.phase),
pos: egui::pos2(
touch.location.x as f32 / pixels_per_point,
touch.location.y as f32 / pixels_per_point,
),
pos: egui::pos2(touch.location.x as f32, touch.location.y as f32)
/ self.pixels_per_point(),
force: match touch.force {
Some(winit::event::Force::Normalized(force)) => Some(force as f32),
Some(winit::event::Force::Calibrated {
Expand All @@ -705,14 +707,14 @@ impl State {
winit::event::TouchPhase::Started => {
self.pointer_touch_id = Some(touch.id);
// First move the pointer to the right location
self.on_cursor_moved(window, touch.location);
self.on_cursor_moved(touch.location);
self.on_mouse_button_input(
winit::event::ElementState::Pressed,
winit::event::MouseButton::Left,
);
}
winit::event::TouchPhase::Moved => {
self.on_cursor_moved(window, touch.location);
self.on_cursor_moved(touch.location);
}
winit::event::TouchPhase::Ended => {
self.pointer_touch_id = None;
Expand All @@ -736,34 +738,26 @@ impl State {

fn on_mouse_wheel(
&mut self,
window: &Window,
delta: winit::event::MouseScrollDelta,
phase: winit::event::TouchPhase,
) {
let pixels_per_point = pixels_per_point(&self.egui_ctx, window);

{
let (unit, delta) = match delta {
winit::event::MouseScrollDelta::LineDelta(x, y) => {
(egui::MouseWheelUnit::Line, egui::vec2(x, y))
}
winit::event::MouseScrollDelta::PixelDelta(winit::dpi::PhysicalPosition {
x,
y,
}) => (
egui::MouseWheelUnit::Point,
egui::vec2(x as f32, y as f32) / pixels_per_point,
),
};
let phase = to_egui_touch_phase(phase);
let modifiers = self.egui_input.modifiers;
self.egui_input.events.push(egui::Event::MouseWheel {
unit,
delta,
phase,
modifiers,
});
}
let (unit, delta) = match delta {
winit::event::MouseScrollDelta::LineDelta(x, y) => {
(egui::MouseWheelUnit::Line, egui::vec2(x, y))
}
winit::event::MouseScrollDelta::PixelDelta(winit::dpi::PhysicalPosition { x, y }) => (
egui::MouseWheelUnit::Point,
egui::vec2(x as f32, y as f32) / self.pixels_per_point(),
),
};
let phase = to_egui_touch_phase(phase);
let modifiers = self.egui_input.modifiers;
self.egui_input.events.push(egui::Event::MouseWheel {
unit,
delta,
phase,
modifiers,
});
}

fn on_keyboard_input(&mut self, event: &winit::event::KeyEvent) {
Expand Down Expand Up @@ -917,8 +911,7 @@ impl State {
}

if let Some(ime) = ime {
let pixels_per_point = pixels_per_point(&self.egui_ctx, window);
let ime_rect_px = pixels_per_point * ime.rect;
let ime_rect_px = self.pixels_per_point() * ime.rect;
if self.ime_rect_px != Some(ime_rect_px)
|| self.egui_ctx.input(|i| !i.events.is_empty())
{
Expand Down Expand Up @@ -973,6 +966,18 @@ impl State {
self.current_cursor_icon = None;
}
}

/// Calculate the `pixels_per_point` for a given window, given the current egui zoom factor
fn pixels_per_point(&self) -> f32 {
self.egui_input
.viewports
.get(&self.viewport_id)
.expect("No viewport")
.native_pixels_per_point
// .expect("ScaleFactorChanged must have been raised")
.unwrap_or(1f32)
* self.egui_ctx.zoom_factor()
}
}

fn to_egui_touch_phase(phase: winit::event::TouchPhase) -> egui::TouchPhase {
Expand Down Expand Up @@ -1027,6 +1032,7 @@ pub fn update_viewport_info(
is_init: bool,
) {
profiling::function_scope!();
// TODO: Keep size and scale consistent with the event loop?
let pixels_per_point = pixels_per_point(egui_ctx, window);

let has_a_position = match window.is_minimized() {
Expand Down Expand Up @@ -1406,6 +1412,7 @@ fn process_viewport_command(

log::trace!("Processing ViewportCommand::{command:?}");

// TODO: keep this consistent with the event loop instead of requerying it from the window
let pixels_per_point = pixels_per_point(egui_ctx, window);

match command {
Expand Down Expand Up @@ -1441,6 +1448,7 @@ fn process_viewport_command(
// because the linux backend converts physical to logical and back again.
// So let's just assume it worked:

// TODO: Don't call inner_size(), but use the returned size
info.inner_rect = inner_rect_in_points(window, pixels_per_point);
info.outer_rect = outer_rect_in_points(window, pixels_per_point);
} else {
Expand Down
8 changes: 2 additions & 6 deletions crates/egui/src/containers/panel.rs
Original file line number Diff line number Diff line change
Expand Up @@ -255,9 +255,7 @@ impl<'a> PanelSizer<'a> {
let side = self.panel.side;
let size_range = self.panel.size_range;

if is_resizing && pointer.is_some() {
let pointer = pointer.unwrap();

if is_resizing && let Some(pointer) = pointer {
match side {
PanelSide::Vertical(side) => {
self.size = (pointer.x - side.side_x(self.panel_rect)).abs();
Expand Down Expand Up @@ -802,9 +800,7 @@ impl Panel {
let resize_id = self.id.with("__resize");
let resize_response = ui.ctx().read_response(resize_id);

if resize_response.is_some() {
let resize_response = resize_response.unwrap();

if let Some(resize_response) = resize_response {
// NOTE(sharky98): The original code was initializing to
// false first, but it doesn't seem necessary.
let is_resizing = resize_response.dragged();
Expand Down
Loading
Loading