Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Avoid deadlocks by using lambdas for context lock #2625

Merged
merged 26 commits into from
Jan 25, 2023
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
Prev Previous commit
Next Next commit
Add ctx.screen_rect() helper function
  • Loading branch information
emilk committed Jan 24, 2023
commit a2dffd0c4740b5b3324ad17550b32b9554472bf9
2 changes: 1 addition & 1 deletion crates/egui/src/containers/area.rs
Original file line number Diff line number Diff line change
Expand Up @@ -358,7 +358,7 @@ impl Prepared {
}

pub(crate) fn content_ui(&self, ctx: &Context) -> Ui {
let screen_rect = ctx.input(|i| i.screen_rect());
let screen_rect = ctx.screen_rect();

let bounds = if let Some(bounds) = self.drag_bounds {
bounds.intersect(screen_rect) // protect against infinite bounds
Expand Down
2 changes: 1 addition & 1 deletion crates/egui/src/containers/combo_box.rs
Original file line number Diff line number Diff line change
Expand Up @@ -248,7 +248,7 @@ fn combo_box_dyn<'c, R>(

let above_or_below =
if ui.next_widget_position().y + ui.spacing().interact_size.y + popup_height
< ui.input(|i| i.screen_rect().bottom())
< ui.ctx().screen_rect().bottom()
{
AboveOrBelow::Below
} else {
Expand Down
6 changes: 3 additions & 3 deletions crates/egui/src/containers/panel.rs
Original file line number Diff line number Diff line change
Expand Up @@ -335,7 +335,7 @@ impl SidePanel {
let layer_id = LayerId::background();
let side = self.side;
let available_rect = ctx.available_rect();
let clip_rect = ctx.input(|i| i.screen_rect());
let clip_rect = ctx.screen_rect();
let mut panel_ui = Ui::new(ctx.clone(), layer_id, self.id, available_rect, clip_rect);

let inner_response = self.show_inside_dyn(&mut panel_ui, add_contents);
Expand Down Expand Up @@ -787,7 +787,7 @@ impl TopBottomPanel {
let available_rect = ctx.available_rect();
let side = self.side;

let clip_rect = ctx.input(|i| i.screen_rect());
let clip_rect = ctx.screen_rect();
let mut panel_ui = Ui::new(ctx.clone(), layer_id, self.id, available_rect, clip_rect);

let inner_response = self.show_inside_dyn(&mut panel_ui, add_contents);
Expand Down Expand Up @@ -1044,7 +1044,7 @@ impl CentralPanel {
let layer_id = LayerId::background();
let id = Id::new("central_panel");

let clip_rect = ctx.input(|i| i.screen_rect());
let clip_rect = ctx.screen_rect();
let mut panel_ui = Ui::new(ctx.clone(), layer_id, id, available_rect, clip_rect);

let inner_response = self.show_inside_dyn(&mut panel_ui, add_contents);
Expand Down
11 changes: 5 additions & 6 deletions crates/egui/src/containers/popup.rs
Original file line number Diff line number Diff line change
Expand Up @@ -156,14 +156,13 @@ fn show_tooltip_at_avoid_dyn<'c, R>(
let spacing = 4.0;

// if there are multiple tooltips open they should use the same common_id for the `tooltip_size` caching to work.
let mut frame_state = ctx.frame_state(|fs| {
fs.tooltip_state
let mut frame_state =
ctx.frame_state(|fs| fs.tooltip_state)
.unwrap_or(crate::frame_state::TooltipFrameState {
common_id: individual_id,
rect: Rect::NOTHING,
count: 0,
})
});
});

let mut position = if frame_state.rect.is_positive() {
avoid_rect = avoid_rect.union(frame_state.rect);
Expand All @@ -189,7 +188,7 @@ fn show_tooltip_at_avoid_dyn<'c, R>(
position.y -= expected_size.y;
}

position = position.at_most(ctx.input(|i| i.screen_rect().max) - expected_size);
position = position.at_most(ctx.screen_rect().max - expected_size);

// check if we intersect the avoid_rect
{
Expand All @@ -207,7 +206,7 @@ fn show_tooltip_at_avoid_dyn<'c, R>(
}
}

let position = position.at_least(ctx.input(|i| i.screen_rect().min));
let position = position.at_least(ctx.screen_rect().min);

let area_id = frame_state.common_id.with(frame_state.count);

Expand Down
2 changes: 1 addition & 1 deletion crates/egui/src/containers/resize.rs
Original file line number Diff line number Diff line change
Expand Up @@ -180,7 +180,7 @@ impl Resize {
.at_least(self.min_size)
.at_most(self.max_size)
.at_most(
ui.input(|i| i.screen_rect().size()) - ui.spacing().window_margin.sum(), // hack for windows
ui.ctx().screen_rect().size() - ui.spacing().window_margin.sum(), // hack for windows
);

State {
Expand Down
17 changes: 11 additions & 6 deletions crates/egui/src/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -776,7 +776,7 @@ impl Context {

/// Get a full-screen painter for a new or existing layer
pub fn layer_painter(&self, layer_id: LayerId) -> Painter {
let screen_rect = self.input(|i| i.screen_rect());
let screen_rect = self.screen_rect();
Painter::new(self.clone(), layer_id, screen_rect)
}

Expand All @@ -785,6 +785,11 @@ impl Context {
Self::layer_painter(self, LayerId::debug())
}

/// Position and size of the egui area.
pub fn screen_rect(&self) -> Rect {
self.input(|i| i.screen_rect())
}

/// How much space is still available after panels has been added.
/// This is the "background" area, what egui doesn't cover with panels (but may cover with windows).
/// This is also the area to which windows are constrained.
Expand Down Expand Up @@ -1082,13 +1087,13 @@ impl Context {
if window.width() > area.width() {
// Allow overlapping side bars.
// This is important for small screens, e.g. mobiles running the web demo.
(area.min.x, area.max.x) =
self.input(|i| (i.screen_rect().min.x, i.screen_rect().max.x));
let screen_rect = self.screen_rect();
(area.min.x, area.max.x) = (screen_rect.min.x, screen_rect.max.x);
}
if window.height() > area.height() {
// Allow overlapping top/bottom bars:
(area.min.y, area.max.y) =
self.input(|i| (i.screen_rect().min.y, i.screen_rect().max.y));
let screen_rect = self.screen_rect();
(area.min.y, area.max.y) = (screen_rect.min.y, screen_rect.max.y);
}

let mut pos = window.min;
Expand Down Expand Up @@ -1549,7 +1554,7 @@ impl Context {
size *= (max_preview_size.y / size.y).min(1.0);
ui.image(texture_id, size).on_hover_ui(|ui| {
// show larger on hover
let max_size = 0.5 * ui.ctx().input(|i| i.screen_rect().size());
let max_size = 0.5 * ui.ctx().screen_rect().size();
let mut size = vec2(w as f32, h as f32);
size *= max_size.x / size.x.max(max_size.x);
size *= max_size.y / size.y.max(max_size.y);
Expand Down
2 changes: 1 addition & 1 deletion crates/egui_demo_app/src/wrap_app.rs
Original file line number Diff line number Diff line change
Expand Up @@ -358,7 +358,7 @@ impl WrapApp {
let painter =
ctx.layer_painter(LayerId::new(Order::Foreground, Id::new("file_drop_target")));

let screen_rect = ctx.input(|i| i.screen_rect());
let screen_rect = ctx.screen_rect();
painter.rect_filled(screen_rect, 0.0, Color32::from_black_alpha(192));
painter.text(
screen_rect.center(),
Expand Down
2 changes: 1 addition & 1 deletion crates/egui_demo_lib/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,6 @@ fn test_egui_zero_window_size() {
/// Detect narrow screens. This is used to show a simpler UI on mobile devices,
/// especially for the web demo at <https://egui.rs>.
pub fn is_mobile(ctx: &egui::Context) -> bool {
let screen_size = ctx.input(|i| i.screen_rect().size());
let screen_size = ctx.screen_rect().size();
screen_size.x < 550.0
}
2 changes: 1 addition & 1 deletion examples/file_dialog/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ fn preview_files_being_dropped(ctx: &egui::Context) {
let painter =
ctx.layer_painter(LayerId::new(Order::Foreground, Id::new("file_drop_target")));

let screen_rect = ctx.input(|i| i.screen_rect());
let screen_rect = ctx.screen_rect();
painter.rect_filled(screen_rect, 0.0, Color32::from_black_alpha(192));
painter.text(
screen_rect.center(),
Expand Down