Skip to content

Instantly share code, notes, and snippets.

@defufna
Created February 21, 2025 15:23
Show Gist options
  • Save defufna/c195aa3aa31b2a9e10e931499530defa to your computer and use it in GitHub Desktop.
Save defufna/c195aa3aa31b2a9e10e931499530defa to your computer and use it in GitHub Desktop.
This script automates tidying desktop icon positions in KDE Plasma.
#!/usr/bin/env python
from typing import List, Dict, Tuple
import json
from itertools import batched
import tempfile
from shutil import move
import subprocess
import time
import os
PLASMA_CONFIG = os.path.expanduser("~/.config/plasma-org.kde.plasma.desktop-appletsrc")
DESKTOP_SECTION = "[Containments][36][General]"
ICON_POSITIONS = {
'desktop:/GCB.desktop': ('2', '0'),
'desktop:/Home.desktop': ('0', '0'),
'desktop:/Igre': ('1', '0'),
'desktop:/crtani.desktop': ('3', '0'),
}
def get_icon_positions(data: List[str], section: str) -> str:
start: int = data.index(section)
for index, line in enumerate(data[start + 1:]):
if line.startswith("positions"):
return (index + start + 1, line)
elif line.startswith("[") or line == "":
return None
def tidy_positions(w, h, icons, positions):
res = []
auto_x = w - 1
auto_y = h - 1
for (name, x, y) in icons:
pos = positions.get(name)
if pos is not None:
res.append((name,) + pos)
else:
res.append((name, str(auto_y), str(auto_x)))
if auto_x > 0:
auto_x -= 1
else:
auto_x = w - 1
auto_y -= 1
return res
def tidy_all(positions: Dict[str, List[str]], default_positions: Dict[str, Tuple[str, str]]) -> Dict[str, List[str]]:
result: Dict[str, List[str]] = {}
for screen_res, icons in positions.items():
if len(icons) < 2:
result[screen_res] = []
continue
resw, resh = [int(x) for x in screen_res.split("x")]
w = int(icons[1])
h = int(resh / (resw / w))
tidied = tidy_positions(w, h, batched(icons[2:], 3), default_positions)
max_h = max(int(y) for name, x, y in tidied)
result[screen_res] = [str(max_h), str(w)] + [value for icon in tidied for value in icon]
return result
def positions_to_str(positions: Dict[str, List[str]]) -> str:
as_str = str(positions).replace("'", '"').replace(",", "\\\\,")
return f"positions={as_str}"
def main():
data = []
with open(PLASMA_CONFIG, "r") as f:
data = f.read().splitlines()
index, positions = get_icon_positions(data, DESKTOP_SECTION)
pos = json.loads(positions.replace("positions=", "").replace("\\\\", ""))
tidied = tidy_all(pos, ICON_POSITIONS)
data[index] = positions_to_str(tidied)
with tempfile.NamedTemporaryFile(delete=False) as f:
f.write("\n".join(data).encode("utf8"))
subprocess.run(["kquitapp6", "plasmashell"], check=True)
time.sleep(2)
move(f.name, PLASMA_CONFIG)
subprocess.Popen(["kstart5", "plasmashell"], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL, start_new_session=True)
if __name__ == "__main__":
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment