You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

使用说明

  1. 确保已安装依赖:sudo dnf install kdotool qt6-qdbus
  2. 将脚本保存为konsole-toggle.sh,赋予执行权限:chmod +x konsole-toggle.sh
  3. 在KDE系统设置中,进入「快捷键」→「自定义快捷键」,创建新的全局快捷键,触发方式设为Meta+Return,动作选择「运行命令」,填入脚本的绝对路径(如~/scripts/konsole-toggle.sh)

内容的提问来源于stack exchange,提问作者Mehmet Emin Çakın

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.04 11:18:09