From a76a9a3eaddfd69b478bd5928f8d52ecb112d88b Mon Sep 17 00:00:00 2001 From: Julian Storer Date: Wed, 12 Aug 2026 13:36:47 +0100 Subject: [PATCH] fix(linux): apply the window title to frameless windows MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit setTitle skipped gtk_window_set_title whenever the window was created with Frameless: true. newWindowImpl applies options.Title through that same method, so a frameless window never received a title at all, and every later SetTitle call was dropped too. On Linux the title is not a titlebar: gtk_window_set_title writes the WM_NAME/_NET_WM_NAME hints that taskbars, window switchers and pagers label the window with. Decorations are governed separately, by gtk_window_set_decorated in setFrameless/setBorderless, so titling an undecorated window draws nothing. The visible effect was that every window of a frameless application carried the same label — the g_set_prgname fallback — leaving multiple windows indistinguishable in the taskbar and in alt-tab. Applies to both the GTK4 and GTK3 backends. --- v3/UNRELEASED_CHANGELOG.md | 1 + v3/pkg/application/linux_cgo.go | 12 +++++++----- v3/pkg/application/linux_cgo_gtk3.go | 12 +++++++----- 3 files changed, 15 insertions(+), 10 deletions(-) diff --git a/v3/UNRELEASED_CHANGELOG.md b/v3/UNRELEASED_CHANGELOG.md index 33638e7fc86..a1090a967fb 100644 --- a/v3/UNRELEASED_CHANGELOG.md +++ b/v3/UNRELEASED_CHANGELOG.md @@ -23,6 +23,7 @@ After processing, the content will be moved to the main changelog and this file ## Fixed +- Apply the window title to frameless windows on Linux, so taskbars and window switchers can tell an application's windows apart in [PR](https://github.com/wailsapp/wails/pull/5960) by @julianstorer ## Deprecated diff --git a/v3/pkg/application/linux_cgo.go b/v3/pkg/application/linux_cgo.go index e4751c88262..3c7db624ad7 100644 --- a/v3/pkg/application/linux_cgo.go +++ b/v3/pkg/application/linux_cgo.go @@ -1306,11 +1306,13 @@ func (w *linuxWebviewWindow) present() { } func (w *linuxWebviewWindow) setTitle(title string) { - if !w.parent.options.Frameless { - cTitle := C.CString(title) - C.gtk_window_set_title(w.gtkWindow(), cTitle) - C.free(unsafe.Pointer(cTitle)) - } + // Set unconditionally, frameless included: gtk_window_set_title writes the + // WM_NAME/_NET_WM_NAME hints that taskbars and window switchers label the + // window with, it does not draw a titlebar. Decorations are governed + // separately, by gtk_window_set_decorated. + cTitle := C.CString(title) + C.gtk_window_set_title(w.gtkWindow(), cTitle) + C.free(unsafe.Pointer(cTitle)) } func (w *linuxWebviewWindow) setSize(width, height int) { diff --git a/v3/pkg/application/linux_cgo_gtk3.go b/v3/pkg/application/linux_cgo_gtk3.go index 4b4be6eaf28..9df0e7ac2b6 100644 --- a/v3/pkg/application/linux_cgo_gtk3.go +++ b/v3/pkg/application/linux_cgo_gtk3.go @@ -1704,11 +1704,13 @@ func (w *linuxWebviewWindow) setOpacity(opacity float64) { } func (w *linuxWebviewWindow) setTitle(title string) { - if !w.parent.options.Frameless { - cTitle := C.CString(title) - C.gtk_window_set_title(w.gtkWindow(), cTitle) - C.free(unsafe.Pointer(cTitle)) - } + // Set unconditionally, frameless included: gtk_window_set_title writes the + // WM_NAME/_NET_WM_NAME hints that taskbars and window switchers label the + // window with, it does not draw a titlebar. Decorations are governed + // separately, by gtk_window_set_decorated. + cTitle := C.CString(title) + C.gtk_window_set_title(w.gtkWindow(), cTitle) + C.free(unsafe.Pointer(cTitle)) } func (w *linuxWebviewWindow) setIcon(icon pointer) {