# CHANGELOG ## v0.12.4 (2026-08-20) ### Bug Fixes - Pitch scan message for correct beamline ([`4f5cb08`](https://gitea.psi.ch/mx/AareDAQ/commit/4f5cb08319dc61b6b28b99c1950b516192da4389)) ## v0.12.3 (2026-08-20) ### Bug Fixes - Do not multiply screening request by steps ([`1756cab`](https://gitea.psi.ch/mx/AareDAQ/commit/1756caba690f637db7bb8787318346fa66aecc30)) - Read beamline state from BEC on server startup ([`dd04a2f`](https://gitea.psi.ch/mx/AareDAQ/commit/dd04a2fc89c81e71c84669312bc48afe76126574)) ## v0.12.2 (2026-08-20) ### Bug Fixes - Save collimator positions ([`002dba7`](https://gitea.psi.ch/mx/AareDAQ/commit/002dba774245ea35b0ec90a8ede3fc91b30bbc4c)) ## v0.12.1 (2026-08-20) ### Bug Fixes - Update bs x and y instead of z ([`a36a051`](https://gitea.psi.ch/mx/AareDAQ/commit/a36a051a2b968a8e5c345319cd909223ab591d7e)) ## v0.12.0 (2026-08-19) ### Features - Connect beam steering routine to GUI ([`de0445e`](https://gitea.psi.ch/mx/AareDAQ/commit/de0445efdd671940d926989892260cb104bb6f71)) ## v0.11.0 (2026-08-18) ### Bug Fixes - No BEAMLINE BUSY overlay during Sample alignment ([`16b61b8`](https://gitea.psi.ch/mx/AareDAQ/commit/16b61b886b2c97664c148f0e52cdbca70856ec80)) Same exception as the motion watch: busy in Sample alignment is the alignment itself, and the sample motion is watched in these very views - the curtain hid exactly what the user needed to see. Gated at both style call sites (sample camera and the Axis views); the session-driven 'In viewing mode' badge is unaffected. Co-Authored-By: Claude Fable 5 ### Chores - Update png so they have gaps ([`0f12b68`](https://gitea.psi.ch/mx/AareDAQ/commit/0f12b688fe79c776b9492d86052f22b611bc43eb)) ### Code Style - Collapse multiline _status calls for ruff format ([`167d78d`](https://gitea.psi.ch/mx/AareDAQ/commit/167d78db68a528af8c275e1923e2ef8cecd0b65d)) Co-Authored-By: Claude Fable 5 ### Features - Status bar splits passive left / operable right ([`7a01a86`](https://gitea.psi.ch/mx/AareDAQ/commit/7a01a866ef5f942b3b5543bcc9c66c9210196dad)) Operable controls (Fast Shutter, State, p-group, Session) group right via addPermanentWidget and share one hover affordance - hand cursor + underline - now owned by ClickableLabel; ValueLabel opts out for the passive readouts, and the unwired busy label becomes a plain QLabel. Cryo sits first in the operable group but stays passive: a cryo operation is planned (TODO in status_bar.py), the placement just reserves its spot. Co-Authored-By: Claude Fable 5 ## v0.10.0 (2026-08-17) ### Bug Fixes - Measured threshold is rotation count >= 1 ([`2909182`](https://gitea.psi.ch/mx/AareDAQ/commit/2909182bb104d96a5b2d44ae8bb33a5056a69d67)) Confirmed by Dawn: any rotation data counts as measured; unmeasured is exactly rotation count 0. The old > 1 rule left single-rotation samples looking like still-to-do work in the Unmeasured view. Co-Authored-By: Claude Fable 5 - No auto-switch to beamline view during Sample alignment ([`cb5837d`](https://gitea.psi.ch/mx/AareDAQ/commit/cb5837d90f03c02c56fd017f9eb714a2164e1753)) Busy in Sample alignment IS the alignment (centring moves) - yanking the view away to the combined beamline tab hid exactly what the user was doing. The motion-watch switch now skips that state; robot exchange and other busy transitions still switch as before. Co-Authored-By: Claude Fable 5 - Order sample count columns by workflow, unwire crossed columns ([`f303f29`](https://gitea.psi.ch/mx/AareDAQ/commit/f303f29214c780b9c97e360b598d6a849e2f7a14)) Both bottom-dock tables now list mount -> raster -> screening -> rotation, the order the work actually happens in. In the Auxiliary table the swap also fixes a real bug: data() feeds get_entry header-index-minus-1, but rotation/raster were crossed against the header, so 'Raster count' displayed rotation counts and vice versa. Co-Authored-By: Claude Fable 5 - Pyright-style ignore for setGraphicsEffect(None) ([`03ae77f`](https://gitea.psi.ch/mx/AareDAQ/commit/03ae77fa749a216412dc23045f2660e840ae1b98)) basedpyright disables mypy-style 'type: ignore' comments by default, so the diff-quality gate still counted the violation; match the existing 'pyright: ignore[reportArgumentType]' convention from main_window. Co-Authored-By: Claude Fable 5 ### Chores - Clarify move to mounting position in smargon movement ([`adcc63d`](https://gitea.psi.ch/mx/AareDAQ/commit/adcc63d45cfaf95357b86fd311d8b5c8a5d06b22)) ### Code Style - Expanded help overlay opens top center, under the badge ([`3053aaa`](https://gitea.psi.ch/mx/AareDAQ/commit/3053aaae9386bc108b429b036dab0b359a9446f1)) The '?' badge moved to the top middle but the cheat sheet still opened bottom-left, sending the mouse across the view to close it. The overlay now drops in where the badge was. Co-Authored-By: Claude Fable 5 - Help badge at center top, More link right-aligned ([`a0baa2b`](https://gitea.psi.ch/mx/AareDAQ/commit/a0baa2b54dde762af27be62c7c15658728e797b6)) The '?' badge sat in a corner, which drifts oddly when the view is scaled to fit; the top middle stays put and out of the sample's way. Transparency unchanged - visible enough to find, not disturbing. 'More... (F1)' moves to the overlay's right edge, reading like a dialog's action button. Co-Authored-By: Claude Fable 5 - Move Unmeasured next to All, 1px gap between filter chips ([`378c257`](https://gitea.psi.ch/mx/AareDAQ/commit/378c25799f9da4e393619439776d2e5af69d389e)) Unmeasured and All are both 'what is left' views; the hand-applied labels (Queued/Flagged/Measured) follow. The 1px spacing keeps the chips readable as separate buttons instead of one solid bar. Co-Authored-By: Claude Fable 5 - Wrap shutter flag f-strings for ruff format ([`32a835b`](https://gitea.psi.ch/mx/AareDAQ/commit/32a835b6616425fca6b2a9444705212cc98a5b1c)) Co-Authored-By: Claude Fable 5 ### Features - Add Unflag to the sample table context menu ([`900bc2f`](https://gitea.psi.ch/mx/AareDAQ/commit/900bc2f6f7f9c58a8c45d123f5c9bfb70319cb5e)) Below Mount/Unmount, acting on the selection like the queue actions. Flagging happens by dropping rows on the Flagged chip; until now there was no way back. Disabled when nothing in the selection is flagged. Co-Authored-By: Claude Fable 5 - Add Unmeasured filter chip to the sample table ([`4175cb8`](https://gitea.psi.ch/mx/AareDAQ/commit/4175cb8edfa6b732260d9a4f2c3f339216e9ba04)) Complement of Measured (rotation count <= 1): one click shows everything still to be done, so it can be selected wholesale and queued. Plain chip like All - unmeasured rows carry no tint, so there is no legend color to wear; cross-status marks (queued/ flagged) show like in the Measured view. Co-Authored-By: Claude Fable 5 - Breathe the pending transition target in the state strip ([`fbd40ee`](https://gitea.psi.ch/mx/AareDAQ/commit/fbd40eee90b96e517252a757c3e00e9af4902977)) While Moving, the target state sat solid blue and read as already reached. An opacity pulse (QGraphicsOpacityEffect + QPropertyAnimation) marks it as in progress; a stylesheet animation would repolish the button every frame, which the guarded updates in _apply_highlight exist to avoid. Co-Authored-By: Claude Fable 5 - Clicking the '#' header selects all rows ([`4a728ba`](https://gitea.psi.ch/mx/AareDAQ/commit/4a728baf79a9fa677e83ccb895a1689901b6ce23)) The status column holds no sortable data, so its header click slot was free: it now does Ctrl+A, pairing with the Unmeasured chip to grab everything still to be done in one motion. The sort indicator is put back afterwards - the click drags it onto '#' even though the model ignores sorting there. Co-Authored-By: Claude Fable 5 - Current energy readout in Exp. Config energy row ([`1fef282`](https://gitea.psi.ch/mx/AareDAQ/commit/1fef28231b707118f645e02f04ad3cf81e953349)) Mirrors the Beamline setup live readout above Set Energy, fed by the same DAQ tick with the zero-energy guard and repaint skip. Co-Authored-By: Claude Fable 5 - Fast shutter open/close row in Beamline setup ([`8f91f1e`](https://gitea.psi.ch/mx/AareDAQ/commit/8f91f1ed2ed1cbca04dcd00f761292b0108b19a7)) Status flag on the left (same rich-text scheme as the status bar, theme-aware via set_theme), Open/Close buttons on the right, wired to the same daq.open_shutter/close_shutter slots staff-gated in main_window. Co-Authored-By: Claude Fable 5 - Live energy/wavelength readout in Beamline setup ([`2a82c59`](https://gitea.psi.ch/mx/AareDAQ/commit/2a82c598c0010a8d766cb781f31f0a4d85f09b2e)) New 'Current energy / lambda' row above the setpoint, fed per DAQ tick from diffraction.energy_keV; the setpoint row is renamed 'Set Energy (keV)' so 'what is' and 'what to set' are distinct. Guards energy 0.0 (server's detector-unavailable fallback) because the wavelength property divides by it. The copied energy row in the experiment configuration is renamed to match. Co-Authored-By: Claude Fable 5 - Put the ExpHutch shutter left of the fast shutter ([`977483e`](https://gitea.psi.ch/mx/AareDAQ/commit/977483ef2843d56abe921fb8c6d999a130423c2e)) Beam-path order in the status bar: the hutch shutter sits upstream of the fast shutter, so it reads left to right along the beam. Co-Authored-By: Claude Fable 5 - Queue controls live only in the Queued view ([`6ace1fc`](https://gitea.psi.ch/mx/AareDAQ/commit/6ace1fcbcfd8815f75c3d4498427050b35edc659)) Run/Remove selected/Clear list act on the queue, whose order only the Queued chip view shows - in other views they are greyed out with a tooltip pointing at the chip. Run stays enabled while automation runs so pausing is always possible. Applies to the docked trio and the pop-out clones alike. Co-Authored-By: Claude Fable 5 - Queued chip view shows the actual run order ([`344888d`](https://gitea.psi.ch/mx/AareDAQ/commit/344888dac072090fcf33a751dfb330bd2094bee1)) The queue engine keeps insertion order and Run pops its head, but the Queued view sorted by the dewar table's header sort - the top row was not what runs next. set_queued_ids now keeps the order it is fed (the queue model's order) and the Queued view displays exactly that; header clicks no longer reorder it. Co-Authored-By: Claude Fable 5 - Sample camera starts in scale-to-fit ([`b58c23d`](https://gitea.psi.ch/mx/AareDAQ/commit/b58c23d0f65207a6ed15489fbcdeaa04acc2265a)) _autoscale now defaults on, so the view fits from the first layout (the constructor's placeholder already carries the camera size and resizeEvent refits on every resize). update_pixmap additionally refits when the frame size changes - the real stream resolution can differ from the placeholder, and only a view resize refit before. Right-click 'Scale to fit' still toggles back to 1:1. Co-Authored-By: Claude Fable 5 - Wave-animate the busy overlay titles ([`80063a5`](https://gitea.psi.ch/mx/AareDAQ/commit/80063a5df1c7c8b3c0c04aed6dfb5f160e477d47)) BEAMLINE BUSY and the robot warnings now hop per letter (clipped sine) so they read as an in-progress signal, not a frozen label. Gated by a new BusyOverlayStyle.animate flag: 'In viewing mode' stays static because it is a passive notice. No timer - the phase rides the wall clock and repaints ride the ~20 fps camera frames, so the wave freezes with a stalled feed (which has its own error surface). Co-Authored-By: Claude Fable 5 ### Refactoring - Replace Qt overrides with native mechanisms, install app filters once ([`c24da77`](https://gitea.psi.ch/mx/AareDAQ/commit/c24da7739b2f845094b875ad2943f0d736b66b3f)) Per-window installs of the two QApplication-level filters (cursor, wheel guard) stacked one stale copy per MainWindow; now installed once per process, parented to the app. closeEvent overrides in the baton dialogs replaced by finished.connect(timer.stop); keyPressEvent in VideoGraphicsView replaced by WidgetShortcut QShortcuts; hover enter/leave overrides in PlayPauseButton replaced by underMouse(); ValueLabel inherits ClickableLabel instead of duplicating its mousePressEvent. Dead raster-timer branch and a PyQt5-era event-position fallback deleted; redundant try/except and getattr guards dropped now that class-level defaults cover pre-init reads. Co-Authored-By: Claude Fable 5 ### Testing - Pin the Sample-alignment motion-watch exception ([`e9428ca`](https://gitea.psi.ch/mx/AareDAQ/commit/e9428ca64dece6f9a9c2be6fc5867c635b08449c)) Robot motion switches to the combined view; alignment beginning switches straight back while busy is still set, and staying busy in alignment never re-triggers. Piggybacks on the init test's window - extra MainWindow constructions feed the PySide teardown flake. Co-Authored-By: Claude Fable 5 ## v0.9.0 (2026-08-17) ### Bug Fixes - Busy flag in Axis views as plain status text, not a badge ([`69d552c`](https://gitea.psi.ch/mx/AareDAQ/commit/69d552c0683a1c7b7768c9491b78130cf52a1330)) 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 - Clear basedpyright diff violations ([`5871c95`](https://gitea.psi.ch/mx/AareDAQ/commit/5871c959e22f9399430195ba2a1d41b9dc16c662)) 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 - Explain gated Beamline tab clicks; drop login state POST ([`6c720d2`](https://gitea.psi.ch/mx/AareDAQ/commit/6c720d29d328563ca186be6af71e17c458ce824e)) 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 - Exposure wheel only increased when Alt held ([`ac5936f`](https://gitea.psi.ch/mx/AareDAQ/commit/ac5936f7be272e956a937ecf164b3ce28bb53680)) 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 - Grey out whole state strip while beamline is busy ([`d659f05`](https://gitea.psi.ch/mx/AareDAQ/commit/d659f0500934e462ea195d09d7234fe1213a659a)) 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 - Install gate event filters after eventFilter's targets exist ([`190e728`](https://gitea.psi.ch/mx/AareDAQ/commit/190e728734559a22fe1155cf3932c9c7ed0cb528)) 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 - Prevent libzmq abort and per-frame decode errors in prediction subscriber ([`6917894`](https://gitea.psi.ch/mx/AareDAQ/commit/69178945e5b64e73413169056673714a3db2d8cf)) 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 - Reserve sign width for GM labels; annotate red-highlight mismatch ([`c837e6c`](https://gitea.psi.ch/mx/AareDAQ/commit/c837e6c44d26f96477a72753b7123805878803c7)) 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 - Send light slider changes from every input path, guard readback ([`869a66f`](https://gitea.psi.ch/mx/AareDAQ/commit/869a66ff4b7c51133609ff7f4d5eb8d70fdbf85a)) 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 - Unsqueeze Chi/Phi row and widen Step box in smargon panel ([`70107e6`](https://gitea.psi.ch/mx/AareDAQ/commit/70107e6219aa25ce6736fb7af04894ecc355fe10)) 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 ### Chores - Name the bluebird theme in menu the default theme ([`63f4ad7`](https://gitea.psi.ch/mx/AareDAQ/commit/63f4ad7612e87554aa3bdb92edbedeeeee81a7d2)) - Rename Beamline Setup to Beamline setup, comment tweaks ([`75d7bed`](https://gitea.psi.ch/mx/AareDAQ/commit/75d7bed380b8ababd876b86335079648ca05b51e)) Panel title case now matches the other banner names. Also clarify the splash banner comment in gui.py. Co-Authored-By: Claude Fable 5 - Satisfy ruff format and SIM201 lint ([`b489610`](https://gitea.psi.ch/mx/AareDAQ/commit/b4896105ab529e62374f6f11b0424a8cc54c7d30)) 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 - Specify the omega panel 0 degree is a go-to not a move-by ([`b8177bd`](https://gitea.psi.ch/mx/AareDAQ/commit/b8177bd764b584a09ab925dedeff811b69ec4d66)) - Use rock and goto for better understanding ([`252e083`](https://gitea.psi.ch/mx/AareDAQ/commit/252e08384dd69955f0e53151445e24a62e19a4ce)) - Using aare_banner.png since svg could be rendered wrong at rhel9 consoles ([`d94fb88`](https://gitea.psi.ch/mx/AareDAQ/commit/d94fb88148ad317f8cf7e44ca35ccc0c9eb6d184)) ### Continuous Integration - Run pytest with -s -vv in the test jobs ([`727f19d`](https://gitea.psi.ch/mx/AareDAQ/commit/727f19d52a3810a9ad7cf15cd07305b224359dae)) 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 ### Features - Add Change Energy row to experiment configuration ([`c618354`](https://gitea.psi.ch/mx/AareDAQ/commit/c618354c0146e6a071873507aad4d085c71e344f)) Copy of the Beamline Setup energy row (keV display, eV emit), placed below the Auto Centering / Draw a 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 - Add More link in sample camera help overlay opening F1 dialog ([`ebe0860`](https://gitea.psi.ch/mx/AareDAQ/commit/ebe0860ed4446d76005b00493ebf2c05aec5d93e)) 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 - Default beamline state on login by role ([`656b441`](https://gitea.psi.ch/mx/AareDAQ/commit/656b44159322c857ef6f6a2a0623a5e0cbf8792b)) 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 - Disable Beamline tab when active pgroup is outside token pgroups ([`c5a6a17`](https://gitea.psi.ch/mx/AareDAQ/commit/c5a6a175bddda9acb517acea74ecf93776cae3cb)) 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 - Rename Monochromator panel to Beamline Setup, add WIP beam-to-box row ([`bb447b1`](https://gitea.psi.ch/mx/AareDAQ/commit/bb447b15670addb7fb339db41690abbe21b7533a)) 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 - Show locked beamline banners to non-staff ([`1bce76e`](https://gitea.psi.ch/mx/AareDAQ/commit/1bce76e6fcd0c430cee449e82679cc36c946b414)) 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 - Stage motor entry values, apply moves in one click ([`e18c7fe`](https://gitea.psi.ch/mx/AareDAQ/commit/e18c7feded837db8d26d20ee021b58057137cc5d)) 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 - Switch to Beamline combined view while busy ([`58bde93`](https://gitea.psi.ch/mx/AareDAQ/commit/58bde9379bd09b6c22bf0409b829894b753e59c9)) 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 ### Testing - Cover every changed line in the branch diff ([`aa6c226`](https://gitea.psi.ch/mx/AareDAQ/commit/aa6c226103401234b371f26727c5b544aa686329)) 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 - Lift diff coverage over the 80 percent gate ([`16e112f`](https://gitea.psi.ch/mx/AareDAQ/commit/16e112f44a4eac6024e94d359c17a9704e78a2a8)) 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 ## v0.8.3 (2026-08-12) ### Bug Fixes - Rename free beamline to clear busy ([`362880e`](https://gitea.psi.ch/mx/AareDAQ/commit/362880ec820953e95c14bfd3a1c3fa3351030643)) - Rename recover beamline to force maintenance ([`63ea060`](https://gitea.psi.ch/mx/AareDAQ/commit/63ea060fb9dc4df994cc266b7084e4ba7c4c48db)) - Show viewing mode for all states ([`8e68972`](https://gitea.psi.ch/mx/AareDAQ/commit/8e6897262537e221d42d7b44e418322d2cb15d54)) ### Refactoring - Remove dead code ([`1b3b144`](https://gitea.psi.ch/mx/AareDAQ/commit/1b3b144265b825ffbe27fca63f1593b198f73861)) ## v0.8.2 (2026-08-12) ### Bug Fixes - Allow str has no get when in recovery ([`34c8182`](https://gitea.psi.ch/mx/AareDAQ/commit/34c8182cfa54da98baeed0376d9c5d32b13efc6c)) - Include graphics to wheel ([`ca05748`](https://gitea.psi.ch/mx/AareDAQ/commit/ca05748d1fdf092d962f074f570e583b3490ac54)) ### Chores - Add test to improve coverage ([`9906937`](https://gitea.psi.ch/mx/AareDAQ/commit/9906937525f73a91b658fdcb50ea7093cc76a759)) - Fix linting ([`bb35209`](https://gitea.psi.ch/mx/AareDAQ/commit/bb35209be8737f2db107f092a6cac6bfe2b0e026)) - Formatting, tab space misused ([`17bb654`](https://gitea.psi.ch/mx/AareDAQ/commit/17bb65420f85319e793873481e0f6536f26a4d66)) - Hide debug log in the log_panel ([`328a46b`](https://gitea.psi.ch/mx/AareDAQ/commit/328a46b09c4b08f3704cd9c577c687ed043b166d)) - Make default theme bluebird (solid) ([`8a9f35e`](https://gitea.psi.ch/mx/AareDAQ/commit/8a9f35ef7409465a139a33b603ab332ad151061e)) - Removing trailing space ([`23ad114`](https://gitea.psi.ch/mx/AareDAQ/commit/23ad11430bf639bc2263b25fe8bd6f8a107b4cac)) - Stop logger info display lots of pgroups ([`0ca9682`](https://gitea.psi.ch/mx/AareDAQ/commit/0ca968277c68a456f3944cd72831ee4b5a58396a)) ## v0.8.1 (2026-08-11) ### Bug Fixes - Allow workflow dispatch of release wf ([`110bfb3`](https://gitea.psi.ch/mx/AareDAQ/commit/110bfb3f5f2f53fb5093663c93f9363904160821)) ## v0.8.0 (2026-08-11) ### Bug Fixes - Adapt main window to monitor size instead of overflowing ([`f4f3c5e`](https://gitea.psi.ch/mx/AareDAQ/commit/f4f3c5ec3d7d734dc34cf6c2c72d053deea4a200)) The window's minimum was 1400x1207 - taller than a 1920x1200 console - so the status bar was pushed off-screen on every monitor. Three causes: - the standard page's combined panel minimums: now wrapped in a QScrollArea so scrollbars appear instead of clamping the window - hidden portrait/compact stack pages inflating the QStackedWidget minimum (portrait alone demands 720px height): only the visible page contributes now - launching at the natural size hint (1577x1612): launch maximized so the window takes whatever the monitor offers Minimum drops to 1400x555; verified on a 1920x1200 X display that the status bar is visible and panels scroll when space runs out. Co-Authored-By: Claude Fable 5 - Dark-mode legibility for the status bar, sample tables, and surfaces ([`7b30c95`](https://gitea.psi.ch/mx/AareDAQ/commit/7b30c959a20e62c58f190f5b06dddbdcafa5d956)) Status-bar flags get status_colors(theme) (Mocha variants on Sunset) via a new set_theme; sample tables stop hard-filling rows WHITE and pin dark ink on tinted rows via ForegroundRole; dewar tab and log panel get solid dark surfaces (transparent renders black on the non-composited X11 container); developer help cards go square for the same reason. Co-Authored-By: Claude Fable 5 - Declutter the Local Contact view ([`c14d93f`](https://gitea.psi.ch/mx/AareDAQ/commit/c14d93ffcf0a9f8c3f3b98318ec772cd153789a8)) - drop the redundant Local Contact banner (the window title carries it) - remove the three parent=self config spinboxes that painted themselves over the top-left corner; parentless placeholders are replaced in _build_config_tab - remove all rounded corners (status card, value badges, group boxes, transfer-error frame, recovery panels) - tighten status rows to 2px spacing with a per-row minimum height so word-wrapped value labels can never compress rows until text clips (previously visible on the Hardware tab) Co-Authored-By: Claude Fable 5 - Heal poisoned all-docks-hidden layout and restore layout before watch-only close ([`3a7f1f5`](https://gitea.psi.ch/mx/AareDAQ/commit/3a7f1f584ad49d72b1fae6617ffa5d7aa9147d7c)) A window state saved during the watch-only fold restores as every dock hidden (the vanished-Sample-List-on-restart bug). Fall back to the default layout when a restore comes back all-hidden, and put the pre-watch layout back before saving state in closeEvent. Co-Authored-By: Claude Fable 5 - Opaque faces for floating windows and theme-aware pop-out icons ([`7f838f4`](https://gitea.psi.ch/mx/AareDAQ/commit/7f838f4b985c24a5003aa5d559e65acc4b27ce4a)) A transparent top-level renders black on the container's non-composited X11, so floating docks get a dynamic floating property feeding the QSS [floating="true"] opaque face, and PopoutWindow sets WA_StyledBackground. Pop-out titlebar glyphs are now painted in the palette's WindowText color and re-tint on PaletteChange, so they stay visible after a theme flip. Co-Authored-By: Claude Fable 5 - Reset connection state if cancel fails ([`7a60b7d`](https://gitea.psi.ch/mx/AareDAQ/commit/7a60b7d9329ac8e0a9705bad6e542be9570b179d)) - Scroll Local Contact tabs so rows keep text height ([`7a57d85`](https://gitea.psi.ch/mx/AareDAQ/commit/7a57d85282888bf967e6c6e6b756a610dfa4ebf0)) The dialog's explicit minimum size is smaller than some tabs' content; without a scroll area Qt squeezes rows below text height (clipped labels on the Hardware tab). Wrap every tab in a QScrollArea. Co-Authored-By: Claude Fable 5 - Window and dock sizing behavior ([`266f833`](https://gitea.psi.ch/mx/AareDAQ/commit/266f8337a9a1fcc163d2abf8a70a2b1038c454d2)) Three main-window chrome fixes: the un-maximized geometry is pre-set to half-screen centered so leaving maximized mode no longer restores an oversized size hint (the beamline state bar also stops imposing its ~2000px minimum width); closing a popped-out dock re-docks it instead of silently hiding the panel, and pop-outs open enlarged and clamped to the screen; state-bar buttons only update font/stylesheet/cursor when values change, since repolishing every DAQ tick dropped the hover cursor under a resting mouse. Co-Authored-By: Claude Fable 5 ### Code Style - Add typography, tooltip, scrollbar, and card tokens to the palette ([`e63ddb0`](https://gitea.psi.ch/mx/AareDAQ/commit/e63ddb090f68524b5193fe472176f46534dd1c7f)) The QSS gains a role-named font-size ladder (FONT_HERO..FONT_FINE), borderless QToolTip styling for both themes, soft rounded scrollbars without end arrows, and a card_style() helper with one shared CARD_RADIUS so card-shaped frames keep uniform geometry. Banner text flips to near-white with a shadow constant for the painted emboss. Recovery-card and console-log colors are marked TODO for a later retheme. Co-Authored-By: Claude Fable 5 - Apply the typography ladder and card_style across the GUI ([`913089b`](https://gitea.psi.ch/mx/AareDAQ/commit/913089b9b62793f74e003c7afa2fd35c12f25864)) Inline font-size literals become FONT_* tokens and hand-written card QSS collapses into card_style() (recovery cards and console-log notifications keep FLAT_CARD_RADIUS). TitleLabel paints its text by hand — QSS has no text-shadow — for an embossed banner title, elided when narrow, and gains a section_title() helper for small in-panel headings. Co-Authored-By: Claude Fable 5 - Centralize the GUI color palette in styles.py ([`271ca54`](https://gitea.psi.ch/mx/AareDAQ/commit/271ca54d9ad3a2001dddaa5c4f960c8929f13d3c)) Every color literal in the GUI moves into one palette module: ~200 grouped constants, a qcolor() helper (hue from the theme, alpha at the call site), and both QSS stylesheets become string.Templates fed by _palette() so a renamed constant fails loudly. Also retints: light background #d8e4fd -> #e2e7ee, banner indigo -> #a2b7e4, and the portrait dark theme adopts Catppuccin Macchiato. Co-Authored-By: Claude Fable 5 - Clear the basedpyright gate for the new-code lines ([`4ef2ad6`](https://gitea.psi.ch/mx/AareDAQ/commit/4ef2ad64d706c2fbc0631668f00bdd8266f5ace3)) Narrow QApplication.instance() before use, wrap the theme QSettings read in str(), hand QPropertyAnimation a real QByteArray, and declare the lazily-set watch-mode attributes on the class. Co-Authored-By: Claude Fable 5 - Clear the basedpyright gate for the ported round ([`84ccf27`](https://gitea.psi.ch/mx/AareDAQ/commit/84ccf275f9e2e954ee415ee905b7e3d90a43d518)) Declare MainWindow's lazily-set attributes, guard Optional layouts and the sample tab bar, wrap QSettings reads (typed object even with type=...), include _press_geom in the pop-out resize guard, and ignore the PySide6 stub gap on setGraphicsEffect(None). Co-Authored-By: Claude Fable 5 - Clear the two portrait-mode diff-gate violations ([`ed42738`](https://gitea.psi.ch/mx/AareDAQ/commit/ed42738693e6033ebeb5877c15bb842ed52e915e)) The sample-name labels are created in __init__ now (the build helper only styles and mounts them) so reportUninitializedInstanceVariable stops firing on the ported styling lines, and the queue placeholder uses the scoped Qt.AlignmentFlag.AlignCenter. Co-Authored-By: Claude Fable 5 - Compact the control panels ([`5f44be2`](https://gitea.psi.ch/mx/AareDAQ/commit/5f44be2a62a8d978d51ee29398aaa4845456147e)) Vertical-space pass: samcam merges exposure+gain onto one row, ABR and monochromator tighten their grids (energy now displayed in keV, DAQ API stays eV), beam-mark's clear button shares the readings row, the data collection pages move Run/Abort under the last configurable row and the tab area becomes QTabBar+QStackedWidget, the raster grid table gets a fixed height, and the automation panel drops its own title since the dock title bar already says it. Control panels start expanded via default_collapsed=False. Co-Authored-By: Claude Fable 5 - Cool the sunset gradient base ([`0b696a5`](https://gitea.psi.ch/mx/AareDAQ/commit/0b696a56f0f051dc1da01f9da86c5b0e6444a361)) The warm glow at the bottom of the dusk sky didn't fit — stay in the blue range. Co-Authored-By: Claude Fable 5 - Declare HoverableButton state attribute for the pyright gate ([`e818682`](https://gitea.psi.ch/mx/AareDAQ/commit/e818682abdcdc5e4c1db04c48180af7f4218ee3e)) The dynamic _beamline_state assignment was a pre-existing pattern, but the panel rewrite turned its line into a changed line, so the basedpyright diff gate now counts it. Declare the attribute instead. Co-Authored-By: Claude Fable 5 - Extend the palette with selection, frame, slider, and sample-status tokens ([`0bfa9db`](https://gitea.psi.ch/mx/AareDAQ/commit/0bfa9dbbeb5f8798fac8506c420d5ccdb33ed514)) SELECTION_BG/TEXT pin the app-wide selection blue to the banner color (was Qt's undeclared palette default); FRAME_L1/L2/L3 knobs put window, panel, and data-view borders on three tunable levels (panel etching off by default); QTabBar tabs and filter chips go borderless with a hover underline; QSlider matches the scrollbar look; scrollbar tracks turn square with a track-colored corner; SAMPLE_STATUS_* and SAMPLE_ROW_ALT_BG drive the sample-table status tints. Co-Authored-By: Claude Fable 5 - Fix lint for the banner/adaptive changes ([`ce0ed20`](https://gitea.psi.ch/mx/AareDAQ/commit/ce0ed20d5a1d4d2f33e662eb8be7bd58fbe2d368)) - ruff format and import ordering (main_window, data_collection_settings, beam_center_panel, beamline_state_panel) - rename unused unpacked variable in test_title_label - replace the mousePressEvent monkeypatch on the beamline state title with a proper eventFilter so basedpyright accepts the diff Co-Authored-By: Claude Fable 5 - Move panel and model colors to the shared palette ([`b7d6610`](https://gitea.psi.ch/mx/AareDAQ/commit/b7d6610261840ad45ad91b9663c37c52f5915d89)) Mechanical swap of hardcoded color literals for styles.py constants and qcolor() across panels, models, and scan_logic. portrait_mode.py drops its private palette block; beamline_controls and data_collection_settings gain object names so the new $border QSS rules can target them. The status-panel test asserts the palette hex instead of 'red'. Co-Authored-By: Claude Fable 5 - Move widget colors to the shared palette ([`590e500`](https://gitea.psi.ch/mx/AareDAQ/commit/590e500da5f7ed22b4d1ac515356dff13b06992b)) Same mechanical swap for the widgets and the tutorial manager: painter QColors go through qcolor(), inline QSS literals become palette constants (baton dialog, busy overlay, status bar, camera overlays, splash screen, numeric inputs). Co-Authored-By: Claude Fable 5 - Narrow Optionals for basedpyright diff gate ([`ee7a835`](https://gitea.psi.ch/mx/AareDAQ/commit/ee7a8356a6d46de5e97a010886eb6e7cb1a4f051)) QLayout.itemAt/QWidget.layout return Optionals; pyright cannot narrow across repeated method calls, so hold them in locals before use in tighten_column, _apply_collapsed and _set_visible. Co-Authored-By: Claude Fable 5 - Narrow the log pop-out view for the pyright gate ([`2adf8ff`](https://gitea.psi.ch/mx/AareDAQ/commit/2adf8ff6d5a57d98527f45b7450dd3b9565d65e4)) The Optional _popout_view is assert-narrowed once after opening; the unguarded accesses were the last three diff-gate violations. Co-Authored-By: Claude Fable 5 - Narrow the manual-resize press state for the pyright gate ([`763a258`](https://gitea.psi.ch/mx/AareDAQ/commit/763a25837c4c880bc9c50d707084237c756c0463)) The diff-vs-main basedpyright gate flags QRect(self._press_geom) because only _press_global was narrowed; both are set together in mousePressEvent, so the extra check is a no-op at runtime. Co-Authored-By: Claude Fable 5 - Relabel theme entries, tuck prototype views into the View menu ([`c179ea9`](https://gitea.psi.ch/mx/AareDAQ/commit/c179ea992c8d57d45423317b64b7283296ae485d)) Legacy/Portrait themes become Sunrise (default)/Sunset. Automation View and Portrait (now Playlist) Mode leave the menubar for the View menu with in-progress labels; Return to Main View stays top-level since it only shows inside the automation view. Co-Authored-By: Claude Fable 5 - Ruff-format the ported round, scope splash Qt enums ([`2638308`](https://gitea.psi.ch/mx/AareDAQ/commit/263830841208776fc9b65648313ca2c32775bd87)) The sandbox port was ruff-check clean but not ruff-format clean (CI formats before linting); splash_screen's alignment flags move to the scoped enum since the port put that line into the diff gate's scope. Co-Authored-By: Claude Fable 5 - Small panel polish ([`f7194ca`](https://gitea.psi.ch/mx/AareDAQ/commit/f7194ca3a4fa98a0ab3fa76a40a5955955e113fa)) Energy unit moves from spinbox suffix to the label (the suffix ate field width next to the new spin arrows); samcam exposure/gain get a 3:2 stretch so 3-decimal exposure isn't cut; the Exp. Config. tab bar gets a BANNER_TAB_GAP spacer under its banner. Co-Authored-By: Claude Fable 5 - Swap the splash banner text to the white variant ([`cd4b623`](https://gitea.psi.ch/mx/AareDAQ/commit/cd4b62323c509717641d858fc1d5cb8d9d364603)) Copied from aare_banner_w.svg; the black glyphs vanished on the dark splash panel, the white fills read on it. Co-Authored-By: Claude Fable 5 - Visual and interaction polish ([`833a6d1`](https://gitea.psi.ch/mx/AareDAQ/commit/833a6d136f1b862cd38932c0b24083fbe0ebd95a)) Windowed startup at 50%x70% instead of maximized; overlay legend now defaults off (it covers the camera image); square slider handles with grip-line PNG assets (the round handle clipped flat); warmer sunrise gradient bottom; abr/beam-mark layout tweaks; hover cues on the beamline-state entries; DPI/font-aware pop-out titlebar icons; the out-of-date Tutorial menu entries are hidden until content is redone. Co-Authored-By: Claude Fable 5 ### Documentation - Note the spreadsheet log-spam TODO in daq_worker ([`27c9b93`](https://gitea.psi.ch/mx/AareDAQ/commit/27c9b93d5ca87093db33fe3a3fb540421024e75a)) load_spreadsheet/load_reference_tools log a GET they never send every ~12.5s poll while base_url is None; fix later by demoting to debug or logging once on the None->set edge. Co-Authored-By: Claude Fable 5 ### Features - Add spin-arrow and check-mark glyph assets ([`900315d`](https://gitea.psi.ch/mx/AareDAQ/commit/900315d412db59d85a54cd3d5d3409b12b91909b)) Co-Authored-By: Claude Fable 5 - Camera help overlay, camera-error message, and session badge hover feedback ([`3db8b11`](https://gitea.psi.ch/mx/AareDAQ/commit/3db8b11dd1039439a844bbe74ab784634fac1bcc)) The controls cheatsheet gets its own help badge/overlay instead of riding the detection legend; the camera-unavailable state now draws the actual error reason bottom-center (pushed from MainWindow to all three camera views); the session badge shows hover feedback and the vacant overlay reads 'In viewing mode' with a grab-baton hint. Co-Authored-By: Claude Fable 5 - Camera session badge and collapsible legend ([`2054f07`](https://gitea.psi.ch/mx/AareDAQ/commit/2054f078b0d9ad3e982cbace0ccf34dc6c02b562)) The camera overlay gains a clickable session badge (opens the session menu at the click position) and a baton gate: watching stays free, operating clicks are blocked when the baton is elsewhere. The legend collapses to a ? badge until clicked - the full box covered too much image. Co-Authored-By: Claude Fable 5 - Collapsible half-height panel banners with a universal gap ([`a9137b3`](https://gitea.psi.ch/mx/AareDAQ/commit/a9137b3221fff7364d0a3c98d9d6a4199eeb95b9)) TitleLabel gains an optional collapsible mode: whole-banner click target, bare +/- glyph (no pill background), per-title collapsed state persisted in QSettings, and an expand() helper. Banners are halved to 25px with plain text + QSS font (H3 margins would clip vertically). - convert Zoom, Light, Omega, Smargon, Sample camera, Monochromator, ABR meas. pos., Beam mark, Beam center, Beam size, Dataset path and Loop centering to collapsible banners - new collapsible Exp. Config. section wrapping the scan tabs - move Manual sample from a bottom dock into the left column between Dataset path and Exp. Config.; Ctrl+M now expands it instead of raising the dock - Beamline state banner restyled to match (25px, plain font, bare glyph, whole banner clickable) - universal 11px banner gap via tighten_column() shared by both panel columns and the left column stack; ABR banner spans all grid columns and file path / manual sample drop side margins so widths align - abort button sits under the tabs instead of pinned to the bottom - unit tests for the collapse behavior Co-Authored-By: Claude Fable 5 - Cross-fade and palette flip on theme switch ([`ed8b2bd`](https://gitea.psi.ch/mx/AareDAQ/commit/ed8b2bd16539d22ad2c0b4b5b37c5dc1ac20044d)) Freeze the old look in a click-through screenshot overlay and fade it out over the restyled window — QSS has no transitions and animating the palette would re-polish every widget per frame. Sunset also flips the app-palette text roles so native primitives QSS can't recolor (spin and combo arrow glyphs) follow the theme. Co-Authored-By: Claude Fable 5 - Dusk-gradient theme overhaul with transparent-widget scheme ([`1946430`](https://gitea.psi.ch/mx/AareDAQ/commit/1946430f0d69c46a41191e9c54e189dd0fa49dd1)) Both stylesheets move to transparent children over a gradient painted only by top-level windows; inputs, buttons, headers, and menus get opaque faces back. Sunset drops Catppuccin Macchiato for the Daemmerung dusk palette. Spin/combo arrows and check indicators become theme-tinted PNGs. Widgets stop carrying inline input/text stylesheets so the theme QSS can win (empty stylesheet = theme reset). Co-Authored-By: Claude Fable 5 - Float alert banners over content as anchored toasts ([`1f2a538`](https://gitea.psi.ch/mx/AareDAQ/commit/1f2a538959b7f654dfde6d1d8ac9b2a177a8cab0)) Banners in the root layout shifted the whole UI on every message; now they float over the content root (repositioned on resize) and the baton toast anchors as a compact pill under the camera view, auto-clearing in 4s instead of 10s. Co-Authored-By: Claude Fable 5 - Group beam mark/center/size under one Beam Config banner ([`00e5d11`](https://gitea.psi.ch/mx/AareDAQ/commit/00e5d116a61c16e91bbf456c05e90ca8341f18d9)) The three small beam panels shared a column with three collapsible banners; BeamConfigPanel puts them under a single collapsible 'Beam Config.' TitleLabel with section_title() sub-headings. beam_mark/beam_center/beam_size stay as aliases on BeamlineControls so main_window signal wiring is untouched. Co-Authored-By: Claude Fable 5 - Hide operation panels in watch-only mode ([`d127863`](https://gitea.psi.ch/mx/AareDAQ/commit/d127863b1f8fc6907828aef9b8aca26a64bfe03d)) Without the baton the GUI now shows only the camera stream and status bar; every operating surface (panels, docks, pop-out mirrors) is hidden outright. Regaining the baton restores dock layout via saveState/ restoreState — per-dock visibility snapshots lose docks tabbed behind others — so LogDock gains the objectName restoreState requires. Co-Authored-By: Claude Fable 5 - Horizontal beamline state bar above the status bar ([`9ef4032`](https://gitea.psi.ch/mx/AareDAQ/commit/9ef4032d06274fb1448907f21b53b53b2ac34400)) Replaces the vertical station map that consumed left-column space with a slim always-visible strip in the bottom toolbar area, directly above the status bar: - states in physical beamline order, 18px text, one line when the bar is wide enough and wrapped at the last space otherwise - availability coloring from the route graph plus the status-bar shortcut transitions: bold blue = active (red for Maintenance), orange = reachable in one step, grey = not reachable; no backgrounds or rounded corners - transitions only via right-click 'Go to '; left click shows a reminder tip for available states and the reachability explanation for grey ones; hovering a grey state for 3 s shows the same explanation - whole entry is the hover/click region; tips anchor to the entry and disappear when the mouse leaves - always visible: no View-menu toggle, not hidden by portrait or compact modes Co-Authored-By: Claude Fable 5 - Lazily init jfj client ([`8a51eef`](https://gitea.psi.ch/mx/AareDAQ/commit/8a51eef4f08f9756e7ea8307554f1fed58a045a8)) - Let panels opt out of starting collapsed ([`460f703`](https://gitea.psi.ch/mx/AareDAQ/commit/460f7034c37033f5bca7729471a4eb5aa8106aee)) TitleLabel gains default_collapsed; the small motor/light panels start open (their per-title persisted choice still wins). Co-Authored-By: Claude Fable 5 - Merge Automation progress and Console log into one Information dock ([`e457236`](https://gitea.psi.ch/mx/AareDAQ/commit/e457236777b80514bc5f24085abd1ee6a0a23df8)) The two tabified bottom docks left their switcher tabs stranded at the window bottom; one Information dock with proper tabs mirrors the Sample List dock's layout. LogDock becomes the LogPanel widget with mirror views for the pop-out and a reveal_requested signal so the owner controls visibility (Ctrl+Shift+L, notifications). Co-Authored-By: Claude Fable 5 - Merge Sample List, Reference Tools, and the queue into one dock ([`1f90098`](https://gitea.psi.ch/mx/AareDAQ/commit/1f9009807d555c96b1be214c9a4d0791deef32e8)) Reference Tools was a separate staff-only dock tabified behind Sample List and kept vanishing (saved dock state, raise order); the automation job list was a third dock for what is conceptually the same table. One tabbed dock now holds Dewar samples + Auxiliary puck (concept from aaregui2's QueuePanel): the dewar table doubles as the queue view with the queue buttons and an Unmount button in a row beneath it, SampleQueuePanel lives on hidden as the queue engine, and queue/flag membership is edited via right-click or row drags onto the Queued and Flagged chips. Column 0 is a frozen #+status cell (mounted > queued > flagged > measured, tints context-dependent per chip filter); non-staff see Auxiliary greyed out with a Staff-only popup instead of hidden. Ctrl+L/Ctrl+R raise the Dewar/Auxiliary tab. The Sample List and log pop-outs are fully operational second views on shared models. Riders: MainWindow installs WheelValueGuard, wires the camera session badge, and moves samcam/monochromator/ABR/beam-config into the left column's Beamline group (BeamlineControls keeps only zoom/light/omega/smargon). Co-Authored-By: Claude Fable 5 - Pointing-hand cursor on all interactive widgets ([`257edc2`](https://gitea.psi.ch/mx/AareDAQ/commit/257edc25f87a88d22a34b2410af47bfdb491eeea)) QSS cannot set cursors and per-widget setCursor calls get forgotten as widgets are added, so an app-level filter catches every Polish event on buttons, combos, and sliders — dialogs and pop-outs included. Co-Authored-By: Claude Fable 5 - Pop-out windows instead of floating docks ([`6e1305c`](https://gitea.psi.ch/mx/AareDAQ/commit/6e1305cb927a11cc04ea86b88366961ec6aa27fd)) Floating a dock rips it from the row and reshuffles the rest, so PopoutWindow opens an ADDITIONAL frameless top-level window instead: 12px outer resize halo (border painted OUTER_GRIP inside the real edge so an outside-looking grab still works), hand-painted borderless titlebar glyphs, close hides and keeps geometry. DockTitleBar puts the popout button next to the close box. The console log adopts it: dock floating disabled, the pop-out view is a second QPlainTextEdit fed by the same emitter (a shared QTextDocument would make two views fight over one layout), clear() clears both. Co-Authored-By: Claude Fable 5 - Reference-tools position column and state-driven default sample tab ([`b088170`](https://gitea.psi.ch/mx/AareDAQ/commit/b08817024dd6c03d8b7f67abfb7a9cd982d0a76e)) The reference table gets a display-only '#' column (like the Dewar list) with sort indices shifted around it; the sample dock switches to the Auxiliary puck tab on entering alignment/maintenance states and back to Dewar elsewhere, only on state transitions so a manual choice sticks. Co-Authored-By: Claude Fable 5 - Rename themes to sunrise/sunset, add bluebird theme with Catppuccin-Latte light palette ([`c13ea11`](https://gitea.psi.ch/mx/AareDAQ/commit/c13ea11430cf595395fc8de83988d73de088b930)) Sunrise/sunset replace the original/portrait tokens (QSettings values migrate on restore); bluebird is sunrise with a flat sky. The light palette is repainted with Catppuccin Latte across alerts, chips, cards, log, splash, inputs, and status flags, plus button/input height caps and hover rules in the QSS. Co-Authored-By: Claude Fable 5 - Rest-to-reveal hint for dock separators ([`f9a6c7b`](https://gitea.psi.ch/mx/AareDAQ/commit/f9a6c7bc319bad40c015ac692c6ba7857274c712)) Separators stay invisible until the mouse rests on one for ~1s (or a drag starts); the QSS ::separator:hover rule does the hit-testing and a dynamic separatorHint property gates it, so event() never needs to know where separators are. Co-Authored-By: Claude Fable 5 - Start all collapsible panels collapsed by default ([`f84bee6`](https://gitea.psi.ch/mx/AareDAQ/commit/f84bee66ee726598dd38b75f5a8978a29bcc7806)) A fresh GUI shows only the banners; the Beamline state panel keeps its own expanded default. A user's saved per-title states still override. Co-Authored-By: Claude Fable 5 - Swap the splash banner to an SVG ([`efcdc0c`](https://gitea.psi.ch/mx/AareDAQ/commit/efcdc0c1912c0024719105411f1bb0a7c09225dd)) The PNG banner is replaced by an SVG so the splash artwork scales; the old aare_banner.png is removed and gui.py loads the .svg path (the stale path yielded a null splash pixmap). Co-Authored-By: Claude Fable 5 - Theme-aware beamline state panel ([`7801025`](https://gitea.psi.ch/mx/AareDAQ/commit/7801025802d66291d1bc46177dd1a820ffb6dbd2)) The panel paints availability/message colors in code per DAQ tick, so QSS can't retint it — state_colors(theme) hands it a per-theme dict (Catppuccin Mocha inks for Sunset) and _apply_theme pushes theme flips. Co-Authored-By: Claude Fable 5 - Wheel only adjusts values while the right button is held ([`f87b895`](https://gitea.psi.ch/mx/AareDAQ/commit/f87b8952c8cf9c01f863e5f9a20c96b53e99ad9c)) WheelValueGuard (app-level event filter, installed by MainWindow) makes a bare wheel over spin boxes, sliders, dials, and combos scroll the enclosing scroll area instead of nudging the value - motor protection. NoWheelScrollArea stops swallowing wheel events since values are now guarded at the widget. Co-Authored-By: Claude Fable 5 ### Refactoring - Shared busy-badge renderer for camera and axis video views ([`e77dfb4`](https://gitea.psi.ch/mx/AareDAQ/commit/e77dfb4716f7adcb6673593c1d5075824ae9aeb1)) draw_busy_badge in busy_overlay renders the title+subtext pill once; the sample camera and axis video overlays both delegate to it instead of keeping diverging copies. The axis panel's dot+label status pill and its per-theme QSS go away with it. Co-Authored-By: Claude Fable 5 ### Testing - Cover the beamline state bar ([`3175e43`](https://gitea.psi.ch/mx/AareDAQ/commit/3175e437a4ebf4c749d4f6c841d67f35a506fdeb)) Availability sets (routes + menu shortcuts, Moving/unknown), signal gating, palette and cursors per availability, red/blue active states, adaptive label wrapping, left-click hint paths, hover-hint timer lifecycle, and pending-target clearing. Lifts the PR diff coverage back over the 80 percent gate (measured 88 percent locally). Co-Authored-By: Claude Fable 5 - Cover the camera overlays, theme migration, layout heal, and splash ([`7b4764e`](https://gitea.psi.ch/mx/AareDAQ/commit/7b4764e7caa336e2b26165cc3cbd43f6afed86f7)) Diff coverage vs main was 77%, under the 80% CI gate; the new camera help/error/badge code and the theme+layout main_window paths were the uncovered bulk. Locally: 82%. Co-Authored-By: Claude Fable 5 - Cover the sample-status logic, wheel guard, pop-outs, and log mirror ([`69b6813`](https://gitea.psi.ch/mx/AareDAQ/commit/69b68130259827ba2166360474959d45d0ec5310)) New tests for what the port added: status tint priority and context-dependent chip filters on the dewar/queue model, the right-button wheel guard (motor protection), PopoutWindow edge maths, manual-resize fallback, close-hides behavior and DockTitleBar, the chip drag-drop relabeling, and the console-log pop-out mirror. The widgets' __main__ self-checks are superseded by these and removed. Brings PR diff coverage from 70% to 81% (gate: 80%). Co-Authored-By: Claude Fable 5 - Inline smoke check for the wheel guard ([`546fb5d`](https://gitea.psi.ch/mx/AareDAQ/commit/546fb5d3f041f71410093604e8c712013a0deea5)) Co-Authored-By: Claude Fable 5 - Track the sample-table column shift, sort imports ([`0b80c75`](https://gitea.psi.ch/mx/AareDAQ/commit/0b80c75c63d58d03666c354744c4074e8d1952c6)) The frozen #+status column shifted data columns +1, so the User-column model tests move from index 5 to 6; ruff import-sort fixes for main_window and log_panel ride along. Co-Authored-By: Claude Fable 5 ## v0.7.3 (2026-08-11) ### Bug Fixes - Kwarg name for mlbox klass ([`40a9e84`](https://gitea.psi.ch/mx/AareDAQ/commit/40a9e8464c67c2032ba5718a6bc1763690a28be4)) - Remove noisy disabled ring current log ([`1bdf056`](https://gitea.psi.ch/mx/AareDAQ/commit/1bdf056af52af86d25f2573b789bff1c4364a0b4)) ## v0.7.2 (2026-08-05) ### Bug Fixes - Don't create pixmap before qapp ([`214c204`](https://gitea.psi.ch/mx/AareDAQ/commit/214c204d062559fcdfaee4649502423d0158bc21)) ### Documentation - Make new zensical docs ([`deb1ea4`](https://gitea.psi.ch/mx/AareDAQ/commit/deb1ea4f505bad12b2705dc6e8a63b13f9093f50)) - Move the readme cheatsheet content to a docs page - Udpate cheatsheet formatting ([`6244d77`](https://gitea.psi.ch/mx/AareDAQ/commit/6244d77a12f2e69afaa7d0e480ef750d84eecdb2)) ## v0.7.1 (2026-08-04) ### Bug Fixes - No longer load user macros through client ([`bf503e4`](https://gitea.psi.ch/mx/AareDAQ/commit/bf503e416ff2dfdf9c36661da7fcbd9564a59bbf)) - they have been moved to the dynamic beamline dispatch module, where they are concretely loaded from each beamline repo instead ## v0.7.0 (2026-08-04) ### Continuous Integration - Fail diff cover below threshold ([`71d9d07`](https://gitea.psi.ch/mx/AareDAQ/commit/71d9d07f3900d259716a9e1fe23bb6596b76e689)) - Fail new pyright errors ([`db520e8`](https://gitea.psi.ch/mx/AareDAQ/commit/db520e8579542f1dea4fdd83fe5b6f5a4a1d1dbd)) ### Features - Add beamline dispatch for x06da ([`e0db953`](https://gitea.psi.ch/mx/AareDAQ/commit/e0db953b86cf09ebdcd44c0e08857525594db848)) ## v0.6.1 (2026-08-03) ### Bug Fixes - Add coverage comment ([`8def022`](https://gitea.psi.ch/mx/AareDAQ/commit/8def022d4c68ac928a22b4ab214b9e7df9eb279f)) - As many ruff errors as possible, some type ([`0135129`](https://gitea.psi.ch/mx/AareDAQ/commit/0135129c89c377084cc87ee9704e21b67a94265a)) ### Chores - Update common dep ([`28dec7a`](https://gitea.psi.ch/mx/AareDAQ/commit/28dec7a3fefe82ee1246cf227e90149b14737c77)) ### Code Style - Ruff check --fix --unsafe-fixes ([`f63107a`](https://gitea.psi.ch/mx/AareDAQ/commit/f63107a1e0090ce51e8a2958d5ba1d2c4bc3574b)) ### Continuous Integration - Add better linting ([`70c81ab`](https://gitea.psi.ch/mx/AareDAQ/commit/70c81abdd86b67d6a792d13595b88e8bc5d00f95)) - Make sure main is available for diff ([`7c28b5f`](https://gitea.psi.ch/mx/AareDAQ/commit/7c28b5f023dba7e5fa952130b485398cffd90c4a)) ## v0.6.0 (2026-07-31) ### Bug Fixes - Pxi and pxiii tests shouldn't work yet ([`ba68b6b`](https://gitea.psi.ch/mx/AareDAQ/commit/ba68b6b2335535079c92a0153024a4bff533d2be)) - Remove many duplicated methods ([`03e289c`](https://gitea.psi.ch/mx/AareDAQ/commit/03e289c6d7ebe1f9f83e48171264fdfb650fd3c3)) - Use macros from dispatch ([`b492fac`](https://gitea.psi.ch/mx/AareDAQ/commit/b492face878a9ad27d9e03c64c135582d0aa85d6)) ### Code Style - Remove pointless name-mangled attrs ([`7b79dd8`](https://gitea.psi.ch/mx/AareDAQ/commit/7b79dd8ec5efb741eafa565ba1436fbff396aff5)) the fact that removing them didn't break anything shows that they were completely unneccessary - there is no inheritance tree using the same names - Replace dunder attributes with normal 'private' attrs ([`fb0c8ef`](https://gitea.psi.ch/mx/AareDAQ/commit/fb0c8efebec4a9270d6091902768bc2e74b8c798)) ### Continuous Integration - Add concurrency to test suite ([`1ef5b20`](https://gitea.psi.ch/mx/AareDAQ/commit/1ef5b20172b6ea5173f2a3b71776a420ea5871f9)) - Run on push only for main, otherwise PR ([`0c55bc8`](https://gitea.psi.ch/mx/AareDAQ/commit/0c55bc800821488a73541df46256bf129e91b85b)) ### Features - Beamline dispatch framework ([`991e4be`](https://gitea.psi.ch/mx/AareDAQ/commit/991e4bea474c667b50067c96b4aa6234a1782f37)) - Get auth from dispatch ([`660a0ac`](https://gitea.psi.ch/mx/AareDAQ/commit/660a0acf7c0028e16072f396787e32971e14faac)) - Make bec macros dispatched and test against beamline plugins ([`0f1aa30`](https://gitea.psi.ch/mx/AareDAQ/commit/0f1aa3090b8deb33502e710e87f92d6e3299f576)) ### Testing - Add test for dispatch against each plugin ([`e90fd52`](https://gitea.psi.ch/mx/AareDAQ/commit/e90fd52e479550d87dcb6047770324d665862041)) ## v0.5.2 (2026-07-27) ### Bug Fixes - Return 0 if ring current device is not accessible ([`69421be`](https://gitea.psi.ch/mx/AareDAQ/commit/69421be3e9e1e94a831b655801201aa0b53d11db)) ## v0.5.1 (2026-07-27) ### Bug Fixes - Unpin uvicorn ([`105e85c`](https://gitea.psi.ch/mx/AareDAQ/commit/105e85c06b0cba614c7781ba92f98e0a7772f5c9)) - Update aaredb tag ([`d3a84c9`](https://gitea.psi.ch/mx/AareDAQ/commit/d3a84c9fb832ae592477dcaf7f39b2415badf9a8)) ## v0.5.0 (2026-07-27) ### Bug Fixes - Add py 3.13 to test matrix ([`d7fa11b`](https://gitea.psi.ch/mx/AareDAQ/commit/d7fa11bc1946589fbc1bc8bfdc4cf040f644ac15)) - Added end_operation to the exception mess at the end of def measure() in daq.py ([`0a4054d`](https://gitea.psi.ch/mx/AareDAQ/commit/0a4054d69e8cc26d27b990511da341833195ca1b)) - Detector url ([`9fb2004`](https://gitea.psi.ch/mx/AareDAQ/commit/9fb2004e05d75905a595b3fe3c92d3bec6eed9c8)) - Handle mountingfailed specifically and split on critical ([`2c80ef7`](https://gitea.psi.ch/mx/AareDAQ/commit/2c80ef7381686062184551406018cd3f162f0fb4)) - One internal worker ([`2663570`](https://gitea.psi.ch/mx/AareDAQ/commit/2663570f6827ef43a563254943142e9313a2bd33)) - Persist workflow git fetch auth ([`3185811`](https://gitea.psi.ch/mx/AareDAQ/commit/3185811e6129c77d0b90c8daba169e2c27589b69)) - Remove excess warning logs ([`f821c2d`](https://gitea.psi.ch/mx/AareDAQ/commit/f821c2dd99d9cf79f581f984d2ccfa10d85ed327)) - Reset git fetch auth to token ([`bc9094d`](https://gitea.psi.ch/mx/AareDAQ/commit/bc9094dc6e09d0732b0ae328b7e221062d8af29d)) - Spurious import ([`c259e10`](https://gitea.psi.ch/mx/AareDAQ/commit/c259e102284c7265e365c6aa08c373784190d6d0)) - Supply operation to end ([`3a64439`](https://gitea.psi.ch/mx/AareDAQ/commit/3a64439c6b835d499dc971a18141a37443814a44)) - Suppress only baton error ([`fbb0143`](https://gitea.psi.ch/mx/AareDAQ/commit/fbb01439505ac9c1b3faad860fecb5781b8d3b9c)) - Typo in exception name ([`951ee05`](https://gitea.psi.ch/mx/AareDAQ/commit/951ee0591e421c70c998d8b38bd2bcf32d22ac7f)) - User values now should persist between samples, only reset to default on start up. ([`89564a5`](https://gitea.psi.ch/mx/AareDAQ/commit/89564a55e1f4972bb7232fe7b3aa78fbe44e8c9b)) ### Chores - Add gunicorn dep ([`5a9d4a2`](https://gitea.psi.ch/mx/AareDAQ/commit/5a9d4a2662641d985a69f447af1f1d6645b52ae5)) - Bump aarecommon dependency ([`aae4ea7`](https://gitea.psi.ch/mx/AareDAQ/commit/aae4ea7a32e99e7b7c29b792bd9bfd06ad112d9b)) - Removed redundant /camera/source and /beamline/imafge from server.py and test_server.py ([`60faea7`](https://gitea.psi.ch/mx/AareDAQ/commit/60faea716faf28204eca0d77cd91d3444d031624)) ### Code Style - Fix a few style issues by hand ([`2c237b6`](https://gitea.psi.ch/mx/AareDAQ/commit/2c237b66235255acfd9b44a95a04ba5488224330)) - Formatter again ([`72d96ec`](https://gitea.psi.ch/mx/AareDAQ/commit/72d96ecd6ac44cdf942cd052ae3d1ca84823aea3)) - Ruff check --fix ([`910076a`](https://gitea.psi.ch/mx/AareDAQ/commit/910076a2389bf1d93016226e6b1ae55892a6adb5)) - Ruff check --fix --unsafe-fixes ([`6affbf9`](https://gitea.psi.ch/mx/AareDAQ/commit/6affbf91480b19d11f5354eb1581c971c7563272)) - Ruff format ([`0451b8c`](https://gitea.psi.ch/mx/AareDAQ/commit/0451b8cebb87adabe8d7b2d1d91a2525bb2286b9)) ### Continuous Integration - Introduce release workflow ([`5f1a09a`](https://gitea.psi.ch/mx/AareDAQ/commit/5f1a09a1e96565c20fdc3259a7a86462fad17717)) ### Features - Added flux macro to devices for x10sa ([`014ae0f`](https://gitea.psi.ch/mx/AareDAQ/commit/014ae0f47a5175266b12a0322713360e3640c8e3)) - Server about info ([`52a9765`](https://gitea.psi.ch/mx/AareDAQ/commit/52a9765182e3372629c884295ace6a8546fb22bb)) - Updated the idle close timeout to 8 hours ([`99ec01c`](https://gitea.psi.ch/mx/AareDAQ/commit/99ec01c34ccc0eaa21ef58091f6f08742094d95a)) - Updated the idle close timeout to 8 hours ([`e6b759e`](https://gitea.psi.ch/mx/AareDAQ/commit/e6b759e6e234f116e6b4e8e853356d520ac05515)) ## v0.4.0 (2026-07-08) ### Bug Fixes - Crash on bec init failure; beamline must be set explicitly ([`12bca38`](https://gitea.psi.ch/mx/AareDAQ/commit/12bca38a124c0ceb38a9e5d0852320e8a2adfcf1)) ### Chores - Add a bunch of stuff to gitignore ([`9025c42`](https://gitea.psi.ch/mx/AareDAQ/commit/9025c425f8b5ab0f20cd02d2cf6ec748b91b7105)) - Add aarecommon dependency ([`ccc2185`](https://gitea.psi.ch/mx/AareDAQ/commit/ccc21855612f506b61101df85ebfd80d4218447b)) - Add uv to dependencies ([`3d46663`](https://gitea.psi.ch/mx/AareDAQ/commit/3d46663e23b61f37985cf817c784bdde78478c8b)) - Bump version ([`6012607`](https://gitea.psi.ch/mx/AareDAQ/commit/60126073eb8284f183134872748e02c7b9a25867)) - Remove common tests from daq ([`264e667`](https://gitea.psi.ch/mx/AareDAQ/commit/264e6671c76832dfcc7f8c01c1c80c0dcd59da70)) - Update aarecommon dependency ([`b57b26d`](https://gitea.psi.ch/mx/AareDAQ/commit/b57b26d1e23d027cf4ca5462e173bace9c900515)) - Update aarecommon dependency to 0.1.3 ([`228e0ed`](https://gitea.psi.ch/mx/AareDAQ/commit/228e0edd16b830d9d0ee77ab85cb9b011bb59da4)) ### Code Style - Format with ruff ([`b0863e5`](https://gitea.psi.ch/mx/AareDAQ/commit/b0863e5ddba5d7310148a6d17752b77cc02c32cd)) - Ruff check fix ([`9932661`](https://gitea.psi.ch/mx/AareDAQ/commit/99326614aec6d94a6a50ed896c3234a303995b45)) ### Features - Add hostname+user to gui logs ([`3ec2bc0`](https://gitea.psi.ch/mx/AareDAQ/commit/3ec2bc011bbcc6cdcecd68d8c6c242349f8c119a)) - Display version, gui and env location in about ([`cebd4e8`](https://gitea.psi.ch/mx/AareDAQ/commit/cebd4e82bcd6c9a931fa91bfe360fa1925879401)) - Display version, gui and env location in about ([`cf879ee`](https://gitea.psi.ch/mx/AareDAQ/commit/cf879ee2a5606415a6610a80c8f89dc4be48a89f)) - Live changes 26-07-06 ([`b0b655a`](https://gitea.psi.ch/mx/AareDAQ/commit/b0b655aea0355eb2441eaf1093534561f028e7a3)) ### Refactoring - Move qt logging to gui module ([`8f0a853`](https://gitea.psi.ch/mx/AareDAQ/commit/8f0a85316d7e6e313d09bf5f95c99a1fe0a0a5af)) - Use aarecommon and remove common ([`13bddd4`](https://gitea.psi.ch/mx/AareDAQ/commit/13bddd43c7c36624f6e93e2718d82439d39809ff)) ### Testing - Corrected test for aaredb to use db_id ([`f05ab28`](https://gitea.psi.ch/mx/AareDAQ/commit/f05ab282405780844de76156122c2c3daea642bf)) - Fixed bug in workflow test ([`95384d1`](https://gitea.psi.ch/mx/AareDAQ/commit/95384d175a0277277ca33ad5c114e6b04797692f))