Ability to set image as GDM background

Closes #40.
This commit is contained in:
Vladyslav Hroshev
2025-03-26 20:27:16 +02:00
parent d6250ca33a
commit 9f77980c27
7 changed files with 142 additions and 15 deletions

View File

@@ -79,6 +79,9 @@ Icon theme: https://github.com/vinceliuice/Colloid-icon-theme
## 🖥️ GDM theme ## 🖥️ GDM theme
![GDM theme](./readme-images/gdm.png) ![GDM theme](./readme-images/gdm.png)
> **Image:** [Network Abstract](https://4kwallpapers.com/abstract/network-abstract-background-blue-background-5k-8k-8270.html).
>
> **Config:** `sudo python install.py --gdm --blue --gdm-image /path/to/image.jpg --gdm-blur=40 --gdm-darken=30`
> [!NOTE] > [!NOTE]
> This theme only supports GNOME Display Manager. Ubuntu Display Manager is currently not supported. > This theme only supports GNOME Display Manager. Ubuntu Display Manager is currently not supported.
@@ -86,9 +89,9 @@ Icon theme: https://github.com/vinceliuice/Colloid-icon-theme
> [!WARNING] > [!WARNING]
> I am not responsible for any damage caused by the installation of the theme. If you have any problems, please open an issue. > I am not responsible for any damage caused by the installation of the theme. If you have any problems, please open an issue.
> [!IMPORTANT] ### 🚧 Additional requirements
> Install `glib2-devel` package before running the program. - `glib2-devel` (`libglib2.0-dev` on Debian-based distros).
> For Debian-based systems, use the `libglib2.0-dev` package. - `imagemagick` (if you want to apply filters to the background image).
1. Open the terminal. 1. Open the terminal.
2. Go to the directory with the theme. 2. Go to the directory with the theme.
@@ -100,6 +103,9 @@ Icon theme: https://github.com/vinceliuice/Colloid-icon-theme
```shell ```shell
sudo python install.py --gdm --blue --filled sudo python install.py --gdm --blue --filled
``` ```
```shell
sudo python install.py --gdm --gray --gdm-image /path/to/image.jpg --gdm-blur=40 --gdm-darken=30
```
4. After successful file restart GDM service: 4. After successful file restart GDM service:
```shell ```shell
sudo systemctl restart gdm sudo systemctl restart gdm
@@ -153,6 +159,15 @@ Icon theme: https://github.com/vinceliuice/Colloid-icon-theme
| --mode | light / dark | light / dark theme only | | --mode | light / dark | light / dark theme only |
| --sat | (0 - 250) | custom color saturation (<100% - reduce, >100% - increase) | | --sat | (0 - 250) | custom color saturation (<100% - reduce, >100% - increase) |
#### GDM tweaks
| Option | Secondary option | Description |
|---------------|--------------------------|-----------------------------|
| --gdm-image | /absolute/path/to/image/ | set background image to GDM |
| --gdm-blur | 0+ | apply blur to image (px) |
| --gdm-darken | 0 - 100 | darken image (%) |
| --gdm-lighten | 0 - 100 | lighten image (%) |
#### Panel tweaks #### Panel tweaks
**Panel default size** **Panel default size**
@@ -167,7 +182,7 @@ Icon theme: https://github.com/vinceliuice/Colloid-icon-theme
|----------------------------|------------------|--------------------------------| |----------------------------|------------------|--------------------------------|
| -Pds, --panel-default-size | | set default panel size | | -Pds, --panel-default-size | | set default panel size |
| -Pnp, --panel-no-pill | | remove panel button background | | -Pnp, --panel-no-pill | | remove panel button background |
| -Ptc, --panel-text-color | #abcdef | custom panel HEX(A) text color | | -Ptc, --panel-text-color | #abcdef | custom panel HEX(A) text color |
| --wider-panel | | make the panel a bit wider | | --wider-panel | | make the panel a bit wider |
#### Overview tweaks #### Overview tweaks
@@ -181,11 +196,12 @@ Icon theme: https://github.com/vinceliuice/Colloid-icon-theme
| --launchpad | Change Show Apps icon to macOS Launchpad icon | | --launchpad | Change Show Apps icon to macOS Launchpad icon |
#### Examples #### Examples
| Command | Description | | Command | Description |
|------------------------------------------------|----------------------------------------------------------------------| |-----------------------------------------------------------|--------------------------------------------------------------------------|
| -a | Install all accent colors with light & dark mode | | -a | Install all accent colors with light & dark mode |
| --all --mode dark | Install all accent colors with dark mode only | | --all --mode dark | Install all accent colors with dark mode only |
| --purple --mode=light | Install purple accent color with light mode only | | --purple --mode=light | Install purple accent color with light mode only |
| --hue 150 --name coldgreen | Install custom coldgreen accent color, light & dark mode | | --hue 150 --name coldgreen | Install custom coldgreen accent color, light & dark mode |
| --red --green --sat=70 | red, green accent colors, 70% of the stock saturation | | --red --green --sat=70 | red, green accent colors, 70% of the stock saturation |
| --hue=200 --name=grayblue --sat=50 --mode=dark | custom grayblue accent color, 50% of the stock saturation, dark mode | | --hue=200 --name=grayblue --sat=50 --mode=dark | custom grayblue accent color, 50% of the stock saturation, dark mode |
| --gdm --blue --gdm-image /path/to/image.jpg --gdm-blur=40 | Install GDM theming in blue color with own GDM background image and blur |

View File

@@ -16,6 +16,7 @@
import json # working with json files import json # working with json files
import argparse # command-line options import argparse # command-line options
import os.path
import shutil import shutil
import textwrap # example text in argparse import textwrap # example text in argparse
@@ -155,10 +156,10 @@ def global_theme(args, colors):
:param args: parsed arguments :param args: parsed arguments
:param colors: colors from colors.json :param colors: colors from colors.json
""" """
gdm_temp = os.path.join(config.temp_folder, config.gdm_folder)
gdm_theme = GlobalTheme(colors, f"{config.raw_theme_folder}/{config.gnome_folder}", gdm_theme = GlobalTheme(colors, f"{config.raw_theme_folder}/{config.gnome_folder}",
config.global_gnome_shell_theme, config.gnome_shell_gresource, config.global_gnome_shell_theme, config.gnome_shell_gresource,
config.temp_folder, mode=args.mode, is_filled=args.filled) gdm_temp, mode=args.mode, is_filled=args.filled)
if args.remove: if args.remove:
gdm_rm_status = gdm_theme.remove() gdm_rm_status = gdm_theme.remove()
@@ -166,6 +167,8 @@ def global_theme(args, colors):
print("GDM theme removed successfully.") print("GDM theme removed successfully.")
return return
for theme in gdm_theme.themes:
apply_tweaks(args, theme.theme, colors)
if apply_colors(args, gdm_theme, colors, gdm=True) is None: if apply_colors(args, gdm_theme, colors, gdm=True) is None:
print("\nGDM theme installed successfully.") print("\nGDM theme installed successfully.")

Binary file not shown.

Before

Width:  |  Height:  |  Size: 25 KiB

After

Width:  |  Height:  |  Size: 319 KiB

View File

@@ -2,6 +2,7 @@ from tempfile import gettempdir
# folder definitions # folder definitions
temp_folder = f"{gettempdir()}/marble" temp_folder = f"{gettempdir()}/marble"
gdm_folder = "gdm"
gnome_folder = "gnome-shell" gnome_folder = "gnome-shell"
temp_gnome_folder = f"{temp_folder}/{gnome_folder}" temp_gnome_folder = f"{temp_folder}/{gnome_folder}"
tweaks_folder = "tweaks" tweaks_folder = "tweaks"

View File

@@ -34,7 +34,7 @@ class GlobalTheme:
self.theme_folder = theme_folder self.theme_folder = theme_folder
self.destination_folder = destination_folder self.destination_folder = destination_folder
self.destination_file = destination_file self.destination_file = destination_file
self.temp_folder = os.path.join(temp_folder, "gdm") self.temp_folder = temp_folder
self.backup_file = f"{self.destination_file}.backup" self.backup_file = f"{self.destination_file}.backup"
self.backup_trigger = "\n/* Marble theme */\n" # trigger to check if theme is installed self.backup_trigger = "\n/* Marble theme */\n" # trigger to check if theme is installed

21
scripts/utils/is_photo.py Normal file
View File

@@ -0,0 +1,21 @@
image_extensions = [
'jpg', 'jpeg', 'png', 'gif', 'bmp',
'webp', 'tiff', 'tif', 'svg', 'heic', 'heif'
]
def is_photo(extension: str):
"""
Check if extension is supported photo format
"""
return extension.lower() in image_extensions
class NotSupportedPhotoExtension(Exception):
"""
Exception for not supported photo extension
"""
def __init__(self, extension):
self.message = (f"Photo extension {extension} is not supported. "
f"Supported formats: {", ".join(image_extensions)}.")
super().__init__(self.message)

86
tweaks/gdm/tweak.py Executable file
View File

@@ -0,0 +1,86 @@
import os.path
import shutil
import subprocess
from argparse import ArgumentParser
from scripts import config
from scripts.utils.is_photo import is_photo, NotSupportedPhotoExtension
def define_arguments(parser: ArgumentParser):
gdm_args = parser.add_argument_group("GDM tweaks")
gdm_args.add_argument("--gdm-image", type=str, nargs="?", help="Set GDM background image")
gdm_args.add_argument("--gdm-blur", type=int, nargs="?", help="Blur GDM background image (px)")
gdm_args.add_argument("--gdm-darken", type=int, choices=range(0, 100), help="Darken GDM background image (%)", metavar="(0 - 100)")
gdm_args.add_argument("--gdm-lighten", type=int, choices=range(0, 100), help="Lighten GDM background image", metavar="(0 - 100)")
def apply_tweak(args, theme, colors):
if args.gdm_image:
gdm_image = GDMImage(args.gdm_image, config.temp_folder, args.gdm_blur)
destination_dir = os.path.join(config.temp_folder, config.gdm_folder, config.raw_theme_folder)
os.makedirs(destination_dir, exist_ok=True)
gdm_image.copy_image(destination_dir)
theme += f"""
.login-dialog {{
background-image: url("{gdm_image.image_name}");
background-size: cover;
{f"box-shadow: inset 0 0 0 9999px rgba(0, 0, 0, {args.gdm_darken/100});" if args.gdm_darken else ""}
{f"box-shadow: inset 0 0 0 9999px rgba(255, 255, 255, {args.gdm_lighten/100});" if args.gdm_lighten else ""}
}}
"""
class GDMImage:
"""
Class to apply effects to GDM background image
"""
image_name: str
def __init__(self, path: str, temp_folder: str, blur: int = None):
self.path = path
extension = path.split(".")[-1]
if not is_photo(extension):
raise NotSupportedPhotoExtension(extension)
self.image_name = f"gdm-image.{extension}"
self.destination_dir = temp_folder
self.destination_file = os.path.join(self.destination_dir, self.image_name)
if not os.path.exists(self.destination_file):
self._create_file()
self._magick_tweaks(blur)
def copy_image(self, destination: str):
dest_path = os.path.join(destination, self.image_name)
shutil.copyfile(self.destination_file, dest_path)
def _create_file(self):
os.makedirs(self.destination_dir, exist_ok=True)
shutil.copyfile(self.path, self.destination_file)
def _magick_tweaks(self, blur: int = None):
if not shutil.which("magick"):
print("Warning: ImageMagick not found. Image effects will be skipped.")
return
file = self.destination_file
modified = False
command = ["magick", file]
if blur:
command.extend(["-blur", f"0x{blur}"])
modified = True
if modified:
print("Applying image filters... This may take a while.")
output_file = file
command.append(output_file)
try:
subprocess.run(command, check=True)
except subprocess.CalledProcessError:
print(f"Error: Failed to apply image effects to {file}")