1
0
mirror of https://github.com/emilk/egui.git synced 2026-08-29 12:50:04 -04:00
Commit Graph

1015 Commits

Author SHA1 Message Date
Lucas Meurer
d232be740f Fix bug in ui stack color blending (#8021)
Co-authored-by: Emil Ernerfeldt <emil.ernerfeldt@gmail.com>
2026-03-25 13:40:54 +01:00
Emil Ernerfeldt
0b0c561a81 Fade out the edges of ScrollAreas (#8018)
## Before:
<img width="381" height="307" alt="image"
src="https://github.com/user-attachments/assets/0528ae2a-44bf-4d9e-89a4-c3f4ab438eb2"
/>

It is very hard here to realize this is a scrollable area

## After
<img width="383" height="310" alt="image"
src="https://github.com/user-attachments/assets/9e0ee6de-8b96-4e5c-a505-f57977010990"
/>

The fade at the bottom tells the user they should try scrolling.

You can turn if off with `style.spacing.scroll.fade.enabled`
2026-03-25 12:53:00 +01:00
Lucas Meurer
845b8c2f09 Make egui::IdSet public (#8019)
It wasn't public before
2026-03-25 12:46:49 +01:00
Emil Ernerfeldt
e8f04292a9 Add UiStack::bg_color (#8020)
This lets you ask for the background color of a ui with
`ui.stack().bg_color()`
2026-03-25 12:41:35 +01:00
Emil Ernerfeldt
bfbf23b4fb Add Ui::is_tooltip (#8016) 2026-03-25 10:11:30 +01:00
Emil Ernerfeldt
12b5045633 Add Context::time (#8017) 2026-03-25 10:11:21 +01:00
Emil Ernerfeldt
2ccc8e8bab Add Context::text_edit_focused (#8014) 2026-03-25 09:21:39 +01:00
Lucas Meurer
4feac890aa Respect WidgetVisuals::expansion in TextEdit (#8013)
This broke in #7587

---------

Co-authored-by: Emil Ernerfeldt <emil.ernerfeldt@gmail.com>
2026-03-24 17:33:20 +01:00
Lucas Meurer
0d065f9e78 Add Response::parent_id and improve warn_if_rect_changes_id (#8010)
Reduces the amount of false positives

---------

Co-authored-by: Emil Ernerfeldt <emil.ernerfeldt@gmail.com>
2026-03-24 16:22:44 +01:00
Emil Ernerfeldt
a1af9abe70 Shrink the byte-size of Response slightly (#8011)
Small optimization! 96 -> 88 bytes, so no huge win.
2026-03-24 15:46:56 +01:00
rustbasic
5ed92c3011 Add Button::left_text (#7955)
feat: Add left_text() to egui::Button

This PR introduces the `left_text()` method to `egui::Button`. It
enables placing additional text content on the left side of the button's
primary label, which is useful for displaying auxiliary information,
labels, and for facilitating left-aligned text within the button.

```rust
                            let is_selected = true;
                            let selectable_label_widget = egui::Button::selectable(
                                is_selected,
                                "",
                            ).left_text("Left");

                            let desired_width = ui.available_width();
                            let desired_height = ui.spacing().interact_size.y;

                            interaction_response = ui.add_sized(
                                egui::vec2(desired_width, desired_height),
                                selectable_label_widget,
                            );
```
2026-03-24 14:03:20 +01:00
Frank
405eb81578 Fix menu keyboard toggle for open submenus (#7957)
Summary
This PR fixes submenu keyboard parity: pressing Enter/Space on an
already-open submenu button now collapses that submenu (matching
top-level menu button behavior).

What changed
Updated submenu interaction logic to distinguish pointer primary clicks
from keyboard/accessibility-triggered clicks.
Kept pointer/touch behavior unchanged (submenu button clicks still don’t
auto-close submenu).
Added regression tests for:
keyboard open of nested submenu,
keyboard close (second Enter) of nested submenu,
pointer clicks on submenu button keeping submenu open.


Validation
cargo test -p egui_kittest --test regression_tests

Breaking changes
None. Behavior change is limited to keyboard/accessibility activation of
already-open submenu buttons.

* Closes <https://github.com/emilk/egui/issues/7926> 
* [ X ] I have followed the instructions in the PR template

---------

Co-authored-by: Lucas Meurer <hi@lucasmerlin.me>
2026-03-24 14:03:00 +01:00
Umaĵo
b4f9cd7140 Much improved IME (#7967)
<!--
Please read the "Making a PR" section of
[`CONTRIBUTING.md`](https://github.com/emilk/egui/blob/main/CONTRIBUTING.md)
before opening a Pull Request!

* Keep your PR:s small and focused.
* The PR title is what ends up in the changelog, so make it descriptive!
* If applicable, add a screenshot or gif.
* If it is a non-trivial addition, consider adding a demo for it to
`egui_demo_lib`, or a new example.
* Do NOT open PR:s from your `master` branch, as that makes it hard for
maintainers to test and add commits to your PR.
* Remember to run `cargo fmt` and `cargo clippy`.
* Open the PR as a draft until you have self-reviewed it and run
`./scripts/check.sh`.
* When you have addressed a PR comment, mark it as resolved.

Please be patient! I will review your PR, but my time is limited!
-->

* Closes #7809
* Closes #7876
* Closes #7908
* Supersedes #7877
* Supersedes #7898
* The author of the PR above replaced it with #7914, which additionally
fixes another IME issue. I believe that fix deserves a separate PR.
* Reverts #4794  
* [x] I have followed the instructions in the PR template

This approach is better than #7898 (#7914) because it correctly handles
all three major IME types (Chinese, Japanese, and Korean) without
requiring a predefined “IME mode”.

## Environments I haved tested this PR in

<details><summary>macOS 15.7.3 (AArch64, Host of other virtual
machines)</summary>

Run command: `cargo run -p egui_demo_app --release`

Tested IMEs:

- builtin Chinese IME (Shuangpin - Simplified)
- builtin Japanese IME (Romaji)
- builtin Korean IME (2-Set)
</details>

<details><summary>Windows 11 25H2 (AArch64, Virtual Machine)</summary>

Build command: `cargo build --release -p egui_demo_app
--target=x86_64-pc-windows-gnu --features=glow --no-default-features`

(I cannot use `wgpu` due to [this
bug](https://github.com/emilk/egui/issues/4381), which prevents
debugging inside the VM. Anyways, the rendering backend should be
irrelevant here.)

Tested IMEs:

- builtin Chinese IME (Shuangpin)
- Sogou IME (Chinese Shuangpin)
- WeType IME (Chinese Shuangpin)
- builtin Japanese IME (Hiragana)
- builtin Korean IME (2 Beolsik)
</details>

<details><summary>Linux [Wayland + IBus] (AArch64, Virtual
Machine)</summary>

Fedora KDE Plasma Desktop 43 [Wayland + IBus 1.5.33-rc2]

(Not working at the moment because of [another
issue](https://github.com/emilk/egui/issues/7485) that will be fixed by
#7983. It is [a complicated
story](https://github.com/emilk/egui/pull/7973#issuecomment-4074627603).
)

> [!NOTE]
>
> IBus is partially broken in this system. The Input Method Selector
refuses to select IBus. As a workaround, I have to open System Settings
-> Virtual Keyboard and select “IBus Wayland” to start an IBus instance
that works in egui.
>
> The funny thing is: the Chinese Intelligent Pinyin IME is broken in
native Apps like System Settings and KWrite, but works correctly in
egui!
>
> <details><summary>Screencast: What</summary>
>
> ![2026-03-13 3 10
11 AM](https://github.com/user-attachments/assets/4001cf12-8089-46f5-9cf4-e41d8f77ee24)
> </details>

Build command: `cross build --release -p egui_demo_app
--target=aarch64-unknown-linux-gnu --features=wayland,wgpu
--no-default-features`

(The Linux toolchain on my mac is somehow broken, so I used `cross`
instead.)

Tested IMEs:

- Chinese Intelligent Pinyin IME (Shuangpin)
- Japanese Anthy IME (Hiragana)
- Korean Hangul IME
</details>

<details><summary>Linux [X11 + Fcitx5] (AArch64, Virtual
Machine)</summary>

Debian 13 [Cinnamon 6.4.10 + X11 + Fcitx5 5.1.2]

Build command: `cross build --release -p egui_demo_app
--target=aarch64-unknown-linux-gnu --features=x11,wgpu
--no-default-features`

Tested IMEs:

- Chinese Shuangpin IME
- Chinese Rime IME with `luna-pinyin`
- Japanese Mozc IME (Hiragana)
- Korean Hangul IME

Unlike macOS and Linux + Wayland, key-release events for keys processed
by the IME are still forwarded to `egui`. These appear to be harmless in
practice.
Unlike on Windows, however, they cannot be filtered reliably because
there are no corresponding key-press events marked as “processed by
IME”.

</details>

---

There are too many possible combinations to test (Operating Systems ×
[Desktop
Environment](https://en.wikipedia.org/wiki/Desktop_environment)s ×
[Windowing System](https://en.wikipedia.org/wiki/Windowing_system)s ×
[IMF](https://wiki.archlinux.org/title/Input_method#Input_method_framework)s
× [IME](https://en.wikipedia.org/wiki/Input_method)s × …), and I only
have access to a limited subset. For example, Google Japanese Input
refused to install on my Windows VM, and some paid Japanese IMEs are not
accessible to me. Therefore, I would appreciate feedback from people
other than me using all kinds of environments.

## Details

There are two possible approaches to removing keyboard events that have
already been processed by an IME:

* Approach 1: Filter out events inside `egui` that appear to have been
received during IME composition.
* Approach 2: Filter out such events in the platform backend
(terminology [borrowed from
imgui](https://github.com/ocornut/imgui/blob/master/docs/BACKENDS.md#using-standard-backends),
e.g. the `egui-winit` crate or the code under `web/` in the `eframe`
crate.).

Both approaches already exist in `egui`:

* #4794 uses the first approach, filtering these events in the
`TextEdit`-related code.
* `eframe` uses the second approach in its web integration. See:
<14afefa252/crates/eframe/src/web/events.rs (L173-L176)>

Compared to the first approach, the second has a clear advantage: when
events are passed from the platform backends into `egui`, they are
simplified and lose information. In contrast, events in the platform
backends are the original events, which allows them to be handled more
flexibly. This is also why #7898 (#7914), which attempts to address the
issue from within the `egui` crate, struggles to make all IMEs work
correctly at the same time and requires manually selecting an “IME
mode”: the events received by `egui` have already been reduced and
therefore lack necessary information.

A more appropriate solution is to consistently follow the second
approach, explicitly requiring platform backends not to forward events
that have already been processed by the IME to `egui`. This is the
method used in this PR. Specifically, this PR works within the
`egui-winit` crate, where the original `KeyboardInput` events can be
accessed. At least for key press events, these can be used directly to
determine whether the event has already been processed by the IME on
Windows (by checking whether `logical_key` equals
`winit:⌨️:NamedKey::Process`). This makes it straightforward to
ensure that all IMEs work correctly at the same time.

This PR also reverts #4794, which took the first approach. It filters
out some events that merely look like they were received during IME
composition but actually are not. It also messes up the order of those
events along the way.
As a result, it caused several IME-related issues. One of the sections
in the Demonstrations below will illustrate these problems.

## Demonstrations

<details><summary>Changes not included in this PR for displaying Unicode
characters in demonstrations</summary>

Download `unifont-17.0.03.otf` from
<https://unifoundry.com/pub/unifont/unifont-17.0.03/font-builds/>, and
place it at `crates/egui_demo_app/src/unifont-17.0.03.otf`.

In `crates/egui_demo_app/src/wrap_app.rs`, add these lines at the
beginning of `impl WrapApp`'s `pub fn new`:
```rust
        {
            const MAIN_FONT: &'static [u8] = include_bytes!("./unifont-17.0.03.otf");

            let mut fonts = egui::FontDefinitions::default();

            fonts.font_data.insert(
                "main-font".to_owned(),
                std::sync::Arc::new(egui::FontData::from_static(MAIN_FONT)),
            );

            let proportional = fonts
                .families
                .entry(egui::FontFamily::Proportional)
                .or_default();
            proportional.insert(0, "main-font".to_owned());

            cc.egui_ctx.set_fonts(fonts);
        }
```

(I took this from somewhere, but I forgot where it is. Sorry…)
</details>

[GNU Unifont](https://unifoundry.com/unifont/index.html) is licensed
under [OFL-1.1](https://unifoundry.com/OFL-1.1.txt).

### This PR Fixes: Focus on a single-line `TextEdit` is lost after
completing candidate selection with Japanese IME on Windows (#7809)

<details><summary>Screencast:  Japanese IME now behaves correctly while
Korean IME behaves as before</summary>


![7809](https://github.com/user-attachments/assets/6e92f6e6-fed4-46f4-96e1-e0e12dadc360)
</details>

### This PR Fixes: Committing Japanese IME text with <kbd>Enter</kbd>
inserts an unintended newline in multiline `TextEdit` on Windows (#7876)

<details><summary>Screencast:  Japanese IME now behaves correctly while
Korean IME behaves as before</summary>


![7876](https://github.com/user-attachments/assets/03d2cb22-fd0c-45fe-9132-e59fa39bfcf3)
</details>

### This PR Fixes: Backspacing deletes characters during composition in
certain Chinese IMEs (e.g., Sogou) on Windows (#7908)

<details><summary>Screencast:  Sogou IME now behaves
correctly</summary>


![7908](https://github.com/user-attachments/assets/2c63de28-26f0-4387-9c50-dceabfdbe99d)
</details>

### This PR Obsoletes #4794, because `egui` receives only IME events
during composition from now on

On Windows, “incompatible” events are filtered in `egui-winit`, aligning
the behavior with other systems.

<details><summary>Screencasts</summary>

Some Chinese IMEs on Windows:
![2026-03-13 12 25
37 AM](https://github.com/user-attachments/assets/064fd1c7-244b-4053-bd24-c65d768cd943)

The default Japanese IMEs on Windows:
![2026-03-13 12 28
33 AM](https://github.com/user-attachments/assets/f799b0b5-350b-4b05-a769-bcef16255bdb)
</details>

The 2-set Korean IMEs handle arrow keys differently. It will be
discussed in the next section.

### This PR Reverts #4794, because it introduced several bugs

Some of its bugs have already been worked around in the past, but those
workarounds might also be problematic. For example, #4912 is a
workaround for a bug (#4908) introduced by #4794, and that workaround is
in fact the root cause of the macOS backspacing bug I have worked around
with #7810. (The reversion of #4912 is out of the scope of this PR, I
will do that in #7983.)

#### It Caused: Arrow keys are incorrectly blocked during typical Korean
IME composition

When composing Korean text using 2-Set IMEs, users should still be able
to move the cursor with arrow keys regardless if the composition is
committed.

##### Correct behavior

<details><summary>Screencasts</summary>

macOS TextEdit:
![2026-03-12 8 04
15 PM](https://github.com/user-attachments/assets/24383568-f51c-4a74-9251-adfd942cad8f)

Windows Notepad:
![2026-03-12 8 05
08 PM](https://github.com/user-attachments/assets/5a29a5b5-69b8-407b-b1a4-84fdb8f8847d)

With #4794 reverted, `egui` also behaves correctly (tested on Linux +
Wayland, macOS, and Windows):
![2026-03-12 8 03
51 PM](https://github.com/user-attachments/assets/fcb7f25c-1329-4eb1-82f2-1cea33dcca73)
</details>

##### Incorrect behavior caused by #4794

`remove_ime_incompatible_events` removed arrow-key events in such cases.
As a result, the first arrow key press only commits the composition, and
users need to press the arrow key again to move the cursor:

<details><summary>Screencast</summary>

![2026-03-12 8 06
40 PM](https://github.com/user-attachments/assets/6760c6bd-b6ce-44ea-b192-6bd165191c01)
</details>

This is essentially the same issue described here:
https://github.com/emilk/egui/pull/7877#issuecomment-3852719948

#### It Caused: Backspacing leaves the last character in Korean IME
pre-edit text not removed on macOS

<details><summary>Screencasts</summary>

Before this PR:
![2026-03-17 10 48
12 PM](https://github.com/user-attachments/assets/88021e7e-caf6-4aa9-8f73-ecffc63cda06)

After this PR:
![2026-03-17 10 47
23 PM](https://github.com/user-attachments/assets/379cd0db-24e0-4c0e-a5b4-edb37d3e1df7)
</details>

### Korean IMEs also use <kbd>Enter</kbd> to confirm Hanja selections,
and will not work properly in the Korean “IME mode” proposed by #7898
(#7914)

<details><summary>Screencast: Korean IME using <kbd>Enter</kbd> and
<kbd>Space</kbd> for confirmation (IBus Korean Hangul IME)</summary>

The screencast below demonstrates that some Korean IMEs handle Hanja
selection in a way similar to Japanese IMEs: the
<kbd>Up</kbd>/<kbd>Down</kbd> arrow keys are used to navigate
candidates, and <kbd>Enter</kbd> confirms the selected candidate.

![2026-03-13 6 39
17 AM](https://github.com/user-attachments/assets/0b054cc6-2251-4689-95a4-d69a9be36371)
</details>

<details><summary>Screencasts: Another example</summary>

Using the built-in Korean IME on Windows, I type two lines: the first
line in Hangul, and the second line as the same word converted to Hanja.

Correct behavior in Notepad (reference):

![7914-ref](https://github.com/user-attachments/assets/1e9f9315-eb71-497a-b6e2-2b11eb6bbf7f)

Behavior after applying this PR, which matches the Notepad behavior:

![7914-7967](https://github.com/user-attachments/assets/26f12b9f-9354-45b8-b2a8-ede28c34c5b1)

Behavior after applying #7914 with the “IME mode” set to Korean (which
is also the behavior before this PR being applied):

![7914-7914](https://github.com/user-attachments/assets/0f82a019-c491-4b64-a92a-d88d62dfbd84)
On the second line, each time a Hanja character is confirmed, an
unintended newline is inserted. This mirrors the Japanese IME issues
that are supposed to be fixed by setting the “IME mode” to Japanese.
(These Japanese IME issues are fixed in this PR as mentioned before.)

</details>
2026-03-24 11:58:58 +01:00
ilya sheprut
cc7cfd27ca Fix horizontal_wrapping row height after using text_edit_multiline (#8000)
* [x] I have followed the instructions in the PR template

This PR have two commits:
* **First commit** - introduction of tests and their canonization image.
Expected behaviour is that `horizontal_wrapped_multiline_row_height`
would match `horizontal_wrapped_multiline_row_height_reference`, but it
doesn't. There is a bug in `horizontal_wrapped` that breaks line height
after using `text_edit_multiline`.
* **Second commit** - fix. You can see that
`horizontal_wrapped_multiline_row_height` now looks like
`horizontal_wrapped_multiline_row_height_reference` (although it's not a
perfect match, upd: found, this is because of this issue:
https://github.com/emilk/egui/issues/4921).

I have used LLM to help me with this PR (codex + claude code).

BTW, I'm using horizontal_wrapped with end_row instead of vertical +
horizontal alternation, because I automatically generate my UI through
some complex interactions between elements in my code, and it's can be
that my `horizontal` starts in one function, and ends in another.
Something like `begin_horizontal`/`end_horizontal`/`get_current_layout`
would be very handy, related to
https://github.com/emilk/egui/issues/1004.

Also, I would like indent to be supported in `horizontal_wrapped`, or
also, to have `indent_start`/`indent_end`. This is why I used
`monospace("| ")` in my example, it simulates my use-case.
2026-03-24 11:37:37 +01:00
RndUsr123
2a03ae1348 Enables every combination of TextEdit and LayoutJob alignments (#7831)
<!--
Please read the "Making a PR" section of
[`CONTRIBUTING.md`](https://github.com/emilk/egui/blob/main/CONTRIBUTING.md)
before opening a Pull Request!

* Keep your PR:s small and focused.
* The PR title is what ends up in the changelog, so make it descriptive!
* If applicable, add a screenshot or gif.
* If it is a non-trivial addition, consider adding a demo for it to
`egui_demo_lib`, or a new example.
* Do NOT open PR:s from your `master` branch, as that makes it hard for
maintainers to test and add commits to your PR.
* Remember to run `cargo fmt` and `cargo clippy`.
* Open the PR as a draft until you have self-reviewed it and run
`./scripts/check.sh`.
* When you have addressed a PR comment, mark it as resolved.

Please be patient! I will review your PR, but my time is limited!
-->

This is a fix/improvement that makes all kinds of alignments work in
`TextEdit` when a custom `LayoutJob` with halign is used.


I used the simplest approach possible to avoid unwanted bugs as I wasn't
sure what's safe to change, but there's potentially better ways to
achieve this. In particular, I'm not sure I fully understand the
rationale behind aligning rows in a `Galley` based on the latter's
leftmost border, considering the size is what's ultimately used in
widgets (in `TextEdit` at least).

Regardless, here's a demo of this PR:


https://github.com/user-attachments/assets/5d9801d7-73af-4576-80c5-47f169700462


* [x] I have followed the instructions in the PR template

---------

Co-authored-by: Emil Ernerfeldt <emil.ernerfeldt@gmail.com>
2026-03-24 11:35:37 +01:00
Emil Ernerfeldt
7fbd1315ec Include LICENSE files in published crates (#8004)
* Closes https://github.com/emilk/egui/issues/7977
2026-03-24 11:28:49 +01:00
Lucas Meurer
c0ea6117e0 Use AtomLayoutResponse in TextEditOutput (#8003)
This is necessary to add e.g. buttons as prefix/suffix within the
textedit (so you can read the rect and place the button).

I'm not sure if deref on the AtomLayoutResponse is the right call but it
should make the migration easier and is generally convenient (but might
lead to some confusion).
2026-03-24 11:04:36 +01:00
Emil Ernerfeldt
b077cf9102 Add some example docs to atoms (#7997) 2026-03-23 15:50:57 +01:00
Emil Ernerfeldt
4714aa7d31 Fix instable IDs following animated panels (#7994)
* Found thanks to https://github.com/emilk/egui/pull/7984

If you put an animated `Panel` inside a `Ui`, then the automatic ids for
following widgets would differ when the panel was collapsed or open.
2026-03-21 21:52:52 +01:00
Lucas Meurer
8b2315375b TextEdit Atom prefix/suffix (#7587)
* part of https://github.com/emilk/egui/issues/7264
* part of https://github.com/emilk/egui/issues/7445

This PR changes the layout within the TextEdit to be done with
AtomLayout. It also adds a Prefix and Postfix that allows adding
permanent icons / icon buttons within the textedit.

Breaking changes:
- Removed `TextEdit::hint_text_font`. Hint text is an atom now, so the
font can be set that way

<img width="264" height="130" alt="Screenshot 2025-10-06 at 12 25 21"
src="https://github.com/user-attachments/assets/03b6b56b-ca82-4ac3-b5c0-585cca336834"
/>

---------

Co-authored-by: Emil Ernerfeldt <emil.ernerfeldt@gmail.com>
Co-authored-by: lucasmerlin <8009393+lucasmerlin@users.noreply.github.com>
2026-03-20 11:29:32 +01:00
Emil Ernerfeldt
ad510257de Quit on Ctrl-Q (#7985)
This adds `Ctrl-Q` as the default shortcut for closing the current egui
`Viewport`, which also means closing the entire application if you are
in the root viewport.

Can be configured by `egui::Options::quit_shortcuts`

On Mac, `cmd-Q` already triggers a quit, but not on all Linux:es.
2026-03-18 15:24:19 +01:00
Emil Ernerfeldt
265cf7ebae Add DebugOptions::warn_if_rect_changes_id (#7984)
If turned on (default in debug builds), if the exact same `Rect` exist
in two subsequent frames but with different `Id`s, a warning is logged
an a red rect is flashed on the screen.
2026-03-18 15:08:06 +01:00
Umaĵo
f32727ddca Improve IME, and restrict mac-specific workaround (#7973)
<!--
Please read the "Making a PR" section of
[`CONTRIBUTING.md`](https://github.com/emilk/egui/blob/main/CONTRIBUTING.md)
before opening a Pull Request!

* Keep your PR:s small and focused.
* The PR title is what ends up in the changelog, so make it descriptive!
* If applicable, add a screenshot or gif.
* If it is a non-trivial addition, consider adding a demo for it to
`egui_demo_lib`, or a new example.
* Do NOT open PR:s from your `master` branch, as that makes it hard for
maintainers to test and add commits to your PR.
* Remember to run `cargo fmt` and `cargo clippy`.
* Open the PR as a draft until you have self-reviewed it and run
`./scripts/check.sh`.
* When you have addressed a PR comment, mark it as resolved.

Please be patient! I will review your PR, but my time is limited!
-->

* Closes N/A
* [x] I have followed the instructions in the PR template

My PR that fixes the macOS backspacing issue (#7810) unfortunately
breaks text selection on Wayland (Fedora KDE Plasma Desktop 43 [Wayland,
with or without IBus]). I had actually tested on a Wayland setup but
failed to notice that :(

Windows and Linux+X11 (Debian 13 [Cinnamon 6.4.10 + X11 + fcitx5 5.1.2])
are not affected.

This PR fixes the issue by restricting the macOS fix to macOS-only.

<details><summary>Here is the correct behavior on Wayland after this PR
(and before #7810 is applied)</summary>

![2026-03-13 5 25
24 PM](https://github.com/user-attachments/assets/3b0831c1-1d96-4003-9109-4bfe68e06d40)
</details>

<details><summary>Here is the buggy behavior on Wayland before this
PR</summary>

![2026-03-13 5 31
58 PM](https://github.com/user-attachments/assets/c6d69382-0104-4e38-ad47-2d431f83f1fa)
</details>

## Cause of the Wayland issue

On Wayland, `winit` constantly emits `winit::event::Ime::Preedit("",
None)` events.

PR #7810 added these lines for handling `winit::event::Ime::Preedit(_,
None)` in `egui-winit` without considering the `target_os`:

14afefa252/crates/egui-winit/src/lib.rs (L619-L621)

As a result, while text is being selected, `egui-winit` receives these
`winit::event::Ime::Preedit("", None)` events from `winit` and forwards
them to `egui` as `egui::ImeEvent::Preedit("")`. `egui` then clears the
current text selection, because it currently does not distinguish
between IME pre-edit text and selected text.

---------

Co-authored-by: lucasmerlin <hi@lucasmerlin.me>
2026-03-16 20:09:07 +01:00
shuppy
5031c47cb2 Update accesskit to 0.24.0 (and related deps) (#7850)
this patch updates our deps to [accesskit
0.24.0](https://docs.rs/accesskit/0.24.0/accesskit/) (was
[0.21.1](https://docs.rs/accesskit/0.21.1/accesskit/)),
[accesskit_consumer
0.35.0](https://docs.rs/accesskit_consumer/0.35.0/accesskit_consumer/)
(was
[0.30.1](https://docs.rs/accesskit_consumer/0.30.1/accesskit_consumer/)),
and [accesskit_winit
0.32.0](https://docs.rs/accesskit_winit/0.32.0/accesskit_winit/) (was
[0.29.1](https://docs.rs/accesskit_winit/0.29.1/accesskit_winit/)),
allowing egui to be used in apps that use accessibility subtrees
(AccessKit/accesskit#655).

for now, we handle the subtree-related breaking changes by assuming that
egui will use [the root
tree](https://docs.rs/accesskit/0.24.0/accesskit/struct.TreeId.html#associatedconstant.ROOT),
which is good enough for [servoshell](https://github.com/servo/servo)
and does not require any API changes.


* [x] I have followed the instructions in the PR template

<img width="1185" height="954" alt="image"
src="https://github.com/user-attachments/assets/6acfb85a-096d-4a7b-963b-d8549bfc749f"
/>

---------

Co-authored-by: Luke Warlow <lwarlow@igalia.com>
Co-authored-by: lucasmerlin <hi@lucasmerlin.me>
Co-authored-by: Arnold Loubriat <datatriny@gmail.com>
2026-03-16 10:34:54 +01:00
Lucas Meurer
8b90dc60c6 ⚠️ Atom improvements: Atom::id, align, closure, max_size (#7958)
Migration guide:
- `AtomKind::Custom` has been removed. You can now set an id to any kind
via `Atom::custom` or `AtomExt::atom_id`.
2026-03-10 12:03:10 +01:00
valadaptive
699fc7e887 Add font variations API (#7859)
<!--
Please read the "Making a PR" section of
[`CONTRIBUTING.md`](https://github.com/emilk/egui/blob/main/CONTRIBUTING.md)
before opening a Pull Request!

* Keep your PR:s small and focused.
* The PR title is what ends up in the changelog, so make it descriptive!
* If applicable, add a screenshot or gif.
* If it is a non-trivial addition, consider adding a demo for it to
`egui_demo_lib`, or a new example.
* Do NOT open PR:s from your `master` branch, as that makes it hard for
maintainers to test and add commits to your PR.
* Remember to run `cargo fmt` and `cargo clippy`.
* Open the PR as a draft until you have self-reviewed it and run
`./scripts/check.sh`.
* When you have addressed a PR comment, mark it as resolved.

Please be patient! I will review your PR, but my time is limited!
-->

* Closes N/A
* [x] I have followed the instructions in the PR template

This was mostly from last month, but I never got around to submitting
it.

This PR adds font variation coordinates to the `TextFormat` struct, and
uses them when rendering text. The coordinates are stored in a
`SmallVec`; I've chosen to store up to 2 inline, which makes it take up
24 bytes (the minimum possible for a `SmallVec`). The variation axis
tags are stored as the `font_types::Tag` type, which I've chosen to
re-export from `epaint::text`.

The variation coordinates are resolved to a `skrifa::Location` during
font rendering/scaling, and are cached in the same way as all the other
scaled metrics. I've renamed the `ScaledMetrics` struct to
`StyledMetrics`, since it now also contains the resolved variation
coordinates. I haven't benchmarked the performance of text layout with
variation coordinates, but the existing text layout performance is
unchanged.

I've replaced the API for manually overriding a font's weight
(https://github.com/emilk/egui/pull/7790) with an API for manually
overriding any variation coordinates via `FontTweak`. This should
support the same use case as #7790 while being substantially more
flexible.

I have *not* yet added any higher-level API for mapping style attributes
(weight, width, slant, etc) to variation coordinates or to different
font faces within a single family. That's a pretty huge can of worms,
and it'd involve rethinking the split between `FontId` and `TextFormat`
(and whether `FontId` is so big that we should provide a way to reuse
it). This API is intentionally pretty low-level for now.

Likewise, I've intentionally not used variation coordinates when
computing a font's row height. I can't think of any fonts that change
their vertical metrics depending on variation axes, so this should be
fine for now.

---------

Co-authored-by: Emil Ernerfeldt <emil.ernerfeldt@gmail.com>
2026-03-03 22:58:42 +01:00
Emil Ernerfeldt
ee3e73bdf9 Fix: repaint on drag-and-drop files (#7953)
When someone drag-and-drops files onto an egui/eframe app, it makes
sense to wake it up
2026-03-03 17:02:30 +01:00
Emil Ernerfeldt
b733679760 Fix text color when selecting newline character (#7951)
* Closes https://github.com/emilk/egui/issues/7865
2026-03-03 13:27:56 +01:00
Lucas Meurer
a354c02e76 Add Atom prefix/suffix support to DragValue (#7949) 2026-03-03 11:35:29 +01:00
Emil Ernerfeldt
2be6e225bf Add ViewportInfo::occluded and visible (#7948)
* Part of https://github.com/emilk/egui/issues/5112
* Part of https://github.com/emilk/egui/issues/5113
* Part of https://github.com/emilk/egui/issues/5136

Once we support calling `App::logic` when an app is occluded or
minimized, it is useful to know that it is, in fact, occluded or
minimized.

---------

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2026-03-02 18:36:04 +01:00
Lucas Meurer
fd257b2e95 Use FnMut in __run_test_ui (#7933)
Matches the `__run_test_ctx` implementation
2026-02-24 14:27:45 +01:00
Lucas Meurer
e0bac4e260 Pass in an explicit id in UiBuilder, to avoid wrapping passed in ids with Id::new() (#7925)
I was really confused why I couldn't find the response for my ui with
explicit id. Turns out the id I passed in was wrapped by `Id::new`
2026-02-24 11:07:55 +01:00
Lucas Meurer
08f3fd2dc1 Fix scroll area not consuming scroll events (#7904)
This fixes scrolling in a nested scroll area also scrolling the outer
scroll area


https://github.com/user-attachments/assets/ade40b1e-c974-4806-8045-881bea590d4a
2026-02-17 11:08:18 +01:00
Emil Ernerfeldt
64a96ef391 Stop ctrl+arrow etc from moving focus (#7897)
Previously any pressing of arrow keys would move the focus, but now we
check that there are no modifier keys pressed down
2026-02-10 12:24:30 +01:00
Roman Popov
f1cde5aab4 Fix CentralPanel::show_inside_dyn to round panel_rect (#7868)
While using CentralPanel::show_inside_dyn inside egui_tiles I've noticed
that sometimes it renders "Unaligned" message with certain tile
positions. Match SidePanel behavior by calling round_ui() on the panel
rect.
<img width="364" height="173" alt="image"
src="https://github.com/user-attachments/assets/08a9cef3-67f8-49af-9ea7-75aff711186a"
/>

---------

Co-authored-by: Emil Ernerfeldt <emil.ernerfeldt@gmail.com>
2026-02-04 17:52:39 +01:00
Emil Ernerfeldt
83e61c6fb0 Improve docs of key/button "down" state (#7851) 2026-01-19 09:01:11 +01:00
Trương Hoàng Long
7fb4627dad Make FrameCache::get return a reference instead of cloning the cached value (#7834)
This is a breaking change.

- Enables using `FrameCache` in cases where the cached value cannot be
cloned.
- Improves use cases where only a reference to the cached value is
needed.
- If the user needs an owned value, they can clone it themselves.

Adding a `get_ref` method instead of changing `get` would avoid the
breaking change, but I didn't want to do so because it is kind of
expected for `get` to return `&V` when querying a collection.
2026-01-11 16:31:58 +01:00
Belu Antonie-Gabriel
a9e92525c0 Implemented distance threshold for double/triple clicks (#7817)
This change introduces a distance check to double and triple clicks.
Previously, double/triple clicks were determined solely by timing,
allowing clicks on different UI elements to trigger a
double_clicked()/triple_clicked() event.

By requiring consecutive clicks to occur within a specific radius
(max_multiple_click_dist), we prevent double_clicked()/triple_clicked()
events from triggering when a user clicks on two different, distant UI
elements in rapid succession.

<!--
Please read the "Making a PR" section of
[`CONTRIBUTING.md`](https://github.com/emilk/egui/blob/main/CONTRIBUTING.md)
before opening a Pull Request!

* Keep your PR:s small and focused.
* The PR title is what ends up in the changelog, so make it descriptive!
* If applicable, add a screenshot or gif.
* If it is a non-trivial addition, consider adding a demo for it to
`egui_demo_lib`, or a new example.
* Do NOT open PR:s from your `master` branch, as that makes it hard for
maintainers to test and add commits to your PR.
* Remember to run `cargo fmt` and `cargo clippy`.
* Open the PR as a draft until you have self-reviewed it and run
`./scripts/check.sh`.
* When you have addressed a PR comment, mark it as resolved.

Please be patient! I will review your PR, but my time is limited!
-->

* Closes <https://github.com/emilk/egui/issues/3508>
* [x] I have followed the instructions in the PR template
2026-01-07 16:20:16 +01:00
Emil Ernerfeldt
f8e763378a Remove CacheTrait::as_any_mut (#7833)
* Part of https://github.com/emilk/egui/issues/5876

No longer needed on modern MSRV
2026-01-05 18:33:38 +01:00
Ivor Wanders
0566fb17a5 Allow specifying override_redirect x11 window attribute (#7830) 2026-01-05 13:16:00 +01:00
Umaĵo
6d416fab2e Fix backspacing leaving last character in IME prediction not removed on macOS native and Safari (#7810)
<!--
Please read the "Making a PR" section of
[`CONTRIBUTING.md`](https://github.com/emilk/egui/blob/main/CONTRIBUTING.md)
before opening a Pull Request!

* Keep your PR:s small and focused.
* The PR title is what ends up in the changelog, so make it descriptive!
* If applicable, add a screenshot or gif.
* If it is a non-trivial addition, consider adding a demo for it to
`egui_demo_lib`, or a new example.
* Do NOT open PR:s from your `master` branch, as that makes it hard for
maintainers to test and add commits to your PR.
* Remember to run `cargo fmt` and `cargo clippy`.
* Open the PR as a draft until you have self-reviewed it and run
`./scripts/check.sh`.
* When you have addressed a PR comment, mark it as resolved.

Please be patient! I will review your PR, but my time is limited!
-->

* Closes N/A
* [x] I have followed the instructions in the PR template

## Before the fix

| Platform | Screenshot |
| - | - |
| macOS native |
![before-macos15-apple_shuangpin](https://github.com/user-attachments/assets/8397b236-7adf-4eca-9eb6-337e42c9efae)
|
| Safari |
![before-safari26](https://github.com/user-attachments/assets/1f4162a2-ccb7-4b42-960d-95aa3310f908)
|

## After the fix

| Platform | Screenshot |
| - | - |
| macOS native |
![after-macos15-apple_shuangpin](https://github.com/user-attachments/assets/8f50d43c-21bc-4c47-a7fb-86d0543c5088)
|
| Safari |
![after-safari26](https://github.com/user-attachments/assets/be4a69cd-8a0e-4512-865b-d6ebed2fd6c7)
|

(The font used in the screenshots is [GNU
Unifont](https://unifoundry.com/unifont/index.html), licensed under
[OFL-1.1.txt](https://unifoundry.com/OFL-1.1.txt).)
2026-01-05 12:51:09 +01:00
Lucas Meurer
f9bf0ee6c4 Don't focus Areas, Windows and ScrollAreas (#7827)
Currently, tabbing through egui demo app, there are a lot of widgets
that have invisible focus. Tabbing into a window for example takes 10
(!) presses of the tab key before the first widget within the window is
focused. Before that, the focus moves to each resize handle, the scroll
area and the scroll bar. At that point a user might think the focus is
entirely broken.

This pr removes the focusable sense from all these elements. Anything
that can be focused should somehow indicate that it currently has focus,
or the user could get frustrated.

It also adds a debug flag to always show the focused widget, so it's
easier to debug these cases
2026-01-05 12:50:52 +01:00
n4n5
06e491c5ec feat: add documentation to structs (#7800)
feat: add documentation to structs
2026-01-05 12:11:14 +01:00
n4n5
0a5cf3156e Improve docstring for egui_extras features (#7813)
It's nice to have


* [x] I have followed the instructions in the PR template
2026-01-05 11:44:21 +01:00
Bayley Foster
457f8f4467 plugin: export TypedPluginGuard and TypedPluginHandle (#7780)
We have made this patch internally on our fork as we use
`TypedPluginGuard` and `TypedPluginHandle` internally

* [x] I have followed the instructions in the PR template
2026-01-05 09:57:00 +01:00
Lucas Meurer
db76c5ca3b Fix new move_to_top flag breaking widget order (#7825)
* closes https://github.com/emilk/egui/issues/7812
* related https://github.com/emilk/egui/pull/7805

That pr introduced a bug that caused a mismatch in the `by_layer` /
`by_id` widget rects. This should fix it by updating the index of all
following widgets. Not super pretty and efficient, but I'm not sure if
there's a better way.

Maybe we could also just leave a "tombstone" / duplicate there in the
by_layer map so we don't need to update the indexes?
2026-01-05 08:22:54 +01:00
Emil Ernerfeldt
9e95b9ca50 Don't expand widgets on hover (#7808)
* Part of https://github.com/emilk/egui/issues/5605

This changes the default style of egui.

The problem with "expanding" widgets is that they now want to paint
outside their own bounds, which then requires all parent UIs to have
proper margins.

It also means hovered things are no longer properly aligned with every
other widget.
2025-12-22 22:30:53 +01:00
Emil Ernerfeldt
f53a9c96d5 Small refactor of debug assert 2025-12-22 22:03:29 +01:00
Emil Ernerfeldt
ec4313d8a8 Refactor: don't call ctx.global_style more than once 2025-12-22 22:01:23 +01:00
Emil Ernerfeldt
2984ff07cd Move window resize interaction to be over contents (#7807)
When resizing a window, it makes more sense that the resize "splitters"
are on top of the content. It makes them easier to hit.
2025-12-22 21:57:00 +01:00