Giter Site home page Giter Site logo

hyprland-community / pyprland Goto Github PK

View Code? Open in Web Editor NEW
234.0 4.0 15.0 720 KB

Scratchpads & many goodies for Hyprland [maintainer=@fdev31]

License: MIT License

Python 91.22% Nix 0.88% Just 0.28% Shell 7.62%
asyncio extension hyprland hyprland-ipc menus multiscreen python scratchpad scriptable shortcuts

pyprland's Introduction

rect

Hyprland Discord

DocumentationDiscussionsChanges HistoryShare Your Setup

Enhance your Hyprland experience with Pyprland

Welcome to Pyprland, your gateway to extending the capabilities of Hyprland. Pyprland offers a plethora of plugins designed for simplicity and efficiency, allowing you to supercharge your productivity and customize your user experience.

You can think of it as a Gnome tweak tool but for Hyprland users (involves editing text files). With a "100%" plugin-based architecture, Pyprland is designed to be lightweight and easy to use.

Note that usage of Python and architecture of the software encourages using many plugins with little impact on the footprint and performance.

Contributions, suggestions, bug reports and comments are welcome.

  • Explore our variety of plugins to tailor your Hyprland setup to your liking.
  • New users, check the getting started guide.
About Pyprland

Packaging Status

🎉 Hear what others are saying:

Contributing

Check out the creating a pull request document for guidance.

  • Report bugs or propose features here
  • Improve our wiki

and if you have coding skills you can also

  • Enhance the coverage of our tests
  • Propose & write new plugins or enhancements
Dependencies
  • Hyprland >= 0.37
  • Python >= 3.11
    • aiofiles
Latest major changes

Check the Releases change log for more information

2.2

2.1

  • Requires Hyprland >= 0.37
  • Monitors plugin improvements.

2.0

1.10

1.9

1.8

Star History Chart

pyprland's People

Contributors

asthestarsfalll avatar dantefromhell avatar evangelospro avatar fdev31 avatar iliayar avatar jozhin-s-bazhin avatar notashelf avatar zarredfelicite avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

pyprland's Issues

Terminal scratchpad not moving with windowrules

i was setting up a scratchpad for alacritty. i did as specified in the wiki, and gave it a class name. its floating, but its position such that the right edge of the terminal touches to end of the screen, and i cant move it around with windowrule=move. any help?

Environment variable PAGER=/bin/cat

Hi!

I was wondering why bat wasn't paging in the terminals (kitty) opened by the workspace plugin while it works in terminals launched by rofi.
Turns out there was an environment variable set by pyprland, PAGER=/bin/cat.
Overwriting that in my .zshrc works, however other people might run into this issue.

My python skills suck and I don't know where this variable is coming from, maybe you can figure that out?

Thank you!

Scratchpads do not work properly for emacs client

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

monitorAdded and monitorRemoved events stop registering after one reconnection of a monitor

The monitorAdded and monitorRemoved events don't register after you connect and disconnect a monitor once.
Here's the config I used:

[pyprland]
plugins = ["debug_blah"]

debug_blah:

from pyprland.plugins.interface import Plugin
from pyprland.ipc import hyprctlJSON, hyprctl


class Extension(Plugin):
    async def event_monitoradded(self, name):
        print("monitor added")

    async def event_monitorremoved(self, name):
        print("monitor removed")

Log:

                      ipc - Logger initialized for ipc // common.py:70
                  startup - Logger initialized for startup // common.py:70
                     pypr - Logger initialized for pypr // common.py:70
                     pypr - Loading testconfig // command.py:52
               debug_blah - Logger initialized for debug_blah // common.py:70
                     pypr - ================================[ initialized ]================================= // command.py:264
                     pypr - debug_blah.event_monitoradded('HDMI-A-1\n',) // command.py:118
monitor added
                     pypr - debug_blah.event_monitorremoved('HDMI-A-1\n',) // command.py:118
monitor removed
^C                     pypr - cancelled // command.py:270

The first monitor connection was detected but the ones I did after that weren't shown.
I tried this using the pyprland and pyprland-git packages from the aur.

Bug: Multiple chrome PWA apps in scratchpad

Some applications don't provide native linux experience and are installed as PWAs (e.g. google meet, yt music, amplenote).

The problem is that currently only 1st PWA application works in a scratchpad, and others give an error:
/Failed to show scratch. The command terminated successfully, is it already running.

I believe this is because chrome reuses the same process id when running multiple applications.
In sway I was just launching the apps and then matched them by app_id that is specific for each application, but it doesn't seem to work here.

Here is a snippet from my config:

[scratchpads.amplenote]
animation = "fromBottom"
command = "/opt/google/chrome-beta/google-chrome-beta --profile-directory=Default --app-id=pfphgelppkenhllngngioolkaeelhlmi"
class = "chrome-pfphgelppkenhllngngioolkaeelhlmi-Default"
class_match = true
size = "50% 80%"
lazy = true

[scratchpads.ytmusic]
animation = "fromBottom"
command = "/opt/google/chrome-beta/google-chrome-beta --profile-directory=Default --app-id=cinhimbnkkaeohfgghhklpknlkffjgod"
class = "chrome-cinhimbnkkaeohfgghhklpknlkffjgod-Default"
class_match = true
size = "50% 80%"
lazy = true
unfocus = "hide"

Thank you for your help and this amazing project!

[FEAT] How to send commands to the created scratchpads?

Hello! Hope you're doing well. Thank you for creating pyprland!

Description

I'm using scratchpads:

[scratchpads.music]
command = "kitty --class kitty_music"
animation = "fromRight"
class = "kitty_music"
size = "20% 60%"
margin = 10

After the scratchpads, I'd like to run the command ncmpcpp such that I'm dropped straight to my music player.

What I've Tried

The following command doesn't work:

command = "kitty --class kitty_music zsh -c 'ncmpcpp'"

Any help is much appreciated. Thank you!

opening firefox - open a normal hyprland window

tried this configuration:

[scratchpads.nixpkgs-search]
animation = "fromTop"
command = "firefox --no-remote --class nixpkgs-search --new-window https://search.nixos.org/packages"
class = "nixpkgs-search"
lazy = true
size = "50% 75%"
position = "25% 5%"
excludes = "*"

get this error:
Failed spawning nixpkgs-search as proc 608846 "firefox --new-window https://search.nixos.org/packages": The command terminated sucessfully, is it already running? Failed to show nixpkgs-search, aborting.

PS. also tried without the class

image

Cannot Toggle scratchpads due to errors

Hi, I've been trying to use this for my setup but it keeps giving out the following error

ERROR:scratch:client_info of  must be a dict: None
scratchpads::run_toggle(('term',)) failed:

Traceback (most recent call last):
  File "/home/red/.local/pipx/venvs/pyprland/lib/python3.11/site-packages/pyprland/plugins/scratchpads.py", line 124, in updateClientInfo
    assert isinstance(client_info, dict)
AssertionError

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "/home/red/.local/pipx/venvs/pyprland/lib/python3.11/site-packages/pyprland/command.py", line 75, in _callHandler
    await getattr(plugin, full_name)(*params)
  File "/home/red/.local/pipx/venvs/pyprland/lib/python3.11/site-packages/pyprland/plugins/scratchpads.py", line 275, in run_toggle
    await self.run_show(uid)
  File "/home/red/.local/pipx/venvs/pyprland/lib/python3.11/site-packages/pyprland/plugins/scratchpads.py", line 385, in run_show
    await self.updateScratchInfo(item)
  File "/home/red/.local/pipx/venvs/pyprland/lib/python3.11/site-packages/pyprland/plugins/scratchpads.py", line 317, in updateScratchInfo
    await scratch.updateClientInfo()
  File "/home/red/.local/pipx/venvs/pyprland/lib/python3.11/site-packages/pyprland/plugins/scratchpads.py", line 129, in updateClientInfo
    raise AssertionError(e) from e
AssertionError

Steps to recreate this
pypr
pypr toggle term
Gives out this exception
Is it due to python version ? If so what version should I set it up using, thank you!

Quick flashes of other workspaces when moving the mouse between monitors

I just tried this out in order to get the workspace switching behaviour I'm looking for on multi-monitor. I really like this idea of running a side process with plugins.

The only plugin I enabled is workspaces following focus. I noticed that if I move the mouse between the monitors there is sometimes a flickering effect where I briefly see another workspace displayed on the monitor I'm switching to.

If you move the mouse back and forth across the boundary between monitors very quickly it seems to happen more.

Exclude appears not working on 1.6.8

Hi, I just update to the latest version 1.6.8 and the exclude feature appears not working. Steps to reproduce

  1. Open term scratchpad
  2. Open messenger scratchpad
  3. I expect the term scratchpad is hidden by pypr, but it's not. Both scratchpad are showed at the same time.

My configurations:

[pyprland]
plugins = [
  "scratchpads",
]

[scratchpads.term]
command = "alacritty -t __scratchpad"
animation = ""
lazy = true
unfocus = ""
size = "50% 50%"
position = "25% 25%"
excludes = "*"

[scratchpads.messenger]
command = "caprine"
animation = ""
unfocus = ""
lazy = true
size = "50% 50%"
position = "25% 25%"
excludes = "*"

Thank you!

Unable to hide scratchpad

pyprland config:

{
  "pyprland": {
    "plugins": [
      "scratchpads"
    ]
  },
  "scratchpads": {
    "term": {
      "command": "foot",
      "animation": "fromTop",
      "unfocus": "hide"
    },
    "irc": {
      "command": "freetube-bin",
      "animation": "fromTop",
      "unfocus": "hide",
      "lazy": "true"
    },
    "qutebrowser": {
      "command": "qutebrowser",
      "animation": "fromTop",
      "lazy": "true"
    },
    "volume": {
      "command": "pavucontrol",
      "unfocus": "hide",
      "animation": "fromRight"
    }
  },
  "monitors": {
    "placement": {
      "LG 40WP95C-W": {
        "topOf": "DP-1"
      }
    }
  }
}

hyprland config:

bind = SUPER,Y,exec,pypr toggle irc
$irc  = ^(freetube-bin)$
windowrule = float,$irc
windowrule = workspace special silent,$irc
windowrule = size 50% 60%,$irc
windowrule = center,$irc

error:

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "/usr/lib/python3.11/site-packages/pyprland/command.py", line 75, in _callHandler
    await getattr(plugin, full_name)(*params)
  File "/usr/lib/python3.11/site-packages/pyprland/plugins/scratchpads.py", line 275, in run_toggle
    await self.run_show(uid)
  File "/usr/lib/python3.11/site-packages/pyprland/plugins/scratchpads.py", line 385, in run_show
    await self.updateScratchInfo(item)
  File "/usr/lib/python3.11/site-packages/pyprland/plugins/scratchpads.py", line 317, in updateScratchInfo
    await scratch.updateClientInfo()
  File "/usr/lib/python3.11/site-packages/pyprland/plugins/scratchpads.py", line 129, in updateClientInfo
    raise AssertionError(e) from e
AssertionError
ERROR:scratch:client_info of  must be a dict: None
scratchpads::run_toggle(('irc',)) failed:

Traceback (most recent call last):
  File "/usr/lib/python3.11/site-packages/pyprland/plugins/scratchpads.py", line 124, in updateClientInfo
    assert isinstance(client_info, dict)
AssertionError

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "/usr/lib/python3.11/site-packages/pyprland/command.py", line 75, in _callHandler
    await getattr(plugin, full_name)(*params)
  File "/usr/lib/python3.11/site-packages/pyprland/plugins/scratchpads.py", line 273, in run_toggle
    await self.run_hide(uid)
  File "/usr/lib/python3.11/site-packages/pyprland/plugins/scratchpads.py", line 336, in run_hide
    await self._anim_hide(animation_type, scratch)
  File "/usr/lib/python3.11/site-packages/pyprland/plugins/scratchpads.py", line 283, in _anim_hide
    await self.updateScratchInfo(scratch)
  File "/usr/lib/python3.11/site-packages/pyprland/plugins/scratchpads.py", line 317, in updateScratchInfo
    await scratch.updateClientInfo()
  File "/usr/lib/python3.11/site-packages/pyprland/plugins/scratchpads.py", line 129, in updateClientInfo
    raise AssertionError(e) from e
AssertionError
ERROR:scratch:client_info of  must be a dict: None
scratchpads::run_toggle(('irc',)) failed:

fromRight animation not applied on first display of lazy loaded scratchpad

I configured a scratchpad for pavucontrol to be started lazily with animation = fromRight.

When I first open the scratchpad the animation comes from the left, re-opening the scratchpad after it's started applies the configured animation.
See video below, it helps to watch the video at 20% - 50% of the original speed.

Setting lazy: false applies the correct animation every time.

scratchpad config

"scratchpads": {                                                                                                  
  "volume": {                                                                                                     
    "command": "pavucontrol",                                                                                     
    "animation": "fromRight",                                                                                     
    "lazy": true,                                                                                                 
    "unfocus": "hide"                                                                                             
  }                                                                                                               
} 
pavucontrol-lazy-fromRight.mp4

Scratchpads don't work on non-default screen scales

My laptop has a 14" display, so I have set the scale to the value 2. I can't get Pyprland to work correctly with this. I tried to configure a scratchpad with a dropterm just as in the README, but the terminal window spawns outside the screen. When I set the scale to 1, everything works just as intended, but I can't use this scale all the time.

UPD: The problem only occurs when an animation is set in pyprland.json.

Cannot launch pypr

Hi I am getting this error when I try to launch pypr from terminal. I installed it manually following aur steps. Also tried using pip to install it. Both show the following error

Traceback (most recent call last):
File "/usr/lib/python3.11/site-packages/pyprland/command.py", line 165, in run_daemon
await manager.load_config() # ensure sockets are connected first
^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/lib/python3.11/site-packages/pyprland/command.py", line 39, in load_config
self.config = json.loads(f.read())
^^^^^^^^^^^^^^^^^^^^
File "/usr/lib/python3.11/json/init.py", line 346, in loads
return _default_decoder.decode(s)
^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/lib/python3.11/json/decoder.py", line 340, in decode
raise JSONDecodeError("Extra data", s, end)
json.decoder.JSONDecodeError: Extra data: line 1 column 14 (char 13)
Exception ignored in: <function StreamWriter.del at 0x7f317ec3d940>
Traceback (most recent call last):
File "/usr/lib/python3.11/asyncio/streams.py", line 396, in del
self.close()
File "/usr/lib/python3.11/asyncio/streams.py", line 344, in close
return self._transport.close()
^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/lib/python3.11/asyncio/selector_events.py", line 860, in close
self._loop.call_soon(self._call_connection_lost, None)
File "/usr/lib/python3.11/asyncio/base_events.py", line 761, in call_soon
self._check_closed()
File "/usr/lib/python3.11/asyncio/base_events.py", line 519, in _check_closed
raise RuntimeError('Event loop is closed')
RuntimeError: Event loop is closed

Scratchpad behaviour when switching workspaces

Hi, it's me again.

I wonder you could consider improving the behaviour of scratchpad windows when switching workspaces as it is something I noticed recently.

  1. Open scratchpad (e.g. term) window on current worskpace 1
  2. Without closing it, switch to another workspace
  3. Try to open the same scratchpad again

Current behaviour:
It switches you back to workspace 1 where the toggle hides the term

Expected behaviour
Have term from scratchpad open on the current workspace

What do you think?

[BUG] Scratchpad stays on screen when hidden after reconnecting monitor

Pyprland version
2.0.2

Describe the bug
When disconnecting external monitor scratchpad will always stays on screen. When hidden it show on top of all windows and is unable to focus. When shown it behaves as usual. The problem stays after all of: close scratchapd window, hyprctl reload, restart pypr.

To Reproduce

  1. Scratchpad is shown on external monitor
  2. Disconnect monitor
  3. Observe wrong behavior on laptop screen. Stays broken after connecting monitor

Expected behavior
Behave as usual: hide scratchpad completely

Configuration (provide following files/samples when relevant):

  • pyprland.toml
        [scratchpads.term-quake]
        command = "wezterm start --class term-quake"
        position = "0% 0%"
        size = "100% 50%"
  • hyprland.conf
          bind = ,T, exec, pypr toggle term-quake
          bind = ,T, submap, reset
          $term_quake = ^(term-quake)$
          windowrule = workspace special silent,$term_quake
          windowrule = float,$term_quake
    

Additional context
I was able to fix manually by hyprctl dispatch togglespecialworkspace scratch_term-quake. After that works as expected.

Scratchpad does not detect that terminal process has ended

When using scratchpads for a Terminal scratchpad as described in https://github.com/hyprland-community/pyprland/wiki/Plugins#scratchpads with lazy mode enabled, it is possible to end the terminal process with CTRL + D from within the terminal.

When pressing the terminal scratchpad key combo again pypr seems to be unaware that the process has ended - nothing happens.
Pressing the keyboard combo for the terminal scratchpad again will restart it. Needing to press the key combo twice is non-intuitive.

Desired behaviour
pypr restarts the program within a scratchpad in case it was closed on first attempt to open it.

Possible solution
It would be great if pypr could detect if the program within a scratchpad is still/ not anymore running and restart it accordingly.

Feature request: Max scratchpad size / per monitor config

Hi, firstly let me thank you for this amazing project. Your scratchpad implementation is the best I found so far!

I would like you to consider adding an option for maximum width/height of the scratchpad window.
The problem I have is that I work with different screen ratios:

  • 3:2 laptop (2256x1504)
  • 16:9 monitors at work (mix of 1080p, 1440p and 4k)
  • 32:9 monitor at home (5120x1440)

The main problem for me is the width at my ultrawide monitor at home. If i set up a scratchpad width for 80% it looks ok at my laptop and even at work, but it is way too wide on my 5120 ultrawide.

Ideally it would be great to be able to set maxWidth and maxHeight in pixels so it never gets bigger than these values on huge screens.

Another solution would be a setting per monitor, but it would have to match per description as work and home are being connected to the same port on my laptop so it's not always same resolution.

On sway I just used absolute values in px for my scratchpad for something that works ok-ish on all monitors, so that would also help even though it's not ideal.

Thank you for your work!

feishin scratchpad issue

Hi! I tried to pair feishin with pyprland to achieve a toggleable set-up, but I couldn't get pypr to hide feishin when focus was lost. In addition to that, pypr also reports this error when launching feishin:

Client address is invalid
Traceback (most recent call last):
  File "/usr/lib/python3.11/site-packages/pyprland/command.py", line 75, in _callHandler
    await getattr(plugin, full_name)(*params)
  File "/usr/lib/python3.11/site-packages/pyprland/plugins/scratchpads.py", line 389, in run_toggle
    await self.run_show(uid)
  File "/usr/lib/python3.11/site-packages/pyprland/plugins/scratchpads.py", line 429, in run_show
    await item.updateClientInfo()
  File "/usr/lib/python3.11/site-packages/pyprland/plugins/scratchpads.py", line 194, in updateClientInfo
    client_info = await get_client_props(addr="0x" + self.address)
                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3.11/site-packages/pyprland/plugins/scratchpads.py", line 52, in get_client_props
    assert len(addr) > 2, "Client address is invalid"
           ^^^^^^^^^^^^^
AssertionError: Client address is invalid

Here's my pyprland.json:

{
  "pyprland": {
    "plugins": ["scratchpads", "magnify"]
  },
  "scratchpads": {
    "terminal": {
      "command": "kitty --class scratchpad",
      "margin": 50,
      "animation": "fromBottom",
      "unfocus": "hide"
    },
    "music": {
      "command": "/usr/bin/feishin",
      "lazy": true,
      "animation": "fromBottom",
      "unfocus": "hide"
    }
  }
}

and relevant parts from hyprland.conf:

bind = SUPER SHIFT, M,      exec, pypr toggle music     && hyprctl dispatch bringactivetotop

$music          = class:^(feishin)$
windowrulev2    = float,                    $music 
windowrulev2    = size 80% 80%,             $music
windowrulev2    = center,                   $music

Scratchpads do not work properly for emacsclient

Reopen of #6 with more information
Video demonstration: https://youtu.be/chP2NtZRRVw (youtube is still processing the video at time of submitting, give it a few minutes if high resolution isn't available yet)

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

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 (see video demonstration)

Issue with pypr commands

First of all I want to say that I am sorry if I am missing something obvious here.

I have pypr installed from the lazy branch as was documented here:

          Thank you very much !

For anyone else wondering I used

pipx install git+https://github.com/hyprland-community/pyprland.git@onlylazy

To install it

Originally posted by @redsteadz in #19 (comment)

Here is my .config/hypr/hyprland.conf:


# -----------------------------------------------------
# Keyboard Layout
# -----------------------------------------------------
# $keyboardlayout=de
$keyboardlayout=us

# -----------------------------------------------------
# Monitor Setup
# See https://wiki.hyprland.org/Configuring/Monitors/
# -----------------------------------------------------
monitor=HDMI-A-1,1920x1080@60,0x0,1
monitor=eDP-1,1920x1080@60,1920x0,auto
# monitor=,2560x1440@120,auto,1
# monitor=,1920x1080,auto,1
#
# -----------------------------------------------------
# Autostart & Environment
# -----------------------------------------------------
source = ~/dotfiles/hypr/conf/environment.conf
source = ~/dotfiles/hypr/conf/autostart.conf

# -----------------------------------------------------
# Load pywal color file
# -----------------------------------------------------
source = ~/.cache/wal/colors-hyprland.conf

# -----------------------------------------------------
# Load configuration files
# -----------------------------------------------------
source = ~/dotfiles/hypr/conf/keyboard.conf
source = ~/dotfiles/hypr/conf/window.conf
source = ~/dotfiles/hypr/conf/decoration.conf
source = ~/dotfiles/hypr/conf/layouts.conf
source = ~/dotfiles/hypr/conf/misc.conf
source = ~/dotfiles/hypr/conf/keybindings.conf
source = ~/dotfiles/hypr/conf/windowrules.conf

# -----------------------------------------------------
# Animation
# -----------------------------------------------------
source = ~/dotfiles/hypr/conf/animations-low.conf
# source = ~/dotfiles/hypr/conf/animations-high.conf
#
#xwayland { use_nearest_neighbor = false }

exec-once = pypr
bind = SUPER,D,exec,pypr toggle discord
#windowrule = floa,^(discord)$
#windowrule = workspace special silent,^(discord)$

# <------- Here is the relevant part !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -------->
bind = SUPER,V,exec,pypr toggle volume
windowrule = float,^(pavucontrol)$
windowrule = workspace special silent,^(pavucontrol)$

here is my pyprland.json:

{
    "pyprland": {
        "plugins": [
            "scratchpads"
	]
    },
    "scratchpads": {
        "discord": {
            "command": "discord",
            "animation": "fromTop",
            "unfocus": "false"
        },
	"volume": {
	    "command": "pavucontrol",
	    "animation": "fromRight"
	}
    }
}

Through some debugging I noticed if i ran pypr inside the terminal discord and pavucontrol start up, but when i run pypr toggle volume in order to toggle pavucontrol I get an unhandled exception:

❯ pypr toggle volume
Unhandled exception:
Traceback (most recent call last):
  File "/home/anime_protagonist/.local/pipx/venvs/pyprland/lib/python3.11/site-packages/pyprland/command.py", line 242, in main
    asyncio.run(run_daemon() if len(sys.argv) <= 1 else run_client())
  File "/usr/lib/python3.11/asyncio/runners.py", line 190, in run
    return runner.run(main)
           ^^^^^^^^^^^^^^^^
  File "/usr/lib/python3.11/asyncio/runners.py", line 118, in run
    return self._loop.run_until_complete(task)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3.11/asyncio/base_events.py", line 653, in run_until_complete
    return future.result()
           ^^^^^^^^^^^^^^^
  File "/home/anime_protagonist/.local/pipx/venvs/pyprland/lib/python3.11/site-packages/pyprland/command.py", line 220, in run_client
    _, writer = await asyncio.open_unix_connection(CONTROL)
                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3.11/asyncio/streams.py", line 98, in open_unix_connection
    transport, _ = await loop.create_unix_connection(
                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3.11/asyncio/unix_events.py", line 259, in create_unix_connection
    await self.sock_connect(sock, path)
  File "/usr/lib/python3.11/asyncio/selector_events.py", line 634, in sock_connect
    return await fut
           ^^^^^^^^^
  File "/usr/lib/python3.11/asyncio/selector_events.py", line 642, in _sock_connect
    sock.connect(address)
ConnectionRefusedError: [Errno 111] Connection refused

The output for the show command is the same:

❯ pypr show volume
Unhandled exception:
Traceback (most recent call last):
  File "/home/anime_protagonist/.local/pipx/venvs/pyprland/lib/python3.11/site-packages/pyprland/command.py", line 242, in main
    asyncio.run(run_daemon() if len(sys.argv) <= 1 else run_client())
  File "/usr/lib/python3.11/asyncio/runners.py", line 190, in run
    return runner.run(main)
           ^^^^^^^^^^^^^^^^
  File "/usr/lib/python3.11/asyncio/runners.py", line 118, in run
    return self._loop.run_until_complete(task)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3.11/asyncio/base_events.py", line 653, in run_until_complete
    return future.result()
           ^^^^^^^^^^^^^^^
  File "/home/anime_protagonist/.local/pipx/venvs/pyprland/lib/python3.11/site-packages/pyprland/command.py", line 220, in run_client
    _, writer = await asyncio.open_unix_connection(CONTROL)
                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3.11/asyncio/streams.py", line 98, in open_unix_connection
    transport, _ = await loop.create_unix_connection(
                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3.11/asyncio/unix_events.py", line 259, in create_unix_connection
    await self.sock_connect(sock, path)
  File "/usr/lib/python3.11/asyncio/selector_events.py", line 634, in sock_connect
    return await fut
           ^^^^^^^^^
  File "/usr/lib/python3.11/asyncio/selector_events.py", line 642, in _sock_connect
    sock.connect(address)
ConnectionRefusedError: [Errno 111] Connection refused

Any pypr commands will have the same problem with discord or any other scratchpad.

I also installed it with pipx install pyprland before all of this and the behaviour was the same.

[feature] Option to have a given scratchpad to only start the commands on first display

Loving the scratchpad functionality that this brings to Hyprland.

I am defining quite a few scratchpads, many of which I use rarely, so having them all launch on startup even though they are hidden is not ideal, at least not for the less often used ones.

Is it possible to have an option to not launch some or all scratchpads on pyprland start? I would be happy even if I have to trigger the keybinding twice to open it as currently happens if you close the scratchpad window and try to launch it again

how do I set up expose plugin?

{
  "pyprland": {
    "plugins": [
      "scratchpads",
      "expose"
    ]
  },
  "scratchpads": {
    "term": {
      "command": "wezterm start --class wezterm-dropterm",
      "animation": "fromTop",
      "unfocus": "hide"
    }
  },
  "expose": {
    "include_special": true
  }
}
Error loading plugin expose: No module named 'pyprland.plugins.expose'

also it would be nice to have pypr --version

activewindow can return an empty result, crashing pypr

Need some guards around these cast values (and probably anywhere else this assumption is made).

expose::run_expose(()) failed:
'address'
Traceback (most recent call last):
  File "/usr/lib/python3.11/site-packages/pyprland/command.py", line 119, in _run_plugin_handler
    await getattr(plugin, full_name)(*params)
  File "/usr/lib/python3.11/site-packages/pyprland/plugins/expose.py", line 44, in run_expose
    focused_addr = aw["address"]
                   ~~^^^^^^^^^^^
KeyError: 'address'
expose::run_expose(()) failed:
'address'
Traceback (most recent call last):
  File "/usr/lib/python3.11/site-packages/pyprland/command.py", line 119, in _run_plugin_handler
    await getattr(plugin, full_name)(*params)
  File "/usr/lib/python3.11/site-packages/pyprland/plugins/expose.py", line 44, in run_expose
    focused_addr = aw["address"]
                   ~~^^^^^^^^^^^
KeyError: 'address'

When this happened during expose I had to manually move all my windows back to their original workspaces from the expose workspace.

Scratchpads running, but wont show up

I'm experiencing a problem where when i run an application in a scratchpad it does run the program but wont display it. I think this problem occurs when a program is running trough xwayland instead of native wayland, since everything I've tried so far suggests that being the issue. It would be nice if someone could try reproducing it because I've not seen anyone online raise this issue. I'm running arch linux if that information helps.

Maybe this isn't even a pyprland problem but a hyprland one, not sure.

Scratchpads not working with keybind

I cannot get scratchpads to work. I have tried the same config as described in the wiki, but I cannot get a keybind to launch the scratchpad.

If I call pypr toggle term from the terminal, however, it does work- including removing the window when it loses focus.

in my hyprland.conf:

exec-once = pypr
# scratchpad
bind = ALT, code:51, exec, pypr toggle term
$dropterm = ^(kitty-dropterm)$
windowrule = float, $dropterm
windowrule = workspace special silent, $dropterm
windowrule = size 80% 70%, $dropterm

and in my pyprland.json:

{
  "pyprland": {
    "plugins": [
    "scratchpads",
    "monitors"
    ]
  },
  "scratchpads": {
    "term": {
      "command": "kitty --class kitty-dropterm"
    }
  },
  "monitors": {
    "placement": {
      "SB2": {
        "topOf": "eDP-1"
      }
    },
    "unknown": "wlrlui"
  }
}

running pypr --debug /tmp/pypr.log I get:

❯ pypr --debug /tmp/pypr.log
                      ipc - Logger initialized for ipc // common.py:70
                  startup - Logger initialized for startup // common.py:70
                     pypr - Logger initialized for pypr // common.py:70
              scratchpads - Logger initialized for scratchpads // common.py:70
                 monitors - Logger initialized for monitors // common.py:70
                      ipc - monitors // ipc.py:25
                     pypr - scratchpads.event_activewindowv2('5609d0214130\n',) // command.py:73
                     pypr - scratchpads.event_activewindowv2('5609d0214130\n',) // command.py:73
                     pypr - scratchpads.event_openwindow('5609d06194d0,special,kitty-dropterm,kitty\n',) // command.py:73
                      ipc - clients // ipc.py:25
              scratchpads - Hiding term // scratchpads.py:322
                      ipc - movetoworkspacesilent special:scratch_term,address:0x5609d06194d0 // ipc.py:53
                     pypr - scratchpads.event_activewindowv2('5609d0c2c8f0\n',) // command.py:73
                     pypr - scratchpads.event_activewindowv2('5609d0c2c8f0\n',) // command.py:73
                     pypr - scratchpads.event_activewindowv2('5609d0214130\n',) // command.py:73

but pressing my set keybind does not output anything to the log. I should note that I have also tried $mainMod + V to no avail.

I have tried both the pip package and build from source, both have the same behavior (1.4.0)

[BUG] scratchpads "position" option is ignored

Pyprland version
Pyprland 2.0.4 and pyprland-git r650.ba16fc8-1 (Arch Linux AUR Package)

Describe the bug
scratchpads don't follow "position" option

To Reproduce

  1. set "position" option in pyprland.toml
  2. (re)start pypr daemon
  3. The floating window is fixed in relation of the "animation" option.
    "fromTop" puts it in the center of the screen horizontally. "fromRight" puts it in the center of the screen vertically. The "position" option is ignored.

Expected behavior
The drop window should be placed at the designated coordinates.

Configuration

  • pyprland.toml
…
[scratchpads.term]
animation = "fromRight"
command = "wezterm start --class=wezterm-dropterm"
class = "wezterm-dropterm"
margin = 13
size = "2102px 1154px"
position = "500px 500px"

Additional context
LOG

2024-02-29 18:19:49,293 [INFO] ipc :: Logger "ipc" initialized :: common.py:78
2024-02-29 18:19:49,293 [INFO] startup :: Logger "startup" initialized :: common.py:78
2024-02-29 18:19:49,293 [INFO] pypr :: Logger "pypr" initialized :: common.py:78
2024-02-29 18:19:49,294 [INFO] pypr :: Loading /home/ewigkeit/.config/hypr/pyprland.toml :: command.py:66
2024-02-29 18:19:49,294 [INFO] pyprland :: Logger "pyprland" initialized :: common.py:78
2024-02-29 18:19:49,294 [DEBUG] ipc :: activeworkspace :: ipc.py:75
2024-02-29 18:19:49,294 [DEBUG] ipc :: monitors :: ipc.py:75
2024-02-29 18:19:49,294 [INFO] pyprland :: configured :: command.py:119
2024-02-29 18:19:49,299 [INFO] scratchpads :: Logger "scratchpads" initialized :: common.py:78
2024-02-29 18:19:49,299 [DEBUG] ipc :: monitors :: ipc.py:75
2024-02-29 18:19:49,299 [DEBUG] ipc :: keyword ['windowrule workspace special:scratch_term silent,^(wezterm-dropterm)$', 'windowrule float,^(wezterm-dropterm)$', 'windowrule move 200% 500,^(wezterm-dropterm)$', 'windowrule size 2102 1154,^(wezterm-dropterm)$'] :: ipc.py:114
2024-02-29 18:19:49,300 [INFO] scratchpads :: term is not running, starting... :: scratchpads.py:512
2024-02-29 18:19:49,301 [INFO] scratchpads :: scratch term (wezterm start --class=wezterm-dropterm) has pid 39792 :: scratchpads.py:531
2024-02-29 18:19:49,301 [INFO] scratchpads :: starting term :: scratchpads.py:485
2024-02-29 18:19:49,301 [INFO] scratchpads :: ==> Wait for term spawning :: scratchpads.py:435
2024-02-29 18:19:49,402 [DEBUG] ipc :: clients :: ipc.py:75
2024-02-29 18:19:49,804 [DEBUG] ipc :: clients :: ipc.py:75
2024-02-29 18:19:49,805 [INFO] scratchpads :: => term client (proc:39792, addr:0x606d6d6bfc40) detected on time :: scratchpads.py:448
2024-02-29 18:19:49,805 [INFO] scratchpads :: configured :: command.py:119
2024-02-29 18:19:49,805 [DEBUG] pypr :: ================================[ initialized ]================================= :: command.py:293
2024-02-29 18:19:49,805 [DEBUG] pyprland :: �[30;1mevent_activewindowv2('606d6d6b2f50',)�[0m :: command.py:142
2024-02-29 18:19:49,805 [DEBUG] scratchpads :: �[30;1mevent_activewindowv2('606d6d6b2f50',)�[0m :: command.py:142
2024-02-29 18:19:49,805 [DEBUG] scratchpads :: �[30;1mevent_openwindow('606d6d6bfc40,special:scratch_term silent,wezterm-dropterm,wezterm',)�[0m :: command.py:142
2024-02-29 18:19:49,805 [DEBUG] ipc :: clients :: ipc.py:75
2024-02-29 18:19:49,806 [DEBUG] ipc :: dispatch movetoworkspacesilent special:scratch_term,address:0x606d6d6bfc40 :: ipc.py:114
2024-02-29 18:20:02,944 [DEBUG] pyprland :: �[30;1mevent_activewindowv2('606d6d6b2f50',)�[0m :: command.py:142
2024-02-29 18:20:02,944 [DEBUG] scratchpads :: �[30;1mevent_activewindowv2('606d6d6b2f50',)�[0m :: command.py:142
2024-02-29 18:20:03,504 [DEBUG] scratchpads :: �[33;1mrun_toggle('term',)�[0m :: command.py:142
2024-02-29 18:20:03,504 [DEBUG] scratchpads :: term is visible = False :: scratchpads.py:691
2024-02-29 18:20:03,504 [INFO] scratchpads :: Showing term :: scratchpads.py:738
2024-02-29 18:20:03,504 [DEBUG] ipc :: monitors :: ipc.py:75
2024-02-29 18:20:03,505 [DEBUG] ipc :: keyword ['windowrule workspace special:scratch_term silent,^(wezterm-dropterm)$', 'windowrule float,^(wezterm-dropterm)$', 'windowrule move 200% 500,^(wezterm-dropterm)$', 'windowrule size 2102 1154,^(wezterm-dropterm)$'] :: ipc.py:114
2024-02-29 18:20:03,506 [DEBUG] ipc :: clients :: ipc.py:75
2024-02-29 18:20:03,506 [DEBUG] ipc :: monitors :: ipc.py:75
2024-02-29 18:20:03,506 [DEBUG] ipc :: dispatch ['moveworkspacetomonitor special:scratch_term DP-1', 'movetoworkspacesilent 1,address:0x606d6d6bfc40', 'alterzorder top,address:0x606d6d6bfc40'] :: ipc.py:114
2024-02-29 18:20:03,507 [DEBUG] pyprland :: �[30;1mevent_activewindowv2('606d6d6b2f50',)�[0m :: command.py:142
2024-02-29 18:20:03,510 [DEBUG] ipc :: dispatch movewindowpixel exact 500 500,address:0x606d6d6bfc40 :: ipc.py:114
2024-02-29 18:20:03,511 [DEBUG] ipc :: dispatch resizewindowpixel exact 2102 1154,address:0x606d6d6bfc40 :: ipc.py:114
2024-02-29 18:20:03,511 [DEBUG] ipc :: clients :: ipc.py:75
2024-02-29 18:20:03,512 [DEBUG] ipc :: dispatch movewindowpixel exact 1325 143,address:0x606d6d6bfc40 :: ipc.py:114
2024-02-29 18:20:03,512 [DEBUG] ipc :: dispatch focuswindow address:0x606d6d6bfc40 :: ipc.py:114
2024-02-29 18:20:03,513 [DEBUG] pyprland :: �[30;1mevent_activewindowv2('606d6d6bfc40',)�[0m :: command.py:142
2024-02-29 18:20:03,713 [DEBUG] scratchpads :: �[30;1mevent_activewindowv2('606d6d6b2f50',)�[0m :: command.py:142
2024-02-29 18:20:03,714 [DEBUG] scratchpads :: �[30;1mevent_activewindowv2('606d6d6bfc40',)�[0m :: command.py:142
2024-02-29 18:20:29,523 [DEBUG] scratchpads :: �[33;1mrun_toggle('term',)�[0m :: command.py:142
2024-02-29 18:20:29,523 [DEBUG] scratchpads :: term is visible = True :: scratchpads.py:691
2024-02-29 18:20:29,523 [INFO] scratchpads :: Hiding term :: scratchpads.py:831
2024-02-29 18:20:29,523 [DEBUG] ipc :: dispatch movewindowpixel 1500 0,address:0x606d6d6bfc40 :: ipc.py:114
2024-02-29 18:20:29,724 [DEBUG] ipc :: dispatch movetoworkspacesilent special:scratch_term,address:0x606d6d6bfc40 :: ipc.py:114
2024-02-29 18:20:29,726 [DEBUG] ipc :: dispatch focuswindow address:0x606d6d6b2f50 :: ipc.py:114
2024-02-29 18:20:29,726 [DEBUG] pyprland :: �[30;1mevent_activewindowv2('606d6d6b2f50',)�[0m :: command.py:142
2024-02-29 18:20:29,727 [DEBUG] pyprland :: �[30;1mevent_activewindowv2('606d6d6b2f50',)�[0m :: command.py:142
2024-02-29 18:20:29,727 [DEBUG] scratchpads :: �[30;1mevent_activewindowv2('606d6d6b2f50',)�[0m :: command.py:142
2024-02-29 18:20:29,727 [DEBUG] scratchpads :: �[30;1mevent_activewindowv2('606d6d6b2f50',)�[0m :: command.py:142
2024-02-29 18:20:38,990 [CRITICAL] pypr :: cancelled :: command.py:299

Especially lines 37 & 40 are interessting, as the designated position gets overridden:

2024-02-29 18:20:03,510 [DEBUG] ipc :: dispatch movewindowpixel exact 500 500,address:0x606d6d6bfc40 :: ipc.py:114
2024-02-29 18:20:03,512 [DEBUG] ipc :: dispatch movewindowpixel exact 1325 143,address:0x606d6d6bfc40 :: ipc.py:114

Thank you for your time and this helpful project!

Pyprland makes all chromium instances started with --app switch floating

Pyprland version
2.0.4

Describe the bug
I use chromium instances with the --app switch for a lot of my daily apps (like discord,element,teams,spotifiy,...).

eg.:

[scratchpads.spotify]
animation = "fromRight"
command = "chromium --class=Spotify --user-data-dir=$HOME/.cache/chromium/spotify-webApp --app=https://open.spotify.com/"
class = "Spotify"
size = "50% 80%"
lazy = true
unfocus = "hide"

These work flawlessly. But i also use chromium webApp instances for stuff like outlook where i don't want them in a scratchpad. But if i exec any other chromium with the --app switch set the spawning Window starts in a floating state.

To Reproduce

  1. Add a Scratchpad as shown in above example
  2. Open a different chromium instance via shell, hotkey or launcher with --app switch active
    eg.:
$ chromium --class=Discord --user-data-dir=$HOME/.cache/chromium/discord-webApp --app=https://discord.com/app
  1. New window starts in floating state.

Expected behavior
New window with different class Name should not start in a floating state

aur package is broken

==> Making package: pyprland 1.3.1-1 (Sun 14 May 2023 12:49:34 PM IST)
==> Retrieving sources...
  -> Cloning pyprland git repo...
Cloning into bare repository '/home/ultrahalf/.cache/paru/clone/pyprland/pyprland'...
remote: Enumerating objects: 268, done.
remote: Counting objects: 100% (30/30), done.
remote: Compressing objects: 100% (20/20), done.
remote: Total 268 (delta 14), reused 23 (delta 10), pack-reused 238
Receiving objects: 100% (268/268), 40.99 KiB | 545.00 KiB/s, done.
Resolving deltas: 100% (178/178), done.
==> Validating source files with md5sums...
    pyprland ... Skipped
==> Making package: pyprland 1.3.1-1 (Sun 14 May 2023 12:49:36 PM IST)
==> Checking runtime dependencies...
==> Checking buildtime dependencies...
==> Retrieving sources...
  -> Updating pyprland git repo...
==> Validating source files with md5sums...
    pyprland ... Skipped
==> Removing existing $srcdir/ directory...
==> Extracting sources...
  -> Creating working copy of pyprland git repo...
Cloning into 'pyprland'...
done.
Switched to a new branch 'makepkg'
==> Starting pkgver()...
Note: switching to '1.3.1'.

You are in 'detached HEAD' state. You can look around, make experimental
changes and commit them, and you can discard any commits you make in this
state without impacting any branches by switching back to a branch.

If you want to create a new branch to retain commits you create, you may
do so (now or later) by using -c with the switch command. Example:

  git switch -c <new-branch-name>

Or undo this operation with:

  git switch -

Turn off this advice by setting config variable advice.detachedHead to false

HEAD is now at b117037 monitors: trigger the rules on init & reload
==> Sources are ready.
pyprland-1.3.1-1: parsing pkg list...
==> Making package: pyprland 1.3.1-1 (Sun 14 May 2023 12:49:39 PM IST)
==> Checking runtime dependencies...
==> Checking buildtime dependencies...
==> WARNING: Using existing $srcdir/ tree
==> Starting pkgver()...
HEAD is now at b117037 monitors: trigger the rules on init & reload
==> Starting build()...
/usr/bin/python: No module named build
==> ERROR: A failure occurred in build().
    Aborting...
error: failed to build 'pyprland-1.3.1-1':
error: packages failed to build: pyprland-1.3.1-1

Sorry for the text dump I'm still exploring wayland

Scratchpad with anytype does not open

I am trying to configure a scratchpad containing AnyType which is an electron app distributed as appimage [1].

When trying to open anytype via the SUPER + a key combo anytype gets started, the tray icon appears, but the main window is never shown. Triggering the key combo multiple times does not work.

I use the following configuration (which works well with wezterm)

hyprland.conf

bind = $mod, a, exec, pypr toggle anytype                                                                               
$droptype = ^(anytype)$                                                                                                 
windowrule = float, $droptype                                                                                           
windowrule = workspace special silent, $droptype                                                                        
windowrule = size 75% 60%, $droptype

pyprland.json

{                                                                                                                       
  "pyprland": {                                                                                                         
    "plugins": ["scratchpads"]                                                                                          
  },                                                                                                                    
  "scratchpads": {                                                                                                      
    "anytype": {                                                                                                        
      "command": "anytype --ozone-platform=wayland --enable-features=UseOzonePlatform",                                 
      "animation": "fromTop",                                                                                           
      "lazy": true                                                                                                      
    }                                                                                  
  }

I am starting pypr with pypr --debug /tmp/pypr.log which produces the following log output when trying to open anytype

2023-09-02 16:09:30,335 [INFO] ipc :: Logger initialized for ipc :: common.py:70
2023-09-02 16:09:30,335 [INFO] startup :: Logger initialized for startup :: common.py:70
2023-09-02 16:09:30,336 [INFO] pypr :: Logger initialized for pypr :: common.py:70
2023-09-02 16:09:30,337 [INFO] scratchpads :: Logger initialized for scratchpads :: common.py:70
2023-09-02 16:09:31,116 [DEBUG] pypr :: scratchpads.event_activewindowv2('459e530\n',) :: command.py:73
2023-09-02 16:09:32,500 [DEBUG] pypr :: scratchpads.event_activewindowv2('45dd400\n',) :: command.py:73
2023-09-02 16:09:32,534 [DEBUG] pypr :: scratchpads.event_activewindowv2('45c7840\n',) :: command.py:73
2023-09-02 16:09:35,159 [DEBUG] pypr :: scratchpads.event_activewindowv2('45dd400\n',) :: command.py:73
2023-09-02 16:09:46,988 [DEBUG] pypr :: scratchpads.event_activewindowv2('45c7840\n',) :: command.py:73
2023-09-02 16:09:47,480 [DEBUG] pypr :: scratchpads.event_activewindowv2('45d32a0\n',) :: command.py:73
2023-09-02 16:09:51,950 [DEBUG] pypr :: scratchpads.event_activewindowv2('45c7840\n',) :: command.py:73
2023-09-02 16:09:55,738 [DEBUG] pypr :: CMD: run_toggle(['anytype']) :: command.py:119
2023-09-02 16:09:55,738 [DEBUG] pypr :: scratchpads.run_toggle('anytype',) :: command.py:73
2023-09-02 16:09:55,738 [DEBUG] scratchpads :: anytype is visible = False :: scratchpads.py:262
2023-09-02 16:09:55,738 [DEBUG] ipc :: activewindow :: ipc.py:25
2023-09-02 16:09:55,739 [INFO] scratchpads :: Showing anytype :: scratchpads.py:358
2023-09-02 16:09:55,739 [INFO] scratchpads :: anytype is not running, restarting... :: scratchpads.py:361
2023-09-02 16:09:57,271 [DEBUG] pypr :: scratchpads.event_activewindowv2('45c7840\n',) :: command.py:73
2023-09-02 16:09:57,272 [DEBUG] pypr :: scratchpads.event_openwindow('45ee350,special,anytype,Anytype\n',) :: command.py:73
2023-09-02 16:09:57,272 [DEBUG] ipc :: clients :: ipc.py:25
2023-09-02 16:10:11,149 [DEBUG] pypr :: scratchpads.event_activewindowv2('45d32a0\n',) :: command.py:73
2023-09-02 16:10:13,682 [DEBUG] pypr :: scratchpads.event_activewindowv2('45c7840\n',) :: command.py:73

The hyprland log looks like this

[LOG] [16:09:55:604] Keybind triggered, calling dispatcher (64, , 97)
[LOG] [16:09:55:604] Executing WAYLAND_DISPLAY=wayland-1 DISPLAY=:0 pypr toggle anytype
[LOG] [16:09:55:613] Process Created with pid 14337
[LOG] [16:09:56:763] TextInputV1Manager bound successfully!
[LOG] [16:09:57:264] New XDG Surface created. (class: anytype)
[LOG] [16:09:57:264] Registered signal for owner 45ee350: 45e9520 -> 45ee3b8 (owner: XDG Window)
[LOG] [16:09:57:264] Registered signal for owner 45ee350: 45f0a40 -> 45ee488 (owner: XDG Window)
[LOG] [16:09:57:269] Registered signal for owner 45ee350: 45e9dc0 -> 45ee968 (owner: Toplevel)
[LOG] [16:09:57:269] Registered signal for owner 45ee350: 45e9dd0 -> 45ee9d0 (owner: Toplevel)
[LOG] [16:09:57:269] Registered signal for owner 45ee350: 45e9de0 -> 45ee900 (owner: Toplevel)
[LOG] [16:09:57:269] Registered signal for owner 45eeb70: 45e9550 -> 45eeb78 (owner: CWLSurface)
[LOG] [16:09:57:269] CWLSurface 45eeb70 called init()
[LOG] [16:09:57:269] Registered signal for owner 45ee350: 45e9530 -> 45ee420 (owner: CWindow)
[LOG] [16:09:57:269] Searching for matching rules for anytype (title: Anytype)
[LOG] [16:09:57:270] Window rule size 75% 60% -> ^(anytype)$ matched 45ee350 [Anytype]
[LOG] [16:09:57:270] Window rule float -> ^(anytype)$ matched 45ee350 [Anytype]
[LOG] [16:09:57:270] Window rule workspace special silent -> ^(anytype)$ matched 45ee350 [Anytype]
[LOG] [16:09:57:270] Rule workspace matched by window 45ee350, ^(anytype)$ applied.
[LOG] [16:09:57:270] Rule size, applying to window 45ee350
[LOG] [16:09:57:270] Window got assigned a surfaceTreeNode 0
[LOG] [16:09:57:270] Registered signal for owner 45ee350: 45e9510 -> 45ee350 (owner: XDG Window Late)
[LOG] [16:09:57:270] Registered signal for owner 45ee350: 45f10d0 -> 45ee4f0 (owner: XDG Window Late)
[LOG] [16:09:57:270] Registered signal for owner 45ee350: 45f0a60 -> 45ee628 (owner: XDG Window Late)
[LOG] [16:09:57:270] Registered signal for owner 45ee350: 45f1060 -> 45ee760 (owner: XDG Window Late)
[LOG] [16:09:57:270] Registered signal for owner 45ee350: 45f1080 -> 45ee6f8 (owner: XDG Window Late)
[LOG] [16:09:57:270] Registered signal for owner 45ee350: 45f1090 -> 45ee690 (owner: XDG Window Late)
[LOG] [16:09:57:270] Registered signal for owner 45ee350: 45f10a0 -> 45ee7c8 (owner: XDG Window Late)
[LOG] [16:09:57:271] Registered signal for owner 45ee350: 45f1070 -> 45ee5c0 (owner: XDG Window Late)
[LOG] [16:09:57:271] Registered signal for owner 45cc470: 45e9540 -> 45cc4e8 (owner: SurfaceTreeNode)
[LOG] [16:09:57:271] Registered signal for owner 45cc470: 45e9510 -> 45cc550 (owner: SurfaceTreeNode)
[LOG] [16:09:57:271] Registered signal for owner 45cc470: 45e9550 -> 45cc5b8 (owner: SurfaceTreeNode)
[LOG] [16:09:57:271] Creating a surfaceTree Root! (pWindow: 45ee350)
[LOG] [16:09:57:271] Map request dispatched, monitor eDP-1, xywh: 1408.000000 2528.000000 1692.000000 902.400000
[LOG] [16:10:00:114] Searching for matching rules for anytype (title: Untitled - Anytype)
[LOG] [16:10:00:114] Window rule size 75% 60% -> ^(anytype)$ matched 45ee350 [Untitled - Anytype]
[LOG] [16:10:00:114] Window rule float -> ^(anytype)$ matched 45ee350 [Untitled - Anytype]
[LOG] [16:10:00:114] Window rule workspace special silent -> ^(anytype)$ matched 45ee350 [Untitled - Anytype]
[LOG] [16:10:00:114] Window 45ee350 set title to Untitled - Anytype
[LOG] [16:10:00:549] Searching for matching rules for anytype (title: Task tracker - Anytype)
[LOG] [16:10:00:549] Window rule size 75% 60% -> ^(anytype)$ matched 45ee350 [Task tracker - Anytype]
[LOG] [16:10:00:549] Window rule float -> ^(anytype)$ matched 45ee350 [Task tracker - Anytype]
[LOG] [16:10:00:549] Window rule workspace special silent -> ^(anytype)$ matched 45ee350 [Task tracker - Anytype]
[LOG] [16:10:00:549] Window 45ee350 set title to Task tracker - Anytype

[1] https://anytype-release.fra1.cdn.digitaloceanspaces.com/Anytype-0.34.3.AppImage

[FEAT] Remembering size and position of scratchpad windows

Currently the size and position is always restored to some default, even if size and position are not configured explicitly. I would like to have a behavior like on i3, where I can resize and move windows on the scratchpad, hide it and show it again, where the position of the window stays like before.

Please add an additional option to keep manual geometry changes (optimally independent per monitor).

[BUG] Flatpak apps not working as others are (scratchpads)

Pyprland version
2.0 (latest)

Bug
Unable to get flatpak apps to run as scratchpads properly.
The app (in this case: Spotify) does launch but with the following errors:

  1. The command terminated normally. is it already running?
  2. Failed to show scratch "spotify"
    Also the app does not work as "Scratch", as the hide feature is not working here

Configuration

  • pyprland.toml
    [scratchpads.spotify] command="flatpak run com.spotify.Client" class= "spotify" process_tracking= "false" class_match= "true" animation= "fromRight" lazy= "true" unfocus= "hide"
  • hyprland.conf
    bind = $mainMod CTRL,s,exec,pypr toggle spotify $spotiify = ^(spotify)$ windowrule = size 75% 60%,$spotiify windowrule = move 50% -200%,$spotiify

pypr throws error

I wanted to setup some scratchpads, and i followed the guide on their github page. I had to install it from the AUR, because pip kept complaining about externally managed packages. I also tried using pipx for that matter, but it doesn't seem to work.

Traceback (most recent call last):
  File "/usr/bin/pypr", line 8, in <module>
    sys.exit(main())
             ^^^^^^
  File "/usr/lib/python3.11/site-packages/pyprland/command.py", line 171, in main
    asyncio.run(run_daemon() if len(sys.argv) <= 1 else run_client())
  File "/usr/lib/python3.11/asyncio/runners.py", line 190, in run
    return runner.run(main)
           ^^^^^^^^^^^^^^^^
  File "/usr/lib/python3.11/asyncio/runners.py", line 118, in run
    return self._loop.run_until_complete(task)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3.11/asyncio/base_events.py", line 653, in run_until_complete
    return future.result()
           ^^^^^^^^^^^^^^^
  File "/usr/lib/python3.11/site-packages/pyprland/command.py", line 162, in run_client
    _, writer = await asyncio.open_unix_connection(CONTROL)
                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3.11/asyncio/streams.py", line 98, in open_unix_connection
    transport, _ = await loop.create_unix_connection(
                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3.11/asyncio/unix_events.py", line 259, in create_unix_connection
    await self.sock_connect(sock, path)
  File "/usr/lib/python3.11/asyncio/selector_events.py", line 634, in sock_connect
    return await fut
           ^^^^^^^^^
  File "/usr/lib/python3.11/asyncio/selector_events.py", line 642, in _sock_connect
    sock.connect(address)

I get this error when I manually try to run pypr toggle term. This is also the case with hpr-scratcher. I can see that processes are spawned, but i just can't seem to access the scratchpads.
I also don't see pypr in btop after restarting. I do have the exec-once line in hyprland.conf

[Feature Request] Minimization Plugin Integration with Scratchpads

Hi,

Thank you for the fantastic project. I'd like to propose the addition of minimization features through a new plugin. Here are some of the functionalities I'm suggesting:

  1. Introduce a dock/secondary bar, similar to nwg-dock-hyprland or the awesomewm bar:

    • Enabling users to click on a window icon to toggle the visibility of the corresponding window.
  2. Provide an option to display only windows in the current workspace.

  3. Ensure compatibility with the scratchpad plugin:

    • If the scratchpad is visible, the application's icon should be present in the dock.
    • If the scratchpad is not visible, the application's icon should be removed from the dock.

I understand this is a lot to ask for, so please let me know if you think it worth implementing.

Thank you.

pypr crashes on start due to missing tomllib

Using commit 8a32727, I get the following stack trace:

Traceback (most recent call last):
  File "/nix/store/02p8hqpn1my8j1cb79z8r1c9pndjzx8w-python3.10-pyprland-1.5.1/bin/.pypr-wrapped", line 6, in <module>
    from pyprland.command import main
  File "/nix/store/02p8hqpn1my8j1cb79z8r1c9pndjzx8w-python3.10-pyprland-1.5.1/lib/python3.10/site-packages/pyprland/command.py", line 7, in <module>
    import tomllib
ModuleNotFoundError: No module named 'tomllib'

According to [1] tomllib was added in Python 3.11, while poetry and the nix flake still point to Python 3.10.

[1] https://docs.python.org/3/library/tomllib.html

Template for plugins not working

When trying to run the experimental.py module it crashes with this error:

Traceback (most recent call last):
File "/usr/lib/python3.11/site-packages/pyprland/plugins/./experimental.py", line 2, in
from .interface import Plugin
ImportError: attempted relative import with no known parent package

To reproduce go to /usr/lib/python3-3.11/site-packages/pyprland/plugins/ and run experimental.py with python3.
I suspect that I'm running it wrong but don't know how else I'm supposed to do it.

Rofi can't bring `pyprland`-managed `scratchpads` back into focus

Hello! Hope you're doing well. Sorry it's me again. I'm migrating from Sway and so new to Hyprland, apologies in advance if this is not the right place for this question.

How to reproduce

Please see the following video:

scratchpad-demo.mp4
  1. rofi -show window
  2. choose kitty_music, which is managed by pyprland's scratchpads
  3. The following happens:
    • kitty_music is not brought into focus (I expect it'll be brought into focus)
    • my current window is dimmed; I can't focus back to it and it "freezes"; it doesn't respond to any keystrokes and clicks
  4. I have to run rofi -show window and choose kitty_music again in order to unfreeze my current window

pyprland.toml:

[pyprland]
plugins = [ "scratchpads" ]

[scratchpads.kitty_top]
command = "kitty --class kitty_dropterm --execute tmux attach-session -t misc"
animation = "fromTop"
class = "kitty_dropterm"
size = "50% 45%"
margin = 40

[scratchpads.kitty_right]
command = "kitty --class kitty_music --execute ncmpcpp"
animation = "fromRight"
class = "kitty_music"
size = "20% 60%"
margin = 10

What I have tried

I know (hopefully) how to built-in scratchpad works in hyprland:

bind =    $mod,          s,        movetoworkspacesilent, special

When I press $mod, s, it'll move the current focused window to the special workspace called special.
When I run rofi -show window, and move the scratchpad back to focus.

But pyprland-managed scratchpads doesn't seem to work this way?

Any help is much appreciated. Thank you!

[BUG] layout_center: centered window to big

Pyprland version
Which version did you use?
2.0.5
Describe the bug
A clear and concise description of what the bug is.
I am using the layout_center plugin configured as mentioned in the wiki.
When activation the layout_center the Windows which should be centered is resized above the right an bottom screen boundaries.
To Reproduce
Steps to reproduce the behavior:
Activate the layout_center plugin.

Expected behavior
A centered window with a margin from the screen on each side of the window.

Configuration (provide following files/samples when relevant):

  • pyprland.toml
    [pyprland]
    plugins = [
    "scratchpads",
    "toggle_special",
    "layout_center",

"monitors",

"shift_monitors",

"workspaces_follow_focus",

"expose"
]

[workspaces_follow_focus]
max_workspaces = 9 # number of workspaces before cycling

[scratchpads.volume]
lazy = true
command = "pavucontrol"
class = "volume"
unfocus = "hide"
animation = "fromBottom"

[scratchpads.term]
lazy=true
command = "kitty --class kitty-dropterm"
class = "term"
animation = "fromTop"
unfocus = "keep"

[scratchpads.logseq]
command = "logseq"
class = "Logseq"
animation = "fromTop"
unfocus = "keep"
lazy = true

[scratchpads.stb]
animation = "fromBottom"
class = "kitty-stb"
lazy = true
command = "kitty --class kitty-stb sstb"

[scratchpads.stb-logs]
animation = "fromTop"
class = "kitty-stb-logs"
lazy = true
command = "kitty --class kitty-stb-logs stbLog"

[layout_center]

margin = 100

offset = [0, 0]

next = "movefocus r"
prev = "movefocus l"
next2 = "movefocus d"
prev2 = "movefocus u"`

  • hyprland.conf
    bind = $mainMod, M, exec, pypr layout_center toggle # toggle the layout

focus change keys

bind = $mainMod, left, exec, pypr layout_center prev
bind = $mainMod, right, exec, pypr layout_center next
bind = $mainMod, up, exec, pypr layout_center prev2
bind = $mainMod, down, exec, pypr layout_center next2
Additional context
Add any other context about the problem here.

Expose plugin will send windows to special, but will not bring them back.

Hey! Title mostly covers it- I'm using the AUR version from august first, was testing out the expose plugin. The hotkey I set will send away my windows, but won't return them from the workspace. I have the following in my config JSON:

    "pyprland": {
        "plugins": [
            "scratchpads",
            "expose"
        ]
    },
    "scratchpads": {
        "term": {
            "command": "kitty --class kitty-dropterm",
            "animation": "fromTop",
            "placements": ""
        },
        "files": {
            "command": "dolphin",
            "animation": "fromTop",
            "placements": ""
        }
    },
    "expose": {
        "include_special": true
      }
}

and the following command in hypr:
bind = $mainMod, N, exec, pypr toggle_minimized

I've also got some debug output attached for you.
pypr.log

[Feature Request] Move the scratchpad to new workspace instead of closing it

Hi, I'm using the scratchpad plugin with the unfocus set to "" (no action), so that it won't automatically close when losing focus. I'm having the following minor inconvenience.

Step to reproduce:

  1. Toggle the scratchpad on Workspace 1
  2. Switch to Workspace 2
  3. Toggling the scratchpad again

Currently, pypr will close the scratchpad because it remains open in workspace 1. I think it would be more intuitive if the scratchpad moves from workspace 1 to workspace 2.

Error when spawning new scratchpad window

Trying to add some scratchpad windows to my hyprland config (built from source on Arch), encountering the following error:

Bug detected, please report on https://github.com/fdev31/pyprland/issues
Client address is invalid
Traceback (most recent call last):
  File "/usr/lib/python3.11/site-packages/pyprland/command.py", line 75, in _callHandler
    await getattr(plugin, full_name)(*params)
  File "/usr/lib/python3.11/site-packages/pyprland/plugins/scratchpads.py", line 468, in run_toggle
    await self.run_show(uid)
  File "/usr/lib/python3.11/site-packages/pyprland/plugins/scratchpads.py", line 519, in run_show
    await item.updateClientInfo()
  File "/usr/lib/python3.11/site-packages/pyprland/plugins/scratchpads.py", line 194, in updateClientInfo
    client_info = await get_client_props(addr="0x" + self.address)
                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3.11/site-packages/pyprland/plugins/scratchpads.py", line 52, in get_client_props
    assert len(addr) > 2, "Client address is invalid"
           ^^^^^^^^^^^^^
AssertionError: Client address is invalid

The contents of my pyprland.conf:

{
  "pyprland": {
    "plugins": [
      "scratchpads",
      "lost_windows"
    ]
  },
  "scratchpads": {
    "volume": {
      "command": "pavucontrol",
      "animation": "fromRight",
      "margin": 40,
      "size": "20% 40%",
      "position": "75% 55%",
      "lazy": true
    }
  }
}

And the relevant parts of my hyprland.conf:

# Scratchpad Configuration
# Add scratchpads in pyprland.conf

bind = $mainMod,V,exec,pypr toggle volume
windowrule = float,^(pavucontrol)$
windowrule = workspace special silent,^(pavucontrol)$

EDIT: Just noticed that I do not get this printout when I run pypr toggle volume, only when I launch the window with my Hyprland binding.

scratchpads gets hidden behind in fullscreen mode

Hi, I am gratefully using scratchpads, but there's one caveat. When I toggle scratchpad on in fullscreen mode, it gets hidden behind the current window. It does show up when I turn off fullscreen mode but I want scratchpad to be visible whenever I toggle on whether I am in fullscreen mode or not. This does not happen initially right after booting, but happens after I open and close new windows. I feel like this could be Hyprland issue as I post this issue. If it is, please understand since I am a wayland newbie..

Thanks!

[BUG] Nix Flake build failed: "No module name 'hatchling' for pygments"

Pyprland version
Which version did you use?
commit cb4de47

Describe the bug
A clear and concise description of what the bug is.

On NixOS, flake installation fails on building

To Reproduce
Steps to reproduce the behavior:

  1. Build package from flake
  2. get an error

Expected behavior
installation without error

Additional context
image

Issues with programs that spawn child windows

Hi! I've stumbled across this issue while using KeePassXC, specifically when clicking on buttons that spawn child windows, such as the password generator.

With hyprctl clients:

This is the main window, which is obviously locked when a modal window is on:

Window 5d0c00f43390 -> Passwords - KeePassXC:
	mapped: 1
	hidden: 0
	at: 2112,1279
	size: 1536,864
	workspace: -93 (special:scratch_keepassxc)
	floating: 1
	monitor: 1
	class: org.keepassxc.KeePassXC
	title: Passwords - KeePassXC
	initialClass: org.keepassxc.KeePassXC
	initialTitle: Passwords.kdbx [Locked] - KeePassXC
	pid: 43896
	xwayland: 0
	pinned: 0
	fullscreen: 0
	fullscreenmode: 0
	fakefullscreen: 0
	grouped: 0
	swallowing: 0
	focusHistoryID: 3

This is the child (modal) window created:

Window 5d0c00f6ad90 -> Generate Password:
	mapped: 1
	hidden: 0
	at: 2112,2160
	size: 1536,864
	workspace: -93 (special:scratch_keepassxc)
	floating: 1
	monitor: 1
	class: org.keepassxc.KeePassXC
	title: Generate Password
	initialClass: org.keepassxc.KeePassXC
	initialTitle: Generate Password
	pid: 43896
	xwayland: 0
	pinned: 0
	fullscreen: 0
	fullscreenmode: 0
	fakefullscreen: 0
	grouped: 0
	swallowing: 0
	focusHistoryID: 7

Since both windows share the same class but not the same window address, they can be shown at the same time by pypr?

Anyways, have a nice day/night :)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.