Skip to content

Commit b32a89c

Browse files
authored
Fix a bugs with KDE Plasma when importin/saving configuration
1 parent 80aba57 commit b32a89c

File tree

1 file changed

+62
-118
lines changed

1 file changed

+62
-118
lines changed

src/config.py

Lines changed: 62 additions & 118 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,42 @@
1717

1818
args = parser.parse_args()
1919

20+
def get_kde_files(home):
21+
"""
22+
This method saves the KDE Plasma's configuration files from ~/.config
23+
and ~/.local/share directories to ./xdg-config and ./xdg-data directories
24+
in resulting archive
25+
"""
26+
27+
config_dir = Path(f"{home}/.config")
28+
localshare_dir = Path(f"{home}/.local/share")
29+
30+
kde_files = [
31+
(Path(f"{home}/.config/plasma-org.kde.plasma.desktop-appletsrc"), Path("./xdg-config/plasma-org.kde.plasma.desktop-appletsrc"), False),
32+
(Path(f"{home}/.local/share/plasma-systemmonitor"), Path("./xdg-config/plasma-systemmonitor"), True),
33+
(Path(f"{home}/.local/share/color-schemes"), Path("./xdg-config/color-schemes"), True),
34+
(Path(f"{home}/.config/plasmashellrc"), Path("./xdg-config/plasmashellrc"), False),
35+
(Path(f"{home}/.config/spectaclerc"), Path("./xdg-config/spectaclerc"), False),
36+
(Path(f"{home}/.config/gwenviewrc"), Path("./xdg-config/gwenviewrc"), False),
37+
(Path(f"{home}/.config/dolphinrc"), Path("./xdg-config/dolphinrc"), False),
38+
(Path(f"{home}/.local/share/dolphin"), Path("./xdg-data/dolphin"), True),
39+
(Path(f"{home}/.local/share/aurorae"), Path("./xdg-data/aurorae"), True),
40+
(Path(f"{home}/.config/plasmarc"), Path("./xdg-data/plasmarc"), False),
41+
(Path(f"{home}/.config/Kvantum"), Path("./xdg-data/Kvantum"), True),
42+
(Path(f"{home}/.local/share/sddm"), Path("./xdg-data/sddm"), True),
43+
(Path(f"{home}/.config/gtkrc"), Path("./xdg-data/gtkrc"), False),
44+
(Path(f"{home}/.config/latte"), Path("./xdg-data/latte"), True),
45+
]
46+
47+
# Add all files/dirs starting with "k" from ~/.config
48+
for item in config_dir.glob("k*"):
49+
kde_files.append((item, Path("./xdg-config") / item.name, item.is_dir()))
50+
51+
# Add all files/dirs starting with "k" from ~/.local/share
52+
for item in localshare_dir.glob("k*"):
53+
kde_files.append((item, Path("./xdg-data") / item.name, item.is_dir()))
54+
55+
return kde_files
2056

2157
class DesktopEnvironment(Enum):
2258
"""
@@ -205,9 +241,6 @@ def __init__(self):
205241
desktop = GLib.get_user_special_dir(GLib.UserDirectory.DIRECTORY_DESKTOP).replace(" ", "*")
206242

207243
self.config_files = [
208-
ConfigFiles("Desktop folder", [
209-
(Path(f"{desktop}"), Path("./Desktop/"), True),
210-
]),
211244
ConfigFiles("Gtk settings", [
212245
(Path(f"{home}/.config/gtk-4.0"), Path("./gtk-4.0"), True),
213246
(Path(f"{home}/.config/gtk-3.0"), Path("./gtk-3.0"), True),
@@ -247,7 +280,8 @@ def __init__(self):
247280

248281
if settings["save-desktop-folder"]:
249282
self.config_files.extend([
250-
ConfigFiles("GVFS metadata files", [
283+
ConfigFiles("Desktop directory and GVFS metadata files", [
284+
(Path(f"{desktop}"), Path("./Desktop"), True),
251285
(Path(f"{home}/.local/share/gvfs-metadata"), Path("./gvfs-metadata"), True),
252286
]),
253287
])
@@ -289,24 +323,7 @@ def __init__(self):
289323
DesktopEnvironment.MATE: [
290324
(Path(f"{home}/.config/caja"), Path("./caja"), True)
291325
],
292-
DesktopEnvironment.KDE_PLASMA: [
293-
(Path(f"{home}/.config/plasma-org.kde.plasma.desktop-appletsrc"), Path("./xdg-config/plasma-org.kde.plasma.desktop-appletsrc"), False),
294-
(Path(f"{home}/.local/share/plasma-systemmonitor"), Path("./xdg-config/plasma-systemmonitor"), True),
295-
(Path(f"{home}/.local/share/color-schemes"), Path("./xdg-config/color-schemes"), True),
296-
(Path(f"{home}/.config/plasmashellrc"), Path("./xdg-config/plasmashellrc"), False),
297-
(Path(f"{home}/.config/spectaclerc"), Path("./xdg-config/spectaclerc"), False),
298-
(Path(f"{home}/.config/gwenviewrc"), Path("./xdg-config/gwenviewrc"), False),
299-
(Path(f"{home}/.config/dolphinrc"), Path("./xdg-config/dolphinrc"), False),
300-
(Path(f"{home}/.local/share/dolphin"), Path("./xdg-data/dolphin"), True),
301-
(Path(f"{home}/.local/share/aurorae"), Path("./xdg-data/aurorae"), True),
302-
(Path(f"{home}/.config/plasmarc"), Path("./xdg-data/plasmarc"), False),
303-
(Path(f"{home}/.config/Kvantum"), Path("./xdg-data/Kvantum"), True),
304-
(Path(f"{home}/.local/share/sddm"), Path("./xdg-data/sddm"), True),
305-
(Path(f"{home}/.local/share/[k]*"), Path("./xdg-data/[k]*"), True),
306-
(Path(f"{home}/.config/gtkrc"), Path("./xdg-data/gtkrc"), False),
307-
(Path(f"{home}/.config/latte"), Path("./xdg-data/latte"), True),
308-
(Path(f"{home}/.config/[k]*"), Path("./xdg-config/[k]*"), True),
309-
],
326+
DesktopEnvironment.KDE_PLASMA: get_kde_files(home),
310327
DesktopEnvironment.DEEPIN: [
311328
(Path(f"{home}/.local/share/deepin"), Path("./deepin-data"), True),
312329
(Path(f"{home}/.config/deepin"), Path("./deepin"), True),
@@ -347,7 +364,7 @@ def __init__(self):
347364
desktop_env_config.extend([
348365
(Path(f"{home}/.local/share/plasma"), Path("./xdg-data/plasma"), True),
349366
])
350-
367+
351368
self.config_files.append(desktop_env_config)
352369

353370
@abstractmethod
@@ -430,7 +447,7 @@ def _parallel_copy(self, max_workers: Optional[int] = None) -> None:
430447
431448
:return: None
432449
"""
433-
450+
434451
with ThreadPoolExecutor(max_workers=max_workers or MAX_WORKERS) as executor:
435452
for config in self.config_files:
436453
print(f"Processing: {config.label}")
@@ -547,87 +564,20 @@ def __init__(self):
547564

548565
def __revert_copies(self):
549566
"""
567+
self.config_files = [x.reverse() for x in self.config_files]
550568
Reverts the changes made to the configuration files and restores them to
551-
their original location. This method applies the `reverse()` operation to each
552-
configuration file in the `config_files` collection.
553-
554-
:return: None
555-
"""
556-
self.config_files = self.config_files = [x.reverse() for x in self.config_files]
557-
558-
@staticmethod
559-
def __change_grandparent_dir(paths: List[Path], grandparent: Path):
560-
"""
561-
Modifies paths to replace their parent directory with a specified grandparent
562-
directory if their parent directory name matches specific values.
563-
564-
:param paths: List containing Path objects to be modified.
565-
:param grandparent: The grandparent directory used for replacement.
566-
:return: A list of Path objects with updated parent directories where applicable.
567569
"""
568-
return list(map(
569-
lambda p: grandparent / p.parent.name / p.name
570-
if p.parent.name in ['xdg-config', 'xdg-data']
571-
else p,
572-
paths
573-
))
570+
self.config_files = [x.reverse() for x in self.config_files]
574571

575-
@staticmethod
576-
def __is_xdg_path(path: Path) -> bool:
577-
"""
578-
Determines if the given path is an XDG path based on the naming convention.
579-
580-
This static method checks whether the provided path belongs to the XDG
581-
configuration or data directory by examining the name of the parent
582-
directory.
583-
584-
:param path: The path to be checked.
585-
:type path: Path
586-
:return: Returns True if the path belongs to an XDG directory, otherwise False.
587-
:rtype: bool
588-
"""
589-
return path.parent.name in ['xdg-config', 'xdg-data']
590-
591-
@staticmethod
592-
def __create_xdg_path(grandparent: Path, path: Path) -> Path:
593-
"""
594-
Generate a new XDG-compliant path.
595-
596-
This method constructs a new path by combining the given `grandparent` path with the
597-
parent directory name and the name of the `path`. The resulting path follows the structure:
598-
`grandparent / parent_name_of_path / name_of_path`.
599-
600-
:param grandparent: The top-level directory where the new path should be rooted.
601-
:type grandparent: Path
602-
:param path: The source path whose parent directory name and file name will be used
603-
to form the new path.
604-
:type path: Path
605-
:return: A new path combining `grandparent`, and the name of `path`.
606-
:rtype: Path
607-
"""
608-
return grandparent / path.name
609-
610-
def __kde_import_or_sync(self) -> None:
611-
"""
612-
Processes and updates the list of configuration file paths by ensuring they comply
613-
with the XDG (X Desktop Group) specification. Determines the current directory
614-
to use based on whether syncing or import configuration paths exist before transforming
615-
configurable file paths accordingly.
616-
617-
:param self: Instance of the class calling the function.
618-
"""
619-
syncing_path = Path(f"{CACHE}/syncing")
620-
import_config_path = Path(f"{CACHE}/import_config")
621-
current_dir = syncing_path if syncing_path.exists() else import_config_path
622-
623-
modify = partial(self.__create_xdg_path, current_dir)
624-
transform = lambda p: modify(p) if self.__is_xdg_path(p) else p
625-
self.config_files = list(map(transform, self.config_files))
572+
def import_kde_plasma_shell(self):
573+
# Copy all of xdg-config to ~/.config/
574+
os.system(f'cp -au xdg-config/. {home}/.config/')
575+
# Copy all of xdg-data to ~/.local/share/
576+
os.system(f'cp -au xdg-data/. {home}/.local/share/')
626577

627578
def create_flatpak_desktop(self):
628579
os.system(f"cp {system_dir}/install_flatpak_from_script.py {CACHE}/")
629-
if not os.path.exists(f"{DATA}/savedesktop-synchronization.sh") or not os.path.exists(
630-
f"{CACHE}/syncing/sync_status"):
580+
if not os.path.exists(f"{DATA}/savedesktop-synchronization.sh") or not os.path.exists(f"{CACHE}/syncing/sync_status"):
631581
if not os.path.exists(f"{home}/.config/autostart"):
632582
os.mkdir(f"{home}/.config/autostart")
633583
if not os.path.exists(f"{home}/.config/autostart/io.github.vikdevelop.SaveDesktop.Flatpak.desktop"):
@@ -637,19 +587,10 @@ def create_flatpak_desktop(self):
637587

638588
def setup(self):
639589
"""
640-
Sets up the application configuration by importing settings from the Dconf
641-
database. Handles both backwards compatibility and Flatpak configurations.
642-
643-
Behavior changes based on whether a "user" directory exists, and whether
644-
running under Flatpak is detected. Copies configuration directory for older
645-
versions or executes system commands to load Dconf settings dynamically.
646-
647-
:param self: Instance of the class containing this method.
648-
649-
:raises FileNotFoundError: If the required configuration file or directory
650-
is missing.
590+
This method imports the user settings using the dconf command. For the backward compatibility reasons,
591+
it's also possible copy the 'user' file to the ~/.config/dconf directory, if presents in the archive
651592
"""
652-
print("importing settings from the Dconf database")
593+
print("importing settings from the dconf-settings.ini file")
653594
if Path("user").exists():
654595
shutil.copytree("user", f"{home}/.config/dconf/") # backward compatibility with versions 2.9.4 and older
655596
else:
@@ -661,16 +602,18 @@ def setup(self):
661602

662603
def run(self, max_workers: Optional[int] = None):
663604
"""
664-
Executes the process to handle parallel copy and create the Flatpak desktop integration
665-
if applicable. This method is designed to check for specific files and handle Flatpak
666-
desktop creation when these files are detected.
667-
668-
:return: None
605+
This method first opens the setup() method to import Dconf settings,
606+
then imports KDE Plasma settings from the xdg-config and xdg-data folders.
607+
This is followed by running a parallel copy, and finally running the
608+
create_flatpak_desktop() method to set up the import of Flatpak applications
609+
and their data after logging back into the system.
669610
"""
611+
670612
self.setup()
671-
self._parallel_copy(max_workers=max_workers)
613+
# For KDE Plasma, use the shell copy logic and skip the parallel Python copy
672614
if DesktopEnvironment.get_current_de() == DesktopEnvironment.KDE_PLASMA:
673-
self.__kde_import_or_sync()
615+
self.import_kde_plasma_shell()
616+
self._parallel_copy(max_workers=max_workers)
674617
if flatpak:
675618
if any(os.path.exists(path) for path in ["app", "installed_flatpaks.sh", "installed_user_flatpaks.sh"]):
676619
self.create_flatpak_desktop()
@@ -682,3 +625,4 @@ def teardown(self) -> None:
682625
Save().run()
683626
elif args.import_:
684627
Import().run()
628+

0 commit comments

Comments
 (0)