Skip to content

LT-22452 - fix mouse scrolling on date field in lex edit#754

Open
johnml1135 wants to merge 5 commits intomainfrom
LT-22452
Open

LT-22452 - fix mouse scrolling on date field in lex edit#754
johnml1135 wants to merge 5 commits intomainfrom
LT-22452

Conversation

@johnml1135
Copy link
Contributor

@johnml1135 johnml1135 commented Mar 11, 2026

JIRA Explanation for LT-22452

Problem:
Mouse wheel scrolling does not work in the Lexicon Editor when the cursor is over the Date field (and potentially other non-ButtonLauncher controls in the DataTree).

Root Cause:
The Date field (DateSlice in BasicTypeSlices.cs) wraps a RichTextBox set to ReadOnly with BorderStyle.None. RichTextBox inherits from ScrollableControl and has internal scroll machinery that consumes WM_MOUSEWHEEL messages without propagating them to the parent DataTree. Win32 delivers WM_MOUSEWHEEL to the focused window handle (the RichTextBox), so the message never reaches DataTree and its AutoScrollPosition property is never updated — the pane doesn't scroll.

This is a general WinForms problem: any child control that internally handles WM_MOUSEWHEEL (e.g. RichTextBox, ListView, TreeView) will swallow the mouse wheel and prevent its container from scrolling.

Fix:
Added a WheelRedirector inner class to DataTree that implements IMessageFilter — a .NET/WinForms mechanism that intercepts Windows messages at the application message pump before they are dispatched to any window. This is the same pattern used in 7 other places in the FieldWorks codebase (e.g. FwFindReplaceDlg, SimpleRootSite, FwApp).

When WM_MOUSEWHEEL is intercepted, the filter checks whether the cursor is over any live DataTree instance. If so, it calculates the new scroll position using the same AutoScrollPosition/AutoScrollMinSize API that DataTree itself uses, applies it, and marks the message as handled. This ensures consistent scrolling regardless of which child control has focus.

Changes:

  • DataTree.cs: Added WheelRedirector inner class (~65 lines), Register() call in constructor, Unregister() call in Dispose.
  • DataTreeScrollTests.cs: New test verifying the scroll position calculation works correctly.
  • No changes to ButtonLauncher.cs or any other file.

Made changes.


This change is Reviewable

@johnml1135 johnml1135 requested review from Copilot and jasonleenaylor and removed request for Copilot March 11, 2026 17:10
@github-actions
Copy link

github-actions bot commented Mar 11, 2026

NUnit Tests

    1 files      1 suites   5m 42s ⏱️
4 411 tests 4 324 ✅ 87 💤 0 ❌
4 420 runs  4 333 ✅ 87 💤 0 ❌

Results for commit 7ac2ac0.

♻️ This comment has been updated with latest results.

Copy link
Contributor

@jasonleenaylor jasonleenaylor left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It looks like this test adds another test that pops up a window while it is running. I was hoping to get away from that, I'd rather not have a unit test for this if that is the case.

@jasonleenaylor reviewed 1 file and all commit messages, and made 1 comment.
Reviewable status: 1 of 3 files reviewed, all discussions resolved.

Copilot AI review requested due to automatic review settings March 12, 2026 16:04
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds an application-level IMessageFilter to ensure DataTree scrolls when the mouse wheel is used over child controls that consume WM_MOUSEWHEEL (e.g., RichTextBox inside DateSlice), and introduces configuration stubs in Serena project settings.

Changes:

  • Register/unregister a static WheelRedirector to intercept WM_MOUSEWHEEL and update DataTree.AutoScrollPosition.
  • Add WheelRedirector inner class implementing IMessageFilter to redirect wheel scrolling based on cursor location.
  • Extend .serena/project.yml with additional (currently unset) configuration keys.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 4 comments.

File Description
Src/Common/Controls/DetailControls/DataTree.cs Installs a message filter to redirect mouse-wheel scrolling to DataTree regardless of focused child control.
.serena/project.yml Adds new Serena configuration keys for line endings and read-only memory patterns.
Comments suppressed due to low confidence (1)

Src/Common/Controls/DetailControls/DataTree.cs:1

  • Unregister() is called unconditionally, including when disposing == false (finalizer path). Since Application.Add/RemoveMessageFilter is thread-affine (per-UI-thread message loop), attempting to remove the filter from a non-UI/finalizer thread may not actually remove it (leaking the filter/list entry) and can introduce cross-thread issues. Move the s_wheelRedirector.Unregister(this); call inside the if (disposing) block (or otherwise ensure it executes on the same UI thread that performed Register).
// Copyright (c) 2015-2017 SIL International

@sillsdev sillsdev deleted a comment from Copilot AI Mar 13, 2026
@johnml1135
Copy link
Contributor Author

@jasonleenaylor - I removed the test. It doesn't really need a test, I was just trying to replicate it. It's hard to replicate without a full test. That is another PR (getting true no-popup testing).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants