Skip to content

Commit 39ccb3a

Browse files
deblasisclaude
andcommitted
feat: add Windows support via ConPTY
Add Windows platform support to ghostling using the ConPTY API for pseudo-terminal emulation. The implementation lives entirely in main.c alongside the existing Unix code, gated by #ifdef _WIN32. Key changes: - ConPTY-based pty spawning with shell auto-detection (pwsh > powershell > cmd) - Threaded pipe reader for ConPTY output (PeekNamedPipe is unreliable) - --shell <path> flag for explicit shell selection on all platforms - GUI subsystem build to prevent console window on Windows - Windows CI job on windows-latest - Bump ghostty to include import-lib OUTPUT fix (ghostty-org/ghostty#11794) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent d6e707a commit 39ccb3a

4 files changed

Lines changed: 563 additions & 46 deletions

File tree

.github/workflows/test.yml

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,3 +59,22 @@ jobs:
5959
run: |
6060
nix develop -c cmake -B build -G Ninja
6161
nix develop -c cmake --build build
62+
63+
build-windows:
64+
runs-on: windows-latest
65+
steps:
66+
- name: Checkout code
67+
uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1
68+
69+
- name: Setup Zig
70+
uses: mlugg/setup-zig@v2
71+
with:
72+
version: 0.15.2
73+
74+
- name: Setup Ninja
75+
uses: seanmiddleditch/gha-setup-ninja@7e868db0f3406270dd46e1dac26c65f621456723 # master
76+
77+
- name: Build
78+
run: |
79+
cmake -B build -G Ninja
80+
cmake --build build

CMakeLists.txt

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,9 +28,11 @@ endif()
2828
# The Ghostty CMakeLists.txt delegates to `zig build lib-vt` to produce the
2929
# shared library. See https://ghostty.org/docs/install/build for the
3030
# required Zig version.
31+
# TODO: point back to ghostty-org/ghostty once the import-lib OUTPUT fix
32+
# lands upstream (see: https://github.com/ghostty-org/ghostty/pull/11794).
3133
FetchContent_Declare(ghostty
32-
GIT_REPOSITORY https://github.com/ghostty-org/ghostty.git
33-
GIT_TAG ecc55b94c803789762682065ab68f227447909c5
34+
GIT_REPOSITORY https://github.com/deblasis/ghostty.git
35+
GIT_TAG 7d31d9b57f7064f74cd8a098189d2f9248ef4dd5
3436
)
3537
FetchContent_MakeAvailable(ghostty)
3638

@@ -56,9 +58,25 @@ target_compile_features(${PROJECT_NAME} PRIVATE c_std_11)
5658
target_include_directories(${PROJECT_NAME} PRIVATE "${CMAKE_BINARY_DIR}")
5759
target_link_libraries(${PROJECT_NAME} raylib ghostty-vt)
5860

61+
# Build as a GUI subsystem app on Windows so we don't get a console window.
62+
# Without this, the child shell inherits our console and writes there instead
63+
# of through the ConPTY pipe. We keep main() as the entry point.
64+
if(WIN32)
65+
set_target_properties(${PROJECT_NAME} PROPERTIES WIN32_EXECUTABLE TRUE)
66+
# MSVC/Clang need an explicit entry point override to keep main() as the
67+
# entry point in a GUI subsystem app. MinGW handles this automatically.
68+
if(MSVC OR (CMAKE_C_COMPILER_ID STREQUAL "Clang" AND NOT MINGW))
69+
target_link_options(${PROJECT_NAME} PRIVATE "LINKER:/ENTRY:mainCRTStartup")
70+
endif()
71+
endif()
72+
5973
# macOS requires these system frameworks for raylib's windowing/input/rendering.
6074
if (APPLE)
6175
target_link_libraries(${PROJECT_NAME} "-framework IOKit")
6276
target_link_libraries(${PROJECT_NAME} "-framework Cocoa")
6377
target_link_libraries(${PROJECT_NAME} "-framework OpenGL")
6478
endif()
79+
80+
# Windows: ConPTY APIs (used for terminal emulation) are provided by kernel32.lib,
81+
# which is linked implicitly by default on all Windows compilers (MSVC, MinGW-w64, Clang).
82+
# No explicit target_link_libraries() call is needed for Windows.

README.md

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,7 @@ Ghostling is a demo project meant to highlight a minimum
44
functional terminal built on the libghostty C API in a
55
[single C file](https://github.com/ghostty-org/ghostling/blob/main/main.c).
66

7-
The example uses Raylib for windowing and rendering. It is single-threaded
8-
(although libghostty-vt supports threading) and uses a 2D graphics renderer
7+
The example uses Raylib for windowing and rendering. It uses a 2D graphics renderer
98
instead of a direct GPU renderer like the primary [Ghostty](https://ghostty.org) GUI. This is to
109
showcase the flexibility of libghostty and how it can be used in a variety of
1110
contexts.
@@ -64,11 +63,6 @@ These features aren't properly exposed by libghostty-vt yet but will be:
6463
- OSC clipboard support
6564
- OSC title setting
6665

67-
These are things that could work but haven't been tested or aren't
68-
implemented in Ghostling itself:
69-
70-
- Windows support (libghostty-vt supports Windows)
71-
7266
This list is incomplete and we'll add things as we find them.
7367

7468
### What You Won't Ever Get
@@ -112,9 +106,13 @@ Requirements:
112106
```sh
113107
cmake -B build -G Ninja
114108
cmake --build build
115-
./build/ghostling
109+
./build/ghostling # Linux / macOS
110+
.\build\ghostling.exe # Windows
116111
```
117112

113+
On Windows, ghostling uses ConPTY and auto-detects the best available
114+
shell (pwsh > powershell > cmd). Use `--shell <path>` to override.
115+
118116
> [!WARNING]
119117
>
120118
> Debug builds are VERY SLOW since Ghostty included a lot of extra

0 commit comments

Comments
 (0)