Parent window id (unix).
This commit is contained in:
parent
b5c699b40d
commit
176a3d48a1
4 changed files with 86 additions and 13 deletions
|
@ -452,10 +452,13 @@ func loadFlags() []zenity.Option {
|
|||
if attach != "" {
|
||||
opts = append(opts, zenity.Attach(zenutil.ParseWindowId(attach)))
|
||||
} else if modal {
|
||||
if pid := zenutil.GetParentWindowId(); pid != 0 {
|
||||
opts = append(opts, zenity.Attach(pid))
|
||||
if id := zenutil.GetParentWindowId(os.Getppid()); id != 0 {
|
||||
opts = append(opts, zenity.Attach(id))
|
||||
}
|
||||
}
|
||||
if modal {
|
||||
opts = append(opts, zenity.Modal())
|
||||
}
|
||||
|
||||
// Message options
|
||||
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
package zenutil
|
||||
|
||||
import (
|
||||
"os"
|
||||
"strconv"
|
||||
|
||||
"golang.org/x/sys/unix"
|
||||
|
@ -16,8 +15,7 @@ func ParseWindowId(id string) any {
|
|||
}
|
||||
|
||||
// GetParentWindowId is internal.
|
||||
func GetParentWindowId() int {
|
||||
pid := os.Getppid()
|
||||
func GetParentWindowId(pid int) int {
|
||||
for {
|
||||
kinfo, err := unix.SysctlKinfoProc("kern.proc.pid", pid)
|
||||
if err != nil {
|
||||
|
|
|
@ -8,6 +8,7 @@ import (
|
|||
"io"
|
||||
"os/exec"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// ParseWindowId is internal.
|
||||
|
@ -17,14 +18,38 @@ func ParseWindowId(id string) int {
|
|||
}
|
||||
|
||||
// GetParentWindowId is internal.
|
||||
func GetParentWindowId() int {
|
||||
buf, err := exec.Command("ps", "-xo", "pid=,ppid=").CombinedOutput()
|
||||
func GetParentWindowId(pid int) int {
|
||||
winids, err := getPidToWindowMap()
|
||||
if err != nil {
|
||||
return 0
|
||||
}
|
||||
|
||||
ppids, err := getPidToPpidMap()
|
||||
if err != nil {
|
||||
return 0
|
||||
}
|
||||
|
||||
for {
|
||||
if winid, ok := winids[pid]; ok {
|
||||
id, _ := strconv.Atoi(winid)
|
||||
return id
|
||||
}
|
||||
if ppid, ok := ppids[pid]; ok {
|
||||
pid = ppid
|
||||
} else {
|
||||
return 0
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func getPidToPpidMap() (map[int]int, error) {
|
||||
out, err := exec.Command("ps", "-xo", "pid=,ppid=").Output()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
ppids := map[int]int{}
|
||||
reader := bytes.NewReader(buf)
|
||||
reader := bytes.NewReader(out)
|
||||
for {
|
||||
var pid, ppid int
|
||||
_, err := fmt.Fscan(reader, &pid, &ppid)
|
||||
|
@ -32,11 +57,58 @@ func GetParentWindowId() int {
|
|||
break
|
||||
}
|
||||
if err != nil {
|
||||
return 0
|
||||
return nil, err
|
||||
}
|
||||
ppids[pid] = ppid
|
||||
}
|
||||
|
||||
// Find the relevant pid and window id.
|
||||
return 0
|
||||
return ppids, nil
|
||||
}
|
||||
|
||||
func getPidToWindowMap() (map[int]string, error) {
|
||||
ids, err := getWindowIDs()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var pid int
|
||||
winids := map[int]string{}
|
||||
for _, id := range ids {
|
||||
pid, err = getWindowPid(id)
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
winids[pid] = id
|
||||
}
|
||||
if err != nil && len(winids) == 0 {
|
||||
return nil, err
|
||||
}
|
||||
return winids, nil
|
||||
}
|
||||
|
||||
func getWindowIDs() ([]string, error) {
|
||||
out, err := exec.Command("xprop", "-root", "0i", "\t$0+", "_NET_CLIENT_LIST").Output()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if i := bytes.IndexByte(out, '\t'); i < 0 {
|
||||
return nil, fmt.Errorf("xprop: unexpected output: %q", out)
|
||||
} else {
|
||||
out = out[i+1:]
|
||||
}
|
||||
return strings.Split(string(out), ", "), nil
|
||||
}
|
||||
|
||||
func getWindowPid(id string) (int, error) {
|
||||
out, err := exec.Command("xprop", "-id", id, "0i", "\t$0", "_NET_WM_PID").Output()
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
if i := bytes.IndexByte(out, '\t'); i < 0 {
|
||||
return 0, fmt.Errorf("xprop: unexpected output: %q", out)
|
||||
} else {
|
||||
out = out[i+1:]
|
||||
}
|
||||
return strconv.Atoi(string(out))
|
||||
}
|
||||
|
|
|
@ -9,6 +9,6 @@ func ParseWindowId(id string) uintptr {
|
|||
}
|
||||
|
||||
// GetParentWindowId is internal.
|
||||
func GetParentWindowId() int {
|
||||
func GetParentWindowId(pid int) int {
|
||||
return 0
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue