#10023·TiddlyWiki5

[Report] $edit-text with focus="yes" does not takes keyboard focus when inside a modal

Author: superuser-doesCreated Sep 11, 2026Updated Sep 11, 2026

Problem description

An <$edit-text> field with focus="yes" inside a modal opened with tm-modal never receives focus, regardless of how the modal is opened (whether by clicking a button or using a keyboard shortcut).

The same attribute works when the tiddler is opened in the story river, so modals are a specific context where focus silently does nothing.

tm-focus-selector does work for this use case as a workaround but it is naturally more obscure. I would not have thought to do it without AI assistance.

To reproduce

Import this 6-tiddler JSON and then:

  1. Open the Open modal tiddler and click Open modal. The modal opens, but the field does not receive focus.
  2. Close the modal and click Open modal (focused). This is identical to the first button except that a tm-focus-selector message is sent immediately after tm-modal. The field is focused.
  3. Press Alt+R. The modal with a simple focus="yes" opens, and the field again does not receive focus.
  4. Press Alt+F. This is the same trigger but with the explicit tm-focus-selector step. The field is focused. So the step works from the keyboard too.

For contrast, you can transclude {{Focus modal}} into any regular tiddler. The field will receive focus from focus="yes" alone.

Expected behaviour

As a user, I would expect focus="yes" to focus the field inside a modal exactly as it does in the story river, Without having to know that an extra tm-focus-selector message must be sent after every tm-modal.

Environment

TiddlyWiki configuration

  • Version: v5.4.1
  • Saving mechanism: Not relevant
  • Plugins installed: Not relevant

Desktop

  • OS: Fedora Linux 44 KDE Edition
  • Browser: Ungoogled Chromium 152.0.7977.82

Additional context

I use keyboard shortcuts to open modals for a to-do list application (a new tiddler creation form, the first field of which is the title). I need to reach for the mouse to focus the first field, and I would prefer to be able to start typing my new tiddler title right away.

A keyboard shortcut is where it is most problematic, because the user is already at the keyboard.

Workaround

May give you some ideas for the solution.

You can work around this by sending an explicit tm-focus-selector message after every tm-modal, as the second button (Alt+F) does in the wiki.

Current state analysis using AI (GLM-5.3 Flash)

focus is implemented at render time. $:/core/modules/editor/factory.js, in EditTextWidget.render():

javascript
// Focus if required
if($tw.browser && (this.editFocus === "true" || this.editFocus === "yes") && !$tw.utils.hasClass(this.parentDomNode.ownerDocument.activeElement,"tc-keep-focus")) {
    this.engine.focus();
}

The engines focus synchronously — e.g. SimpleEngine.focus() in $:/core/modules/editor/engines/simple.js just calls this.domNode.focus().

tm-modal is handled by $tw.modal.display() in $:/core/modules/utils/dom/modal.js, whose ordering is the problem:

javascript
bodyWidgetNode.render(modalBody,null);      // modal body rendered here — wrapper not yet in the document
...
// Put the message into the document
this.srcDocument.body.appendChild(wrapper); // append happens only afterwards

All four widget trees of the modal (navigator, header, body, footer) are rendered while wrapper is detached from the document; the single appendChild(wrapper) comes later in the same function. So at the moment engine.focus() runs, the field has no connection to the document, and per browser behaviour .focus() on such an element is a no-op — document.activeElement is unchanged, and nothing re-focuses the field after the append. (The activeElement guard in the focus block passes because ownerDocument is still the real document during detached rendering.)

Steps 2 and 4 of the reproduction confirm both halves of that diagnosis: an explicit tm-focus-selector sent after the modal has attached works from either trigger, and the identical widget focuses from focus="yes" alone when rendered attached. The only thing at fault is the timing of the render-time focus attempt relative to the append.