Fix GTK 4 foreground matching and menu labels
This commit is contained in:
1 parent
d0c977281d
commit
49eeae89f4
8 files changed
+254
-9
No files matched your search
@@ -0,0 +1,85 @@
|
||||
// Copyright (c) 2026 Storm Dragon
|
||||
// Authors: Storm Dragon, Angus Kola
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
package atspi_test
|
||||
|
||||
import (
|
||||
"context"
|
||||
"os"
|
||||
"strings"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"git.stormux.org/storm/cthulhu/internal/atspi"
|
||||
"git.stormux.org/storm/cthulhu/internal/presentation"
|
||||
)
|
||||
|
||||
// GTK 4 popover menu items leave Name empty and point LABELLED_BY at an
|
||||
// internal label whose role is invalid; only its text holds the item's label.
|
||||
func TestNativeGTK4MenuItemLabels(t *testing.T) {
|
||||
if os.Getenv("CTHULHU_NATIVE_GTK4_MENU_LABELS") != "1" {
|
||||
t.Skip("requires isolated GTK 4 menu label fixture")
|
||||
}
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 12*time.Second)
|
||||
defer cancel()
|
||||
adapter := atspi.New()
|
||||
if err := adapter.Start(ctx); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
defer func() {
|
||||
stopCtx, stopCancel := context.WithTimeout(context.Background(), 3*time.Second)
|
||||
defer stopCancel()
|
||||
if err := adapter.Stop(stopCtx); err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
}()
|
||||
tree, err := adapter.CaptureDesktop(ctx)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
root, err := tree.Root()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
var items []atspi.Snapshot
|
||||
var walk func(atspi.ObjectReference)
|
||||
walk = func(ref atspi.ObjectReference) {
|
||||
snapshot, err := tree.Resolve(ref)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if snapshot.Role == "menu item" || snapshot.Role == "check menu item" || snapshot.Role == "radio menu item" {
|
||||
items = append(items, snapshot)
|
||||
}
|
||||
child, ok, err := tree.FirstChild(ref)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
for ok {
|
||||
walk(child)
|
||||
child, ok, err = tree.NextSibling(child)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
}
|
||||
walk(root)
|
||||
for _, want := range []string{"New Message", "Add Account…", "Group into Conversations", "All Messages"} {
|
||||
t.Run(want, func(t *testing.T) {
|
||||
for _, item := range items {
|
||||
if item.Name == want {
|
||||
if spoken := presentation.FocusText(item); !strings.Contains(spoken, want) {
|
||||
t.Errorf("speech %q omits label %q", spoken, want)
|
||||
}
|
||||
return
|
||||
}
|
||||
}
|
||||
names := make([]string, 0, len(items))
|
||||
for _, item := range items {
|
||||
names = append(names, item.Role+": "+item.Name)
|
||||
}
|
||||
t.Errorf("no menu item named %q; captured %q", want, names)
|
||||
})
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user