workspaces: derive trail width only from a live button; wire the launcher hotkey
Two fixes. The trail pill still grew when spamming between workspace 1 and an empty 6. Switching to an empty workspace makes Hyprland create and destroy it, which rebuilds the button row mid-animation and leaves the source button detached — button_geom then returned None and the fallback handed the wide mid-stretch span straight back in, reintroducing exactly the accumulation the previous commit removed. Width now falls back to the destination button, which is always live, and no path returns the live width any more. Separately, AppInput::OpenLauncher's local arm only called grab_focus(). Focus stopped opening the capsule when connect_enter's open_fn() call was removed (that call was what opened the capsule during window construction), so the keybind focused the entry and left the drawer shut. It now invokes launcher_open_fn, which was added for this and never read — the dead-code warning on that field is what surfaced it.
This commit is contained in:
parent
42d5acb736
commit
1b523eab63
2 changed files with 26 additions and 5 deletions
|
|
@ -369,7 +369,7 @@ impl WorkspaceTrail {
|
|||
|
||||
pub fn stretch(&self, from: Option<>k4::Button>, to: >k4::Button) {
|
||||
self.cancel();
|
||||
let Some(from_g) = self.from_geom(from) else {
|
||||
let Some(from_g) = self.from_geom(from, to) else {
|
||||
self.place(to);
|
||||
return;
|
||||
};
|
||||
|
|
@ -411,7 +411,7 @@ impl WorkspaceTrail {
|
|||
self.inner.borrow_mut().tick = Some(id);
|
||||
}
|
||||
|
||||
fn from_geom(&self, from: Option<>k4::Button>) -> Option<Geom> {
|
||||
fn from_geom(&self, from: Option<>k4::Button>, to: >k4::Button) -> Option<Geom> {
|
||||
let st = self.inner.borrow();
|
||||
let live = if self.pill.is_visible() && st.geom.w > 0.5 {
|
||||
Some(st.geom)
|
||||
|
|
@ -420,7 +420,17 @@ impl WorkspaceTrail {
|
|||
};
|
||||
drop(st);
|
||||
|
||||
let natural = from.and_then(|b| button_geom(b, &self.host).map(inset_pill));
|
||||
// Width must always come from a button that is CURRENTLY IN THE ROW.
|
||||
// Switching to an empty workspace makes Hyprland create and destroy it,
|
||||
// which rebuilds the button row mid-animation and can leave `from`
|
||||
// detached — `button_geom` then returns None. Falling back to the live
|
||||
// geometry there handed the wide mid-stretch span straight back in,
|
||||
// which is exactly the accumulation this function exists to prevent
|
||||
// (reproduced by spamming between workspace 1 and an empty 6). The
|
||||
// destination button is always live, so it is the correct fallback.
|
||||
let natural = from
|
||||
.and_then(|b| button_geom(b, &self.host).map(inset_pill))
|
||||
.or_else(|| button_geom(to, &self.host).map(inset_pill));
|
||||
|
||||
// Continuity without accumulation.
|
||||
//
|
||||
|
|
@ -437,6 +447,10 @@ impl WorkspaceTrail {
|
|||
// Taking position from the live geometry and width from the source
|
||||
// button's natural size keeps the motion continuous while making width
|
||||
// a pure function of which button we started from.
|
||||
// `natural` is None only if BOTH buttons are detached, in which case
|
||||
// there is no sane width to animate from and the caller falls back to
|
||||
// an instant `place()`. There is deliberately no path that returns the
|
||||
// live width.
|
||||
match (live, natural) {
|
||||
(Some(live), Some(natural)) => Some(Geom {
|
||||
x: live.x,
|
||||
|
|
@ -444,8 +458,8 @@ impl WorkspaceTrail {
|
|||
w: natural.w,
|
||||
h: natural.h,
|
||||
}),
|
||||
(Some(live), None) if live.w <= MAX_CHIP_W => Some(live),
|
||||
(_, natural) => natural,
|
||||
(None, natural) => natural,
|
||||
(Some(_), None) => None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1915,6 +1915,13 @@ impl SimpleComponent for App {
|
|||
// below is a silent no-op.
|
||||
self.launcher_entry.set_can_focus(true);
|
||||
self.launcher_entry.grab_focus();
|
||||
// ...and then actually OPEN it. Focus alone no longer
|
||||
// opens the capsule: `connect_enter` used to call
|
||||
// `open_fn()`, which is precisely what made the capsule
|
||||
// open itself during window construction, so that path
|
||||
// was deliberately removed. Without this call the
|
||||
// keybind focuses the entry and leaves the drawer shut.
|
||||
(self.launcher_open_fn)();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue