You are not logged in.

#1 2016-10-30 03:44:07

chikinn
Member
Registered: 2014-04-09
Posts: 42

Interaction between xdotool and xmonad: silent failure of xdotool

Edit: please see also my post below for a much clearer (less terrible) demonstration of the troubleshooting I've done.

Hi all, after upgrading from xdotool 3.20150503.1 to 3.20160805.1, I saw the following issue.  Reverting to the earlier version solved it.

When I call xdotool directly, I see no issue.  But when I launch it via hotkey through my WM xmonad, I'm unable to send a keypress.  See code below: my xmonad config file, which calls a python script, which calls a bash script that launches xdotool.  I added some conspicuous comments to highlight the important lines.  Tried printing the output of the xdotool call to a file, but it seems to fail silently.

I'm wondering whether I'm missing something silly here or I should report this as a bug to the xdotool dev, please let me know your thoughts.

xmonad.hs: WM config file

import XMonad
import XMonad.Util.EZConfig		           -- Keybinding manager
import XMonad.Actions.CycleWS (nextWS, prevWS, shiftToNext, shiftToPrev)

myKeys = [("M-<Right>"              , nextWS)
         ,("M-<Left>"               , prevWS)
         ,("M-S-<Right>"            , shiftToNext)
         ,("M-S-<Left>"             , shiftToPrev)
         ,("S-<Delete>"             , spawn "xcmenuctrl -spc")
         ,("M-b"                    , spawn "bash ~/code/battery/check.sh")
         ,("M-c"                    , spawn "bash ~/code/check_time.sh")
         ,("<XF86AudioLowerVolume>" , spawn "amixer set Master 2%-")
         ,("<XF86AudioMute>"        , spawn "bash ~/code/toggle_mute.sh")
         ,("<XF86AudioRaiseVolume>" , spawn "amixer set Master 2%+")
         ,("<XF86AudioPlay>"        , spawn "python ~/code/mpd_client.py play")
         ,("<XF86AudioPrev>"        , spawn "python ~/code/mpd_client.py prev")
         ,("<XF86AudioNext>"        , spawn "python ~/code/mpd_client.py next")
         ,("<XF86HomePage>"         , spawn "bash ~/code/toggle_HDMI.sh")
         ,("M-M4-0"                 , spawn "python ~/code/mpd_client.py 0") -- THESE LINES ARE WHERE I SEE ISSUES
         ,("M-M4-1"                 , spawn "python ~/code/mpd_client.py 1") --
         ,("M-M4-2"                 , spawn "python ~/code/mpd_client.py 2") --
         ,("M-M4-3"                 , spawn "python ~/code/mpd_client.py 3") --
         ,("M-M4-4"                 , spawn "python ~/code/mpd_client.py 4") --
         ,("M-M4-5"                 , spawn "python ~/code/mpd_client.py 5") --
         ]

main = do
    xmonad $ defaultConfig `additionalKeysP` myKeys

mpd_client.py: script to control MPD and update my media player window after making changes

#!/usr/local/bin/python

from mpd import MPDClient
import sys, taglib, subprocess, os

UPDATE_SCRIPT_PATH = '/home/rk/code/update_ncmpcpp_database.sh'

task = sys.argv[1]

c             = MPDClient()
c.timeout     = 10
c.idletimeout = None
c.connect("localhost", 6600)
#c.connect("0.0.0.0", 6600)

if task == 'play':
    c.pause() # Toggle between play and pause.

elif task == 'prev':
    c.previous()

elif task == 'next':
    c.next()

else: # Set rating, since type(task) == int
    rating = task

    c.command_list_ok_begin()
    c.currentsong()
    res = c.command_list_end()

    path = res[0]['file']
    
    f = taglib.File('/music/' + path)
    
    f.tags['COMMENT'] = [rating]
    
    retVal = f.save()

    if retVal == {}:
        subprocess.call(['twmnc', 'Tag updated']) # Notify.
        subprocess.call(UPDATE_SCRIPT_PATH)       # Update ncmpcpp. ### THIS XDOTOOL CALL IS FAILING

update_ncmpcpp_database.sh: script to send the keypress 'u' (for 'update') to my media player window

#!/bin/bash

ncmpcppPID=`ps a | grep -v grep | awk '{if ($NF=="ncmpcpp") {print $1}}'`
shellPID=`ps -o ppid= $ncmpcppPID | xargs` # xargs trims any whitespace.

# Assert that the process with PID "shellPID" is a shell.
processName=`ps a | awk -v z=$shellPID '{if ($1==z) {print $NF}}'`
if [ $processName != 'bash' ]; then
    exit 1
fi

windowPID=`ps -o ppid= $shellPID | xargs`

# Assert that the process with PID "windowPID" is a terminal window. 
processName=`ps ax | awk -v z=$windowPID '{if ($1==z) {print $NF}}'`
if [ $processName != 'xterm' ]; then
    exit 1
fi

xdotool key --window $(xdotool search --pid $windowPID) u ### VERIFIED THAT NESTED CALL IS WORKING, BUT OUTER CALL DOES NOTHING 

Last edited by chikinn (2016-10-30 04:18:20)

Offline

#2 2016-10-30 04:06:38

Trilby
Inspector Parrot
Registered: 2011-11-29
Posts: 30,530
Website

Re: Interaction between xdotool and xmonad: silent failure of xdotool

chikinn wrote:

When I call xdotool directly, I see no issue.  But when I launch it via hotkey through my WM xmonad

You are comparing running xdotool directly to a WM configuration that calls a python script that in turn calls a shell script that in turn calls xdotool.  Certainly you can do more to narrow this down yourself: does it work if you call the python script from the command line?  If so, the break is between xmonad and the python script, if not, try the bash script from the command line.


"UNIX is simple and coherent" - Dennis Ritchie; "GNU's Not Unix" - Richard Stallman

Offline

#3 2016-10-30 04:17:31

chikinn
Member
Registered: 2014-04-09
Posts: 42

Re: Interaction between xdotool and xmonad: silent failure of xdotool

You're right, sorry.  I really did a terrible job in the OP of communicating what narrowing down I've already done.

Setting aside the python and bash scripts: calling xdotool directly from the command line works.  Calling it via keypress from the WM fails.

More explanation: in the bash script, you can see I have two nested xdotool calls: one to get the window ID of my client, then another to send a keypress to that window.  I separated these calls and found the window ID manually (I forget the actual value, let's call it 12345).  Then I did the following test.

This works (calling directly from the command line):

$ xdotool key --window 12345 u

This does not work (from my xmonad config -- showing just the line I changed):

...
,("M-M4-0"                 , spawn "xdotool key --window 12345 u")
...

Offline

#4 2016-10-30 05:01:53

Trilby
Inspector Parrot
Registered: 2011-11-29
Posts: 30,530
Website

Re: Interaction between xdotool and xmonad: silent failure of xdotool

That's not really what I asked for as there are now other variables at play.  Specifically, if you identified the target window id, the xdotool command called directly should work - but then when you put it into the xmonad config, you need to recompile and restart xmonad for it to take effect, right?  Did you do replace the currently running xmonad, or restart X?  If the later, this definitely wouldn't be expected to work.


"UNIX is simple and coherent" - Dennis Ritchie; "GNU's Not Unix" - Richard Stallman

Offline

#5 2016-10-30 05:09:21

chikinn
Member
Registered: 2014-04-09
Posts: 42

Re: Interaction between xdotool and xmonad: silent failure of xdotool

That's a good point.  I didn't restart X though, I just reloaded xmonad's config on the fly with mod-Q.  After reloading, the direct command continued to work (with the same window ID).

Offline

#6 2016-10-30 05:13:50

Trilby
Inspector Parrot
Registered: 2011-11-29
Posts: 30,530
Website

Re: Interaction between xdotool and xmonad: silent failure of xdotool

Thanks, that clarifies that point.  So it does look like the problem is limited to your xmonad setup calling xdotool (so all the steps of python and shell scripts can be put aside).

Do other xdotool commands work from xmonad hotkeys?  And do other commands (e.g. launching a terminal) work from that same hotkey?


"UNIX is simple and coherent" - Dennis Ritchie; "GNU's Not Unix" - Richard Stallman

Offline

#7 2016-10-30 05:17:33

chikinn
Member
Registered: 2014-04-09
Posts: 42

Re: Interaction between xdotool and xmonad: silent failure of xdotool

Hang on, I think I may have found it, let me think it through on my own a little longer smile

Thanks for your patience!

Offline

#8 2016-10-30 05:40:29

chikinn
Member
Registered: 2014-04-09
Posts: 42

Re: Interaction between xdotool and xmonad: silent failure of xdotool

Okay, I have new information!  I see the issue we've been discussing (namely, xdotool failure when called via hotkey) only when the targeted media player window is *in focus*.  As long as it's out of focus, everything works.  Again, rolling back the xdotool version solves the issue.

So, the experiment I set up is a little flawed: as I type the xdotool command into a separate window, the media player window is necessarily not in focus.  Maybe the issue then has nothing to do with xmonad.  Hypothesis: the new version of xdotool is unable to send a keypress to the currently active window.

To test the hypothesis I closed the media player, exposing the underlying command line prompt while keeping the window the same.  I tested my hypothesis by running the same xdotool command in that window.  It worked: the character 'u' appeared in the terminal.  Hypothesis disproven.  So I'm back to thinking it's some weird interaction between xdotool and xmonad.

----------

Back to your questions: yes, other xdotool commands do work, and other unrelated commands work.  For example, whether or not my media player window is active, a hotkey call to 'xdotool version > ~/test.txt' successfully writes the version info to the test file.

Edited to fix something I said backwards!

Last edited by chikinn (2016-10-30 06:02:26)

Offline

#9 2016-10-30 09:15:50

Raynman
Member
Registered: 2011-10-22
Posts: 1,539

Re: Interaction between xdotool and xmonad: silent failure of xdotool

Maybe the problem is that you're pressing a couple modifiers to trigger an xdotool command simulating a keypress. You could try adding a sleep to get around this or maybe test by binding a single key (like some XF86* multimedia key without modifiers) to this kind of action.

Offline

#10 2016-10-30 12:05:57

Trilby
Inspector Parrot
Registered: 2011-11-29
Posts: 30,530
Website

Re: Interaction between xdotool and xmonad: silent failure of xdotool

I second Raynman's suggestion - but as an additional test, it's possible that xdotool gets confused (regardless of xmonad) when a window id is provided *and* it's the focused window.

By default xdotool targets the currently focused window, and you only need to give a window ID if you want to target something other than the focused window.  It doesn't make much sense that giving the id of the focused window should fail, but it's possible, and easy to test:

In a terminal, use the same xdotool command targetting the desired window, but put a sleep before it, eg:

sleep 3 && xdotool key --window <whatever> u

then during the 3-second sleep change focus to the intended window.  This will take xmonad out of the equation and the xdotool command will run when the targetted window is focused.


"UNIX is simple and coherent" - Dennis Ritchie; "GNU's Not Unix" - Richard Stallman

Offline

#11 2016-10-30 18:01:52

chikinn
Member
Registered: 2014-04-09
Posts: 42

Re: Interaction between xdotool and xmonad: silent failure of xdotool

Raynman, you nailed it.  When I try a single hotkey (in this case 9) everything works as expected.  And in fact, with my original multi-key keybind, if I release the modifiers very quickly (before xdotool can send the keypress), I get the desired outcome.  So: the keypress is always being sent, but *when the target window is active*, it's also being modified by the modifier keys I'm still holding down at the time of the xdotool call and I get M-M4-u instead of u.

I guess this behavior is pretty reasonable.  The question then is what changed in xdotool -- why was it working before?  And why does whether the target window is active make a difference?  That part doesn't seem reasonable.

Trillby, good idea!  I tried your test.  Result is consistent with my first paragraph of this post: if I run the command, switch windows, and press no keys, everything works.  But if I switch windows and then press my two modifier keys, no dice.

Last edited by chikinn (2016-10-30 20:34:30)

Offline

Board footer

Powered by FluxBB