GUI: busy-state UX, role login defaults, control panel fixes #140

Merged
duan_j merged 27 commits from fix/graphics-and-recovery into main 2026-08-17 13:42:00 +02:00
27 Commits
Author SHA1 Message Date
duan_jandClaude Fable 5 190e728734 fix: install gate event filters after eventFilter's targets exist
CI / lint (pull_request) Successful in 1m13s
CI / test (3.12) (pull_request) Successful in 1m30s
CI / test (3.11) (pull_request) Successful in 1m38s
CI / test (3.13) (pull_request) Successful in 1m40s
CI / test-with-beamline-plugins (pxi_bec) (pull_request) Successful in 1m38s
CI / test-with-beamline-plugins (pxii_bec) (pull_request) Successful in 1m41s
CI / test-with-beamline-plugins (pxiii_bec) (pull_request) Successful in 1m51s
CI / test-with-coverage (pull_request) Successful in 2m6s
CI / coverage-analysis (pull_request) Successful in 3s
CI / lint (push) Successful in 31s
Docs build and publish / docker (push) Successful in 15s
CI / test (3.11) (push) Canceled after 37s
CI / test (3.12) (push) Canceled after 33s
CI / test (3.13) (push) Canceled after 32s
CI / test-with-beamline-plugins (pxi_bec) (push) Canceled after 28s
CI / test-with-beamline-plugins (pxii_bec) (push) Canceled after 27s
CI / test-with-beamline-plugins (pxiii_bec) (push) Canceled after 23s
CI / test-with-coverage (push) Canceled after 22s
CI / coverage-analysis (push) Canceled after 0s
Build and Publish / release (push) Successful in 21s
The locked-banner and Beamline-tab-bar filters were installed mid
__init__, but MainWindow.eventFilter reads sample_lists_tabs, which is
created later - every event delivered in between raised AttributeError
inside the filter ('Error calling Python override of eventFilter()'
spam) and broke widget teardown, cascading errors across CI tests and
wedging the pxiii_bec job. Filters now install late, next to
installEventFilter(self), and the filter guards its attribute reads so
construction/teardown-time events can never raise.

Also fold the staff-gate assertions into test_main_window_init: every
extra MainWindow construction raises the odds of the pre-existing
PySide SystemError flake, so don't build a window just for them.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-14 10:54:20 +02:00
duan_jandClaude Fable 5 727f19d52a ci: run pytest with -s -vv in the test jobs
Per-test lines and live (uncaptured) output: the pxiii_bec job sat
silent at 81 percent for hours, and file-level dots could not say which
test wedged. With -s -vv a hang names its test and streams the last
log lines before it.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-14 10:54:20 +02:00
duan_jandClaude Fable 5 aa6c226103 test: cover every changed line in the branch diff
CI / lint (push) Skipped
CI / test (3.11) (push) Skipped
CI / test (3.12) (push) Skipped
CI / test (3.13) (push) Skipped
CI / test-with-beamline-plugins (pxi_bec) (push) Skipped
CI / test-with-beamline-plugins (pxii_bec) (push) Skipped
CI / test-with-beamline-plugins (pxiii_bec) (push) Skipped
CI / lint (pull_request) Successful in 1m17s
CI / test (3.11) (pull_request) Successful in 1m44s
CI / test (3.12) (pull_request) Successful in 1m41s
CI / test (3.13) (pull_request) Successful in 2m1s
CI / test-with-beamline-plugins (pxi_bec) (pull_request) Successful in 1m57s
CI / test-with-beamline-plugins (pxii_bec) (pull_request) Successful in 2m0s
CI / test-with-coverage (pull_request) Successful in 2m26s
CI / coverage-analysis (pull_request) Successful in 3s
CI / test-with-beamline-plugins (pxiii_bec) (pull_request) Failing after 18m13s
Diff coverage vs main now 100 percent from the gui suite alone:
non-staff locked banners and both gated-tab popups, remote-close
bookkeeping in update_daq_status, smargon staged moves, camera More
link and Alt-wheel axis fallback, number box relimits, energy row
emit, and the gui.main() banner/graceful-exit path.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-14 09:20:44 +02:00
duan_jandClaude Fable 5 6c720d29d3 fix: explain gated Beamline tab clicks; drop login state POST
Two changes folded together because they touch the same status path:

- Revert the login-default state POST: a state transition can move
  motors, and merely opening the GUI must never move hardware. The GUI
  now adopts whatever state the server reports.
- A click on the pgroup-gated (disabled) Beamline tab used to be eaten
  silently by the tab bar. An event filter now pops the explanation:
  visitor-pgroup wording for staff, the staff-only message for users
  (same pattern as the Auxiliary-puck tab).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-14 09:20:44 +02:00
duan_jandClaude Fable 5 16e112f44a test: lift diff coverage over the 80 percent gate
CI / lint (push) Skipped
CI / test (3.11) (push) Skipped
CI / test (3.12) (push) Skipped
CI / test (3.13) (push) Skipped
CI / test-with-beamline-plugins (pxi_bec) (push) Skipped
CI / test-with-beamline-plugins (pxii_bec) (push) Skipped
CI / test-with-beamline-plugins (pxiii_bec) (push) Skipped
CI / lint (pull_request) Successful in 1m3s
CI / test (3.11) (pull_request) Successful in 1m25s
CI / test (3.12) (pull_request) Successful in 1m25s
CI / test (3.13) (pull_request) Successful in 1m24s
CI / test-with-beamline-plugins (pxi_bec) (pull_request) Successful in 1m32s
CI / test-with-beamline-plugins (pxiii_bec) (pull_request) Successful in 1m37s
CI / test-with-beamline-plugins (pxii_bec) (pull_request) Successful in 1m41s
CI / test-with-coverage (pull_request) Successful in 2m4s
CI / coverage-analysis (pull_request) Successful in 3s
Promote the illumination panel's __main__ self-check to a real pytest
file so CI counts it, add busy-overlay render checks (status text
paints, video view routes through it), and cover the motor group's
incomplete-entry and below-min Enter paths. Local diff coverage from
the gui suite alone: 82 percent.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-14 08:52:01 +02:00
duan_jandClaude Fable 5 5871c959e2 fix: clear basedpyright diff violations
Rename NumberLineEdit.validator to range_validator: the instance attr
shadowed QLineEdit.validator() and broke type checking at call sites.
Annotate the smargon _move_axes dict and cast the stand-in self in the
prediction subscriber test.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-14 08:52:01 +02:00
duan_jandClaude Fable 5 b4896105ab chore: satisfy ruff format and SIM201 lint
CI / lint (push) Skipped
CI / test (3.11) (push) Skipped
CI / test (3.12) (push) Skipped
CI / test (3.13) (push) Skipped
CI / test-with-beamline-plugins (pxi_bec) (push) Skipped
CI / test-with-beamline-plugins (pxii_bec) (push) Skipped
CI / test-with-beamline-plugins (pxiii_bec) (push) Skipped
CI / lint (pull_request) Failing after 1m3s
CI / test (3.11) (pull_request) Successful in 1m29s
CI / test (3.12) (pull_request) Successful in 1m28s
CI / test (3.13) (pull_request) Successful in 1m27s
CI / test-with-beamline-plugins (pxi_bec) (pull_request) Successful in 1m30s
CI / test-with-beamline-plugins (pxii_bec) (pull_request) Successful in 1m43s
CI / test-with-beamline-plugins (pxiii_bec) (pull_request) Successful in 1m41s
CI / test-with-coverage (pull_request) Successful in 2m6s
CI / coverage-analysis (pull_request) Failing after 3s
ruff format collapsed lines the Beamline setup rename and other edits
left splittable; SIM201 wanted != over 'not ... ==' in the prediction
subscriber's JSON sniff.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-14 07:23:20 +02:00
duan_jandClaude Fable 5 58bde9379b feat: switch to Beamline combined view while busy
CI / lint (push) Skipped
CI / test (3.11) (push) Skipped
CI / test (3.12) (push) Skipped
CI / test (3.13) (push) Skipped
CI / test-with-beamline-plugins (pxi_bec) (push) Skipped
CI / test-with-beamline-plugins (pxii_bec) (push) Skipped
CI / test-with-beamline-plugins (pxiii_bec) (push) Skipped
CI / test (3.11) (pull_request) Successful in 1m27s
CI / test (3.12) (pull_request) Successful in 1m27s
CI / lint (pull_request) Failing after 1m31s
CI / test (3.13) (pull_request) Successful in 1m27s
CI / test-with-beamline-plugins (pxi_bec) (pull_request) Successful in 2m1s
CI / test-with-coverage (pull_request) Successful in 2m12s
CI / coverage-analysis (pull_request) Failing after 3s
CI / test-with-beamline-plugins (pxii_bec) (pull_request) Successful in 2m48s
CI / test-with-beamline-plugins (pxiii_bec) (pull_request) Successful in 2m44s
Generalize the robot-mount auto-switch: any busy period now brings up
the combined view so the motion can be watched, and the sample camera
returns when busy clears. Edge-triggered, so manual tab choices
survive between transitions; _mounting renamed to _watching_motion.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-13 15:42:00 +02:00
duan_jandClaude Fable 5 d659f05009 fix: grey out whole state strip while beamline is busy
Busy now empties the available-target set exactly like Moving, so no
entry looks clickable and no transition can be posted mid-operation
(same guard the status-bar menu already had). The current/pending
entry keeps its highlight as orientation.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-13 15:42:00 +02:00
duan_jandClaude Fable 5 69d552c068 fix: busy flag in Axis views as plain status text, not a badge
CI / lint (push) Skipped
CI / test (3.11) (push) Skipped
CI / test (3.12) (push) Skipped
CI / test (3.13) (push) Skipped
CI / test-with-beamline-plugins (pxi_bec) (push) Skipped
CI / test-with-beamline-plugins (pxii_bec) (push) Skipped
CI / test-with-beamline-plugins (pxiii_bec) (push) Skipped
Gonio camera, Beamline view and the combined view showed BEAMLINE BUSY
in the rounded badge pill, which reads as a clickable button. These
views are passive, so draw the same shadowed colored text the sample
camera uses for its warnings; the pill stays only on the sample-camera
session badges, which really are click targets.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-13 15:15:23 +02:00
duan_jandClaude Fable 5 75d7bed380 chore: rename Beamline Setup to Beamline setup, comment tweaks
CI / lint (push) Skipped
CI / test (3.11) (push) Skipped
CI / test (3.12) (push) Skipped
CI / test (3.13) (push) Skipped
CI / test-with-beamline-plugins (pxi_bec) (push) Skipped
CI / test-with-beamline-plugins (pxii_bec) (push) Skipped
CI / test-with-beamline-plugins (pxiii_bec) (push) Skipped
Panel title case now matches the other banner names. Also clarify the
splash banner comment in gui.py.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-13 15:05:42 +02:00
duan_jandClaude Fable 5 1bce76e6fc feat: show locked beamline banners to non-staff
Beamline setup, ABR meas. pos. and Beam configuration banners stay
visible for non-staff instead of vanishing, but are locked stand-ins:
clicking one pops the staff-only notice (same pattern as the
Auxiliary-puck tab) telling the user to log in as staff or contact
their local contact.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-13 15:05:42 +02:00
duan_jandClaude Fable 5 656b441593 feat: default beamline state on login by role
Staff land in BeamLocation, users in SampleAlignment. One-shot on the
first status tick where the GUI owns the session and the beamline is
idle, so a running operation or a watch-only GUI is never disturbed.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-13 15:05:42 +02:00
duan_jandClaude Fable 5 c5a6a175bd feat: disable Beamline tab when active pgroup is outside token pgroups
CI / lint (push) Skipped
CI / test (3.11) (push) Skipped
CI / test (3.12) (push) Skipped
CI / test (3.13) (push) Skipped
CI / test-with-beamline-plugins (pxi_bec) (push) Skipped
CI / test-with-beamline-plugins (pxii_bec) (push) Skipped
CI / test-with-beamline-plugins (pxiii_bec) (push) Skipped
Switching to a visitor pgroup means running a user experiment: grey out
the Beamline tab (tooltip: beamline scientists only), bring the
Experiment tab forward with Dataset path and Exp. Config. opened.
Gate applies on transitions only so manual tab choices survive the
1 Hz status ticks.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-13 14:35:20 +02:00
duan_jandClaude Fable 5 869a66ff4b fix: send light slider changes from every input path, guard readback
CI / lint (push) Skipped
CI / test (3.11) (push) Skipped
CI / test (3.12) (push) Skipped
CI / test (3.13) (push) Skipped
CI / test-with-beamline-plugins (pxi_bec) (push) Skipped
CI / test-with-beamline-plugins (pxii_bec) (push) Skipped
CI / test-with-beamline-plugins (pxiii_bec) (push) Skipped
Sliders only emitted on sliderReleased, so right-click+wheel, arrow keys
and groove clicks changed the value locally without a PUT and the 500 ms
status poll snapped it back. setTracking(False) + valueChanged now sends
one PUT per deliberate change; readback setValue is wrapped in
blockSignals to avoid echoing PUTs, and a 1.5 s grace window stops
in-flight stale status responses from bouncing the slider.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-13 13:42:07 +02:00
duan_j d94fb88148 chore: using aare_banner.png since svg could be rendered wrong at rhel9 consoles 2026-08-13 13:41:36 +02:00
duan_jandClaude Fable 5 bb447b1567 feat: rename Monochromator panel to Beamline Setup, add WIP beam-to-box row
CI / lint (push) Skipped
CI / test (3.11) (push) Skipped
CI / test (3.12) (push) Skipped
CI / test (3.13) (push) Skipped
CI / test-with-beamline-plugins (pxi_bec) (push) Skipped
CI / test-with-beamline-plugins (pxii_bec) (push) Skipped
CI / test-with-beamline-plugins (pxiii_bec) (push) Skipped
Display title only; class and file keep their names. New full-width
'Move Beam to Box (center) (WIP)' button under the Energy row, disabled
with a coming-soon tooltip until a DAQ endpoint exists.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-13 11:46:45 +02:00
duan_jandClaude Fable 5 c618354c01 feat: add Change Energy row to experiment configuration
Copy of the Beamline Setup energy row (keV display, eV emit), placed
below the ML Loop Centring / Make Raster Grid row and always visible.
Wired to the same daq.change_energy; not staff-gated, server enforces
write permission.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-13 11:46:44 +02:00
duan_j 252e08384d chore: Use rock and goto for better understanding 2026-08-13 11:27:18 +02:00
duan_jandClaude Fable 5 70107e6219 fix: unsqueeze Chi/Phi row and widen Step box in smargon panel
CI / lint (push) Skipped
CI / test (3.11) (push) Skipped
CI / test (3.12) (push) Skipped
CI / test (3.13) (push) Skipped
CI / test-with-beamline-plugins (pxi_bec) (push) Skipped
CI / test-with-beamline-plugins (pxii_bec) (push) Skipped
CI / test-with-beamline-plugins (pxiii_bec) (push) Skipped
Move button gets its own full-width row instead of sharing row 1 with the
Chi/Phi entries; Step box spans columns 1-4 instead of the narrow Chi
column.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-13 11:23:39 +02:00
duan_jandClaude Fable 5 c837e6c44d fix: reserve sign width for GM labels; annotate red-highlight mismatch
CI / lint (push) Skipped
CI / test (3.11) (push) Skipped
CI / test (3.12) (push) Skipped
CI / test (3.13) (push) Skipped
CI / test-with-beamline-plugins (pxi_bec) (push) Skipped
CI / test-with-beamline-plugins (pxii_bec) (push) Skipped
CI / test-with-beamline-plugins (pxiii_bec) (push) Skipped
Value column was content-sized, so rows shifted whenever a value flipped
negative. Labels now reserve '-88.888' width; right alignment keeps digits
anchored. Also TODO: red colors on live aerotech while labels display
aerotech_meas - intent unconfirmed, do not change condition until decided.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-13 11:00:20 +02:00
duan_jandClaude Fable 5 ebe0860ed4 feat: add More link in sample camera help overlay opening F1 dialog
Underlined 'More… (F1)' line at the bottom of the painted help box emits
open_full_help, wired to the existing Mouse / Keyboard Controls dialog.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-13 11:00:20 +02:00
duan_jandClaude Fable 5 e18c7feded feat: stage motor entry values, apply moves in one click
CI / lint (push) Skipped
CI / test (3.11) (push) Skipped
CI / test (3.12) (push) Skipped
CI / test (3.13) (push) Skipped
CI / test-with-beamline-plugins (pxi_bec) (push) Skipped
CI / test-with-beamline-plugins (pxii_bec) (push) Skipped
CI / test-with-beamline-plugins (pxiii_bec) (push) Skipped
Chi/Phi boxes in the Smargon tab no longer move on Enter: edits stage
the target (orange), the Move button sends all staged axes at once
(green), and boxes return to neutral when the motor reports arrival.
Out-of-range entries stay red and are never sent; limit tips pop as
tooltips. MotorMoveGroup is opt-in per box so other panels can adopt
the same logic later.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-13 10:56:32 +02:00
duan_j b8177bd764 chore: specify the omega panel 0 degree is a go-to not a move-by 2026-08-13 10:47:02 +02:00
duan_jandClaude Fable 5 ac5936f7be fix: exposure wheel only increased when Alt held
CI / lint (push) Skipped
CI / test (3.11) (push) Skipped
CI / test (3.12) (push) Skipped
CI / test (3.13) (push) Skipped
CI / test-with-beamline-plugins (pxi_bec) (push) Skipped
CI / test-with-beamline-plugins (pxii_bec) (push) Skipped
CI / test-with-beamline-plugins (pxiii_bec) (push) Skipped
Qt xcb/windows swap wheel axes while Alt is held, so angleDelta().y() is 0
and copysign(_, 0) is always positive. Fall back to angleDelta().x() and
ignore genuine zero deltas.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-13 10:39:36 +02:00
duan_jandClaude Fable 5 69178945e5 fix: prevent libzmq abort and per-frame decode errors in prediction subscriber
CI / lint (push) Skipped
CI / test (3.11) (push) Skipped
CI / test (3.12) (push) Skipped
CI / test (3.13) (push) Skipped
CI / test-with-beamline-plugins (pxi_bec) (push) Skipped
CI / test-with-beamline-plugins (pxii_bec) (push) Skipped
CI / test-with-beamline-plugins (pxiii_bec) (push) Skipped
Sniff for '{' before JSON-parsing zmq parts: JPEG frames start with 0xff
and raised UnicodeDecodeError on every frame. Stop closing the socket
from the GUI thread in stop(): zmq sockets are not thread-safe and the
concurrent close/recv tripped the signaler.cpp POLLIN assertion (core
dump); run() closes it in its own thread via the 500ms RCVTIMEO.

uv.lock: sync version to 0.8.3.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-13 10:31:57 +02:00
duan_j 63f4ad7612 chore: name the bluebird theme in menu the default theme 2026-08-13 10:29:14 +02:00