FeathersNumberInput text input node can be left with zero width when an unrelated node is hovered
I maintainer di solito rispondono entro 2 giorni
@collapsedonion ci sta già lavorando.
Dal 28/10/2026.
Valutazione
- Difficoltà
- 3/5
- Tempo stimato
- Mezza giornata
- Idoneità per principianti
- 68/100
Direzione di ricerca
Start by locating the Bevy Feathers number input implementation and its UI layout tests; the issue does not name specific files. Reproduce the two side-by-side inputs and hover one, then inspect why the other input's text node gets zero width when its container has max_width but no explicit width. Done when the non-hovered input retains a visible text area and a regression test covers the layout.
Scritto dal modello di indicizzazione a partire dal testo della issue.
Descrizione
Bevy version and features
bevy = { version = "0.20.0", features = ["bevy_feathers"] }
What you did
Two FeathersNumberInputs side by side, each in its own Baseline row inside a column inside a shared row, then hover one of them.
use bevy::{
feathers::{
FeathersPlugins,
controls::{
FeathersNumberInput, FeathersTextInput, HardLimit, NumberInputPrecision,
NumberInputStep, NumberInputValue, SoftLimit,
},
dark_theme::create_dark_theme,
theme::{ThemeBackgroundColor, UiTheme},
tokens,
},
prelude::*,
ui::ComputedNode,
};
#[derive(Component, Clone, Copy, Default)]
struct Left;
#[derive(Component, Clone, Copy, Default)]
struct Right;
#[derive(SceneComponent, Clone, Default)]
struct ReproNumberInput;
impl ReproNumberInput {
fn scene() -> impl Scene {
bsn! {
@FeathersNumberInput
Node {
// width: px(100), // This fixes the issue
max_width: px(100),
}
NumberInputValue::F32(1.0)
NumberInputPrecision(1)
NumberInputStep(0.1)
SoftLimit::f32(0.1..=3.0)
HardLimit::f32(0.1..=3.0)
}
}
}
fn main() {
App::new()
.add_plugins((
DefaultPlugins.set(WindowPlugin {
primary_window: Some(Window {
resolution: (400, 200).into(),
..default()
}),
..default()
}),
FeathersPlugins,
))
.insert_resource(UiTheme(create_dark_theme()))
.add_systems(Startup, setup)
.add_systems(Update, drive)
.run();
}
fn setup(mut commands: Commands) {
commands.spawn_scene_list(bsn_list! {
Camera2d
IsDefaultUiCamera
--
Node {
width: percent(100),
height: percent(100),
align_items: AlignItems::Center,
justify_content: JustifyContent::Center,
}
ThemeBackgroundColor(tokens::WINDOW_BG)
Children [
Node {
flex_direction: FlexDirection::Column,
justify_content: JustifyContent::FlexStart,
flex_grow: 1.0,
height: percent(100),
}
Children [
Node {
flex_direction: FlexDirection::Row,
justify_content: JustifyContent::FlexStart,
align_items: AlignItems::Baseline,
}
Children [
Node {
width: px(18),
min_width: px(18),
height: px(18),
}
--
@ReproNumberInput
Left
]
]
--
Node {
flex_direction: FlexDirection::Column,
justify_content: JustifyContent::FlexStart,
flex_grow: 1.0,
height: percent(100),
}
Children [
Node {
flex_direction: FlexDirection::Row,
justify_content: JustifyContent::FlexStart,
align_items: AlignItems::Baseline,
}
Children [
Node {
width: px(18),
min_width: px(18),
height: px(18),
}
--
@ReproNumberInput
Right
]
]
]
});
}
fn text_node_of(
root: Entity,
children: &Query<&Children>,
is_text_input: &Query<(), With<FeathersTextInput>>,
) -> Option<Entity> {
children
.iter_descendants(root)
.find(|e| is_text_input.contains(*e))
}
fn text_width(
root: Entity,
children: &Query<&Children>,
is_text_input: &Query<(), With<FeathersTextInput>>,
nodes: &Query<&ComputedNode>,
) -> Option<f32> {
let text = text_node_of(root, children, is_text_input)?;
nodes.get(text).ok().map(|n| n.size().x)
}
fn drive(
mut verdict: Local<bool>,
q_left: Query<Entity, With<Left>>,
q_right: Query<Entity, With<Right>>,
q_children: Query<&Children>,
q_is_text_input: Query<(), With<FeathersTextInput>>,
q_nodes: Query<&ComputedNode>,
) {
let Ok(left) = q_left.single() else { return };
let Ok(right) = q_right.single() else { return };
let left_width = text_width(left, &q_children, &q_is_text_input, &q_nodes);
let right_width = text_width(right, &q_children, &q_is_text_input, &q_nodes);
if right_width == Some(0.0) && left_width == Some(0.0) {
return;
}
if !*verdict && (right_width == Some(0.0) || left_width == Some(0.0)) {
info!("left text width = {left_width:?}, right text width = {right_width:?}");
*verdict = true;
}
}
What went wrong
The other (non-hovered) FeathersNumberInput renders as a blank grey rectangle. Its text node's ComputedNode::size().x becomes 0 while its height stays non-zero, so only the containers background shows through.
Output from the above repro when hovering over the left input:
left text width = Some(200.0), right text width = Some(0.0)
Additional information
AI was used to help reduce the reproduction to its minimal form.
Initial screenshot:
Screenshot after hovering over leftmost FeathersNumberInput:
Adding an explicit width: px(100) to the FeathersNumberInput Node fixes the issue.
- Lingua principale
- Rust
- Stelle
- 49.7k
- Fork
- 5k
- Merge medio
- 3g 19h
- PR unite (30g)
- 134
Preparare l'ambiente
- Nessun Dockerfile né file Docker Compose
- Ha un modello di pull request
- Leggi la guida per i contributori
Come iniziare
- Leggi tutta la issue e poi la guida ai contributi del progetto.
- Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
- Fai un fork del repository e lavora su un branch.
- Apri una pull request che faccia riferimento al numero della issue.
Altre issue di bevyengine/bevy
-
C-Bug S-Needs-Triage
Difficoltà 2/5 1-3 ore Idoneità per principianti 68/100
bevyengine/bevy#26536 ·
I maintainer di solito rispondono entro 2 giorni
-
Placeholder has no defaultForse già presa Una pull request collegata a questa issue è aperta o già unita. ApertaC-Feature S-Needs-Triage
Difficoltà 1/5 Meno di un'ora Idoneità per principianti 62/100
bevyengine/bevy#26532 · 1 commento ·
I maintainer di solito rispondono entro 2 giorni
-
C-Feature S-Needs-Triage
Difficoltà 2/5 1-3 ore Idoneità per principianti 68/100
bevyengine/bevy#26500 · 1 commento ·
I maintainer di solito rispondono entro 2 giorni
-
C-Feature S-Needs-Triage
Difficoltà 1/5 Meno di un'ora Idoneità per principianti 68/100
bevyengine/bevy#26499 ·
I maintainer di solito rispondono entro 2 giorni
-
`compute_histogram` in auto exposure writes past the end of the 64-bin histogramForse già presa @dev-matru l’ha presa 3 giorni fa. ApertaA-Rendering C-Bug D-Straightforward S-Ready-For-Implementation X-Uncontroversial
Difficoltà 2/5 1-3 ore Idoneità per principianti 88/100
bevyengine/bevy#26479 ·
I maintainer di solito rispondono entro 2 giorni
Tutte le issue di bevyengine/bevy
Issue simili
-
bug UI
Difficoltà 2/5 1-3 ore Idoneità per principianti 70/100
wardian-app/Wardian#1746 ·
I maintainer di solito rispondono entro 1 giorno
-
Difficoltà 2/5 1-3 ore Idoneità per principianti 82/100
jlcodes99/cockpit-tools#3125 ·
I maintainer di solito rispondono entro 2 giorni
-
bug user-sprint
Difficoltà 2/5 1-3 ore Idoneità per principianti 72/100
Vondor/KassenSturz#967 ·
I maintainer di solito rispondono entro 1 giorno
-
area/ci
Difficoltà 1/5 Meno di un'ora Idoneità per principianti 62/100
I maintainer di solito rispondono entro 1 giorno
-
[BUG] Incremental sync warns "no stored highest_uid" on every round for folders with no new mailApertabug
Difficoltà 2/5 1-3 ore Idoneità per principianti 70/100
rustmailer/bichon#411 ·