From 41867429a5d1548421843df0197923619723d34f Mon Sep 17 00:00:00 2001 From: Daniel Legt Date: Fri, 17 Jul 2026 19:35:08 +0300 Subject: [PATCH] fix(build): ensure gtk4-layer-shell loads before libwayland-client - Update CGO_LDFLAGS in build scripts to include gtk4-layer-shell with the correct load order. - Add a new layershell_link.go file to maintain the dependency on gtk4-layer-shell. - Modify overlay_gtk.go to clarify the importance of load order for Layer Shell functionality. - Enhance run.sh to preload gtk4-layer-shell for proper overlay positioning. --- scripts/ci/package-release.sh | 5 +++-- scripts/distrobox/build.sh | 3 +++ scripts/distrobox/run.sh | 7 +++++++ src/cmd/captioneer-desktop/layershell_link.go | 21 +++++++++++++++++++ src/output/overlay/overlay_gtk.go | 7 ++++--- 5 files changed, 38 insertions(+), 5 deletions(-) create mode 100644 src/cmd/captioneer-desktop/layershell_link.go diff --git a/scripts/ci/package-release.sh b/scripts/ci/package-release.sh index b209742..2163926 100755 --- a/scripts/ci/package-release.sh +++ b/scripts/ci/package-release.sh @@ -32,11 +32,12 @@ mkdir -p -- \ # The Sherpa Go module embeds an absolute build-machine RPATH. Add a portable # build-time fallback; the final paths are normalized after dependency copying. +# gtk4-layer-shell must precede libwayland-client so its Wayland shim installs. # shellcheck disable=SC2016 # $ORIGIN must remain literal for the ELF loader. -CGO_LDFLAGS='-Wl,-rpath,$ORIGIN/lib' \ +CGO_LDFLAGS='-Wl,--no-as-needed -lgtk4-layer-shell -Wl,-rpath,$ORIGIN/lib' \ go build -trimpath -o "$package_dir/captioneer" ./src/cmd/captioneer # shellcheck disable=SC2016 # $ORIGIN must remain literal for the ELF loader. -CGO_LDFLAGS='-Wl,-rpath,$ORIGIN/lib' \ +CGO_LDFLAGS='-Wl,--no-as-needed -lgtk4-layer-shell -Wl,-rpath,$ORIGIN/lib' \ go build -trimpath -tags gtk \ -o "$package_dir/captioneer-desktop" ./src/cmd/captioneer-desktop diff --git a/scripts/distrobox/build.sh b/scripts/distrobox/build.sh index f5efcb0..64d9710 100755 --- a/scripts/distrobox/build.sh +++ b/scripts/distrobox/build.sh @@ -19,6 +19,9 @@ build_script='set -Eeuo pipefail repo_root=$1 shift cd -- "$repo_root" +# gtk4-layer-shell must precede libwayland-client in the loader order or the +# Wayland shim never installs and the overlay cannot be positioned. +export CGO_LDFLAGS="-Wl,--no-as-needed -lgtk4-layer-shell ${CGO_LDFLAGS:-}" go build "$@" -o build/captioneer ./src/cmd/captioneer go build "$@" -tags gtk -o build/captioneer-desktop ./src/cmd/captioneer-desktop' diff --git a/scripts/distrobox/run.sh b/scripts/distrobox/run.sh index 9652e7a..1bc3a6f 100755 --- a/scripts/distrobox/run.sh +++ b/scripts/distrobox/run.sh @@ -15,6 +15,13 @@ cd -- "$repo_root" # Avoid host/container DMABUF incompatibilities on mismatched GPU stacks. An # explicit GTK renderer choice still takes precedence. export GSK_RENDERER="${GSK_RENDERER:-cairo}" +# gtk4-layer-shell must load before libwayland-client or its Wayland shim is +# skipped and the overlay sits as an unpositioned normal window. +layer_shell_lib="$(pkg-config --variable=libdir gtk4-layer-shell-0)/libgtk4-layer-shell.so.0" +if [[ -f "$layer_shell_lib" ]]; then + export LD_PRELOAD="${layer_shell_lib}${LD_PRELOAD:+:$LD_PRELOAD}" +fi +export CGO_LDFLAGS="-Wl,--no-as-needed -lgtk4-layer-shell ${CGO_LDFLAGS:-}" exec go run -tags gtk ./src/cmd/captioneer-desktop "$@"' exec distrobox enter --no-workdir --name "$container_name" -- \ diff --git a/src/cmd/captioneer-desktop/layershell_link.go b/src/cmd/captioneer-desktop/layershell_link.go new file mode 100644 index 0000000..b4c54c0 --- /dev/null +++ b/src/cmd/captioneer-desktop/layershell_link.go @@ -0,0 +1,21 @@ +//go:build gtk + +package main + +/* +#cgo pkg-config: gtk4-layer-shell-0 +#cgo LDFLAGS: -Wl,--no-as-needed -lgtk4-layer-shell + +// gtk4-layer-shell shims libwayland-client. It must appear before +// libwayland-client in the dynamic loader order or gtk_layer_is_supported() +// returns false and the overlay becomes an unpositioned normal window. +// Referencing the symbol from the main package keeps the dependency alive +// even when the external linker would otherwise drop or reorder it. +#include + +static void captioneer_keep_layershell_linked(void) __attribute__((used)); +static void captioneer_keep_layershell_linked(void) { + (void)gtk_layer_get_major_version; +} +*/ +import "C" diff --git a/src/output/overlay/overlay_gtk.go b/src/output/overlay/overlay_gtk.go index 359bf73..df46c55 100644 --- a/src/output/overlay/overlay_gtk.go +++ b/src/output/overlay/overlay_gtk.go @@ -4,8 +4,9 @@ package overlay /* -#cgo pkg-config: gtk4 gtk4-x11 gtk4-wayland gtk4-layer-shell-0 -#cgo LDFLAGS: -lX11 +#cgo pkg-config: gtk4-layer-shell-0 +#cgo pkg-config: gtk4 gtk4-x11 gtk4-wayland +#cgo LDFLAGS: -Wl,--no-as-needed -lgtk4-layer-shell -lX11 #include #include @@ -356,7 +357,7 @@ static CaptioneerOverlay *captioneer_overlay_new( } } else if (wayland) { captioneer_append_warning(warnings, - "The Wayland compositor does not support Layer Shell; using a normal window without guaranteed always-on-top, placement, taskbar, or fullscreen behavior."); + "Layer Shell is unavailable in this process (often a libwayland load-order problem); using a normal window without guaranteed always-on-top or placement. Try rebuilding so libgtk4-layer-shell loads before libwayland-client, or set overlay backend to x11."); } GdkMonitor *size_monitor = overlay->monitor;