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

18 Commits

Author SHA1 Message Date
Lucas Meurer
d06f5b5dfc Handle ViewportCommand::InnerSize in egui_kittest (#8350)
Useful to support resizing headless apps via `egui_inspection`
2026-07-28 10:54:45 +02:00
Umaĵo
5bf62ca4b3 Implement proper visuals for IME composition (#8083)
<!--
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 PR adds visual support for IME composition, including the cursor
and conversion segment.
These visuals works (mostly) well on native platforms (`egui-winit`). On
the web (`eframe/web`), support is limited by browser capabilities:
Chromium works well, Firefox shows partial improvement, and Safari
remains subpar.

> [!NOTE]
>
> For `eframe` on Windows, this feature is currently gated behind the
`windows_new_ime_composition_visuals` feature flag.

## Details

We extend `egui::ImeEvent::Preedit(String)` to `egui::ImeEvent::Preedit
{ text: String, active_range_chars: Option<std::ops::Range<usize>> }`.
The new `active_range_chars` field enables rendering of:
- the cursor (when the range is empty), and
- the conversion segment (when the range is non-empty)

in IME composition.

In `egui-winit`, we now use the range provided by
`winit::event::Ime::Preedit` instead of ignoring it.

In `eframe/web`, we derive the range from `selectionStart` and
`selectionEnd` on the text agent. This mapping is fully accurate only in
Chromium, but represents the best available approach for now.

## Demonstrations

### Chinese IMEs (Shuangpin)

We can see where the cursor is now.

| What | With this PR | Without this PR |
|-|-|-|
| macOS builtin |<video
src=https://github.com/user-attachments/assets/487c7e7c-ef6d-4a86-8dbc-8c71871b4470
/>|<video
src=https://github.com/user-attachments/assets/49bd5a60-4b90-4e4a-99e0-cd01d3f7030c
/>|
| macOS builtin (light)|<video
src=https://github.com/user-attachments/assets/e84546f6-947b-4cea-a87e-fda903f49164
/>|——|
| Windows builtin |<video
src=https://github.com/user-attachments/assets/fd331884-1f0c-4822-a99e-8140aed54815
/>|——|
| Wayland iBus Intelligent Pinyin |<video
src=https://github.com/user-attachments/assets/b6796c75-1c4e-45e5-b43a-5d8dea320485
/>|——|
| Chromium (Chrome) macOS | Identical to `macOS builtin`. |——|
| Safari macOS | We can now differentiate between IME composition and
text selection, but we still can't tell where the cursor is. |——|
| Firefox (Zen) macOS | Identical to `macOS builtin`. |——|

### Japanese IMEs

We can see where the conversion segment is now.

| What | With this PR | Without this PR |
|-|-|-|
| macOS builtin |<video
src=https://github.com/user-attachments/assets/f2994cd4-a966-4ff0-9590-d263c202ec76
/>|<video
src=https://github.com/user-attachments/assets/7cf5ff35-003d-4f60-8fbf-15c725c3ecb9
/>|
| macOS builtin (light)|<video
src=https://github.com/user-attachments/assets/6f562bdd-12fc-4486-b37b-8fcf11643295
/>|——|
| Windows builtin |<video
src=https://github.com/user-attachments/assets/f0905659-5335-4034-abda-c25cf8f2fd57
/>|——|
| Wayland iBus Anthy |<video
src=https://github.com/user-attachments/assets/94cd3a24-3158-4d79-ae02-d9b30fdfa738
/>|——|
| Chromium (Chrome) macOS | Identical to `macOS builtin`. |——|
| Safari macOS | We can now differentiate between IME composition and
text selection, but we still can't tell where the conversion segment is.
|——|
| Firefox (Zen) macOS | (Limited improvement.) <video
src=https://github.com/user-attachments/assets/3daf9b63-6e75-467b-8515-31c2a44adf61
/> |——|

### Korean IMEs

We can clearly tell whether we are in composition (in contrast to
selection) now.

| What | With this PR | Without this PR |
|-|-|-|
|macOS builtin|<video
src=https://github.com/user-attachments/assets/73ca28c7-22a0-493f-8f4d-c6e59a2dec54
/>|<video
src=https://github.com/user-attachments/assets/f582de7d-7ec0-48fe-910f-0139ef1620d3
/>|
|macOS builtin (light)|<video
src=https://github.com/user-attachments/assets/269f03bd-6f95-498b-9fb1-1adcb043c738
/>|——|
| Windows builtin| (With a workaround for [this `winit`
bug](https://github.com/emilk/egui/pull/8083#issuecomment-4206742668)
applied.) <video
src=https://github.com/user-attachments/assets/1e82583d-0c41-4f1c-98cf-0606bee5af05
/>|——|
| Wayland iBus Hangul |<video
src=https://github.com/user-attachments/assets/8c9a0de1-9027-4b37-93a3-e9da0251d176
/>|——|
| Chromium (Chrome) macOS | Identical to `macOS builtin`. |——|
| Safari macOS | Identical to `Windows builtin`. |——|
| Firefox (Zen) macOS | Identical to `macOS builtin`. (ignoring the fact
that the composition breaks when typing the second Hangul. (This bug
predates this PR.)) |——|

---------

Co-authored-by: lucasmerlin <hi@lucasmerlin.me>
2026-06-25 18:21:19 +02:00
Emil Ernerfeldt
0ce2b3699b Panel: never overflow available width, nor max_width (#8198)
* Closes https://github.com/emilk/egui/issues/8055
* Closes https://github.com/emilk/egui/pull/8056

This changes the behavior of `Panel` to NEVER overflow
`Panel::max_size`, nor the available space in the parent UI.

If you do overflow it, the content will be silently clipped.
2026-05-26 10:54:38 +02:00
Lucas Meurer
718a82b013 Harness: Add remove_cursor, event and event_modifiers (#7607)
* Closes https://github.com/emilk/egui/issues/7591
2025-10-08 13:47:00 +02:00
Gijs de Jong
48d903d879 Include popups and tooltips in Harness::fit_contents (#7556)
This makes `Harness::fit_contents` also use popups and tooltips to
compute the size of the contents.
2025-09-23 11:03:30 +02:00
Lucas Meurer
42c2fc58c9 Allow masking widgets in kittest snapshots (#7467)
* Closes <https://github.com/emilk/egui/issues/THE_RELEVANT_ISSUE>
* [ ] I have followed the instructions in the PR template
2025-08-21 17:46:36 +02:00
Emil Ernerfeldt
3024c39eaf Enable and fix some more clippy lints (#7426)
One can never have too many lints
2025-08-08 09:57:53 +02:00
Lucas Meurer
6d312cc4c7 Add support for scrolling via accesskit / kittest (#7286)
I need to scroll in a snapshot test in my app, and kittest had no
utilities for this. Event::MouseWheel is error prone. This adds support
for some accesskit scroll actions, and uses this in kittest to add
helpers to scroll to a node / scroll the scroll area surrounding a node.

The accesskit code says down/up/left/right `Scrolls by approximately one
screen in a specific direction.`. Unfortunately it's difficult to get
the size of a "screen" (I guess that would be the size of the containing
scroll area)where I implemented the scrolling, so for now I've hardcoded
it to 100px. I think scrolling a fixed amount is still better than not
scrolling at all.

---------

Co-authored-by: Emil Ernerfeldt <emil.ernerfeldt@gmail.com>
2025-07-03 12:02:05 +02:00
Emil Ernerfeldt
b2995dcb83 Use Rust edition 2024 (#7280) 2025-06-30 14:01:57 +02:00
Lucas Meurer
0152a87519 Create custom egui_kittest::Node (#7138)
This adds a custom Node struct with proper support for egui types
(`Key`, `Modifiers`, `egui::Event`, `Rect`) instead of needing to use
the kittest / accesskit types.

I also changed the `click` function to do a proper mouse move / mouse
down instead of the accesskit click. Also added `accesskit_click` to
trigger the accesskit event. This resulted in some changed snapshots,
since the elements are now hovered.

Also renamed `press_key` to `key_press` for consistency with
`key_down/key_up`.

Also removed the Deref to the AccessKit Node, to make it clearer when to
expect egui and when to expect accesskit types.

* Closes #5705 
* [x] I have followed the instructions in the PR template
2025-06-17 12:17:38 +02:00
Lucas Meurer
120d736cfc Add ImageLoader::has_pending and wait_for_pending_images (#7030)
With kittest it was difficult to wait for images to be loaded before
taking a snapshot test.
This PR adds `Harness::with_wait_for_pending_images` (true by default)
which will cause `Harness::run` to sleep until all images are loaded (or
`HarnessBuilder::with_max_steps` is exceeded).

It also adds a new ImageLoader::has_pending and
BytesLoader::has_pending, which should be implemented if things are
loaded / decoded asynchronously.

It reverts https://github.com/emilk/egui/pull/6901 which was my previous
attempt to fix this (but this didn't work since only the tested crate is
compiled with cfg(test) and not it's dependencies)
2025-05-08 09:27:52 +02:00
Emil Ernerfeldt
f9245954eb Enable more clippy lints (#6853)
* Follows https://github.com/emilk/egui/pull/6848
2025-04-24 17:32:50 +02:00
lucasmerlin
08c5a641a1 Run a frame per queued event in egui_kittest (#5704)
This should fix the remaining problems with the modifiers
* [x] I have followed the instructions in the PR template
2025-02-12 14:20:50 +01:00
lucasmerlin
1c6e7b1bd0 Fix modifiers not working in kittest (#5693)
* Closes <https://github.com/emilk/egui/issues/5690>
* [x] I have followed the instructions in the PR template

It still isn't ideal, since you have to remember to call key_up on a
separate frame.

---------

Co-authored-by: Emil Ernerfeldt <emil.ernerfeldt@gmail.com>
2025-02-10 09:33:36 +01:00
lucasmerlin
b8051cc301 Add SnapshotResults struct to egui_kittest (#5672)
I got annoyed by all the slightly different variations of "collect
snapshot results and unwrap them at the end of test" I've written, so I
added a struct to make this nice and simple.

One controversial thing: It panics when dropped. I wanted to ensure
people cannot forget to unwrap the results at the end, and this was the
best thing I could come up with. I don't think this is possible via
clippy lint or something like that.

* [x] I have followed the instructions in the PR template
2025-02-04 14:01:32 +01:00
lucasmerlin
46b58e5bcc Add Harness::new_eframe and TestRenderer trait (#5539)
Co-authored-by: Andreas Reich <r_andreas2@web.de>
2025-01-02 17:48:39 +01:00
Emil Ernerfeldt
5b2b8cfb34 Remove cylic dependency of egui_kittest on itself 2024-12-16 18:10:01 +01:00
lucasmerlin
ad14bf2490 Add Harness::new_ui, Harness::fit_contents (#5301)
This adds a `Harness::new_ui`, which accepts a Ui closure and shows the
ui in a central panel. One big benefit is that this allows us to add a
fit_contents method that can run the ui closure with a sizing pass and
resize the "screen" based on the content size.

I also used this to add a snapshot test for the rendering_test at
different scales.
2024-11-01 18:30:40 +01:00