Project

General

Profile

Bug #10706

Date FILL-IN: Unintended VALUE-CHANGED Event Triggered by BACKSPACE

Added by Vladimir Tsichevski 9 months ago. Updated 3 months ago.

Status:
WIP
Priority:
Normal
Assignee:
Delia Mitric
Target version:
-
Start date:
Due date:
% Done:

90%

billable:
No
vendor_id:
GCD
case_num:
version_reported:
16212
version_resolved:
reviewer:
Hynek Cihlar, Vladimir Tsichevski
production:
No
env_name:
topics:

10706-optimize.diff Magnifier (2.69 KB) Vladimir Tsichevski, 01/23/2026 06:59 AM


Related issues

Related to User Interface - Bug #11053: DATETIME-TZ FILL-IN crashes in VALUE-CHANGED trigger WIP
Related to User Interface - Bug #11078: Unintended VALUE-CHANGED Event Triggering in DECIMAL, INTEGER, and LOGICAL FILL-IN Widgets New

History

#1 Updated by Vladimir Tsichevski 9 months ago

  • version_reported set to 16212
  • reviewer Hynek Cihlar added

Consider this example:

DEFINE VARIABLE f1 AS DATE.
DEFINE VARIABLE counter AS INTEGER NO-UNDO.

DEFINE FRAME fMain f1.
ON VALUE-CHANGED OF f1 DO:
  MESSAGE counter "Value-changed".
  counter = counter + 1.
END.

ENABLE ALL WITH FRAME fMain.
WAIT-FOR WINDOW-CLOSE OF CURRENT-WINDOW.

In this example, a date-type FILL-IN widget is created with a VALUE-CHANGED handler that indicates when the event fires.

When the user presses BACKSPACE:

  1. In OE: The VALUE-CHANGED event is never triggered.
  2. In FWD: The VALUE-CHANGED event is always triggered.

#3 Updated by Delia Mitric 7 months ago

  • Assignee set to Delia Mitric

I'll investigate this

#4 Updated by Delia Mitric 7 months ago

  • Status changed from New to WIP

#5 Updated by Delia Mitric 7 months ago

  • % Done changed from 0 to 100
  • Status changed from WIP to Review

I've committed a solution to 10706a branch rev.16320 .

Hynek/Vladimir, please review it.
Thank you!

#6 Updated by Delia Mitric 7 months ago

  • reviewer Vladimir Tsichevski added

#7 Updated by Vladimir Tsichevski 7 months ago

Code review 10706a rev. 16320.

This solution does not work for datetime and datetime-tz.

Run this example:

DEFINE VARIABLE f1 AS DATE.
DEFINE VARIABLE f2 AS DATETIME.
DEFINE VARIABLE f3 AS DATETIME-TZ.
DEFINE VARIABLE counter AS INTEGER NO-UNDO.

DEFINE FRAME fMain f1 f2 f3.
ON VALUE-CHANGED OF f1, f2, f3 DO:
  MESSAGE counter "Value-changed".
  counter = counter + 1.
END.

ENABLE ALL WITH FRAME fMain.
WAIT-FOR WINDOW-CLOSE OF CURRENT-WINDOW.

Pressing Backspace in the f2 and f3 FILL-IN s still fires the VALUE-CHANGED event.

The problem is in how the isDateBased is assigned:

      isDateBased = config.dataType.equalsIgnoreCase("date");

#8 Updated by Delia Mitric 7 months ago

  • % Done changed from 100 to 90
  • Status changed from Review to WIP

#9 Updated by Delia Mitric 7 months ago

Vladimir Tsichevski wrote:

Code review 10706a rev. 16320.

The problem is in how the isDateBased is assigned:

[...]

What do you suggest? To consider a DATETIME/DATETIME-TZ FILL-IN also a date-based widget, or we need a new variable to store this?

#10 Updated by Vladimir Tsichevski 7 months ago

Delia Mitric wrote:

Vladimir Tsichevski wrote:

Code review 10706a rev. 16320.

The problem is in how the isDateBased is assigned:

[...]

What do you suggest? To consider a DATETIME/DATETIME-TZ FILL-IN also a date-based widget, or we need a new variable to store this?

The first variant. Check that setting isDateBased to true for date subclasses will not cause regressions.

#11 Updated by Delia Mitric 7 months ago

The application crashes when we using a DATETIME-TZ FILL-IN and trying to introduce any characters.
I've checked this with the latest trunk revision.

#12 Updated by Vladimir Tsichevski 7 months ago

Delia Mitric wrote:

The application crashes when we using a DATETIME-TZ FILL-IN and trying to introduce any characters.
I've checked this with the latest trunk revision.

Confirmed. I will create a separate task for the new issue and take ownership of it.

Note that the proposed change does not fully resolve the original problem for datetime and datetime-tz FILL-IN widgets.

When testing the BACKSPACE handling in these types, avoid entering any digits to prevent interference from the new issue.

#13 Updated by Vladimir Tsichevski 7 months ago

  • Related to Bug #11053: DATETIME-TZ FILL-IN crashes in VALUE-CHANGED trigger added

#14 Updated by Vladimir Tsichevski 7 months ago

Vladimir Tsichevski wrote:

Delia Mitric wrote:

The application crashes when we using a DATETIME-TZ FILL-IN and trying to introduce any characters.
I've checked this with the latest trunk revision.

Confirmed. I will create a separate task for the new issue and take ownership of it.

I've created #11053 for this issue.

#15 Updated by Delia Mitric 7 months ago

  • Status changed from WIP to Review
  • % Done changed from 90 to 100

I've committed the fix for DATETIME and DATETIME-TZ fill-ins to 10706a branch rev.16321.
Also, I've noticed that the cursor position is not correct every time when using BACKSPACE on a selection for a date-based fill-in, so I changed it.

I didn't found any regressions for DATETIME fill-in. DATETIME-TZ cannot be tested if we introduce characters.

Vladimir, please review. Thank You!

#16 Updated by Vladimir Tsichevski 7 months ago

  • Related to Bug #11078: Unintended VALUE-CHANGED Event Triggering in DECIMAL, INTEGER, and LOGICAL FILL-IN Widgets added

#17 Updated by Delia Mitric 6 months ago

Vladimir, when you get a chance, please review this one. Thank you!

#18 Updated by Vladimir Tsichevski 6 months ago

Delia Mitric wrote:

Vladimir, when you get a chance, please review this one. Thank you!

10706a rev. 16321 code review and testing.

The change is good, it fixes the original review for date, datetime and datetime-tz.

I would optimize the change a bit and get rid of additional FillIn field isDateBased.
See 10706-optimize.diff.

#19 Updated by Delia Mitric 6 months ago

Vladimir Tsichevski wrote:

Delia Mitric wrote:

Vladimir, when you get a chance, please review this one. Thank you!

10706a rev. 16321 code review and testing.

The change is good, it fixes the original review for date, datetime and datetime-tz.

I would optimize the change a bit and get rid of additional FillIn field isDateBased.
See 10706-optimize.diff.

Rebased the branch to the latest trunk revision and I applied your suggestions to optimize the changes.
Please check out 16371 revision.

#20 Updated by Vladimir Tsichevski 6 months ago

10706a rev. 16371 – Code review & testing

Code review

  1. FillIn.java and FillInGuiImpl.java: newly added history entry lines exceed the 110-character limit.
  2. Questionable caret positioning logic after selection handling:
    // Move cursor at the most left position of the selection
    setCursorOffset(config.selectionStart + 1);
    

    This sets the caret one character right of the selection start, relying on subsequent code to correct it.

Proposed cleaner replacement (please, check if this is safe):

// Move cursor at the most left position of the selection
setCursorOffset(config.selectionStart);
invalidateSelection();
return;

This immediately places the caret correctly and clears the selection without side effects.

Testing results – fixed original issue, new issues found

The proposed change eliminates the unwanted VALUE-CHANGED on plain BACKSPACE.

However, the following related inconsistencies were observed:

  1. Ctrl-Backspace with text selection
    • OE: behaves like plain Backspace — deletes selection, places caret at left boundary of former selection.
    • FWD: caret placement depends on selection direction:
      • Right-to-left selection → caret at left boundary (matches OE)
      • Left-to-right selection → caret at right boundary (incorrect)
  2. Delete key when exactly one delimiter character is selected
    • OE: does nothing (no change, no event)
    • FWD: deselects the character, moves caret, and triggers VALUE-CHANGED event (incorrect)
  3. Ctrl-Delete with selection
    • OE: deletes/replaces selection with spaces, places caret at left boundary (same as plain Delete)
    • FWD: does not delete the selection, places caret at left or right boundary (behaves like current FWD Ctrl-Backspace)
  4. DATETIME (and likely DATETIME-TZ) FILL-IN with unknown screen value:
    When pressing Space, . (dot) or ; (semicolon):
    • OE: ignores the keys (no change, no delimiters shown)
    • FWD: displays all format delimiters

    Note: DATETIME-TZ currently crashes due to #11053, but would likely show the same delimiter-population behaviour if that crash were fixed.

#21 Updated by Hynek Cihlar 3 months ago

  • Status changed from Review to WIP
  • % Done changed from 100 to 90

Code review 10706a revisions 16368..16371

  • [MAJOR] style FillIn.header: History entry 236 line exceeds the 110-character limit (121 chars). Rewrap the description to fit.
  • [MAJOR] style FillInGuiImpl.header: History entry 099 line exceeds the 110-character limit (117 chars). Rewrap the description to fit.
  • [MAJOR] functional FillInGuiImpl.processKeyEvent: setCursorOffset(config.selectionStart + 1) relies on deleteBack() being called later in super.processKeyEvent() to decrement the cursor by 1. The event is not consumed on this path (consumption at line 1282 only fires for !isDateBased), so execution reaches super.processKeyEvent(ke) which invokes deleteBack(). This implicit coupling is fragile - if deleteBack() behavior changes or is bypassed, the cursor position will be wrong. Consider using setCursorOffset(config.selectionStart) with invalidateSelection() and return instead, making cursor positioning self-contained.
  • [MINOR] performance FillIn.isDateBased: config.dataType.toLowerCase() allocates a new String on every call. Since this is invoked once per keystroke from processKeyEvent, consider using equalsIgnoreCase comparisons instead to avoid the per-call allocation.

Also available in: Atom PDF