norflin321 / fn-lang-switcher

disable macos change input source pop up
69 stars 7 forks source link

Cannot setup script to run on login. #2

Closed mluisbrown closed 2 years ago

mluisbrown commented 2 years ago

On macOS 12.5 running on M1 MacBook Pro I'm unable to make the script run on login. I tried all the suggestions from the Stack Overflow answer linked in the readme, but nothing works.

I can run the script fine with with nohup ./fn-lang-switcher.py & but not as a daemon started with launchctl.

evan-sm commented 2 years ago

Same issue on M1

norflin321 commented 2 years ago

I have managed to make it work with this steps:

  1. Inside fn.plist file, change paths to the python executable and the script file. Mine is /Users/norflin/miniforge3/bin/python (you can check it with which python) and /Users/norflin/fn.py. Paths should be full.
  2. Copy the plist file to special directory: cp -R fn.plist ~/Library/LaunchAgents/.
  3. Then run this command: launchctl load ~/Library/LaunchAgents/fn.plist - it will tell mac to run this file every time you log in. If you want to stop it run launchctl unload ~/Library/LaunchAgents/fn.plist and remove the file rm -rf ~/Library/LaunchAgents/fn.plist.
  4. Mac might ask you to grant permission for python to monitor input from your keyboard.
  5. Restart. Log in. It should work.

Also this was helpful: https://stackoverflow.com/questions/29338066/run-python-script-at-os-x-startup

mluisbrown commented 2 years ago

This is the plist I'm using:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC -//Apple Computer//DTD PLIST 1.0//EN http://www.apple.com/DTDs/PropertyList-1.0.dtd >
<plist version="1.0">
  <dict>
    <key>Label</key>
    <string>net.michael-brown.langSwitcher</string>
    <key>ProgramArguments</key>
    <array>
      <string>/Users/michael/.pyenv/versions/3.10.6/bin/python</string>
      <string>/Users/michael/fn-lang-switcher.py</string>
    </array>
    <key>StandardErrorPath</key>
    <string>/var/log/python_script.error</string>
    <key>KeepAlive</key>
    <true/>
  </dict>
</plist>

And it simply does not work with launchctl load or launchctl start. It works fine with nohup

evan-sm commented 2 years ago

@norflin321 Still not working, something changed on M1. Feels like it works in background, but does not hook key presses.

dAverk commented 2 years ago

@wmw64 @mluisbrown check updated script & README

mluisbrown commented 2 years ago

@dAverk I've tried it again, and it still doesn't work. I have tried with launchctl start just for testing and it shows no apparent errors but after running it there is no python process running (ps -ef | grep python). Same for launchctl load and restart. Nothing.

I wondered whether it was because I had python installed via pyenv so I nuked that and installed python from scratch via Homebrew (and updated all the paths etc). Also made no difference.

I guess I will just have to live with launching it with nohup.

evan-sm commented 2 years ago

I found noscript-solution. In Keyboard preferences remap Globe Fn Key to act as Caps Lock in "Keyboard" tab and check checkbox Caps Lock key to be used to switch to and from U.S in "Input Sources" tab.

dAverk commented 2 years ago

@wmw64 you are right, but its not a better way IMHO. @mluisbrown very strange, I'm tested this with system-wide python3 and installed with brew - both ways works flawlessly. Right now I'm using system-wide python:

image
<string>/usr/bin/python3</string>
<string>/Users/daverk/fn-lang-switcher/fn.py</string>

And for my keylayouts in /Users/daverk/fn-lang-switcher/fn.py looks like

<...>
        stream = os.popen('/usr/local/bin/issw')
        output = stream.read().strip()
        if (output == 'com.apple.keylayout.US'):
            os.system('/usr/local/bin/issw com.apple.keylayout.Russian')
        else:
            os.system('/usr/local/bin/issw com.apple.keylayout.US')
<...>

Do you have your python3 executable allowed in Input Monitoring and Accessibility?

image image

And last addition: Can you try to update your ~/Library/LaunchAgents/fn.plist with strings below placed before </dict>, do launchctl unload ~/Library/LaunchAgents/fn.plist & launchctl load ~/Library/LaunchAgents/fn.plist, open log output with tail -f /tmp/fn* and click on Fn button several times?

<key>StandardErrorPath</key>
<string>/tmp/fn.err</string>
<key>StandardOutPath</key>
<string>/tmp/fn.out</string>
mluisbrown commented 2 years ago

Ok, I finally got it working. I previously had /opt/homebrew/opt/python/libexec/bin/python in the path in the .plist file, which is the Homebrew symlink that points to python3. I changed it to /opt/homebrew/bin/python3 in the .plist file and I think that is what made it finally work, although I also removed all the permissions for python3.10 for Input Monitoring and Accessibility and then forced them to be re-requested by running the script using nohup.

After that the launchctl load worked and I now have it working.

I'm guessing that if you use pyenv or other form of redirection to python3 that causes issues 🤷

Thanks so much for your help!

evan-sm commented 2 years ago

Got it working too!

evan-sm commented 2 years ago

Well. After a few hours of working I noticed that it is too slow and can't keep up with my typing speed. When I hit FN key it takes 0.5-1 seconds to switch and I get something like "пщogle", or "microыщае". I believe in issw fast execution time because it's written in C. Probably App Nap problem or Python is slow.

I'm back to classic Input Source menu

mluisbrown commented 2 years ago

I don't notice any slowdown, it's not "instant", but it's much better than the alternatives. I also have Ctrl+Option+Space mapped to toggle the input source (what I have used for years) and that has the issue that it doesn't change the input source until you have lifted the Ctrl and Option keys, which makes it also seem slower.

piratx commented 1 year ago

I got it working too on Monterey, seems much much faster than the system's input switcher. The only thing that is disappointing is that there's no easy way for this to work on Ventura..

I alway get this when I try it: /opt/local/lib/libInputSourceSwitcher.dylib' (no such file), '/System/Volumes/Preboot/Cryptexes/OS/opt/local/lib/libInputSourceSwitcher.dylib' (no such file), '/opt/local/lib/libInputSourceSwitcher.dylib' (no such file), '/usr/local/lib/libInputSourceSwitcher.dylib' (no such file), '/usr/lib/libInputSourceSwitcher.dylib' (no such file, not in dyld cache)

dAverk commented 1 year ago

Strange issue, I upgraded to Ventura without any issues with lang-switcher (which has been configured/installed on Monterey). Only /usr/bin/python3 -m pip install pynput has been needed.

piratx commented 1 year ago

It might be issw the issue :/

If you have any idea where I should look at to resolve it please let me know 🙂

On 15 Dec 2022, at 7:05 AM, Ilya Gorbunov @.***> wrote:

Strange issue, I upgraded to Ventura without any issues with lang-switcher (which has been configured/installed on Monterey). Only /usr/bin/python3 -m pip install pynput has been needed.

— Reply to this email directly, view it on GitHub https://github.com/norflin321/fn-lang-switcher/issues/2#issuecomment-1352564251, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAB3FPRLPIAFRKOHPTASQQTWNKRJXANCNFSM57IIPN6A. You are receiving this because you commented.

Saba-Sabato commented 1 year ago

It might be issw the issue :/ If you have any idea where I should look at to resolve it please let me know 🙂

It took me a while, but I got it to work on my machine (Ventura). The key was making zsh the executable, instead of python3. I achieved it like so:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>Label</key>
    <string>fn lang switcher</string>
    <key>ProgramArguments</key>
    <array>
        <string>zsh</string>
        <string>-c</string>
        <string>python3 -m pip install pynput; python3 ~/Library/LaunchAgents/fn_lang_switcher/fn.py</string>
    </array>
    <key>KeepAlive</key>
    <true/>
</dict>
</plist>

Or you could try following the manual steps (option 2) from my fork of the repo: https://github.com/Saba-Sabato/fn-lang-switcher/ Let me know if you're still experiencing issues. @piratx