From 74bbc5ec5ba0c0be2b0a52a2da68dc98ce2cf2af Mon Sep 17 00:00:00 2001 From: Keith Herrington Date: Fri, 11 Sep 2026 20:25:48 -0700 Subject: [PATCH] fix: handle macOS Find My window owner name --- internal/findmy/findmy.go | 33 ++++++++++++++++++---------- internal/findmy/window_owner_test.go | 22 +++++++++++++++++++ 2 files changed, 44 insertions(+), 11 deletions(-) create mode 100644 internal/findmy/window_owner_test.go diff --git a/internal/findmy/findmy.go b/internal/findmy/findmy.go index 1d0bb6a..54797e8 100644 --- a/internal/findmy/findmy.go +++ b/internal/findmy/findmy.go @@ -148,22 +148,33 @@ func SwitchTab(name string) error { func MainWindow() (*Window, error) { ls := GetAppStrings() - out, err := runHelper("window", "--owner", ls.WindowOwner) - if err != nil { - return nil, fmt.Errorf("helper window: %w", err) - } - var wins []Window - if err := json.Unmarshal(out, &wins); err != nil { - return nil, fmt.Errorf("decode windows: %w", err) - } - for _, w := range wins { - if w.Layer == 0 && w.OnScreen && w.Height > 100 { - return &w, nil + for _, owner := range windowOwnerCandidates(ls.WindowOwner) { + out, err := runHelper("window", "--owner", owner) + if err != nil { + return nil, fmt.Errorf("helper window: %w", err) + } + var wins []Window + if err := json.Unmarshal(out, &wins); err != nil { + return nil, fmt.Errorf("decode windows: %w", err) + } + for _, w := range wins { + if w.Layer == 0 && w.OnScreen && w.Height > 100 { + return &w, nil + } } } return nil, fmt.Errorf("no visible %s window (open the app first)", ls.WindowOwner) } +// windowOwnerCandidates accounts for macOS builds where Spotlight reports the +// bundle name "FindMy" while CGWindowList reports the visible owner as "Find My". +func windowOwnerCandidates(owner string) []string { + if owner == "FindMy" { + return []string{"FindMy", "Find My"} + } + return []string{owner} +} + // Capture writes the FindMy window's content to dest using `screencapture -l`, // which targets the window by ID and captures actual content rather than the // screen rect. Region capture (`-R x,y,w,h`) would grab whatever is topmost at diff --git a/internal/findmy/window_owner_test.go b/internal/findmy/window_owner_test.go new file mode 100644 index 0000000..c81f755 --- /dev/null +++ b/internal/findmy/window_owner_test.go @@ -0,0 +1,22 @@ +package findmy + +import ( + "reflect" + "testing" +) + +func TestWindowOwnerCandidatesAcceptsMacOSDisplayNameVariant(t *testing.T) { + got := windowOwnerCandidates("FindMy") + want := []string{"FindMy", "Find My"} + if !reflect.DeepEqual(got, want) { + t.Fatalf("windowOwnerCandidates(FindMy) = %#v, want %#v", got, want) + } +} + +func TestWindowOwnerCandidatesLeavesLocalizedNameUntouched(t *testing.T) { + got := windowOwnerCandidates("Localiser") + want := []string{"Localiser"} + if !reflect.DeepEqual(got, want) { + t.Fatalf("windowOwnerCandidates(Localiser) = %#v, want %#v", got, want) + } +}