hyprwm / Hyprland

Hyprland is a highly customizable dynamic tiling Wayland compositor that doesn't sacrifice on its looks.
https://hyprland.org
BSD 3-Clause "New" or "Revised" License
17.88k stars 752 forks source link

`pid` selector for window rules (V2) #6653

Closed leon-erd closed 4 days ago

leon-erd commented 4 days ago

Description

Being able to target a specific window with a window rule using its pid would be really nice. Currently, dynamic window rules are broken with the exec dispatcher because the dispatcher sets them only once, and as per the wiki: "dynamic window rules are re-evaluated every time a property changes" (for example changing the focus of the spawned window) which discards the rule set by the dispatcher (see https://github.com/hyprwm/Hyprland/issues/6593). Under the hood, the exec dispatcher could set the dynamic window rules for the created window with the proposed pid selector which would fix this issue. The pid selector would also fix https://github.com/hyprwm/Hyprland/issues/4648

MightyPlaza commented 4 days ago

use hyprctl setprop

leon-erd commented 4 days ago

Ah I just found out that setprop supports pid But its not mentioned anywhere. On the hyprland wiki it only says in the example

hyprctl setprop address:0x13371337 forcenoanims 1 lock  # with locking
hyprctl setprop address:0x13371337 nomaxsize 0          # without locking

and hyprctl only gives this information

➜  ~ hyprctl setprop --help
usage: hyprctl [flags] setprop <regex> <property> <value> [lock]

regex:
    Regular expression by which a window will be searched
...

Do you know what selection options are available? Then I will add this to the wiki

MightyPlaza commented 4 days ago

that's not a pid, it's the window address (aka the hex value at the start of hyprctl clients after 0x)

see the getWindowByRegex in src/Compositor.cpp for all the options

PHLWINDOW CCompositor::getWindowByRegex(const std::string& regexp) {
    if (regexp.starts_with("active"))
        return m_pLastWindow.lock();

    eFocusWindowMode mode = MODE_CLASS_REGEX;

    std::regex       regexCheck(regexp);
    std::string      matchCheck;
    if (regexp.starts_with("class:")) {
        regexCheck = std::regex(regexp.substr(6));
    } else if (regexp.starts_with("initialclass:")) {
        mode       = MODE_INITIAL_CLASS_REGEX;
        regexCheck = std::regex(regexp.substr(13));
    } else if (regexp.starts_with("title:")) {
        mode       = MODE_TITLE_REGEX;
        regexCheck = std::regex(regexp.substr(6));
    } else if (regexp.starts_with("initialtitle:")) {
        mode       = MODE_INITIAL_TITLE_REGEX;
        regexCheck = std::regex(regexp.substr(13));
    } else if (regexp.starts_with("address:")) {
        mode       = MODE_ADDRESS;
        matchCheck = regexp.substr(8);
    } else if (regexp.starts_with("pid:")) {
        mode       = MODE_PID;
        matchCheck = regexp.substr(4);
    } else if (regexp.starts_with("floating") || regexp.starts_with("tiled")) {
        // first floating on the current ws
        if (!valid(m_pLastWindow))
            return nullptr;

        const bool FLOAT = regexp.starts_with("floating");

        for (auto& w : m_vWindows) {
            if (!w->m_bIsMapped || w->m_bIsFloating != FLOAT || w->m_pWorkspace != m_pLastWindow->m_pWorkspace || w->isHidden())
                continue;

            return w;
        }

        return nullptr;
    }
leon-erd commented 4 days ago

that's not a pid, it's the window address (aka the hex value at the start of hyprctl clients after 0x)

Yeah I know. I just found out that hyprctl setprop pid:<...> ... works. Thanks! The snippet helps. Will make a MR for the wiki :)