hyprland-community / pyprland

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

Issues with programs that spawn child windows #44

Closed fybx closed 7 months ago

fybx commented 7 months ago

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 :)

fdev31 commented 7 months ago

Should I understand that the first window is managed as expected, but the popups it triggers aren't ? This is indeed not supported and makes little sense: a scratchpad is one window, any "position", "size" etc applied to more than one window would just be inconsistent.

In theory one could just add support for multiple client windows but:

  1. it would force to always listen to every window creation & deletion to understand the lifecycle of each
  2. it would require some fuzzy rules to try to make the difference between the different windows, find a way to express it in the config, etc...

I don't see how that could work, if you know please enlight me :)

Regardless, I think I see your use case and use a very similar one for some VPN app. Check toggle_minimized in the expose plugin: https://github.com/hyprland-community/pyprland/wiki/Plugins#commands - the name can be a bit confusing, it's more generic than this...

Edit: and have a nice day ;)

fdev31 commented 7 months ago

I just released a new version : 1.8.0

I believe a special workspace can do the job, if you need to quickly move windows between the special workspace and the normal active one, in two directions, have a look at https://github.com/hyprland-community/pyprland/wiki/toggle_special (same as I recommended before, but now it has its own plugin and has been renamed for clarity).

Closing the issue since I don't think scratchpads is meant to cover those use cases. If you have a proposition or a clear feature request feel free to re-open or create a new issue.

punk-dev-robot commented 5 months ago

It also causes other issues, for example:

  1. I have slack as pyprland scratchpad - works great for single window
  2. My coworker starts a huddle with me and shares the screen, I pop-up the video window to be able to see it
  3. The popped window is now inaccessible because it is in a scratch:slack special workspace
  4. Toggle only toggles my main slack window (which is OK and I can agree it is expected behaviour)

But even when I got to my special workspace and I moved it to my normal workspace next time pyprland toggles slack it moves both windows to scratch:slack and I'm back at step 1.

I think matching windows would need to be matched by any attribute, similar to hyprland rules (in this case I could use initialTitle .

Example hyprctl output:

Window 559f59faa260 -> person1, person2 (DM) -  Slack [Main] 🏠:
    mapped: 1
    hidden: 0
    at: 1600,1440
    size: 1920,1296
    workspace: -35 (special:scratch_slack)
    floating: 1
    monitor: 1
    class: Slack
    title: person, person2 (DM) - Trint - Slack [Main] 🏠
    initialClass: Slack
    initialTitle: Slack
    pid: 8758
    xwayland: 0
    pinned: 0
    fullscreen: 0
    fullscreenmode: 0
    fakefullscreen: 0
    grouped: 0
    swallowing: 0
    focusHistoryID: 3

Window 559f5bafb380 -> Huddle: person1, person2  - Slack 🎤:
    mapped: 1
    hidden: 0
    at: 1696,116
    size: 2488,1265
    workspace: -35 (special:scratch_slack)
    floating: 1
    monitor: 1
    class: Slack
    title: Huddle: person1, person2 - Slack 🎤
    initialClass: Slack
    initialTitle: Huddle
    pid: 8758
    xwayland: 0
    pinned: 0
    fullscreen: 0
    fullscreenmode: 0
    fakefullscreen: 0
    grouped: 0
    swallowing: 0
    focusHistoryID: 2
fdev31 commented 5 months ago

So to be sure, in your scenario, you want the original window to be the scratchpad but sub-windows to not have a special threatment ? And that could work by, for instance, refactoring the class_match into something like: match_by="class" which would reuse the class attribute... and for your case match_by="initialTitle" ?

You would provide initialTitle="Slack" directly in the properties of the scratch ? or match_value="Slack" to avoid name clash between the scratchpad's configuration items & the client's attributes...

punk-dev-robot commented 5 months ago

Hi, thank you for a quick response! I think that would work, or if possible something similar to hyprland windowrule where it's possible to match by any field(s) with regex, as that could probably cover more use-cases in the future

fdev31 commented 5 months ago

Hi, thank you for a quick response! I think that would work, or if possible something similar to hyprland windowrule where it's possible to match by any field(s) with regex, as that could probably cover more use-cases in the future

If I push some experimental version later, are you able to test it without having a proper release (use the latest git version)?

punk-dev-robot commented 5 months ago

Yes I should be able to to test it tomorrow. Thank you!

punk-dev-robot commented 5 months ago

Not sure what update did it (might by hyprland) but the behaviour changed for the better.

Now pyprland toggle toggles only the main slack window, which is great. The only issue is that it still opens in the scratchpad at the beginning so it's hard to access it, but after I move it manually to regular workspace all works as expected. Can we prevent opening newly spawned windows in the scratchpad?

fdev31 commented 5 months ago

Not sure what update did it (might by hyprland) but the behaviour changed for the better.

Now pyprland toggle toggles only the main slack window, which is great. The only issue is that it still opens in the scratchpad at the beginning so it's hard to access it, but after I move it manually to regular workspace all works as expected. Can we prevent opening newly spawned windows in the scratchpad?

In theory only one is added... so it must be a rule in your hyprland.conf ? It works as follows: when launching an app, the PID is kept, then it waits for a window using this PID and associates it to the scratchpad. A single window per scratchpad is supported at the moment...

Actually you made me think about implementing some kind of group of windows and matching multiple clients, but today it's not possible so I'm surprised this is happening for you.

punk-dev-robot commented 5 months ago

The new window has the same PID as the original one (in slack - see below). I don't have any window rules for slack, it must by from pyprland

Window 564ba188d5f0 -> Huddle: Anna, Jinn  - Slack:                                                                                                                                                                                                                                                                                                                                                                                                                       
        mapped: 1                                                                                                                                                                                                                                                                                                                                                                                                                                                                
        hidden: 0                                                                                                                                                                                                                                                                                                                                                                                                                                                                
        at: 3972,739                                                                                                                                                                                                                                                                                                                                                                                                                                                             
        size: 1142,695                                                                                                                                                                                                                                                                                                                                                                                                                                                           
        workspace: 2 (2)                                                                                                                                                                                                                                                                                                                                                                                                                                                         
        floating: 0                                                                                                                                                                                                                                                                                                                                                                                                                                                              
        monitor: 1                                                                                                                                                                                                                                                                                                                                                                                                                                                               
        class: Slack                                                                                                                                                                                                                                                                                                                                                                                                                                                             
        title: Huddle: Anna, Jinn - Trint - Slack                                                                                                                                                                                                                                                                                                                                                                                                                                
        initialClass: Slack                                                                                                                                                                                                                                                                                                                                                                                                                                                      
        initialTitle: Huddle                                                                                                                                                                                                                                                                                                                                                                                                                                                     
        pid: 9669                                                                                                                                                                                                                                                                                                                                                                                                                                                                
        xwayland: 0                                                                                                                                                                                                                                                                                                                                                                                                                                                              
        pinned: 0                                                                                                                                                                                                                                                                                                                                                                                                                                                                
        fullscreen: 0                                                                                                                                                                                                                                                                                                                                                                                                                                                            
        fullscreenmode: 0                                                                                                                                                                                                                                                                                                                                                                                                                                                        
        fakefullscreen: 0                                                                                                                                                                                                                                                                                                                                                                                                                                                        
        grouped: 0                                                                                                                                                                                                                                                                                                                                                                                                                                                               
        swallowing: 0                                                                                                                                                                                                                                                                                                                                                                                                                                                            
        focusHistoryID: 2                                                                                                                                                                                                                                                                                                                                                                                                                                                        

Window 564ba17da140 -> product-feedback (Channel) - 1 new item - Slack [Main] 🏠:                                                                                                                                                                                                                                                                                                                                                                                        
        mapped: 1                                                                                                                                                                                                                                                                                                                                                                                                                                                                
        hidden: 0                                                                                                                                                                                                                                                                                                                                                                                                                                                                
        at: 1600,1440                                                                                                                                                                                                                                                                                                                                                                                                                                                            
        size: 1920,1296                                                                                                                                                                                                                                                                                                                                                                                                                                                          
        workspace: -45 (special:scratch_slack)                                                                                                                                                                                                                                                                                                                                                                                                                                   
        floating: 1                                                                                                                                                                                                                                                                                                                                                                                                                                                              
        monitor: 1                                                                                                                                                                                                                                                                                                                                                                                                                                                               
        class: Slack                                                                                                                                                                                                                                                                                                                                                                                                                                                             
        title: product-feedback (Channel) - 1 new item - Slack [Main] 🏠                                                                                                                                                                                                                                                                                                                                                                                                 
        initialClass: Slack                                                                                                                                                                                                                                                                                                                                                                                                                                                      
        initialTitle: Slack                                                                                                                                                                                                                                                                                                                                                                                                                                                      
        pid: 9669                                                                                                                                                                                                                                                                                                                                                                                                                                                                
        xwayland: 0                                                                                                                                                                                                                                                                                                                                                                                                                                                              
        pinned: 0                                                                                                                                                                                                                                                                                                                                                                                                                                                                
        fullscreen: 0                                                                                                                                                                                                                                                                                                                                                                                                                                                            
        fullscreenmode: 0                                                                                                                                                                                                                                                                                                                                                                                                                                                        
        fakefullscreen: 0                                                                                                                                                                                                                                                                                                                                                                                                                                                        
        grouped: 0                                                                                                                                                                                                                                                                                                                                                                                                                                                               
        swallowing: 0                                                                                                                                                                                                                                                                                                                                                                                                                                                            
        focusHistoryID: 5

In the above: main slack window (564ba17da140) is started by pyprland and it is being toggles. When I joined the huddle window 564ba188d5f0 got created in the special:scratch_slack workspace.

This window is hard to access to me because `pyprland' only toggles the main window. I managed to move that window to regular workspace with some script and now it works as expected

fdev31 commented 5 months ago

In theory only the first created one will be the scratchpad... it should be visible in pyprland's log file... (passed via --debug)

punk-dev-robot commented 5 months ago

sorry just edited above with some extra info

fdev31 commented 5 months ago

Note that now you can match by initialTitle if you like...

fybx commented 5 months ago

didn't expect this to be relevant to others 😄 maybe a wiki entry or a guide on this matter would be helpful for future references. i'll try to add if i find the time!

fdev31 commented 5 months ago

There is a chance Hyprland assigns the child window to the special workspace... I can maybe add a feature / option so that every window on the scratchpad will be moving with the "main" scratchpad, needs to be tested, I'm not sure it can easily work without adding a lot of logic.