Martin Fischer - 2026-10-05

I gave this bug to Claude. See the full analysis below.

The bug is in the Win32 wlib, not in cselect.c or ctext.c, and it isn't really specific to the German layout. The fix is a one-line change in app/wlib/mswlib/mswmisc.c.
I haven't changed anything, and I can't build or test Win32 here.

What happens when you type . with the mouse over the canvas:

  1. Windows sends WM_CHAR with wParam = '.', which is 0x2E. That is the same number as VK_DELETE. WM_CHAR carries a character, while VK_* are key codes, so the code mixes
    up two different kinds of value.
  2. The main window procedure (mswmisc.c:2858) handles WM_CHAR and WM_KEYUP together. When the cursor is over the canvas, it hands the message on to the draw window
    (mswmisc.c:2897). On the way it marks the message as a special key ("extended", bit 24 of lParam) if wParam equals VK_UP, VK_DOWN, VK_RIGHT, VK_LEFT, VK_INSERT or
    VK_DELETE. That marking is meant for the number-pad keys on WM_KEYUP, but it is applied to WM_CHAR too.
  3. Because of that mark, the draw window (mswdraw.c:1788) reads 0x2E as VK_DELETE and sends wActionExtKey | wAccelKey_Del instead of the text '.'.
  4. draw.c:2584 (DoPanKeyAction) then calls SelectDelete(). You're in the Text command, not Select mode, so cselect.c:758 shows "Delete only works in Select Mode".

The same problem hits five other characters, because their codes also equal one of those key codes:

All of these are lost when typed with the cursor over the canvas, on any keyboard layout. A real Delete key is not affected: it produces no WM_CHAR and reaches the
canvas through the WM_KEYUP path.

Proposed fix (mswmisc.c:2898): only mark these keys as special for WM_KEYUP.

          if (b && b->type == B_DRAW) {
              // Change Num keypad to a special code to emulate cursor keys

  -            if (wParam == VK_UP ||
  +            if (message == WM_KEYUP &&
  +                    (wParam == VK_UP ||
                      wParam == VK_DOWN ||
                      wParam == VK_RIGHT ||
                      wParam == VK_LEFT ||
                      wParam == VK_INSERT ||
  -                    wParam == VK_DELETE) {
  +                    wParam == VK_DELETE)) {

After this, typed characters go through as text. The number-pad and real cursor/Ins/Del keys keep working, because they still come in on WM_KEYUP. No real character key
is a Windows "extended" key, so a typed character never carries that mark and the draw window's check at mswdraw.c:1791 treats it as text.

To check on Windows, with the cursor over the canvas:

  • Type ., -, %, ( in a text label. Each should appear as a character.
  • Delete with selected tracks in Select mode should still delete them.
  • The arrow keys and number-pad arrows should still pan.
 

Last edit: Martin Fischer 2026-10-05