This repository has been archived by the owner on Apr 17, 2024. It is now read-only.
/
hypr-run-or-raise
executable file
·240 lines (227 loc) · 10.7 KB
/
hypr-run-or-raise
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
#!/usr/bin/env bash
# arg1: target_class (regexp)
# other args: command
# demo:
# 根据 arg1(window target_class) 来匹配当前运行的程序中有没有匹配的窗口,
# 1. 如果有
# 1.1 若此窗口已经是聚焦的窗口,则将焦点转移到上一次聚焦的窗口上
# 1.2 若此窗口不是当前聚焦的窗口,则将焦点转移到此窗口
# 2. 如果没有,则使用 arg2 及之后的参数 以启动目录程序,并聚焦之(有可能程序是在其他 workspace 启动,故需要将焦点转移到那)
# hypr-run-or-raise emacs emacs
# hypr-run-or-raise 'firefox|firefox-esr' firefox
# hypr-run-or-raise --cd --float-only Alacritty alacritty --working-directory=$(hypr-cwd||echo $HOME)
# hypr-run-or-raise --float-only Alacritty alacritty --working-directory=$(hypr-cwd||echo $HOME)
# hypr-run-or-raise --floating 'dterm|Alacritty|kitty|org.wezfurlong.wezterm' term.sh -- --class=dterm --working-directory=$(hypr-cwd||echo $HOME)
# hypr-run-or-raise --cd --floating 'dterm|Alacritty|kitty|org.wezfurlong.wezterm' term.sh -- --class=dterm --working-directory=$(hypr-cwd||echo $HOME)
# 有个特例,参见 hypr-cwd
# 若当前窗口是 emacs ,我能从 emacs 的 title 中获取到 emacs 的 default-directory(emacs 当前编辑的文件所在的目录)
# 而我的目录窗口若是 alacritty 终端,则当我切换到 alacritty 终端时,我希望执行 cd directory 命令,切换到与 emacs 中文件所在目录 相同的目录
# 需要依赖 ydotool
#
PROG=$( basename "$0" )
float_only=""
floating=""
maximize=""
cd=""
resize=""
TEMP=$( getopt --options h --longoptions maximize,cd,floating,float-only,resize:,help -- "$@" ) || exit 1
eval set -- "$TEMP"
for i in "$@"; do
case "$i" in
-h|--help)
echo "Usage: $PROG OPTIONS target [runstring]"
echo
echo "Give focus to a program based on window class. If we can't give focus to something with that window class, then exec 'runstring'" |fmt
echo
echo "OPTIONS"
echo "-f|--float-only 只在 target_floating 窗口中寻找匹配的 target"
exit 0
;;
--cd*)
cd="set"
shift
;;
--maximize*)
maximize="set"
shift
;;
--floating*)
# 将目标窗口转成floating
floating="true"
shift
;;
--float-only*)
# 只匹配当前是floating 的
float_only="set"
shift
;;
--resize*)
resize="$2"
shift
shift
;;
esac
done
shift # remove --
# $target= app_id for wayland or target_class for x11
target=$1
# 转成小写
# target=`echo $target|tr '[:upper:]' '[:lower:]'`
# 获取除第 1 个参数外的所有参数
shift 1
cmd="$@"
#
if [ -n "$float_only" ]; then
# only match floating app
target_appinfo=`hyprctl clients -j | jq -rc '.[] | select((.class | test("'"$target"'"; "i")) and (.floating == true) )'`
else
# make the target floating
if [ "$floating" == "true" ]; then
# target_appinfo=`hyprctl clients -j | jq -rc '.[] | select((.class | test("'"$target"'"; "i")) and (.floating == true) )'`
# 优先匹配floating 的
target_appinfo=`hyprctl clients -j | jq -rc '.[] | select((.class | test("'"$target"'"; "i")) and (.floating == true) )'`
if [ -z "$target_appinfo" ]; then
target_appinfo=`hyprctl clients -j | jq -rc '.[] | select((.class |test("'"$target"'"; "i")))'`
fi
else
target_appinfo=`hyprctl clients -j | jq -rc '.[] | select((.class |test("'"$target"'"; "i")))'`
fi
fi
if [ ! "$target_appinfo" ]; then
# if app not found ,run the cmde
if echo "$cmd" | grep -q " "; then
$cmd &
else
$cmd &
fi
sleep 0.3
# 如果期望新创建的窗口是floating,则尝试将期转成floating
if [ "$floating" == "true" ]; then
if [ -n "$float_only" ]; then
target_appinfo=`hyprctl clients -j | jq -r '.[] | select((.class | test("'"$target"'"; "i")) and (.floating == true) )'`
else
target_appinfo=`hyprctl clients -j | jq -r '.[] | select((.class |test("'"$target"'"; "i")))'`
fi
target_floating=`echo $target_appinfo|jq -r '.floating'|head -n 1`
if [ "$target_floating" == "false" ]; then
# 如果目标窗口不是floating,且 有--floating 参数( 即想让目标窗口以floating的形式展示)
hyprctl dispatch togglefloating address:${target_addr}
hyprctl dispatch centerwindow
fi
fi
else
# frontappinfo=`hyprctl clients -j | jq -r '.[] |select(.focused)'`
front_app=`hyprctl activewindow -j`
# front_class=`echo $front_app|jq -r '.class'`
front_addr=`echo $front_app|jq -r '.address'`
front_floating=`echo $front_app|jq -r '.floating'`
front_fullscreen=`echo $front_app|jq -r '.fullscreen'`
front_ws_name=`echo $front_app|jq -r '.workspace.name'`
front_ws_id=`echo $front_app|jq -r '.workspace.id'`
# jq 的(.app_id // "") 表示取 app_id 若无此字段则为空串
# target_class=`echo $target_appinfo|jq -r '.class'|head -n 1`
target_addr=`echo $target_appinfo|jq -r '.address'|head -n 1`
target_floating=`echo $target_appinfo|jq -r '.floating'|head -n 1`
target_title=`echo $target_appinfo|jq -r '.title'|head -n 1`
target_ws_id=`echo $target_appinfo|jq -r '.workspace.id'`
# target_pid=`echo $target_appinfo|jq -r '.pid'`
cwd=$(hypr-cwd)
if [ "$front_addr" != "$target_addr" ]; then
# 如果当前窗口是special 的window,则先隐藏之,以免其遮挡聚焦后的窗口
if [[ "$front_ws_name" == *"special"* ]]; then
hyprctl dispatch "togglespecialworkspace"
fi
# # 如果当前窗口是floating,则将其move 到special workspace,以免其遮挡聚焦后的窗口
# if [[ "$front_floating" == "true" ]]; then
# hyprctl dispatch "movetoworkspacesilent special address:${front_addr}"
# fi
if [[ "$target_floating" == "true" || "$floating" == "true" ]]; then
# 如果当前窗口是fullscreen,则将其恢复
if [ "$front_fullscreen" == "true" ]; then
hyprctl dispatch "fullscreen"
fi
# move window to current ws
# hyprctl keyword animations:enabled 0
hyprctl dispatch "movetoworkspacesilent e+0,address:${target_addr}"
hyprctl dispatch "focuswindow address:${target_addr}"
if [[ "$floating" = "true" && "$target_floating" = "false" ]]; then
# 如果目标窗口不是floating,且 有--floating 参数( 即想让目标窗口以floating的形式展示)
hyprctl dispatch togglefloating address:${target_addr}
hyprctl dispatch centerwindow
# resize 有bug
# hyprctl dispatch resizeactive "$resize"
fi
# hyprctl keyword animations:enabled 1
if [ $maximize ]; then
hyprctl dispatch "fullscreen 1"
fi
else
# 如果当前窗口是floating,则将其move 到special workspace,以免其遮挡聚焦后的窗口
if [[ "$front_floating" == "true" && "$target_ws_id" == "$front_ws_id" ]]; then
hyprctl dispatch "movetoworkspacesilent special address:${front_addr}"
fi
hyprctl dispatch "focuswindow address:${target_addr}"
fi
if [[ "$target" == *"foot"* || "$target" == *"dterm"* ]]; then
if [[ -n "$cwd" && -n "$cd" ]]; then
# 如果 hypr-cwd 获取到当前 working directory
# 且目标 app 是 alacritty 则在 alacritty 中 执行 cd 目标目录
# root@host:/path
regex="(\/ssh:)?([a-zA-Z0-9_\-]+@)?([a-zA-Z0-9_\.\-]+):(.+)"
tmux_session=""
if [[ $target_title == TMUX:* ]]; then
# Remove the prefix "TMUX:" and then split the remaining string by ":"
# 格式: "TMUX:session:path"
target_title=${target_title#TMUX:}
tmux_session=${target_title%%:*}
# cwd=${cwd#*:}
fi
# root@host#2222:/path # host#2222:/path
# regex2="(\/ssh:)?([a-zA-Z0-9_]+@)?([a-zA-Z0-9_\.]+)#([0-9]+):(.+)"
# ;; listen_on unix:/tmp/mykitty
# ;; allow_remote_control yes
# kitty @ --to=unix:/tmp/mykitty-${target_pid} send-key ctrl+u
tmux send-keys -t $tmux_session C-u
if [[ $cwd =~ $regex ]]; then
userat=${BASH_REMATCH[2]}
host=${BASH_REMATCH[3]}
path=${BASH_REMATCH[4]}
termcwd=$(hypr-cwd)
# alacritty -e ssh -t root@bench1 'cd /tmp&& exec $SHELL'
if [[ $termcwd =~ $regex ]]; then
# wl-copy --primary " cd $path"
# kitty @ --to=unix:/tmp/mykitty-${target_pid} send-text "cd $path\n"
tmux send-keys -t $tmux_session "cd $path"
tmux send-keys -t $tmux_session Enter
else
# wl-copy --primary " ssh -t $userat$host 'cd $path && exec "'$SHELL'"'"
tmux send-keys -t $tmux_session " ssh -t $userat$host 'cd $path && exec "'$SHELL'"'"
tmux send-keys -t $tmux_session Enter
# kitty @ --to=unix:/tmp/mykitty-${target_pid} send-text " ssh -t $userat$host 'cd $path && exec "'$SHELL'"'\n"
fi
else
tmux send-keys -t $tmux_session "cd $cwd"
tmux send-keys -t $tmux_session Enter
# kitty @ --to=unix:/tmp/mykitty-${target_pid} send-text "cd $cwd\n"
# wl-copy --primary " cd $cwd"
fi
# sleep 0.1
# fcitx5-remote -s keyboard-us
# /usr/include/linux/input-event-codes.h
# keyd do C-u C-S-v enter C-l
# ydotool key 29:1 22:1 22:0 42:1 47:1 47:0 42:0 29:0 28:1 28:0 29:1 38:1 38:0 29:0
# echo key ctrl+u ctrl+shift+v ctrl+m|dotoolc
fi
fi
else
if [[ "$front_ws_name" == *"special"* ]]; then
# hide 当前special workspace
hyprctl dispatch "togglespecialworkspace"
elif [ "$target_floating" == "true" ]; then
hyprctl dispatch "movetoworkspacesilent special"
else
hypr-focus-last-win
# hyprctl dispatch "focuscurrentorlast"
fi
fi
fi