# SPDX-License-Identifier: MIT # Copyright (c) 2026 code@svcomplex.ai # svw - example Tcl plugin that owns an opaque fullscreen TUI surface. source [file join [file dirname [info script]] svw_plugin.tcl] set ::demo_surface_ready 0 set ::demo_mode fullscreen set ::demo_width 0 set ::demo_height 0 set ::demo_cursor unknown set ::demo_signal "" set ::demo_status "native link idle" set ::demo_dock_width 0 set ::demo_dock_height 0 proc paint_surface {width height title lines {claim_focus true}} { ::svw::surface_clear root ::svw::surface_text root 2 1 $title -fg palette:12 set row 3 foreach line $lines { if {$row >= $height - 1} { break } ::svw::surface_text root 2 $row $line -fg palette:7 incr row } ::svw::surface_commit root if {$claim_focus} { ::svw::focus root } } proc draw_demo {event} { set width [dict get $event width] set height [dict get $event height] set ::demo_width $width set ::demo_height $height if {$width eq "" || $height eq "" || $width < 20 || $height < 8} { return } if {$::demo_mode eq "dock"} { return } if {$::demo_surface_ready} { ::svw::surface_destroy root } ::svw::surface_create root 0 0 $width $height \ -mode fullscreen -z 100 -opaque true -focusable true paint_surface $width $height "Tcl owns this svw UI" [list \ "Resize is delivered as an event." \ "Press m for a mixed core/plugin layout." \ "Press q to return to svw; press Esc three times for emergency recovery." \ "No ANSI or terminal descriptor is exposed to this plugin."] set ::demo_surface_ready 1 set ::demo_mode fullscreen } proc draw_dock {event} { if {[dict get $event surface] ne "root" || $::demo_mode ne "dock"} { return } set width [dict get $event width] set height [dict get $event height] set ::demo_dock_width $width set ::demo_dock_height $height paint_surface $width $height "Tcl dock" [list \ "builtin.frame is live" \ "state cursor: $::demo_cursor" \ "selected signal: $::demo_signal" \ "beside this surface." \ "Press Enter to reveal that signal/time in native panels." \ $::demo_status \ "Press f for fullscreen." \ "Press q to unload."] } proc handle_state {event} { if {[dict exists $event cursor]} { set ::demo_cursor [dict get $event cursor] } if {[dict exists $event selected_signal]} { set ::demo_signal [dict get $event selected_signal] } } proc enter_dock {} { set ::demo_mode dock ::svw::surface_destroy root ::svw::surface_create root 0 0 1 1 \ -mode overlay -z 100 -opaque true -focusable true set core [::svw::layout::leaf core builtin.frame \ -weight 3 -min_width 40 -min_height 14] set dock [::svw::layout::leaf dock surface:root \ -cells 24 -min_width 20 -min_height 8] set layout [::svw::layout::row root [list $core $dock] -gap 1] ::svw::layout_replace $layout } proc enter_fullscreen {} { set ::demo_mode fullscreen ::svw::layout_restore ::svw::surface_destroy root set ::demo_surface_ready 0 draw_demo [dict create width $::demo_width height $::demo_height] } proc navigation_done {line} { set problem [::svw::string_field $line {error message}] set ::demo_status [expr {$problem eq "" ? "native W linked: $::demo_signal @ $::demo_cursor" : $problem}] if {$::demo_mode eq "dock" && $::demo_dock_width > 0} { paint_surface $::demo_dock_width $::demo_dock_height "Tcl dock" [list \ "builtin.frame is live" \ "state cursor: $::demo_cursor" \ "selected signal: $::demo_signal" \ "beside this surface." \ "Press Enter to reveal that signal/time in native panels." \ $::demo_status \ "Click this pane to regain plugin focus." \ "Press q to unload."] false } } proc handle_input {event} { set key [dict get $event key] if {$key eq "enter" && $::demo_mode eq "dock" && $::demo_signal ne "" && $::demo_cursor ne "unknown"} { ::svw::reveal_wave $::demo_signal $::demo_cursor false navigation_done return } if {$key ne "char"} { return } set character [dict get $event character] if {$character eq "q"} { # shutdown atomically releases this plugin's surfaces, layout and # focus lease in the host, so no teardown request can race Tcl exit. ::svw::shutdown } elseif {$character eq "m" && $::demo_mode eq "fullscreen"} { enter_dock } elseif {$character eq "f" && $::demo_mode eq "dock"} { enter_fullscreen } } ::svw::on ui.resize draw_demo ::svw::on ui.layout draw_dock ::svw::on ui.input handle_input ::svw::on state.changed handle_state after 0 {::svw::subscribe {cursor view selection focus wave}} ::svw::run