Skip to content

Repository files navigation

wGac — Wayland Port of GacUI

中文版

wGac implements the native GacUI platform layer for Linux Wayland using Wayland, Cairo, Pango, and XKBCommon.

Ask DeepWiki

Prerequisites

The committed Import/ and Apps/ snapshots make a normal build self-contained. On Debian or Ubuntu, install:

sudo apt update
sudo apt install build-essential clang cmake pkg-config \
    libwayland-dev libxkbcommon-dev \
    libdecor-0-dev libdecor-0-plugin-1-gtk \
    libcairo2-dev libpango1.0-dev libfontconfig1-dev \
    libgdk-pixbuf-2.0-dev libglib2.0-dev liburing-dev

The retained WGacDialogService implementation uses GIO, but current Wayland applications select FakeDialogService and do not require a desktop portal backend.

Run applications from a Wayland desktop session with WAYLAND_DISPLAY and XDG_RUNTIME_DIR available.

wGac requires libdecor and a real runtime decoration plugin at startup; it stops with a diagnostic instead of silently accepting libdecor's undecorated fallback. To make repeated switches between GacUI custom frames and platform frames safe on every compositor, wGac forces libdecor to provide its client-side platform frame even when server-side decorations are available. This libdecor frame is the native platform frame from GacUI's perspective and is distinct from GacUI's custom window template.

For maintenance work, keep the GacUI, Workflow, and Tools repositories beside wGac, or run ./syncOrg.sh. import.sh reads GacUI framework snapshots, and syncProj.sh reads GacUI test resources and builds the Workflow and GacUI generators. The sibling Release repository is not a build or import dependency.

Project Structure

wGac/
├── WGac/                              Wayland platform implementation
│   ├── Protocol/                      Committed Wayland protocol sources
│   ├── Renderers/                     Cairo/Pango GacUI renderer
│   ├── Services/                      Native platform and automation services
│   └── Wayland/                       Display, seat, and buffer integration
├── WGacShared/                        GacUI, wGac, and shared test libraries
├── WGacTest/                          Hello World test app
├── WGacFullControlTest/               Full Control Test, standard or hosted
├── RemotingTest_Renderer_Wayland/     Native renderer for RemotingTest_Core
├── Apps/                              Synchronized resources and generated C++
├── Import/                            Imported GacUI amalgamated sources
├── import.sh                          Refresh Import from sibling GacUI
├── syncProj.sh                        Refresh and generate Apps and shared sources
├── syncOrg.sh                         Synchronize sibling organization repositories
├── build.sh                           Build all test targets
└── test.sh                            Launch one test target

Import/ is frozen after ./import.sh; framework fixes belong in GacUI, and Wayland compatibility fixes belong in wGac. Files under Apps/*/Resources/ and Apps/*/Source/ are synchronized or generated by ./syncProj.sh and must not be edited directly.

Synchronizing Dependencies

Synchronize the sibling organization repositories:

./syncOrg.sh

Refresh the imported framework snapshot:

./import.sh

This replaces Import/ with files from ../GacUI/Import/ and ../GacUI/Release/, adds the DarkSkin release sources, and marks the result read-only.

Refresh the Full Control Test and Remote Protocol Test projects:

./syncProj.sh

This incrementally builds Workflow's CppMerge and GacUI's GacGen, copies the upstream resource trees, regenerates their x64 C++ sources under Apps/, copies the portable MiniHTTP automation service into WGacShared/, and copies the portable native-renderer entry point into RemotingTest_Renderer_Wayland/.

Building

./build.sh
./build.sh --rebuild

The first command is incremental. --rebuild removes ignored build output with git clean -xdf and performs a clean build, so commit or stage any new source files before using it.

The root CMake project uses C++23 and builds:

  • GacUI, the imported GacUI framework.
  • WGac, the Wayland platform layer.
  • WGacShared, shared MiniHTTP automation support.
  • Test_HellWorld_Cpp.
  • Test_FullControlTest.
  • RemotingTest_Renderer_Wayland.

Running and Automation

./test.sh --app:simple
./test.sh --app:simple --unblock
./test.sh --app:fct
./test.sh --app:fct --hosted
./test.sh --app:fct --hosted --unblock
./test.sh --app:renderer
./test.sh --app:renderer --unblock

--hosted is valid only with --app:fct. --unblock starts the selected executable in the background and prints its PID.

The normal applications expose MiniHTTP automation on port 8888:

  • Hello World: /Automation/Test_HellWorld_Cpp
  • Full Control Test: /Automation/Test_FullControlTest

For example:

curl http://localhost:8888/Automation/Test_HellWorld_Cpp/Controls
curl -H 'Content-Type: application/json; charset=utf8' \
    --data '!Exit' \
    http://localhost:8888/Automation/Test_HellWorld_Cpp/IO

Use GET .../Controls to inspect the control tree and POST .../IO or POST .../IO/<windowId> to send an IO command. A successful command returns Queued.

Always stop background test processes when verification is complete.

Native Remote Renderer

Build and start GacUI/Test/Linux/RemotingTest_Core in /MiniHttp mode for either /RPT or /FCT, then run:

./test.sh --app:renderer

The core listens on port 8888. The Wayland renderer connects through /MiniHttp and exposes its DOM and renderer-side IO on port 8889 at:

/Automation/RemotingTest_Renderer_Wayland

Follow GacUI's native-renderer verification guide for the complete RPT/FCT, replacement, takeover, and cleanup workflow.

Known Limitations

  • Native Dialogs:
    • The native FileChooser portal is implemented for open and save dialogs.
    • Message box not implemented.
    • Color picker not implemented.
    • Font picker not implemented.
    • These are limitations of WGacDialogService; the Wayland implementation currently always uses GacUI's FakeDialogService, so applications do not invoke any native dialog.
  • Wayland does not allow clients to position normal top-level windows globally; placement requests are compositor-dependent.
  • libdecor has no platform-frame window-icon API, so IconVisible is unsupported and always reports false.
  • libdecor cannot independently hide the maximize control. Its maximize affordance follows SizeBox (the frame's resize capability); MaximizedBox retains its requested value but cannot override that platform limitation.

About

Wayland Port for GacUI

Resources

Stars

Watchers

Forks

Releases

Packages

Contributors

Languages