With tab stop
ImGui’s PushTabStop / PopTabStop pair lets you control which widgets
participate in TAB / Shift+TAB focus cycling. The boost layer wraps it as a
stateless scope wrapper:
with_tab_stop(false) {
input_text(TS_FIELD_SKIP, (text = "Skipped by TAB", init = "..."))
}
The wrapper itself emits no telemetry — it only pushes the tab-stop flag on
entry and pops it on exit, matching the rest of the with_* family
(with_indent, with_disabled, with_button_repeat, with_font,
with_clip_rect).
Source: examples/tutorial/with_tab_stop.das.
Walkthrough
1options gen2
2
3require imgui
4require imgui_app
5require opengl/opengl_boost
6require live/glfw_live
7require live/live_api
8require live/live_commands
9require live/live_vars
10require live_host
11require imgui/imgui_live
12require imgui/imgui_boost_runtime
13require imgui/imgui_boost_v2
14require imgui/imgui_widgets_builtin
15require imgui/imgui_containers_builtin
16require imgui/imgui_scope_builtin
17require imgui/imgui_visual_aids
18
19// =============================================================================
20// TUTORIAL: with_tab_stop — stateless scope wrapper around PushTabStop /
21// PopTabStop. While the wrapped block is active, every widget
22// inside is skipped by TAB / Shift+Tab focus cycling. Useful for
23// help markers or decorative inputs that shouldn't steal keyboard
24// focus when navigating an editable form.
25//
26// with_tab_stop(false) { widgets_to_skip... }
27//
28// STANDALONE: daslang.exe modules/dasImgui/examples/tutorial/with_tab_stop.das
29// LIVE: daslang-live modules/dasImgui/examples/tutorial/with_tab_stop.das
30// =============================================================================
31
32[export]
33def init() {
34 live_create_window("dasImgui with_tab_stop tutorial", 760, 460)
35 live_imgui_init(live_window)
36 let io & = unsafe(GetIO())
37 GetStyle().FontScaleMain = 1.4
38}
39
40[export]
41def update() {
42 if (!live_begin_frame()) return
43 begin_frame()
44
45 ImGui_ImplGlfw_NewFrame()
46 apply_synth_io_override()
47 NewFrame()
48
49 SetNextWindowPos(ImVec2(40.0f, 40.0f), ImGuiCond.Always)
50 SetNextWindowSize(ImVec2(720.0f, 400.0f), ImGuiCond.Always)
51 window(TS_WIN, (text = "with_tab_stop", closable = false,
52 flags = ImGuiWindowFlags.None)) {
53 text("Press TAB / Shift+TAB to cycle focus.")
54 text("The middle field is wrapped in with_tab_stop(false) - TAB skips it.")
55 separator()
56
57 input_text(TS_FIELD_A, (text = "Field A"))
58 input_text(TS_FIELD_B, (text = "Field B"))
59
60 with_tab_stop(false) {
61 input_text(TS_FIELD_SKIP,
62 (text = "Skipped by TAB", init = "(unreachable via keyboard)"))
63 }
64
65 input_text(TS_FIELD_C, (text = "Field C"))
66 input_text(TS_FIELD_D, (text = "Field D"))
67 }
68
69 end_of_frame()
70 Render()
71 var w, h : int
72 live_get_framebuffer_size(w, h)
73 glViewport(0, 0, w, h)
74 glClearColor(0.10f, 0.10f, 0.12f, 1.0f)
75 glClear(GL_COLOR_BUFFER_BIT)
76 live_imgui_render()
77
78 live_end_frame()
79}
80
81[export]
82def shutdown() {
83 live_imgui_shutdown()
84 live_destroy_window()
85}
86
87[export]
88def main() {
89 init()
90 while (!exit_requested()) {
91 update()
92 }
93 shutdown()
94}
Requires
Same baseline as the other with_* wrappers — already in
imgui/imgui_scope_builtin (re-exported by imgui/imgui_boost_v2).
Behaviour
While the wrapped block is active, every focusable widget inside has its ImGui tab-stop flag suppressed:
TAB and Shift+TAB cycling skip past those widgets.
Mouse click still focuses the widget (tab-stop is keyboard-only).
Programmatic focus (
SetKeyboardFocusHere) still works.
The flag scope follows the block exactly: as soon as the wrapped block
exits, the previous tab-stop policy is restored, so wrapping a help-marker
or decorative input inside with_tab_stop(false) doesn’t leak the
suppression onto sibling widgets.
When to reach for it
The two recurring shapes:
Help markers / tooltips — a
(?)glyph that opens an info popup on hover but shouldn’t intercept TAB navigation through the editable form.Decorative inputs — a read-only field that displays computed state next to editable siblings; keyboard navigation should skip past it entirely.
The same pattern is used in examples/imgui_demo/inputs.das — both the
Tabbing and Focus-from-code sub-sections wrap their “(tab skip)” field +
help marker in with_tab_stop(false) { ... }.
Standalone vs live
Same convention as the other scope-wrapper tutorials. daslang.exe runs
the demo headlessly to frame N; daslang-live keeps the window open
and reloads on source edits.
See also
Full source: examples/tutorial/with_tab_stop.das
Integration test: tests/integration/test_with_tab_stop.das.
Boost macros — the macro layer.