Commit 23e4e84a authored by Roman Alifanov's avatar Roman Alifanov

Happy birthday, GUI on gtk4! (+ moving to Meson and reorganizing the repo)

GUI on Yad is forever in my heart ,- ,
parent a2daead1
prefix = /usr/local
sysconfdir = /etc
datadir = $(prefix)/share
bindir = $(prefix)/bin
all: dir install
dir:
mkdir -p $(bindir)
mkdir -p $(prefix)/lib/systemd/user
mkdir -p $(sysconfdir)/ximper-unified-theme-switcher
mkdir -p $(datadir)/icons/hicolor/scalable/apps/
mkdir -p $(datadir)/applications/
install: dir
cp ./bin/ximper-unified-theme-switcher-service $(bindir)
cp ./bin/ximper-unified-theme-switcher-gui $(bindir)
cp ./data/ximper-unified-theme-switcher.service $(prefix)/lib/systemd/user
cp ./data/ximper-unified-theme-switcher-gui.svg $(datadir)/icons/hicolor/scalable/apps/
cp ./data/ximper-unified-theme-switcher-gui.desktop $(datadir)/applications
uninstall:
rm -f $(prebindirfix)/ximper-unified-theme-switcher-service
rm -f $(bindir)/ximper-unified-theme-switcher-gui
rm -f $(prefix)/lib/systemd/user/ximper-unified-theme-switcher.service
rm -f $(datadir)/icons/hicolor/scalable/apps/ximper-unified-theme-switcher-gui.svg
rm -f $(datadir)/applications/ximper-unified-theme-switcher-gui.desktop
#!/bin/bash
# shellcheck source=/usr/bin/shell-config
source shell-config
export GDK_BACKEND="x11"
SWITCHER_TMP_PATH=$(mktemp -d -t ximper-unified-theme-switcher-gui.XXXXXXX)
cleanup() {
rm -rf "$SWITCHER_TMP_PATH"
}
trap "cleanup" EXIT
SYSTEM_CONFIG_DIR="/etc/ximper-unified-theme-switcher"
SYSTEM_CONFIG_FILE="$SYSTEM_CONFIG_DIR/themes"
HOME_CONFIG_DIR="$HOME/.config/ximper-unified-theme-switcher"
HOME_CONFIG_FILE="$HOME_CONFIG_DIR/themes"
# Функция для создания конфига в домашнем каталоге
create_config() {
if [ "$(id -u)" -eq 0 ]; then
mkdir -p "$SYSTEM_CONFIG_DIR"
touch "$SYSTEM_CONFIG_FILE"
echo "$SYSTEM_CONFIG_FILE"
else
mkdir -p "$HOME_CONFIG_DIR"
touch "$HOME_CONFIG_FILE"
echo "$HOME_CONFIG_FILE"
fi
}
cfg_check() {
# Проверка наличия конфига в /etc
if [ -f "$SYSTEM_CONFIG_FILE" ] && [ -w "$SYSTEM_CONFIG_FILE" ]; then
echo "$SYSTEM_CONFIG_FILE"
else
# Если нет конфига в /etc, ищем в домашнем каталоге
if [ -f "$HOME_CONFIG_FILE" ]; then
echo "$HOME_CONFIG_FILE"
else
create_config
fi
fi
}
EDITABLE_CONFIG_FILE=$(cfg_check)
echo "$EDITABLE_CONFIG_FILE"
# Вспомогательная функция для обработки списка тем
manipulate-list() {
TARGET="$2"
THEMES_LIST="$1"
RESULT=$(echo "$THEMES_LIST" | grep -Fxv "$TARGET")
echo -e "$TARGET\n$RESULT"
}
gtk3-themes-list() {
local LIST
local REPLACE_OBJ
local OUTPUT
local THEMES_DIRS
local THEMES_DIR
THEMES_DIRS=(
"/usr/share/themes/"
"$HOME/.themes/"
"$HOME/.local/share/themes/"
)
for THEMES_DIR in "${THEMES_DIRS[@]}"; do
if [ -z "$(find "$THEMES_DIR" -maxdepth 0 -empty)" ]; then
LIST="${LIST}$(basename -a "$THEMES_DIR"/*)\n"
fi
done
if [ "$1" == "light" ]; then
REPLACE_OBJ=$(shell_config_get "$EDITABLE_CONFIG_FILE" GTK3_LIGHT_THEME)
elif [ "$1" == "dark" ]; then
REPLACE_OBJ=$(shell_config_get "$EDITABLE_CONFIG_FILE" GTK3_DARK_THEME)
else
REPLACE_OBJ=""
fi
OUTPUT=$(manipulate-list "$LIST" "$REPLACE_OBJ")
echo "$OUTPUT" | tr '\n' '!' | sed 's/.$//'
}
kv-themes-list() {
local LIST
local REPLACE_OBJ
local OUTPUT
local THEMES_DIRS
local THEMES_DIR
THEMES_DIRS=(
"/usr/share/color-schemes/"
)
for THEMES_DIR in "${THEMES_DIRS[@]}"; do
if [ -z "$(find "$THEMES_DIR" -maxdepth 0 -empty)" ]; then
LIST="${LIST}$(basename -a "$THEMES_DIR"Kv*)\n"
fi
done
LIST=$(echo "$LIST" | sed 's/\.colors//')
if [ "$1" == "light" ]; then
REPLACE_OBJ=$(shell_config_get "$EDITABLE_CONFIG_FILE" KV_LIGHT_THEME)
elif [ "$1" == "dark" ]; then
REPLACE_OBJ=$(shell_config_get "$EDITABLE_CONFIG_FILE" KV_DARK_THEME)
else
REPLACE_OBJ=""
fi
OUTPUT=$(manipulate-list "$LIST" "$REPLACE_OBJ")
echo "$OUTPUT" | tr '\n' '!' | sed 's/.$//'
}
change-style() {
local CURRENT_THEME
CURRENT_THEME=$(gsettings get org.gnome.desktop.interface color-scheme | awk -F"'" '{print $2}')
if [ "$CURRENT_THEME" == "default" ]; then
gsettings set org.gnome.desktop.interface color-scheme 'prefer-dark'
else
gsettings set org.gnome.desktop.interface color-scheme 'default'
fi
}
export -f change-style
YAD_RANDOM=$RANDOM
while true; do
yad --form \
--plug=$YAD_RANDOM --tabnum=1 \
--columns=2 --align=center \
--field="change style to light/dark:FBTN" \
"bash -c 'change-style'" \
&
yad --form \
--plug=$YAD_RANDOM --tabnum=2 \
--columns=2 -align=center \
\
--field="Kvantum light theme:CB" \
"$(kv-themes-list light)" \
--field="Kvantum dark theme:CB" \
"$(kv-themes-list dark)" \
\
--field="GTK3 light theme:CB" \
"$(gtk3-themes-list light)" \
--field="GTK3 dark theme:CB" \
"$(gtk3-themes-list dark)" \
\
> "${SWITCHER_TMP_PATH}/SETTINGS" \
&
yad --paned \
--key=$YAD_RANDOM \
--title="ximper-unified-theme-switcher-gui" --class="ximper-unified-theme-switcher-gui" \
--orient=vert --splitter=0 --width=300 --height=200 \
\
--button="yad-apply:0" \
--button="yad-cancel:1"
if [[ $? == 252 || $? == 1 ]]; then
echo "EXIT"
break
fi
NEW_SETTINGS=$(cat "$SWITCHER_TMP_PATH/SETTINGS")
IFS='|' read -r KV_LIGHT KV_DARK GTK3_LIGHT GTK3_DARK <<< "$NEW_SETTINGS"
declare -A THEMES=(
["KV_LIGHT_THEME"]="$KV_LIGHT"
["KV_DARK_THEME"]="$KV_DARK"
["GTK3_LIGHT_THEME"]="$GTK3_LIGHT"
["GTK3_DARK_THEME"]="$GTK3_DARK"
)
for THEME in "${!THEMES[@]}"; do
shell_config_set "$EDITABLE_CONFIG_FILE" "$THEME" "${THEMES[$THEME]}"
done
done
application_id = 'ru.ximperlinux.UnifiedThemeSwitcher'
scalable_dir = 'hicolor' / 'scalable' / 'apps'
install_data(
scalable_dir / ('@0@.svg').format(application_id),
install_dir: get_option('datadir') / 'icons' / scalable_dir
)
desktop_file = i18n.merge_file(
input: 'ru.ximperlinux.UnifiedThemeSwitcher.desktop.in',
output: 'ru.ximperlinux.UnifiedThemeSwitcher.desktop',
type: 'desktop',
po_dir: '../po',
install: true,
install_dir: get_option('datadir') / 'applications'
)
desktop_utils = find_program('desktop-file-validate', required: false)
if desktop_utils.found()
test('Validate desktop file', desktop_utils, args: [desktop_file])
endif
appstream_file = i18n.merge_file(
input: 'ru.ximperlinux.UnifiedThemeSwitcher.metainfo.xml.in',
output: 'ru.ximperlinux.UnifiedThemeSwitcher.metainfo.xml',
po_dir: '../po',
install: true,
install_dir: get_option('datadir') / 'metainfo'
)
appstreamcli = find_program('appstreamcli', required: false, disabler: true)
test('Validate appstream file', appstreamcli,
args: ['validate', '--no-net', '--explain', appstream_file])
install_data('ru.ximperlinux.UnifiedThemeSwitcher.gschema.xml',
install_dir: get_option('datadir') / 'glib-2.0' / 'schemas'
)
compile_schemas = find_program('glib-compile-schemas', required: false, disabler: true)
test('Validate schema file',
compile_schemas,
args: ['--strict', '--dry-run', meson.current_source_dir()])
subdir('icons')
[Desktop Entry]
Name=Ximper Theme Switcher
Name[ru]=Единый переключатель тем
Exec=ximper-unified-theme-switcher-gui
Icon=ru.ximperlinux.UnifiedThemeSwitcher
Terminal=false
Type=Application
Categories=GTK;
StartupNotify=true
<?xml version="1.0" encoding="UTF-8"?>
<schemalist gettext-domain="ximper-unified-theme-switcher-gui">
<schema id="ru.ximperlinux.UnifiedThemeSwitcher" path="/ru/ximperlinux/UnifiedThemeSwitcher/">
</schema>
</schemalist>
<?xml version="1.0" encoding="UTF-8"?>
<component type="desktop">
<id>ru.ximperlinux.UnifiedThemeSwitcher.desktop</id>
<metadata_license>CC0-1.0</metadata_license>
<project_license>MIT</project_license>
<description>
<p>No description</p>
</description>
</component>
[Desktop Entry]
Type=Application
Name=Theme switcher
Name[ru]=Смена тем
Comment=Color theme management
Comment[ru]=Управление цветовой темой
Categories=Utility;
Exec=ximper-unified-theme-switcher-gui
Icon=ximper-unified-theme-switcher-gui
project('ximper-unified-theme-switcher-gui',
version: '0.1.0',
meson_version: '>= 0.62.0',
default_options: [ 'warning_level=2', 'werror=false', ],
)
i18n = import('i18n')
gnome = import('gnome')
subdir('data')
subdir('src')
subdir('po')
subdir('service')
gnome.post_install(
glib_compile_schemas: true,
gtk_update_icon_cache: true,
update_desktop_database: true,
)
ru
\ No newline at end of file
data/ru.ximperlinux.UnifiedThemeSwitcher.desktop.in
data/ru.ximperlinux.UnifiedThemeSwitcher.metainfo.xml.in
data/ru.ximperlinux.UnifiedThemeSwitcher.gschema.xml
src/main.py
src/window.ui
\ No newline at end of file
i18n.gettext(
'ximper-unified-theme-switcher-gui',
preset: 'glib'
)
msgid ""
msgstr ""
"Project-Id-Version: ru.ximperlinux.UnifiedThemeSwitcher\n"
"POT-Creation-Date: 2024-07-10 17:18+0300\n"
"PO-Revision-Date: 2024-07-10 17:18+0300\n"
"Last-Translator: \n"
"Language-Team: \n"
"Language: ru\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Generator: Poedit 3.4.4\n"
"X-Poedit-Basepath: ../src\n"
"X-Poedit-SearchPath-0: .\n"
msgid "Ximper Unified Theme Switcher"
msgstr "Единый переключатель тем"
msgid "_About Ximper Unified Theme Switcher"
msgstr "О Едином переключателе тем"
msgid "_Light theme"
msgstr "Светлая тема"
msgid "_Dark theme"
msgstr "Тёмная тема"
msgid "Change style"
msgstr "Сменить стиль"
<?xml version='1.0' encoding='UTF-8' standalone='no'?>
<!DOCTYPE cambalache-project SYSTEM "cambalache-project.dtd">
<cambalache-project version="0.17.3" target_tk="gtk-4.0">
<ui>
(7,1,"window.ui","src/window.ui",None,None,None,None,None,None,None)
</ui>
<ui_library>
(7,"Adw","1.0",None),
(7,"gio","2.0",None),
(7,"gtk","4.0",None),
(7,"libadwaita","1.4",None)
</ui_library>
<object>
(7,1,"AdwApplicationWindow","XimperUnifiedThemeSwitcherGuiGtk4Window",None,None,None,None,None,None,None),
(7,2,"AdwToolbarView",None,1,None,None,None,None,None,None),
(7,3,"GtkBox",None,2,None,None,None,None,None,None),
(7,4,"GtkBox",None,3,None,None,None,None,None,None),
(7,5,"GtkButton","change_style_btn",4,None,None,None,None,None,None),
(7,6,"GtkBox",None,5,None,None,None,None,None,None),
(7,7,"GtkImage",None,6,None,None,None,None,None,None),
(7,8,"GtkLabel",None,6,None,None,None,1,None,None),
(7,9,"GtkBox",None,3,None,None,None,1,None,None),
(7,10,"GtkBox",None,9,None,None,None,None,None,None),
(7,11,"GtkLabel",None,10,None,None,None,None,None,None),
(7,12,"GtkListBox",None,10,None,None,None,1,None,None),
(7,13,"AdwComboRow","kv_light_cr",12,None,None,None,None,None,None),
(7,14,"AdwComboRow","kv_dark_cr",12,None,None,None,1,None,None),
(7,15,"GtkBox",None,9,None,None,None,1,None,None),
(7,16,"GtkLabel",None,15,None,None,None,None,None,None),
(7,17,"GtkListBox",None,15,None,None,None,1,None,None),
(7,18,"AdwComboRow","gtk3_light_cr",17,None,None,None,None,None,None),
(7,19,"AdwComboRow","gtk3_dark_cr",17,None,None,None,1,None,None),
(7,20,"AdwHeaderBar","header_bar",2,None,"top",None,1,None,None),
(7,21,"GtkMenuButton",None,20,None,"end",None,None,None,None),
(7,22,"(menu)","primary_menu",None,None,None,None,None,None,None),
(7,23,"(section)",None,22,None,None,None,None,None,None),
(7,24,"(item)",None,23,None,None,None,None,None,None),
(7,25,"(item)",None,23,None,None,None,1,None,None),
(7,26,"(item)",None,23,None,None,None,2,None,None)
</object>
<object_property>
(7,1,"AdwApplicationWindow","content",None,None,None,None,None,2,None,None,None,None),
(7,1,"GtkWindow","default-height","300",None,None,None,None,None,None,None,None,None),
(7,1,"GtkWindow","default-width","600",None,None,None,None,None,None,None,None,None),
(7,3,"GtkOrientable","orientation","vertical",None,None,None,None,None,None,None,None,None),
(7,3,"GtkWidget","margin-end","15",None,None,None,None,None,None,None,None,None),
(7,3,"GtkWidget","margin-start","15",None,None,None,None,None,None,None,None,None),
(7,3,"GtkWidget","valign","start",None,None,None,None,None,None,None,None,None),
(7,4,"GtkOrientable","orientation","vertical",None,None,None,None,None,None,None,None,None),
(7,4,"GtkWidget","valign","center",None,None,None,None,None,None,None,None,None),
(7,5,"GtkWidget","halign","center",None,None,None,None,None,None,None,None,None),
(7,5,"GtkWidget","height-request","80",None,None,None,None,None,None,None,None,None),
(7,5,"GtkWidget","hexpand","True",None,None,None,None,None,None,None,None,None),
(7,5,"GtkWidget","width-request","80",None,None,None,None,None,None,None,None,None),
(7,6,"GtkOrientable","orientation","vertical",None,None,None,None,None,None,None,None,None),
(7,7,"GtkImage","icon-name","ru.ximperlinux.UnifiedThemeSwitcher",None,None,None,None,None,None,None,None,None),
(7,7,"GtkImage","icon-size","large",None,None,None,None,None,None,None,None,None),
(7,7,"GtkImage","pixel-size","70",None,None,None,None,None,None,None,None,None),
(7,7,"GtkWidget","margin-bottom","5",None,None,None,None,None,None,None,None,None),
(7,7,"GtkWidget","margin-end","5",None,None,None,None,None,None,None,None,None),
(7,7,"GtkWidget","margin-start","5",None,None,None,None,None,None,None,None,None),
(7,7,"GtkWidget","margin-top","5",None,None,None,None,None,None,None,None,None),
(7,8,"GtkLabel","justify","center",None,None,None,None,None,None,None,None,None),
(7,8,"GtkLabel","label","Change style",1,None,None,None,None,None,None,None,None),
(7,8,"GtkWidget","halign","center",None,None,None,None,None,None,None,None,None),
(7,8,"GtkWidget","valign","center",None,None,None,None,None,None,None,None,None),
(7,10,"GtkOrientable","orientation","vertical",None,None,None,None,None,None,None,None,None),
(7,10,"GtkWidget","margin-bottom","5",None,None,None,None,None,None,None,None,None),
(7,10,"GtkWidget","margin-end","5",None,None,None,None,None,None,None,None,None),
(7,10,"GtkWidget","margin-start","5",None,None,None,None,None,None,None,None,None),
(7,10,"GtkWidget","margin-top","5",None,None,None,None,None,None,None,None,None),
(7,11,"GtkLabel","label","Kvantum",None,None,None,None,None,None,None,None,None),
(7,11,"GtkWidget","margin-bottom","8",None,None,None,None,None,None,None,None,None),
(7,12,"GtkListBox","selection-mode","none",None,None,None,None,None,None,None,None,None),
(7,12,"GtkWidget","hexpand","True",None,None,None,None,None,None,None,None,None),
(7,13,"AdwPreferencesRow","title","_Light theme",1,None,None,None,None,None,None,None,None),
(7,13,"AdwPreferencesRow","use-underline","True",None,None,None,None,None,None,None,None,None),
(7,13,"GtkWidget","hexpand","True",None,None,None,None,None,None,None,None,None),
(7,13,"GtkWidget","width-request","100",None,None,None,None,None,None,None,None,None),
(7,14,"AdwPreferencesRow","title","_Dark theme",1,None,None,None,None,None,None,None,None),
(7,14,"AdwPreferencesRow","use-underline","True",None,None,None,None,None,None,None,None,None),
(7,14,"GtkWidget","hexpand","True",None,None,None,None,None,None,None,None,None),
(7,14,"GtkWidget","width-request","100",None,None,None,None,None,None,None,None,None),
(7,15,"GtkOrientable","orientation","vertical",None,None,None,None,None,None,None,None,None),
(7,15,"GtkWidget","margin-bottom","5",None,None,None,None,None,None,None,None,None),
(7,15,"GtkWidget","margin-end","5",None,None,None,None,None,None,None,None,None),
(7,15,"GtkWidget","margin-start","5",None,None,None,None,None,None,None,None,None),
(7,15,"GtkWidget","margin-top","5",None,None,None,None,None,None,None,None,None),
(7,16,"GtkLabel","label","GTK3",None,None,None,None,None,None,None,None,None),
(7,16,"GtkWidget","margin-bottom","8",None,None,None,None,None,None,None,None,None),
(7,17,"GtkListBox","selection-mode","none",None,None,None,None,None,None,None,None,None),
(7,17,"GtkWidget","hexpand","True",None,None,None,None,None,None,None,None,None),
(7,18,"AdwPreferencesRow","title","_Light theme",1,None,None,None,None,None,None,None,None),
(7,18,"AdwPreferencesRow","use-underline","True",None,None,None,None,None,None,None,None,None),
(7,18,"GtkWidget","hexpand","True",None,None,None,None,None,None,None,None,None),
(7,18,"GtkWidget","width-request","100",None,None,None,None,None,None,None,None,None),
(7,19,"AdwPreferencesRow","title","_Dark theme",1,None,None,None,None,None,None,None,None),
(7,19,"AdwPreferencesRow","use-underline","True",None,None,None,None,None,None,None,None,None),
(7,19,"GtkWidget","hexpand","True",None,None,None,None,None,None,None,None,None),
(7,19,"GtkWidget","width-request","100",None,None,None,None,None,None,None,None,None),
(7,21,"GtkMenuButton","icon-name","open-menu-symbolic",None,None,None,None,None,None,None,None,None),
(7,21,"GtkMenuButton","menu-model","22",None,None,None,None,None,None,None,None,None),
(7,21,"GtkMenuButton","primary","True",None,None,None,None,None,None,None,None,None),
(7,21,"GtkWidget","tooltip-text","Menu",1,None,None,None,None,None,None,None,None),
(7,24,"(item)","action","app.preferences",None,None,None,None,None,None,None,None,None),
(7,24,"(item)","label","_Preferences",1,None,None,None,None,None,None,None,None),
(7,25,"(item)","action","win.show-help-overlay",None,None,None,None,None,None,None,None,None),
(7,25,"(item)","label","_Keyboard Shortcuts",1,None,None,None,None,None,None,None,None),
(7,26,"(item)","action","app.about",None,None,None,None,None,None,None,None,None),
(7,26,"(item)","label","_About Ximper-unified-theme-switcher-gui",1,None,None,None,None,None,None,None,None)
</object_property>
<object_data>
(7,12,"GtkWidget",1,1,None,None,None,None,None,None),
(7,12,"GtkWidget",2,2,None,1,None,None,None,None),
(7,17,"GtkWidget",1,1,None,None,None,None,None,None),
(7,17,"GtkWidget",2,2,None,1,None,None,None,None)
</object_data>
<object_data_arg>
(7,12,"GtkWidget",2,2,"name","boxed-list"),
(7,17,"GtkWidget",2,2,"name","boxed-list")
</object_data_arg>
</cambalache-project>
[Unit]
Description=Ximper unified theme switcher
Description=Ximper unified theme switcher
StartLimitInterval=500
StartLimitBurst=5
......@@ -8,3 +8,6 @@ ExecStartPre=/bin/sleep 2
ExecStart=/usr/bin/ximper-unified-theme-switcher-service
Restart=on-failure
RestartSec=1
[Install]
WantedBy=default.target
\ No newline at end of file
prefix = get_option('prefix')
sysconfdir = join_paths(prefix, get_option('sysconfdir'))
install_data(
'./bin/ximper-unified-theme-switcher-service',
install_dir: get_option('bindir'),
install_mode: 'r-xr-xr-x'
)
install_data(
'./data/ximper-unified-theme-switcher.service',
install_dir: join_paths(prefix, 'lib', 'systemd', 'user')
)
cfg_dir = join_paths(sysconfdir, 'ximper-unified-theme-switcher')
install_data(
'./ximper_distro_conf/themes',
install_dir: cfg_dir
)
message('Created directory: ' + cfg_dir)
KV_LIGHT_THEME=KvGnome
KV_DARK_THEME=KvGnomeDark
GTK3_LIGHT_THEME=adw-gtk3
GTK3_DARK_THEME=adw-gtk3-dark
<?xml version="1.0" encoding="UTF-8"?>
<interface>
<object class="GtkShortcutsWindow" id="help_overlay">
<property name="modal">True</property>
<child>
<object class="GtkShortcutsSection">
<property name="section-name">shortcuts</property>
<property name="max-height">10</property>
<child>
<object class="GtkShortcutsGroup">
<property name="title" translatable="yes" context="shortcut window">General</property>
<child>
<object class="GtkShortcutsShortcut">
<property name="title" translatable="yes" context="shortcut window">Show Shortcuts</property>
<property name="action-name">win.show-help-overlay</property>
</object>
</child>
<child>
<object class="GtkShortcutsShortcut">
<property name="title" translatable="yes" context="shortcut window">Quit</property>
<property name="action-name">app.quit</property>
</object>
</child>
</object>
</child>
</object>
</child>
</object>
</interface>
# MIT License
#
# Copyright (c) 2024 Roman Alifanov
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in all
# copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
#
# SPDX-License-Identifier: MIT
import sys, os
import gi
gi.require_version('Gtk', '4.0')
gi.require_version('Adw', '1')
from gi.repository import Gtk, Gio, Adw
from .window import XimperUnifiedThemeSwitcherGuiGtk4Window
class XimperUnifiedThemeSwitcherGuiGtk4Application(Adw.Application):
"""The main application singleton class."""
def __init__(self):
super().__init__(application_id='ru.ximperlinux.UnifiedThemeSwitcher',
flags=Gio.ApplicationFlags.DEFAULT_FLAGS)
self.create_action('quit', lambda *_: self.quit(), ['<primary>q'])
self.create_action('about', self.on_about_action)
self.create_action('preferences', self.on_preferences_action)
def do_activate(self):
"""Called when the application is activated.
We raise the application's main window, creating it if
necessary.
"""
win = self.props.active_window
if not win:
win = XimperUnifiedThemeSwitcherGuiGtk4Window(application=self)
win.present()
def on_about_action(self, widget, _):
"""Callback for the app.about action."""
about = Adw.AboutWindow(transient_for=self.props.active_window,
application_name='Ximper\nUnified Theme Switcher\nGUI',
application_icon='ru.ximperlinux.UnifiedThemeSwitcher',
developer_name='Ximper Linux',
version='0.1.0',
developers=['Ximper', 'Fiersik'],
issue_url="https://gitlab.eterfund.ru/ximperlinux/ximper-unified-theme-switcher/issues",
website="https://gitlab.eterfund.ru/ximperlinux/ximper-unified-theme-switcher",
copyright='© 2024 Etersoft')
about.present()
def on_preferences_action(self, widget, _):
"""Callback for the app.preferences action."""
print('app.preferences action activated')
def create_action(self, name, callback, shortcuts=None):
"""Add an application action.
Args:
name: the name of the action
callback: the function to be called when the action is
activated
shortcuts: an optional list of accelerators
"""
action = Gio.SimpleAction.new(name, None)
action.connect("activate", callback)
self.add_action(action)
if shortcuts:
self.set_accels_for_action(f"app.{name}", shortcuts)
def main(version):
"""The application's entry point."""
app = XimperUnifiedThemeSwitcherGuiGtk4Application()
return app.run(sys.argv)
pkgdatadir = get_option('prefix') / get_option('datadir') / meson.project_name()
moduledir = pkgdatadir / 'ximper_unified_theme_switcher_gui_gtk4'
gnome = import('gnome')
gnome.compile_resources('ximper-unified-theme-switcher-gui',
'ximper-unified-theme-switcher-gui.gresource.xml',
gresource_bundle: true,
install: true,
install_dir: pkgdatadir,
)
python = import('python')
conf = configuration_data()
conf.set('PYTHON', python.find_installation('python3').full_path())
conf.set('VERSION', meson.project_version())
conf.set('localedir', get_option('prefix') / get_option('localedir'))
conf.set('pkgdatadir', pkgdatadir)
configure_file(
input: 'ximper-unified-theme-switcher-gui.in',
output: 'ximper-unified-theme-switcher-gui',
configuration: conf,
install: true,
install_dir: get_option('bindir'),
install_mode: 'r-xr-xr-x'
)
ximper_unified_theme_switcher_gui_gtk4_sources = [
'__init__.py',
'main.py',
'window.py',
'utils.py',
]
install_data(ximper_unified_theme_switcher_gui_gtk4_sources, install_dir: moduledir)
import sys, os, re
import subprocess
import functools
import gi
gi.require_version('Gtk', '4.0')
gi.require_version('Adw', '1')
from gi.repository import Gtk
SYSTEM_CONFIG_DIR = "/etc/ximper-unified-theme-switcher"
SYSTEM_CONFIG_FILE = os.path.join(SYSTEM_CONFIG_DIR, "themes")
HOME_CONFIG_DIR = os.path.join(os.path.expanduser("~/.config/ximper-unified-theme-switcher"))
HOME_CONFIG_FILE = os.path.join(HOME_CONFIG_DIR, "themes")
def create_config():
try:
if os.geteuid() == 0:
os.makedirs(SYSTEM_CONFIG_DIR, exist_ok=True)
open(SYSTEM_CONFIG_FILE, 'a').close()
return SYSTEM_CONFIG_FILE
else:
os.makedirs(HOME_CONFIG_DIR, exist_ok=True)
open(HOME_CONFIG_FILE, 'a').close()
return HOME_CONFIG_FILE
except Exception as e:
print(f"Error creating config file: {e}")
return None
def cfg_check():
try:
if os.path.isfile(SYSTEM_CONFIG_FILE) and os.access(SYSTEM_CONFIG_FILE, os.W_OK):
return SYSTEM_CONFIG_FILE
elif os.path.isfile(HOME_CONFIG_FILE):
return HOME_CONFIG_FILE
else:
return create_config()
except Exception as e:
print(f"Error checking config file: {e}")
return None
def read_config(key):
with open(cfg_check(), 'r') as file:
for line in file:
line = line.strip()
if line:
k, v = line.split('=')
if k.strip() == key:
return v.strip()
def write_config(key, value):
config_file = cfg_check()
lines = []
with open(config_file, 'r') as file:
lines = file.readlines()
with open(config_file, 'w') as file:
found = False
for line in lines:
if line.strip():
k, v = line.split('=')
if k.strip() == key:
file.write(f"{key}={value}\n")
found = True
else:
file.write(line)
else:
file.write(line)
if not found:
file.write(f"{key}={value}\n")
def make_gtk3_themes_list():
themes_dirs = [
"/usr/share/themes/",
os.path.expanduser("~/.themes/"),
os.path.expanduser("~/.local/share/themes/")
]
themes_list = []
for themes_dir in themes_dirs:
if os.path.exists(themes_dir) and os.listdir(themes_dir):
themes = os.listdir(themes_dir)
for theme in themes:
themes_list.append(theme)
return themes_list
def make_kv_themes_list():
themes_dirs = [
"/usr/share/color-schemes/"
]
themes_list = []
for themes_dir in themes_dirs:
if os.path.exists(themes_dir) and os.listdir(themes_dir):
themes = os.listdir(themes_dir)
for theme in themes:
if theme.startswith("Kv"):
theme_name = re.sub(r'\.colors$', '', theme)
themes_list.append(theme_name)
return themes_list
def find_string_index(lst, string):
try:
index = lst.index(string)
return index
except ValueError:
return 0
def configure_cr_widgets(crs_configurations, selected_func):
for cr, themes_list, config_key in crs_configurations:
model = Gtk.StringList()
for theme in themes_list:
model.append(theme)
cr.set_model(model)
cr.set_selected(find_string_index(
themes_list,
read_config(config_key))
)
cr.connect(
'notify::selected-item',
functools.partial(
selected_func,
cfg_key=config_key
)
)
def service_status(service_name):
try:
# Запускаем команду systemctl is-active <service_name>
result = subprocess.run(['systemctl', 'is-active', service_name], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
# Проверяем статус
if result.stdout.decode('utf-8').strip() == 'active':
return True
else:
return False
except Exception as e:
print(f"An error occurred: {e}")
return False
# MIT License
#
# Copyright (c) 2024 Unknown
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in all
# copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
#
# SPDX-License-Identifier: MIT
from .utils import write_config, configure_cr_widgets
from .utils import make_gtk3_themes_list, make_kv_themes_list
from gi.repository import Adw
from gi.repository import Gtk, Gio
@Gtk.Template(resource_path='/ru/ximperlinux/UnifiedThemeSwitcher/window.ui')
class XimperUnifiedThemeSwitcherGuiGtk4Window(Adw.ApplicationWindow):
__gtype_name__ = 'XimperUnifiedThemeSwitcherGuiGtk4Window'
kv_light_cr = Gtk.Template.Child()
kv_dark_cr = Gtk.Template.Child()
gtk3_light_cr = Gtk.Template.Child()
gtk3_dark_cr = Gtk.Template.Child()
change_style_btn = Gtk.Template.Child()
def __init__(self, **kwargs):
super().__init__(**kwargs)
self.change_style_btn.connect('clicked', self.change_style)
kv_themes_list = make_kv_themes_list()
gtk3_themes_list = make_gtk3_themes_list()
crs_configurations = [
(self.kv_light_cr, kv_themes_list, "KV_LIGHT_THEME"),
(self.kv_dark_cr, kv_themes_list, "KV_DARK_THEME"),
(self.gtk3_light_cr, gtk3_themes_list, "GTK3_LIGHT_THEME"),
(self.gtk3_dark_cr, gtk3_themes_list, "GTK3_DARK_THEME")
]
configure_cr_widgets(crs_configurations, self.cr_theme_selected)
def cr_theme_selected(self, cr, _pspec, cfg_key):
cfg_new_value = cr.props.selected_item.props.string
if cfg_new_value is not None and cfg_key is not None:
print(f"For {cfg_key} selected {cfg_new_value}")
write_config(cfg_key, cfg_new_value)
def change_style(self, _button):
schema = 'org.gnome.desktop.interface'
key = 'color-scheme'
# Получить текущее значение color-scheme
settings = Gio.Settings.new(schema)
current_theme = settings.get_string(key)
# Установить новое значение color-scheme
if current_theme == 'default':
style = 'prefer-dark'
else:
style = 'default'
settings.set_string(key, style)
print(f"Color scheme changed to: {style}")
<?xml version='1.0' encoding='UTF-8'?>
<!-- Created with Cambalache 0.90.4 -->
<interface>
<!-- interface-name window.ui -->
<requires lib="Adw" version="1.0"/>
<requires lib="gio" version="2.0"/>
<requires lib="gtk" version="4.0"/>
<requires lib="libadwaita" version="1.4"/>
<template class="XimperUnifiedThemeSwitcherGuiGtk4Window" parent="AdwApplicationWindow">
<property name="content">
<object class="AdwToolbarView">
<child>
<object class="GtkBox">
<property name="margin-end">15</property>
<property name="margin-start">15</property>
<property name="orientation">vertical</property>
<property name="valign">start</property>
<child>
<object class="GtkBox">
<property name="orientation">vertical</property>
<property name="valign">center</property>
<child>
<object class="GtkButton" id="change_style_btn">
<property name="halign">center</property>
<property name="height-request">80</property>
<property name="hexpand">True</property>
<property name="width-request">80</property>
<child>
<object class="GtkBox">
<property name="orientation">vertical</property>
<child>
<object class="GtkImage">
<property name="icon-name">ru.ximperlinux.UnifiedThemeSwitcher</property>
<property name="icon-size">large</property>
<property name="margin-bottom">5</property>
<property name="margin-end">5</property>
<property name="margin-start">5</property>
<property name="margin-top">5</property>
<property name="pixel-size">70</property>
</object>
</child>
<child>
<object class="GtkLabel">
<property name="halign">center</property>
<property name="justify">center</property>
<property name="label" translatable="yes">Change style</property>
<property name="valign">center</property>
</object>
</child>
</object>
</child>
</object>
</child>
</object>
</child>
<child>
<object class="GtkBox">
<child>
<object class="GtkBox">
<property name="margin-bottom">5</property>
<property name="margin-end">5</property>
<property name="margin-start">5</property>
<property name="margin-top">5</property>
<property name="orientation">vertical</property>
<child>
<object class="GtkLabel">
<property name="label">Kvantum</property>
<property name="margin-bottom">8</property>
</object>
</child>
<child>
<object class="GtkListBox">
<property name="hexpand">True</property>
<property name="selection-mode">none</property>
<child>
<object class="AdwComboRow" id="kv_light_cr">
<property name="hexpand">True</property>
<property name="title" translatable="yes">_Light theme</property>
<property name="use-underline">True</property>
<property name="width-request">100</property>
</object>
</child>
<child>
<object class="AdwComboRow" id="kv_dark_cr">
<property name="hexpand">True</property>
<property name="title" translatable="yes">_Dark theme</property>
<property name="use-underline">True</property>
<property name="width-request">100</property>
</object>
</child>
<style>
<class name="boxed-list"/>
</style>
</object>
</child>
</object>
</child>
<child>
<object class="GtkBox">
<property name="margin-bottom">5</property>
<property name="margin-end">5</property>
<property name="margin-start">5</property>
<property name="margin-top">5</property>
<property name="orientation">vertical</property>
<child>
<object class="GtkLabel">
<property name="label">GTK3</property>
<property name="margin-bottom">8</property>
</object>
</child>
<child>
<object class="GtkListBox">
<property name="hexpand">True</property>
<property name="selection-mode">none</property>
<child>
<object class="AdwComboRow" id="gtk3_light_cr">
<property name="hexpand">True</property>
<property name="title" translatable="yes">_Light theme</property>
<property name="use-underline">True</property>
<property name="width-request">100</property>
</object>
</child>
<child>
<object class="AdwComboRow" id="gtk3_dark_cr">
<property name="hexpand">True</property>
<property name="title" translatable="yes">_Dark theme</property>
<property name="use-underline">True</property>
<property name="width-request">100</property>
</object>
</child>
<style>
<class name="boxed-list"/>
</style>
</object>
</child>
</object>
</child>
</object>
</child>
</object>
</child>
<child type="top">
<object class="AdwHeaderBar" id="header_bar">
<child type="end">
<object class="GtkMenuButton">
<property name="icon-name">open-menu-symbolic</property>
<property name="menu-model">primary_menu</property>
<property name="primary">True</property>
<property name="tooltip-text" translatable="yes">Menu</property>
</object>
</child>
</object>
</child>
</object>
</property>
<property name="default-height">300</property>
<property name="default-width">600</property>
</template>
<menu id="primary_menu">
<section>
<item>
<attribute name="action">app.preferences</attribute>
<attribute name="label" translatable="yes">_Preferences</attribute>
</item>
<item>
<attribute name="action">win.show-help-overlay</attribute>
<attribute name="label" translatable="yes">_Keyboard Shortcuts</attribute>
</item>
<item>
<attribute name="action">app.about</attribute>
<attribute name="label" translatable="yes">_About Ximper Unified Theme Switcher</attribute>
</item>
</section>
</menu>
</interface>
<?xml version="1.0" encoding="UTF-8"?>
<gresources>
<gresource prefix="/ru/ximperlinux/UnifiedThemeSwitcher">
<file preprocess="xml-stripblanks">window.ui</file>
<file preprocess="xml-stripblanks">gtk/help-overlay.ui</file>
</gresource>
</gresources>
#!@PYTHON@
# MIT License
#
# Copyright (c) 2024 Roman Alifanov
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in all
# copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
#
# SPDX-License-Identifier: MIT
import os
import sys
import signal
import locale
import gettext
VERSION = '@VERSION@'
pkgdatadir = '@pkgdatadir@'
localedir = '@localedir@'
sys.path.insert(1, pkgdatadir)
signal.signal(signal.SIGINT, signal.SIG_DFL)
locale.bindtextdomain('ximper-unified-theme-switcher-gui', localedir)
locale.textdomain('ximper-unified-theme-switcher-gui')
gettext.install('ximper-unified-theme-switcher-gui', localedir)
if __name__ == '__main__':
import gi
from gi.repository import Gio
resource = Gio.Resource.load(os.path.join(pkgdatadir, 'ximper-unified-theme-switcher-gui.gresource'))
resource._register()
from ximper_unified_theme_switcher_gui_gtk4 import main
sys.exit(main.main(VERSION))
......@@ -8,13 +8,16 @@ Summary: Unified theme switcher for Ximper linux
Group: System/Configuration/Other
Url: https://gitlab.eterfund.ru/ximperlinux/ximper-unified-theme-switcher
Vcs: https://gitlab.eterfund.ru/ximperlinux/ximper-unified-theme-switcher.git
BuildArch: noarch
Source: %name-%version.tar
BuildRequires(pre): rpm-macros-make rpm-macros-systemd
BuildRequires(pre): rpm-macros-meson rpm-macros-systemd
BuildRequires(pre): rpm-build-python3
BuildRequires(pre): rpm-build-gir
BuildRequires: libadwaita-gir-devel
BuildRequires: meson
Requires: Kvantum libgio
%description
......@@ -24,7 +27,6 @@ Requires: Kvantum libgio
Summary: GUI for Ximper unified theme switcher
Group: System/Configuration/Other
Requires: %name = %version-%release
Requires: yad
%description gui
GUI for Ximper unified theme switcher.
......@@ -32,15 +34,30 @@ GUI for Ximper unified theme switcher.
%prep
%setup
%build
%meson
%meson_build
%install
%makeinstall
%meson_install
%find_lang ximper-unified-theme-switcher-gui
%files
%_bindir/ximper-unified-theme-switcher-service
%_userunitdir/ximper-unified-theme-switcher.service
%_user_unitdir/ximper-unified-theme-switcher.service
%dir %_sysconfdir/ximper-unified-theme-switcher
%files gui
%files gui -f ximper-unified-theme-switcher-gui.lang
%_bindir/ximper-unified-theme-switcher-gui
%_desktopdir/%name-gui.desktop
%_datadir/ximper-unified-theme-switcher-gui
%_datadir/glib-2.0/schemas/*.gschema.xml
%_datadir/metainfo/*.metainfo.xml
%_desktopdir/ru.ximperlinux.UnifiedThemeSwitcher.desktop
%_iconsdir/hicolor/*/apps/*.svg
%changelog
* Thu Jul 11 2024 Roman Alifanov <ximper@altlinux.ru> 0.1.0-alt1
- initial build
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment