You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@camel.apache.org by "gnodet (via GitHub)" <gi...@apache.org> on 2026/07/01 08:58:24 UTC

[PR] Improve mouse support in TUI: scroll, tab clicks, node selection, panel resize [camel]

gnodet opened a new pull request, #24351:
URL: https://github.com/apache/camel/pull/24351

   ## Summary
   
   _Claude Code on behalf of Guillaume Nodet_
   
   Add comprehensive mouse event handling to the Camel TUI monitor:
   
   - **Mouse wheel scrolling** in all scrollable views: logs, diagrams, topology, routes, errors, history, metrics, process info, configuration, spans, startup, and HTTP spec/probe views
   - **Click on tab headers** to switch between tabs (Overview, Log, Diagram, Route, Endpoint, HTTP, Health, Inspect, Errors, More)
   - **Click on topology nodes** and EIP nodes in diagram views to select them
   - **Drag panel border** between content area and shell/AI panel to resize the split
   - **Mouse scroll in shell panel and AI panel** (AI panel was missing scroll support)
   
   ### Implementation Details
   
   - `MonitorTab` interface gains a default `handleMouseEvent(MouseEvent, Rect)` method
   - `CamelMonitor` dispatches mouse events to the active tab, handles tab bar click detection, and panel border drag resize
   - `DiagramSupport` provides `handleMouseScroll()` for wheel scrolling and `handleNodeClick()`/`handleEipNodeClick()` for click-to-select on topology and route diagram node boxes
   - `ShellPanel` and `AiPanel` gain `setSplitPercent()` for continuous drag resize (snapping to nearest preset: 25%, 50%, 75%, 100%)
   - 14 tab implementations override `handleMouseEvent()` with view-specific scroll handling
   
   ### Files Changed (16 files, +527 lines)
   
   | File | Change |
   |------|--------|
   | `MonitorTab.java` | Added `handleMouseEvent()` default method |
   | `CamelMonitor.java` | Mouse dispatch, tab click detection, panel drag resize |
   | `DiagramSupport.java` | Mouse scroll, node click hit-testing |
   | `DiagramTab.java` | Delegate mouse to DiagramSupport |
   | `RoutesTab.java` | Delegate mouse to DiagramSupport |
   | `LogTab.java` | Mouse wheel scroll for log view |
   | `ProcessTab.java` | Mouse wheel scroll for process info |
   | `ErrorsTab.java` | Mouse scroll + diagram node clicks |
   | `HistoryTab.java` | Mouse scroll + diagram node clicks |
   | `MetricsTab.java` | Mouse wheel scroll for raw metrics view |
   | `HttpTab.java` | Mouse scroll for spec and probe views |
   | `SpansTab.java` | Mouse scroll for waterfall view |
   | `StartupTab.java` | Mouse wheel scroll |
   | `ConfigurationTab.java` | Mouse wheel scroll |
   | `ShellPanel.java` | Added `setSplitPercent()` for drag resize |
   | `AiPanel.java` | Mouse scroll + `setSplitPercent()` for drag resize |
   
   ## Test plan
   
   - [ ] Verify mouse wheel scrolling works in the Log tab
   - [ ] Verify mouse wheel scrolling works in the Diagram/Topology view
   - [ ] Verify clicking on tab labels switches to the correct tab
   - [ ] Verify clicking on topology nodes selects them
   - [ ] Verify dragging the shell/AI panel border resizes the split
   - [ ] Verify mouse wheel scrolling works in all other scrollable tabs
   - [ ] Verify existing keyboard navigation still works as before
   
   🤖 Generated with [Claude Code](https://claude.com/claude-code)


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@camel.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


Re: [PR] Improve mouse support in TUI: scroll, tab clicks, node selection, panel resize [camel]

Posted by "github-actions[bot] (via GitHub)" <gi...@apache.org>.
github-actions[bot] commented on PR #24351:
URL: https://github.com/apache/camel/pull/24351#issuecomment-4852680359

   <!-- ci-tested-modules -->
   :test_tube: **CI tested the following changed modules:**
   
   - `dsl/camel-jbang/camel-jbang-plugin-tui`
   
   <details><summary>All tested modules (2 modules)</summary>
   
   - Camel :: JBang :: Plugin :: TUI
   - Camel :: Launcher :: Container
   
   </details>
   
   ---
   :gear: [View full build and test results](https://github.com/apache/camel/actions/runs/28505887068)


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@camel.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


Re: [PR] Improve mouse support in TUI: scroll, tab clicks, node selection, panel resize [camel]

Posted by "gnodet (via GitHub)" <gi...@apache.org>.
gnodet merged PR #24351:
URL: https://github.com/apache/camel/pull/24351


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@camel.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


Re: [PR] Add mouse interaction support to TUI monitor [camel]

Posted by "gnodet (via GitHub)" <gi...@apache.org>.
gnodet commented on PR #24351:
URL: https://github.com/apache/camel/pull/24351#issuecomment-4859171787

   @davsclaus Rebased on main and force-pushed — all 5 commits sit cleanly on current main.


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@camel.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


Re: [PR] Improve mouse support in TUI: scroll, tab clicks, node selection, panel resize [camel]

Posted by "github-actions[bot] (via GitHub)" <gi...@apache.org>.
github-actions[bot] commented on PR #24351:
URL: https://github.com/apache/camel/pull/24351#issuecomment-4852519987

   :star2: Thank you for your contribution to the Apache Camel project! :star2:
     :robot: CI automation will test this PR automatically.
   
     :camel: Apache Camel Committers, please review the following items:
   
     * First-time contributors **require MANUAL approval** for the GitHub Actions to run
     * You can use the command `/component-test (camel-)component-name1 (camel-)component-name2..` to request a test from the test bot although they are normally detected and executed by CI.
     * You can label PRs using `skip-tests` and `test-dependents` to fine-tune the checks executed by this PR.
     * Build and test logs are available in the summary page. **Only** [Apache Camel committers](https://camel.apache.org/community/team/#committers) have access to the summary.
     
     :warning: Be careful when sharing logs. Review their contents before sharing them publicly.


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@camel.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


Re: [PR] Improve mouse support in TUI: scroll, clicks, popups, and tables [camel]

Posted by "gnodet (via GitHub)" <gi...@apache.org>.
gnodet commented on code in PR #24351:
URL: https://github.com/apache/camel/pull/24351#discussion_r3508072680


##########
dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/ConfigurationTab.java:
##########
@@ -44,6 +46,7 @@
 
 class ConfigurationTab implements MonitorTab {
 
+    private static final int MOUSE_SCROLL_LINES = 3;

Review Comment:
   Good point. I'll move it to a shared constant on `MonitorTab` (or a small `MouseConstants` utility) so scroll speed is controlled in one place. Will address in the next push.



##########
dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/ShellPanel.java:
##########
@@ -116,6 +116,22 @@ void cycleHeight() {
         splitIndex = (splitIndex + 1) % SPLIT_PERCENTS.length;
     }
 
+    /**
+     * Sets the panel height to the nearest preset percentage matching the given target. Used by mouse drag resize.
+     */
+    void setSplitPercent(int percent) {

Review Comment:
   Agreed — `setSplitPercent` is identical in both. I'll extract it into the `DragSplit` helper (which already owns the split logic) so the panels just delegate to it.



##########
dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/CamelMonitor.java:
##########
@@ -719,6 +735,113 @@ private boolean handleTabKeys(KeyEvent ke) {
         return false;
     }
 
+    private boolean handleMouseEvent(MouseEvent me) {
+        // Panel border drag resize: detect press on the border row, then track drag
+        if (panelBorderY >= 0 && lastContentArea != null && (shellPanel.isOpen() || aiPanel.isOpen())) {
+            if (me.isPress() && Math.abs(me.y() - panelBorderY) <= 1) {
+                draggingPanelBorder = true;
+                return true;
+            }
+            if (draggingPanelBorder && me.kind() == MouseEventKind.DRAG) {
+                int contentHeight = lastContentArea.height();
+                if (contentHeight > 0) {
+                    int panelHeight = lastContentArea.y() + contentHeight - me.y();
+                    int percent = Math.max(10, Math.min(100, panelHeight * 100 / contentHeight));
+                    if (shellPanel.isOpen()) {
+                        shellPanel.setSplitPercent(percent);
+                    } else {
+                        aiPanel.setSplitPercent(percent);
+                    }
+                }
+                return true;
+            }
+            if (draggingPanelBorder && me.isRelease()) {
+                draggingPanelBorder = false;
+                return true;
+            }
+        }
+
+        // Tab bar clicks: detect which tab was clicked and switch to it
+        if (me.isClick() && lastTabsArea != null && lastTabLabels != null) {
+            int mx = me.x();
+            int my = me.y();
+            // Tabs render on the second row of the tabs area (y+1)
+            int tabsY = lastTabsArea.height() >= 2 ? lastTabsArea.y() + 1 : lastTabsArea.y();
+            if (my == tabsY && mx >= lastTabsArea.x() && mx < lastTabsArea.x() + lastTabsArea.width()) {
+                int clickedTab = findClickedTab(mx - lastTabsArea.x());
+                if (clickedTab >= 0) {
+                    if (isInfraSelected()) {
+                        // Infra mode: map 0→Overview, 1→Log
+                        int realTab = clickedTab == 1 ? TAB_LOG : TAB_OVERVIEW;
+                        tabsState.select(realTab);
+                    } else {
+                        tabRegistry.handleTabKey(clickedTab, ctx, dataService);
+                    }
+                    return true;
+                }
+            }
+        }
+
+        // Mouse events in the content area: delegate to the active tab
+        if (lastContentArea != null) {
+            int mx = me.x();
+            int my = me.y();
+            if (mx >= lastContentArea.x() && mx < lastContentArea.x() + lastContentArea.width()
+                    && my >= lastContentArea.y() && my < lastContentArea.y() + lastContentArea.height()) {
+                // Popups intercept before the tab
+                if (popupManager.isMorePopupVisible() || popupManager.isSwitchPopupVisible()
+                        || filesBrowser.isVisible() || actionsPopup.isVisible()) {
+                    return false;
+                }
+                MonitorTab activeTab = tabRegistry.activeTab();
+                if (activeTab != null && activeTab.handleMouseEvent(me, lastContentArea)) {
+                    return true;
+                }
+                // Scroll events that the tab did not handle: map to navigateUp/Down
+                if (me.kind() == MouseEventKind.SCROLL_UP) {
+                    tabRegistry.navigateUp();
+                    tabRegistry.navigateUp();
+                    tabRegistry.navigateUp();

Review Comment:
   Good catch — that should indeed reference the constant rather than hard-coding 3 repeated calls. Will fix.



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@camel.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


Re: [PR] Add mouse interaction support to TUI monitor [camel]

Posted by "davsclaus (via GitHub)" <gi...@apache.org>.
davsclaus commented on PR #24351:
URL: https://github.com/apache/camel/pull/24351#issuecomment-4859715152

   @gnodet there is also a PR #24365 


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@camel.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


Re: [PR] Improve mouse support in TUI: scroll, clicks, popups, and tables [camel]

Posted by "davsclaus (via GitHub)" <gi...@apache.org>.
davsclaus commented on PR #24351:
URL: https://github.com/apache/camel/pull/24351#issuecomment-4857943411

   rebase on main if you can


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@camel.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


Re: [PR] Add mouse interaction support to TUI monitor [camel]

Posted by "gnodet (via GitHub)" <gi...@apache.org>.
gnodet commented on code in PR #24351:
URL: https://github.com/apache/camel/pull/24351#discussion_r3508418994


##########
dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/ConfigurationTab.java:
##########
@@ -44,6 +46,7 @@
 
 class ConfigurationTab implements MonitorTab {
 
+    private static final int MOUSE_SCROLL_LINES = 3;

Review Comment:
   Done — `MOUSE_SCROLL_LINES` is now a single constant on the `MonitorTab` interface. The 9 tab classes that implement `MonitorTab` inherit it; the 3 that don't (`AiPanel`, `ShellPanel`, `DiagramSupport`) qualify it as `MonitorTab.MOUSE_SCROLL_LINES`. See commit 565b7ce.



##########
dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/ShellPanel.java:
##########
@@ -116,6 +116,22 @@ void cycleHeight() {
         splitIndex = (splitIndex + 1) % SPLIT_PERCENTS.length;
     }
 
+    /**
+     * Sets the panel height to the nearest preset percentage matching the given target. Used by mouse drag resize.
+     */
+    void setSplitPercent(int percent) {

Review Comment:
   Done — `setSplitPercent` now delegates to `MonitorTab.nearestPresetIndex()`, a static utility on the shared interface. Both `ShellPanel` and `AiPanel` use it. See commit 565b7ce.



##########
dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/CamelMonitor.java:
##########
@@ -719,6 +735,113 @@ private boolean handleTabKeys(KeyEvent ke) {
         return false;
     }
 
+    private boolean handleMouseEvent(MouseEvent me) {
+        // Panel border drag resize: detect press on the border row, then track drag
+        if (panelBorderY >= 0 && lastContentArea != null && (shellPanel.isOpen() || aiPanel.isOpen())) {
+            if (me.isPress() && Math.abs(me.y() - panelBorderY) <= 1) {
+                draggingPanelBorder = true;
+                return true;
+            }
+            if (draggingPanelBorder && me.kind() == MouseEventKind.DRAG) {
+                int contentHeight = lastContentArea.height();
+                if (contentHeight > 0) {
+                    int panelHeight = lastContentArea.y() + contentHeight - me.y();
+                    int percent = Math.max(10, Math.min(100, panelHeight * 100 / contentHeight));
+                    if (shellPanel.isOpen()) {
+                        shellPanel.setSplitPercent(percent);
+                    } else {
+                        aiPanel.setSplitPercent(percent);
+                    }
+                }
+                return true;
+            }
+            if (draggingPanelBorder && me.isRelease()) {
+                draggingPanelBorder = false;
+                return true;
+            }
+        }
+
+        // Tab bar clicks: detect which tab was clicked and switch to it
+        if (me.isClick() && lastTabsArea != null && lastTabLabels != null) {
+            int mx = me.x();
+            int my = me.y();
+            // Tabs render on the second row of the tabs area (y+1)
+            int tabsY = lastTabsArea.height() >= 2 ? lastTabsArea.y() + 1 : lastTabsArea.y();
+            if (my == tabsY && mx >= lastTabsArea.x() && mx < lastTabsArea.x() + lastTabsArea.width()) {
+                int clickedTab = findClickedTab(mx - lastTabsArea.x());
+                if (clickedTab >= 0) {
+                    if (isInfraSelected()) {
+                        // Infra mode: map 0→Overview, 1→Log
+                        int realTab = clickedTab == 1 ? TAB_LOG : TAB_OVERVIEW;
+                        tabsState.select(realTab);
+                    } else {
+                        tabRegistry.handleTabKey(clickedTab, ctx, dataService);
+                    }
+                    return true;
+                }
+            }
+        }
+
+        // Mouse events in the content area: delegate to the active tab
+        if (lastContentArea != null) {
+            int mx = me.x();
+            int my = me.y();
+            if (mx >= lastContentArea.x() && mx < lastContentArea.x() + lastContentArea.width()
+                    && my >= lastContentArea.y() && my < lastContentArea.y() + lastContentArea.height()) {
+                // Popups intercept before the tab
+                if (popupManager.isMorePopupVisible() || popupManager.isSwitchPopupVisible()
+                        || filesBrowser.isVisible() || actionsPopup.isVisible()) {
+                    return false;
+                }
+                MonitorTab activeTab = tabRegistry.activeTab();
+                if (activeTab != null && activeTab.handleMouseEvent(me, lastContentArea)) {
+                    return true;
+                }
+                // Scroll events that the tab did not handle: map to navigateUp/Down
+                if (me.kind() == MouseEventKind.SCROLL_UP) {
+                    tabRegistry.navigateUp();
+                    tabRegistry.navigateUp();
+                    tabRegistry.navigateUp();

Review Comment:
   Done — replaced the repeated calls with a `for (int i = 0; i < MonitorTab.MOUSE_SCROLL_LINES; i++)` loop for both `navigateUp()` and `navigateDown()`. See commit 565b7ce.



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@camel.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


Re: [PR] Improve mouse support in TUI: scroll, clicks, popups, and tables [camel]

Posted by "gnodet (via GitHub)" <gi...@apache.org>.
gnodet commented on PR #24351:
URL: https://github.com/apache/camel/pull/24351#issuecomment-4858680376

   Thanks for the thorough review, Claus!
   
   Replying to the general notes:
   
   - **JIRA ticket** — will create one and update the commit messages.
   - **Tests** — fair point. The coordinate math in `findClickedTab`, `handleNodeClick`, `handleEipNodeClick`, and `setSplitPercent` is pure logic that can be unit-tested without a running TUI. Will add tests for the hit-testing and split math.
   - **HistoryTab and EIP node clicks** — intentional. HistoryTab shows topology-level diagrams (route overview) when in history mode, and uses `diagram.handleNodeClick()` for those. It doesn't drill into route-level EIP diagrams the way DiagramTab/ErrorsTab/RoutesTab do, so `handleEipNodeClick` isn't needed there. If we add EIP-level history views later, we'd add it then.
   
   Will address the inline comments (shared `MOUSE_SCROLL_LINES` constant, `setSplitPercent` extraction, navigate loop) in the next push.


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@camel.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


Re: [PR] Improve mouse support in TUI: scroll, tab clicks, node selection, panel resize [camel]

Posted by "gnodet (via GitHub)" <gi...@apache.org>.
gnodet commented on PR #24351:
URL: https://github.com/apache/camel/pull/24351#issuecomment-4862484765

   @ammachado This is now merged — feel free to rebase your PR on top of main.


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@camel.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


Re: [PR] Improve mouse support in TUI: scroll, tab clicks, node selection, panel resize [camel]

Posted by "davsclaus (via GitHub)" <gi...@apache.org>.
davsclaus commented on code in PR #24351:
URL: https://github.com/apache/camel/pull/24351#discussion_r3504782652


##########
dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/ConfigurationTab.java:
##########
@@ -44,6 +46,7 @@
 
 class ConfigurationTab implements MonitorTab {
 
+    private static final int MOUSE_SCROLL_LINES = 3;

Review Comment:
   This same `MOUSE_SCROLL_LINES = 3` constant is now declared independently in 11 files (plus the pre-existing one in `ShellPanel`). Consider defining it once — e.g. as a constant on `MonitorTab` — so the scroll speed is configurable in a single place.



##########
dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/ShellPanel.java:
##########
@@ -116,6 +116,22 @@ void cycleHeight() {
         splitIndex = (splitIndex + 1) % SPLIT_PERCENTS.length;
     }
 
+    /**
+     * Sets the panel height to the nearest preset percentage matching the given target. Used by mouse drag resize.
+     */
+    void setSplitPercent(int percent) {

Review Comment:
   This `setSplitPercent` method is identical to the one added in `AiPanel`. Consider extracting it to a shared helper or base class to avoid the duplication.



##########
dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/CamelMonitor.java:
##########
@@ -719,6 +735,113 @@ private boolean handleTabKeys(KeyEvent ke) {
         return false;
     }
 
+    private boolean handleMouseEvent(MouseEvent me) {
+        // Panel border drag resize: detect press on the border row, then track drag
+        if (panelBorderY >= 0 && lastContentArea != null && (shellPanel.isOpen() || aiPanel.isOpen())) {
+            if (me.isPress() && Math.abs(me.y() - panelBorderY) <= 1) {
+                draggingPanelBorder = true;
+                return true;
+            }
+            if (draggingPanelBorder && me.kind() == MouseEventKind.DRAG) {
+                int contentHeight = lastContentArea.height();
+                if (contentHeight > 0) {
+                    int panelHeight = lastContentArea.y() + contentHeight - me.y();
+                    int percent = Math.max(10, Math.min(100, panelHeight * 100 / contentHeight));
+                    if (shellPanel.isOpen()) {
+                        shellPanel.setSplitPercent(percent);
+                    } else {
+                        aiPanel.setSplitPercent(percent);
+                    }
+                }
+                return true;
+            }
+            if (draggingPanelBorder && me.isRelease()) {
+                draggingPanelBorder = false;
+                return true;
+            }
+        }
+
+        // Tab bar clicks: detect which tab was clicked and switch to it
+        if (me.isClick() && lastTabsArea != null && lastTabLabels != null) {
+            int mx = me.x();
+            int my = me.y();
+            // Tabs render on the second row of the tabs area (y+1)
+            int tabsY = lastTabsArea.height() >= 2 ? lastTabsArea.y() + 1 : lastTabsArea.y();
+            if (my == tabsY && mx >= lastTabsArea.x() && mx < lastTabsArea.x() + lastTabsArea.width()) {
+                int clickedTab = findClickedTab(mx - lastTabsArea.x());
+                if (clickedTab >= 0) {
+                    if (isInfraSelected()) {
+                        // Infra mode: map 0→Overview, 1→Log
+                        int realTab = clickedTab == 1 ? TAB_LOG : TAB_OVERVIEW;
+                        tabsState.select(realTab);
+                    } else {
+                        tabRegistry.handleTabKey(clickedTab, ctx, dataService);
+                    }
+                    return true;
+                }
+            }
+        }
+
+        // Mouse events in the content area: delegate to the active tab
+        if (lastContentArea != null) {
+            int mx = me.x();
+            int my = me.y();
+            if (mx >= lastContentArea.x() && mx < lastContentArea.x() + lastContentArea.width()
+                    && my >= lastContentArea.y() && my < lastContentArea.y() + lastContentArea.height()) {
+                // Popups intercept before the tab
+                if (popupManager.isMorePopupVisible() || popupManager.isSwitchPopupVisible()
+                        || filesBrowser.isVisible() || actionsPopup.isVisible()) {
+                    return false;
+                }
+                MonitorTab activeTab = tabRegistry.activeTab();
+                if (activeTab != null && activeTab.handleMouseEvent(me, lastContentArea)) {
+                    return true;
+                }
+                // Scroll events that the tab did not handle: map to navigateUp/Down
+                if (me.kind() == MouseEventKind.SCROLL_UP) {
+                    tabRegistry.navigateUp();
+                    tabRegistry.navigateUp();
+                    tabRegistry.navigateUp();

Review Comment:
   The three repeated `navigateUp()` / `navigateDown()` calls are a magic number that should match `MOUSE_SCROLL_LINES`. Consider using a loop:
   ```suggestion
                       for (int i = 0; i < 3; i++) {
                           tabRegistry.navigateUp();
                       }
   ```
   (And similarly for `navigateDown` below.)



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@camel.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org