The previous blit path converted the whole axes bbox (several megapixels
on HiDPI displays) from RGBA to premultiplied ARGB on every motion
event, costing about 84 ms per frame on a maximized window. Per frame
now only the thin strips around the old and new line positions are
erased from a cached full-figure background, redrawn and blitted,
which brings the frame cost below 1 ms.
- BlitSafeCanvas paints blitted regions immediately instead of queueing
them, which kept regular paints partial and wiped the axis labels
- CrosshairCursor coalesces motion events to 60 fps and erases strips
by direct numpy copy from the background; matplotlib's restore_region
with a bbox argument addresses a different coordinate frame and
restores the wrong area, so it is avoided
- after a full render the old line positions are blitted right away,
otherwise motion events processed before the pending repaint drew the
cursor at its new position next to the stale one on screen
- clear_display recreates the crosshair so it survives plot switches
Generated by Mistral Vibe.
Co-Authored-By: Mistral Vibe <vibe@mistral.ai>
The crosshair toggle button loaded the "crosshairs" icon from the
icon theme inside a bare try/except, so on systems without that
icon the button was empty and invisible. Replace it with a
self-contained red reticle (circle, center dot, cross arms) drawn
from inline XPM data, and set always-show-image so the desktop
default gtk-button-images=False cannot hide it.
Generated by Mistral Vibe.
Co-Authored-By: Mistral Vibe <vibe@mistral.ai>
- debian/rules: build sphinx HTML into build/html
- debian/install: install it as usr/share/doc/python3-damaris/html/
instead of shipping the raw doc/ source tree (whose gitignored
doc/_build never existed on CI checkouts)
- debian/control: declare ${sphinxdoc:Depends} and python3-sphinx
(provides sphinx-build) explicitly
- requirements.debian: install python3-sphinx explicitly
- DamarisGUI: point the manual at the packaged HTML path with a
source-tree fallback, populate the Help dropdown menu, and open
the DAMARIS manual on a plain toolbar click
- doc/manual.rst: document the Help menu
Generated by Mistral Vibe.
Co-Authored-By: Mistral Vibe <vibe@mistral.ai>
FitResult is a new Drawable in damaris.data with x-values independent of
the measured points, so fits can be sampled on a dense grid. It is stored
as its own data pool entry (e.g. "measurement/fit"), written to and read
from the HDF5 data pool (damaris_type "FitResult", params as attributes),
and drawn by the GUI as overlay on its measurement, including a fit
parameter text box. Fits get no entry in the display tree, so measurement
rows stay directly selectable. Result scripts create them via
FitResult(x, y, title, source, params).
Additionally, HDF5 files that experiment or result scripts left open
(e.g. after a script failure) are closed when the experiment stops.
pytables keeps such handles registered process-wide, which blocked
reopening the dump file and the scripts' own files on the next run.
Generated by Mistral Vibe.
Co-Authored-By: Mistral Vibe <vibe@mistral.ai>
Removing gobject.type_register(GtkSource.View) broke startup: the
call was load-bearing, it forced registration of the GtkSourceView
GType so GtkBuilder could resolve the type in damaris3.glade
("Invalid object type 'GtkSourceView'"). Restore the registration
by referencing gtksourceview.View at import time, which is the
same effect without the PyGTK compat API.
Generated by Mistral Vibe.
Co-Authored-By: Mistral Vibe <vibe@mistral.ai>
- raise instead of silent None for unsupported operands and empty negation
- validate before acquiring lock in Accumulation operators (no RLock leak)
- Accumulation._copy_provenance helper, ADC_Result._copy_metadata for all result paths
- shared _sandbox_stdout_redirect contextmanager for sandboxed scripts
- TemperatureMonitor dead code removal (gtk helper, traceback, unused properties)
- new unit tests incl. lock-freedom regression test
- gitignore sphinx generated doc/_autosummary/ and doc/damaris/
set_active_text() does not exist in GTK 3.24.x (only in GTK 4.x).
When loading a saved config with temperature_controller_type='simulated',
the set() method crashed on startup with AttributeError.
Added _set_combo_active_text() helper that iterates the model to find
the matching entry and calls set_active(index) instead.