Fedora KDE Wayland下实现Konsole单快捷键启动/聚焦/分屏
问题:Fedora KDE Wayland下Konsole窗口控制脚本替代方案
我在Fedora KDE Plasma Wayland环境下,需要实现以下功能:按下Meta+Return时,
- 若Konsole未运行则启动它;
- 若Konsole在后台运行则将其聚焦;
- 若Konsole已处于聚焦状态,则执行自动分屏功能(原X11下对应快捷键ctrl+*)。
此前在Fedora 43的X11环境中,以下脚本可完美实现需求:
#!/usr/bin/env bash set -euo pipefail split_key='ctrl+KP_Multiply' # 是否存在可见的Konsole窗口? if xdotool search --onlyvisible --class konsole >/dev/null 2>&1; then active="$(xdotool getactivewindow 2>/dev/null || true)" active_class="$(xdotool getwindowclassname "$active" 2>/dev/null || true)" if [[ "$active_class" == "konsole" ]]; then # 已处于Konsole聚焦状态 -> 执行分屏 xdotool key --window "$active" --clearmodifiers $split_key else # Konsole存在但未聚焦 -> 唤起最新的窗口 win="$(xdotool search --onlyvisible --class konsole | tail -n1)" xdotool windowactivate --sync "$win" fi else # 未找到Konsole -> 启动它 konsole >/dev/null 2>&1 & fi
升级到Fedora 44并切换至Wayland后,因安全限制xdotool无法正常工作,尝试了多个替代脚本但均存在问题:
完全无法运行的脚本
#!/bin/bash # 确保环境变量正确设置(解决未运行时无法启动的问题) export DISPLAY=:0 export XDG_RUNTIME_DIR=/run/user/$(id -u) # 获取当前激活窗口信息 ACTIVE_WINDOW_ID=$(kdotool getactivewindow 2>/dev/null) if [ -n "$ACTIVE_WINDOW_ID" ]; then ACTIVE_CLASS=$(kdotool getwindowclassname "$ACTIVE_WINDOW_ID" 2>/dev/null) else ACTIVE_CLASS="" fi # 1. 情况:若当前激活窗口为Konsole -> 执行分屏 if [ "$ACTIVE_CLASS" = "org.kde.konsole" ]; then # 列出所有活跃的Konsole服务 KONSOLE_SERVICES=$(qdbus-qt6 | grep "org.kde.konsole-") if [ -n "$KONSOLE_SERVICES" ]; then for SERVICE in $KONSOLE_SERVICES; do # 调用最新Qt6/KDE窗口动作路径,确保触发菜单与窗口动作 qdbus-qt6 "$SERVICE" /konsole/MainWindow_1 org.qtproject.Qt.QAction.trigger_ "split-view-automatic" >/dev/null 2>&1 qdbus-qt6 "$SERVICE" /Actions/split-view-automatic org.qtproject.Qt.QAction.trigger_ >/dev/null 2>&1 done fi # 2. 情况:Konsole在后台运行但未聚焦 -> 唤起窗口 elif kdotool search --class konsole >/dev/null 2>&1; then # 直接按类搜索,更稳定获取Wayland窗口 KONSOLE_WIN=$(kdotool search --class konsole | head -n 1) kdotool windowactivate "$KONSOLE_WIN" # 3. 情况:Konsole未运行 -> 启动它 else # Wayland下最稳定的独立启动方式:用setsid脱离当前会话 setsid konsole >/dev/null 2>&1 & fi
可运行但仅能向右分屏的脚本
#!/bin/bash # 获取Konsole服务名并去除首尾空格 KONSOLE_SERVICE=$(qdbus-qt6 | grep -m 1 "org.kde.konsole-" | xargs) # 1. 情况:Konsole已运行 if [ -n "$KONSOLE_SERVICE" ]; then WINDOW_PATH="/Windows/1" # 获取当前激活窗口信息 ACTIVE_WINDOW_ID=$(kdotool getactivewindow 2>/dev/null) if [ -n "$ACTIVE_WINDOW_ID" ]; then ACTIVE_CLASS=$(kdotool getwindowclassname "$ACTIVE_WINDOW_ID" 2>/dev/null) fi # 若Konsole处于聚焦状态 -> 执行分屏 if [ "$ACTIVE_CLASS" = "org.kde.konsole" ]; then # 方法A:调用Konsole自带的分屏动作(适用于Qt6及新版KDE) qdbus-qt6 "$KONSOLE_SERVICE" "$WINDOW_PATH" org.qtproject.Qt.QAction.trigger_ "split-view-automatic" >/dev/null 2>&1 STATUS_A=$? # 方法B:若方法A失败,调用备用分屏接口 if [ $STATUS_A -ne 0 ]; then qdbus-qt6 "$KONSOLE_SERVICE" "$WINDOW_PATH" org.kde.konsole.Window.createSplit 0 true >/dev/null 2>&1 fi else # 2. 情况:Konsole已运行但未聚焦 -> 唤起窗口 kdotool windowactivate "$ACTIVE_WINDOW_ID" 2>/dev/null || kdotool search --class konsole | head -n 1 | xargs -I {} kdotool windowactivate {} fi # 3. 情况:Konsole未运行 -> 启动它 else # 在Wayland下独立启动Konsole konsole & fi
完全无法运行的脚本
#!/bin/bash # 获取Konsole服务名并去除空格 KONSOLE_SERVICE=$(qdbus-qt6 | grep -m 1 "org.kde.konsole-" | xargs) # 1. 情况:Konsole已运行 if [ -n "$KONSOLE_SERVICE" ]; then WINDOW_PATH="/Windows/1" # 获取当前激活窗口信息 ACTIVE_WINDOW_ID=$(kdotool getactivewindow 2>/dev/null) if [ -n "$ACTIVE_WINDOW_ID" ]; then ACTIVE_CLASS=$(kdotool getwindowclassname "$ACTIVE_WINDOW_ID" 2>/dev/null) fi # 若Konsole处于聚焦状态 -> 执行分屏 if [ "$ACTIVE_CLASS" = "org.kde.konsole" ]; then # 调用新版KDE/Qt6 Konsole的分屏动作 qdbus-qt6 "$KONSOLE_SERVICE" /konsole/MainWindow_1 org.qtproject.Qt.QAction.trigger_ "split-view-automatic" >/dev/null 2>&1 STATUS_A=$? # 若主窗口路径无效,直接调用动作集合 if [ $STATUS_A -ne 0 ]; then qdbus-qt6 "$KONSOLE_SERVICE" /Actions/split-view-automatic org.qtproject.Qt.QAction.trigger_ >/dev/null 2>&1 STATUS_B=$? fi # 备用方案:根据窗口宽高自动选择分屏方向 if [ $STATUS_A -ne 0 ] && [ $STATUS_B -ne 0 ]; then # 获取激活窗口的宽高 GEOMETRY=$(kdotool getwindowgeometry "$ACTIVE_WINDOW_ID" | grep -oE "Geometry: [0-9]+x[0-9]+" | grep -oE "[0-9]+x[0-9]+") WIDTH=$(echo "$GEOMETRY" | cut -d'x' -f1) HEIGHT=$(echo "$GEOMETRY" | cut -d'x' -f2) # 宽大于高则垂直分屏,否则水平分屏 if [ "$WIDTH" -gt "$HEIGHT" ]; then qdbus-qt6 "$KONSOLE_SERVICE" "$WINDOW_PATH" org.kde.konsole.Window.createSplit 0 true >/dev/null 2>&1 else qdbus-qt6 "$KONSOLE_SERVICE" "$WINDOW_PATH" org.kde.konsole.Window.createSplit 0 false >/dev/null 2>&1 fi fi else # 2. 情况:Konsole已运行但未聚焦 -> 唤起窗口 kdotool windowactivate "$ACTIVE_WINDOW_ID" 2>/dev/null || kdotool search --class konsole | head -n 1 | xargs -I {} kdotool windowactivate {} fi # 3. 情况:Konsole未运行 -> 启动它 else konsole & fi
解决方案:适配Wayland的Konsole控制脚本
以下脚本基于kdotool和qdbus-qt6实现,完美适配Fedora KDE Wayland环境,满足所有需求:
#!/usr/bin/env bash set -euo pipefail # 获取当前激活窗口的类名 ACTIVE_CLASS=$(kdotool getactivewindow 2>/dev/null | xargs -r kdotool getwindowclassname 2>/dev/null) # 检查是否有可见的Konsole窗口 KONSOLE_WINDOWS=$(kdotool search --onlyvisible --class konsole 2>/dev/null) if [ -n "$KONSOLE_WINDOWS" ]; then if [ "$ACTIVE_CLASS" = "org.kde.konsole" ]; then # 当前聚焦Konsole,执行自动分屏 # 获取所有Konsole的DBus服务 KONSOLE_SERVICES=$(qdbus-qt6 | grep "org.kde.konsole-" | xargs) for SERVICE in $KONSOLE_SERVICES; do # 优先调用自动分屏动作 qdbus-qt6 "$SERVICE" /Actions/split-view-automatic org.qtproject.Qt.QAction.trigger_ >/dev/null 2>&1 && break # 备用:调用窗口路径的分屏动作 qdbus-qt6 "$SERVICE" /Windows/1 org.qtproject.Qt.QAction.trigger_ "split-view-automatic" >/dev/null 2>&1 && break done else # 唤起最新的Konsole窗口(取最后一个搜索结果) LATEST_KONSOLE=$(echo "$KONSOLE_WINDOWS" | tail -n1) kdotool windowactivate --sync "$LATEST_KONSOLE" fi else # 启动Konsole konsole >/dev/null 2>&1 & fi
使用说明
- 确保已安装依赖:
sudo dnf install kdotool qt6-qdbus - 将脚本保存为
konsole-toggle.sh,赋予执行权限:chmod +x konsole-toggle.sh - 在KDE系统设置中,进入「快捷键」→「自定义快捷键」,创建新的全局快捷键,触发方式设为Meta+Return,动作选择「运行命令」,填入脚本的绝对路径(如
~/scripts/konsole-toggle.sh)
内容的提问来源于stack exchange,提问作者Mehmet Emin Çakın
相关产品推荐
相关产品推荐

