The BOM revision in IPC-2581 export was hardcoded to "1.0"
instead of reflecting the actual design revision.
The project file stores two separate fields: bomRev for
explicit user overrides set in the PCBnew export dialog or
via --bom-rev on the CLI, and schRevision for the value
auto-propagated from eeschema.
When the GPU context is invalidated by sleep/wake or a driver
reset, glMapBuffer fails with GL_OUT_OF_MEMORY and the renderer
permanently falls back to Cairo. Instead, attempt a full OpenGL
GAL reinit once before giving up. SwitchBackend recreates all
GPU resources and SetGAL triggers clearGroupCache so every
cached item is regenerated on the next frame. A flag prevents
infinite retry loops and resets after each successful paint.
LAYER_RANGE enters an infinite loop when constructed with
layer_count < 2. The next_layer() arithmetic underflows,
producing unreachable termination values, so the iterator
increments forever. This happens during board import when a
file produces a board with zero copper layers.
Clamp layer_count to a minimum of 2 in the LAYER_RANGE
constructor since F_Cu and B_Cu are always present.
Add content validation to the Fabmaster plugin, which
previously accepted any .txt file based on extension alone.
CanReadBoard now scans for !-delimited rows containing
known Fabmaster column headers before claiming the file.
Background library loading threads call GetRow() through
loadFromScope(), which writes to m_rowCache concurrently
with the main thread clearing it in loadTables(). The
unsynchronized access corrupts the map's red-black tree,
causing a double-free crash when switching projects.
Add m_rowCacheMutex to protect all m_rowCache accesses.
Also replace std::tie with std::make_tuple to avoid
unnecessary temporary conversions, and use a single
find() instead of contains() followed by at().
Add an aAllowSkip parameter to DoRePaint that gates both skip
checks. onPaint and ForceRefresh pass false so they always
execute the full GL/Cairo cycle. The rate-limited Refresh path
continues to pass true (the default), preserving the GPU
utilization improvement from b728c08b7a.
Fixes https://gitlab.com/kicad/code/kicad/-/issues/23325
Initializing m_last to time_point::min() causes signed integer
overflow when computing now - m_last, since the nanosecond
difference exceeds int64_t range. Initialize to now - interval
instead so the first Ready() call passes naturally.
Add m_hasPendingItemUpdates to VIEW so UpdateItems() can
return immediately when no item has queued update flags.
The flag is set wherever m_requiredUpdate is modified and
cleared at the end of UpdateItems().
In DoRePaint(), check the new flag alongside IsDirty() and
cursor movement to skip both item processing and the GL
draw cycle when nothing has changed. Route onPaint through
Refresh() so the existing frame-rate throttle applies to
native paint events as well.
Five call sites independently reimplemented the same
time-gated throttle pattern. This consolidates them all
into a single THROTTLE class backed by steady_clock.
Three call sites duplicated the wxWidgets YieldFor workaround
for timer-event backlog (wxWidgets issue #26192). This replaces them
with a shared DrainPendingEvents free function.
PG_FPID_EDITOR is registered in wxPropertyGrid's global editor
registry and persists across SCH_PROPERTIES_PANEL lifetimes.
UpdateFrame() didn't update the netlist callback lambda.
To fix this, we add an UpdateCallback() to PG_FPID_EDITOR and
call it alongside UpdateFrame() when reusing an existing
editor instance.
Fixes https://gitlab.com/kicad/code/kicad/-/issues/23307
Update zone manager to improve usability. Filter zones based on layers,
provide move to top/move to bottom actions, global arrow key navigation,
zoom preservation across zone switches, right-click zoom-to-fit on the
preview canvas, and pixel-aligned icons for top/bottom move buttons.
The matched length diff pair panel had skew data in the constraint class
but no UI field to display or edit it. Added a dedicated overlay panel
with min/opt/max length plus max skew fields, a new bitmap showing a
diff pair with length arrows and skew indicator.
Move onUpdateUI from public to private in EDA_BASE_FRAME since
it is an internal event handler bound via Bind(), not part of
the public API.
Capture the empty-check result before erasing rows in
library_manager.cpp to avoid using invalidated iterators from
the subrange returned by std::ranges::remove_if.
Add null guards to the netHighlightCond toolbar condition
lambda in PCB_EDIT_FRAME to prevent null dereference during
shutdown, matching the pattern used by other toolbar
conditions fixed in f962de966b.
SearchDynamicEventTable does a linear scan through all dynamic
Bind entries for every dispatched event, regardless of event type.
Replace the per-action Bind() calls with a single wxID_ANY handler
that dispatches to the existing m_uiUpdateMap through a hash map.
This reduces the per-event scan from around 150 to about 1 for all
event types. This is particularly noticeable during high frequency
events like mouse drag.
The default constructor of RULE_EDITOR_DATA_BASE left m_isNew
uninitialized. On Linux, the garbage memory value was assigned
causing IsNew() to return true for every rule and appending
astersix to all tree items.
Fix by adding a default member initializer: m_isNew = false.
Clicking on rules in the tree created a wxDragImage each time, which on
macOS opens a hidden full-screen window. These windows were never cleaned
up and piled up as ghost windows in Mission Control.
Removed wxDragImage and replaced drag feedback with a highlight
on the drop target item.
The previous 1 MB limit caused "Maximum line length exceeded" errors
when loading schematics containing large embedded images or other long
quoted tokens. The S-expression parser (DSNLEXER) requires entire
quoted strings to fit within a single line buffer, so Prettify cannot
split them across lines. Raise the limit from 1 MB to 16 MB and add
regression tests.
Fixes https://gitlab.com/kicad/code/kicad/-/issues/23162
Merge Minimum uVia Hole and Minimum uVia Diameter constraints
into the existing Via Style panel. Remove unused optimum/preferred
diameter and hole size fields.
Add a via type dropdown (Any/Through/Micro/Blind/Buried) used to
generate the appropriate A.Via_Type condition clause in the DRC.
Strip the via type condition on rule load to prevent duplication
on save cycles.
The DXF exporter was missing the $INSUNITS header variable, which tells
CAD software what physical units the drawing coordinates represent. Without
it, other programs have no reliable way to determine the coordinate scale.
Add $INSUNITS to the HEADER section alongside the existing $MEASUREMENT
variable. When exporting in millimeters, $INSUNITS is set to 4; when
exporting in inches, it is set to 1.
Fixes https://gitlab.com/kicad/code/kicad/-/issues/23181
GAL::computeWorldScale() called Pgm() unconditionally, which
crashes with SIGSEGV when running from standalone Python where
PGM_BASE is never initialized. This affected all non-PDF plot
formats (DXF, SVG, Gerber) because they render text through
CALLBACK_GAL, whose base GAL constructor calls computeWorldScale().
PDF was unaffected because it has its own native text rendering
that never creates a CALLBACK_GAL.
Use PgmOrNull() instead
Fixes https://gitlab.com/kicad/code/kicad/-/issues/23171
The angle is stored internally in decidegrees but was read and
written without applying the required scale factor in two places.
Also adds missing includes to toolbars_pcb_editor.cpp to fix a
build failure from 855c996475.
Fixes: https://gitlab.com/kicad/code/kicad/-/issues/23134
When the user imported settings from a previous version during the
startup wizard, the settings provider's Finish() reloaded all settings
from the migrated files. This changed the in-memory state so
data_collection_prompt became true (from the old version). The Finish
loop then re-evaluated NeedsUserInput() for each provider, causing
the privacy provider to be skipped
Fix this by tracking which providers had their wizard pages shown
using a flag
Fixes https://gitlab.com/kicad/code/kicad/-/issues/23051
Update constraint SVG source files to use the standard KiCad color
palette, reposition textboxes, and add missing eda_text.h include
in toolbars_pcb_editor.cpp
This allows us to pick GLX on X11 and EGL on Wayland
at runtime when building with wxWidgets 3.3.2+
GLEW only allowed to choose between GLX/EGL at compile time.
This also removes KICAD_USE_EGL option, KiCad will use
whatever wxWidgets was built with.
Fixes https://gitlab.com/kicad/code/kicad/-/issues/20647
Remove MINIMUM_TRACK_WIDTH, BASIC_CLEARANCE, BOARD_OUTLINE_CLEARANCE,
and MINIMUM_ITEM_CLEARANCE panels from the DRC rule editor. These were
redundant with ROUTING_WIDTH, MINIMUM_CLEARANCE, COPPER_TO_EDGE_CLEARANCE,
and SILK_TO_SILK_CLEARANCE respectively. Rename the minimum_item_clearance
bitmap to silk_to_silk_clearance and assign it to the silk clearance panel.
Revert matcher claim changes for HOLE_SIZE and MINIMUM_VIA_DIAMETER.
DIALOG_SHIM::Show() and finishDialogSettings() both
call SetSizeHints(), which computes the best size from
the full unconstrained scrolled content area. This
inflated the dialog to unusable heights.
Move size correction logic into the base class by
overriding Show() to cap minimum height at 500px and
resetting to m_initialSize after finishDialogSettings().
Remove the duplicate size fixups from the derived DRC
editor's TransferDataToWindow(). Increase default
initial height from 680 to 800.
On mixed-DPI multi-monitor setups, dialog sizes grow each time they are
reopened because logical pixel values change when a window moves between
monitors with different scaling factors. The std::max comparison during
restore guarantees monotonic growth since the DPI-scaled value always
exceeds the previously saved unscaled value.
Store width and height as DIP (device-independent pixels) using ToDIP()
on save and FromDIP() on restore. This makes the persisted size stable
regardless of which monitor the dialog was on when closed. A "dip" flag
in the JSON differentiates new DIP-format values from legacy logical
pixel values, which are converted in place on first load.
Fixes https://gitlab.com/kicad/code/kicad/-/issues/20120
Remove 15 BITMAPS enum values that have no registered image data
in bitmap_info.cpp and no remaining code references. These were
placeholders for constraint types that either never got SVG artwork
or used different naming than the generated bitmaps.
Removed: constraint_net_antenna, constraint_short_circuit,
constraint_unrouted, constraint_allow_fillet_outside_zone_outline,
constraint_silk_to_silk_clearance, constraint_minimum_acute_angle,
constraint_matched_length_all_traces_in_group,
constraint_absolute_length, constraint_parallel_limit,
constraint_daisy_chain_stub, constraint_daisy_chain_stub_2,
constraint_corner_style, constraint_smd_corner,
constraint_smd_entry, constraint_smd_to_plane_plus
Remove stale m_ShowRepairSchematic member from
advanced_config.h left behind when RepairSchematic() was
retired. Remove unnecessary const_cast in wxExecute call
in jobs_runner.cpp. Fix stray semicolon after return in
pcb_barcode.cpp and use >= ZINT_ERROR instead of truthiness
for the ZBarcode_Buffer_Vector return check.
When a dialog closes with the mouse hovering over an auxiliary panel
(e.g. the properties panel), focus would land on that panel instead
of the drawing canvas, breaking hotkey operation until the user moved
the mouse back over the canvas.
Set focus directly on the parent frame's tool canvas when closing
dialogs via Show(false) and ShowQuasiModal(), falling back to the
parent window when no canvas is available.
Fixes https://gitlab.com/kicad/code/kicad/-/issues/20926
Wrap the right side content area in a wxScrolledWindow so that rule
panels remain accessible when many constraints are added.
RefreshContentScrollArea() function is called on resize,
rule switch and and dynamic condition changes.
PCB_REFERENCE_IMAGE::Flip() was the only board item type that did not
call SetLayer(GetBoard()->FlipLayer(GetLayer())) during a flip operation.
Also avoids expensive re-encoding and wxBitmap rebuid processes to speed
up swapping
Fixes https://gitlab.com/kicad/code/kicad/-/issues/23059
The GAL draw panel was rendering far more frames than needed, causing
100% GPU utilization on systems where vsync was unavailable or disabled.
Three changes address this:
Refresh() now enforces a minimum period between renders. With vsync
active the guard is 3ms (the driver throttles via SwapBuffers). Without
vsync a 16ms floor caps rendering at 60 FPS, preventing GPU saturation.
DoRePaint() tracks the cursor position and skips the entire GL cycle
when neither the view is clean and the cursor doesn't move
OnEvent() delegates directly to the rate-limited Refresh() instead of
maintaining its own adaptive throttle with a RequestRefresh() idle
fallback that fired immediately and provided no actual throttling.
Fixes https://gitlab.com/kicad/code/kicad/-/issues/19112