Add an opt-in TCP/NDJSON inspector for running eepp applications. It
provides authenticated, UI-thread-safe access to windows, scenes, and
widgets, including nested WebView documents. The v1 protocol supports
queries, trees, properties, focus, input actions, watches, screenshots,
and composed batches with result references and deferred execution.
Add a standard-library Python CLI, protocol documentation, build
entries, and integration tests. The listener remains disabled unless
explicitly enabled.
Fix HTML compatibility issues found while debugging NewsBlur:
- Let explicit flex minimums, including min-width: 0, replace the
automatic content minimum.
- Measure flex lines against the container content box when padding
and explicit dimensions are present.
- Keep promoted positioned descendants of hidden ancestors out of
the paint list.
An embedded UI scene can leave the host event dispatcher pointing to it after teardown. With hidden windows starting the mouse at (0, 0), the next update can call onMouseLeave on the destroyed scene and crash.
Clear hover, focus, and mouse-down references before detaching the shared dispatcher.
Verified with 20 runs of UIWebView.DestroyWithPendingSubresourcesIsSafe and the full macOS release suite (1,310 tests).
Add a View menu toggle, keyboard shortcut, and --zen-mode option.
Hide the side panel, status bar, menu controls, tab bar, and document
info while Zen Mode is active, then restore configured visibility.
Add the menu label to all locale catalogs. Refs SpartanJ/ecode#964.
Test stability
test(ui): stabilize visual tests and Windows clipboard assertions
Initialize hidden SDL windows with an internal mouse position of (0, 0)
so desktop cursor hover cannot affect visual tests. Assert this in
complexLayout3 and normalize Windows clipboard line endings in the
Markdown selection test.
Allow each LineSeries to fill down to the plot’s bottom edge, using a translucent version of its line color by default or a custom fill color. Render overlapping fills beneath the strokes, document the new API, and demonstrate it in the charts example. Add coverage for blending, data gaps, and toggling fills.
Introduce UITextSelectionController to coordinate selection across independent
RichText owners while retaining RichText hit testing and painting. Support
forward and reverse dragging, nested content, gap hit testing, autoscroll,
plain-text copy, select-all, and context menus.
Enable UIRichText and UITextSpan selection by default. Add CSS user-select
semantics and the -webkit-user-select alias, while preserving the separate
text-selection capability flag.
Clear selection safely when owners or documents are destroyed, suppress link
activation after a selection drag, and add regression tests, documentation,
and an updated rich-text example.
- Add persistent eproc settings for refresh interval, appearance, fonts,
and renderer options, with a settings button in the main window.
- Collect per-core CPU usage on macOS and FreeBSD for Performance charts.
- Keep the settings search focused in eproc and eterm, and wrap long
setting names.
- Share macOS theme-colored titlebar handling across ecode, eproc,
and eterm.
- Stabilize fixed-size UI tests on Retina displays and prevent macOS
build scripts from starting unlimited jobs when sysctl fails.
Use Breeze theme colors for eproc's process table and Performance charts,
while preserving the translucent Username colors. Keep process icons
visible in the light theme with a white tint.
Add eproc CLI options for font hinting, font antialiasing, and color scheme.
Add -c/--prefers-color-scheme to eterm and retain close-on-exit through
its long options.
Support EEPP_FONT_HINTING, EEPP_FONT_ANTIALIASING, and EEPP_COLOR_SCHEME
across eepp UI apps, with valid environment values taking precedence
over application settings. Document and test the overrides.
Show local branches without a matching fetched remote ref as local only.
Match binary rename paths in Git numstat output to staged files so they
do not appear as untracked. Add regression coverage for rename paths
and filenames containing " => "
- Add CPU, memory, GPU, and network charts with ten-minute history,
a 60-second view, clickable cards, and overall or per-core CPU views.
- Add Family Memory and Family Memory % to both process views. Use
proportional memory on Linux, count zero-memory zombies correctly,
and collect the data after the first frame without delaying it.
- Add column tooltips, rename Total Memory to Resident Memory, keep
Command last by default, and migrate saved column layouts.
- Enable sorting within each tree level and preserve selection.
- Improve eepp chart margins and sorting behavior, and document UIChart.
- Add configurable vertical and horizontal grids with axis tick, data,
and screen spacing modes.
- Add monotone cubic line smoothing and angled X-axis tick labels.
- Return references for chart APIs that always have a result, and document
model ownership and borrowed references.
- Prevent empty tooltips and refresh chart hover when live data changes
under a stationary cursor.
- Update the charts example and add rendering and tooltip regression tests.
- Honor EEPP_PIXEL_DENSITY when an app has not specified a scale,
without resizing its window.
- Scale chart measurements in dp, expose chart styling, and resolve
default colors through the UI theme.
- Fix gaps at miter joins and round chart text to device pixels.
- Use inline storage for common chart axis, series, and label counts.
- Add density and rendering regression tests.
Implement chart axes, line series, data sources, pixel-bucket reduction,
tooltips, and pan, zoom, fit, and live-follow interactions. Register Chart
as a default UI widget and expose the new APIs through ui.hpp.
Add a responsive four-chart example, benchmarks, and unit tests. Reuse
rendering buffers and fix ring-buffer rendering and hover tooltip behavior.
Use KERN_PROC_PROC so eproc shows one row per process instead of one
row per thread.
Select clang by default in Premake 4 and 5, add the required FreeBSD
library paths and links, and remove redundant CI compiler overrides.
Fix the Premake 4 BSD SONAME rule so eproc can find libeepp.so when
launched from the repository root.
- Collect process and system metrics on macOS and FreeBSD.
- Resolve macOS app icons and share the XDG icon resolver between Linux and FreeBSD.
- Hide unavailable columns, label resident memory “Real Mem” on macOS, and scale row height with pixel density.
- Fix Premake filters and add macOS collector tests.
Add process columns, GPU metrics, tree mode, multi-process actions,
GUI and tray detection, and persistent filter and table settings.
Add optional column header reordering to eepp table and tree views.
Keep dragged headers in place during refresh and draw them above other
headers. Preserve row selection when sorting and when opening context
menus, and support application items in header context menus.
Refresh eepp and tool icons and add the icon generation script.
Add tests for the process views, icon decoding, and GUI table behavior.
Handle document reload events in the Git plugin, since reloading replaces
the document lines without emitting a text-changed event.
Clear stale gutter and minimap markers, invalidate in-flight diff results,
and compare the reloaded contents against the existing Git baseline.
* Fix UICodeEditorSplitter dropping its widget listeners on tab moves:
UITabWidget reports drag & drop transfers as OnTabClosed + OnTabAdded,
so treating OnTabClosed as "left the splitter" permanently unhooked the
moved widget and left mCurEditor/mCurWidget tracking nothing
(SpartanJ/ecode#958).
* Tie splitter-owned callbacks to splitter membership: attach on
OnTabAdded of managed tab widgets, detach on OnTabClosed. Creation and
transfer now share one registration path; moves to external tab
widgets stay detached.
* Keep mEditorSelections for the editor lifetime instead of the tab
membership lifetime: it survives split moves and is cleared from the
editor OnClose callback, which is disconnected in the splitter
destructor so outliving editors cannot call into a destroyed splitter.
* Apply the same ownership model to UITabWidgetSplitter, which had the
inverse bug: widgets dragged out kept notifying the splitter through
stale connections; drop the duplicated closeTab() cleanup.
* Store listeners as Scene::EventConnection/List (RAII disconnect)
instead of std::vector<Uint32> + removeEventListener bookkeeping.
* Add regression tests covering editor and generic widget moves between
splits, in and out of the splitter, focus/title tracking after each
transition, selection cache survival, and editor destruction cleanup.
* Serialize tracked realloc and free bookkeeping to prevent cross-thread
address reuse from corrupting the memory tracker during tab teardown.
* Add concurrent allocation and terminal close/resize regression coverage.
* Install a macOS-only File, Edit, and Window menu that mirrors eterm
keybindings without binding Cmd+W.
* Keep the native menu outside the splitter layout and document the canonical
macOS build workflow.
Compute document line changes asynchronously against the repository
baseline and render added, modified, and removed markers in the editor
gutter and minimap.
Keep diff indicators disabled by default to avoid unexpected background
work. Add settings for enabling them and configuring the debounce delay,
with translations for all supported locales.
Handle fully added files, stale asynchronous results, document lifetime,
repository changes, and unsaved edits. Add focused Git diff and document
serialization regression coverage.
Vendor a reduced simdutf build and use it to accelerate String UTF-8 and
UTF-32 conversion and codepoint counting. Preserve efficient scalar and
cached-ASCII paths while reusing output storage for document snapshots.
Add simdutf to the Premake 4, Premake 5, and Android builds.
Fix UIConsole wheel and keyboard scrolling, and repair its text cache by
hashing log entries before moving their strings. Initialize cache hashes
and add regression coverage for scrolling and moved log entries.
Preserve debugger response data when notifying multiple listeners by
copying for all but the final listener. Remove an evaluation-order hazard
when capturing and submitting URIs for asynchronous document loading.
Refs SpartanJ/ecode#955.
Replace Variant's heap-owned payloads with manually managed inline
storage while preserving its return-by-value API.
- inline std::string, String, DrawablePtr, Vector2f, and Rectf
- add move construction and capacity-preserving assignment
- add explicit borrowed std::string support and string views
- avoid redundant conversions in table and tree hot paths
- borrow stable process fields in eproc
- eliminate per-frame eproc class allocation churn
- focus the eproc search input on startup
- add comprehensive Variant lifecycle and ownership tests
Snapshot document search state before dispatching highlight workers and
retain the searched document for the duration of each job.
Publish results through MainThreadLifetime and reject results when the
editor has changed document or search parameters. Remove the obsolete
worker counter and destructor wait used for editor lifetime management.
Use atomic cancellation flags in TextDocument::findAll() and protect
active-search map inspection during destruction.
Add regression coverage for concurrent cancellation, stale highlight
results, rapid backtick searches after a large multiline paste, and
editor destruction during active search.
Refs SpartanJ/ecode#956.
- Centralized .gitignore, .prjallowed, and .prjdisallowed filtering in src/tools/ecode/projectdirectorytree.cpp:392.
- Live directories now require an already-admitted parent and use (parentDirectory, filename) matching before insertion.
- Live file additions use the same shared filtering.
- Newly admitted directories still load their own nested .gitignore before recursive scanning.
- Added eight direct regression tests in src/tests/unit_tests/projectdirectorytree_tests.cpp:84.
- Added the required ecode sources to both Premake unit-test targets.
- No FileSystemListener changes; directory moves remain outside this Add-focused patch.
- Context menu issue cause was terminal focus reporting: Codex enables focus events, and opening the popup sent ESC [ O through the ordinary input path, which scrolls to the bottom. Focus reports now use the non-scrolling protocol-write path while still reaching the application correctly.
- Add the eproc process-monitoring application and persistent window/table state
- Implement Linux process, network, GPU, icon, and GUI-window collection
- Add optional process columns, styling, i18n-ready strings, and command copying
- Retain exited processes for one update and color them as ended
- Extend table sizing and header behavior for persisted column layouts
- Organize Linux-specific sources under platform/linux
- Keep unsupported platforms buildable with a startup WIP warning
Reuse RegEx match data and bound the pattern cache.
lTrim and rTrim returned an all-separator string unchanged where trim() returns empty;
all sixteen overloads now drop everything when no non-separator is left.
readBySeparator handed the callback one empty chunk for an empty buffer; it hands none
now, as the UTF-32 overloads already did.
RegEx::matches allocated its match data per call, four allocations per row while
filtering over a table. It is created once per object now, held by a unique_ptr whose
deleter knows the engine, so the destructor no longer repeats that split. RegEx is
movable but not copyable: it was implicitly copyable while owning that block, and a
copy taken after a match released it twice. syntaxtokenizer.cpp was copying its
std::variant temporary because the user-declared destructor suppressed the implicit
move; it moves now.
RegExCache held two unordered_maps, hash to pattern and hash to options, and never
evicted. It is one DynamicLRU<8192, size_t, shared_ptr<void>> now: the engine lives in
each pattern's deleter so the options map is gone, and values own the pattern, because
an eviction must not free one a live RegEx is still matching with. That also fixes a
racing insert that leaked the loser's pattern. The bound leaves ample room over the
working set and cache hits stay allocation-free (0 new, 0 malloc per 1000
constructions). New tests: lTrimAndRTrim, readBySeparator, splitCb, cacheIsBounded.
Release and AddressSanitizer suites pass 1216 tests each.
String::trim: when the input consisted only of separators, both find_first_not_of
and find_last_not_of returned npos and the pos2 fallback computed length() - 1, so
trim(" ") returned " " and every all-separator value came back one character
shorter instead of empty, making an all-whitespace value look non-empty to callers.
All eight overloads were affected: std::string, std::string_view, String and
String::View, in their char and separator-set forms. Return an empty result when
there is no non-separator, and compute the trimmed range as
substr(pos1, pos2 - pos1 + 1).
RegEx: mCompiledPattern stores whichever engine compiled the pattern, a pcre2_code*
or an OnigRegex, but the destructor released it with pcre2_code_free() whenever
RegExCache did not own it. With useCache = false that freed an Oniguruma pattern as
a PCRE2 block, which corrupts the heap: constructing and destroying such a RegEx
crashes with SIGSEGV, a path snippetparser.cpp reaches by passing Utf |
AllowFallback with useCache = false. Release the pattern with the deallocator of the
engine recorded in Options::UseOniguruma, the predicate matches(), getCaptureCount()
and RegExCache::clear() already use, and remove the mOnigEngine flag, which was
never set or read anywhere.
Both fixes come with regression tests. String.trim covers the all-separator boundary
and the trimmed range of every overload. RegExEngines.uncachedPatternIsFreedByItsOwnEngine
destroys uncached patterns from both engines; it crashed the test binary before the fix.
Read application cursor, keypad, and NumLock state from the worker display
when encoding mapped keys. These are display modes rather than terminal text
modes, so checking mTerm.mode caused full-screen applications such as htop
and nvtop to receive normal cursor sequences instead of application-mode
sequences.
Add regression coverage for application-mode Up and Down keys.
eterm:
- derive scroll and history notifications from adopted snapshots instead
of delayed worker events
- prevent PTY parsing from publishing its temporary live-buffer viewport
- restore scrollback correctly when new output wraps the history ring
- keep selections attached to their text during output and absolute scrolling
- preserve terminal focus and selection while interacting with the scrollbar
- keep the scrollbar available while a selection is active
- suppress application mouse reports when Shift overrides mouse capture
- preserve scrollback when Kitty reports standalone modifier keys
- retain scroll-to-bottom behavior for regular and modified input keys
- remove obsolete worker scroll and history event tracking
- add regression coverage for viewport, selection, focus, keyboard, and
history behaviord selection synchronization
Add an EE::System::FileAssociation abstraction with XDG, Windows,
and macOS implementations.
Expose extensions from syntax predefinitions and add custom widget
support to UISettingsPanel. Add an ecode settings page for selecting
file associations and installing an XDG desktop entry.
Apply changes asynchronously with lifecycle-safe UI handling, disable
controls while applying, and avoid redundant XDG database updates.
Add translations and coverage for the new functionality.
Implements SpartanJ/ecode#192
eterm:
- render the active match with palette yellow and black text
- use translucent palette yellow for inactive matches
- share search color handling across all terminal rendering paths
- collect the complete visible range of wrapped active matches
- move the find bar below matches in either of the first two rows
- remove unreliable horizontal overlap checks from find bar placement
eterm:
- expose the visible active terminal search range
- move the find bar below first-row matches it would otherwise occlude
- restore the top-right position when no overlap exists
- recalculate find bar placement when the terminal is resized
- clip animated find bar content to the terminal bounds
- serialize and tag visibility transitions to prevent conflicting actions
Add an explicit Plugin::shutdown() phase that removes all application-facing
state while the complete plugin type is still alive. Detach editor and
document commands, listeners, clients, UI objects, and queued callbacks on
the main thread before scheduling resource-only destruction on a worker.
Move plugin-specific cleanup into unregisterEditors() and the PluginBase
unregister hooks. Keep potentially blocking cleanup, such as stopping LSP
servers or joining workers, in destructors so normal plugin unload does not
stall the UI.
Stop plugin reloads, broadcasts, late ready callbacks, and unlocked command
dispatch once application closing begins. During final shutdown, unload
plugins synchronously and wait for any previously queued destruction.
Document the Plugin and PluginBase lifecycle, cleanup checklist, and a
complete implementation example.
Previously, plugin destructors could mutate editor and UI state from a worker
thread, while destructor-time virtual dispatch skipped derived unregister
logic. This could leave commands capturing a destroyed plugin instance or
race registrations from a newly loaded generation. A queued key event during
application close could then execute one of these stale callbacks and jump to
invalid memory.