Parent window id (macOS).

This commit is contained in:
Nuno Cruces 2022-06-13 23:46:03 +01:00
parent b3fe9d02e9
commit b94ee718ba
4 changed files with 17 additions and 67 deletions

View file

@ -52,6 +52,7 @@ var (
icon string icon string
windowIcon string windowIcon string
attach string attach string
modal bool
multiple bool multiple bool
defaultCancel bool defaultCancel bool
@ -211,7 +212,7 @@ func setupFlags() {
flag.StringVar(&text, "text", "", "Set the dialog `text`") flag.StringVar(&text, "text", "", "Set the dialog `text`")
flag.StringVar(&windowIcon, "window-icon", "", "Set the window `icon` (error, info, question, warning)") flag.StringVar(&windowIcon, "window-icon", "", "Set the window `icon` (error, info, question, warning)")
flag.StringVar(&attach, "attach", "", "Set the parent `window` to attach to") flag.StringVar(&attach, "attach", "", "Set the parent `window` to attach to")
flag.Bool("modal", true, "Set the modal hint") flag.BoolVar(&modal, "modal", runtime.GOOS == "darwin", "Set the modal hint")
flag.BoolVar(&multiple, "multiple", false, "Allow multiple items to be selected") flag.BoolVar(&multiple, "multiple", false, "Allow multiple items to be selected")
flag.BoolVar(&defaultCancel, "default-cancel", false, "Give Cancel button focus by default") flag.BoolVar(&defaultCancel, "default-cancel", false, "Give Cancel button focus by default")
@ -448,6 +449,10 @@ func loadFlags() []zenity.Option {
if attach != "" { if attach != "" {
opts = append(opts, zenity.Attach(zenutil.ParseWindowId(attach))) opts = append(opts, zenity.Attach(zenutil.ParseWindowId(attach)))
} else if modal {
if pid := zenutil.GetParentWindowId(); pid != 0 {
opts = append(opts, zenity.Attach(pid))
}
} }
// Message options // Message options

2
go.mod
View file

@ -9,7 +9,7 @@ require (
github.com/randall77/makefat v0.0.0-20210315173500-7ddd0e42c844 github.com/randall77/makefat v0.0.0-20210315173500-7ddd0e42c844
go.uber.org/goleak v1.1.12 // test go.uber.org/goleak v1.1.12 // test
golang.org/x/image v0.0.0-20220601225756-64ec528b34cd golang.org/x/image v0.0.0-20220601225756-64ec528b34cd
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a golang.org/x/sys v0.0.0-20220610221304-9f5ed59c137d
) )
require ( require (

4
go.sum
View file

@ -42,8 +42,8 @@ golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7w
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a h1:dGzPydgVsqGcTRVwiLJ1jVbufYwmzD3LfVPLKsKg+0k= golang.org/x/sys v0.0.0-20220610221304-9f5ed59c137d h1:Zu/JngovGLVi6t2J3nmAf3AoTDwuzw85YZ3b9o4yU7s=
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220610221304-9f5ed59c137d/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=

View file

@ -3,8 +3,8 @@ package zenutil
import ( import (
"os" "os"
"strconv" "strconv"
"syscall"
"unsafe" "golang.org/x/sys/unix"
) )
// ParseWindowId is internal. // ParseWindowId is internal.
@ -17,75 +17,20 @@ func ParseWindowId(id string) any {
// GetParentWindowId is internal. // GetParentWindowId is internal.
func GetParentWindowId() int { func GetParentWindowId() int {
buf, err := sysctlKernProcAll()
if err != nil {
return 0
}
type kinfo_proc struct {
_ [40]byte
Pid int32
_ [516]byte
PPid int32
_ [84]byte
}
const size = int(unsafe.Sizeof(kinfo_proc{}))
ppids := map[int]int{}
for i := 0; i+size < len(buf); i += size {
p := (*kinfo_proc)(unsafe.Pointer(&buf[i]))
ppids[int(p.Pid)] = int(p.PPid)
}
pid := os.Getppid() pid := os.Getppid()
for { for {
ppid := ppids[pid] kinfo, err := unix.SysctlKinfoProc("kern.proc.pid", pid)
if err != nil {
return 0
}
ppid := kinfo.Eproc.Ppid
switch ppid { switch ppid {
case 0: case 0:
return 0 return 0
case 1: case 1:
return pid return pid
default: default:
pid = ppid pid = int(ppid)
} }
} }
} }
func sysctlKernProcAll() ([]byte, error) {
const (
CTRL_KERN = 1
KERN_PROC = 14
KERN_PROC_ALL = 0
)
mib := [4]int32{CTRL_KERN, KERN_PROC, KERN_PROC_ALL, 0}
size := uintptr(0)
_, _, errno := syscall.Syscall6(
syscall.SYS___SYSCTL,
uintptr(unsafe.Pointer(&mib[0])),
uintptr(len(mib)),
0,
uintptr(unsafe.Pointer(&size)),
0,
0)
if errno != 0 {
return nil, errno
}
bs := make([]byte, size)
_, _, errno = syscall.Syscall6(
syscall.SYS___SYSCTL,
uintptr(unsafe.Pointer(&mib[0])),
uintptr(len(mib)),
uintptr(unsafe.Pointer(&bs[0])),
uintptr(unsafe.Pointer(&size)),
0,
0)
if errno != 0 {
return nil, errno
}
return bs[0:size], nil
}