hyprland-community / pyprland

Scratchpads & many goodies for Hyprland [maintainer=@fdev31]
MIT License
349 stars 15 forks source link

Scratchpads do not work properly for emacs client #6

Closed nmccarty closed 1 year ago

nmccarty commented 1 year ago

With the following pypr configuration:

        {
          "pyprland": {
            "plugins": [
              "scratchpads"
            ]
          },
          "scratchpads": {
            "emacs": {
              "command": "emacsclient -c --frame-parameters='(quote (name . "scratchmacs"))'",
              "animation": "",
              "unfocus": "hide"
            }
          }
        }

and the following hyprland configuration:

        # Emacs
        bind = SUPER ALT, W, exec, pypr toggle emacs
        $scratchmacs = title:^(scratchmacs)$
        windowrulev2 = float,$scratchmacs
        windowrulev2 = size 40% 50%,$scratchmacs
        windowrulev2 = workspace special silent,$scratchmacs
        windowrulev2 = center,$scratchmacs

pyprland seems to be unable to identify the emacs process holding the frame, and gives the following error when trying to activate the emacs scratchpad:

scratchpads::run_toggle(('emacs',)) failed:
Traceback (most recent call last):
  File "/nix/store/p9shqq7kxf2khagwp4yf7jdjvbw65w58-python3.10-pyprland-1.3.1/lib/python3.10/site-packages/pyprland/command.py", line 51, in _callHandler
    await getattr(plugin, full_name)(*params)
  File "/nix/store/p9shqq7kxf2khagwp4yf7jdjvbw65w58-python3.10-pyprland-1.3.1/lib/python3.10/site-packages/pyprland/plugins/scratchpads.py", line 209, in run_toggle
    await self.run_show(uid)
  File "/nix/store/p9shqq7kxf2khagwp4yf7jdjvbw65w58-python3.10-pyprland-1.3.1/lib/python3.10/site-packages/pyprland/plugins/scratchpads.py", line 306, in run_show
    await self.updateScratchInfo(item)
  File "/nix/store/p9shqq7kxf2khagwp4yf7jdjvbw65w58-python3.10-pyprland-1.3.1/lib/python3.10/site-packages/pyprland/plugins/scratchpads.py", line 226, in updateScratchInfo
    await scratch.updateClientInfo()
  File "/nix/store/p9shqq7kxf2khagwp4yf7jdjvbw65w58-python3.10-pyprland-1.3.1/lib/python3.10/site-packages/pyprland/plugins/scratchpads.py", line 105, in updateClientInfo
    assert isinstance(clientInfo, dict)
AssertionError
fdev31 commented 1 year ago

Is it https://github.com/hrehfeld/emacsclient-desktop that you are using ?

nmccarty commented 1 year ago

No, my system has the .desktop file provided by the emacs package from my operating system, but there shouldn't be any usage of .desktop files involved in how I've got pyprland configured

fdev31 commented 1 year ago

I can see issues in your config. I wonder how it's still loaded because it has an incorrect escaping (invalid JSON syntax). It works after fixing it and replacing the command with just "emacs" (which is ran by default by the .desktop file in the package, but understand my ignorance related to emacs). I suggest that you set the window floating and add some width and height to it to control the size, but maybe having it tiled is what you wanted ? In short, it works well with emacs, there must be something wrong with the command - also check the JSON syntax, you can run pypr in the foreground and with debug logs using:

DEBUG=1 pypr

Hint: to make the syntax simpler in the JSON, you can use some .sh file somewhere in your $PATH instead of inlining the full command.

I'll reject since I don't think it's related to pypr, re-open if you believe different and have some data to show.

nmccarty commented 1 year ago

The JSON errors were from a copy/paste error extracting just one section from my config (and I did actually try using a wrapper script in my config)

The window is set floating and has the height correctly configured in the actual config, the resulting window doesn't appear as tiled, and, well, never actually appears at all despite actually getting launched

Unfortunately, simply replacing the command with emacs doesn't result in something equivlant, emacs and emacsclient are entirely different commands that have very different semantics. The emacsclient command creates a new window and attaches it to an existing emacs session, where as emacs always creates a new session.

The emacsclient command I am using runs fine from the terminal, and produces a floating window with the expected geometry.

Here is the current complete state of my pyprland config:

  {
    "pyprland": {
      "plugins": [
        "scratchpads"
      ]
    },
    "scratchpads": {
      "term": {
        "command": "alacritty --class alacritty-dropterm --working-directory ~ -e tmux new -A -s scratch",
        "animation": ""
      },
      "emacs": {
        "command": "/nix/store/61alz9sbbbnysgq8az0snc6pr3y2lldb-emacsStart.sh",
        "animation": "",
        "unfocus": "hide"
      },
      "ario": {
        "command": "ario",
        "animation": ""
       },
      "spotify": {
        "command": "spotify",
        "animation": ""
       }
    }
  }

The contents of the included script:

  #!/nix/store/8fv91097mbh5049i9rglc73dx6kjg3qk-bash-5.2-p15/bin/bash
  exec emacsclient -c --frame-parameters='(quote (name . "scratchmacs"))'

(tested again and calling this script from the terminal creates a floating window with the expected geometry)

and the output from DEBUG=1 pypr, popping open and closing the terminal scratchpad to make sure pypr was working, and then attempting to open the emacs scratchpad:

Welcome to fish, the friendly interactive shell
Type help for instructions on how to use fish

~
01:03 PM❯ set -x DEBUG 1

~
01:03 PM❯ pypr
EVT event_createworkspace(special)
EVT event_activewindow(Alacritty,pypr ~)
EVT event_activewindowv2(1ecf400)
EVT event_openwindow(1d2d600,special,emacs,scratchmacs)
(JS)>>> clients
EVT event_activewindow(Alacritty,pypr ~)
EVT event_activewindowv2(1ecf400)
EVT event_openwindow(1ecdfa0,special,alacritty-dropterm,Alacritty)
(JS)>>> clients
>>> movetoworkspacesilent special:scratch_term,address:0x1ecdfa0
<<< b'ok'
EVT event_createworkspace(special:scratch_term)
EVT event_movewindow(1ecdfa0,special:scratch_term)
EVT event_activewindow(Alacritty,pypr ~)
EVT event_activewindowv2(1ecf400)
EVT event_activewindow(Alacritty,pypr ~)
EVT event_activewindowv2(1ecf400)
EVT event_openwindow(1dbda00,special,ario,Ario)
(JS)>>> clients
>>> movetoworkspacesilent special:scratch_ario,address:0x1dbda00
<<< b'ok'
EVT event_createworkspace(special:scratch_ario)
EVT event_movewindow(1dbda00,special:scratch_ario)
EVT event_activewindow(Alacritty,pypr ~)
EVT event_activewindowv2(1ecf400)
EVT event_windowtitle(1dbda00)
EVT event_activewindow(Alacritty,pypr ~)
EVT event_activewindowv2(1ecf400)
EVT event_openwindow(20dbfd0,special,,Spotify)
(JS)>>> clients
>>> movetoworkspacesilent special:scratch_spotify,address:0x20dbfd0
<<< b'ok'
EVT event_createworkspace(special:scratch_spotify)
EVT event_movewindow(20dbfd0,special:scratch_spotify)
EVT event_activewindow(Alacritty,pypr ~)
EVT event_activewindowv2(1ecf400)
CMD: run_toggle(['term'])
(JS)>>> activewindow
(JS)>>> monitors
(JS)>>> clients
>>> moveworkspacetomonitor special:scratch_term DP-3
<<< b'ok'
>>> movetoworkspacesilent 1,address:0x1ecdfa0
EVT event_movewindow(1ecdfa0,1)
EVT event_activewindow(alacritty-dropterm,Alacritty)
EVT event_activewindowv2(1ecdfa0)
<<< b'ok'
>>> focuswindow address:0x1ecdfa0
EVT event_activewindow(alacritty-dropterm,Alacritty)
EVT event_activewindowv2(1ecdfa0)
<<< b'ok'
EVT event_activewindow(alacritty-dropterm,Alacritty)
EVT event_activewindowv2(1ecdfa0)
EVT event_destroyworkspace(special:scratch_term)
CMD: run_toggle(['term'])
>>> movetoworkspacesilent special:scratch_term,address:0x1ecdfa0
EVT event_createworkspace(special:scratch_term)
EVT event_movewindow(1ecdfa0,special:scratch_term)
EVT event_activewindow(Alacritty,pypr ~)
EVT event_activewindowv2(1ecf400)
<<< b'ok'
CMD: run_toggle(['emacs'])
(JS)>>> activewindow
(JS)>>> monitors
(JS)>>> clients
scratchpads::run_toggle(('emacs',)) failed:
Traceback (most recent call last):
  File "/nix/store/ivdglgzgnkwqk9ky7z3rl7d2vhk0b1v1-python3.10-pyprland-1.3.1/lib/python3.10/site-packages/pyprland/command.py", line 51, in _callHandler
    await getattr(plugin, full_name)(*params)
  File "/nix/store/ivdglgzgnkwqk9ky7z3rl7d2vhk0b1v1-python3.10-pyprland-1.3.1/lib/python3.10/site-packages/pyprland/plugins/scratchpads.py", line 209, in run_toggle
    await self.run_show(uid)
  File "/nix/store/ivdglgzgnkwqk9ky7z3rl7d2vhk0b1v1-python3.10-pyprland-1.3.1/lib/python3.10/site-packages/pyprland/plugins/scratchpads.py", line 306, in run_show
    await self.updateScratchInfo(item)
  File "/nix/store/ivdglgzgnkwqk9ky7z3rl7d2vhk0b1v1-python3.10-pyprland-1.3.1/lib/python3.10/site-packages/pyprland/plugins/scratchpads.py", line 226, in updateScratchInfo
    await scratch.updateClientInfo()
  File "/nix/store/ivdglgzgnkwqk9ky7z3rl7d2vhk0b1v1-python3.10-pyprland-1.3.1/lib/python3.10/site-packages/pyprland/plugins/scratchpads.py", line 105, in updateClientInfo
    assert isinstance(clientInfo, dict)
AssertionError
nmccarty commented 1 year ago

(@fdev31 would appreciate you reopening, given that I'm not able to)

nmccarty commented 1 year ago

After another quick round of troubleshooting, it looks like pypr is indeed actually creating the emacsclient window, hyprctl clients shows it there in it's special workspace, pypr is just struggling with calling it back from the special workspace