Daylight bar chrome + embedded launcher, v0.7.5 pins #5
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