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
|
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__ = [
|
__all__ = [
|
||||||
"get_window",
|
"get_window",
|
||||||
"get_monitor_available_rect",
|
"get_monitor_available_rect",
|
||||||
"resize",
|
"resize",
|
||||||
"resize_and_move",
|
"resize_and_move",
|
||||||
|
"settiled",
|
||||||
]
|
]
|
||||||
|
|||||||
@ -350,7 +350,16 @@ class FullscreenPreview(QMainWindow):
|
|||||||
# F11 → fullscreen → F11 has a sensible target.
|
# F11 → fullscreen → F11 has a sensible target.
|
||||||
self._windowed_geometry = None
|
self._windowed_geometry = None
|
||||||
# Restore saved state or start fullscreen
|
# 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.setGeometry(FullscreenPreview._saved_geometry)
|
||||||
self._pending_position_restore = (
|
self._pending_position_restore = (
|
||||||
FullscreenPreview._saved_geometry.x(),
|
FullscreenPreview._saved_geometry.x(),
|
||||||
@ -628,6 +637,7 @@ class FullscreenPreview(QMainWindow):
|
|||||||
|
|
||||||
_saved_geometry = None # remembers window size/position across opens
|
_saved_geometry = None # remembers window size/position across opens
|
||||||
_saved_fullscreen = False
|
_saved_fullscreen = False
|
||||||
|
_saved_tiled = False # True if Hyprland had it tiled at last close
|
||||||
_current_tags: dict[str, list[str]] = {}
|
_current_tags: dict[str, list[str]] = {}
|
||||||
_current_tag_list: list[str] = []
|
_current_tag_list: list[str] = []
|
||||||
|
|
||||||
@ -1754,9 +1764,13 @@ class FullscreenPreview(QMainWindow):
|
|||||||
# Geometry is adapter-side concern, not state machine concern,
|
# Geometry is adapter-side concern, not state machine concern,
|
||||||
# so the state machine doesn't see it.
|
# so the state machine doesn't see it.
|
||||||
FullscreenPreview._saved_fullscreen = self.isFullScreen()
|
FullscreenPreview._saved_fullscreen = self.isFullScreen()
|
||||||
|
FullscreenPreview._saved_tiled = False
|
||||||
if not self.isFullScreen():
|
if not self.isFullScreen():
|
||||||
# On Hyprland, Qt doesn't know the real position — ask the WM
|
# On Hyprland, Qt doesn't know the real position — ask the WM
|
||||||
win = hyprland.get_window(self.windowTitle())
|
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"):
|
if win and win.get("at") and win.get("size"):
|
||||||
from PySide6.QtCore import QRect
|
from PySide6.QtCore import QRect
|
||||||
x, y = win["at"]
|
x, y = win["at"]
|
||||||
|
|||||||
@ -76,17 +76,21 @@ class PopoutController:
|
|||||||
from .popout.window import FullscreenPreview
|
from .popout.window import FullscreenPreview
|
||||||
saved_geo = self._app._db.get_setting("slideshow_geometry")
|
saved_geo = self._app._db.get_setting("slideshow_geometry")
|
||||||
saved_fs = self._app._db.get_setting_bool("slideshow_fullscreen")
|
saved_fs = self._app._db.get_setting_bool("slideshow_fullscreen")
|
||||||
|
saved_tiled = self._app._db.get_setting_bool("slideshow_tiled")
|
||||||
if saved_geo:
|
if saved_geo:
|
||||||
parts = saved_geo.split(",")
|
parts = saved_geo.split(",")
|
||||||
if len(parts) == 4:
|
if len(parts) == 4:
|
||||||
from PySide6.QtCore import QRect
|
from PySide6.QtCore import QRect
|
||||||
FullscreenPreview._saved_geometry = QRect(*[int(p) for p in parts])
|
FullscreenPreview._saved_geometry = QRect(*[int(p) for p in parts])
|
||||||
FullscreenPreview._saved_fullscreen = saved_fs
|
FullscreenPreview._saved_fullscreen = saved_fs
|
||||||
|
FullscreenPreview._saved_tiled = saved_tiled
|
||||||
else:
|
else:
|
||||||
FullscreenPreview._saved_geometry = None
|
FullscreenPreview._saved_geometry = None
|
||||||
FullscreenPreview._saved_fullscreen = True
|
FullscreenPreview._saved_fullscreen = True
|
||||||
|
FullscreenPreview._saved_tiled = False
|
||||||
else:
|
else:
|
||||||
FullscreenPreview._saved_fullscreen = True
|
FullscreenPreview._saved_fullscreen = True
|
||||||
|
FullscreenPreview._saved_tiled = saved_tiled
|
||||||
cols = self._app._grid._flow.columns
|
cols = self._app._grid._flow.columns
|
||||||
show_actions = self._app._stack.currentIndex() != 2
|
show_actions = self._app._stack.currentIndex() != 2
|
||||||
monitor = self._app._db.get_setting("slideshow_monitor")
|
monitor = self._app._db.get_setting("slideshow_monitor")
|
||||||
@ -135,7 +139,9 @@ class PopoutController:
|
|||||||
from .popout.window import FullscreenPreview
|
from .popout.window import FullscreenPreview
|
||||||
fs = FullscreenPreview._saved_fullscreen
|
fs = FullscreenPreview._saved_fullscreen
|
||||||
geo = FullscreenPreview._saved_geometry
|
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_fullscreen", "1" if fs else "0")
|
||||||
|
self._app._db.set_setting("slideshow_tiled", "1" if tiled else "0")
|
||||||
if geo:
|
if geo:
|
||||||
self._app._db.set_setting("slideshow_geometry", f"{geo.x()},{geo.y()},{geo.width()},{geo.height()}")
|
self._app._db.set_setting("slideshow_geometry", f"{geo.x()},{geo.y()},{geo.width()},{geo.height()}")
|
||||||
self._app._preview.show()
|
self._app._preview.show()
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user