Take the 2-minute tour ×
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems.. It's 100% free, no registration required.

From a bash script, is there some way to get the ID of the X window under the mouse pointer?

(edit) I need the process to be non-interactive.

share|improve this question

6 Answers 6

up vote 10 down vote accepted

xdotool exposes the pointer location (xdotool getmouselocation). None of xdotool, xwininfo or wmctrl appear to have a way to match a window by a screen position where it's visible.

The underlying X library call is XQueryPointer (corresponding to a QueryPointer message). Here's a simple Python wrapper script around this call (using ctypes). Error checking largely omitted. Assumes you're using screen 0 (if you didn't know that displays could have more than one screen, ignore this).

#! /usr/bin/env python
import sys
from ctypes import *
Xlib = CDLL("libX11.so.6")
display = Xlib.XOpenDisplay(None)
if display == 0: sys.exit(2)
w = Xlib.XRootWindow(display, c_int(0))
(root_id, child_id) = (c_uint32(), c_uint32())
(root_x, root_y, win_x, win_y) = (c_int(), c_int(), c_int(), c_int())
mask = c_uint()
ret = Xlib.XQueryPointer(display, c_uint32(w), byref(root_id), byref(child_id),
                         byref(root_x), byref(root_y),
                         byref(win_x), byref(win_y), byref(mask))
if ret == 0: sys.exit(1)
print child_id.value

Usage example:

xwininfo -tree -id $(XQueryPointer)
share|improve this answer
1  
Thanks Gilles: This is (almost) exactly what I need... It is ideal but for the fact that it returns a value of '0' for the desktop itself.. A non-zero window ID is returned (for the desktop) by the asynchronous xdotool click 1 method mentioned in the comment to Bruce Ediger's answer.. The non-zero desktop ID is valid insomuch as it returns the appropriate image via import -window $nonzeroID screen.png.... Is there some simple tweak for the python script to return that value for the desktop? –  Peter.O Jul 6 '11 at 13:48
    
@Gilles... Testing $(XQueryPointer) for 0, and calling xwininfo -root for this condition resolves this quirk.. Thanks.. –  Peter.O Jul 6 '11 at 14:34
    
@fred Untested because I'm not in front of a unix machine: try printing root_id.value if child_id.value == 0. –  Gilles Jul 6 '11 at 14:39
    
Yes, your mod works fine.. if child_id.value == 0: print root_id.value else: print child_id.value :) –  Peter.O Jul 6 '11 at 15:23
xprop -root 2>/dev/null | sed -n '/^_NET_ACTIVE_WINDOW/ s/.* // p'
share|improve this answer
    
This gives the ID of the active window instead of the window under the mouse pointer. –  Peter.O Nov 24 at 12:34
    
Oh, I was assuming sloppy focus (focus follows mouse) here. –  blueyed Nov 24 at 21:25

ArchWiki has a good answer to this:

activeWinLine=$(xprop -root | grep "_NET_ACTIVE_WINDOW(WINDOW)")
activeWinId=${activeWinLine:40}

Using sed you can do this in a single line, which is probably the most readable way to do it:

activeWin="$(xprop -root | sed -n 's/^_NET_ACTIVE_WINDOW(WINDOW): window id # //p')"

Note that xdotool was missing in my Debian minimal X11 while xprop was included (likewise sed of course).

If you don't want to fork sed nor grep you can do the text transformation it entirely in bash, which perhaps is a little bit more safe in case the output of xprop changes a bit:

activeWin="$(xprop -root)"
activeWin="${activeWin#*_NET_ACTIVE_WINDOW(WINDOW):}'
activeWin="${activeWin%%?_NET_*}'
activeWin="${activeWin##* }'

Anyway, it's still a strange way to archive such a simple task.

share|improve this answer
    
This gives the ID of the active window instead of the window under the mouse pointer. –  Peter.O Nov 24 at 12:35

I toyed around with the answer from Peter.O and came up with:

xdotool click 1|xwininfo|grep 'Window id:'
share|improve this answer

try this, it uses only xdotool, but its version is at least "2.20110530.1"

eval `xdotool getmouselocation --shell 2>/dev/null |grep WINDOW`
echo $WINDOW

to get the window id directly you can use this:

sedGetValue='s".*=\(.*\)"\1"'
windowId=`xdotool getmouselocation --shell 2>/dev/null |grep WINDOW |sed "$sedGetValue"`
echo $windowId
share|improve this answer

The xwininfo command gives this kind of output, but you do have to click on the window you want info on:

% xwininfo
xwininfo: Please select the window about which you
          would like information by clicking the
          mouse in that window.

xwininfo: Window id: 0xa0000d "flask"

...

So doing: xwininfo | grep 'Window id:' might give you something you can parse the ID out of.

share|improve this answer
    
I need it to be non-interactive... –  Peter.O Jul 6 '11 at 4:32
1  
It can be made to be non-interactive by running it in the background xwinfo |grep window id:' &, and following it by xdotool click 1... but that runs the risk of the foreground click executing before the xdotool grabs the mouse. I'd rathen not use a nominal `sleep n, so although this answer is on-track, I'll wait a wihile to see if something more inline turns up... –  Peter.O Jul 6 '11 at 5:39

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.