スリープ後にxmodmapが失われる

スリープ後にxmodmapが失われる

Ubuntu 18.04では、次の自動起動スクリプトを使用します。

[Desktop Entry]
Type=Application
Exec=/home/user/.xinitrc
Version=1.0
X-GNOME-Autostart-enabled=true
Name=xmodmap
Comment=xmodmap script

これだけですxmodmap /path/.Xmodmap &

システムが起動すると動作します。システムがスリープ状態から復帰すると、再マッピングは動作しなくなります。この問題をどのように解決できますか?

編集:(コメントへの回答)これは問題を解決しません。

$ cat /etc/systemd/system/xmodmapbindings.service
[Unit]
Description=xmodmap bindings
Before=sleep.target
StopWhenUnneeded=yes

[Service]
Type=oneshot
RemainAfterExit=yes
ExecStop=-/home/norake/.xinitrc

[Install]
WantedBy=sleep.target

$ cat ~/.xinitrc 
#!/bin/bash

if [ "$USER" != norake ]; then
    su norake -c 'sleep 5; /usr/bin/xmodmap /home/norake/.Xmodmap' &
    # without su, without sleep, without fork (&): doesn't work either
else
    (sleep 5; /usr/bin/xmodmap /home/norake/.Xmodmap) &
fi

sleep 30いいえ。もちろん、スクリプトを手動で実行すると機能します。

答え1

キーボードを取り外して再接続すると、変更された設定も「失われます」。これはここで起こります。一時停止に入るとキーボードが無効になり、有効化を終了すると再接続されるため、一時停止はホットプラグイベントを生成します。

Xサーバーの観点からは、一時停止状態から復帰した後、接続されたキーボードは新しいキーボードなので、2番目のキーボードと同様に標準バインディングで始まる。

これはUSBキーボードドライバの既知の欠点であり、カーネルで修正することは困難です(USBは回復時に再び列挙されるため、新しい番号が割り当てられてもデバイスのIDを維持する方法が必要です)。 Xサーバーで変更するのは難しいです(デバイスの記録を保存する必要があるため)。

あなたができる最善の方法は、おそらくセッションの開始の一部とキーボードのホットプラグ処理の一部としてコマンドを実行することですが、ここでは完全にクリーンなソリューションを考えることはできません。

答え2

この問題の特別なケースのための低技術ハッキーソリューションは次のとおりです。

私のキーボードにはメニューキーが必要な場所に印刷キーがあるので、xmodmapはそのキーだけを再マップします。

実行したい印刷キーのキーバインディングを設定しました(私の場合はGNOMEシェルで)。

/bin/bash -c "/usr/bin/xmodmap $HOME/.Xmodmap"

したがって、一時停止後に初めてPrintキーを押すと、xmodmapがトリガされ、それ以降からメニューキーとして機能します。

(私のキーボードにはもう印刷キーがありません。)

このアプローチは、次の状況で機能する必要があります。

  1. 最初に「ブラインド」キーを押すことは気にしません。
  2. 再マッピングが関連付けられる前または再マッピングが関連付けられるとすぐに、1つ以上のボタンがあります。
  3. ボタンの元のキーシンボルは、新しいマッピングに表示されなくなりました。

修正する: その後、初期のリバインディング段階でコンテキストメニュー自体がトリガーされるようにxdotoolを使用してソリューションを改善しました。

/bin/bash -c "xdotool keyup Print key --clearmodifiers Menu && /usr/bin/xmodmap $HOME/.Xmodmap"

答え3

$USER実際のユーザー名に変更する必要があります。

  1. .Xmodmap私の場合は、マッピングを使用してファイルを生成します。

    keycode 96 = XF86AudioLowerVolume
    keycode 95 = XF86AudioMute
    keycode 76 = XF86AudioNext
    keycode 75 = XF86AudioPlay
    keycode 74 = XF86AudioPrev
    

    そしてそれを/home/$USER/.Xmodmap道の下に置きなさい。

  2. アプリケーションの起動設定を作成し(真の検索メニューからアプリケーションの起動設定に移動します)、次を追加します。

    Name: xmodmap
    Command: /bin/bash -c "sleep 7 && xmodmap ~/.Xmodmap"
    Comment: 
    

    そして保存してください。起動アプリケーションのデフォルト設定をオフにします。

  3. 次に、/usr/lib/systemd/system-sleep以下のようにフォルダに移動します。

    cd /usr/lib/systemd/system-sleep
    
  4. 次のことxkeyboard.shができます(sudo権限が必要)。

    sudo touch xkeyboard.sh
    
  5. ここで$XAUTHORITY変数の値を取得します。次のことができます。

    echo $XAUTHORITY
    

    私の場合は、以下を返しました。

    /run/user/1000/gdm/Xauthority
    

    どこかに書いておいてください。

  6. 編集用に新しく作成されたファイルを開くには、次のようにします。

    sudo nano xkeyboard.sh
    
  7. このコードを貼り付けてください。以前に記録した$USERユーザー名と$XAUTH変数で置き換える必要があります。

    #!/bin/bash
    
    echo "Running xkeyboard.sh with argument: $1" >> /tmp/xkeyboard.log
    
    if [ "${1}" == "pre" ]; then
        echo "pre" >> /tmp/xkeyboard.log
        # Nothing to do for pre-sleep
    elif [ "${1}" == "post" ]; then
        echo "post" >> /tmp/xkeyboard.log
        export DISPLAY=:0  # Set the DISPLAY variable
        export XAUTHORITY=$XAUTH
        /bin/bash -c "sleep 7 && xmodmap home/$USER/.Xmodmap" >> /tmp/xkeyboard.log 2>&1
    fi
    

    このコードでは、ファイルにロギングを追加しました。/tmp/xkeyboard.logしたがって、キーマップが機能しない場合は、そこに行き、何が間違っているかを確認できます。

答え4

これはさまざまなソースの助けを借りて動作するソリューションですが、ほとんどは私が書いています。 capsはxmodmapスクリプトです(CapsLock => F13)。

#!/bin/bash

USERN=cemkalyoncu
SCRIPT=/home/cemkalyoncu/Installed/caps

case $1 in
    post)
        DISPLAY=:0
        export DISPLAY
        su $USERN -c "$SCRIPT"
        #screen
        #su $USERN -c "sleep 30; kwin --replace &" &
    esac

kwinが時々欠陥を引き起こし、リセットが必要なので私も去りましたkwin --replace。しかし、それはデーモンではなく、画面分離を使用する必要があります。これはKDEを使用している場合にのみ当てはまります。インストールされていない場合はインストール画面。ここでは、ディスプレイをエクスポートすることが正常に動作するようにするために重要です。ユーザーと一緒に実行することも必要です。アカウントが最初に復元されても、まだアカウントではありません。 xmodmapには省電力モードは必要ありません。しかし、kwinは再開後数秒後にシステムによって自動的にリセットされますが、時には失敗するため、遅延が必要です。

関連情報