summaryrefslogtreecommitdiff
path: root/scripts/toggle_laptop_monitor.sh
blob: a84e4d8ecbe11c1e0608a206dbfaa773ba37a1f4 (plain) (blame)
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
#!/bin/bash
# ~/.config/hypr/scripts/toggle_laptop_screen.sh

LAPTOP="eDP-1"
CONFIG_DIR="$HOME/.config/hypr"
CACHE_FILE="$CONFIG_DIR/monitor_preferred"

# 确保配置目录存在
mkdir -p "$CONFIG_DIR"

# 从缓存获取最佳模式
get_cached_best_mode() {
    local monitor="$1"
    if [ -f "$CACHE_FILE" ]; then
        grep "^$monitor=" "$CACHE_FILE" | cut -d= -f2-
    fi
}

# 保存最佳模式到缓存
save_cached_best_mode() {
    local monitor="$1"
    local mode="$2"
    
    if [ -f "$CACHE_FILE" ]; then
        # 删除旧的缓存
        grep -v "^$monitor=" "$CACHE_FILE" > "$CACHE_FILE.tmp" 2>/dev/null || true
        mv "$CACHE_FILE.tmp" "$CACHE_FILE" 2>/dev/null || touch "$CACHE_FILE"
    else
        touch "$CACHE_FILE"
    fi
    
    # 保存新的缓存
    echo "$monitor=$mode" >> "$CACHE_FILE"
}

# 检测外接显示器并选择最佳模式
detect_external_best_mode() {
    # 获取所有非笔记本显示器
    EXTERNAL_MONITORS=$(hyprctl monitors | grep "Monitor" | grep -v "$LAPTOP")
    
    if [ -z "$EXTERNAL_MONITORS" ]; then
        echo ""
        return
    fi
    
    # 取第一个外接显示器
    EXTERNAL_NAME=$(echo "$EXTERNAL_MONITORS" | head -1 | awk '{print $2}' | tr -d '()')
    
    # 首先尝试从缓存获取
    CACHED_MODE=$(get_cached_best_mode "$EXTERNAL_NAME")
    if [ -n "$CACHED_MODE" ] && [ "$CACHED_MODE" != "preferred" ]; then
        echo "$EXTERNAL_NAME,$CACHED_MODE"
        return
    fi
    
    # 获取该显示器支持的所有模式
    MODES=$(hyprctl monitors --list | grep -A 50 "$EXTERNAL_NAME" | tail -n +2 | grep -E "^[[:space:]]*[0-9]+x[0-9]+@[0-9]+")
    
    if [ -z "$MODES" ]; then
        echo "$EXTERNAL_NAME"
        save_cached_best_mode "$EXTERNAL_NAME" "preferred"
        return
    fi
    
    # 解析并选择最佳模式
    BEST_MODE=""
    BEST_AREA=0
    BEST_REFRESH=0
    
    while IFS= read -r MODE; do
        # 清理空格
        MODE=$(echo "$MODE" | xargs)
        
        # 解析分辨率宽高和刷新率
        if [[ "$MODE" =~ ([0-9]+)x([0-9]+)@([0-9]+) ]]; then
            WIDTH="${BASH_REMATCH[1]}"
            HEIGHT="${BASH_REMATCH[2]}"
            REFRESH="${BASH_REMATCH[3]}"
            
            # 比较逻辑:先比面积,再比刷新率
            AREA=$((WIDTH * HEIGHT))
            
            if [ "$AREA" -gt "$BEST_AREA" ]; then
                # 更大的分辨率
                BEST_AREA="$AREA"
                BEST_REFRESH="$REFRESH"
                BEST_MODE="$MODE"
            elif [ "$AREA" -eq "$BEST_AREA" ] && [ "$REFRESH" -gt "$BEST_REFRESH" ]; then
                # 相同分辨率,更高刷新率
                BEST_REFRESH="$REFRESH"
                BEST_MODE="$MODE"
            fi
        fi
    done <<< "$MODES"
    
    # 保存到缓存
    if [ -n "$BEST_MODE" ]; then
        save_cached_best_mode "$EXTERNAL_NAME" "$BEST_MODE"
        echo "$EXTERNAL_NAME,$BEST_MODE"
    else
        save_cached_best_mode "$EXTERNAL_NAME" "preferred"
        echo "$EXTERNAL_NAME"
    fi
}

# 检查笔记本是否启用
is_enabled() {
    hyprctl monitors | grep -q "$LAPTOP" && ! hyprctl monitors | grep "$LAPTOP" | grep -q "disabled"
}

# 检查是否安全
safe_to_disable() {
    ENABLED_COUNT=$(hyprctl monitors | grep "Monitor" | grep -c "disabled")
    TOTAL_COUNT=$(hyprctl monitors | grep -c "Monitor")
    [ "$ENABLED_COUNT" -eq 0 ] && [ "$TOTAL_COUNT" -gt 1 ]
}

# 主逻辑
EXTERNAL_INFO=$(detect_external_best_mode)

if is_enabled; then
    if safe_to_disable; then
        if [ -n "$EXTERNAL_INFO" ]; then
            # 解析外接显示器信息
            IFS=',' read -r EXTERNAL_NAME EXTERNAL_MODE <<< "$EXTERNAL_INFO"
            
            if [ -n "$EXTERNAL_MODE" ]; then
                hyprctl keyword monitor "$EXTERNAL_NAME, $EXTERNAL_MODE, 0x0, 1"
            else
                hyprctl keyword monitor "$EXTERNAL_NAME, preferred, 0x0, 1"
            fi
        fi
        
        hyprctl keyword monitor "$LAPTOP, disable"
        notify-send "显示器" "笔记本屏幕已禁用"
    else
        notify-send -u critical "错误" "不能禁用唯一显示器"
    fi
else
    hyprctl keyword monitor "$LAPTOP, 2560x1440@240, 1920x0, 1"
    
    if [ -n "$EXTERNAL_INFO" ]; then
        IFS=',' read -r EXTERNAL_NAME EXTERNAL_MODE <<< "$EXTERNAL_INFO"
        
        if [ -n "$EXTERNAL_MODE" ]; then
            hyprctl keyword monitor "$EXTERNAL_NAME, $EXTERNAL_MODE, 0x0, 1"
        else
            hyprctl keyword monitor "$EXTERNAL_NAME, preferred, 0x0, 1"
        fi
    fi
    
    notify-send "显示器" "笔记本屏幕已启用"
fi