Port · Calendar: a real exit clears the preview after a key
The calendar's grid clears its preview on leave, and ignores a leave that follows a key. gpui records the exit a key makes before the handler runs, so the guard swallowed it and a real exit afterwards had no change left to report: the stale day stayed the preview. The grid now listens independently of input, while its days keep the default, so a key is no leave and a real exit is. A test leaves the grid after an arrow, a letter and a month key. shaped()'s doc goes back to its one line; AGENTS.md keeps the why. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
94deeaed52
commit
f76c3c1280
5 files changed
+28
-5
No files matched your search
@@ -53,7 +53,7 @@ Ely GPUI Component. A component library for GPUI, in light and dark.
|
||||
- `hover()` needs an element id.
|
||||
- gpui applies hover and group-hover styles once an element has a hitbox, in prepaint and paint, but text takes its color at layout, so a hover cannot recolor text. What shows on hover rests `invisible()` and turns `visible()` through `group_hover` (`chat::ConversationItem`, `messaging::ChatMessage`).
|
||||
- gpui 0.2.2 panics on a deferred draw inside another. Whatever draws over the page goes through `primitives::raise`: at the top it defers; inside something raised it lays out on its own and draws last there, so a list opened in a dialog lies over the dialog. A raise takes its owner's id and draws under it, so its keyed state and focus hold while other raises come and go. `scripts/check.sh` refuses gpui's `deferred` anywhere else.
|
||||
- gpui hides hover after a key press until the mouse moves. A hover that holds or shows something (the toast stack, a carousel, tooltips, hover cards, charts, scroll activity) sets `HoverListenerMode::InputModalityIndependent`, so typing under a resting pointer keeps it. A hover preview the keyboard also moves keeps the default, and its leave ignores a key press through `last_input_was_keyboard` (`forms::Calendar`).
|
||||
- gpui hides hover after a key press until the mouse moves. A hover that holds or shows something (the toast stack, a carousel, tooltips, hover cards, charts, scroll activity) sets `HoverListenerMode::InputModalityIndependent`, so typing under a resting pointer keeps it. A hover preview the keyboard also moves keeps the default on its items; the box that clears it on leave listens independently, so a real exit still reports, and ignores a leave that follows a key through `last_input_was_keyboard` (`forms::Calendar`).
|
||||
- `occlude()` blocks the pointer for everything painted before it, its own ancestors too. Put it on the outermost box that should stop the pointer, as the toast stack does, or the ancestors' hover never fires.
|
||||
- A drag that pans, turns or slides goes through gpui's drag, whose moves reach the owner in or out of its box; `on_mouse_move` stops at the box's edge. gpui sends a drag's moves to every listener of its type, so each payload carries its owner's `EntityId` and handlers check it.
|
||||
- gpui 0.2.2 paints pictures without a transform, so a picture turns by its pixels: `media::turn` turns decoded frames by quarter turns off the main thread, an asset keyed by the picture and the turn. An svg turns to any angle through its `Transformation`, so a control that turns shows one (`interaction::Rotatable`).
|
||||
|
||||
@@ -476,3 +476,4 @@ Per-component lines live in `tasks/`. Tags there:
|
||||
| T44a | 1 | FAIL | twelve roots in nine components still said w_full: a root held in a variable, a match arm or an animation passed the sweep |
|
||||
| T44a | 2 | FAIL | roots built in render(mut self), returned by shared helpers or passed through them still said w_full: fields, charts, state views, Steps, previews; five measured at content width in a padded card |
|
||||
| T44a | 3 | PASS | the brief counted 43 components in the new tests; they hold 41 |
|
||||
| T44b | 1 | FAIL | after a key, leaving the calendar grid kept a stale preview, since the guard swallowed the exit gpui records for the key; the shaped() doc grew to 40 words |
|
||||
+1
-1
@@ -15,7 +15,7 @@ use crate::{
|
||||
typography::{Ellipsis, format::file_size},
|
||||
};
|
||||
|
||||
/// A box in a picture's own shape: as wide as the picture, but no wider than `widest` or its container. Hand it to a flex column inside a block: taffy 0.13 sizes the column by its width before its cap.
|
||||
/// A box in a picture's own shape: as wide as the picture, but no wider than `widest` or its container.
|
||||
pub(crate) fn shaped(width: f32, height: f32, widest: Pixels) -> Div {
|
||||
assert!(
|
||||
width > 0.0 && height > 0.0,
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
use std::rc::Rc;
|
||||
|
||||
use gpui::{
|
||||
Animation, AnimationExt, App, ElementId, FocusHandle, FontWeight, InteractiveElement,
|
||||
IntoElement, ParentElement, RenderOnce, StatefulInteractiveElement, Styled, Window, div,
|
||||
prelude::*, transparent_black,
|
||||
Animation, AnimationExt, App, ElementId, FocusHandle, FontWeight, HoverListenerMode,
|
||||
InteractiveElement, IntoElement, ParentElement, RenderOnce, StatefulInteractiveElement, Styled,
|
||||
Window, div, prelude::*, transparent_black,
|
||||
};
|
||||
use jiff::{ToSpan, civil::Date};
|
||||
|
||||
@@ -328,6 +328,7 @@ impl RenderOnce for Calendar {
|
||||
.grid()
|
||||
.grid_cols(7)
|
||||
.gap_0p5()
|
||||
.hover_listener_mode(HoverListenerMode::InputModalityIndependent)
|
||||
.on_hover(move |over, window, cx| {
|
||||
if !*over && !window.last_input_was_keyboard() {
|
||||
leave.update(cx, |hover, cx| {
|
||||
|
||||
@@ -236,3 +236,24 @@ fn keys_keep_the_preview_under_a_resting_pointer(cx: &mut TestAppContext) {
|
||||
"the keyboard's day stays the preview"
|
||||
);
|
||||
}
|
||||
|
||||
#[gpui::test]
|
||||
fn leaving_the_grid_after_a_key_clears_the_preview(cx: &mut TestAppContext) {
|
||||
setup(cx);
|
||||
for key in ["right", "a", "pagedown"] {
|
||||
let (view, cx) = cx.add_window_view(|_, _| Watched { seen: Vec::new() });
|
||||
cx.update(|window, cx| window.focus_next(cx));
|
||||
cx.simulate_mouse_move(point(px(120.0), px(200.0)), None, Modifiers::none());
|
||||
cx.simulate_keystrokes(key);
|
||||
cx.update(|window, _| window.refresh());
|
||||
cx.run_until_parked();
|
||||
cx.simulate_mouse_move(point(px(700.0), px(480.0)), None, Modifiers::none());
|
||||
cx.update(|window, _| window.refresh());
|
||||
cx.run_until_parked();
|
||||
assert_eq!(
|
||||
view.read_with(cx, |view, _| view.seen.last().copied().flatten()),
|
||||
None,
|
||||
"after {key}, leaving the grid clears its preview"
|
||||
);
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user