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)
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?
$(XQueryPointer) for 0, and calling xwininfo -root for this condition resolves this quirk.. Thanks..
root_id.value if child_id.value == 0.
if child_id.value == 0: print root_id.value else: print child_id.value :)
sed /x[0-9]\\++/q\;d <(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.
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...
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
xdotool getmouselocation --shell | grep WINDOW | awk -F "=" '{print $2}'
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/.*://")
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.
xprop -root 2>/dev/null | sed -n '/^_NET_ACTIVE_WINDOW/ s/.* // p'
xdotool getwindowsfocus from a console and moving mouse around. Value would be the same until you click mouse or interact keyboard (alt+tab, etc)