gui: robust window activation + headless --selftest/--version flags
Center the main window on the active screen and raise()/activateWindow() it on launch, so it cannot open off-screen or behind the focused frame on a tiling compositor (Sway/i3/Hyprland) — the usual cause of reports that 'the GUI won't start / is stuck': it launched, but was not visible. Add lightweight non-GUI flags handled before the QApplication is built: --version print GUI + pinned-CLI version and Qt binding --help usage --selftest build the full UI, spin the event loop once, exit 0 so a successful launch can be verified with no display (headless/CI/remote). Also emit a one-line 'window open' notice to stderr so a terminal launch is not mistaken for a hung shell.
This commit is contained in:
parent
5cb04bf837
commit
e15329a7c9
1 changed files with 49 additions and 6 deletions
|
|
@ -23,7 +23,7 @@ try:
|
|||
QTextEdit, QProgressBar, QTabWidget, QFrame, QCheckBox,
|
||||
QSpinBox, QMessageBox, QStatusBar, QScrollArea
|
||||
)
|
||||
from PySide6.QtCore import Qt, Signal, QObject, QThread
|
||||
from PySide6.QtCore import Qt, Signal, QObject, QThread, QTimer
|
||||
from PySide6.QtGui import QPalette, QColor, QIcon, QPixmap
|
||||
QT_BINDING = "PySide6"
|
||||
except ImportError:
|
||||
|
|
@ -34,7 +34,7 @@ except ImportError:
|
|||
QTextEdit, QProgressBar, QTabWidget, QFrame, QCheckBox,
|
||||
QSpinBox, QMessageBox, QStatusBar, QScrollArea
|
||||
)
|
||||
from PyQt6.QtCore import Qt, pyqtSignal as Signal, QObject, QThread
|
||||
from PyQt6.QtCore import Qt, pyqtSignal as Signal, QObject, QThread, QTimer
|
||||
from PyQt6.QtGui import QPalette, QColor, QIcon, QPixmap
|
||||
QT_BINDING = "PyQt6"
|
||||
except ImportError:
|
||||
|
|
@ -858,9 +858,26 @@ class ZuptWindow(QMainWindow):
|
|||
|
||||
|
||||
def main():
|
||||
compress_files = extract_file = None
|
||||
args = sys.argv[1:]
|
||||
if args:
|
||||
|
||||
# Lightweight non-GUI flags first, so `vaptvupt-gui --version|--help|--selftest`
|
||||
# work with no display and aren't mistaken for files to compress. `--selftest`
|
||||
# is a headless-friendly smoke test: it builds the whole UI and spins the event
|
||||
# loop once, then exits 0 — the reliable way to confirm the GUI stack launches
|
||||
# on a machine where the window itself is hard to see (tiling WM, remote, CI).
|
||||
if args and args[0] in ("--version", "-V", "version"):
|
||||
print(f"vaptvupt-gui {ZUPT_VER_NUMBER} ({QT_BINDING}) | CLI: {VAPTVUPT}")
|
||||
return 0
|
||||
if args and args[0] in ("--help", "-h", "help"):
|
||||
print("usage: vaptvupt-gui [ARCHIVE.zupt | --extract ARCHIVE.zupt |\n"
|
||||
" --compress FILE [FILE ...]]\n"
|
||||
" vaptvupt-gui --selftest # verify the GUI launches (no window kept)\n"
|
||||
" vaptvupt-gui --version")
|
||||
return 0
|
||||
|
||||
compress_files = extract_file = None
|
||||
selftest = ("--selftest" in args[:1])
|
||||
if args and not selftest:
|
||||
if args[0] == "--compress" and len(args) > 1: compress_files = args[1:]
|
||||
elif args[0] == "--extract" and len(args) > 1: extract_file = args[1]
|
||||
elif args[0].endswith(".zupt"): extract_file = args[0]
|
||||
|
|
@ -882,8 +899,34 @@ def main():
|
|||
pal.setColor(role, QColor(c))
|
||||
app.setPalette(pal)
|
||||
win = ZuptWindow(compress_files=compress_files, extract_file=extract_file)
|
||||
|
||||
if selftest:
|
||||
win.show()
|
||||
sys.exit(app.exec())
|
||||
QTimer.singleShot(400, app.quit)
|
||||
rc = app.exec()
|
||||
print(f"selftest OK — {QT_BINDING}: window + {win.tabs.count()} tabs built, "
|
||||
f"event loop ran (rc={rc}); CLI={VAPTVUPT}")
|
||||
return rc
|
||||
|
||||
# Center on the active screen and force focus. Without this the window can
|
||||
# open off-screen or behind the last-focused frame on a tiling compositor
|
||||
# (Sway/i3/Hyprland) — the usual cause of "the GUI won't start / is stuck":
|
||||
# it launched, but you can't see it.
|
||||
scr = app.primaryScreen()
|
||||
if scr is not None:
|
||||
fg = win.frameGeometry()
|
||||
fg.moveCenter(scr.availableGeometry().center())
|
||||
win.move(fg.topLeft())
|
||||
win.show()
|
||||
win.raise_()
|
||||
win.activateWindow()
|
||||
|
||||
# A GUI blocks the launching shell, so a working launch otherwise looks like
|
||||
# a "stuck" terminal. Emit one line to stderr so it's unambiguous.
|
||||
sys.stderr.write(f"VaptVupt {ZUPT_VER_NUMBER} GUI started — window open "
|
||||
f"(close it to exit).\n")
|
||||
sys.stderr.flush()
|
||||
return app.exec()
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
sys.exit(main())
|
||||
|
|
|
|||
Loading…
Reference in a new issue