New features - #527
Open
zaum wants to merge 26 commits into
Open
New features#527zaum wants to merge 26 commits into
zaum wants to merge 26 commits into
Conversation
Collaborator
|
@copilot resolve the merge conflicts in this pull request |
There was a problem hiding this comment.
Pull request overview
This PR modernizes Angry IP Scanner’s UI layer by migrating from SWT to JavaFX, while adding several UX/features around comments, openers, and column management, plus moving some user settings from Java Preferences into plain files under a portable config directory.
Changes:
- Replace the SWT GUI stack with a JavaFX-based GUI (
net.azib.ipscan.gui.fx.*), updating app startup and DI registration accordingly. - Add file-backed persistence for user data/config (portable
config/dir near the app, comments stored incomments.txt, per-IP default openers stored inopeners-defaults.txt). - Add “default opener per IP” functionality, including opener-related fetchers and UI hooks for setting/launching.
Reviewed changes
Copilot reviewed 124 out of 130 changed files in this pull request and generated 6 comments.
Show a summary per file
| File | Description |
|---|---|
| test/net/azib/ipscan/gui/SWTTestCase.java | Removed SWT test base class as part of SWT deprecation. |
| test/net/azib/ipscan/gui/StatisticsDialogTest.java | Removed SWT StatisticsDialog test (dialog removed). |
| test/net/azib/ipscan/gui/SelectFetchersDialogTest.java | Removed test for removed SWT dialog. |
| test/net/azib/ipscan/gui/PreferencesDialogTest.java | Removed SWT preferences dialog tests. |
| test/net/azib/ipscan/gui/InputDialogTest.java | Removed SWT input dialog tests. |
| test/net/azib/ipscan/gui/GUITest.java | Removed SWT GUI error-localization test (SWT GUI removed). |
| test/net/azib/ipscan/gui/fetchers/PortTextFetcherPrefsTest.java | Removed tests tied to removed SWT fetcher prefs UI. |
| test/net/azib/ipscan/gui/feeders/FeederGUIRegistryTest.java | Replaced SWT GUI registry tests with minimal RangeFeeder assertions (misnamed now). |
| test/net/azib/ipscan/gui/feeders/AbstractFeederGUITest.java | Updated feeder GUI test to target FX feeder GUI base class. |
| test/net/azib/ipscan/gui/actions/StartStopScanningActionTest.java | Removed SWT action test. |
| test/net/azib/ipscan/gui/actions/OpenerLauncherTest.java | Removed SWT opener launcher tests (launcher removed/ported). |
| test/net/azib/ipscan/gui/actions/GotoActionsTest.java | Removed SWT go-to actions tests. |
| test/net/azib/ipscan/fetchers/FetcherRegistryTest.java | Updated for FetcherRegistry constructor signature changes. |
| test/net/azib/ipscan/exporters/TXTExporterTest.java | Updated TXT import test API from GUI feeder to FeederCreator; improved resource path handling. |
| test/net/azib/ipscan/config/GUIConfigTest.java | Updated to match GUIConfig’s new int[] sizing fields (no SWT Point). |
| test/net/azib/ipscan/config/ComponentRegistryTest.java | Removed SWT-dependent DI instantiation test. |
| src/net/azib/ipscan/util/GoogleAnalytics.java | Removed SWT-specific exception code handling from stack extraction. |
| src/net/azib/ipscan/Main.java | Switched app startup to JavaFX (FXGUI) and simplified error fallback behavior. |
| src/net/azib/ipscan/gui/util/LayoutHelper.java | Deleted SWT layout/icon helper. |
| src/net/azib/ipscan/gui/SWTAwareStateMachine.java | Deleted SWT-thread marshalling state machine. |
| src/net/azib/ipscan/gui/StatusBar.java | Deleted SWT status bar (replaced by FXStatusBar). |
| src/net/azib/ipscan/gui/StatisticsDialog.java | Deleted SWT statistics dialog. |
| src/net/azib/ipscan/gui/Startup.java | Deleted SWT startup flow (FX TODO remains). |
| src/net/azib/ipscan/gui/SelectFetchersDialog.java | Deleted SWT fetcher selection dialog. |
| src/net/azib/ipscan/gui/menu/ToolsMenu.java | Deleted SWT tools menu implementation. |
| src/net/azib/ipscan/gui/menu/ScanMenu.java | Deleted SWT scan menu implementation. |
| src/net/azib/ipscan/gui/menu/ResultsContextMenu.java | Deleted SWT results context menu wrapper. |
| src/net/azib/ipscan/gui/menu/OpenersMenu.java | Deleted SWT openers menu wrapper. |
| src/net/azib/ipscan/gui/menu/OpenersContextMenu.java | Deleted SWT openers context menu wrapper. |
| src/net/azib/ipscan/gui/menu/HelpMenu.java | Deleted SWT help menu implementation. |
| src/net/azib/ipscan/gui/menu/GotoMenu.java | Deleted SWT goto menu implementation. |
| src/net/azib/ipscan/gui/menu/FavoritesMenu.java | Deleted SWT favorites menu implementation. |
| src/net/azib/ipscan/gui/menu/ExtendableMenu.java | Deleted SWT menu base class. |
| src/net/azib/ipscan/gui/menu/CommandsMenu.java | Deleted SWT commands menu implementation. |
| src/net/azib/ipscan/gui/menu/ColumnsMenu.java | Deleted SWT columns menu implementation. |
| src/net/azib/ipscan/gui/menu/AbstractMenu.java | Deleted SWT abstract menu base class. |
| src/net/azib/ipscan/gui/MainMenu.java | Deleted SWT main menu wiring and enable/disable logic. |
| src/net/azib/ipscan/gui/MacApplicationMenu.java | Deleted SWT Mac application menu integration. |
| src/net/azib/ipscan/gui/InputDialog.java | Deleted SWT input dialog. |
| src/net/azib/ipscan/gui/InfoDialog.java | Deleted SWT info dialog. |
| src/net/azib/ipscan/gui/GUI.java | Deleted SWT GUI entrypoint/event loop. |
| src/net/azib/ipscan/gui/GettingStartedDialog.java | Deleted SWT getting started dialog. |
| src/net/azib/ipscan/gui/fx/FXStatusBar.java | Added JavaFX status bar replacement. |
| src/net/azib/ipscan/gui/fx/FXStateMachine.java | Added JavaFX-thread marshalling state machine. |
| src/net/azib/ipscan/gui/fx/FXOpenersDialog.java | Added JavaFX “Edit Openers” dialog. |
| src/net/azib/ipscan/gui/fx/FXGUI.java | Added JavaFX Application entrypoint and window wiring. |
| src/net/azib/ipscan/gui/fx/FXFavoritesDialog.java | Added JavaFX favorites management dialog. |
| src/net/azib/ipscan/gui/fx/FXDetailsDialog.java | Added JavaFX details dialog with comment editing. |
| src/net/azib/ipscan/gui/fx/feeders/FXRandomFeederGUI.java | Added JavaFX RandomFeeder UI. |
| src/net/azib/ipscan/gui/fx/feeders/FXFileFeederGUI.java | Added JavaFX FileFeeder UI. |
| src/net/azib/ipscan/gui/fx/feeders/FXFeederGUIRegistry.java | Added JavaFX feeder registry and persistence of feeder UI state. |
| src/net/azib/ipscan/gui/fx/feeders/FXAbstractFeederGUI.java | Added JavaFX feeder GUI base class implementing FeederCreator. |
| src/net/azib/ipscan/gui/fetchers/PortTextFetcherPrefs.java | Deleted SWT PortText fetcher preferences dialog. |
| src/net/azib/ipscan/gui/fetchers/PortsFetcherPrefs.java | Deleted SWT Ports fetcher preferences shim. |
| src/net/azib/ipscan/gui/fetchers/PingFetcherPrefs.java | Deleted SWT Ping fetcher preferences shim. |
| src/net/azib/ipscan/gui/fetchers/MACFetcherPrefs.java | Deleted SWT MAC fetcher preferences dialog. |
| src/net/azib/ipscan/gui/feeders/RandomFeederGUI.java | Deleted SWT RandomFeeder UI. |
| src/net/azib/ipscan/gui/feeders/FileFeederGUI.java | Deleted SWT FileFeeder UI. |
| src/net/azib/ipscan/gui/feeders/FeederSelectionCombo.java | Deleted SWT feeder selection combo wrapper. |
| src/net/azib/ipscan/gui/feeders/FeederGUIRegistry.java | Deleted SWT feeder registry. |
| src/net/azib/ipscan/gui/feeders/FeederArea.java | Deleted SWT feeder area composite. |
| src/net/azib/ipscan/gui/feeders/ControlsArea.java | Deleted SWT controls area composite. |
| src/net/azib/ipscan/gui/feeders/AbstractFeederGUI.java | Deleted SWT feeder GUI base. |
| src/net/azib/ipscan/gui/EditFavoritesDialog.java | Deleted SWT favorites editor dialog. |
| src/net/azib/ipscan/gui/DetailsWindow.java | Deleted SWT details window. |
| src/net/azib/ipscan/gui/actions/ToolsActions.java | Deleted SWT tools actions (selection logic/UI hooks). |
| src/net/azib/ipscan/gui/actions/TerminalLauncher.java | Deleted SWT-era terminal launcher. |
| src/net/azib/ipscan/gui/actions/OpenerLauncher.java | Deleted SWT-era opener launcher. |
| src/net/azib/ipscan/gui/actions/HelpMenuActions.java | Deleted SWT help actions. |
| src/net/azib/ipscan/gui/actions/GotoMenuActions.java | Deleted SWT goto actions. |
| src/net/azib/ipscan/gui/actions/FeederActions.java | Deleted SWT feeder helper actions. |
| src/net/azib/ipscan/gui/actions/FavoritesMenuActions.java | Deleted SWT favorites menu actions. |
| src/net/azib/ipscan/gui/actions/ColumnsActions.java | Deleted SWT column header actions. |
| src/net/azib/ipscan/gui/actions/BrowserLauncher.java | Deleted SWT Program.launch-based browser launcher. |
| src/net/azib/ipscan/gui/AbstractModalDialog.java | Deleted SWT modal dialog base. |
| src/net/azib/ipscan/gui/AboutDialog.java | Deleted SWT about dialog. |
| src/net/azib/ipscan/fetchers/PortTextFetcher.java | Removed SWT preferences editor binding (prefs class now null). |
| src/net/azib/ipscan/fetchers/PortsFetcher.java | Removed SWT preferences editor binding (prefs class now null). |
| src/net/azib/ipscan/fetchers/PingFetcher.java | Removed SWT preferences editor binding (prefs class now null). |
| src/net/azib/ipscan/fetchers/OpenerLaunchFetcher.java | Added fetcher providing a clickable “open” indicator value. |
| src/net/azib/ipscan/fetchers/OpenerColumnFetcher.java | Added fetcher that displays per-IP default opener label/placeholder. |
| src/net/azib/ipscan/fetchers/MACFetcher.java | Removed SWT preferences editor binding (prefs class now null). |
| src/net/azib/ipscan/fetchers/FetcherRegistry.java | Simplified prefs editor instantiation; updated default selected fetchers. |
| src/net/azib/ipscan/exporters/TXTExporter.java | Updated TXT import API to consume FeederCreator instead of GUI type. |
| src/net/azib/ipscan/core/ScanningResultList.java | Added helpers for result snapshots, safe removals, and fetcher/result re-alignment. |
| src/net/azib/ipscan/core/ScanningResultComparator.java | Added fallback comparison when typed compare fails (ClassCastException). |
| src/net/azib/ipscan/config/OpenersConfig.java | Ensured default openers are always present and removed legacy opener.* keys. |
| src/net/azib/ipscan/config/GUIRegistry.java | Deleted SWT GUI DI registration. |
| src/net/azib/ipscan/config/GUIConfig.java | Added startup preference + column order persistence + feeder data helpers; removed SWT Point APIs. |
| src/net/azib/ipscan/config/FXComponentRegistry.java | Added minimal JavaFX DI registration (Stage). |
| src/net/azib/ipscan/config/DefaultOpenerConfig.java | Added file-based per-IP default opener persistence. |
| src/net/azib/ipscan/config/ConfigModule.java | Registered DefaultOpenerConfig in DI container. |
| src/net/azib/ipscan/config/Config.java | Added portable config directory resolution and exposed favorites/default openers accessors. |
| src/net/azib/ipscan/config/ComponentRegistry.java | Registered opener fetchers and moved pinger plugin loading outside GUI-only init. |
| src/net/azib/ipscan/config/CommentsConfig.java | Migrated comment persistence from Java Preferences to comments.txt in config dir. |
| run-javafx.bat | Added local developer convenience script (currently machine-specific). |
| run-ipscan.bat | Added local developer convenience script (currently machine-specific/outdated). |
| resources/messages.properties | Updated/added strings for opener columns, comments editing, startup options. |
| resources/messages_zh_TW.properties | Updated translated button.ipUp text. |
| resources/messages_zh_CN.properties | Updated translated button.ipUp text. |
| resources/messages_tr.properties | Updated translated button.ipUp text. |
| resources/messages_pt_BR.properties | Updated translated button.ipUp text. |
| resources/messages_it.properties | Updated translated button.ipUp text. |
| resources/messages_hu.properties | Added/updated opener/startup strings; updated button.ipUp. |
| resources/messages_ga_IE.properties | Updated translated button.ipUp text. |
| resources/messages_fr.properties | Updated translated button.ipUp text. |
| resources/messages_fi.properties | Updated translated button.ipUp text. |
| ext/jna.pro | Updated ProGuard config to suppress warnings for removed SWT + added JavaFX classes. |
| classpath.gradle | Added helper task to print runtimeClasspath. |
| build.gradle | Added JavaFX plugin/modules, removed SWT packaging, updated jar/jlink packaging logic. |
| AGENTS.md | Added repository guidance for agent/dev workflow verification. |
| .gitignore | Added bin/, *.jar, and hs_err_pid logs. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
Comment on lines
+60
to
+64
| public String get(String ip) { | ||
| var openerName = defaults.getProperty(ip); | ||
| if (openerName != null) return openerName; | ||
| return Labels.getInstance().get("opener.ping"); | ||
| } |
Comment on lines
+151
to
+155
| var oldName = listView.getItems().get(currentSelectionIndex); | ||
| var opener = openersConfig.getOpener(oldName); | ||
| var workingDir = workingDirText.getText().length() > 0 ? new File(workingDirText.getText()) : null; | ||
| openersConfig.add(nameText.getText(), new OpenersConfig.Opener(stringText.getText(), inTerminalCheck.isSelected(), workingDir)); | ||
| listView.getItems().set(currentSelectionIndex, nameText.getText()); |
Comment on lines
+3
to
+7
| set JAVA_HOME=C:\Users\peter\scoop\apps\openjdk21\current | ||
| set PATH=%JAVA_HOME%\bin;%PATH% | ||
| cd /d "I:\Angry IP Scanner\ipscan" | ||
|
|
||
| set GRADLE_CACHE=%USERPROFILE%\.gradle\caches\modules-2\files-2.1 |
Comment on lines
+3
to
+7
| set JAVA_HOME=C:\Users\peter\scoop\apps\openjdk21\current | ||
| set PATH=%JAVA_HOME%\bin;%PATH% | ||
| cd /d "I:\Angry IP Scanner\ipscan" | ||
| set PLUGIN_JAR=..\ipscan-tasmota-plugin\build\libs\ipscan-tasmota-plugin-1.0.1.jar | ||
| set SWT=C:\Users\peter\.gradle\caches\modules-2\files-2.1\org.eclipse.platform\org.eclipse.swt.win32.win32.x86_64\3.134.0\978f1c41438ebab37caf2e8d8446b420bf61c2a\org.eclipse.swt.win32.win32.x86_64-3.134.0.jar |
Comment on lines
+10
to
+14
| public class FeederGUIRegistryTest { | ||
| private FeederArea parent; | ||
| private FeederGUIRegistry registry; | ||
| private FeederSelectionCombo feederSelectionCombo; | ||
| private RangeFeederGUI feederGUI; | ||
|
|
||
| @Before | ||
| public void createRegistry() { | ||
| parent = new FeederArea(new Shell()); | ||
|
|
||
| feederSelectionCombo = mock(FeederSelectionCombo.class); | ||
|
|
||
| feederGUI = new RangeFeederGUI(parent); | ||
| feederGUI.initialize(); | ||
| registry = new FeederGUIRegistry(Collections.singletonList(feederGUI), feederSelectionCombo, null); | ||
| } | ||
|
|
||
| @After | ||
| public void dispose() { | ||
| parent.dispose(); | ||
| } | ||
|
|
||
| @Test | ||
| public void addFeederNamesToTheCombo() throws Exception { | ||
| reset(feederSelectionCombo); | ||
| new FeederGUIRegistry(Collections.singletonList(feederGUI), feederSelectionCombo, null); | ||
| verify(feederSelectionCombo).add(Labels.getLabel(feederGUI.getFeederId())); | ||
| } | ||
|
|
||
| @Test | ||
| public void lastFeederIsNeverNull() throws Exception { | ||
| assertNotNull(registry.lastFeeder); | ||
| assertNotNull(registry.lastFeeder.toString()); | ||
| } | ||
|
|
||
| @Test | ||
| public void createFeederRemembersTheLastOne() throws Exception { | ||
| var lastFeeder = registry.createFeeder(); | ||
| assertSame(lastFeeder, registry.lastFeeder); | ||
| assertNotSame(lastFeeder, registry.createFeeder()); | ||
| public void rangeFeederIsNeverNull() throws Exception { | ||
| var feeder = new RangeFeeder("127.0.0.1", "127.0.0.2"); |
Comment on lines
+132
to
+135
| var stream = FXGUI.class.getResourceAsStream(path); | ||
| if (stream != null) { | ||
| javafx.scene.text.Font.loadFont(stream, -1); | ||
| } |
…plement inline editing in ResultTable
…for setting and opening with default openers
… ResultTable and DetailsWindow
…alog - Removed SelectFetchersDialog from MacApplicationMenu and MainWindow. - Updated MacApplicationMenu constructor and initialization to exclude SelectFetchersDialog. - Adjusted MainWindow to remove references to SelectFetchersDialog and its related listener. - Cleaned up related code in ResultTable to handle fetcher visibility and interactions without SelectFetchersDialog. - Introduced ColumnVisibilityMenu to manage column visibility directly from the header context menu. - Enhanced ResultTable to support dynamic column visibility and reordering. - Updated various actions and menu items to reflect the removal of SelectFetchersDialog.
…llback to text comparison; update ResultTable event handling for control-relative coordinates; refactor ColumnsActions to remove unused ColumnsMenu and improve column sorting logic.
…ColumnVisibilityMenu
…e updated getColumnOrder() yet when the Move event fires
…nst disposed table in asyncExec updates
…the list is empty
…are re-added on startup
Replace the MouseMove-based HeaderTooltipHandler with a HeaderTooltipPoller: on Windows the table header is a separate native SysHeader32 control, so Table-level mouse events never fire over it and the tooltip either showed in the wrong place or never at all. The poller checks the cursor position every 100ms via Display.timerExec, shows the width-capped (360px) wrapping fetcher info tooltip after a 2000ms hover delay, hides it on focus loss/outside-header/rows, and resolves the hovered column in visual order so drag-reordered columns map correctly.
TableItem.setText()/getTextBounds() index columns in MODEL (creation) order: write row values to modelCol instead of the visual position, and detect the clicked visual column by summing widths in visual (getColumnOrder) order in the double-click, opener-triangle and Details double-click handlers.
…nch cooldown (port 3e8f233, e120035) Render the OpenerLaunch triangle only when an Opener is assigned to the row, update both opener columns atomically via updateOpenerAssignment(), run launches on a background thread guarded by a cooldown so rapid clicks cannot queue up many openers, and drop the first-opener fallback.
Set each header text immediately at column creation and rebuild the column set from scratch in updateColumnNames(): on Windows the native header may map setText() calls to stale positions after a drag-reorder.
…ateAutoFitButtonColumn to SWT) Fixed 46px '<->' header button as the first model column (mirrors the JavaFX autofit button): clicking it packs every fetcher column to fit content. It carries no Fetcher, so rendering, column-order persistence, hit-testing, tooltips and moveability explicitly skip it; the status icon now follows the IP column's model slot.
- Precompute a column-to-fetcher index map to avoid repeated getFetcherIndex calls during virtual table rendering; batch UI updates in populateNewFetcher (100 rows per asyncExec instead of one per row); precompute fetcher positions in ScanningResultList.syncFetchers (port of new-features 39b5cf1) - Shorter header tooltip delay (1s), tooltip for the leading autofit column, tooltip width now fits the text (capped as before) - Size the autofit column via pack() after clearAll() so it keeps a fixed small width on column rebuilds (stale item text would otherwise be measured) - Force a full repaint after column rebuilds: Win32 does not always invalidate the client area (blank results after closing a modal dialog such as Preferences) - Refresh the table immediately before the first batch of network scans when populating a newly added column, and guarantee setRedraw(true) via try/finally
…nfig untouched Edits are now applied to an in-memory working copy of the openers; the shared OpenersConfig is only updated when OK is pressed (port of new-features 9fc43b2). Deleted openers are dropped from the working copy too, so re-adding an opener with the same name starts fresh.
If the selection loop threw while redraw was disabled, the result table would stay blank until restarted. Also fixes indentation of the loop body.
- Config.getConfigDir: probe writability with a temp file (canWrite lies under Program Files); wire DefaultOpenerConfig as singleton, public forFavorites - OpenersConfig: drop legacy opener.* keys before re-adding defaults - GUIConfig: add get/setFeederData helpers (SWT Point APIs kept) - ScanningResultList: add getResultsSnapshot + removeExcept (syncFetchers perf already ported in b6f2064)
Plain jar builds lack the Version/Build-Date manifest entries, which left getVersion() null and crashed callers with NPE. Fall back to current/today.
…fault width logic, implement debounced saving on resize
- OpenerLauncher: fall back to the IP for missing fetcher values, but throw for typos in fetcher references (hybrid of the old and new behavior) - OpenerLauncher: use double quotes on Windows (cmd.exe does not treat single quotes as quoting) - fixes openers like Ping failing with 'Unable to resolve target system name' - FetcherRegistry: add isRegisteredFetcher() to distinguish unknown fetchers from unselected ones - PluginLoader: decode percent-encoded resource paths so spaces in the installation path work - TXTExporterTest: resolve test resources via toURI() (also fixes paths with spaces) - AbstractPingerTest: ping a locally opened ServerSocket port to make pingAlive deterministic behind firewalls
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
1. File-based Comments + Inline Editing
Commits:
16033af8,7ade9ea5,57747ca2Textwidget;Enter/FocusOutsaves,Escapecancels.CommentsConfigpersists tocomments.txtinstead of Java Preferences (survives restarts, flushed immediately).Config.getConfigDir()— portable config directory next to the JAR, falls back to~/.ipscan.2. Default Opener per IP
Commits:
219305eb,4e8ac91e,4c0efca0,3e8f2333OpenerColumnFetcher— column showing the configured opener name; double-click opens a radio-menu to pick one.OpenerLaunchFetcher— centered triangle (▶) icon column; click to launch the default opener for that IP.DefaultOpenerConfig— per-IP opener assignment (persisted to file).3. ColumnVisibilityMenu (removes SelectFetchersDialog)
Commits:
ed77fc0cColumnVisibilityMenu— right-click on the table header toggles individual columns on/off inline.SelectFetchersDialog.java— old modal dialog removed.MacApplicationMenu,MainWindow,ToolsActions,ColumnsActions,CommandsMenuActions,OpenerLauncher,AbstractModalDialog.4. Column Order Persistence + Drag-Reorder
Commits: (Contained within
ed77fc0cand95c1f86e)saveColumnOrder()— persists visual column order viaguiConfig.setColumnOrder()after every drag.6. Column Header Tooltip
Commits:
3a2f7eaaHeaderTooltipPoller— polls cursor position every 100ms to show a width-capped (360px), wrapping tooltip over column headers.ResultTable Performance
Commits:
39b5cf1ecolumnFetcherIndexMapforpopulateNewFetcher()— background thread that fills a newly added fetcher column in batches (100 rows per UI update) without freezing the table.ScanningResultList.Table Rebuild on Fetcher Change
Commits: (Contained within
ed77fc0c)handleUpdateOfSelectedFetchers()now preserves scanned results, re-aligns columns in saved order, and populates newly added fetchers with real data off the UI thread.