Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

protocols: allow xdg share pickers to reconcile with hyprctl #8939

Open
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

Aetherall
Copy link

Describe your PR, what does it fix/add?

Recently, xdph got the possiblity to use your own share picker.

For the sharing output to follow the window when it moves or is resized, it is needed to return the handle id back.

Tools like slurp are really nice ui wise, but they dont know about those handles, and they are not accessible from hyprctl.

To be able to reconcile the XDPH_WINDOW_SHARING_LIST env variable provided to the picker with the informations from hyprctl, we need to provide it somehow.

I know nothing about wayland, wlr, xdg, foreign top level stuff, and dont know how to code in c++. I still wanted to see if I could make something nice to use as I share my desktop all the time for work.

It seems like we have to comply with the protocol defined here:
https://wayland.app/protocols/wlr-foreign-toplevel-management-unstable-v1#zwlr_foreign_toplevel_handle_v1:event:app_id
but I dont understand why neither...

Anyway, this PR uses the title to propagate the window address to the portal that will in turn propagate it to the picker, allowing for the nice window selection.

Is it ready for merging, or does it need work?

I dont really aim to merge this, i was planning on maintaining a patch (its like 10 lines total of code that has not really moved a lot), but if there is a way to achieve the same with a clean approach, I can dedicate some time to it.

@Aetherall Aetherall force-pushed the xdg-portal-window-address-forwarding branch 3 times, most recently from e93db52 to 08d5340 Compare January 3, 2025 17:06
@Aetherall Aetherall force-pushed the xdg-portal-window-address-forwarding branch from 08d5340 to d4c5be7 Compare January 3, 2025 18:37
@Aetherall
Copy link
Author

For context, here is my picker script:

#!/usr/bin/env sh
# share-quickpick.sh

# xdph will run this with the list of windows as an environment variable
# XDPH_WINDOW_SHARING_LIST="00000001[HC>]1[HT>]0x00000001 1[HE>]00000002[HC>]2[HT>]0x00000002 2[HE>]"
# echo $XDPH_WINDOW_SHARING_LIST > /tmp/xdph-share-picker.log

# parse window list to extract "handle address" mapping
# the handle is what wayland lets foreign clients use to refer to windows
# the address is what hyprctl uses to refer to windows
MAPPING=$(echo "$XDPH_WINDOW_SHARING_LIST" | sed -E 's/\[HE>\]/\n/g' | cut -d' ' -f1 | sed -E 's/\[.+\]/-/g')

# following block retrieved from https://github.com/hyprwm/contrib/blob/main/grimblast/grimblast
FULLSCREEN_WORKSPACES="$(hyprctl workspaces -j | jq -r 'map(select(.hasfullscreen) | .id)')"
WORKSPACES="$(hyprctl monitors -j | jq -r '[(foreach .[] as $monitor (0; if $monitor.specialWorkspace.name == "" then $monitor.activeWorkspace else $monitor.specialWorkspace end)).id]')"
WINDOWS="$(hyprctl clients -j | jq -r --argjson workspaces "$WORKSPACES" --argjson fullscreenWorkspaces "$FULLSCREEN_WORKSPACES" 'map((select(([.workspace.id] | inside($workspaces)) and ([.workspace.id] | inside($fullscreenWorkspaces) | not) or .fullscreen > 0)))')"

# parse windows to extract "address" and "geometry" mapping
WINS=$(echo "$WINDOWS" | jq -r '.[] | "\(.at[0]),\(.at[1]) \(.size[0])x\(.size[1]) [SELECTION]r/window:\(.address)"')

# replace addresses with handles so xdph can use them
for mapping in ${MAPPING//\\n/ }; do
  handle=$(echo $mapping | cut -d'-' -f1)
  address=$(echo $mapping | cut -d'-' -f2)
  WINS=$(echo "$WINS" | sed -E "s/$address/$handle/g")
done

# get monitor geometries, swap width and height for vertical monitors
MONS_H="$(hyprctl monitors -j | jq -r '.[] | select(.transform == 0 or .transform == 2) | "\(.x),\(.y) \(.width)x\(.height) [SELECTION]r/screen:\(.name)"')"
MONS_V="$(hyprctl monitors -j | jq -r '.[] | select(.transform == 1 or .transform == 3) | "\(.x),\(.y) \(.height)x\(.width) [SELECTION]r/screen:\(.name)"')"

# run slurp to get the selection
GEOM=$(echo -e "$MONS_V\n$MONS_H\n$WINS" | slurp -f '%l')

# echo the selection so xdph can use it
echo $GEOM

# Example output:
#[SELECTION]r/screen:DP-1
#[SELECTION]r/region:DP-1@991,476,282,185 # not supported yet
#[SELECTION]r/window:101765664

@vaxerski
Copy link
Member

vaxerski commented Jan 3, 2025

wait, is your goal to be able to get window geometries from the picker data?

@Aetherall
Copy link
Author

Exactly, maybe I can retrieve the info from xdph directly ?

@vaxerski
Copy link
Member

vaxerski commented Jan 4, 2025

I don't think you can do this, really... Your best bet is to match titles and classes from hyprctl clients and the sharing data.

Share data was never designed to carry such information

@Aetherall
Copy link
Author

That's what I tried first, but in my specific workflow it is too frequent to have multiple windows with the same info
I took a look at the plugin system, but i am not sure if I can use it for this intent

i'll just maintain the patch for the time being, thanks for your input !

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants