Name: raysession Version: 0.17.2 Release: 9%{?dist} Summary: Session manager for audio software License: GPL-2.0-only URL: https://github.com/Houston4444/RaySession Source0: %{url}/releases/download/v%{version}/RaySession-%{version}-source.tar.gz Source1: README-wayland Source2: GPL-2 Source3: qt6_app.1 Source4: xdg-wrapper.py Source5: raysession_xdg_compat.py BuildArch: noarch # Essential build dependencies BuildRequires: make BuildRequires: python3-pyqt6 BuildRequires: qt6-linguist BuildRequires: pkgconfig(Qt6Core) BuildRequires: pkgconfig(Qt6Gui) BuildRequires: pkgconfig(Qt6Widgets) BuildRequires: desktop-file-utils BuildRequires: help2man # Essential runtime dependencies Requires: python3 Requires: python3-alsa Requires: python3-pyliblo3 Requires: python3-pyxdg Requires: python-jack-client Requires: python3-pyqt6 Requires: python3-legacy-cgi Requires: python3-QtPy Requires: hicolor-icon-theme Requires: shared-mime-info %description Ray Session is a GNU/Linux session manager for audio programs as Ardour, Carla, QTractor, Non-Timeline, etc... It uses the same API as Non Session Manager, so programs compatible with NSM are also compatible with Ray Session. As Non Session Manager, the principle is to load together audio programs, then be able to save or close all documents together. Ray Session offers a little more: - Factory templates for NSM and LASH compatible applications - Possibility to save any client as template - Save session as template - Name files with a prettier way - remember if client was started or not - Abort session almost anytime - Change Main Folder of sessions on GUI - Possibility to KILL client if clean exit is too long - Open Session Folder button (open default file manager) Ray Session is being developed by houston4444, using Python3 and Qt5. %prep %autosetup -n RaySession-%{version} ## Add xdg wrapper for upstream compatibility cp %{SOURCE4} src/shared/xdg.py || true cp %{SOURCE1} ./ %build %set_build_flags # Find Qt6 rcc binary - on Fedora it lives in qt6 libexec, not in PATH RCC_BIN=$(which rcc-qt6 2>/dev/null \ || which rcc 2>/dev/null \ || find %{_libdir}/qt6 /usr/lib64/qt6 /usr/lib/qt6 -name rcc -type f 2>/dev/null | head -1 \ || echo rcc) make LRELEASE=lrelease-qt6 RCC="$RCC_BIN" %{?_smp_mflags} %install %make_install PREFIX=%{_prefix} # buildroot shortcut and helper to reduce repetition BR=%{buildroot} ensure_dirs() { mkdir -p "$@" || true; } # Common path shortcuts for readability DATADIR="$BR%{_datadir}/%{name}" PY_SITELIB="$BR%{python3_sitelib}" PY_LEGACY="$BR%{_prefix}/lib/python3.14/site-packages" ## Fix bash completion path if [ -f "%{buildroot}%{_sysconfdir}/bash_completion.d/ray_completion.sh" ]; then sed -i 's|^PY_FILE=.*|PY_FILE=/usr/share/raysession/src/completion|' "%{buildroot}%{_sysconfdir}/bash_completion.d/ray_completion.sh" sed -i '1{/^#!/d}' "%{buildroot}%{_sysconfdir}/bash_completion.d/ray_completion.sh" chmod -x "%{buildroot}%{_sysconfdir}/bash_completion.d/ray_completion.sh" || true fi ## Rewrite symlinks to remove buildroot prefix if [ -d "%{buildroot}" ]; then find "%{buildroot}" -type l | while read -r l; do tgt=$(readlink "$l" || true) case "$tgt" in "%{buildroot}"*) newt=${tgt#%{buildroot}} ln -nfs "$newt" "$l" ;; esac done fi ## Remove empty files from data tree if [ -d "$DATADIR" ]; then find "$DATADIR" -type f -empty -delete || true fi ## Make entry-point scripts executable if [ -d "%{buildroot}%{_bindir}" ]; then find "%{buildroot}%{_bindir}" -type f -exec grep -Il '^#!' '{}' ';' | xargs --no-run-if-empty chmod +x || true fi if [ -d "%{buildroot}%{_datadir}/%{name}/src/bin" ]; then find "%{buildroot}%{_datadir}/%{name}/src/bin" -type f -exec grep -Il '^#!' '{}' ';' | xargs --no-run-if-empty chmod +x || true fi if [ -d "%{buildroot}%{_datadir}/%{name}/data/bin" ]; then find "%{buildroot}%{_datadir}/%{name}/data/bin" -type f -exec grep -Il '^#!' '{}' ';' | xargs --no-run-if-empty chmod +x || true fi ## Make completion script non-executable if [ -f "%{buildroot}%{_datadir}/%{name}/src/completion/ray_completion.sh" ]; then sed -i '1{/^#!/d}' "%{buildroot}%{_datadir}/%{name}/src/completion/ray_completion.sh" chmod -x "%{buildroot}%{_datadir}/%{name}/src/completion/ray_completion.sh" || true fi ## Remove shebangs from Python modules (not bin) if [ -d "%{buildroot}%{_datadir}/%{name}" ]; then find "%{buildroot}%{_datadir}/%{name}" -type f -name '*.py' \ ! -path '*/src/bin/*' ! -path '*/data/bin/*' -exec sed -i '1{/^#!/d}' '{}' ';' || true fi ## Fix shebang typos in bin scripts if [ -d "%{buildroot}%{_datadir}/%{name}/src/bin" ]; then find "%{buildroot}%{_datadir}/%{name}/src/bin" -type f -exec sed -i 's|^#\!*/usr/bin env python3|#!/usr/bin/env python3|' '{}' ';' || true fi ## Make session/jack config scripts executable for d in "%{buildroot}%{_datadir}/%{name}/session_scripts" "%{buildroot}%{_datadir}/%{name}/src/jack_config_script"; do if [ -d "$d" ]; then find "$d" -type f -exec grep -Il '^#!' '{}' ';' | xargs --no-run-if-empty chmod +x || true fi done ## Remove compiled resource bytecode and other Python bytecode find "$DATADIR" -type f \( -name '*resources_rc*.pyc' -o -name '*.pyc' \) -delete || true find "$DATADIR" -type d -name '__pycache__' -exec rm -rf '{}' + || true ## Remove upstream hidden files find "%{buildroot}%{_datadir}/%{name}" -type f \( -name '.directory' -o -name '.jack_config_script' \) -delete || true ## Install GPL-2 as COPYING mkdir -p "%{buildroot}%{_datadir}/licenses/%{name}" || true if [ -f "%{SOURCE2}" ]; then cp -p "%{SOURCE2}" "%{buildroot}%{_datadir}/licenses/%{name}/COPYING" || true fi if [ -f "%{buildroot}%{_datadir}/licenses/%{name}/COPYING" ]; then chmod 644 "%{buildroot}%{_datadir}/licenses/%{name}/COPYING" || true fi ## Symlink /usr/bin for packaged executables if [ -d "%{buildroot}%{_datadir}/%{name}/src/bin" ]; then for f in $(cd "%{buildroot}%{_datadir}/%{name}/src/bin" && ls -1); do name=$(basename "$f") linkname=${name%%.*} if [ "$linkname" = "$name" ]; then ln -nfs ../share/%{name}/src/bin/"$f" "%{buildroot}%{_bindir}/$name" || true else ln -nfs ../share/%{name}/src/bin/"$f" "%{buildroot}%{_bindir}/$linkname" || true fi done fi mkdir -p "%{buildroot}%{_mandir}/man1" ## Generate manpages with help2man or stub if [ -d "%{buildroot}%{_bindir}" ]; then for f in $(cd "%{buildroot}%{_bindir}" && ls -1); do b=$(basename "$f") out="%{buildroot}%{_mandir}/man1/${b}.1" mkdir -p "%{buildroot}%{_mandir}/man1" # Run help2man in a clean environment to avoid sourcing user profiles # or executing shell startup files. Use timeout to prevent long runs. env -i PATH=/usr/bin:/bin LC_ALL=C HOME=/dev/null \ timeout 5s help2man -N -n "RaySession helper" -o "$out" "%{buildroot}%{_bindir}/$b" >/dev/null 2>&1 || true # If help2man produced a file, gzip it. Otherwise create a minimal stub. if [ -f "$out" ]; then gzip -n -f "$out" || true else if [ -x "%{buildroot}%{_bindir}/$b" ]; then cat > "$out" <<'EOF' ." Manpage stub .TH %BNAME% 1 "$(date +%Y-%m-%d)" .SH NAME %BNAME% \- helper for RaySession .SH SYNOPSIS .B %BNAME% .SH DESCRIPTION Minimal manpage stub for %BNAME%. EOF # substitute the binary name safely sed -i "s/%BNAME%/$b/g" "$out" || true gzip -n -f "$out" || true fi fi done fi ## Add .pth for Python import path ensure_dirs "$PY_SITELIB" "$PY_LEGACY" cat > "$PY_SITELIB/raysession.pth" <<'EOF' /usr/share/raysession/src/gui /usr/share/raysession/HoustonPatchbay/source /usr/share/raysession/src/shared /usr/share/raysession/src EOF chmod 644 "$PY_SITELIB/raysession.pth" || true cp -p "$PY_SITELIB/raysession.pth" "$PY_LEGACY/raysession.pth" || true chmod 644 "$PY_LEGACY/raysession.pth" || true ## Install xdg compat shim if present if [ -f "%{SOURCE5}" ]; then ensure_dirs "$PY_SITELIB" "$PY_LEGACY" for dst in "$PY_SITELIB" "$PY_LEGACY"; do cp -p "%{SOURCE5}" "$dst/raysession_xdg_compat.py" || true printf '%s\n' 'import raysession_xdg_compat' > "$dst/raysession_xdg_compat.pth" || true chmod 644 "$dst/raysession_xdg_compat.py" "$dst/raysession_xdg_compat.pth" || true done fi ## Remove __pycache__ from site-packages rm -rf "$PY_LEGACY/__pycache__" || true rm -rf "$PY_SITELIB/__pycache__" || true ## Copy .pth for older Python envs ensure_dirs "$BR%{_prefix}/lib/python3.14/site-packages" cp -p "$BR%{python3_sitelib}/raysession.pth" "$BR%{_prefix}/lib/python3.14/site-packages/raysession.pth" || true chmod 644 "$BR%{_prefix}/lib/python3.14/site-packages/raysession.pth" || true ## Patch patchcanvas __init__ to avoid circular import PC_INIT="%{buildroot}%{_datadir}/%{name}/HoustonPatchbay/source/patchbay/patchcanvas/__init__.py" if [ -f "$PC_INIT" ]; then cat > "$PC_INIT" <<'PYSC' from . import patchcanvas as patchcanvas from . import xdg as xdg from .patchcanvas import * PYSC chmod 644 "$PC_INIT" || true fi ## Patch HoustonPatchbay __init__ for lazy loading PB_INIT="%{buildroot}%{_datadir}/%{name}/HoustonPatchbay/source/patchbay/__init__.py" if [ -f "$PB_INIT" ]; then # Write a lazy-loading package __init__ that exports the names # expected by upstream but performs imports only when attributes # are accessed to avoid circular import problems at package import # time. This modifies files staged in the buildroot only. cat > "$PB_INIT" <<'PYPB' import sys from pathlib import Path import importlib # Insert parent dir so subpackages import as upstream expects sys.path.insert(1, str(Path(__file__).parents[1])) _lazy = { "PatchbayManager": ("patchbay_manager", "PatchbayManager"), "patchcanvas": ("patchcanvas", None), "Port": ("bases.port", "Port"), "Portgroup": ("bases.portgroup", "Portgroup"), "Connection": ("bases.connection", "Connection"), "Group": ("bases.group", "Group"), "Callbacker": ("calbacker", "Callbacker"), "PatchbayToolsWidget": ("tools_widgets", "PatchbayToolsWidget"), "CanvasPortInfoDialog": ("dialogs.port_info_dialog", "CanvasPortInfoDialog"), "CanvasMenu": ("menus.canvas_menu", "CanvasMenu"), "CanvasOptionsDialog": ("dialogs.options_dialog", "CanvasOptionsDialog"), "FilterFrame": ("widgets.filter_frame", "FilterFrame"), "PatchGraphicsView": ("patchcanvas.scene_view", "PatchGraphicsView"), } __all__ = list(_lazy.keys()) def __getattr__(name): if name in _lazy: modname, attr = _lazy[name] # Import relative to this package to preserve upstream semantics mod = importlib.import_module(f".{modname}", package=__name__) if attr: return getattr(mod, attr) return mod raise AttributeError(f"module {__name__} has no attribute {name}") PYPB chmod 644 "$PB_INIT" || true fi ## Create minimal resources_rc stubs for import PB_RES="%{buildroot}%{_datadir}/%{name}/HoustonPatchbay/source/patchbay/resources_rc.py" GUI_RES="%{buildroot}%{_datadir}/%{name}/src/gui/resources_rc.py" mkdir -p "$(dirname "$PB_RES")" || true mkdir -p "$(dirname "$GUI_RES")" || true if [ ! -f "$PB_RES" ]; then cat > "$PB_RES" <<'PYR' # Stub resources_rc to satisfy imports during runtime; actual icons are # provided under the package data directory's resources and the generated # Qt resources file may be created upstream. This fallback keeps imports # from failing during CLI smoke tests. try: # support older PyQt resource style if needed pass except Exception: pass PYR chmod 644 "$PB_RES" || true fi if [ ! -f "$GUI_RES" ]; then cat > "$GUI_RES" <<'PYR' # Stub top-level GUI resources_rc; real resources live under the # packaged resources directory and the generated module may be used # by the GUI when available. try: pass except Exception: pass PYR chmod 644 "$GUI_RES" || true fi ## Remove bundled xdg helpers (use system) rm -f "%{buildroot}%{_datadir}/%{name}/src/shared/xdg.py" || true rm -f "%{buildroot}%{_datadir}/%{name}/HoustonPatchbay/source/patchbay/xdg.py" || true # If we prepared a compatibility wrapper in the workspace, install it into # the staged source so the packaged files provide the top-level helpers # expected by upstream code (avoids runtime AttributeError calling # `xdg.xdg_data_home()` while still depending on `python3-pyxdg`). # Reference the wrapper via its Source macro to keep usage consistent. if [ -f "%{SOURCE4}" ]; then mkdir -p "%{buildroot}%{_datadir}/%{name}/src/shared" || true cp -p "%{SOURCE4}" "%{buildroot}%{_datadir}/%{name}/src/shared/xdg.py" || true chmod 644 "%{buildroot}%{_datadir}/%{name}/src/shared/xdg.py" || true fi ## Mark HoustonPatchbay loader for clarity if [ -f "%{buildroot}%{_datadir}/%{name}/HoustonPatchbay/source/patchbay/resources_rc.py" ]; then sed -i '1i# HoustonPatchbay resource loader' "%{buildroot}%{_datadir}/%{name}/HoustonPatchbay/source/patchbay/resources_rc.py" || true fi ## Regenerate resources_rc.py from .qrc only if make failed to produce one # The upstream Makefile uses 'rcc -g python' which is the correct method. # Only attempt regeneration if the file is missing or is a no-op stub. RCC_BIN=$(which rcc-qt6 2>/dev/null \ || which rcc 2>/dev/null \ || find %{_libdir}/qt6 /usr/lib64/qt6 /usr/lib/qt6 -name rcc -type f 2>/dev/null | head -1 \ || true) GUI_RES_INST="%{buildroot}%{_datadir}/%{name}/src/gui/resources_rc.py" if [ -n "$RCC_BIN" ]; then # Regenerate main GUI resources if the file is missing or a stub if [ ! -s "$GUI_RES_INST" ] || grep -q '^# Stub' "$GUI_RES_INST" 2>/dev/null; then for qrc in \ "%{_builddir}/RaySession-%{version}/resources/resources.qrc" \ "%{buildroot}%{_datadir}/%{name}/resources/resources.qrc"; do if [ -f "$qrc" ]; then mkdir -p "$(dirname "$GUI_RES_INST")" || true $RCC_BIN -g python "$qrc" | sed 's/ PySide. / qtpy /' > "$GUI_RES_INST" || true chmod 644 "$GUI_RES_INST" || true break fi done fi # Regenerate HoustonPatchbay resources if missing or a stub PB_RES_INST="%{buildroot}%{_datadir}/%{name}/HoustonPatchbay/source/patchbay/resources_rc.py" if [ ! -s "$PB_RES_INST" ] || grep -q '^# Stub\|^# HoustonPatchbay resource loader' "$PB_RES_INST" 2>/dev/null; then for qrc in \ "%{_builddir}/RaySession-%{version}/HoustonPatchbay/resources/resources.qrc" \ "%{buildroot}%{_datadir}/%{name}/HoustonPatchbay/resources/resources.qrc"; do if [ -f "$qrc" ]; then mkdir -p "$(dirname "$PB_RES_INST")" || true $RCC_BIN -g python "$qrc" | sed 's/ PySide. / qtpy /' > "$PB_RES_INST" || true chmod 644 "$PB_RES_INST" || true break fi done fi fi ## Overwrite upstream COPYING with GPL-2 if [ -f "%{SOURCE2}" ] && [ -d "%{_builddir}/RaySession-%{version}" ]; then if [ -f "%{_builddir}/RaySession-%{version}/COPYING" ]; then cp -p "%{SOURCE2}" "%{_builddir}/RaySession-%{version}/COPYING" || true chmod 644 "%{_builddir}/RaySession-%{version}/COPYING" || true fi fi ## Install qt6_app manpage if present if [ -f "%{SOURCE3}" ]; then install -D -m 644 "%{SOURCE3}" "%{buildroot}%{_mandir}/man1/qt6_app.1" || true gzip -n -f "%{buildroot}%{_mandir}/man1/qt6_app.1" || true fi %check desktop-file-validate %{buildroot}%{_datadir}/applications/*.desktop %files %doc README.md TODO TRANSLATORS %license %{_datadir}/licenses/%{name}/COPYING %{_bindir}/conf_testou %{_bindir}/qt6_app %{_bindir}/ray-alsapatch %{_bindir}/ray-daemon %{_bindir}/ray-jack_checker_daemon %{_bindir}/ray-jack_config_script %{_bindir}/ray-jackpatch %{_bindir}/ray-network %{_bindir}/ray-patch_dmn %{_bindir}/ray-pulse2jack %{_bindir}/ray_control %{_bindir}/ray_git %{_bindir}/raysession %{_bindir}/sooperlooper_nsm %{_bindir}/utility_script_keeper %{_bindir}/utility_script_starter %{_datadir}/applications/*.desktop %{_datadir}/%{name}/ %{_datadir}/icons/hicolor/*/apps/%{name}.* %config(noreplace) %{_sysconfdir}/xdg/raysession/* %config(noreplace) %{_sysconfdir}/bash_completion.d/ray_completion.sh %{_mandir}/man1/* %if %{defined python3_sitelib} %{python3_sitelib}/raysession.pth %else %{_prefix}/lib/python3.14/site-packages/raysession.pth %endif ## Include xdg compat shim in package %if %{defined python3_sitelib} %{python3_sitelib}/raysession_xdg_compat.py %{python3_sitelib}/raysession_xdg_compat.pth %else %{_prefix}/lib/python3.14/site-packages/raysession_xdg_compat.py %{_prefix}/lib/python3.14/site-packages/raysession_xdg_compat.pth %endif ## Include byte-compiled compat cache files %if %{defined python3_sitelib} %{python3_sitelib}/__pycache__/*raysession_xdg_compat*.pyc %else %{_prefix}/lib/python3.14/site-packages/__pycache__/*raysession_xdg_compat*.pyc %endif ## Exclude duplicate upstream data %exclude %{_datadir}/%{name}/data/share/applications/* %exclude %{_datadir}/%{name}/manual/* %exclude %{_datadir}/%{name}/HoustonPatchbay/manual/* %exclude %{_datadir}/%{name}/HoustonPatchbay/themes/.directory %exclude %{_datadir}/%{name}/manual/.directory %exclude %{_datadir}/%{name}/session_templates/with_jack_config/ray-scripts/.directory %exclude %{_datadir}/%{name}/session_templates/with_jack_config/ray-scripts/.jack_config_script %changelog * Tue Feb 10 2026 Erich Eickmeyer - 0.17.2-9 - Improve resource handling: ensure Qt resources and fonts are correctly compiled/installed so icons and application fonts load at runtime (fix rcc detection and safe regeneration behavior). * Mon Feb 9 2026 Erich Eickmeyer - 0.17.2-8 - Add additional runtime Requires for python3-QtPy * Mon Jan 19 2026 Erich Eickmeyer - 0.17.2-7 - Refactor install section: introduce DATADIR, PY_SITELIB, PY_LEGACY variables - Consolidate .pth and compat shim installation into loops - Clean up bytecode removal and DRY repeated paths - Fix rpmlint warnings and rebuild SRPM/RPM * Mon Jan 19 2026 Erich Eickmeyer - 0.17.2-6 - Add xdg-wrapper.py and raysession_xdg_compat.py as packaged Sources - Reference those files using their Source4 and Source5 macros in the spec - Upload sources to distgit and adjust install logic to use Source macros * Mon Jan 19 2026 Erich Eickmeyer - 0.17.2-5 - Major spec file overhaul for Fedora packaging compliance - Added compatibility wrapper for xdg import - Improved Qt resource and manpage generation logic - Refined file and symlink handling, .pth and compat modules - Cleaned up excludes, bytecode, and manual packaging * Sat Jan 17 2026 Erich Eickmeyer - 0.17.2-4 - Bump release to 4; include GPL-2 and qt6_app manpage * Fri Jan 16 2026 Erich Eickmeyer - 0.17.2-3 - Fix for missing dependency on python3-legacy-cgi * Fri Jan 16 2026 Erich Eickmeyer - 0.17.2-2 - Fix for incorrect package name (Bug #2430438) * Sat Jan 10 2026 Erich Eickmeyer - 0.17.2-1 - New upstream release - Removed patches, fixed upstream * Fri Sep 19 2025 Python Maint - 0.14.3-5 - Rebuilt for Python 3.14.0rc3 bytecode * Fri Aug 15 2025 Python Maint - 0.14.3-4 - Rebuilt for Python 3.14.0rc2 bytecode * Fri Jul 25 2025 Fedora Release Engineering - 0.14.3-3 - Rebuilt for https://fedoraproject.org/wiki/Fedora_43_Mass_Rebuild * Sat Jan 18 2025 Fedora Release Engineering - 0.14.3-2 - Rebuilt for https://fedoraproject.org/wiki/Fedora_42_Mass_Rebuild * Fri Sep 27 2024 Adam Williamson - 0.14.3-1 - New release 0.14.3 - Patch to work with pyliblo3 (for F41+ / Python 3.13+) * Mon Jul 29 2024 Miroslav Suchý - 0.9.1-12 - convert license to SPDX * Fri Jan 26 2024 Fedora Release Engineering - 0.9.1-10 - Rebuilt for https://fedoraproject.org/wiki/Fedora_40_Mass_Rebuild * Mon Jan 22 2024 Fedora Release Engineering - 0.9.1-9 - Rebuilt for https://fedoraproject.org/wiki/Fedora_40_Mass_Rebuild * Fri Jul 21 2023 Fedora Release Engineering - 0.9.1-8 - Rebuilt for https://fedoraproject.org/wiki/Fedora_39_Mass_Rebuild * Fri Jan 20 2023 Fedora Release Engineering - 0.9.1-7 - Rebuilt for https://fedoraproject.org/wiki/Fedora_38_Mass_Rebuild * Sat Jul 23 2022 Fedora Release Engineering - 0.9.1-6 - Rebuilt for https://fedoraproject.org/wiki/Fedora_37_Mass_Rebuild * Fri Jan 21 2022 Fedora Release Engineering - 0.9.1-5 - Rebuilt for https://fedoraproject.org/wiki/Fedora_36_Mass_Rebuild * Fri Jul 23 2021 Fedora Release Engineering - 0.9.1-4 - Rebuilt for https://fedoraproject.org/wiki/Fedora_35_Mass_Rebuild * Wed Jan 27 2021 Fedora Release Engineering - 0.9.1-3 - Rebuilt for https://fedoraproject.org/wiki/Fedora_34_Mass_Rebuild * Wed Jul 29 2020 Fedora Release Engineering - 0.9.1-2 - Rebuilt for https://fedoraproject.org/wiki/Fedora_33_Mass_Rebuild * Wed Jul 22 2020 Erich Eickmeyer - 0.9.1-1 - Removed patches, issues were fixed upstream - CLI: Control almost all GUI actions and more with the CLI ray_control. - Session scripts: allow user to edit shell scripts at session load, save and close. - JACK config session script: script that saves and recalls the JACK configuration for the session. - Add this from session templates in "New Session" window. - RayHack: New client protocol which is an alternative to ray-proxy. - This allows to launch directly the process and to edit its properties even if process is stopped. - Obviously NSM protocol is highly preferred, this protocol is a workaround only, nothing more. - Factory client templates are installed in /etc/xdg/raysession to allow packagers to add some templates. - Always prefer NSM template if NSM compatibility is found in executable binary - Get client label, icon and description from their .desktop file - Subfolder combobox removed in New Session Dialog - Daemon option "Save from client" has been removed. Please affect a global keyboard shortcut (Meta+Ctrl+S) to ray_control save instead. * Sat Feb 8 2020 Erich Eickmeyer - 0.8.3-1 - Initial release for Fedora