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 != "" {
|
if attach != "" {
|
||||||
opts = append(opts, zenity.Attach(zenutil.ParseWindowId(attach)))
|
opts = append(opts, zenity.Attach(zenutil.ParseWindowId(attach)))
|
||||||
} else if modal {
|
} else if modal {
|
||||||
if pid := zenutil.GetParentWindowId(); pid != 0 {
|
if id := zenutil.GetParentWindowId(os.Getppid()); id != 0 {
|
||||||
opts = append(opts, zenity.Attach(pid))
|
opts = append(opts, zenity.Attach(id))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if modal {
|
||||||
|
opts = append(opts, zenity.Modal())
|
||||||
|
}
|
||||||
|
|
||||||
// Message options
|
// Message options
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
package zenutil
|
package zenutil
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"os"
|
|
||||||
"strconv"
|
"strconv"
|
||||||
|
|
||||||
"golang.org/x/sys/unix"
|
"golang.org/x/sys/unix"
|
||||||
|
@ -16,8 +15,7 @@ func ParseWindowId(id string) any {
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetParentWindowId is internal.
|
// GetParentWindowId is internal.
|
||||||
func GetParentWindowId() int {
|
func GetParentWindowId(pid int) int {
|
||||||
pid := os.Getppid()
|
|
||||||
for {
|
for {
|
||||||
kinfo, err := unix.SysctlKinfoProc("kern.proc.pid", pid)
|
kinfo, err := unix.SysctlKinfoProc("kern.proc.pid", pid)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
@ -8,6 +8,7 @@ import (
|
||||||
"io"
|
"io"
|
||||||
"os/exec"
|
"os/exec"
|
||||||
"strconv"
|
"strconv"
|
||||||
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
// ParseWindowId is internal.
|
// ParseWindowId is internal.
|
||||||
|
@ -17,14 +18,38 @@ func ParseWindowId(id string) int {
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetParentWindowId is internal.
|
// GetParentWindowId is internal.
|
||||||
func GetParentWindowId() int {
|
func GetParentWindowId(pid int) int {
|
||||||
buf, err := exec.Command("ps", "-xo", "pid=,ppid=").CombinedOutput()
|
winids, err := getPidToWindowMap()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return 0
|
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{}
|
ppids := map[int]int{}
|
||||||
reader := bytes.NewReader(buf)
|
reader := bytes.NewReader(out)
|
||||||
for {
|
for {
|
||||||
var pid, ppid int
|
var pid, ppid int
|
||||||
_, err := fmt.Fscan(reader, &pid, &ppid)
|
_, err := fmt.Fscan(reader, &pid, &ppid)
|
||||||
|
@ -32,11 +57,58 @@ func GetParentWindowId() int {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return 0
|
return nil, err
|
||||||
}
|
}
|
||||||
ppids[pid] = ppid
|
ppids[pid] = ppid
|
||||||
}
|
}
|
||||||
|
return ppids, nil
|
||||||
// Find the relevant pid and window id.
|
}
|
||||||
return 0
|
|
||||||
|
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.
|
// GetParentWindowId is internal.
|
||||||
func GetParentWindowId() int {
|
func GetParentWindowId(pid int) int {
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue