Skip to content

Conversation

lucasmerlin
Copy link
Collaborator

@lucasmerlin lucasmerlin commented Jul 14, 2025

Currently ui.put moves the cursor after the placed widget. In my opinion that is a bit unexpected and counterproductive in most cases where ui.put makes sense.

The following example breakes with the current behavior and looks right with my change:

            ui.horizontal(|ui| {
                let custom_button_id = Id::new("custom_button");
                let response = Button::new((
                    Atom::custom(custom_button_id, Vec2::splat(18.0)),
                    "Look at my mini button!",
                ))
                .atom_ui(ui);
                if let Some(rect) = response.rect(custom_button_id) {
                    ui.put(rect, Button::new("🔎").frame_when_inactive(false));
                }

                let custom_button_id = Id::new("custom_button");
                let response = Button::new((
                    Atom::custom(custom_button_id, Vec2::splat(18.0)),
                    "Look at my mini button!",
                ))
                .atom_ui(ui);
                if let Some(rect) = response.rect(custom_button_id) {
                    ui.put(rect, Button::new("🔎").frame_when_inactive(false));
                }
            });

            ui.add_space(10.0);

            let response = ui.button("Notifications");

            ui.put(
                Rect::from_center_size(response.rect.right_top(), Vec2::splat(12.0)),
                |ui: &mut Ui| {
                    Frame::new()
                        .fill(Color32::RED)
                        .corner_radius(10.0)
                        .show(ui, |ui| {
                            ui.label(RichText::new("11").size(8.0).color(Color32::WHITE));
                        }).response
                },
            );

            ui.button("Some other button");
Screenshot 2025-07-14 at 10 58 30 Screenshot 2025-07-14 at 10 58 51

I had a look at reruns source code and there are no uses of ui.put that would break with this change (very little usages in general).

Alternatives

Instead of a breaking change we could of course instead introduce a new metheod (e.g. Ui::place?).

Copy link

Preview available at https://egui-pr-preview.github.io/pr/7359-lucasui-put-cursor
Note that it might take a couple seconds for the update to show up after the preview_build workflow has completed.

@lucasmerlin lucasmerlin changed the title Change Ui::put to not affect the current Uis cursor ⚠️ Change Ui::put to not affect the current Uis cursor Jul 14, 2025
@lucasmerlin
Copy link
Collaborator Author

Change it to Ui::place and deprecate put

@lucasmerlin lucasmerlin changed the title ⚠️ Change Ui::put to not affect the current Uis cursor Add Ui::place, to place widgets without changing the cursor Sep 3, 2025
@lucasmerlin
Copy link
Collaborator Author

Ive now added a new Ui::place and reverted the Ui::put behaviour. I think when we initially went through this we decided to deprecate Ui::put but I think it's fine to keep it around.

@lucasmerlin lucasmerlin requested a review from emilk September 3, 2025 08:38
@lucasmerlin lucasmerlin added this to the 0.32.2 milestone Sep 4, 2025
@lucasmerlin lucasmerlin merged commit d3cd6d4 into main Sep 4, 2025
65 of 66 checks passed
@lucasmerlin lucasmerlin deleted the lucas/ui-put-cursor branch September 4, 2025 08:07
lucasmerlin added a commit that referenced this pull request Sep 4, 2025
* Closes <#7353>

Currently `ui.put` moves the cursor after the placed widget. In my
opinion that is a bit unexpected and counterproductive in most cases
where `ui.put` makes sense.

The following example breakes with the current behavior and looks right
with my change:
```rs
            ui.horizontal(|ui| {
                let custom_button_id = Id::new("custom_button");
                let response = Button::new((
                    Atom::custom(custom_button_id, Vec2::splat(18.0)),
                    "Look at my mini button!",
                ))
                .atom_ui(ui);
                if let Some(rect) = response.rect(custom_button_id) {
                    ui.put(rect, Button::new("🔎").frame_when_inactive(false));
                }

                let custom_button_id = Id::new("custom_button");
                let response = Button::new((
                    Atom::custom(custom_button_id, Vec2::splat(18.0)),
                    "Look at my mini button!",
                ))
                .atom_ui(ui);
                if let Some(rect) = response.rect(custom_button_id) {
                    ui.put(rect, Button::new("🔎").frame_when_inactive(false));
                }
            });

            ui.add_space(10.0);

            let response = ui.button("Notifications");

            ui.put(
                Rect::from_center_size(response.rect.right_top(), Vec2::splat(12.0)),
                |ui: &mut Ui| {
                    Frame::new()
                        .fill(Color32::RED)
                        .corner_radius(10.0)
                        .show(ui, |ui| {
                            ui.label(RichText::new("11").size(8.0).color(Color32::WHITE));
                        }).response
                },
            );

            ui.button("Some other button");
```

<img width="253" height="86" alt="Screenshot 2025-07-14 at 10 58 30"
src="https://github.com/user-attachments/assets/fca56e60-e3c0-4b59-8e2d-0a39aefea9f9"
/>


<img width="361" height="107" alt="Screenshot 2025-07-14 at 10 58 51"
src="https://github.com/user-attachments/assets/85e2fbf9-9174-41e0-adaa-60c721b16bf6"
/>

I had a look at reruns source code and there are no uses of `ui.put`
that would break with this change (very little usages in general).

## Alternatives
Instead of a breaking change we could of course instead introduce a new
metheod (e.g. `Ui::place`?).
lucasmerlin added a commit that referenced this pull request Sep 4, 2025
* Closes <#7353>

Currently `ui.put` moves the cursor after the placed widget. In my
opinion that is a bit unexpected and counterproductive in most cases
where `ui.put` makes sense.

The following example breakes with the current behavior and looks right
with my change:
```rs
            ui.horizontal(|ui| {
                let custom_button_id = Id::new("custom_button");
                let response = Button::new((
                    Atom::custom(custom_button_id, Vec2::splat(18.0)),
                    "Look at my mini button!",
                ))
                .atom_ui(ui);
                if let Some(rect) = response.rect(custom_button_id) {
                    ui.put(rect, Button::new("🔎").frame_when_inactive(false));
                }

                let custom_button_id = Id::new("custom_button");
                let response = Button::new((
                    Atom::custom(custom_button_id, Vec2::splat(18.0)),
                    "Look at my mini button!",
                ))
                .atom_ui(ui);
                if let Some(rect) = response.rect(custom_button_id) {
                    ui.put(rect, Button::new("🔎").frame_when_inactive(false));
                }
            });

            ui.add_space(10.0);

            let response = ui.button("Notifications");

            ui.put(
                Rect::from_center_size(response.rect.right_top(), Vec2::splat(12.0)),
                |ui: &mut Ui| {
                    Frame::new()
                        .fill(Color32::RED)
                        .corner_radius(10.0)
                        .show(ui, |ui| {
                            ui.label(RichText::new("11").size(8.0).color(Color32::WHITE));
                        }).response
                },
            );

            ui.button("Some other button");
```

<img width="253" height="86" alt="Screenshot 2025-07-14 at 10 58 30"
src="https://github.com/user-attachments/assets/fca56e60-e3c0-4b59-8e2d-0a39aefea9f9"
/>


<img width="361" height="107" alt="Screenshot 2025-07-14 at 10 58 51"
src="https://github.com/user-attachments/assets/85e2fbf9-9174-41e0-adaa-60c721b16bf6"
/>

I had a look at reruns source code and there are no uses of `ui.put`
that would break with this change (very little usages in general).

## Alternatives
Instead of a breaking change we could of course instead introduce a new
metheod (e.g. `Ui::place`?).
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Cursor position goes backwards leading to overlapping widgets

2 participants