XFCE4环境下外接显示器热拔插时窗口自动缩放问题的Compiz解决方案


阅读 7 次

问题场景描述

在双屏开发环境中,当外接显示器突然断开时,原本在大屏上的窗口会保持原有尺寸,导致在笔记本小屏上显示不全。这个问题在使用Compiz窗口管理器配合XFCE4桌面环境时尤为明显。

核心解决思路

我们需要通过脚本监听显示器变化事件,并在检测到显示器断开时自动调整所有窗口尺寸。这里给出一个基于xdotool和xrandr的完整解决方案:


#!/bin/bash
# 监听显示器状态变化
xrandr --query | grep " connected" | while read line; do
    output=$(echo $line | awk '{print $1}')
    status=$(echo $line | awk '{print $2}')
    
    if [ "$status" == "disconnected" ]; then
        # 获取当前活动窗口列表
        windows=$(xdotool search --onlyvisible --class .)
        
        # 获取主显示器分辨率
        resolution=$(xrandr | grep -oP 'primary \K\d+x\d+')
        width=$(echo $resolution | cut -d'x' -f1)
        height=$(echo $resolution | cut -d'x' -f2)
        
        # 调整所有窗口尺寸
        for window in $windows; do
            xdotool windowsize $window $(($width-50)) $(($height-100))
            xdotool windowmove $window 25 50
        done
    fi
done

与XFCE4深度集成

为了使脚本自动运行,我们需要将其添加到XFCE4的会话启动项中:

  1. 打开XFCE4设置管理器
  2. 进入"会话和启动"设置
  3. 在"应用程序自启动"标签页中添加我们的脚本

针对Compiz的特殊处理

由于使用了Compiz窗口管理器,我们还需要确保窗口管理策略不会干扰我们的自动调整:


gconftool-2 --set /apps/compiz/plugins/place/screen0/options/mode --type int 0
gconftool-2 --set /apps/compiz/plugins/place/screen0/options/position_force --type bool false

实际效果优化

为了更平滑的过渡效果,可以添加动画延迟:


for window in $windows; do
    xdotool windowsize --usehints $window 80% 80%
    sleep 0.1
    xdotool windowsize --usehints $window 90% 90%
    sleep 0.1
    xdotool windowsize --usehints $window 100% 100%
done

异常处理机制

添加错误处理确保脚本稳定性:


adjust_windows() {
    try_count=0
    while [ $try_count -lt 3 ]; do
        if xdotool windowsize $1 $2 $3; then
            break
        fi
        try_count=$((try_count+1))
        sleep 1
    done
}