iWish — Tcl/Tk for iOS

A port of Tcl/Tk (AndroWish / undroidwish, full extension set) to 64-bit iOS and iPadOS.

iwish on GitHub →

What it is

iWish is a port of AndroWish's undroidwish — the batteries-included, SDL2-rendered Tcl/Tk wish — to iOS and iPadOS (with a Mac Catalyst build alongside).

It runs a real Tcl 8.6 interpreter and the real Tk 8.6 widget set on an iPhone or iPad. Tk is drawn through AndroWish's SdlTk — an X11-on-SDL2 emulation layer — using the AGG anti-aliased renderer for graphics and FreeType for text, composited onto an SDL2 Metal surface. There is no WebView and no native-UIKit-widget bridge: it is the actual Tk canvas and widgets, running on the device.

The whole stack — Tcl, Tk/SdlTk, SDL2, AGG, FreeType — is statically linked into a single sdl2wish binary, compiled for arm64-apple-ios.

Status

0.2 — alpha. The runtime runs a large third-party Tk application end-to-end on a physical iPad: full GUI, the batteries-included extension set, a bundled demo menu, and hardware access over CoreBluetooth. APIs, the build layout, and the bundled extension set are still in flux.

What's included (batteries)

Every build (device and Catalyst) bundles the AndroWish extension set plus built-in demo apps; the bare runtime is not shipped separately.

Building & signing (high level)

The repo is a recipe — build scripts, a set of patches against upstream, and the iOS-native glue code. It does not redistribute AndroWish, SDL2, or Tcl/Tk; you fetch those and apply the patches.

Rough shape of a build:

  1. Get an AndroWish checkout and a stock SDL 2.30.11 source tree.
  2. Apply the iWish patches (apply-patches.sh).
  3. Build the foundation — FreeType, SDL2, AndroWish Tcl, sdl2tk and sdl2wish — all for arm64-apple-ios, at TCL_UTF_MAX=6.
  4. Build the loadable extension stack and stage the full battery set into the bundle's lib-batteries/.
  5. Compile the src-ios/ shims (borg / ble / hardexit) to dylibs.
  6. Assemble the .app: the renamed sdl2wish binary, lib/tcl8.6 + lib/tk8.6, main.tcl + payload, an Info.plist (landscape orientations, status bar hidden, MinimumOSVersion 15.0), and the lib-batteries/.
  7. Build the app icon (any image → opaque 1024×1024 → asset catalog via actool).
  8. Wrap every native dylib in its own .framework bundle under Frameworks/ (see Implementation notes) — required for AltStore/SideStore.
  9. Sign and install to a device.

Signing uses a standard Apple Development certificate plus a provisioning profile that includes the target device's UDID. Distribution is via TestFlight / sideload / EU notarization — App Store policy 2.5.2 forbids interpreters that load downloaded code. (This page omits the project's private signing identities, team IDs, device UDIDs, and local paths.)

Implementation notes

The port reconciles a threaded X11-style toolkit with UIKit's main-thread rules and pixel model. Fixes:

Repository

Source, build scripts, and patches: https://github.com/johnbuckman/iwish

Part of the Tcl/Tk on modern platforms collection. Sibling projects build the same stack as a native Apple-Silicon macOS binary and as a 32-bit armv7 / iOS 9 full-source snapshot for old jailbroken devices.