popout: let open animation play on first fit
resize() and resize_and_move() gain an animate flag — when True, skip the no_anim setprop so Hyprland's windowsIn/popin animation plays through. Popout passes animate=_first_fit_pending so the first fit after open animates; subsequent navigation fits still suppress anim to avoid resize flicker. behavior change: popout now animates in on open instead of snapping.
This commit is contained in:
parent
9713794633
commit
e004add28f
@ -89,7 +89,9 @@ windowrule {
|
|||||||
popout geometry
|
popout geometry
|
||||||
- `dispatch togglefloating` on the main window at launch
|
- `dispatch togglefloating` on the main window at launch
|
||||||
- `dispatch setprop address:<addr> no_anim 1` applied during popout
|
- `dispatch setprop address:<addr> no_anim 1` applied during popout
|
||||||
transitions
|
transitions (skipped on the first fit after open so Hyprland's
|
||||||
|
`windowsIn` / `popin` animation can play — subsequent navigation
|
||||||
|
fits still suppress anim to avoid resize flicker)
|
||||||
- The startup "prime" sequence that warms Hyprland's per-window
|
- The startup "prime" sequence that warms Hyprland's per-window
|
||||||
floating cache
|
floating cache
|
||||||
|
|
||||||
|
|||||||
@ -54,7 +54,7 @@ def get_window(window_title: str) -> dict | None:
|
|||||||
return None
|
return None
|
||||||
|
|
||||||
|
|
||||||
def resize(window_title: str, w: int, h: int) -> None:
|
def resize(window_title: str, w: int, h: int, animate: bool = False) -> None:
|
||||||
"""Ask Hyprland to resize the popout and lock its aspect ratio.
|
"""Ask Hyprland to resize the popout and lock its aspect ratio.
|
||||||
|
|
||||||
No-op on non-Hyprland systems. Tiled windows skip the resize
|
No-op on non-Hyprland systems. Tiled windows skip the resize
|
||||||
@ -86,12 +86,12 @@ def resize(window_title: str, w: int, h: int) -> None:
|
|||||||
if not win.get("floating"):
|
if not win.get("floating"):
|
||||||
# Tiled — don't resize (fights the layout). Optionally set
|
# Tiled — don't resize (fights the layout). Optionally set
|
||||||
# aspect lock and no_anim depending on the env vars.
|
# aspect lock and no_anim depending on the env vars.
|
||||||
if rules_on:
|
if rules_on and not animate:
|
||||||
cmds.append(f"dispatch setprop address:{addr} no_anim 1")
|
cmds.append(f"dispatch setprop address:{addr} no_anim 1")
|
||||||
if aspect_on:
|
if aspect_on:
|
||||||
cmds.append(f"dispatch setprop address:{addr} keep_aspect_ratio 1")
|
cmds.append(f"dispatch setprop address:{addr} keep_aspect_ratio 1")
|
||||||
else:
|
else:
|
||||||
if rules_on:
|
if rules_on and not animate:
|
||||||
cmds.append(f"dispatch setprop address:{addr} no_anim 1")
|
cmds.append(f"dispatch setprop address:{addr} no_anim 1")
|
||||||
if aspect_on:
|
if aspect_on:
|
||||||
cmds.append(f"dispatch setprop address:{addr} keep_aspect_ratio 0")
|
cmds.append(f"dispatch setprop address:{addr} keep_aspect_ratio 0")
|
||||||
@ -111,6 +111,7 @@ def resize_and_move(
|
|||||||
x: int,
|
x: int,
|
||||||
y: int,
|
y: int,
|
||||||
win: dict | None = None,
|
win: dict | None = None,
|
||||||
|
animate: bool = False,
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Atomically resize and move the popout via a single hyprctl batch.
|
"""Atomically resize and move the popout via a single hyprctl batch.
|
||||||
|
|
||||||
@ -140,7 +141,7 @@ def resize_and_move(
|
|||||||
if not addr:
|
if not addr:
|
||||||
return
|
return
|
||||||
cmds: list[str] = []
|
cmds: list[str] = []
|
||||||
if rules_on:
|
if rules_on and not animate:
|
||||||
cmds.append(f"dispatch setprop address:{addr} no_anim 1")
|
cmds.append(f"dispatch setprop address:{addr} no_anim 1")
|
||||||
if aspect_on:
|
if aspect_on:
|
||||||
cmds.append(f"dispatch setprop address:{addr} keep_aspect_ratio 0")
|
cmds.append(f"dispatch setprop address:{addr} keep_aspect_ratio 0")
|
||||||
|
|||||||
@ -1325,7 +1325,7 @@ class FullscreenPreview(QMainWindow):
|
|||||||
else:
|
else:
|
||||||
floating = None
|
floating = None
|
||||||
if floating is False:
|
if floating is False:
|
||||||
hyprland.resize(self.windowTitle(), 0, 0) # tiled: just set keep_aspect_ratio
|
hyprland.resize(self.windowTitle(), 0, 0, animate=self._first_fit_pending) # tiled: just set keep_aspect_ratio
|
||||||
self._tiled_pending_content = (content_w, content_h)
|
self._tiled_pending_content = (content_w, content_h)
|
||||||
return
|
return
|
||||||
self._tiled_pending_content = None
|
self._tiled_pending_content = None
|
||||||
@ -1373,7 +1373,10 @@ class FullscreenPreview(QMainWindow):
|
|||||||
# Hyprland: hyprctl is the sole authority. Calling self.resize()
|
# Hyprland: hyprctl is the sole authority. Calling self.resize()
|
||||||
# here would race with the batch below and produce visible flashing
|
# here would race with the batch below and produce visible flashing
|
||||||
# when the window also has to move.
|
# when the window also has to move.
|
||||||
hyprland.resize_and_move(self.windowTitle(), w, h, x, y, win=win)
|
hyprland.resize_and_move(
|
||||||
|
self.windowTitle(), w, h, x, y, win=win,
|
||||||
|
animate=self._first_fit_pending,
|
||||||
|
)
|
||||||
else:
|
else:
|
||||||
# Non-Hyprland fallback: Qt drives geometry directly. Use
|
# Non-Hyprland fallback: Qt drives geometry directly. Use
|
||||||
# setGeometry with the computed top-left rather than resize()
|
# setGeometry with the computed top-left rather than resize()
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user