0

Trying to xmodmap this file .Xmodmap upon resume. Tried how to execute a command after resume from suspend? by adding multiple key mappings using xmodmap -e without success (each time it would only accept the first line). I feel it should be able to use .Xmodmap to keep the code simple. Ubuntu 14.04. Thank you.

My .Xmodmap (with executable permission) in /home/dadtwo/

clear control
clear mod4

keycode 133 = Control_L NoSymbol Control_L
keycode 37 = Super_L NoSymbol Super_L

add control = Control_L
add mod4 = Super_L

My 10_keyboard-swap (with executable permission) located in /etc/pm/sleep.d

#!/bin/sh

# Remap Swap Super_L and Control_L

case "${1}" in
    resume|thaw)
    DISPLAY=:0.0 ; export DISPLAY
    su $dadtwo -c "sleep 3; /usr/bin/xmodmap /home/dadtwo/.Xmodmap"&
;;
esac

/var/log/pm-suspend.log says "/usr/bin/xmodmap: unable to open display ':0.0'"

  • 1
    Try: Change the name, so it happens later in the sequence, e.g. 50_keyboard-swap. See man run-parts – waltinator Aug 04 '16 at 15:29
  • @waltinator changed to 50, still unable to open display, no difference. When I change it to a single keyboard map su $dadtwo -c "sleep 3; /usr/bin/xmodmap -e "clear conrol"" & It runs without returning any errors, however I could not figure out the syntax on adding additional lines, as contained in my .Xmodmap – Seek Truth Aug 05 '16 at 15:32

1 Answers1

0

ldd $(type -p xmodmap) shows that xmodmap uses libX11.so.6 to communicate with the X server. Therefore, one cannot use xmodmap before the X server is running.

$ ldd $(type -p xmodmap)
    linux-vdso.so.1 =>  (0x00007ffc5c1f3000)
    libX11.so.6 => /usr/lib/x86_64-linux-gnu/libX11.so.6 (0x00007f8abffa6000)
    libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f8abfbe1000)
    libxcb.so.1 => /usr/lib/x86_64-linux-gnu/libxcb.so.1 (0x00007f8abf9c2000)
    libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007f8abf7be000)
    /lib64/ld-linux-x86-64.so.2 (0x00007f8ac02db000)
    libXau.so.6 => /usr/lib/x86_64-linux-gnu/libXau.so.6 (0x00007f8abf5ba000)
    libXdmcp.so.6 => /usr/lib/x86_64-linux-gnu/libXdmcp.so.6 (0x00007f8abf3b4000)

On my Ubuntu 14.04.5, (YMMV), by using pgrep X, and ps -fp$(pgrep X) and following the PPID field back two steps, I see:

$ ps -fp1851,1801,1603
UID        PID  PPID  C STIME TTY          TIME CMD
root      1603     1  0 Jul27 ?        00:00:00 gdm
root      1801  1603  0 Jul27 ?        00:00:00 /usr/lib/gdm/gdm-simple-slave --display-id /org/gnome/DisplayManager/Displays/_0
root      1851  1801  1 Jul27 tty7     04:30:37 /usr/bin/X :0 -background none -verbose -logverbose 7 -core -auth /var/run/gdm/auth-for-gdm-ZKZ4jH/database -seat seat0 -nolisten t

Which tells me that the X server (X), PID 1851 (on my system, at this time, YMMV) was started by PID 1801 (/usr/lib/gdm/gdm-simple-slave), which, in turn, was started by PID 1603 (gdm).

gdm only starts gdm-simple-slave (which starts X) AFTER you login, so this won't work before login.

Running xmodmap either before X is started, or without putting export DISPLAY=:0 into your script before the xmodmap, AND having done man xhost;xhost +local: in your X session.

Rephrased answer:

Read man xhost.

After you've logged in, open a terminal window and look:

$ echo $DISPLAY
:0

Allow processes running on this system, but NOT running under the X server process to communicate with the X server process:

$ xhost +local:
non-network local connections being added to access control list

This will last until you change it back (xhost -local:) OR until the X server exits, so, if this works for you, put it in your user startup somewhere.

For as long as xhost +locakl: is in effect, you can run your xmodmap in any context (e.g. from /etc/pm/power.d/) by doing:

env DISPLAY=:0 xmodmap ....

or, if you want to use multiple xmodmap commands,

export DISPLAY=:0
xmodmap ...
xmodmap ...

Note: Allowing connections to your X server by "non-network local connections" DOES make your system less secure.

waltinator
  • 36,399
  • not trying to make the system less secure. 1: Are you saying that waking from sleep creates a login process? What I don't understand is how putting the code directly in that line as described here [http://askubuntu.com/questions/92218/how-to-execute-a-command-after-resume-from-suspend] is not functioning. 2: Was the answer provided there wrong? ie. not possible? – Seek Truth Aug 06 '16 at 16:09
  • But you are making your system a little less secure. 1. No. That's "not even wrong" See pstree -a -c -l -p -u 1. 1.5 Environment variables last the length of the script, then vanish. 2. Not wrong, just incomplete. X server must be told to accept requests from outside its' process subtree.
  • – waltinator Aug 06 '16 at 17:07
  • Could a different approach be used? If I implemented a 10 second delay on the execution of the xmodmap, would it then be inside the x server subtree? Or would it still be outside because I'm calling it from sleep.d? – Seek Truth Aug 10 '16 at 14:59
  • Or... is there a way to make the map permanent so it does not revert when going into suspend? – Seek Truth Aug 10 '16 at 15:08
  • After some more digging, I found a script by dedalu that runs in the background and initiates xmodmap. What do you think of it? I tested, and is working. xmodmap python script – Seek Truth Aug 10 '16 at 16:38