Has copy command button
This commit is contained in:
@@ -5,6 +5,7 @@ import json
|
|||||||
import subprocess
|
import subprocess
|
||||||
import sys
|
import sys
|
||||||
import os
|
import os
|
||||||
|
import shlex
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
|
||||||
# Try to import PySide6 for the GUI
|
# Try to import PySide6 for the GUI
|
||||||
@@ -206,7 +207,7 @@ class DisplayProfileManagerGUI(QMainWindow):
|
|||||||
def __init__(self):
|
def __init__(self):
|
||||||
super().__init__()
|
super().__init__()
|
||||||
self.setWindowTitle("KDE Display Profile Manager")
|
self.setWindowTitle("KDE Display Profile Manager")
|
||||||
self.setMinimumSize(400, 300)
|
self.setMinimumSize(420, 300)
|
||||||
|
|
||||||
# Ensure default directory exists
|
# Ensure default directory exists
|
||||||
DEFAULT_PROFILE_DIR.mkdir(parents=True, exist_ok=True)
|
DEFAULT_PROFILE_DIR.mkdir(parents=True, exist_ok=True)
|
||||||
@@ -237,6 +238,11 @@ class DisplayProfileManagerGUI(QMainWindow):
|
|||||||
self.refresh_btn.clicked.connect(self.refresh_profiles)
|
self.refresh_btn.clicked.connect(self.refresh_profiles)
|
||||||
btn_layout.addWidget(self.refresh_btn)
|
btn_layout.addWidget(self.refresh_btn)
|
||||||
|
|
||||||
|
self.copy_btn = QPushButton("Copy Load Cmd")
|
||||||
|
self.copy_btn.setMinimumWidth(120)
|
||||||
|
self.copy_btn.clicked.connect(self.on_copy_clicked)
|
||||||
|
btn_layout.addWidget(self.copy_btn)
|
||||||
|
|
||||||
layout.addLayout(btn_layout)
|
layout.addLayout(btn_layout)
|
||||||
|
|
||||||
def refresh_profiles(self):
|
def refresh_profiles(self):
|
||||||
@@ -291,6 +297,23 @@ class DisplayProfileManagerGUI(QMainWindow):
|
|||||||
except Exception as e:
|
except Exception as e:
|
||||||
QMessageBox.critical(self, "Error", f"Failed to load profile: {e}")
|
QMessageBox.critical(self, "Error", f"Failed to load profile: {e}")
|
||||||
|
|
||||||
|
def on_copy_clicked(self):
|
||||||
|
selected_item = self.profile_list.currentItem()
|
||||||
|
if not selected_item:
|
||||||
|
QMessageBox.warning(self, "No Selection", "Please select a profile to copy the command for.")
|
||||||
|
return
|
||||||
|
|
||||||
|
profile_name = selected_item.text()
|
||||||
|
profile_path = DEFAULT_PROFILE_DIR / f"{profile_name}.json"
|
||||||
|
|
||||||
|
script_path = os.path.abspath(__file__)
|
||||||
|
cmd = f"python3 {shlex.quote(script_path)} load {shlex.quote(str(profile_path))}"
|
||||||
|
|
||||||
|
clipboard = QApplication.clipboard()
|
||||||
|
clipboard.setText(cmd)
|
||||||
|
|
||||||
|
QMessageBox.information(self, "Command Copied", f"The following command has been copied to your clipboard:\n\n{cmd}")
|
||||||
|
|
||||||
def show_gui():
|
def show_gui():
|
||||||
if not PYSIDE_AVAILABLE:
|
if not PYSIDE_AVAILABLE:
|
||||||
print("Error: PySide6 is not installed. Please install it to use the GUI.", file=sys.stderr)
|
print("Error: PySide6 is not installed. Please install it to use the GUI.", file=sys.stderr)
|
||||||
|
|||||||
@@ -1,222 +0,0 @@
|
|||||||
#!/usr/bin/env bash
|
|
||||||
|
|
||||||
VERBOSE=1
|
|
||||||
|
|
||||||
|
|
||||||
function log {
|
|
||||||
if [ $VERBOSE -eq 1 ]; then
|
|
||||||
echo "$@"
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
set -e
|
|
||||||
|
|
||||||
# Make sure a config file was provided
|
|
||||||
if [ $# -lt 1 ]; then
|
|
||||||
echo "Usage: $0 <config file>"
|
|
||||||
exit
|
|
||||||
fi
|
|
||||||
|
|
||||||
PROFILE=$1
|
|
||||||
|
|
||||||
if [[ ! -f "$PROFILE" ]]; then
|
|
||||||
echo "Profile file not found: $PROFILE" >&2
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
if ! command -v jq &>/dev/null; then
|
|
||||||
echo "jq not installed!" >&2
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
if ! command -v kscreen-doctor &>/dev/null; then
|
|
||||||
echo "kscreen-doctor not found!" >&2
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Extract outputs list
|
|
||||||
enabled_outputs=$(jq -c '.outputs[] | select(.enabled == true)' "$PROFILE")
|
|
||||||
disabled_outputs=$(jq -c '.outputs[] | select(.enabled == false)' "$PROFILE")
|
|
||||||
outputs=$(jq -c '.outputs[]' "$PROFILE")
|
|
||||||
|
|
||||||
# Restore enabled/disabled starting with the enabled monitors
|
|
||||||
# Starting with a disabled monitor might not work if it was
|
|
||||||
# previously the only enabled monitor
|
|
||||||
|
|
||||||
function enable_outputs {
|
|
||||||
local outputs=$1
|
|
||||||
|
|
||||||
# If empty or only whitespace, return early
|
|
||||||
[[ -z "$outputs" ]] && return
|
|
||||||
|
|
||||||
while IFS= read -r out; do
|
|
||||||
id=$(echo "$out" | jq -r '.id')
|
|
||||||
log "[VAR] id:" $id
|
|
||||||
name=$(echo "$out" | jq -r '.name')
|
|
||||||
log "[VAR] name:" $name
|
|
||||||
enabled=$(echo "$out" | jq -r '.enabled')
|
|
||||||
log "[VAR] enabled:" $enabled
|
|
||||||
|
|
||||||
# Enable/disable
|
|
||||||
if [[ "$enabled" == "true" ]]; then
|
|
||||||
CMD="kscreen-doctor output.$name.enable"
|
|
||||||
log "[CMD]" $CMD
|
|
||||||
$CMD
|
|
||||||
else
|
|
||||||
CMD="kscreen-doctor output.$name.disable"
|
|
||||||
log "[CMD]" $CMD
|
|
||||||
$CMD
|
|
||||||
fi
|
|
||||||
done <<< "$outputs"
|
|
||||||
}
|
|
||||||
|
|
||||||
log "Enabling enabled outputs..."
|
|
||||||
enable_outputs "$enabled_outputs"
|
|
||||||
log "Disabling disabled outputs..."
|
|
||||||
enable_outputs "$disabled_outputs"
|
|
||||||
|
|
||||||
function apply_attribute {
|
|
||||||
output_id=$1
|
|
||||||
attribute=$2
|
|
||||||
value=$3
|
|
||||||
value_map=$4
|
|
||||||
|
|
||||||
if [ $value != "null" ]; then
|
|
||||||
|
|
||||||
if [[ -n "$value_map" ]]; then
|
|
||||||
log "[PREVALUE] Value supplied for $output_id $attribute: $value"
|
|
||||||
value=${value_map["$value"]}
|
|
||||||
log "[POSTVALUE] Value output for $output_id $attribute: $value"
|
|
||||||
fi
|
|
||||||
|
|
||||||
CMD="kscreen-doctor output.$output_id.$attribute.$value"
|
|
||||||
log "[CMD]" $CMD
|
|
||||||
$CMD
|
|
||||||
else
|
|
||||||
log "Output $output_id has not attribute $attribute, skipping..."
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
function load_profile_to_outputs {
|
|
||||||
local outputs=$1
|
|
||||||
|
|
||||||
# If empty or only whitespace, return early
|
|
||||||
[[ -z "$outputs" ]] && return
|
|
||||||
|
|
||||||
while IFS= read -r out; do
|
|
||||||
id=$(echo "$out" | jq -r '.id')
|
|
||||||
name=$(echo "$out" | jq -r '.name')
|
|
||||||
posx=$(echo "$out" | jq -r '.pos.x')
|
|
||||||
posy=$(echo "$out" | jq -r '.pos.y')
|
|
||||||
rotation=$(echo "$out" | jq -r '.rotation')
|
|
||||||
scale=$(echo "$out" | jq -r '.scale')
|
|
||||||
mode_id=$(echo "$out" | jq -r '.currentModeId')
|
|
||||||
brightness=$(echo "$out" | jq -r '.brightness')
|
|
||||||
brightness=$(awk "BEGIN {printf \"%d\", $brightness * 100}")
|
|
||||||
ddcCi=$(echo "$out" | jq -r '.ddcCi')
|
|
||||||
iccProfilePath=$(echo "$out" | jq -r '.iccProfilePath')
|
|
||||||
# mode_name=$(echo "$out" | jq -r ".modes[] | select(.id == \"$mode_id\") | .name")
|
|
||||||
# log "[VAR] mode_name:" $mode_name
|
|
||||||
refresh_rate=$(echo "$out" | jq -r ".modes[] | select(.id == \"$mode_id\") | .refreshRate")
|
|
||||||
refresh_rate=$(printf "%.0f" "$refresh_rate")
|
|
||||||
height=$(echo "$out" | jq -r ".modes[] | select(.id == \"$mode_id\") | .size.height")
|
|
||||||
width=$(echo "$out" | jq -r ".modes[] | select(.id == \"$mode_id\") | .size.width")
|
|
||||||
mode="${width}x${height}@${refresh_rate}"
|
|
||||||
replication_source_id=$(echo "$out" | jq -r ".replicationSource")
|
|
||||||
hdr=$(echo "$out" | jq -r ".hdr")
|
|
||||||
maxBpc=$(echo "$out" | jq -r ".maxBpc")
|
|
||||||
overscan=$(echo "$out" | jq -r ".overscan")
|
|
||||||
rgbRange=$(echo "$out" | jq -r ".rgbRange")
|
|
||||||
sdrbrightness=$(echo "$out" | jq -r '."sdr-brightness"')
|
|
||||||
vrrPolicy=$(echo "$out" | jq -r ".vrrPolicy")
|
|
||||||
wcg=$(echo "$out" | jq -r ".wcg")
|
|
||||||
|
|
||||||
|
|
||||||
declare -A bool_enable_map
|
|
||||||
bool_enable_map["true"]="enable"
|
|
||||||
bool_enable_map["false"]="disable"
|
|
||||||
|
|
||||||
declare -A bool_allow_map
|
|
||||||
bool_allow_map["true"]="allow"
|
|
||||||
bool_allow_map["false"]="disallow"
|
|
||||||
|
|
||||||
declare -A rgb_range_map
|
|
||||||
rgb_range_map["0"]="automatic"
|
|
||||||
rgb_range_map["full"]="full"
|
|
||||||
rgb_range_map["limited"]="limited"
|
|
||||||
|
|
||||||
declare -A rotation_map
|
|
||||||
rotation_map["1"]="normal"
|
|
||||||
rotation_map["2"]="left"
|
|
||||||
rotation_map["4"]="inverted"
|
|
||||||
rotation_map["8"]="right"
|
|
||||||
|
|
||||||
apply_attribute $name "wcg" $wcg $bool_enable_map
|
|
||||||
apply_attribute $name "sdr-brightness" $sdrbrightness
|
|
||||||
apply_attribute $name "vrrpolicy" $vrrPolicy
|
|
||||||
apply_attribute $name "rgbrange" $rgbRange $rgb_range_map
|
|
||||||
apply_attribute $name "overscan" $overscan
|
|
||||||
apply_attribute $name "hdr" $hdr $bool_enable_map
|
|
||||||
apply_attribute $name "brightness" $brightness
|
|
||||||
|
|
||||||
if [ "$maxBpc" == 0 ]; then
|
|
||||||
maxBpc="automatic"
|
|
||||||
fi
|
|
||||||
apply_attribute $name "maxbpc" $maxBpc
|
|
||||||
apply_attribute $name "ddcCi" $ddcCi $bool_allow_map
|
|
||||||
|
|
||||||
|
|
||||||
log "[VAR] replication_source_id: $replication_source_id"
|
|
||||||
if [ $replication_source_id != 0 ]; then
|
|
||||||
replication_source_name=$(echo "$outputs.[] | select(.id == \"$replication_source_id\" | .name)" )
|
|
||||||
apply_attribute $name "mirror" $replication_source_name
|
|
||||||
else
|
|
||||||
apply_attribute $name "mirror" "none"
|
|
||||||
fi
|
|
||||||
|
|
||||||
priority=$(echo "$out" | jq -r '.priority')
|
|
||||||
|
|
||||||
if [ "$iccProfilePath" != "" ]; then
|
|
||||||
apply_attribute $name "iccProfilePath" $iccProfilePath
|
|
||||||
fi
|
|
||||||
|
|
||||||
|
|
||||||
apply_attribute $name "mode" $mode
|
|
||||||
|
|
||||||
# Position
|
|
||||||
# CMD="kscreen-doctor output.$name.position.$posx,$posy"
|
|
||||||
# log "[CMD]" $CMD
|
|
||||||
# $CMD
|
|
||||||
fullPosition="$posx,$posy"
|
|
||||||
apply_attribute $name "position" $fullPosition
|
|
||||||
|
|
||||||
apply_attribute $name "scale" $scale
|
|
||||||
|
|
||||||
# Rotation (map from JSON names to kscreen-doctor options)
|
|
||||||
# CMD=""
|
|
||||||
# case "$rotation" in
|
|
||||||
# "1") CMD="kscreen-doctor output.$name.rotation.normal" ;;
|
|
||||||
# "2") CMD="kscreen-doctor output.$name.rotation.left" ;;
|
|
||||||
# "4") CMD="kscreen-doctor output.$name.rotation.inverted" ;;
|
|
||||||
# "8") CMD="kscreen-doctor output.$name.rotation.right" ;;
|
|
||||||
# esac
|
|
||||||
# log "[CMD]" $CMD
|
|
||||||
# $CMD
|
|
||||||
apply_attribute $name "rotation" $rotation $rotation_map
|
|
||||||
|
|
||||||
# Primary / Not Primary
|
|
||||||
if [ $priority -eq 1 ]; then
|
|
||||||
CMD="kscreen-doctor output.$name.primary"
|
|
||||||
log "[CMD]" $CMD
|
|
||||||
$CMD
|
|
||||||
fi
|
|
||||||
|
|
||||||
CMD="kscreen-doctor output.$name.priority.$priority"
|
|
||||||
log "[CMD]" $CMD
|
|
||||||
$CMD
|
|
||||||
|
|
||||||
done <<< "$outputs"
|
|
||||||
}
|
|
||||||
|
|
||||||
load_profile_to_outputs "$outputs"
|
|
||||||
|
|
||||||
echo "Display configuration restored."
|
|
||||||
@@ -1,10 +0,0 @@
|
|||||||
#!/bin/bash
|
|
||||||
|
|
||||||
# Check for correct usage
|
|
||||||
if [ $# -lt 1 ]; then
|
|
||||||
echo "Usage: $0 <config name>"
|
|
||||||
exit
|
|
||||||
fi
|
|
||||||
|
|
||||||
OUTPUT_CONFIG_NAME=$1
|
|
||||||
kscreen-doctor --json > $OUTPUT_CONFIG_NAME
|
|
||||||
Reference in New Issue
Block a user