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)
  • 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 'SO- stop being evil' 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
  • sed /x[0-9]\\++/q\;d <(xwininfo -tree -id $(XQueryPointer)) – F. Hauri Feb 14 '15 at 22:19

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.

  • 1
    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

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:

windowId=`xdotool getmouselocation --shell 2>/dev/null |grep WINDOW |sed "$sedGetValue"`
echo $windowId
  • 1
    worked, thanks, BTW this may be useful xdotool getmouselocation --shell | grep WINDOW | awk -F "=" '{print $2}' – user41209 Mar 24 '19 at 7:50

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 :)

  • 1
    This gives the ID of the active window (wherever that window may be), regardless of whether or not that active window is under the mouse pointer. As per the wording of the question: "... find the X window ID under the mouse pointer ..." (wherever that mouse may be). – Peter.O May 25 '15 at 4:51
  • 1
    Thank you for correction, youre right. Updated. I was mixing the concept of getmouselocation with activewindow, but anyway, xdotool is cool enough. – m3nda May 25 '15 at 5:25

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()


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

xdotool click 1|xwininfo|grep 'Window id:'
  • 1
    That sends a mouse click, so it would e.g. click a button where the mouse cursor is. It would incidentally report the window where the cursor is in if you use click to focus, but sending a click event is disruptive. – Gilles 'SO- stop being evil' May 25 '15 at 11:28

ArchWiki has a good answer to this:

activeWinLine=$(xprop -root | grep "_NET_ACTIVE_WINDOW(WINDOW)")

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##* }'

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

  • 3
    This gives the ID of the active window instead of the window under the mouse pointer. – Peter.O Nov 24 '14 at 12:35
  • @Peter.O You are right this does return the active window. Sorry for the wrong answer, however with my tests it worked - probably because I had focus-follows-mouse on. – Tino May 29 '15 at 12:08
xprop -root 2>/dev/null | sed -n '/^_NET_ACTIVE_WINDOW/ s/.* // p'
  • 1
    This gives the ID of the active window instead of the window under the mouse pointer. – Peter.O Nov 24 '14 at 12:34
  • Oh, I was assuming sloppy focus (focus follows mouse) here. – blueyed Nov 24 '14 at 21:25
  • @blueyed Focus is on the active windows, and this windows does respond to KEYBOARD. Mouse is followed/tracked by X11 as it's server from it, and when you click a windows, x11 sets window-manager focus to clicked windows. Focus don't follow mouse really. You can check running xdotool getwindowsfocus from a console and moving mouse around. Value would be the same until you click mouse or interact keyboard (alt+tab, etc) – m3nda May 25 '15 at 5:39

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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