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.
xdotool exposes the pointer location (xdotool getmouselocation), and recent versions (since 2.20110530.1) indicate which window is at that location as well. None of xwininfo, wmctrl or older versions of xdotool 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)
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.
try this, it uses only xdotool, but its version is at least "2.20110530.1"
xdotool getmouselocation --shell | grep WINDOW
to get the window id directly you can use this:
sedGetValue='s/.*=\(.*\)/\1/' # or more readable: sedGetValue='s".*=\(.*\)"\1"' # as / \ confuses me
windowId=`xdotool getmouselocation --shell 2>/dev/null |grep WINDOW |sed "$sedGetValue"`
echo $windowId
If you have access to python-xlib, here's a shorter and more pythonic equivalent to Gilles' answer:
from Xlib.display import Display
display = Display()
window = display.screen().root
result = window.query_pointer()
print(result.child.id)
xdotool is good enough to do so.
Run xdotool getactivewindow and you'll see the result (int)
The window can be over ANY monitor. Just read where is located the x11 pointer waiting for a click :), and no matter if it's a remote window, a vncserver or the 3rd desktop of the cube desktop environment. Just works.
You can play it using sleep for better testing sleep 3; xdotool click 1+2; xdotool getactivewindow.
I've see that getwindowsfocus returns the same value than getactivewindow.
If you do the clicks manually you'll see the contextual menu, but click 1+2 fires both clicks at time clicking on the current mouse location and getting the desired id.
Try it :)
I use: xdotool getmouselocation | sed "s/.*://"
For example, to minimize the window under mouse cursor:
xdotool windowminimize $(xdotool getmouselocation|sed "s/.*://")
xprop -root 2>/dev/null | sed -n '/^_NET_ACTIVE_WINDOW/ s/.* // p'
I toyed around with the answer from Peter.O and came up with:
xdotool click 1|xwininfo|grep 'Window id:'
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.