popout: remember tiled state across open/close
Popout was always reopening as floating even when it had been tiled at close. closeEvent already persisted geometry + fullscreen, but nothing captured the Hyprland floating/tiled bit, so the windowrule's `float = yes` rule always won on reopen. Now closeEvent records `_saved_tiled` from hyprctl, popout_controller persists it as `slideshow_tiled`, and FullscreenPreview's restore path calls the new `hyprland.settiled` helper shortly after show() to push the window back into the layout. Saved geometry is ignored for tiled reopens since the tile extent is the layout's concern. behavior change: popout reopens tiled if it was tiled at close.
This commit is contained in:
parent
a2609199bd
commit
3c2aa5820d
@ -211,9 +211,35 @@ def get_monitor_available_rect(monitor_id: int | None = None) -> tuple[int, int,
|
||||
return None
|
||||
|
||||
|
||||
def settiled(window_title: str) -> None:
|
||||
"""Ask Hyprland to un-float the popout, restoring it to tiled layout.
|
||||
|
||||
Used on reopen when the popout was tiled at close — the windowrule
|
||||
opens it floating, so we dispatch `settiled` to push it back into
|
||||
the layout.
|
||||
|
||||
Gated by BOORU_VIEWER_NO_HYPR_RULES so ricers with their own rules
|
||||
keep control.
|
||||
"""
|
||||
if not _on_hyprland():
|
||||
return
|
||||
if not hypr_rules_enabled():
|
||||
return
|
||||
win = get_window(window_title)
|
||||
if not win:
|
||||
return
|
||||
addr = win.get("address")
|
||||
if not addr:
|
||||
return
|
||||
if not win.get("floating"):
|
||||
return
|
||||
_dispatch_batch([f"dispatch settiled address:{addr}"])
|
||||
|
||||
|
||||
__all__ = [
|
||||
"get_window",
|
||||
"get_monitor_available_rect",
|
||||
"resize",
|
||||
"resize_and_move",
|
||||
"settiled",
|
||||
]
|
||||
|
||||
@ -350,7 +350,16 @@ class FullscreenPreview(QMainWindow):
|
||||
# F11 → fullscreen → F11 has a sensible target.
|
||||
self._windowed_geometry = None
|
||||
# Restore saved state or start fullscreen
|
||||
if FullscreenPreview._saved_geometry and not FullscreenPreview._saved_fullscreen:
|
||||
if FullscreenPreview._saved_tiled and not FullscreenPreview._saved_fullscreen:
|
||||
# Was tiled at last close — let Hyprland's layout place it,
|
||||
# then dispatch `settiled` to override the windowrule's float.
|
||||
# Saved geometry is meaningless for a tiled window, so skip
|
||||
# setGeometry entirely.
|
||||
self.show()
|
||||
QTimer.singleShot(
|
||||
50, lambda: hyprland.settiled(self.windowTitle())
|
||||
)
|
||||
elif FullscreenPreview._saved_geometry and not FullscreenPreview._saved_fullscreen:
|
||||
self.setGeometry(FullscreenPreview._saved_geometry)
|
||||
self._pending_position_restore = (
|
||||
FullscreenPreview._saved_geometry.x(),
|
||||
@ -628,6 +637,7 @@ class FullscreenPreview(QMainWindow):
|
||||
|
||||
_saved_geometry = None # remembers window size/position across opens
|
||||
_saved_fullscreen = False
|
||||
_saved_tiled = False # True if Hyprland had it tiled at last close
|
||||
_current_tags: dict[str, list[str]] = {}
|
||||
_current_tag_list: list[str] = []
|
||||
|
||||
@ -1754,9 +1764,13 @@ class FullscreenPreview(QMainWindow):
|
||||
# Geometry is adapter-side concern, not state machine concern,
|
||||
# so the state machine doesn't see it.
|
||||
FullscreenPreview._saved_fullscreen = self.isFullScreen()
|
||||
FullscreenPreview._saved_tiled = False
|
||||
if not self.isFullScreen():
|
||||
# On Hyprland, Qt doesn't know the real position — ask the WM
|
||||
win = hyprland.get_window(self.windowTitle())
|
||||
if win and win.get("floating") is False:
|
||||
# Tiled: reopen will re-tile instead of restoring geometry.
|
||||
FullscreenPreview._saved_tiled = True
|
||||
if win and win.get("at") and win.get("size"):
|
||||
from PySide6.QtCore import QRect
|
||||
x, y = win["at"]
|
||||
|
||||
@ -76,17 +76,21 @@ class PopoutController:
|
||||
from .popout.window import FullscreenPreview
|
||||
saved_geo = self._app._db.get_setting("slideshow_geometry")
|
||||
saved_fs = self._app._db.get_setting_bool("slideshow_fullscreen")
|
||||
saved_tiled = self._app._db.get_setting_bool("slideshow_tiled")
|
||||
if saved_geo:
|
||||
parts = saved_geo.split(",")
|
||||
if len(parts) == 4:
|
||||
from PySide6.QtCore import QRect
|
||||
FullscreenPreview._saved_geometry = QRect(*[int(p) for p in parts])
|
||||
FullscreenPreview._saved_fullscreen = saved_fs
|
||||
FullscreenPreview._saved_tiled = saved_tiled
|
||||
else:
|
||||
FullscreenPreview._saved_geometry = None
|
||||
FullscreenPreview._saved_fullscreen = True
|
||||
FullscreenPreview._saved_tiled = False
|
||||
else:
|
||||
FullscreenPreview._saved_fullscreen = True
|
||||
FullscreenPreview._saved_tiled = saved_tiled
|
||||
cols = self._app._grid._flow.columns
|
||||
show_actions = self._app._stack.currentIndex() != 2
|
||||
monitor = self._app._db.get_setting("slideshow_monitor")
|
||||
@ -135,7 +139,9 @@ class PopoutController:
|
||||
from .popout.window import FullscreenPreview
|
||||
fs = FullscreenPreview._saved_fullscreen
|
||||
geo = FullscreenPreview._saved_geometry
|
||||
tiled = FullscreenPreview._saved_tiled
|
||||
self._app._db.set_setting("slideshow_fullscreen", "1" if fs else "0")
|
||||
self._app._db.set_setting("slideshow_tiled", "1" if tiled else "0")
|
||||
if geo:
|
||||
self._app._db.set_setting("slideshow_geometry", f"{geo.x()},{geo.y()},{geo.width()},{geo.height()}")
|
||||
self._app._preview.show()
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user