Commit Graph

387 Commits

Author SHA1 Message Date
Lege19
3978ba9783
Allowed creating uninitialized images (for use as storage textures) (#17760)
# Objective
https://github.com/bevyengine/bevy/issues/17746
## Solution
- Change `Image.data` from being a `Vec<u8>` to a `Option<Vec<u8>>`
- Added functions to help with creating images
## Testing

- Did you test these changes? If so, how?
All current tests pass
Tested a variety of existing examples to make sure they don't crash
(they don't)
- If relevant, what platforms did you test these changes on, and are
there any important ones you can't test?
Linux x86 64-bit NixOS 
---
## Migration Guide
Code that directly access `Image` data will now need to use unwrap or
handle the case where no data is provided.
Behaviour of new_fill slightly changed, but not in a way that is likely
to affect anything. It no longer panics and will fill the whole texture
instead of leaving black pixels if the data provided is not a nice
factor of the size of the image.

---------

Co-authored-by: IceSentry <IceSentry@users.noreply.github.com>
2025-02-10 22:22:07 +00:00
JMS55
669d139c13
Upgrade to wgpu v24 (#17542)
Didn't remove WgpuWrapper. Not sure if it's needed or not still.

## Testing

- Did you test these changes? If so, how? Example runner
- Are there any parts that need more testing? Web (portable atomics
thingy?), DXC.

## Migration Guide
- Bevy has upgraded to [wgpu
v24](https://github.com/gfx-rs/wgpu/blob/trunk/CHANGELOG.md#v2400-2025-01-15).
- When using the DirectX 12 rendering backend, the new priority system
for choosing a shader compiler is as follows:
- If the `WGPU_DX12_COMPILER` environment variable is set at runtime, it
is used
- Else if the new `statically-linked-dxc` feature is enabled, a custom
version of DXC will be statically linked into your app at compile time.
- Else Bevy will look in the app's working directory for
`dxcompiler.dll` and `dxil.dll` at runtime.
- Else if they are missing, Bevy will fall back to FXC (not recommended)

---------

Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com>
Co-authored-by: IceSentry <c.giguere42@gmail.com>
Co-authored-by: François Mockers <francois.mockers@vleue.com>
2025-02-09 19:40:53 +00:00
François Mockers
7400e7adfd
Cleanup publish process (#17728)
# Objective

- publish script copy the license files to all subcrates, meaning that
all publish are dirty. this breaks git verification of crates
- the order and list of crates to publish is manually maintained,
leading to error. cargo 1.84 is more strict and the list is currently
wrong

## Solution

- duplicate all the licenses to all crates and remove the
`--allow-dirty` flag
- instead of a manual list of crates, get it from `cargo package
--workspace`
- remove the `--no-verify` flag to... verify more things?
2025-02-09 17:46:19 +00:00
mgi388
756948e311
Fix cursor hotspot out of bounds when flipping (#17571)
# Objective

- Fix off by one error introduced in
https://github.com/bevyengine/bevy/pull/17540 causing:

```
Cursor image StrongHandle<Image>{ id: Index(AssetIndex { generation: 0, index: 3 }), path: Some(cursors/kenney_crosshairPack/Tilesheet/crosshairs_tilesheet_white.png) } is invalid: The specified hotspot (64, 64) is outside the image bounds (64x64).
```

- First PR commit and run shows the bug:
https://github.com/bevyengine/bevy/actions/runs/13009405866/job/36283507530?pr=17571
- Second PR commit fixes it.

## Solution

- Hotspot coordinates are 0-indexed, so we need to subtract 1 from the
width and height.

## Testing

- Fix the tests which included the off-by-one error in their expected
values.
- Consolidate the tests into a single test for brevity.
- Test round trip transform to ensure we can "undo" to get back to the
original value.
- Add a specific bounds test.
- Ran the example again and observed there are no more error logs:
`cargo run --example custom_cursor_image --features=custom_cursor`.
2025-02-02 18:22:34 +00:00
mgi388
e8cd12daf4
Automatically transform cursor hotspot user asks to flip cursor image (#17540)
# Objective

- As discussed in
https://github.com/bevyengine/bevy/issues/17276#issuecomment-2611203714,
we should transform the cursor's hotspot if the user is asking for the
image to be flipped.
- This becomes more important when a `scale` transform option exists.
It's harder for users to transform the hotspot themselves when using
`scale` because they'd need to look up the image to get its dimensions.
Instead, we let Bevy handle the hotspot transforms and make the
`hotspot` field the "original/source" hotspot.
- Refs #17276.

## Solution

- When the image needs to be transformed, also transform the hotspot. If
the image does not need to be transformed (i.e. fast path), no hotspot
transformation is applied.

## Testing

- Ran the example: `cargo run --example custom_cursor_image
--features=custom_cursor`.
- Add unit tests for the hotspot transform function.
- I also ran the example I have in my `bevy_cursor_kit` crate, which I
think is a good illustration of the reason for this PR.
- In the following videos, there is an arrow pointing up. The button
hover event fires as I move the mouse over it.
- When I press `Y`, the cursor flips. 
- In the first video, on `bevy@main` **before** this PR, notice how the
hotspot is wrong after flipping and no longer hovering the button. The
arrow head and hotspot are no longer synced.
- In the second video, on the branch of **this** PR, notice how the
hotspot gets flipped as soon as I press `Y` and the cursor arrow head is
in the correct position on the screen and still hovering the button.
Speaking back to the objective listed at the start: The user originally
defined the _source_ hotspot for the arrow. Later, they decide they want
to flip the cursor vertically: It's nice that Bevy can automatically
flip the _source_ hotspot for them at the same time it flips the
_source_ image.

First video (main):


https://github.com/user-attachments/assets/1955048c-2f85-4951-bfd6-f0e7cfef0cf8

Second video (this PR):


https://github.com/user-attachments/assets/73cb9095-ecb5-4bfd-af5b-9f772e92bd16
2025-01-28 05:49:46 +00:00
mgi388
14ad25227b
Make CustomCursor variants CustomCursorImage/CustomCursorUrl structs (#17518)
# Objective

- Make `CustomCursor::Image` easier to work with by splitting the enum
variants off into `CustomCursorImage` and `CustomCursorUrl` structs and
deriving `Default` on those structs.
- Refs #17276.

## Testing

- Ran two examples: `cargo run --example custom_cursor_image
--features=custom_cursor` and `cargo run --example window_settings
--features=custom_cursor`
- CI.

---

## Migration Guide

The `CustomCursor` enum's variants now hold instances of
`CustomCursorImage` or `CustomCursorUrl`. Update your uses of
`CustomCursor` accordingly.
2025-01-24 05:39:04 +00:00
Zachary Harrold
9bc0ae33c3
Move hashbrown and foldhash out of bevy_utils (#17460)
# Objective

- Contributes to #16877

## Solution

- Moved `hashbrown`, `foldhash`, and related types out of `bevy_utils`
and into `bevy_platform_support`
- Refactored the above to match the layout of these types in `std`.
- Updated crates as required.

## Testing

- CI

---

## Migration Guide

- The following items were moved out of `bevy_utils` and into
`bevy_platform_support::hash`:
  - `FixedState`
  - `DefaultHasher`
  - `RandomState`
  - `FixedHasher`
  - `Hashed`
  - `PassHash`
  - `PassHasher`
  - `NoOpHash`
- The following items were moved out of `bevy_utils` and into
`bevy_platform_support::collections`:
  - `HashMap`
  - `HashSet`
- `bevy_utils::hashbrown` has been removed. Instead, import from
`bevy_platform_support::collections` _or_ take a dependency on
`hashbrown` directly.
- `bevy_utils::Entry` has been removed. Instead, import from
`bevy_platform_support::collections::hash_map` or
`bevy_platform_support::collections::hash_set` as appropriate.
- All of the above equally apply to `bevy::utils` and
`bevy::platform_support`.

## Notes

- I left `PreHashMap`, `PreHashMapExt`, and `TypeIdMap` in `bevy_utils`
as they might be candidates for micro-crating. They can always be moved
into `bevy_platform_support` at a later date if desired.
2025-01-23 16:46:08 +00:00
Alice Cecile
44ad3bf62b
Move Resource trait to its own file (#17469)
# Objective

`bevy_ecs`'s `system` module is something of a grab bag, and *very*
large. This is particularly true for the `system_param` module, which is
more than 2k lines long!

While it could be defensible to put `Res` and `ResMut` there (lol no
they're in change_detection.rs, obviously), it doesn't make any sense to
put the `Resource` trait there. This is confusing to navigate (and
painful to work on and review).

## Solution

- Create a root level `bevy_ecs/resource.rs` module to mirror
`bevy_ecs/component.rs`
- move the `Resource` trait to that module
- move the `Resource` derive macro to that module as well (Rust really
likes when you pun on the names of the derive macro and trait and put
them in the same path)
- fix all of the imports

## Notes to reviewers

- We could probably move more stuff into here, but I wanted to keep this
PR as small as possible given the absurd level of import changes.
- This PR is ground work for my upcoming attempts to store resource data
on components (resources-as-entities). Splitting this code out will make
the work and review a bit easier, and is the sort of overdue refactor
that's good to do as part of more meaningful work.

## Testing

cargo build works!

## Migration Guide

`bevy_ecs::system::Resource` has been moved to
`bevy_ecs::resource::Resource`.
2025-01-21 19:47:08 +00:00
Carter Anderson
ba5e71f53d
Parent -> ChildOf (#17427)
Fixes #17412

## Objective

`Parent` uses the "has a X" naming convention. There is increasing
sentiment that we should use the "is a X" naming convention for
relationships (following #17398). This leaves `Children` as-is because
there is prevailing sentiment that `Children` is clearer than `ParentOf`
in many cases (especially when treating it like a collection).

This renames `Parent` to `ChildOf`.

This is just the implementation PR. To discuss the path forward, do so
in #17412.

## Migration Guide

- The `Parent` component has been renamed to `ChildOf`.
2025-01-20 22:13:29 +00:00
Alice Cecile
5a9bc28502
Support non-Vec data structures in relations (#17447)
# Objective

The existing `RelationshipSourceCollection` uses `Vec` as the only
possible backing for our relationships. While a reasonable choice,
benchmarking use cases might reveal that a different data type is better
or faster.

For example:

- Not all relationships require a stable ordering between the
relationship sources (i.e. children). In cases where we a) have many
such relations and b) don't care about the ordering between them, a hash
set is likely a better datastructure than a `Vec`.
- The number of children-like entities may be small on average, and a
`smallvec` may be faster

## Solution

- Implement `RelationshipSourceCollection` for `EntityHashSet`, our
custom entity-optimized `HashSet`.
-~~Implement `DoubleEndedIterator` for `EntityHashSet` to make things
compile.~~
   -  This implementation was cursed and very surprising.
- Instead, by moving the iterator type on `RelationshipSourceCollection`
from an erased RPTIT to an explicit associated type we can add a trait
bound on the offending methods!
- Implement `RelationshipSourceCollection` for `SmallVec`

## Testing

I've added a pair of new tests to make sure this pattern compiles
successfully in practice!

## Migration Guide

`EntityHashSet` and `EntityHashMap` are no longer re-exported in
`bevy_ecs::entity` directly. If you were not using `bevy_ecs` / `bevy`'s
`prelude`, you can access them through their now-public modules,
`hash_set` and `hash_map` instead.

## Notes to reviewers

The `EntityHashSet::Iter` type needs to be public for this impl to be
allowed. I initially renamed it to something that wasn't ambiguous and
re-exported it, but as @Victoronz pointed out, that was somewhat
unidiomatic.

In
1a8564898f,
I instead made the `entity_hash_set` public (and its `entity_hash_set`)
sister public, and removed the re-export. I prefer this design (give me
module docs please), but it leads to a lot of churn in this PR.

Let me know which you'd prefer, and if you'd like me to split that
change out into its own micro PR.
2025-01-20 21:26:08 +00:00
Zachary Harrold
a64446b77e
Create bevy_platform_support Crate (#17250)
# Objective

- Contributes to #16877

## Solution

- Initial creation of `bevy_platform_support` crate.
- Moved `bevy_utils::Instant` into new `bevy_platform_support` crate.
- Moved `portable-atomic`, `portable-atomic-util`, and
`critical-section` into new `bevy_platform_support` crate.

## Testing

- CI

---

## Showcase

Instead of needing code like this to import an `Arc`:

```rust
#[cfg(feature = "portable-atomic")]
use portable_atomic_util::Arc;

#[cfg(not(feature = "portable-atomic"))]
use alloc::sync::Arc;
```

We can now use:

```rust
use bevy_platform_support::sync::Arc;
```

This applies to many other types, but the goal is overall the same:
allowing crates to use `std`-like types without the boilerplate of
conditional compilation and platform-dependencies.

## Migration Guide

- Replace imports of `bevy_utils::Instant` with
`bevy_platform_support::time::Instant`
- Replace imports of `bevy::utils::Instant` with
`bevy::platform_support::time::Instant`

## Notes

- `bevy_platform_support` hasn't been reserved on `crates.io`
- ~~`bevy_platform_support` is not re-exported from `bevy` at this time.
It may be worthwhile exporting this crate, but I am unsure of a
reasonable name to export it under (`platform_support` may be a bit
wordy for user-facing).~~
- I've included an implementation of `Instant` which is suitable for
`no_std` platforms that are not Wasm for the sake of eliminating feature
gates around its use. It may be a controversial inclusion, so I'm happy
to remove it if required.
- There are many other items (`spin`, `bevy_utils::Sync(Unsafe)Cell`,
etc.) which should be added to this crate. I have kept the initial scope
small to demonstrate utility without making this too unwieldy.

---------

Co-authored-by: TimJentzsch <TimJentzsch@users.noreply.github.com>
Co-authored-by: Chris Russell <8494645+chescock@users.noreply.github.com>
Co-authored-by: François Mockers <francois.mockers@vleue.com>
2025-01-20 20:45:30 +00:00
Carter Anderson
21f1e3045c
Relationships (non-fragmenting, one-to-many) (#17398)
This adds support for one-to-many non-fragmenting relationships (with
planned paths for fragmenting and non-fragmenting many-to-many
relationships). "Non-fragmenting" means that entities with the same
relationship type, but different relationship targets, are not forced
into separate tables (which would cause "table fragmentation").

Functionally, this fills a similar niche as the current Parent/Children
system. The biggest differences are:

1. Relationships have simpler internals and significantly improved
performance and UX. Commands and specialized APIs are no longer
necessary to keep everything in sync. Just spawn entities with the
relationship components you want and everything "just works".
2. Relationships are generalized. Bevy can provide additional built in
relationships, and users can define their own.

**REQUEST TO REVIEWERS**: _please don't leave top level comments and
instead comment on specific lines of code. That way we can take
advantage of threaded discussions. Also dont leave comments simply
pointing out CI failures as I can read those just fine._

## Built on top of what we have

Relationships are implemented on top of the Bevy ECS features we already
have: components, immutability, and hooks. This makes them immediately
compatible with all of our existing (and future) APIs for querying,
spawning, removing, scenes, reflection, etc. The fewer specialized APIs
we need to build, maintain, and teach, the better.

## Why focus on one-to-many non-fragmenting first?

1. This allows us to improve Parent/Children relationships immediately,
in a way that is reasonably uncontroversial. Switching our hierarchy to
fragmenting relationships would have significant performance
implications. ~~Flecs is heavily considering a switch to non-fragmenting
relations after careful considerations of the performance tradeoffs.~~
_(Correction from @SanderMertens: Flecs is implementing non-fragmenting
storage specialized for asset hierarchies, where asset hierarchies are
many instances of small trees that have a well defined structure)_
2. Adding generalized one-to-many relationships is currently a priority
for the [Next Generation Scene / UI
effort](https://github.com/bevyengine/bevy/discussions/14437).
Specifically, we're interested in building reactions and observers on
top.

## The changes

This PR does the following:

1. Adds a generic one-to-many Relationship system
3. Ports the existing Parent/Children system to Relationships, which now
lives in `bevy_ecs::hierarchy`. The old `bevy_hierarchy` crate has been
removed.
4. Adds on_despawn component hooks
5. Relationships can opt-in to "despawn descendants" behavior, meaning
that the entire relationship hierarchy is despawned when
`entity.despawn()` is called. The built in Parent/Children hierarchies
enable this behavior, and `entity.despawn_recursive()` has been removed.
6. `world.spawn` now applies commands after spawning. This ensures that
relationship bookkeeping happens immediately and removes the need to
manually flush. This is in line with the equivalent behaviors recently
added to the other APIs (ex: insert).
7. Removes the ValidParentCheckPlugin (system-driven / poll based) in
favor of a `validate_parent_has_component` hook.

## Using Relationships

The `Relationship` trait looks like this:

```rust
pub trait Relationship: Component + Sized {
    type RelationshipSources: RelationshipSources<Relationship = Self>;
    fn get(&self) -> Entity;
    fn from(entity: Entity) -> Self;
}
```

A relationship is a component that:

1. Is a simple wrapper over a "target" Entity.
2. Has a corresponding `RelationshipSources` component, which is a
simple wrapper over a collection of entities. Every "target entity"
targeted by a "source entity" with a `Relationship` has a
`RelationshipSources` component, which contains every "source entity"
that targets it.

For example, the `Parent` component (as it currently exists in Bevy) is
the `Relationship` component and the entity containing the Parent is the
"source entity". The entity _inside_ the `Parent(Entity)` component is
the "target entity". And that target entity has a `Children` component
(which implements `RelationshipSources`).

In practice, the Parent/Children relationship looks like this:

```rust
#[derive(Relationship)]
#[relationship(relationship_sources = Children)]
pub struct Parent(pub Entity);

#[derive(RelationshipSources)]
#[relationship_sources(relationship = Parent)]
pub struct Children(Vec<Entity>);
```

The Relationship and RelationshipSources derives automatically implement
Component with the relevant configuration (namely, the hooks necessary
to keep everything in sync).

The most direct way to add relationships is to spawn entities with
relationship components:

```rust
let a = world.spawn_empty().id();
let b = world.spawn(Parent(a)).id();

assert_eq!(world.entity(a).get::<Children>().unwrap(), &[b]);
```

There are also convenience APIs for spawning more than one entity with
the same relationship:

```rust
world.spawn_empty().with_related::<Children>(|s| {
    s.spawn_empty();
    s.spawn_empty();
})
```

The existing `with_children` API is now a simpler wrapper over
`with_related`. This makes this change largely non-breaking for existing
spawn patterns.

```rust
world.spawn_empty().with_children(|s| {
    s.spawn_empty();
    s.spawn_empty();
})
```

There are also other relationship APIs, such as `add_related` and
`despawn_related`.

## Automatic recursive despawn via the new on_despawn hook

`RelationshipSources` can opt-in to "despawn descendants" behavior,
which will despawn all related entities in the relationship hierarchy:

```rust
#[derive(RelationshipSources)]
#[relationship_sources(relationship = Parent, despawn_descendants)]
pub struct Children(Vec<Entity>);
```

This means that `entity.despawn_recursive()` is no longer required.
Instead, just use `entity.despawn()` and the relevant related entities
will also be despawned.

To despawn an entity _without_ despawning its parent/child descendants,
you should remove the `Children` component first, which will also remove
the related `Parent` components:

```rust
entity
    .remove::<Children>()
    .despawn()
```

This builds on the on_despawn hook introduced in this PR, which is fired
when an entity is despawned (before other hooks).

## Relationships are the source of truth

`Relationship` is the _single_ source of truth component.
`RelationshipSources` is merely a reflection of what all the
`Relationship` components say. By embracing this, we are able to
significantly improve the performance of the system as a whole. We can
rely on component lifecycles to protect us against duplicates, rather
than needing to scan at runtime to ensure entities don't already exist
(which results in quadratic runtime). A single source of truth gives us
constant-time inserts. This does mean that we cannot directly spawn
populated `Children` components (or directly add or remove entities from
those components). I personally think this is a worthwhile tradeoff,
both because it makes the performance much better _and_ because it means
theres exactly one way to do things (which is a philosophy we try to
employ for Bevy APIs).

As an aside: treating both sides of the relationship as "equivalent
source of truth relations" does enable building simple and flexible
many-to-many relationships. But this introduces an _inherent_ need to
scan (or hash) to protect against duplicates.
[`evergreen_relations`](https://github.com/EvergreenNest/evergreen_relations)
has a very nice implementation of the "symmetrical many-to-many"
approach. Unfortunately I think the performance issues inherent to that
approach make it a poor choice for Bevy's default relationship system.

## Followup Work

* Discuss renaming `Parent` to `ChildOf`. I refrained from doing that in
this PR to keep the diff reasonable, but I'm personally biased toward
this change (and using that naming pattern generally for relationships).
* [Improved spawning
ergonomics](https://github.com/bevyengine/bevy/discussions/16920)
* Consider adding relationship observers/triggers for "relationship
targets" whenever a source is added or removed. This would replace the
current "hierarchy events" system, which is unused upstream but may have
existing users downstream. I think triggers are the better fit for this
than a buffered event queue, and would prefer not to add that back.
* Fragmenting relations: My current idea hinges on the introduction of
"value components" (aka: components whose type _and_ value determines
their ComponentId, via something like Hashing / PartialEq). By labeling
a Relationship component such as `ChildOf(Entity)` as a "value
component", `ChildOf(e1)` and `ChildOf(e2)` would be considered
"different components". This makes the transition between fragmenting
and non-fragmenting a single flag, and everything else continues to work
as expected.
* Many-to-many support
* Non-fragmenting: We can expand Relationship to be a list of entities
instead of a single entity. I have largely already written the code for
this.
* Fragmenting: With the "value component" impl mentioned above, we get
many-to-many support "for free", as it would allow inserting multiple
copies of a Relationship component with different target entities.

Fixes #3742 (If this PR is merged, I think we should open more targeted
followup issues for the work above, with a fresh tracking issue free of
the large amount of less-directed historical context)
Fixes #17301
Fixes #12235 
Fixes #15299
Fixes #15308 

## Migration Guide

* Replace `ChildBuilder` with `ChildSpawnerCommands`.
* Replace calls to `.set_parent(parent_id)` with
`.insert(Parent(parent_id))`.
* Replace calls to `.replace_children()` with `.remove::<Children>()`
followed by `.add_children()`. Note that you'll need to manually despawn
any children that are not carried over.
* Replace calls to `.despawn_recursive()` with `.despawn()`.
* Replace calls to `.despawn_descendants()` with
`.despawn_related::<Children>()`.
* If you have any calls to `.despawn()` which depend on the children
being preserved, you'll need to remove the `Children` component first.

---------

Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com>
2025-01-18 22:20:30 +00:00
mgi388
4d4253430c
Move CustomCursor to bevy_winit/src/custom_cursor.rs (#17381)
# Objective

- Follow up work from
https://github.com/bevyengine/bevy/pull/17121#issuecomment-2576615700 to
keep the `cursor.rs` file more manageable.

## Solution

- Move `CustomCursor` and make it compile.

## Testing

- Ran the example: `cargo run --example custom_cursor_image
--features=custom_cursor`
- CI
2025-01-15 05:35:57 +00:00
MichiRecRoom
26bb0b40d2
Move #![warn(clippy::allow_attributes, clippy::allow_attributes_without_reason)] to the workspace Cargo.toml (#17374)
# Objective
Fixes https://github.com/bevyengine/bevy/issues/17111

## Solution
Move `#![warn(clippy::allow_attributes,
clippy::allow_attributes_without_reason)]` to the workspace `Cargo.toml`

## Testing
Lots of CI testing, and local testing too.

---------

Co-authored-by: Benjamin Brienen <benjamin.brienen@outlook.com>
2025-01-15 01:14:58 +00:00
mgi388
0756a19f28
Support texture atlases in CustomCursor::Image (#17121)
# Objective

- Bevy 0.15 added support for custom cursor images in
https://github.com/bevyengine/bevy/pull/14284.
- However, to do animated cursors using the initial support shipped in
0.15 means you'd have to animate the `Handle<Image>`: You can't use a
`TextureAtlas` like you can with sprites and UI images.
- For my use case, my cursors are spritesheets. To animate them, I'd
have to break them down into multiple `Image` assets, but that seems
less than ideal.


## Solution

- Allow users to specify a `TextureAtlas` field when creating a custom
cursor image.
- To create parity with Bevy's `TextureAtlas` support on `Sprite`s and
`ImageNode`s, this also allows users to specify `rect`, `flip_x` and
`flip_y`. In fact, for my own use case, I need to `flip_y`.

## Testing

- I added unit tests for `calculate_effective_rect` and
`extract_and_transform_rgba_pixels`.
- I added a brand new example for custom cursor images. It has controls
to toggle fields on and off. I opted to add a new example because the
existing cursor example (`window_settings`) would be far too messy for
showcasing these custom cursor features (I did start down that path but
decided to stop and make a brand new example).
- The new example uses a [Kenny cursor icon] sprite sheet. I included
the licence even though it's not required (and it's CC0).
- I decided to make the example just loop through all cursor icons for
its animation even though it's not a _realistic_ in-game animation
sequence.
- I ran the PNG through https://tinypng.com. Looks like it's about 35KB.
- I'm open to adjusting the example spritesheet if required, but if it's
fine as is, great.

[Kenny cursor icon]: https://kenney-assets.itch.io/crosshair-pack

---

## Showcase


https://github.com/user-attachments/assets/8f6be8d7-d1d4-42f9-b769-ef8532367749

## Migration Guide

The `CustomCursor::Image` enum variant has some new fields. Update your
code to set them.

Before:

```rust
CustomCursor::Image {
    handle: asset_server.load("branding/icon.png"),
    hotspot: (128, 128),
}
```

After:

```rust
CustomCursor::Image {
    handle: asset_server.load("branding/icon.png"),
    texture_atlas: None,
    flip_x: false,
    flip_y: false,
    rect: None,
    hotspot: (128, 128),
}
```

## References

- Feature request [originally raised in Discord].

[originally raised in Discord]:
https://discord.com/channels/691052431525675048/692572690833473578/1319836362219847681
2025-01-14 22:27:24 +00:00
Nicholas Charbonneau
f2e00c8ed5
feat: support for clip children on windows (#16545)
# Objective

Support the parametrization of the WS_CLIPCHILDREN style on Windows.

Fixes #16544

## Solution

Added a window configuration in bevy_winit to control the usage of the
WS_CLIPCHILDREN style.

## Testing

- Did you test these changes? If so, how?
I did. I was able to create a Wry Webview with a transparent HTML
document and was also able to see my Bevy scene behind the webview
elements.

- Are there any parts that need more testing?
I don't believe so. I assume the option is extensively tested within
winit itself.

- How can other people (reviewers) test your changes? Is there anything
specific they need to know?
Test repositiory [here](https://github.com/nicholasc/bevy_wry_test).
Bevy's path will need to be updated in the Cargo.toml

- If relevant, what platforms did you test these changes on, and are
there any important ones you can't test?
This is a Windows specific issue. Should be tested accordingly.

---------

Co-authored-by: jf908 <jf908@users.noreply.github.com>
2025-01-14 22:22:20 +00:00
IceSentry
41fd280596
Make InputFocus optional in bevy_winit (#17358)
# Objective

- Stop bevy from crashing when losing window focus

## Solution

- The InputFocus resource is optional but is accessed unconditionally in
bevy_winit. Make it optional.

## Testing

- Ran the window_settings example

## Note

It's possible this might not be a full fix for the issue, but this stop
bevy from crashing.

Closes #16961 
Closes #17227
2025-01-14 05:08:20 +00:00
MichiRecRoom
447108b2a4
Downgrade clippy::allow_attributes and clippy::allow_attributes_without_reason to warn (#17320)
# Objective
I realized that setting these to `deny` may have been a little
aggressive - especially since we upgrade warnings to denies in CI.

## Solution
Downgrades these lints to `warn`, so that compiles can work locally. CI
will still treat these as denies.
2025-01-12 05:28:26 +00:00
Alice Cecile
145f5f4394
Add a simple directional UI navigation example (#17224)
# Objective

Gamepad / directional navigation needs an example, for both teaching and
testing purposes.

## Solution

- Add a simple grid-based example.
- Fix an intermittent panic caused by a race condition with bevy_a11y
- Clean up small issues noticed in bevy_input_focus


![image](https://github.com/user-attachments/assets/3a924255-0cd6-44a5-9bb7-b2c400a22d7e)

## To do: this PR

- [x] figure out why "enter" isn't doing anything
- [x] change button color on interaction rather than printing
- [x] add on-screen directions
- [x] move to an asymmetric grid to catch bugs
- [x] ~~fix colors not resetting on button press~~ lol this is mostly
just a problem with hacking `Interaction` for this
- [x] swap to using observers + bubbling, rather than `Interaction`

## To do: future work

- when I increase the button size, such that there is no line break, the
text on the buttons is no longer centered :( EDIT: this is
https://github.com/bevyengine/bevy/issues/16783
- add gamepad stick navigation
- add tools to find the nearest populated quadrant to make diagonal
inputs work
- add a `add_edges` method to `DirectionalNavigationMap`
- add a `add_grid` method to `DirectionalNavigationMap`
- make the example's layout more complex and realistic
- add tools to automatically generate this list
- add button shake on failed navigation rather than printing an error
- make Pressed events easier to mock: default fields, PointerId::Focus

## Testing

`cargo run --example directional_navigation`

---------

Co-authored-by: Rob Parrett <robparrett@gmail.com>
2025-01-09 21:15:28 +00:00
MichiRecRoom
3742e621ef
Allow clippy::too_many_arguments to lint without warnings (#17249)
# Objective
Many instances of `clippy::too_many_arguments` linting happen to be on
systems - functions which we don't call manually, and thus there's not
much reason to worry about the argument count.

## Solution
Allow `clippy::too_many_arguments` globally, and remove all lint
attributes related to it.
2025-01-09 07:26:15 +00:00
MichiRecRoom
2403487239
bevy_winit: Apply #![deny(clippy::allow_attributes, clippy::allow_attributes_without_reason)] (#17232)
# Objective
- https://github.com/bevyengine/bevy/issues/17111

## Solution
Set the `clippy::allow_attributes` and
`clippy::allow_attributes_without_reason` lints to `deny`, and bring
`bevy_winit` in line with the new restrictions.

## Testing
`cargo clippy --tests` was run, and no errors were encountered.

---------

Co-authored-by: Benjamin Brienen <benjamin.brienen@outlook.com>
2025-01-09 06:29:29 +00:00
Antony
a2ae7e9a19
Remove temporary iOS workaround (#17217)
# Objective

Fixes #16928.

## Solution

Remove the temporary workaround introduced in #16548.
2025-01-07 18:44:32 +00:00
François Mockers
b4442bc30e
iOS: can change home indicator / status bar during runtime (#17204)
# Objective

- Followup on
https://github.com/bevyengine/bevy/pull/17179#pullrequestreview-2531852653
- Can show / hide home indicator / status bar during runtime

## Solution

- react on window change

## Testing

- Tested on iOS
2025-01-07 01:07:18 +00:00
Wei Xu
fbc55b84e2
Update winit_runner to use spawn_app for wasm32 target (#16630)
# Objective

- Fixes #12562
- Fixes #12195

## Solution

- Use `spawn_app` instead of `run_app` for web platform in
`winit_runner` as suggested in the
[document](https://docs.rs/winit/latest/winit/platform/web/trait.EventLoopExtWebSys.html#tymethod.spawn_app)

## Testing

- Did you test these changes? If so, how?

Tested on web. Created a react app which renders the bevy WASM app and
returns the disposer to JS. Js will call the disposer on component
unmount to stop the app, the disposer sends a signal to a `signal`
receiver in rust which exits the app like this:

```rust
fn handle_stop_signal(
    signal: NonSendMut<StopSignalReceiver>,
    window_entities: Query<(Entity, &Window)>,
    mut event_writer: EventWriter<WindowCloseRequested>,
) {
    if let Ok(_) = signal.try_recv() {
        for (entity, _window) in window_entities.iter() {
            info!("closing window entity: {:x}", entity.to_bits());
            event_writer.send(WindowCloseRequested { window: entity });
        }
    }
}
```


- Are there any parts that need more testing?

  - No

- How can other people (reviewers) test your changes? Is there anything
specific they need to know?

- Are all resources released after stopping the app like this? The WASM
is still loaded, the LogPlugin complains on the logger
re-initialization, but it's a warning anyway.

- If relevant, what platforms did you test these changes on, and are
there any important ones you can't test?

- Tested the WASM version on web platform and the native version on
MacOS.

---------

Co-authored-by: Martín Maita <47983254+mnmaita@users.noreply.github.com>
2025-01-06 23:21:24 +00:00
François Mockers
94b9fe384f
can hide status bar on iOS (#17179)
# Objective

- I want to hide the clock and the battery indicator on iOS

## Solution

- Add the platform specific property `prefers_status_bar_hidden` on
Window creation, and map it to `with_prefers_status_bar_hidden` in
winit.

## Testing

- Tested on iOS
2025-01-06 19:19:56 +00:00
github-actions[bot]
573b980685
Bump Version after Release (#17176)
Bump version after release
This PR has been auto-generated

---------

Co-authored-by: Bevy Auto Releaser <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: François Mockers <mockersf@gmail.com>
2025-01-06 00:04:44 +00:00
Zachary Harrold
a371ee3019
Remove tracing re-export from bevy_utils (#17161)
# Objective

- Contributes to #11478

## Solution

- Made `bevy_utils::tracing` `doc(hidden)`
- Re-exported `tracing` from `bevy_log` for end-users
- Added `tracing` directly to crates that need it.

## Testing

- CI

---

## Migration Guide

If you were importing `tracing` via `bevy::utils::tracing`, instead use
`bevy::log::tracing`. Note that many items within `tracing` are also
directly re-exported from `bevy::log` as well, so you may only need
`bevy::log` for the most common items (e.g., `warn!`, `trace!`, etc.).
This also applies to the `log_once!` family of macros.

## Notes

- While this doesn't reduce the line-count in `bevy_utils`, it further
decouples the internal crates from `bevy_utils`, making its eventual
removal more feasible in the future.
- I have just imported `tracing` as we do for all dependencies. However,
a workspace dependency may be more appropriate for version management.
2025-01-05 23:06:34 +00:00
Zachary Harrold
3c829d7f68
Remove everything except Instant from bevy_utils::time (#17158)
# Objective

- Contributes to #11478
- Contributes to #16877

## Solution

- Removed everything except `Instant` from `bevy_utils::time`

## Testing

- CI

---

## Migration Guide

If you relied on any of the following from `bevy_utils::time`:

- `Duration`
- `TryFromFloatSecsError`

Import these directly from `core::time` regardless of platform target
(WASM, mobile, etc.)

If you relied on any of the following from `bevy_utils::time`:

- `SystemTime`
- `SystemTimeError`

Instead import these directly from either `std::time` or `web_time` as
appropriate for your target platform.

## Notes

`Duration` and `TryFromFloatSecsError` are both re-exports from
`core::time` regardless of whether they are used from `web_time` or
`std::time`, so there is no value gained from re-exporting them from
`bevy_utils::time` as well. As for `SystemTime` and `SystemTimeError`,
no Bevy internal crates or examples rely on these types. Since Bevy
doesn't have a `Time<Wall>` resource for interacting with wall-time (and
likely shouldn't need one), I think removing these from `bevy_utils`
entirely and waiting for a use-case to justify inclusion is a reasonable
path forward.
2025-01-05 20:36:08 +00:00
Vic
b78efd339d
Simplify sort/max_by calls (#17048)
# Objective

Some sort calls and `Ord` impls are unnecessarily complex.

## Solution

Rewrite the "match on cmp, if equal do another cmp" as either a
comparison on tuples, or `Ordering::then_with`, depending on whether the
compare keys need construction.

`sort_by` -> `sort_by_key` when symmetrical. Do the same for
`min_by`/`max_by`.

Note that `total_cmp` can only work with `sort_by`, and not on tuples.

When sorting collected query results that contain
`Entity`/`MainEntity`/`RenderEntity` in their `QueryData`, with that
`Entity` in the sort key:
stable -> unstable sort (all queried entities are unique)

If key construction is not simple, switch to `sort_by_cached_key` when
possible.

Sorts that are only performed to discover the maximal element are
replaced by `max_by_key`.

Dedicated comparison functions and structs are removed where simple.

Derive `PartialOrd`/`Ord` when useful.

Misc. closure style inconsistencies.

## Testing
- Existing tests.
2024-12-30 22:59:36 +00:00
Benjamin Brienen
64efd08e13
Prefer Display over Debug (#16112)
# Objective

Fixes #16104

## Solution

I removed all instances of `:?` and put them back one by one where it
caused an error.

I removed some bevy_utils helper functions that were only used in 2
places and don't add value. See: #11478

## Testing

CI should catch the mistakes

## Migration Guide

`bevy::utils::{dbg,info,warn,error}` were removed. Use
`bevy::utils::tracing::{debug,info,warn,error}` instead.

---------

Co-authored-by: SpecificProtagonist <vincentjunge@posteo.net>
2024-12-27 00:40:06 +00:00
Alice Cecile
fa6cabd432
Replace bevy_a11y::Focus with InputFocus (#16863)
# Objective

Bevy now has first-class input focus handling! We should use this for
accessibility purpose via accesskit too.

## Solution

- Removed bevy_a11y::Focus.
- Replaced all usages of Focus with InputFocus
- Changed the dependency tree so bevy_a11y relies on bevy_input_focus
- Moved initialization of the focus (starts with the primary window)
from bevy_window to bevy_input_focus to avoid circular dependencies (and
it's cleaner)

## Testing

TODO

## Migration Guide

`bevy_a11y::Focus` has been replaced with `bevy_input_focus::Focus`.
2024-12-18 00:16:19 +00:00
Winds
6ca1e756dc
Expose text field from winit in KeyboardInput (#16864)
# Objective

Allow handling of dead keys on some keyboard layouts.

In some cases, dead keys were impossible to get using the
`KeyboardInput` event. This information is already present in the
underlying winit `KeyEvent`, but it wasn't exposed.

## Solution

Expose the `text` field from winit's `KeyEvent` in `KeyboardInput`.

This logic is inspired egui's implementation here:
adfc0bebfc/crates/egui-winit/src/lib.rs (L790-L807)

## Testing

This is a new field, so it shouldn't break any existing functionality. I
tested that this change works by running the modified `text_input`
example on different keyboard layouts.

## Example

Using a Portuguese/ABNT2 keyboard layout on windows and pressing
<kbd>\~</kbd> followed by
<kbd>a</kbd>/<kbd>Space</kbd>/<kbd>d</kbd>/<kbd>\~</kbd> now generates
the following events:
```
KeyboardInput { key_code: Quote, logical_key: Dead(Some('~')), state: Pressed, text: None, repeat: false, window: 0v1#4294967296 }
KeyboardInput { key_code: KeyA, logical_key: Character("ã"), state: Pressed, text: Some("ã"), repeat: false, window: 0v1#4294967296 }

KeyboardInput { key_code: Quote, logical_key: Dead(Some('~')), state: Pressed, text: None, repeat: false, window: 0v1#4294967296 }
KeyboardInput { key_code: Space, logical_key: Space, state: Pressed, text: Some("~"), repeat: false, window: 0v1#4294967296 }

KeyboardInput { key_code: Quote, logical_key: Dead(Some('~')), state: Pressed, text: None, repeat: false, window: 0v1#4294967296 }
KeyboardInput { key_code: KeyD, logical_key: Character("d"), state: Pressed, text: Some("~d"), repeat: false, window: 0v1#4294967296 }

KeyboardInput { key_code: Quote, logical_key: Dead(Some('~')), state: Pressed, text: None, repeat: false, window: 0v1#4294967296 }
KeyboardInput { key_code: Quote, logical_key: Dead(Some('~')), state: Pressed, text: Some("~~"), repeat: false, window: 0v1#4294967296 }
```

The logic for getting an input is pretty simple: check if `text` is
`Some`. If it is, this is actual input text, otherwise it isn't.

There's a small caveat: certain keys generate control characters in the
input text, which needs to be filtered out:
```
KeyboardInput { key_code: Escape, logical_key: Escape, state: Pressed, text: Some("\u{1b}"), repeat: false, window: 0v1#4294967296 }
```

I've updated the text_input example to include egui's solution to this,
which works well.

## Migration Guide

The `KeyboardInput` event now has a new `text` field.
2024-12-17 22:42:54 +00:00
Aevyrie
61b98ec80f
Rename trigger.entity() to trigger.target() (#16716)
# Objective

- A `Trigger` has multiple associated `Entity`s - the entity observing
the event, and the entity that was targeted by the event.
- The field `entity: Entity` encodes no semantic information about what
the entity is used for, you can already tell that it's an `Entity` by
the type signature!

## Solution

- Rename `trigger.entity()` to `trigger.target()`

---

## Changelog

- `Trigger`s are associated with multiple entities. `Trigger::entity()`
has been renamed to `Trigger::target()` to reflect the semantics of the
entity being returned.

## Migration Guide

- Rename `Trigger::entity()` to `Trigger::target()`.
- Rename `ObserverTrigger::entity` to `ObserverTrigger::target`
2024-12-08 21:55:09 +00:00
HugoPeters1024
b9cc6e16da
bevy_winit(emit raw winit events) (#15884)
# Objective

- Exposes raw winit events making Bevy even more modular and powerful
for custom plugin developers (e.g. a custom render plugin).

XRef: https://github.com/bevyengine/bevy/issues/5977
It doesn't quite close the issue as sending events is not supported (or
not very useful to be precise). I would think that supporting that
requires some extra considerations by someone a bit more familiar with
the `bevy_winit` crate. That said, this PR could be a nice step forward.

## Solution

Emit `RawWinitWindowEvent` objects for each received event.

## Testing

I verified that the events are emitted using a basic test app. I don't
think it makes sense to solidify this behavior in one of the examples.

---

## Showcase

My example usage for a custom `egui_winit` integration:

```rust
for ev in winit_events.read() {
    if ev.window_id == window.id {
        let _ = egui_winit.on_window_event(&window, &ev.event);
    }
}
```

---------

Co-authored-by: IceSentry <IceSentry@users.noreply.github.com>
2024-12-03 17:20:43 +00:00
François Mockers
c1d392a5c6
Reduce iOS cpu usage (#16548)
# Objective

- Avoid recreating the monitor every loop (temp fix until it's done
properly on winit side)
- Add a new `WinitSettings` preset for mobile that makes the winit loop
wait more and recommend its usage
2024-11-29 00:34:40 +00:00
Knar
1e3ecbefdb
Handle failed cursor grab mode changes so that the cursor grab mode change can be attempted again (#16293)
# Objective

- Currently when you attempt to change the cursor_grab_mode it caches
the new value whether the cursor grab succeeded or failed. This change
handles the Result being returned by set_cursor_grab and changes the
cursor_grab_mode back to the cached version in case of an Error.
- Creates a way to handle #16237 and #16238

## Solution

- I changed the signature of winit_windows attempt_grab to return the
Result<(), ExternalError> that winit set_cursor_grab returns. The system
that calls attempt_grab now checks if there's an error returned, and if
there is it sets the grab_mode back to the cached version (similar to
what hit_test does a few lines down).

## Testing

- I tested using this system that previously would not correctly lock
the mouse on Ubuntu/x11
```
pub fn lock_mouse(mut primary_window: Query<&mut Window, With<PrimaryWindow>>) {
    let window = &mut primary_window.single_mut();
    if window.focused {
        window.cursor_options.grab_mode = CursorGrabMode::Confined;
    } else {
        window.cursor_options.grab_mode = CursorGrabMode::None;
    }
}
```
- I only tested on Ubuntu with x11
2024-11-09 23:30:57 +00:00
Derick M
0ac495f7f4
Remove accesskit re-export from bevy_a11y (#16257)
# Objective

- Fixes #16235 

## Solution

- Both Bevy and AccessKit export a `Node` struct, to reduce confusion
Bevy will no longer re-export `AccessKit` from `bevy_a11y`

## Testing

- Tested locally

## Migration Guide

```diff
# main.rs
--    use bevy_a11y::{
--        accesskit::{Node, Rect, Role},
--        AccessibilityNode,
--    };
++    use bevy_a11y::AccessibilityNode;
++    use accesskit::{Node, Rect, Role};

# Cargo.toml
++    accesskit = "0.17"
```

- Users will need to add `accesskit = "0.17"` to the dependencies
section of their `Cargo.toml` file and update their `accesskit` use
statements to come directly from the external crate instead of
`bevy_a11y`.
- Make sure to keep the versions of `accesskit` aligned with the
versions Bevy uses.
2024-11-08 21:01:16 +00:00
François Mockers
eb558bbf77
properly flag using CustomCursor::Url in wasm (#16255)
# Objective

- Fixes #16254 
- fix building in wasm without custom_cursor

## Solution

- Properly flag `CustomCursor::Url` which only exist in wasm, but also
only when `custom_cursor` is enabled

## Testing

- `cargo check --target wasm32-unknown-unknown -p bevy_winit`
2024-11-06 13:14:12 +00:00
charlotte
4b05d2f4d8
Upgrade to wgpu 23 (#15988)
Fixes https://github.com/bevyengine/bevy/issues/15893

---------

Co-authored-by: François Mockers <mockersf@gmail.com>
2024-11-05 21:18:48 +00:00
Nolan Darilek
817f160d35
Bump accesskit and accesskit_winit. (#16234)
# Objective

- Bumps accesskit and accesskit_winit dependencies

## Solution

- Fixes several breaking API changes introduced in accesskit 0.23.

## Testing

- Tested with the ui example and seems to work comparably
2024-11-04 20:07:38 +00:00
Friz64
565616622b
Correctly feature gate custom_cursor (#16093)
# Objective

Currently there's no way to change the window's cursor icon with the
`custom_cursor` feature **disabled**. You should still be able to set
system cursor icons.

Connections:

- https://github.com/bevyengine/bevy/pull/15649

## Solution

Move some `custom_cursor` feature gates around, as to expose the
`CursorIcon` type again.

Note this refactoring was mainly piloted by hunting after the compiler
warnings -- I shouldn't have missed anything, but FYI.

## Testing

Disabled the `custom_cursor` feature, ran the `window_settings` example.
2024-11-02 01:47:32 +00:00
Sou1gh0st
db4a74be76
Support prefers_home_indicator_hidden (#16005)
# Objective

- Fixes #15757 

## Solution

- Add the platform specific property `prefers_home_indicator_hidden` to
bevy's Window configuration, and applying it by invoking
`with_prefers_home_indicator_hidden` in `winit`.

## Testing

- I have tested the `bevy_mobile_example` on the iOS platform.

## Showcase
- Currently, the `prefers_home_indicator_hidden` is enabled in the
bevy_mobile_example demo. You can test it with an iOS device. The home
indicator will disappear after several seconds of inactivity in the
bottom areas.

---------

Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com>
2024-10-31 16:09:30 +00:00
Peter Hayman
75096fbf97
fix: add reflect to SceneInstanceReady and other observers/events (#16018)
# Objective

Built-in observers & events should be `Reflect` so that components that
interact with them can be serialized in scenes. This is a similar pr to
#14259.
2024-10-20 13:51:41 +00:00
Elabajaba
8f31c09e60
Add docs for how to manually add a WinitPlugin to a MinimalPlugins setup. (#15989)
# Objective

Adding a `WinitPlugin` to a `MinimalPlugins` setup is a bit tricky and
confusing due to having a terrible error message and no examples in the
repo.

## Solution

Document what you need to add.
2024-10-19 21:44:02 +00:00
Shane Celis
5157fef84b
Add window drag move and drag resize without decoration example. (#15814)
# Objective

Add an example for the new drag move and drag resize introduced by PR
#15674 and fix #15734.

## Solution

I created an example that allows the user to exercise drag move and drag
resize separately. The user can also choose what direction the resize
works in.

![Screenshot 2024-10-10 at 4 06
43 AM](https://github.com/user-attachments/assets/1da558ab-a80f-49af-8b7d-bb635b0f038f)

### Name

The example is called `window_drag_move`. Happy to have that
bikeshedded.

### Contentious Refactor?

This PR removed the `ResizeDirection` enumeration in favor of using
`CompassOctant` which had the same variants. Perhaps this is
contentious.

### Unsafe?

In PR #15674 I mentioned that `start_drag_move()` and
`start_drag_resize()`'s requirement to only be called in the presence of
a left-click looks like a compiler-unenforceable contract that can cause
intermittent panics when not observed, so perhaps the functions should
be marked them unsafe. **I have not made that change** here since I
didn't see a clear consensus on that.

## Testing

I exercised this on x86 macOS. However, winit for macOS does not support
drag resize. It reports a good error when `start_drag_resize()` is
called. I'd like to see it tested on Windows and Linux.

---

## Showcase

Example window_drag_move shows how to drag or resize a window without
decoration.

---------

Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com>
2024-10-15 23:38:35 +00:00
François Mockers
89e19aaff0
force last update after setting state to Suspended (#15888)
# Objective

- Android doesn't receive lifecycle event `Suspended` before suspension

## Solution

- Fix update triggering just after state change on android

## Testing

- Tested on the android emulator
2024-10-14 01:40:03 +00:00
aecsocket
992d17bc7f
Add bevy_window::Window options for MacOS (#15820)
# Objective

MacOS has some nice options for controlling the window and titlebar to
make the content appear much more "immersively" in the window. This PR
exposes options for controlling this.

## Solution

Adds new fields to `Window` to control these, with doc comments to
explain what they do and that they're MacOS only.

## Testing

Tested on a MacOS machine (not my own, I don't have one). That's where
the below screenshots were taken.

---

## Showcase

On MacOS, you now have more options for configuring the window titlebar.
You can, for example, make the title bar transparent and only show the
window controls. This provides a more "immersive" experience for your
rendered content.

Before, only this was possible:
<img width="1392" alt="image"
src="https://github.com/user-attachments/assets/abf03da2-d247-4202-a7e7-731c45d80d54">

Now, you can create windows like this:
<img width="1392" alt="image2"
src="https://github.com/user-attachments/assets/3239d0e3-4708-4798-8755-188541e14f93">

This uses the following `bevy_window::Window` settings:
```rs
fullsize_content_view: true,
titlebar_transparent: true,
titlebar_show_title: false,
```

## Migration Guide

`bevy_window::Window` now has extra fields for configuring MacOS window
settings:
```rs
    pub movable_by_window_background: bool,
    pub fullsize_content_view: bool,
    pub has_shadow: bool,
    pub titlebar_shown: bool,
    pub titlebar_transparent: bool,
    pub titlebar_show_title: bool,
    pub titlebar_show_buttons: bool,
```

Using `Window::default` keeps the same behaviour as before.
2024-10-11 21:11:21 +00:00
Christian Hughes
219b5930f1
Rename App/World::observe to add_observer, EntityWorldMut::observe_entity to observe. (#15754)
# Objective

- Closes #15752

Calling the functions `App::observe` and `World::observe` doesn't make
sense because you're not "observing" the `App` or `World`, you're adding
an observer that listens for an event that occurs *within* the `World`.
We should rename them to better fit this.

## Solution

Renames:
- `App::observe` -> `App::add_observer`
- `World::observe` -> `World::add_observer`
- `Commands::observe` -> `Commands::add_observer`
- `EntityWorldMut::observe_entity` -> `EntityWorldMut::observe`

(Note this isn't a breaking change as the original rename was introduced
earlier this cycle.)

## Testing

Reusing current tests.
2024-10-09 15:39:29 +00:00
Isse
82aa2e3161
Add the functions start_drag_move and start_drag_resize to Window (#15674)
# Objective
Expose the `winit` functions
[drag_window](https://docs.rs/winit/latest/winit/window/struct.Window.html#method.drag_window)
and
[resize_window](https://docs.rs/winit/latest/winit/window/struct.Window.html#method.drag_resize_window).

Which allows implementing move & resize for windows without decorations.

## Solution

Add the functions `start_drag_move` and `start_drag_resize` to
`bevy_window::Window`, which are then assigned to fields in
`InternalWindowState`, and propagated to `winit` in the
`changed_windows` system.

## Testing

I've tested that both functions works on x11 and wayland. Not sure if
someone needs to test on windows/mac?

---

## Showcase

[Screencast from 2024-10-06 11-49-58
(trimmed).webm](https://github.com/user-attachments/assets/1cdee7b1-22bd-41d3-8a0a-6872a6ebf62c)

(The flickering in the video is some issue with resizing without
decorations on x11)

<details>
  <summary>Click to view showcase</summary>

Not the same code used in the video, but simple way to test moving a
window without decorations.
```rust
use bevy::prelude::*;

fn main() {
    App::new()
        .add_plugins(DefaultPlugins.set(WindowPlugin {
            primary_window: Some(Window {
                decorations: false,
                ..default()
            }),
            ..default()
        }))
        .add_systems(Update, move_windows)
        .run();
}

fn move_windows(mut windows: Query<&mut Window>, input: Res<ButtonInput<MouseButton>>) {
    if input.pressed(MouseButton::Left) {
        for mut window in windows.iter_mut() {
            window.start_drag_move();
        }
    }
}
```

</details>

---------

Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com>
2024-10-08 16:32:07 +00:00
Bude
6edb78a8c3
Inverse bevy_render bevy_winit dependency and move cursor to bevy_winit (#15649)
# Objective

- `bevy_render` should not depend on `bevy_winit`
- Fixes #15565

## Solution

- `bevy_render` no longer depends on `bevy_winit`
- The following is behind the `custom_cursor` feature
- Move custom cursor code from `bevy_render` to `bevy_winit` behind the
`custom_cursor` feature
- `bevy_winit` now depends on `bevy_render` (for `Image` and
`TextureFormat`)
- `bevy_winit` now depends on `bevy_asset` (for `Assets`, `Handle` and
`AssetId`)
  - `bevy_winit` now depends on `bytemuck` (already in tree)
- Custom cursor code in `bevy_winit` reworked to use `AssetId` (other
than that it is taken over 1:1)
- Rework `bevy_winit` custom cursor interface visibility now that the
logic is all contained in `bevy_winit`

## Testing

- I ran the screenshot and window_settings examples
- Tested on linux wayland so far

---

## Migration Guide

`CursorIcon` and `CustomCursor` previously provided by
`bevy::render::view::cursor` is now available from `bevy::winit`.
A new feature `custom_cursor` enables this functionality (default
feature).
2024-10-06 18:25:50 +00:00