diff --git a/.github/workflows/autobuild.yml b/.github/workflows/autobuild.yml
index f18136ffb5..f3cb7a48cf 100644
--- a/.github/workflows/autobuild.yml
+++ b/.github/workflows/autobuild.yml
@@ -51,15 +51,27 @@ jobs:
uses: actions/checkout@v4
with:
fetch-depth: 0
+
+ - name: Checkout latest Mock configs
+ uses: actions/checkout@v4
+ with:
+ repository: terrapkg/mock-configs
+ path: mock-configs
+
- name: Set up git repository
run: git config --global --add safe.directory "$GITHUB_WORKSPACE"
- name: Include custom build template instead of package default
run: |
- cp -v anda/terra/mock-configs/terra.tpl /etc/mock/templates/terra.tpl
+ cp -v mock-configs/terra.tpl /etc/mock/templates/terra.tpl
- name: Build with Andaman
- run: anda build ${{ matrix.pkg.pkg }} --package rpm -c anda/terra/mock-configs/terra-${{ matrix.version }}-${{ matrix.pkg.arch }}.cfg
+ run: anda build ${{ matrix.pkg.pkg }} --package rpm -c mock-configs/terra-${{ matrix.version }}-${{ matrix.pkg.arch }}.cfg
+
+ - name: Build with Andaman (alternate arch)
+ if: |
+ matrix.pkg.arch == 'x86_64' && matrix.pkg.labels['multilib']
+ run: anda build ${{ matrix.pkg.pkg }} --package rpm -c mock-configs/terra-${{ matrix.version }}-i386.cfg
- name: Generating artifact name
id: art
@@ -94,7 +106,7 @@ jobs:
- name: Notify Madoguchi (Success)
if: success() && github.event_name == 'push'
- run: ./.github/workflows/mg.sh true ${{matrix.pkg.pkg}} ${{matrix.version}} ${{matrix.pkg.arch}} ${{github.run_id}} ${{secrets.MADOGUCHI_JWT}}
+ run: ./.github/workflows/mg.sh true ${{matrix.pkg.pkg}} ${{matrix.version}} ${{matrix.pkg.arch}} ${{github.run_id}} ${{secrets.MADOGUCHI_JWT}} ${{github.sha}}
- name: Notify Madoguchi (Failure)
if: ( cancelled() || failure() ) && github.event_name == 'push'
- run: ./.github/workflows/mg.sh false ${{matrix.pkg.pkg}} ${{matrix.version}} ${{matrix.pkg.arch}} ${{github.run_id}} ${{secrets.MADOGUCHI_JWT}}
+ run: ./.github/workflows/mg.sh false ${{matrix.pkg.pkg}} ${{matrix.version}} ${{matrix.pkg.arch}} ${{github.run_id}} ${{secrets.MADOGUCHI_JWT}} ${{github.sha}}
diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml
index 57e2db4159..0abf10b578 100644
--- a/.github/workflows/build.yml
+++ b/.github/workflows/build.yml
@@ -14,8 +14,6 @@ on:
required: false
default: all
type: string
-
-
jobs:
parse:
@@ -28,18 +26,18 @@ jobs:
- name: Parse Input
id: parsing
run: |
- echo "${{ inputs.packages }}" | sed 's/ /\n/g' | sed 's/$/\//g' | jq -R . | jq -s . | jq -c . | sed 's/^/pkgs=/' >> $GITHUB_OUTPUT
- echo "builder=${{ inputs.custom_builder }}" >> $GITHUB_OUTPUT
- arch="${{ inputs.architecture }}"
- # Convert to json array using jq
- # if arch is not all, convert to array
- if [ "$arch" != "all" ]; then
- # jq, array with single element as string
- arch=$(echo $arch | sed 's/,/\n/g')
- echo "arch=$(echo $arch | jq -Rs 'split("\n")' | jq 'map(select(length > 0))' | jq -c .)" >> $GITHUB_OUTPUT
- else
- echo "arch=$(echo '["aarch64", "x86_64"]' | jq -c .)" >> $GITHUB_OUTPUT
- fi
+ echo "${{ inputs.packages }}" | sed 's/ /\n/g' | sed 's/$/\//g' | jq -R . | jq -s . | jq -c . | sed 's/^/pkgs=/' >> $GITHUB_OUTPUT
+ echo "builder=${{ inputs.custom_builder }}" >> $GITHUB_OUTPUT
+ arch="${{ inputs.architecture }}"
+ # Convert to json array using jq
+ # if arch is not all, convert to array
+ if [ "$arch" != "all" ]; then
+ # jq, array with single element as string
+ arch=$(echo $arch | sed 's/,/\n/g')
+ echo "arch=$(echo $arch | jq -Rs 'split("\n")' | jq 'map(select(length > 0))' | jq -c .)" >> $GITHUB_OUTPUT
+ else
+ echo "arch=$(echo '["aarch64", "x86_64"]' | jq -c .)" >> $GITHUB_OUTPUT
+ fi
build:
needs: parse
@@ -58,18 +56,22 @@ jobs:
uses: actions/checkout@v4
with:
fetch-depth: 0
+
+ - name: Checkout latest Mock configs
+ uses: actions/checkout@v4
+ with:
+ repository: terrapkg/mock-configs
+ path: mock-configs
+
- name: Set up git repository
run: git config --global --add safe.directory "$GITHUB_WORKSPACE"
- - name: Cache buildroot
- id: br-cache
- uses: actions/cache@v4
- with:
- path: /var/cache
- key: ${{ runner.os }}-br-${{ matrix.version }}-${{ matrix.arch }}-${{ matrix.pkg }}
+ - name: Include custom build template instead of package default
+ run: |
+ cp -v mock-configs/terra.tpl /etc/mock/templates/terra.tpl
- name: Build with Andaman
- run: anda build anda/${{ matrix.pkg }}pkg --package rpm -c anda/terra/mock-configs/terra-${{ matrix.version }}-${{ matrix.arch }}.cfg
+ run: anda build anda/${{ matrix.pkg }}pkg --package rpm -c mock-configs/terra-${{ matrix.version }}-${{ matrix.arch }}.pkg
- name: Generating artifact name
id: art
@@ -102,7 +104,7 @@ jobs:
- name: Notify Madoguchi (Success)
if: success()
- run: ./.github/workflows/mg.sh true ${{matrix.pkg}} ${{matrix.version}} ${{matrix.arch}} ${{github.run_id}} ${{secrets.MADOGUCHI_JWT}}
+ run: ./.github/workflows/mg.sh true ${{matrix.pkg}} ${{matrix.version}} ${{matrix.arch}} ${{github.run_id}} ${{secrets.MADOGUCHI_JWT}} ${{github.sha}}
- name: Notify Madoguchi (Failure)
if: cancelled() || failure()
- run: ./.github/workflows/mg.sh false ${{matrix.pkg}} ${{matrix.version}} ${{matrix.arch}} ${{github.run_id}} ${{secrets.MADOGUCHI_JWT}}
+ run: ./.github/workflows/mg.sh false ${{matrix.pkg}} ${{matrix.version}} ${{matrix.arch}} ${{github.run_id}} ${{secrets.MADOGUCHI_JWT}} ${{github.sha}}
diff --git a/.github/workflows/json-build.yml b/.github/workflows/json-build.yml
index f817d728ba..9180650a40 100644
--- a/.github/workflows/json-build.yml
+++ b/.github/workflows/json-build.yml
@@ -22,18 +22,22 @@ jobs:
uses: actions/checkout@v4
with:
fetch-depth: 0
+
+ - name: Checkout latest Mock configs
+ uses: actions/checkout@v4
+ with:
+ repository: terrapkg/mock-configs
+ path: mock-configs
+
- name: Set up git repository
run: git config --global --add safe.directory "$GITHUB_WORKSPACE"
- - name: Cache buildroot
- id: br-cache
- uses: actions/cache@v4
- with:
- path: /var/cache
- key: ${{ runner.os }}-br-${{ matrix.version }}-${{ matrix.pkg.arch }}-${{ matrix.pkg.pkg }}
+ - name: Include custom build template instead of package default
+ run: |
+ cp -v mock-configs/terra.tpl /etc/mock/templates/terra.tpl
- name: Build with Andaman
- run: anda build ${{ matrix.pkg.pkg }} --package rpm -c anda/terra/mock-configs/terra-${{ matrix.version }}-${{ matrix.pkg.arch }}.cfg
+ run: anda build ${{ matrix.pkg.pkg }} --package rpm -c mock-configs/terra-${{ matrix.version }}-${{ matrix.pkg.arch }}.pkg
- name: Generating artifact name
id: art
@@ -67,7 +71,7 @@ jobs:
- name: Notify Madoguchi (Success)
if: success()
- run: ./.github/workflows/mg.sh true ${{matrix.pkg.pkg}} ${{matrix.version}} ${{matrix.pkg.arch}} ${{github.run_id}} ${{secrets.MADOGUCHI_JWT}}
+ run: ./.github/workflows/mg.sh true ${{matrix.pkg.pkg}} ${{matrix.version}} ${{matrix.pkg.arch}} ${{github.run_id}} ${{secrets.MADOGUCHI_JWT}} ${{github.sha}}
- name: Notify Madoguchi (Failure)
if: cancelled() || failure()
- run: ./.github/workflows/mg.sh false ${{matrix.pkg.pkg}} ${{matrix.version}} ${{matrix.pkg.arch}} ${{github.run_id}} ${{secrets.MADOGUCHI_JWT}}
+ run: ./.github/workflows/mg.sh false ${{matrix.pkg.pkg}} ${{matrix.version}} ${{matrix.pkg.arch}} ${{github.run_id}} ${{secrets.MADOGUCHI_JWT}} ${{github.sha}}
diff --git a/.github/workflows/mg.sh b/.github/workflows/mg.sh
index 1d581aef14..037c4197a1 100755
--- a/.github/workflows/mg.sh
+++ b/.github/workflows/mg.sh
@@ -2,7 +2,7 @@ set -x
dirs=$2
dirs=${dirs/\/pkg/}
-export p="{\"id\":\"$5\",\"ver\":\"%v\",\"rel\":\"%r\",\"arch\":\"$4\",\"dirs\":\"$dirs\",\"succ\":$1}"
+export p="{\"id\":\"$5\",\"ver\":\"%v\",\"rel\":\"%r\",\"arch\":\"$4\",\"dirs\":\"$dirs\",\"succ\":$1,\"commit\":\"%6\"}"
if [[ $1 == false ]]; then
d=${p/\%v/?}
diff --git a/.github/workflows/update.yml b/.github/workflows/update.yml
index 47f81d5820..a17a985c17 100644
--- a/.github/workflows/update.yml
+++ b/.github/workflows/update.yml
@@ -25,7 +25,7 @@ jobs:
git config --global --add safe.directory "$GITHUB_WORKSPACE"
- name: Run Update
- run: anda update -vv
+ run: anda update -vv --filters nightly=0
env:
GITHUB_TOKEN: ${{ secrets.AUTOUPDATE_GH_TOKEN }}
RUST_BACKTRACE: full
diff --git a/anda/apps/anki-bin/anki-bin.spec b/anda/apps/anki-bin/anki-bin.spec
index b440a8f11e..c34b3b914c 100644
--- a/anda/apps/anki-bin/anki-bin.spec
+++ b/anda/apps/anki-bin/anki-bin.spec
@@ -1,18 +1,26 @@
+%global xurl https://files.pythonhosted.org/packages/51/5f/6f52b958fe38a36a0799c01fbd56a742ebdfcf41f89438dbee998b8ce692/anki-24.06.3-cp39-abi3-manylinux_2_28_x86_64.whl
+%global aurl https://files.pythonhosted.org/packages/df/bb/b0bfbc6a06a598b0b614d18dd8c4f40827828649f9742f1f44a4e44d6a2c/anki-24.06.3-cp39-abi3-manylinux_2_31_aarch64.whl
+%global qurl https://files.pythonhosted.org/packages/21/2a/d8e22a9521be04ef29a30d21a2c3008783ab03b6f07cc14696a040f747a4/aqt-24.06.3-py3-none-any.whl
+
Name: anki-bin
Version: 24.06.3
Release: 1%?dist
Summary: Flashcard program for using space repetition learning (Installed with wheel)
License: AGPL-3.0-or-later AND GPL-3.0-or-later AND LGPL-3.0-or-later AND MIT AND BSD-3-Clause AND CC-BY-SA-3.0 AND CC-BY-3.0 AND Apache-2.0 AND CC-BY-2.5
URL: https://apps.ankiweb.net/
-BuildRequires: python3-pip rpm_macro(fdupes)
+BuildRequires: python3-pip rpm_macro(fdupes) cargo
Requires: python3-sqlalchemy python3-simplejson python3-matplotlib python3-decorator python3-markdown python3-orjson
Requires: python3-requests python3-pygame python3-beautifulsoup4 python3-httplib2 python3-pyaudio python3-jsonschema
Requires: python3-flask-cors python3-protobuf python3-requests python3-waitress python3-pyqt6-webengine python3-send2trash
Requires: libxcrypt-compat hicolor-icon-theme sox mpv
ExclusiveArch: x86_64
Conflicts: anki
-Source0: https://files.pythonhosted.org/packages/cp39/a/anki/anki-%{version}-cp39-abi3-manylinux_2_28_%{_arch}.whl
-Source1: https://files.pythonhosted.org/packages/py3/a/aqt/aqt-%{version}-py3-none-any.whl
+%ifarch x86_64
+Source0: %xurl
+%elifarch aarch64
+Source0: %aurl
+%endif
+Source1: %qurl
Source2: https://raw.githubusercontent.com/ankitects/anki/%{version}/qt/runanki.py
Source3: https://raw.githubusercontent.com/ankitects/anki/%{version}/qt/bundle/lin/anki.desktop
Source4: https://raw.githubusercontent.com/ankitects/anki/%{version}/qt/bundle/lin/anki.png
diff --git a/anda/apps/anki-bin/update.rhai b/anda/apps/anki-bin/update.rhai
index 06eb9c5883..a61d878273 100644
--- a/anda/apps/anki-bin/update.rhai
+++ b/anda/apps/anki-bin/update.rhai
@@ -1 +1,15 @@
-rpm.version(gh("ankitects/anki"));
+let aarch64_regex = ``;
+let html = get("https://pypi.org/project/anki/");
+let relevant = find(aarch64_regex, html, 0);
+let ver = find(aarch64_regex, relevant, 4);
+rpm.version(ver);
+if rpm.changed() {
+ rpm.release();
+ rpm.global("aurl", find(`"(.+)"`, relevant, 1));
+ let cp = find(aarch64_regex, relevant, 5);
+ let x86_64_regex = ``;
+ let relevant1 = find(x86_64_regex, html, 0);
+ rpm.global("xurl", find(`"(.+)"`, relevant1, 1));
+ let qhtml = get("https://pypi.org/project/aqt/");
+ rpm.global("qurl", find(``, qhtml, 1));
+}
diff --git a/anda/apps/discord-canary-openasar/discord-canary-openasar.spec b/anda/apps/discord-canary-openasar/discord-canary-openasar.spec
index 9a76f05835..a373c9eb75 100644
--- a/anda/apps/discord-canary-openasar/discord-canary-openasar.spec
+++ b/anda/apps/discord-canary-openasar/discord-canary-openasar.spec
@@ -6,7 +6,7 @@
%global __provides_exclude_from %{_datadir}/%{name}/.*\\.so
Name: discord-canary-openasar
-Version: 0.0.452
+Version: 0.0.454
Release: 1%?dist
Summary: A snappier Discord rewrite with features like further customization and theming
License: MIT AND https://discord.com/terms
diff --git a/anda/apps/discord-canary/discord-canary.spec b/anda/apps/discord-canary/discord-canary.spec
index edbc8423c2..238c3f7bf2 100644
--- a/anda/apps/discord-canary/discord-canary.spec
+++ b/anda/apps/discord-canary/discord-canary.spec
@@ -6,7 +6,7 @@
%global __provides_exclude_from %{_datadir}/%{name}/.*\\.so
Name: discord-canary
-Version: 0.0.452
+Version: 0.0.454
Release: 1%?dist
Summary: Free Voice and Text Chat for Gamers
URL: discord.com
diff --git a/anda/apps/discord-openasar/discord-openasar.spec b/anda/apps/discord-openasar/discord-openasar.spec
index a67cf4660d..8c0c401d53 100644
--- a/anda/apps/discord-openasar/discord-openasar.spec
+++ b/anda/apps/discord-openasar/discord-openasar.spec
@@ -6,7 +6,7 @@
%global __provides_exclude_from %{_datadir}/%{name}/.*\\.so
Name: discord-openasar
-Version: 0.0.59
+Version: 0.0.61
Release: 1%?dist
Summary: A snappier Discord rewrite with features like further customization and theming
License: MIT AND https://discord.com/terms
diff --git a/anda/apps/discord-ptb-openasar/discord-ptb-openasar.spec b/anda/apps/discord-ptb-openasar/discord-ptb-openasar.spec
index ea29f2a0f4..b70f701e43 100644
--- a/anda/apps/discord-ptb-openasar/discord-ptb-openasar.spec
+++ b/anda/apps/discord-ptb-openasar/discord-ptb-openasar.spec
@@ -6,7 +6,7 @@
%global __provides_exclude_from %{_datadir}/%{name}/.*\\.so
Name: discord-ptb-openasar
-Version: 0.0.94
+Version: 0.0.95
Release: 1%?dist
Summary: A snappier Discord rewrite with features like further customization and theming
License: MIT AND https://discord.com/terms
diff --git a/anda/apps/discord-ptb/discord-ptb.spec b/anda/apps/discord-ptb/discord-ptb.spec
index e2783b150e..7d3a0b8749 100644
--- a/anda/apps/discord-ptb/discord-ptb.spec
+++ b/anda/apps/discord-ptb/discord-ptb.spec
@@ -6,7 +6,7 @@
%global __provides_exclude_from %{_datadir}/%{name}/.*\\.so
Name: discord-ptb
-Version: 0.0.94
+Version: 0.0.95
Release: 1%?dist
Summary: Free Voice and Text Chat for Gamers.
URL: https://discord.com
diff --git a/anda/apps/discord/discord.spec b/anda/apps/discord/discord.spec
index 1570a72461..2bf0446fec 100644
--- a/anda/apps/discord/discord.spec
+++ b/anda/apps/discord/discord.spec
@@ -6,7 +6,7 @@
%global __provides_exclude_from %{_datadir}/%{name}/.*\\.so
Name: discord
-Version: 0.0.59
+Version: 0.0.61
Release: 1%?dist
Summary: Free Voice and Text Chat for Gamers
URL: https://discord.com
diff --git a/anda/apps/envision/envision.spec b/anda/apps/envision/envision.spec
index 5dc79eb34f..3d9f6302f7 100644
--- a/anda/apps/envision/envision.spec
+++ b/anda/apps/envision/envision.spec
@@ -1,5 +1,5 @@
-%global commit 6cf5e40b96d1cbd99a3cfcef1f03899356e79448
-%global commit_date 20240703
+%global commit 2addb6ae636b0c2f5bb4313436cb42973d397760
+%global commit_date 20240722
%global shortcommit %(c=%{commit}; echo ${c:0:7})
Name: envision
diff --git a/anda/apps/komikku/anda.hcl b/anda/apps/komikku/anda.hcl
new file mode 100644
index 0000000000..1c08b38522
--- /dev/null
+++ b/anda/apps/komikku/anda.hcl
@@ -0,0 +1,5 @@
+project pkg {
+ rpm {
+ spec = "komikku.spec"
+ }
+}
diff --git a/anda/apps/komikku/komikku.spec b/anda/apps/komikku/komikku.spec
new file mode 100644
index 0000000000..f8b70c5901
--- /dev/null
+++ b/anda/apps/komikku/komikku.spec
@@ -0,0 +1,109 @@
+%global appname Komikku
+%global uuid info.febvre.%{appname}
+%global gtk4_version 4.14.4
+%global libadwaita_version 1.5.1
+%global pure_protobuf_version 2.0.0
+
+Name: komikku
+Version: 1.51.1
+%forgemeta
+Release: %autorelease
+Summary: A manga reader for GNOME
+
+BuildArch: noarch
+
+License: GPL-3.0-or-later
+URL: https://valos.gitlab.io/Komikku
+Source0: https://codeberg.org/valos/%{appname}/archive/v%{version}.tar.gz#/%{name}-v%{version}.tar.gz
+
+BuildRequires: desktop-file-utils
+BuildRequires: intltool
+BuildRequires: libappstream-glib
+BuildRequires: meson >= 0.59.0
+BuildRequires: python3-devel >= 3.8
+BuildRequires: blueprint-compiler
+
+BuildRequires: pkgconfig(gobject-introspection-1.0) >= 1.35.9
+BuildRequires: pkgconfig(gtk4) >= %{gtk4_version}
+BuildRequires: pkgconfig(libadwaita-1) >= %{libadwaita_version}
+
+Requires: hicolor-icon-theme
+Requires: gtk4 >= %{gtk4_version}
+Requires: libadwaita >= %{libadwaita_version}
+Requires: libnotify
+Requires: webkitgtk6.0
+Requires: python3-beautifulsoup4
+Requires: python3-brotli
+Requires: python3-colorthief
+Requires: python3-dateparser %dnl >= 1.1.4 | https://bugzilla.redhat.com/show_bug.cgi?id=2115204
+Requires: python3-emoji
+Requires: python3-gobject
+Requires: python3-keyring >= 21.6.0
+Requires: python3-lxml
+Requires: python3-natsort
+Requires: python3-file-magic
+Requires: python3-piexif
+Requires: python3-pillow
+Requires: python3-pillow-heif
+Requires: python3-pure-protobuf >= %{pure_protobuf_version}
+Requires: python3-rarfile
+Requires: python3-requests
+Requires: python3-unidecode
+
+%description
+Komikku is a manga reader for GNOME. It focuses on providing a clean, intuitive
+and adaptive interface.
+
+Keys features
+
+* Online reading from dozens of servers
+* Offline reading of downloaded comics
+* Categories to organize your library
+* RTL, LTR, Vertical and Webtoon reading modes
+* Several types of navigation:
+ * Keyboard arrow keys
+ * Right and left navigation layout via mouse click or tapping
+ (touchpad/touch screen)
+ * Mouse wheel
+ * 2-fingers swipe gesture (touchpad)
+ * Swipe gesture (touch screen)
+* Automatic update of comics
+* Automatic download of new chapters
+* Reading history
+* Light and dark themes
+
+%prep
+%autosetup -n %{name} -p1
+
+
+%build
+%meson
+%meson_build
+
+
+%install
+%meson_install
+%find_lang %{name}
+
+
+%check
+appstream-util validate-relax --nonet %{buildroot}%{_metainfodir}/*.xml
+desktop-file-validate %{buildroot}%{_datadir}/applications/*.desktop
+
+
+%files -f %{name}.lang
+%license LICENSE
+%doc README.md
+%{_bindir}/%{name}
+%{_datadir}/%{name}/
+%{_datadir}/applications/*.desktop
+%{_datadir}/glib-2.0/schemas/*.gschema.xml
+%{_datadir}/icons/hicolor/scalable/*/*.svg
+%{_datadir}/icons/hicolor/symbolic/*/*.svg
+%{_metainfodir}/*.xml
+%{python3_sitelib}/%{name}/
+
+
+%changelog
+* Thu Jul 11 2024 Trung LĂȘ <8@tle.id.au> - 1.51.1-0
+- Initial RPM package
diff --git a/anda/apps/komikku/update.rhai b/anda/apps/komikku/update.rhai
new file mode 100644
index 0000000000..c0a1b21997
--- /dev/null
+++ b/anda/apps/komikku/update.rhai
@@ -0,0 +1,3 @@
+let latest_tag = get("https://codeberg.org/api/v1/repos/valos/Komikku/tags").json_arr()[0].name;
+let new_version = find("([\\.\\d]+)", latest_tag, 1);
+rpm.version(new_version);
diff --git a/anda/apps/mpv/mpv-nightly.spec b/anda/apps/mpv/mpv-nightly.spec
index dc91477437..6f7cc821d8 100644
--- a/anda/apps/mpv/mpv-nightly.spec
+++ b/anda/apps/mpv/mpv-nightly.spec
@@ -1,6 +1,6 @@
-%global commit 202ecc17af01407e7ed230b395c17a2038c339d4
+%global commit e509ec0aaffce74e520702e16e3e21ea0f168940
%global shortcommit %(c=%{commit}; echo ${c:0:7})
-%global commit_date 20240714
+%global commit_date 20240720
%global ver v0.38.0
Name: mpv-nightly
diff --git a/anda/apps/voicevox/0001-feat-add-repository-entry-in-package.json.patch b/anda/apps/voicevox/0001-feat-add-repository-entry-in-package.json.patch
deleted file mode 100644
index 8b3c61bd79..0000000000
--- a/anda/apps/voicevox/0001-feat-add-repository-entry-in-package.json.patch
+++ /dev/null
@@ -1,22 +0,0 @@
-From 6b8c81d1d4ac0ac562b69e7f8164c8a92dafe13a Mon Sep 17 00:00:00 2001
-From: windowsboy111
-Date: Mon, 19 Jun 2023 10:33:20 +0800
-Subject: [PATCH] feat: add repository entry in package.json
-
----
- package.json | 1 +
- 1 file changed, 1 insertion(+)
-
-diff --git a/package.json b/package.json
-index 622756a..b3d3dfa 100644
---- a/package.json
-+++ b/package.json
-@@ -1,4 +1,5 @@
- {
-+ "repository": "github:VOICEVOX/voicevox",
- "name": "voicevox",
- "version": "999.999.999",
- "author": "Hiroshiba Kazuyuki",
---
-2.40.1
-
diff --git a/anda/apps/voicevox/anda.hcl b/anda/apps/voicevox/anda.hcl
index 2a748721bc..455f83d7d4 100644
--- a/anda/apps/voicevox/anda.hcl
+++ b/anda/apps/voicevox/anda.hcl
@@ -1,4 +1,5 @@
project pkg {
+ arches = ["x86_64"]
rpm {
spec = "voicevox.spec"
}
diff --git a/anda/apps/voicevox/update.rhai b/anda/apps/voicevox/update.rhai
index 20399b6d08..3f2735939d 100644
--- a/anda/apps/voicevox/update.rhai
+++ b/anda/apps/voicevox/update.rhai
@@ -1,5 +1 @@
-let v = gh("VOICEVOX/voicevox");
-rpm.global("ver", v);
-let engines = get(`https://raw.githubusercontent.com/VOICEVOX/voicevox/${v}/package.json`).json().engines;
-rpm.global("nodev", find(">=([\\d.]+)", engines.node, 1));
-rpm.global("npmv", find(">=([\\d.]+)", engines.npm, 1));
+rpm.version(gh("VOICEVOX/voicevox"));
diff --git a/anda/apps/voicevox/voicevox.spec b/anda/apps/voicevox/voicevox.spec
index 647a305bfa..9cdb9c692c 100644
--- a/anda/apps/voicevox/voicevox.spec
+++ b/anda/apps/voicevox/voicevox.spec
@@ -1,6 +1,3 @@
-%global nodev 20.12.2
-%global npmv 10.5.0
-%global ver 0.19.2
%define debug_package %nil
%global _build_id_links none
@@ -9,20 +6,16 @@
%global __provides_exclude_from %{_datadir}/%{name}/.*\\.so
Name: voicevox
-Version: %ver
+Version: 0.19.2
Release: 4%?dist
Summary: Free Japanese text-to-speech editor
License: LGPL-3.0
URL: https://voicevox.hiroshiba.jp
-Source0: https://github.com/VOICEVOX/voicevox/archive/refs/tags/%version.tar.gz
-# requires specific node and npm version
-%ifarch x86_64
-%global a x64
-%elifarch aarch64
-%global a arm64
-%endif
-Source1: https://nodejs.org/download/release/v%nodev/node-v%nodev-linux-%a.tar.xz
-Patch0: 0001-feat-add-repository-entry-in-package.json.patch
+Source0: https://github.com/VOICEVOX/voicevox/releases/download/%version/VOICEVOX.AppImage.7z.001
+Source1: https://github.com/VOICEVOX/voicevox/releases/download/%version/VOICEVOX.AppImage.7z.002
+Source2: https://github.com/VOICEVOX/voicevox/releases/download/%version/VOICEVOX.AppImage.7z.003
+BuildRequires: p7zip-plugins
+ExclusiveArch: x86_64
%description
VOICEVOX is a free Japanese text-to-speech software with medium output quality.
@@ -34,33 +27,28 @@ Summary: Documentation files for voicevox (Japanese)
%summary.
%prep
-%autosetup -p1
-tar xf %SOURCE1
-PATH="$PATH:$PWD/node-v%nodev-linux-%a/bin/"
-npx npm@%npmv i
+cat< voicevox.sh
+#!/bin/sh
+/usr/share/voicevox/VOICEVOX.AppImage
+EOF
+7z x %SOURCE0
+chmod a+x VOICEVOX.AppImage
+
+./VOICEVOX.AppImage --appimage-extract '*.desktop'
+./VOICEVOX.AppImage --appimage-extract 'usr/share/icons/**'
+
+sed -i "s|Exec=.*|Exec=/usr/share/voicevox/VOICEVOX.AppImage|" squashfs-root/voicevox.desktop
%build
-PATH="$PATH:$PWD/node-v%nodev-linux-%a/bin/"
-npx browserslist@latest --update-db
-PATH="$PATH:$PWD/node-v%nodev-linux-%a/bin/"
-npm run electron:build
%install
-rm dist_electron/linux-unpacked/README.txt # dummy
-mkdir -p %buildroot%_datadir/%name %buildroot%_bindir %buildroot%_docdir/%name/res
-mv dist_electron/linux-unpacked/* %buildroot%_datadir/%name/
-ln -s %_datadir/%name/%name %buildroot%_bindir/%name
-install -Dm644 docs/*.md %buildroot%_docdir/%name/
-install -Dm644 docs/res/* %buildroot%_docdir/%name/res/
+install -Dm755 VOICEVOX.AppImage %buildroot%_datadir/voicevox/VOICEVOX.AppImage
+install -Dm755 voicevox.sh %buildroot%_bindir/voicevox
+install -Dm644 squashfs-root%_iconsdir/hicolor/0x0/apps/voicevox.png %buildroot%_iconsdir/hicolor/256x256/apps/voicevox.png
+install -Dm644 squashfs-root/voicevox.desktop %buildroot%_datadir/applications/voicevox.desktop
%files
-%doc README.md
-%license LICENSE LGPL_LICENSE
-%_bindir/%name
-%_datadir/%name/
-
-%files doc
-%doc %_docdir/%name/
-
-%changelog
-%autochangelog
+%_bindir/voicevox
+%_datadir/applications/voicevox.desktop
+%_datadir/voicevox/VOICEVOX.AppImage
+%_iconsdir/hicolor/256x256/apps/voicevox.png
diff --git a/anda/desktops/elementary/elementary-terminal/elementary-terminal.spec b/anda/desktops/elementary/elementary-terminal/elementary-terminal.spec
index 2c010f5225..7bfc152719 100644
--- a/anda/desktops/elementary/elementary-terminal/elementary-terminal.spec
+++ b/anda/desktops/elementary/elementary-terminal/elementary-terminal.spec
@@ -3,8 +3,8 @@
Name: elementary-terminal
Summary: The terminal of the 21st century
-Version: 6.1.2
-Release: 2%{?dist}
+Version: 6.2.0
+Release: 1%?dist
License: LGPL-3.0
URL: https://github.com/elementary/%{srcname}
@@ -90,16 +90,9 @@ appstream-util validate-relax --nonet \
%{_datadir}/glib-2.0/schemas/%{appname}.gschema.xml
%{_datadir}/%{appname}/
%{_datadir}/metainfo/%{appname}.appdata.xml
+%{_mandir}/man1/%{appname}.1.gz
%files fish
%doc README.md
%license COPYING
%{_datadir}/fish/vendor_conf.d/pantheon_terminal_process_completion_notifications.fish
-
-
-%changelog
-* Thu Nov 17 2022 windowsboy111 - 6.1.1-1
-- new version
-
-* Sat Oct 15 2022 windowsboy111
-- Repackaged for Terra
diff --git a/anda/desktops/elementary/elementary-wallpapers/elementary-wallpapers.spec b/anda/desktops/elementary/elementary-wallpapers/elementary-wallpapers.spec
index 2483e47a9b..e3f08e56e1 100644
--- a/anda/desktops/elementary/elementary-wallpapers/elementary-wallpapers.spec
+++ b/anda/desktops/elementary/elementary-wallpapers/elementary-wallpapers.spec
@@ -3,8 +3,8 @@
Name: elementary-wallpapers
Summary: Collection of wallpapers from the elementary project
-Version: 7.0.0
-Release: 1%{?dist}
+Version: 8.0.0
+Release: 1%?dist
# License breakdown is available in debian/copyright
License: CC-BY-SA-4.0 AND CC0-1.0 AND Unlicense
diff --git a/anda/desktops/lomiri-unity/lomiri-system-settings/lomiri-system-settings.spec b/anda/desktops/lomiri-unity/lomiri-system-settings/lomiri-system-settings.spec
index 72e93f586d..de59bc1db8 100644
--- a/anda/desktops/lomiri-unity/lomiri-system-settings/lomiri-system-settings.spec
+++ b/anda/desktops/lomiri-unity/lomiri-system-settings/lomiri-system-settings.spec
@@ -1,5 +1,5 @@
%global forgeurl https://gitlab.com/ubports/development/core/lomiri-system-settings
-%global commit b24c149b46e31c693c28978028493630bc86c799
+%global commit 1530c1fcfd8b8b7eec3a30e2db20cfc9946fa34a
%forgemeta
Name: lomiri-system-settings
diff --git a/anda/desktops/lomiri-unity/lomiri/lomiri.spec b/anda/desktops/lomiri-unity/lomiri/lomiri.spec
index 88efe53ba6..e2fae98e87 100644
--- a/anda/desktops/lomiri-unity/lomiri/lomiri.spec
+++ b/anda/desktops/lomiri-unity/lomiri/lomiri.spec
@@ -1,10 +1,10 @@
%global forgeurl https://gitlab.com/ubports/development/core/lomiri
-%global commit a083a14fe65105fc1996ceb1b92165ca3b0cb94e
+%global commit 0b85fddd0123c86fe6b3464143df86a6d0ad6bb9
%forgemeta
Name: lomiri
-Version: 0.2.1
-Release: 1%{?dist}
+Version: 0.3.0
+Release: 1%?dist
Summary: A convergent desktop environment by Ubports
License: GPLv3 AND LGPLv3
diff --git a/anda/devs/flow/anda.hcl b/anda/devs/flow/anda.hcl
new file mode 100644
index 0000000000..7542fe48ea
--- /dev/null
+++ b/anda/devs/flow/anda.hcl
@@ -0,0 +1,8 @@
+project pkg {
+ rpm {
+ spec = "flow-control-nightly.spec"
+ }
+ labels {
+ nightly = 1
+ }
+}
diff --git a/anda/devs/flow/flow-control-nightly.spec b/anda/devs/flow/flow-control-nightly.spec
new file mode 100644
index 0000000000..b7c18f9ecc
--- /dev/null
+++ b/anda/devs/flow/flow-control-nightly.spec
@@ -0,0 +1,30 @@
+%global commit 787bf3c6585701ec718c740ccb424794c39a2b43
+%global shortcommit %(c=%{commit}; echo ${c:0:7})
+%global commit_date 20240714
+
+Name: flow-control-nightly
+Version: %commit_date.%shortcommit
+Release: 1%?dist
+Summary: A programmer's text editor
+License: MIT
+URL: https://github.com/neurocyte/flow
+Source0: %url/archive/%commit.tar.gz
+BuildRequires: zig
+Provides: flow = %version-%release
+
+%description
+%summary.
+
+%prep
+%autosetup -n flow-%commit
+
+%build
+zig build -Doptimize=ReleaseFast --release=fast
+
+%install
+install -Dpm755 zig-out/bin/flow %buildroot%_bindir/flow
+
+%files
+%doc README.md help.md
+%license LICENSE
+%_bindir/flow
diff --git a/anda/devs/flow/update.rhai b/anda/devs/flow/update.rhai
new file mode 100644
index 0000000000..31f698e529
--- /dev/null
+++ b/anda/devs/flow/update.rhai
@@ -0,0 +1,7 @@
+if filters.contains("nightly") {
+ rpm.global("commit", gh_commit("neurocyte/flow"));
+ if rpm.changed() {
+ rpm.release();
+ rpm.global("commit_date", date());
+ }
+}
diff --git a/anda/devs/flutter/flutter.spec b/anda/devs/flutter/flutter.spec
index 23e2d41f8f..e6023679c9 100644
--- a/anda/devs/flutter/flutter.spec
+++ b/anda/devs/flutter/flutter.spec
@@ -1,5 +1,5 @@
Name: flutter
-Version: 3.22.2
+Version: 3.22.3
Release: 1%?dist
Summary: SDK for crafting beautiful, fast user experiences from a single codebase
License: BSD-3-Clause
diff --git a/anda/devs/kvrocks/anda.hcl b/anda/devs/kvrocks/anda.hcl
new file mode 100644
index 0000000000..0508a7c98d
--- /dev/null
+++ b/anda/devs/kvrocks/anda.hcl
@@ -0,0 +1,6 @@
+project pkg {
+ arches = ["x86_64", "aarch64"]
+ rpm {
+ spec = "kvrocks.spec"
+ }
+}
diff --git a/anda/devs/kvrocks/kvrocks.spec b/anda/devs/kvrocks/kvrocks.spec
new file mode 100644
index 0000000000..28013e819d
--- /dev/null
+++ b/anda/devs/kvrocks/kvrocks.spec
@@ -0,0 +1,50 @@
+Name: kvrocks
+Version: 2.9.0
+Release: 1%?dist
+Summary: Distributed key value NoSQL database that uses RocksDB
+License: Apache-2.0
+URL: https://kvrocks.apache.org/
+Source0: https://github.com/apache/kvrocks/archive/refs/tags/v%version.tar.gz
+Requires: openssl
+BuildRequires: autoconf
+BuildRequires: cmake
+BuildRequires: gcc-c++
+BuildRequires: git
+BuildRequires: openssl-devel
+BuildRequires: python3
+BuildRequires: systemd-rpm-macros
+
+%description
+Apache Kvrocks is a distributed key value NoSQL database that uses RocksDB as storage
+engine and is compatible with Redis protocol.
+
+%prep
+%autosetup
+
+%build
+unset LDFLAGS
+./x.py build -DPORTABLE=1 -DENABLE_STATIC_LIBSTDCXX=OFF -DENABLE_OPENSSL=ON -DCMAKE_BUILD_TYPE=Release --ghproxy -j $(nproc)
+
+%install
+mkdir -p %{buildroot}%{_bindir}
+mkdir -p %{buildroot}%{_datadir}
+
+install -pm755 build/%{name} %{buildroot}%{_bindir}/%{name}
+install -pm755 build/kvrocks2redis %{buildroot}%{_bindir}/kvrocks2redis
+
+install -pDm640 %{name}.conf %{buildroot}%{_sysconfdir}/%{name}/%{name}.conf
+install -pDm644 utils/systemd/%{name}.service %{buildroot}%{_unitdir}/%{name}.service
+
+%files
+%{_bindir}/%{name}
+%{_bindir}/kvrocks2redis
+%attr(0750, root, root) %dir %{_sysconfdir}/%{name}
+%attr(0640, root, root) %config(noreplace) %{_sysconfdir}/%{name}/%{name}.conf
+%{_unitdir}/%{name}.service
+%license LICENSE
+%license NOTICE
+%license licenses/LICENSE-*
+
+
+%changelog
+%autochangelog
diff --git a/anda/devs/kvrocks/update.rhai b/anda/devs/kvrocks/update.rhai
new file mode 100644
index 0000000000..0eb2758a9f
--- /dev/null
+++ b/anda/devs/kvrocks/update.rhai
@@ -0,0 +1 @@
+rpm.version(gh("apache/kvrocks"));
diff --git a/anda/devs/neovide/neovide.spec b/anda/devs/neovide/neovide.spec
index a7a721c352..b3dc4fc42e 100644
--- a/anda/devs/neovide/neovide.spec
+++ b/anda/devs/neovide/neovide.spec
@@ -1,7 +1,7 @@
%define debug_package %nil
Name: neovide
-Version: 0.13.2
+Version: 0.13.3
Release: 1%?dist
Summary: No Nonsense Neovim Client in Rust
License: MIT
diff --git a/anda/devs/zed/nightly/zed-nightly.spec b/anda/devs/zed/nightly/zed-nightly.spec
index 594e233c84..1b63bbdf7b 100644
--- a/anda/devs/zed/nightly/zed-nightly.spec
+++ b/anda/devs/zed/nightly/zed-nightly.spec
@@ -54,6 +54,8 @@ export APP_ID="%app_id"
export APP_ICON="%app_id"
export APP_NAME="Zed Nightly"
export APP_CLI="zed"
+export APP="%{_libexecdir}/zed-editor"
+export APP_ARGS="%U"
export ZED_UPDATE_EXPLANATION="Run dnf up to update Zed Nightly from Terra."
export ZED_RELEASE_CHANNEL=nightly
export BRANDING_LIGHT="#e9aa6a"
diff --git a/anda/devs/zed/preview/zed-preview.spec b/anda/devs/zed/preview/zed-preview.spec
index 45bf534d43..2bdd137b8a 100644
--- a/anda/devs/zed/preview/zed-preview.spec
+++ b/anda/devs/zed/preview/zed-preview.spec
@@ -1,6 +1,6 @@
%bcond_without check
%global debug_package %{nil}
-%global ver 0.144.2
+%global ver 0.145.1
%global crate zed
%global app_id dev.zed.Zed-Preview
@@ -48,6 +48,8 @@ export APP_ID="%app_id"
export APP_ICON="%app_id"
export APP_NAME="Zed Preview"
export APP_CLI="zed"
+export APP="%{_libexecdir}/zed-editor"
+export APP_ARGS="%U"
export ZED_UPDATE_EXPLANATION="Run dnf up to update Zed Preview from Terra."
export ZED_RELEASE_CHANNEL=preview
export BRANDING_LIGHT="#99c1f1"
diff --git a/anda/devs/zed/stable/zed.spec b/anda/devs/zed/stable/zed.spec
index 22549b080a..e3c5aebb56 100644
--- a/anda/devs/zed/stable/zed.spec
+++ b/anda/devs/zed/stable/zed.spec
@@ -7,7 +7,7 @@
%global app_id dev.zed.Zed
Name: zed
-Version: 0.143.7
+Version: 0.144.4
Release: 1%?dist
Summary: Zed is a high-performance, multiplayer code editor
@@ -50,6 +50,8 @@ export APP_ID="%app_id"
export APP_ICON="%app_id"
export APP_NAME="Zed Editor"
export APP_CLI="zed"
+export APP="%{_libexecdir}/zed-editor"
+export APP_ARGS="%U"
export ZED_UPDATE_EXPLANATION="Run dnf up to update Zed from Terra."
export ZED_RELEASE_CHANNEL=stable
export BRANDING_LIGHT="#e9aa6a"
diff --git a/anda/docker/containerd/containerd.spec b/anda/docker/containerd/containerd.spec
index c8a710ae35..2d253c883d 100644
--- a/anda/docker/containerd/containerd.spec
+++ b/anda/docker/containerd/containerd.spec
@@ -7,7 +7,7 @@
# https://github.com/containerd/containerd
%global goipath github.com/containerd/containerd
-Version: 1.7.19
+Version: 1.7.20
%gometa
diff --git a/anda/docker/moby-buildx/moby-buildx.spec b/anda/docker/moby-buildx/moby-buildx.spec
index 4c166d516e..e79073af02 100644
--- a/anda/docker/moby-buildx/moby-buildx.spec
+++ b/anda/docker/moby-buildx/moby-buildx.spec
@@ -1,7 +1,7 @@
%define debug_package %nil
Name: moby-buildx
-Version: 0.16.0
+Version: 0.16.1
Release: 1%?dist
Summary: Docker CLI plugin for extended build capabilities with BuildKit
diff --git a/anda/docker/moby-compose/moby-compose.spec b/anda/docker/moby-compose/moby-compose.spec
index fe6a4af9d7..27347b48ea 100644
--- a/anda/docker/moby-compose/moby-compose.spec
+++ b/anda/docker/moby-compose/moby-compose.spec
@@ -1,7 +1,7 @@
%define debug_package %{nil}
Name: moby-compose
-Version: 2.28.1
+Version: 2.29.0
Release: 1%?dist
Summary: Define and run multi-container applications with Docker
diff --git a/anda/games/gamescope-session-steam/anda.hcl b/anda/games/gamescope-session-steam/anda.hcl
new file mode 100644
index 0000000000..557b0d83d2
--- /dev/null
+++ b/anda/games/gamescope-session-steam/anda.hcl
@@ -0,0 +1,8 @@
+project pkg {
+ rpm {
+ spec = "gamescope-session-steam.spec"
+ }
+ labels {
+ nightly = 1
+ }
+}
diff --git a/anda/games/gamescope-session-steam/gamescope-session-steam.spec b/anda/games/gamescope-session-steam/gamescope-session-steam.spec
new file mode 100644
index 0000000000..8cf4b0533c
--- /dev/null
+++ b/anda/games/gamescope-session-steam/gamescope-session-steam.spec
@@ -0,0 +1,40 @@
+%define debug_package %nil
+
+%global commit 015e09825d4f9a2dfdbc20fc2711e2dcee2af68a
+%global shortcommit %(c=%{commit}; echo ${c:0:7})
+%global commit_date 20240719
+
+Name: gamescope-session-steam
+Version: %commit_date.%shortcommit
+Release: 1%?dist
+Summary: gamescope-session-steam
+License: MIT
+URL: https://github.com/ChimeraOS/gamescope-session-steam
+Source0: %url/archive/%commit.tar.gz
+
+%description
+%summary.
+
+%prep
+%autosetup -n %name-%commit
+
+%build
+
+%install
+mkdir -p %buildroot
+cp -r usr %buildroot/
+
+%files
+%license LICENSE
+%_bindir/steamos-polkit-helpers/
+%_bindir/jupiter-biosupdate
+%_bindir/steam-http-loader
+%_bindir/steamos-select-branch
+%_bindir/steamos-session-select
+%_bindir/steamos-update
+%_datadir/applications/gamescope-mimeapps.list
+%_datadir/applications/steam_http_loader.desktop
+%_datadir/gamescope-session-plus/sessions.d/steam
+%_datadir/polkit-1/actions/org.chimeraos.update.policy
+%_datadir/wayland-sessions/gamescope-session-steam.desktop
+%_datadir/wayland-sessions/gamescope-session.desktop
diff --git a/anda/games/gamescope-session-steam/update.rhai b/anda/games/gamescope-session-steam/update.rhai
new file mode 100644
index 0000000000..35c20f6c72
--- /dev/null
+++ b/anda/games/gamescope-session-steam/update.rhai
@@ -0,0 +1,7 @@
+if filters.contains("nightly") {
+ rpm.global("commit", gh_commit("ChimeraOS/gamescope-session-steam"));
+ if rpm.changed() {
+ rpm.release();
+ rpm.global("commit_date", date());
+ }
+}
diff --git a/anda/games/gamescope-session/anda.hcl b/anda/games/gamescope-session/anda.hcl
new file mode 100644
index 0000000000..e2d33a48b1
--- /dev/null
+++ b/anda/games/gamescope-session/anda.hcl
@@ -0,0 +1,8 @@
+project pkg {
+ rpm {
+ spec = "gamescope-session.spec"
+ }
+ labels {
+ nightly = 1
+ }
+}
diff --git a/anda/games/gamescope-session/gamescope-session.spec b/anda/games/gamescope-session/gamescope-session.spec
new file mode 100644
index 0000000000..d552c2a0cf
--- /dev/null
+++ b/anda/games/gamescope-session/gamescope-session.spec
@@ -0,0 +1,35 @@
+%define debug_package %nil
+
+%global commit 4aa204e6ef332457d277488ffa61959f2dcde470
+%global shortcommit %(c=%{commit}; echo ${c:0:7})
+%global commit_date 20240719
+
+Name: gamescope-session
+Version: %commit_date.%shortcommit
+Release: 1%?dist
+Summary: ChimeraOS session on Gamescope
+License: MIT
+URL: https://github.com/ChimeraOS/gamescope-session
+Source0: %url/archive/%commit.tar.gz
+BuildRequires: systemd-rpm-macros
+
+%description
+Gamescope session plus based on Valve's gamescope.
+
+%prep
+%autosetup -n gamescope-session-%commit
+
+%build
+
+%install
+mkdir -p %buildroot
+cp -r usr %buildroot/
+
+%files
+%doc README.md
+%license LICENSE
+%_bindir/export-gpu
+%_bindir/gamescope-session-plus
+%_userunitdir/gamescope-session-plus@.service
+%_datadir/gamescope-session-plus/device-quirks
+%_datadir/gamescope-session-plus/gamescope-session-plus
diff --git a/anda/games/gamescope-session/update.rhai b/anda/games/gamescope-session/update.rhai
new file mode 100644
index 0000000000..bb1b270640
--- /dev/null
+++ b/anda/games/gamescope-session/update.rhai
@@ -0,0 +1,7 @@
+if filters.contains("nightly") {
+ rpm.global("commit", gh_commit("ChimeraOS/gamescope-session"));
+ if rpm.changed() {
+ rpm.release();
+ rpm.global("commit_date", date());
+ }
+}
diff --git a/anda/games/gamescope/1231.patch b/anda/games/gamescope/1231.patch
new file mode 100644
index 0000000000..e21cb0a8ea
--- /dev/null
+++ b/anda/games/gamescope/1231.patch
@@ -0,0 +1,239 @@
+From ab115896be1a448bde0eb7673c26300ea4ca5040 Mon Sep 17 00:00:00 2001
+From: sharkautarch <128002472+sharkautarch@users.noreply.github.com>
+Date: Sun, 19 May 2024 20:15:36 -0400
+Subject: [PATCH 1/2] QueuePresent: canBypassXWayland(): fetch multiple xcb
+ cookies initially before waiting on any of them
+
+---
+ layer/VkLayer_FROG_gamescope_wsi.cpp | 1 +
+ layer/xcb_helpers.hpp | 105 +++++++++++++++++++++++----
+ 2 files changed, 93 insertions(+), 13 deletions(-)
+
+diff --git a/layer/VkLayer_FROG_gamescope_wsi.cpp b/layer/VkLayer_FROG_gamescope_wsi.cpp
+index 5844c2a63..ca44849f2 100644
+--- a/layer/VkLayer_FROG_gamescope_wsi.cpp
++++ b/layer/VkLayer_FROG_gamescope_wsi.cpp
+@@ -975,6 +975,7 @@ namespace GamescopeWSILayer {
+ continue;
+ }
+
++ xcb::Prefetcher prefetcher(gamescopeSurface->connection, gamescopeSurface->window);
+ const bool canBypass = gamescopeSurface->canBypassXWayland();
+ if (canBypass != gamescopeSwapchain->isBypassingXWayland)
+ UpdateSwapchainResult(canBypass ? VK_SUBOPTIMAL_KHR : VK_ERROR_OUT_OF_DATE_KHR);
+diff --git a/layer/xcb_helpers.hpp b/layer/xcb_helpers.hpp
+index 8fac5635b..72d0ec092 100644
+--- a/layer/xcb_helpers.hpp
++++ b/layer/xcb_helpers.hpp
+@@ -4,22 +4,106 @@
+ #include
+ #include
+ #include
++#include
+
+ namespace xcb {
++ inline static constinit pthread_t g_cache_tid; //incase g_cache could otherwise be accessed by one thread, while it is being deleted by another thread
++ inline static constinit struct cookie_cache_t {
++ xcb_window_t window;
++ std::tuple cached_cookies;
++ std::tuple cached_replies;
++ } g_cache = {};
++
++ //Note: this class is currently only meant to be used within GamescopeWSILayer::VkDeviceOverrides::QueuePresentKHR:
++ struct Prefetcher {
++ explicit Prefetcher(xcb_connection_t* connection, const xcb_window_t window) {
++ g_cache = {
++ .window = window,
++ .cached_cookies = {
++ xcb_get_geometry(connection, window),
++ xcb_query_tree(connection, window)
++ }
++ };
++ g_cache_tid = pthread_self();
++ }
+
++ ~Prefetcher() {
++ g_cache_tid = {};
++ free(std::get<0>(g_cache.cached_replies));
++ free(std::get<1>(g_cache.cached_replies));
++ g_cache.cached_replies = {nullptr,nullptr};
++ }
++ };
++
+ struct ReplyDeleter {
++ const bool m_bOwning = true;
++ consteval ReplyDeleter(bool bOwning = true) : m_bOwning{bOwning} {}
+ template
+ void operator()(T* ptr) const {
+- free(const_cast*>(ptr));
++ if (m_bOwning)
++ free(const_cast*>(ptr));
+ }
+ };
+
+ template
+ using Reply = std::unique_ptr;
++
++ template
++ class XcbFetch {
++ using cookie_f_ptr_t = Cookie_RetType (*)(XcbConn, Args...);
++ using reply_f_ptr_t = Reply_RetType* (*)(XcbConn, Cookie_RetType, xcb_generic_error_t**);
++
++ const cookie_f_ptr_t m_cookieFunc;
++ const reply_f_ptr_t m_replyFunc;
++
++ public:
++ consteval XcbFetch(cookie_f_ptr_t cookieFunc, reply_f_ptr_t replyFunc) : m_cookieFunc{cookieFunc}, m_replyFunc{replyFunc} {}
++
++ inline Reply operator()(XcbConn conn, auto... args) { //have to use auto for argsTwo, since otherwise there'd be a type deduction conflict
++ return Reply { m_replyFunc(conn, m_cookieFunc(conn, args...), nullptr) };
++ }
++ };
++
++ template
++ concept CacheableCookie = std::is_same::value
++ || std::is_same::value;
++
++ template
++ class XcbFetch {
++ using cookie_f_ptr_t = Cookie_RetType (*)(xcb_connection_t*, xcb_window_t);
++ using reply_f_ptr_t = Reply_RetType* (*)(xcb_connection_t*, Cookie_RetType, xcb_generic_error_t**);
++
++ const cookie_f_ptr_t m_cookieFunc;
++ const reply_f_ptr_t m_replyFunc;
++
++ inline Reply getCachedReply(xcb_connection_t* connection) {
++ if (std::get(g_cache.cached_replies) == nullptr) {
++ std::get(g_cache.cached_replies) = m_replyFunc(connection, std::get(g_cache.cached_cookies), nullptr);
++ }
+
++ return Reply{std::get(g_cache.cached_replies), ReplyDeleter{false}}; // return 'non-owning' unique_ptr
++ }
++
++ public:
++ consteval XcbFetch(cookie_f_ptr_t cookieFunc, reply_f_ptr_t replyFunc) : m_cookieFunc{cookieFunc}, m_replyFunc{replyFunc} {}
++
++ inline Reply operator()(xcb_connection_t* conn, xcb_window_t window) {
++ const bool tryCached = pthread_equal(g_cache_tid, pthread_self())
++ && g_cache.window == window;
++ if (!tryCached) [[unlikely]]
++ return Reply { m_replyFunc(conn, m_cookieFunc(conn, window), nullptr) };
++
++ auto ret = getCachedReply(conn);
++ #if !defined(NDEBUG) || NDEBUG == 0
++ if (!ret)
++ fprintf(stderr, "[Gamescope WSI] getCachedReply() failed.\n");
++ #endif
++ return ret;
++ }
++ };
++
+ static std::optional getAtom(xcb_connection_t* connection, std::string_view name) {
+- xcb_intern_atom_cookie_t cookie = xcb_intern_atom(connection, false, name.length(), name.data());
+- auto reply = Reply{ xcb_intern_atom_reply(connection, cookie, nullptr) };
++ auto reply = XcbFetch{xcb_intern_atom, xcb_intern_atom_reply}(connection, false, name.length(), name.data());
+ if (!reply) {
+ fprintf(stderr, "[Gamescope WSI] Failed to get xcb atom.\n");
+ return std::nullopt;
+@@ -34,8 +118,7 @@ namespace xcb {
+
+ xcb_screen_t* screen = xcb_setup_roots_iterator(xcb_get_setup(connection)).data;
+
+- xcb_get_property_cookie_t cookie = xcb_get_property(connection, false, screen->root, atom, XCB_ATOM_CARDINAL, 0, sizeof(T) / sizeof(uint32_t));
+- auto reply = Reply{ xcb_get_property_reply(connection, cookie, nullptr) };
++ auto reply = XcbFetch{xcb_get_property, xcb_get_property_reply}(connection, false, screen->root, atom, XCB_ATOM_CARDINAL, 0, sizeof(T) / sizeof(uint32_t));
+ if (!reply) {
+ fprintf(stderr, "[Gamescope WSI] Failed to read T root window property.\n");
+ return std::nullopt;
+@@ -61,8 +144,7 @@ namespace xcb {
+
+ static std::optional getToplevelWindow(xcb_connection_t* connection, xcb_window_t window) {
+ for (;;) {
+- xcb_query_tree_cookie_t cookie = xcb_query_tree(connection, window);
+- auto reply = Reply{ xcb_query_tree_reply(connection, cookie, nullptr) };
++ auto reply = XcbFetch{xcb_query_tree, xcb_query_tree_reply}(connection, window);
+
+ if (!reply) {
+ fprintf(stderr, "[Gamescope WSI] getToplevelWindow: xcb_query_tree failed for window 0x%x.\n", window);
+@@ -77,8 +159,7 @@ namespace xcb {
+ }
+
+ static std::optional getWindowRect(xcb_connection_t* connection, xcb_window_t window) {
+- xcb_get_geometry_cookie_t cookie = xcb_get_geometry(connection, window);
+- auto reply = Reply{ xcb_get_geometry_reply(connection, cookie, nullptr) };
++ auto reply = XcbFetch{xcb_get_geometry, xcb_get_geometry_reply}(connection, window);
+ if (!reply) {
+ fprintf(stderr, "[Gamescope WSI] getWindowRect: xcb_get_geometry failed for window 0x%x.\n", window);
+ return std::nullopt;
+@@ -112,8 +193,7 @@ namespace xcb {
+ static std::optional getLargestObscuringChildWindowSize(xcb_connection_t* connection, xcb_window_t window) {
+ VkExtent2D largestExtent = {};
+
+- xcb_query_tree_cookie_t cookie = xcb_query_tree(connection, window);
+- auto reply = Reply{ xcb_query_tree_reply(connection, cookie, nullptr) };
++ auto reply = XcbFetch{xcb_query_tree, xcb_query_tree_reply}(connection, window);
+
+ if (!reply) {
+ fprintf(stderr, "[Gamescope WSI] getLargestObscuringWindowSize: xcb_query_tree failed for window 0x%x.\n", window);
+@@ -130,8 +210,7 @@ namespace xcb {
+ for (uint32_t i = 0; i < reply->children_len; i++) {
+ xcb_window_t child = children[i];
+
+- xcb_get_window_attributes_cookie_t attributeCookie = xcb_get_window_attributes(connection, child);
+- auto attributeReply = Reply{ xcb_get_window_attributes_reply(connection, attributeCookie, nullptr) };
++ auto attributeReply = XcbFetch{xcb_get_window_attributes, xcb_get_window_attributes_reply}(connection, child);
+
+ const bool obscuring =
+ attributeReply &&
+
+From 1b59621f4de5c05096d1f279cba2e04264124154 Mon Sep 17 00:00:00 2001
+From: sharkautarch <128002472+sharkautarch@users.noreply.github.com>
+Date: Tue, 18 Jun 2024 22:21:23 -0400
+Subject: [PATCH 2/2] WSI: prefetcher: fix issue w/ attempting to prefetch xcb
+ stuff for pure wayland surfaces
+
+---
+ layer/VkLayer_FROG_gamescope_wsi.cpp | 2 +-
+ layer/xcb_helpers.hpp | 9 ++++++++-
+ 2 files changed, 9 insertions(+), 2 deletions(-)
+
+diff --git a/layer/VkLayer_FROG_gamescope_wsi.cpp b/layer/VkLayer_FROG_gamescope_wsi.cpp
+index f26819a60..ce011dcd7 100644
+--- a/layer/VkLayer_FROG_gamescope_wsi.cpp
++++ b/layer/VkLayer_FROG_gamescope_wsi.cpp
+@@ -1234,7 +1234,7 @@ namespace GamescopeWSILayer {
+ continue;
+ }
+
+- xcb::Prefetcher prefetcher(gamescopeSurface->connection, gamescopeSurface->window);
++ auto prefetcher = xcb::Prefetcher::GetPrefetcherIf(!gamescopeSurface->isWayland(), gamescopeSurface->connection, gamescopeSurface->window);
+ const bool canBypass = gamescopeSurface->canBypassXWayland();
+ if (canBypass != gamescopeSwapchain->isBypassingXWayland)
+ UpdateSwapchainResult(canBypass ? VK_SUBOPTIMAL_KHR : VK_ERROR_OUT_OF_DATE_KHR);
+diff --git a/layer/xcb_helpers.hpp b/layer/xcb_helpers.hpp
+index 72d0ec092..f26aef38b 100644
+--- a/layer/xcb_helpers.hpp
++++ b/layer/xcb_helpers.hpp
+@@ -16,6 +16,13 @@ namespace xcb {
+
+ //Note: this class is currently only meant to be used within GamescopeWSILayer::VkDeviceOverrides::QueuePresentKHR:
+ struct Prefetcher {
++ static std::optional GetPrefetcherIf(bool bCond, xcb_connection_t* connection, const xcb_window_t window) {
++ if (bCond)
++ return std::optional(std::in_place_t{}, connection, window);
++
++ return std::nullopt;
++ }
++
+ explicit Prefetcher(xcb_connection_t* connection, const xcb_window_t window) {
+ g_cache = {
+ .window = window,
+@@ -90,7 +97,7 @@ namespace xcb {
+ inline Reply operator()(xcb_connection_t* conn, xcb_window_t window) {
+ const bool tryCached = pthread_equal(g_cache_tid, pthread_self())
+ && g_cache.window == window;
+- if (!tryCached) [[unlikely]]
++ if (!tryCached)
+ return Reply { m_replyFunc(conn, m_cookieFunc(conn, window), nullptr) };
+
+ auto ret = getCachedReply(conn);
diff --git a/anda/games/gamescope/anda.hcl b/anda/games/gamescope/anda.hcl
new file mode 100644
index 0000000000..cd18050ddc
--- /dev/null
+++ b/anda/games/gamescope/anda.hcl
@@ -0,0 +1,8 @@
+project pkg {
+ rpm {
+ spec = "terra-gamescope.spec"
+ }
+ labels {
+ multilib = 1
+ }
+}
diff --git a/anda/games/gamescope/chimeraos.patch b/anda/games/gamescope/chimeraos.patch
new file mode 100644
index 0000000000..80cc642b3d
--- /dev/null
+++ b/anda/games/gamescope/chimeraos.patch
@@ -0,0 +1,2028 @@
+From c06cdd847679c930ee6197514970bc21f523e853 Mon Sep 17 00:00:00 2001
+From: Matthew Anderson
+Date: Fri, 17 May 2024 19:43:49 -0500
+Subject: [PATCH 01/22] Add touch-gestures to open up Steam menus
+
+---
+ src/main.cpp | 5 +++++
+ src/wlserver.cpp | 28 ++++++++++++++++++++++++++++
+ src/wlserver.hpp | 1 +
+ 3 files changed, 34 insertions(+)
+
+diff --git a/src/main.cpp b/src/main.cpp
+index cd4aeca..4b91c97 100644
+--- a/src/main.cpp
++++ b/src/main.cpp
+@@ -108,6 +108,8 @@ const struct option *gamescope_options = (struct option[]){
+
+ // wlserver options
+ { "xwayland-count", required_argument, nullptr, 0 },
++ { "touch-gestures", no_argument, nullptr, 0 },
++
+
+ // steamcompmgr options
+ { "cursor", required_argument, nullptr, 0 },
+@@ -185,6 +187,7 @@ const char usage[] =
+ " -T, --stats-path write statistics to path\n"
+ " -C, --hide-cursor-delay hide cursor image after delay\n"
+ " -e, --steam enable Steam integration\n"
++ " --touch-gestures enable touch gestures for Steam menus\n"
+ " --xwayland-count create N xwayland servers\n"
+ " --prefer-vk-device prefer Vulkan device for compositing (ex: 1002:7300)\n"
+ " --force-orientation rotate the internal display (left, right, normal, upsidedown)\n"
+@@ -734,6 +737,8 @@ int main(int argc, char **argv)
+ g_bDebugLayers = true;
+ } else if (strcmp(opt_name, "disable-color-management") == 0) {
+ g_bForceDisableColorMgmt = true;
++ } else if (strcmp(opt_name, "touch-gestures") == 0) {
++ cv_touch_gestures = true;
+ } else if (strcmp(opt_name, "xwayland-count") == 0) {
+ g_nXWaylandCount = atoi( optarg );
+ } else if (strcmp(opt_name, "composite-debug") == 0) {
+diff --git a/src/wlserver.cpp b/src/wlserver.cpp
+index ee6891d..62da656 100644
+--- a/src/wlserver.cpp
++++ b/src/wlserver.cpp
+@@ -73,6 +73,7 @@
+ static LogScope wl_log("wlserver");
+
+ //#define GAMESCOPE_SWAPCHAIN_DEBUG
++gamescope::ConVar cv_touch_gestures( "enable_touch_gestures", false, "Enable/Disable the usage of touch gestures" );
+
+ struct wlserver_t wlserver = {
+ .touch_down_ids = {}
+@@ -2568,6 +2569,33 @@ void wlserver_touchmotion( double x, double y, int touch_id, uint32_t time, bool
+
+ if ( bAlwaysWarpCursor )
+ wlserver_mousewarp( tx, ty, time, false );
++
++ if (cv_touch_gestures) {
++ bool start_gesture = false;
++
++ // Round the x-coordinate to the nearest whole number
++ uint32_t roundedCursorX = static_cast(std::round(tx));
++ // Grab 2% of the display to be used for the edge range
++ uint32_t edge_range = static_cast(g_nOutputWidth * 0.02);
++
++ // Determine if the gesture should start
++ if (roundedCursorX <= edge_range || roundedCursorX >= g_nOutputWidth - edge_range) {
++ start_gesture = true;
++ }
++
++ // Handle Home gesture
++ if (start_gesture && roundedCursorX >= edge_range) {
++ wlserver_open_steam_menu(0);
++ start_gesture = false;
++ }
++
++ // Handle QAM gesture
++ if (start_gesture && roundedCursorX >= g_nOutputWidth - edge_range && roundedCursorX <= g_nOutputWidth) {
++ wlserver_open_steam_menu(1);
++ start_gesture = false;
++ }
++ }
++
+ }
+ else if ( eMode == gamescope::TouchClickModes::Disabled )
+ {
+diff --git a/src/wlserver.hpp b/src/wlserver.hpp
+index db7d491..da67bf7 100644
+--- a/src/wlserver.hpp
++++ b/src/wlserver.hpp
+@@ -291,6 +291,7 @@ void wlserver_x11_surface_info_finish( struct wlserver_x11_surface_info *surf );
+ void wlserver_set_xwayland_server_mode( size_t idx, int w, int h, int refresh );
+
+ extern std::atomic g_bPendingTouchMovement;
++extern gamescope::ConVar cv_touch_gestures;
+
+ void wlserver_open_steam_menu( bool qam );
+
+--
+2.45.2
+
+
+From 34f22c6a52dbed8662132e4bdfd8a29dd1b7825c Mon Sep 17 00:00:00 2001
+From: Matthew Anderson
+Date: Fri, 17 May 2024 20:16:20 -0500
+Subject: [PATCH 02/22] Add bypass_steam_resolution to workaround the 720p/800p
+ restrictions Steam has for games
+
+---
+ src/main.cpp | 3 +++
+ src/steamcompmgr.cpp | 11 +++++++++++
+ 2 files changed, 14 insertions(+)
+
+diff --git a/src/main.cpp b/src/main.cpp
+index 4b91c97..3d1057a 100644
+--- a/src/main.cpp
++++ b/src/main.cpp
+@@ -129,6 +129,8 @@ const struct option *gamescope_options = (struct option[]){
+ { "fade-out-duration", required_argument, nullptr, 0 },
+ { "force-orientation", required_argument, nullptr, 0 },
+ { "force-windows-fullscreen", no_argument, nullptr, 0 },
++ { "bypass-steam-resolution", no_argument, nullptr, 0 },
++
+
+ { "disable-color-management", no_argument, nullptr, 0 },
+ { "sdr-gamut-wideness", required_argument, nullptr, 0 },
+@@ -187,6 +189,7 @@ const char usage[] =
+ " -T, --stats-path write statistics to path\n"
+ " -C, --hide-cursor-delay hide cursor image after delay\n"
+ " -e, --steam enable Steam integration\n"
++ " --bypass-steam-resolution bypass Steam's default 720p/800p default resolution\n"
+ " --touch-gestures enable touch gestures for Steam menus\n"
+ " --xwayland-count create N xwayland servers\n"
+ " --prefer-vk-device prefer Vulkan device for compositing (ex: 1002:7300)\n"
+diff --git a/src/steamcompmgr.cpp b/src/steamcompmgr.cpp
+index 9ee265d..bec4268 100644
+--- a/src/steamcompmgr.cpp
++++ b/src/steamcompmgr.cpp
+@@ -349,6 +349,8 @@ bool g_bForceHDR10OutputDebug = false;
+ gamescope::ConVar cv_hdr_enabled{ "hdr_enabled", false, "Whether or not HDR is enabled if it is available." };
+ bool g_bHDRItmEnable = false;
+ int g_nCurrentRefreshRate_CachedValue = 0;
++gamescope::ConVar cv_bypass_steam_resolution{ "bypass_steam_resolution", false, "Workaround the 720p/800p limits Steam uses for games" };
++
+
+ static void
+ update_color_mgmt()
+@@ -5320,6 +5322,13 @@ handle_property_notify(xwayland_ctx_t *ctx, XPropertyEvent *ev)
+ size_t server_idx = size_t{ xwayland_mode_ctl[ 0 ] };
+ int width = xwayland_mode_ctl[ 1 ];
+ int height = xwayland_mode_ctl[ 2 ];
++
++ if ( g_nOutputWidth != 1280 && width == 1280 && cv_bypass_steam_resolution )
++ {
++ width = g_nOutputWidth;
++ height = g_nOutputHeight;
++ }
++
+ bool allowSuperRes = !!xwayland_mode_ctl[ 3 ];
+
+ if ( !allowSuperRes )
+@@ -7166,6 +7175,8 @@ steamcompmgr_main(int argc, char **argv)
+ bForceWindowsFullscreen = true;
+ } else if (strcmp(opt_name, "hdr-enabled") == 0) {
+ cv_hdr_enabled = true;
++ } else if (strcmp(opt_name, "bypass_steam_resolution") == 0) {
++ cv_bypass_steam_resolution = true;
+ } else if (strcmp(opt_name, "hdr-debug-force-support") == 0) {
+ g_bForceHDRSupportDebug = true;
+ } else if (strcmp(opt_name, "hdr-debug-force-output") == 0) {
+--
+2.45.2
+
+
+From 4c5657cca9a37fee0eee1d86ef3c2a6e5acef09c Mon Sep 17 00:00:00 2001
+From: Matthew Anderson
+Date: Wed, 26 Jul 2023 20:46:29 -0500
+Subject: [PATCH 03/22] Add force external orientation.
+
+Co-authored-by: Bouke Sybren Haarsma
+---
+ src/Backends/DRMBackend.cpp | 5 +++++
+ src/main.cpp | 25 ++++++++++++++++++++++++-
+ src/main.hpp | 1 +
+ src/wlserver.cpp | 23 +++++++++++++++++++++++
+ 4 files changed, 53 insertions(+), 1 deletion(-)
+
+diff --git a/src/Backends/DRMBackend.cpp b/src/Backends/DRMBackend.cpp
+index 92f01ca..4c72dc1 100644
+--- a/src/Backends/DRMBackend.cpp
++++ b/src/Backends/DRMBackend.cpp
+@@ -536,6 +536,7 @@ bool g_bSupportsSyncObjs = false;
+
+ extern gamescope::GamescopeModeGeneration g_eGamescopeModeGeneration;
+ extern GamescopePanelOrientation g_DesiredInternalOrientation;
++extern GamescopePanelOrientation g_DesiredExternalOrientation;
+
+ extern bool g_bForceDisableColorMgmt;
+
+@@ -2023,6 +2024,10 @@ namespace gamescope
+ {
+ m_ChosenOrientation = g_DesiredInternalOrientation;
+ }
++ else if ( this->GetScreenType() == GAMESCOPE_SCREEN_TYPE_EXTERNAL && g_DesiredExternalOrientation != GAMESCOPE_PANEL_ORIENTATION_AUTO )
++ {
++ m_ChosenOrientation = g_DesiredExternalOrientation;
++ }
+ else
+ {
+ if ( this->GetProperties().panel_orientation )
+diff --git a/src/main.cpp b/src/main.cpp
+index 3d1057a..fac3df2 100644
+--- a/src/main.cpp
++++ b/src/main.cpp
+@@ -128,6 +128,7 @@ const struct option *gamescope_options = (struct option[]){
+ { "disable-xres", no_argument, nullptr, 'x' },
+ { "fade-out-duration", required_argument, nullptr, 0 },
+ { "force-orientation", required_argument, nullptr, 0 },
++ { "force-external-orientation", required_argument, nullptr, 0 },
+ { "force-windows-fullscreen", no_argument, nullptr, 0 },
+ { "bypass-steam-resolution", no_argument, nullptr, 0 },
+
+@@ -194,6 +195,7 @@ const char usage[] =
+ " --xwayland-count create N xwayland servers\n"
+ " --prefer-vk-device prefer Vulkan device for compositing (ex: 1002:7300)\n"
+ " --force-orientation rotate the internal display (left, right, normal, upsidedown)\n"
++ " --force-external-orientation rotate the external display (left, right, normal, upsidedown)\n"
+ " --force-windows-fullscreen force windows inside of gamescope to be the size of the nested display (fullscreen)\n"
+ " --cursor-scale-height if specified, sets a base output height to linearly scale the cursor against.\n"
+ " --hdr-enabled enable HDR output (needs Gamescope WSI layer enabled for support from clients)\n"
+@@ -289,6 +291,8 @@ bool g_bOutputHDREnabled = false;
+ bool g_bFullscreen = false;
+ bool g_bForceRelativeMouse = false;
+
++bool g_bExternalForced = false;
++
+ bool g_bGrabbed = false;
+
+ float g_mouseSensitivity = 1.0;
+@@ -362,7 +366,24 @@ static GamescopePanelOrientation force_orientation(const char *str)
+ } else if (strcmp(str, "upsidedown") == 0) {
+ return GAMESCOPE_PANEL_ORIENTATION_180;
+ } else {
+- fprintf( stderr, "gamescope: invalid value for --force-orientation\n" );
++ fprintf( stderr, "gamescope: invalid value for given for --force-orientation\n" );
++ exit(1);
++ }
++}
++
++GamescopePanelOrientation g_DesiredExternalOrientation = GAMESCOPE_PANEL_ORIENTATION_AUTO;
++static GamescopePanelOrientation force_external_orientation(const char *str)
++{
++ if (strcmp(str, "normal") == 0) {
++ return GAMESCOPE_PANEL_ORIENTATION_0;
++ } else if (strcmp(str, "right") == 0) {
++ return GAMESCOPE_PANEL_ORIENTATION_270;
++ } else if (strcmp(str, "left") == 0) {
++ return GAMESCOPE_PANEL_ORIENTATION_90;
++ } else if (strcmp(str, "upsidedown") == 0) {
++ return GAMESCOPE_PANEL_ORIENTATION_180;
++ } else {
++ fprintf( stderr, "gamescope: invalid value for --force-external-orientation\n" );
+ exit(1);
+ }
+ }
+@@ -755,6 +776,8 @@ int main(int argc, char **argv)
+ g_eGamescopeModeGeneration = parse_gamescope_mode_generation( optarg );
+ } else if (strcmp(opt_name, "force-orientation") == 0) {
+ g_DesiredInternalOrientation = force_orientation( optarg );
++ } else if (strcmp(opt_name, "force-external-orientation") == 0) {
++ g_DesiredExternalOrientation = force_external_orientation( optarg );
+ } else if (strcmp(opt_name, "sharpness") == 0 ||
+ strcmp(opt_name, "fsr-sharpness") == 0) {
+ g_upscaleFilterSharpness = atoi( optarg );
+diff --git a/src/main.hpp b/src/main.hpp
+index 8cfe629..5492cae 100644
+--- a/src/main.hpp
++++ b/src/main.hpp
+@@ -28,6 +28,7 @@ extern bool g_bGrabbed;
+
+ extern float g_mouseSensitivity;
+ extern const char *g_sOutputName;
++extern bool g_bExternalForced;
+
+ enum class GamescopeUpscaleFilter : uint32_t
+ {
+diff --git a/src/wlserver.cpp b/src/wlserver.cpp
+index 62da656..2998aed 100644
+--- a/src/wlserver.cpp
++++ b/src/wlserver.cpp
+@@ -2530,6 +2530,29 @@ static void apply_touchscreen_orientation(double *x, double *y )
+ break;
+ }
+
++ // Rotate screen if it's forced with --force-external-orientation
++ switch ( GetBackend()->GetConnector( gamescope::GAMESCOPE_SCREEN_TYPE_EXTERNAL )->GetCurrentOrientation() )
++ {
++ default:
++ case GAMESCOPE_PANEL_ORIENTATION_AUTO:
++ case GAMESCOPE_PANEL_ORIENTATION_0:
++ tx = *x;
++ ty = *y;
++ break;
++ case GAMESCOPE_PANEL_ORIENTATION_90:
++ tx = 1.0 - *y;
++ ty = *x;
++ break;
++ case GAMESCOPE_PANEL_ORIENTATION_180:
++ tx = 1.0 - *x;
++ ty = 1.0 - *y;
++ break;
++ case GAMESCOPE_PANEL_ORIENTATION_270:
++ tx = *y;
++ ty = 1.0 - *x;
++ break;
++ }
++
+ *x = tx;
+ *y = ty;
+ }
+--
+2.45.2
+
+
+From 897032bb4b8d8d5c11d67f9844a09a604b2c4333 Mon Sep 17 00:00:00 2001
+From: Bouke Sybren Haarsma
+Date: Tue, 12 Mar 2024 00:07:57 +0100
+Subject: [PATCH 04/22] implement force-panel-type
+
+---
+ src/backend.h | 3 +++
+ src/gamescope_shared.h | 1 +
+ src/main.cpp | 16 ++++++++++++++++
+ 3 files changed, 20 insertions(+)
+
+diff --git a/src/backend.h b/src/backend.h
+index 9c2db15..046eb10 100644
+--- a/src/backend.h
++++ b/src/backend.h
+@@ -17,6 +17,7 @@ struct wlr_buffer;
+ struct wlr_dmabuf_attributes;
+
+ struct FrameInfo_t;
++extern gamescope::GamescopeScreenType g_ForcedScreenType;
+
+ namespace gamescope
+ {
+@@ -213,6 +214,8 @@ namespace gamescope
+ // Dumb helper we should remove to support multi display someday.
+ gamescope::GamescopeScreenType GetScreenType()
+ {
++ if (g_ForcedScreenType != GAMESCOPE_SCREEN_TYPE_AUTO)
++ return g_ForcedScreenType;
+ if ( GetCurrentConnector() )
+ return GetCurrentConnector()->GetScreenType();
+
+diff --git a/src/gamescope_shared.h b/src/gamescope_shared.h
+index f34174e..ed30d8c 100644
+--- a/src/gamescope_shared.h
++++ b/src/gamescope_shared.h
+@@ -22,6 +22,7 @@ namespace gamescope
+ {
+ GAMESCOPE_SCREEN_TYPE_INTERNAL,
+ GAMESCOPE_SCREEN_TYPE_EXTERNAL,
++ GAMESCOPE_SCREEN_TYPE_AUTO,
+
+ GAMESCOPE_SCREEN_TYPE_COUNT
+ };
+diff --git a/src/main.cpp b/src/main.cpp
+index fac3df2..8bea38c 100644
+--- a/src/main.cpp
++++ b/src/main.cpp
+@@ -129,6 +129,7 @@ const struct option *gamescope_options = (struct option[]){
+ { "fade-out-duration", required_argument, nullptr, 0 },
+ { "force-orientation", required_argument, nullptr, 0 },
+ { "force-external-orientation", required_argument, nullptr, 0 },
++ { "force-panel-type", required_argument, nullptr, 0 },
+ { "force-windows-fullscreen", no_argument, nullptr, 0 },
+ { "bypass-steam-resolution", no_argument, nullptr, 0 },
+
+@@ -196,6 +197,7 @@ const char usage[] =
+ " --prefer-vk-device prefer Vulkan device for compositing (ex: 1002:7300)\n"
+ " --force-orientation rotate the internal display (left, right, normal, upsidedown)\n"
+ " --force-external-orientation rotate the external display (left, right, normal, upsidedown)\n"
++ " --force-panel-type force gamescope to treat the display as either internal or external\n"
+ " --force-windows-fullscreen force windows inside of gamescope to be the size of the nested display (fullscreen)\n"
+ " --cursor-scale-height if specified, sets a base output height to linearly scale the cursor against.\n"
+ " --hdr-enabled enable HDR output (needs Gamescope WSI layer enabled for support from clients)\n"
+@@ -387,6 +389,18 @@ static GamescopePanelOrientation force_external_orientation(const char *str)
+ exit(1);
+ }
+ }
++gamescope::GamescopeScreenType g_ForcedScreenType = gamescope::GAMESCOPE_SCREEN_TYPE_AUTO;
++static gamescope::GamescopeScreenType force_panel_type(const char *str)
++{
++ if (strcmp(str, "internal") == 0) {
++ return gamescope::GAMESCOPE_SCREEN_TYPE_INTERNAL;
++ } else if (strcmp(str, "external") == 0) {
++ return gamescope::GAMESCOPE_SCREEN_TYPE_EXTERNAL;
++ } else {
++ fprintf( stderr, "gamescope: invalid value for --force-panel-type\n" );
++ exit(1);
++ }
++}
+
+ static enum GamescopeUpscaleScaler parse_upscaler_scaler(const char *str)
+ {
+@@ -778,6 +792,8 @@ int main(int argc, char **argv)
+ g_DesiredInternalOrientation = force_orientation( optarg );
+ } else if (strcmp(opt_name, "force-external-orientation") == 0) {
+ g_DesiredExternalOrientation = force_external_orientation( optarg );
++ } else if (strcmp(opt_name, "force-panel-type") == 0) {
++ g_ForcedScreenType = force_panel_type( optarg );
+ } else if (strcmp(opt_name, "sharpness") == 0 ||
+ strcmp(opt_name, "fsr-sharpness") == 0) {
+ g_upscaleFilterSharpness = atoi( optarg );
+--
+2.45.2
+
+
+From 2178f85676ba25434e8c39adc3848e3f7355acec Mon Sep 17 00:00:00 2001
+From: Matthew Anderson
+Date: Fri, 17 May 2024 21:11:34 -0500
+Subject: [PATCH 05/22] wlserver: Fix an issue that would cause gamescope to
+ crash when the touchscreen was used
+
+---
+ src/wlserver.cpp | 23 -----------------------
+ 1 file changed, 23 deletions(-)
+
+diff --git a/src/wlserver.cpp b/src/wlserver.cpp
+index 2998aed..62da656 100644
+--- a/src/wlserver.cpp
++++ b/src/wlserver.cpp
+@@ -2530,29 +2530,6 @@ static void apply_touchscreen_orientation(double *x, double *y )
+ break;
+ }
+
+- // Rotate screen if it's forced with --force-external-orientation
+- switch ( GetBackend()->GetConnector( gamescope::GAMESCOPE_SCREEN_TYPE_EXTERNAL )->GetCurrentOrientation() )
+- {
+- default:
+- case GAMESCOPE_PANEL_ORIENTATION_AUTO:
+- case GAMESCOPE_PANEL_ORIENTATION_0:
+- tx = *x;
+- ty = *y;
+- break;
+- case GAMESCOPE_PANEL_ORIENTATION_90:
+- tx = 1.0 - *y;
+- ty = *x;
+- break;
+- case GAMESCOPE_PANEL_ORIENTATION_180:
+- tx = 1.0 - *x;
+- ty = 1.0 - *y;
+- break;
+- case GAMESCOPE_PANEL_ORIENTATION_270:
+- tx = *y;
+- ty = 1.0 - *x;
+- break;
+- }
+-
+ *x = tx;
+ *y = ty;
+ }
+--
+2.45.2
+
+
+From 261124a5a85ad80b0d7b15926f230bacbca21b22 Mon Sep 17 00:00:00 2001
+From: Matthew Anderson
+Date: Fri, 17 May 2024 21:56:55 -0500
+Subject: [PATCH 06/22] Add --custom-refresh-rates
+
+---
+ src/Backends/DRMBackend.cpp | 4 ++++
+ src/main.cpp | 30 ++++++++++++++++++++++++++++++
+ src/main.hpp | 2 ++
+ 3 files changed, 36 insertions(+)
+
+diff --git a/src/Backends/DRMBackend.cpp b/src/Backends/DRMBackend.cpp
+index 4c72dc1..e4caebb 100644
+--- a/src/Backends/DRMBackend.cpp
++++ b/src/Backends/DRMBackend.cpp
+@@ -2125,6 +2125,10 @@ namespace gamescope
+ ( m_Mutable.szMakePNP == "VLV"sv && m_Mutable.szModel == "Jupiter"sv ) ||
+ ( m_Mutable.szMakePNP == "VLV"sv && m_Mutable.szModel == "Galileo"sv );
+
++ if ( g_customRefreshRates.size() > 0 ) {
++ m_Mutable.ValidDynamicRefreshRates = std::span(g_customRefreshRates);
++ return;
++ }
+ if ( bSteamDeckDisplay )
+ {
+ static constexpr uint32_t kPIDGalileoSDC = 0x3003;
+diff --git a/src/main.cpp b/src/main.cpp
+index 8bea38c..a9e1969 100644
+--- a/src/main.cpp
++++ b/src/main.cpp
+@@ -132,6 +132,7 @@ const struct option *gamescope_options = (struct option[]){
+ { "force-panel-type", required_argument, nullptr, 0 },
+ { "force-windows-fullscreen", no_argument, nullptr, 0 },
+ { "bypass-steam-resolution", no_argument, nullptr, 0 },
++ { "custom-refresh-rates", required_argument, nullptr, 0 },
+
+
+ { "disable-color-management", no_argument, nullptr, 0 },
+@@ -210,6 +211,7 @@ const char usage[] =
+ " --hdr-itm-target-nits set the target luminace of the inverse tone mapping process.\n"
+ " Default: 1000 nits, Max: 10000 nits\n"
+ " --framerate-limit Set a simple framerate limit. Used as a divisor of the refresh rate, rounds down eg 60 / 59 -> 60fps, 60 / 25 -> 30fps. Default: 0, disabled.\n"
++ " --custom-refresh-rates Set custom refresh rates for the output. eg: 60,90,110-120\n"
+ " --mangoapp Launch with the mangoapp (mangohud) performance overlay enabled. You should use this instead of using mangohud on the game or gamescope.\n"
+ "\n"
+ "Nested mode options:\n"
+@@ -462,6 +464,32 @@ static enum gamescope::GamescopeBackend parse_backend_name(const char *str)
+ fprintf( stderr, "gamescope: invalid value for --backend\n" );
+ exit(1);
+ }
++
++std::vector g_customRefreshRates;
++// eg: 60,60,90,110-120
++static std::vector parse_custom_refresh_rates( const char *str )
++{
++ std::vector rates;
++ char *token = strtok( strdup(str), ",");
++ while (token)
++ {
++ char *dash = strchr(token, '-');
++ if (dash)
++ {
++ uint32_t start = atoi(token);
++ uint32_t end = atoi(dash + 1);
++ for (uint32_t i = start; i <= end; i++)
++ {
++ rates.push_back(i);
++ }
++ }
++ else
++ {
++ rates.push_back(atoi(token));
++ }
++ token = strtok(nullptr, ",");
++ }
++ return rates;
+ }
+
+ struct sigaction handle_signal_action = {};
+@@ -794,6 +822,8 @@ int main(int argc, char **argv)
+ g_DesiredExternalOrientation = force_external_orientation( optarg );
+ } else if (strcmp(opt_name, "force-panel-type") == 0) {
+ g_ForcedScreenType = force_panel_type( optarg );
++ } else if (strcmp(opt_name, "custom-refresh-rates") == 0) {
++ g_customRefreshRates = parse_custom_refresh_rates( optarg );
+ } else if (strcmp(opt_name, "sharpness") == 0 ||
+ strcmp(opt_name, "fsr-sharpness") == 0) {
+ g_upscaleFilterSharpness = atoi( optarg );
+diff --git a/src/main.hpp b/src/main.hpp
+index 5492cae..0207a51 100644
+--- a/src/main.hpp
++++ b/src/main.hpp
+@@ -3,6 +3,7 @@
+ #include
+
+ #include
++#include
+
+ extern const char *gamescope_optstring;
+ extern const struct option *gamescope_options;
+@@ -29,6 +30,7 @@ extern bool g_bGrabbed;
+ extern float g_mouseSensitivity;
+ extern const char *g_sOutputName;
+ extern bool g_bExternalForced;
++extern std::vector g_customRefreshRates;
+
+ enum class GamescopeUpscaleFilter : uint32_t
+ {
+--
+2.45.2
+
+
+From db4804880ea0fdf810979aea3153e2f45dc97bfe Mon Sep 17 00:00:00 2001
+From: Matthew Anderson
+Date: Sat, 18 May 2024 08:44:38 -0500
+Subject: [PATCH 07/22] Add rotation gamescope_control command
+
+---
+ protocol/gamescope-control.xml | 18 ++++++++++++
+ src/Backends/DRMBackend.cpp | 23 +++++++++++++++-
+ src/gamescope_shared.h | 10 +++++++
+ src/main.cpp | 1 +
+ src/wlserver.cpp | 50 ++++++++++++++++++++++++++++++++++
+ 5 files changed, 101 insertions(+), 1 deletion(-)
+
+diff --git a/protocol/gamescope-control.xml b/protocol/gamescope-control.xml
+index 012c48c..eab8a84 100644
+--- a/protocol/gamescope-control.xml
++++ b/protocol/gamescope-control.xml
+@@ -99,5 +99,23 @@
+
+
+
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
+
+
+diff --git a/src/Backends/DRMBackend.cpp b/src/Backends/DRMBackend.cpp
+index e4caebb..70d5cdf 100644
+--- a/src/Backends/DRMBackend.cpp
++++ b/src/Backends/DRMBackend.cpp
+@@ -2020,7 +2020,9 @@ namespace gamescope
+
+ void CDRMConnector::UpdateEffectiveOrientation( const drmModeModeInfo *pMode )
+ {
+- if ( this->GetScreenType() == GAMESCOPE_SCREEN_TYPE_INTERNAL && g_DesiredInternalOrientation != GAMESCOPE_PANEL_ORIENTATION_AUTO )
++ if ( this->GetScreenType() == ( GAMESCOPE_SCREEN_TYPE_INTERNAL && g_DesiredInternalOrientation != GAMESCOPE_PANEL_ORIENTATION_AUTO )
++ || ( GAMESCOPE_SCREEN_TYPE_EXTERNAL && g_DesiredExternalOrientation != GAMESCOPE_PANEL_ORIENTATION_AUTO
++ && g_bExternalForced ) )
+ {
+ m_ChosenOrientation = g_DesiredInternalOrientation;
+ }
+@@ -2935,6 +2937,25 @@ bool drm_update_color_mgmt(struct drm_t *drm)
+ return true;
+ }
+
++void drm_set_orientation( struct drm_t *drm, bool isRotated)
++{
++ int width = g_nOutputWidth;
++ int height = g_nOutputHeight;
++ g_bRotated = isRotated;
++ if ( g_bRotated ) {
++ int tmp = width;
++ width = height;
++ height = tmp;
++ }
++
++ if (!drm->pConnector || !drm->pConnector->GetModeConnector())
++ return;
++
++ drmModeConnector *connector = drm->pConnector->GetModeConnector();
++ const drmModeModeInfo *mode = find_mode(connector, width, height, 0);
++ update_drm_effective_orientations(drm, mode);
++}
++
+ static void drm_unset_mode( struct drm_t *drm )
+ {
+ drm->pending.mode_id = 0;
+diff --git a/src/gamescope_shared.h b/src/gamescope_shared.h
+index ed30d8c..d04a907 100644
+--- a/src/gamescope_shared.h
++++ b/src/gamescope_shared.h
+@@ -62,6 +62,16 @@ enum GamescopePanelOrientation
+ GAMESCOPE_PANEL_ORIENTATION_AUTO,
+ };
+
++enum GamescopePanelExternalOrientation
++{
++ GAMESCOPE_PANEL_EXTERNAL_ORIENTATION_0, // normal
++ GAMESCOPE_PANEL_EXTERNAL_ORIENTATION_270, // right
++ GAMESCOPE_PANEL_EXTERNAL_ORIENTATION_90, // left
++ GAMESCOPE_PANEL_EXTERNAL_ORIENTATION_180, // upside down
++
++ GAMESCOPE_PANEL_EXTERNAL_ORIENTATION_AUTO,
++};
++
+ // Disable partial composition for now until we get
+ // composite priorities working in libliftoff + also
+ // use the proper libliftoff composite plane system.
+diff --git a/src/main.cpp b/src/main.cpp
+index a9e1969..4469ac1 100644
+--- a/src/main.cpp
++++ b/src/main.cpp
+@@ -397,6 +397,7 @@ static gamescope::GamescopeScreenType force_panel_type(const char *str)
+ if (strcmp(str, "internal") == 0) {
+ return gamescope::GAMESCOPE_SCREEN_TYPE_INTERNAL;
+ } else if (strcmp(str, "external") == 0) {
++ g_bExternalForced = true;
+ return gamescope::GAMESCOPE_SCREEN_TYPE_EXTERNAL;
+ } else {
+ fprintf( stderr, "gamescope: invalid value for --force-panel-type\n" );
+diff --git a/src/wlserver.cpp b/src/wlserver.cpp
+index 62da656..96bb7fc 100644
+--- a/src/wlserver.cpp
++++ b/src/wlserver.cpp
+@@ -1101,6 +1101,55 @@ static void gamescope_control_take_screenshot( struct wl_client *client, struct
+ } );
+ }
+
++static void gamescope_control_rotate_display( struct wl_client *client, struct wl_resource *resource, uint32_t orientation, uint32_t target_type )
++{
++ bool isRotated = false;
++ if (target_type == GAMESCOPE_CONTROL_DISPLAY_TARGET_TYPE_INTERNAL )
++ {
++ switch (orientation) {
++ case GAMESCOPE_CONTROL_DISPLAY_ROTATION_FLAG_NORMAL:
++ //m_ChosenOrientation = GAMESCOPE_PANEL_ORIENTATION_0;
++ break;
++ case GAMESCOPE_CONTROL_DISPLAY_ROTATION_FLAG_LEFT:
++ //m_ChosenOrientation = GAMESCOPE_PANEL_ORIENTATION_90;
++ isRotated = true;
++ break;
++ case GAMESCOPE_CONTROL_DISPLAY_ROTATION_FLAG_RIGHT:
++ //m_ChosenOrientation = GAMESCOPE_PANEL_ORIENTATION_270;
++ isRotated = true;
++ break;
++ case GAMESCOPE_CONTROL_DISPLAY_ROTATION_FLAG_UPSIDEDOWN:
++ //m_ChosenOrientation = GAMESCOPE_PANEL_ORIENTATION_180;
++ break;
++ default:
++ wl_log.errorf("Invalid target orientation selected");
++ }
++ }
++ else if (target_type == GAMESCOPE_CONTROL_DISPLAY_TARGET_TYPE_EXTERNAL )
++ {
++ switch (orientation) {
++ case GAMESCOPE_CONTROL_DISPLAY_ROTATION_FLAG_NORMAL:
++ //m_ChosenOrientation = GAMESCOPE_PANEL_EXTERNAL_ORIENTATION_0;
++ break;
++ case GAMESCOPE_CONTROL_DISPLAY_ROTATION_FLAG_LEFT:
++ //m_ChosenOrientation = GAMESCOPE_PANEL_EXTERNAL_ORIENTATION_90;
++ isRotated = true;
++ break;
++ case GAMESCOPE_CONTROL_DISPLAY_ROTATION_FLAG_RIGHT:
++ //m_ChosenOrientation = GAMESCOPE_PANEL_EXTERNAL_ORIENTATION_270;
++ isRotated = true;
++ break;
++ case GAMESCOPE_CONTROL_DISPLAY_ROTATION_FLAG_UPSIDEDOWN:
++ //m_ChosenOrientation = GAMESCOPE_PANEL_EXTERNAL_ORIENTATION_180;
++ break;
++ default:
++ wl_log.errorf("Invalid target orientation selected");
++ }
++ }
++ //drm_set_orientation(&g_DRM, isRotated);
++ //g_DRM.out_of_date = 2;
++}
++
+ static void gamescope_control_handle_destroy( struct wl_client *client, struct wl_resource *resource )
+ {
+ wl_resource_destroy( resource );
+@@ -1110,6 +1159,7 @@ static const struct gamescope_control_interface gamescope_control_impl = {
+ .destroy = gamescope_control_handle_destroy,
+ .set_app_target_refresh_cycle = gamescope_control_set_app_target_refresh_cycle,
+ .take_screenshot = gamescope_control_take_screenshot,
++ .rotate_display = gamescope_control_rotate_display,
+ };
+
+ static uint32_t get_conn_display_info_flags()
+--
+2.45.2
+
+
+From ef9f07b932c8be1d391b9688b1b31edbb73e86ce Mon Sep 17 00:00:00 2001
+From: Matthew Anderson
+Date: Sat, 18 May 2024 11:54:50 -0500
+Subject: [PATCH 08/22] Fix an issue that caused force-panel to not work
+
+---
+ protocol/gamescope-control.xml | 1 -
+ src/Backends/DRMBackend.cpp | 3 +
+ src/gamescope_shared.h | 10 ---
+ src/wlserver.cpp | 145 ++++++++++++++++++++-------------
+ 4 files changed, 90 insertions(+), 69 deletions(-)
+
+diff --git a/protocol/gamescope-control.xml b/protocol/gamescope-control.xml
+index eab8a84..7f5578b 100644
+--- a/protocol/gamescope-control.xml
++++ b/protocol/gamescope-control.xml
+@@ -99,7 +99,6 @@
+
+
+
+-
+
+
+
+diff --git a/src/Backends/DRMBackend.cpp b/src/Backends/DRMBackend.cpp
+index 70d5cdf..7af994e 100644
+--- a/src/Backends/DRMBackend.cpp
++++ b/src/Backends/DRMBackend.cpp
+@@ -318,6 +318,9 @@ namespace gamescope
+
+ GamescopeScreenType GetScreenType() const override
+ {
++ if ( g_ForcedScreenType != GAMESCOPE_SCREEN_TYPE_AUTO )
++ return g_ForcedScreenType;
++
+ if ( m_pConnector->connector_type == DRM_MODE_CONNECTOR_eDP ||
+ m_pConnector->connector_type == DRM_MODE_CONNECTOR_LVDS ||
+ m_pConnector->connector_type == DRM_MODE_CONNECTOR_DSI )
+diff --git a/src/gamescope_shared.h b/src/gamescope_shared.h
+index d04a907..ed30d8c 100644
+--- a/src/gamescope_shared.h
++++ b/src/gamescope_shared.h
+@@ -62,16 +62,6 @@ enum GamescopePanelOrientation
+ GAMESCOPE_PANEL_ORIENTATION_AUTO,
+ };
+
+-enum GamescopePanelExternalOrientation
+-{
+- GAMESCOPE_PANEL_EXTERNAL_ORIENTATION_0, // normal
+- GAMESCOPE_PANEL_EXTERNAL_ORIENTATION_270, // right
+- GAMESCOPE_PANEL_EXTERNAL_ORIENTATION_90, // left
+- GAMESCOPE_PANEL_EXTERNAL_ORIENTATION_180, // upside down
+-
+- GAMESCOPE_PANEL_EXTERNAL_ORIENTATION_AUTO,
+-};
+-
+ // Disable partial composition for now until we get
+ // composite priorities working in libliftoff + also
+ // use the proper libliftoff composite plane system.
+diff --git a/src/wlserver.cpp b/src/wlserver.cpp
+index 96bb7fc..959f63b 100644
+--- a/src/wlserver.cpp
++++ b/src/wlserver.cpp
+@@ -74,6 +74,8 @@ static LogScope wl_log("wlserver");
+
+ //#define GAMESCOPE_SWAPCHAIN_DEBUG
+ gamescope::ConVar cv_touch_gestures( "enable_touch_gestures", false, "Enable/Disable the usage of touch gestures" );
++extern GamescopePanelOrientation g_DesiredInternalOrientation;
++extern GamescopePanelOrientation g_DesiredExternalOrientation;
+
+ struct wlserver_t wlserver = {
+ .touch_down_ids = {}
+@@ -1107,43 +1109,43 @@ static void gamescope_control_rotate_display( struct wl_client *client, struct w
+ if (target_type == GAMESCOPE_CONTROL_DISPLAY_TARGET_TYPE_INTERNAL )
+ {
+ switch (orientation) {
+- case GAMESCOPE_CONTROL_DISPLAY_ROTATION_FLAG_NORMAL:
+- //m_ChosenOrientation = GAMESCOPE_PANEL_ORIENTATION_0;
+- break;
+- case GAMESCOPE_CONTROL_DISPLAY_ROTATION_FLAG_LEFT:
+- //m_ChosenOrientation = GAMESCOPE_PANEL_ORIENTATION_90;
+- isRotated = true;
+- break;
+- case GAMESCOPE_CONTROL_DISPLAY_ROTATION_FLAG_RIGHT:
+- //m_ChosenOrientation = GAMESCOPE_PANEL_ORIENTATION_270;
+- isRotated = true;
+- break;
+- case GAMESCOPE_CONTROL_DISPLAY_ROTATION_FLAG_UPSIDEDOWN:
+- //m_ChosenOrientation = GAMESCOPE_PANEL_ORIENTATION_180;
+- break;
+- default:
+- wl_log.errorf("Invalid target orientation selected");
++ case GAMESCOPE_CONTROL_DISPLAY_ROTATION_FLAG_NORMAL:
++ g_DesiredInternalOrientation = GAMESCOPE_PANEL_ORIENTATION_0;
++ break;
++ case GAMESCOPE_CONTROL_DISPLAY_ROTATION_FLAG_LEFT:
++ g_DesiredInternalOrientation = GAMESCOPE_PANEL_ORIENTATION_90;
++ isRotated = true;
++ break;
++ case GAMESCOPE_CONTROL_DISPLAY_ROTATION_FLAG_RIGHT:
++ g_DesiredInternalOrientation = GAMESCOPE_PANEL_ORIENTATION_270;
++ isRotated = true;
++ break;
++ case GAMESCOPE_CONTROL_DISPLAY_ROTATION_FLAG_UPSIDEDOWN:
++ g_DesiredInternalOrientation = GAMESCOPE_PANEL_ORIENTATION_180;
++ break;
++ default:
++ wl_log.errorf("Invalid target orientation selected");
+ }
+ }
+ else if (target_type == GAMESCOPE_CONTROL_DISPLAY_TARGET_TYPE_EXTERNAL )
+ {
+ switch (orientation) {
+- case GAMESCOPE_CONTROL_DISPLAY_ROTATION_FLAG_NORMAL:
+- //m_ChosenOrientation = GAMESCOPE_PANEL_EXTERNAL_ORIENTATION_0;
+- break;
+- case GAMESCOPE_CONTROL_DISPLAY_ROTATION_FLAG_LEFT:
+- //m_ChosenOrientation = GAMESCOPE_PANEL_EXTERNAL_ORIENTATION_90;
+- isRotated = true;
+- break;
+- case GAMESCOPE_CONTROL_DISPLAY_ROTATION_FLAG_RIGHT:
+- //m_ChosenOrientation = GAMESCOPE_PANEL_EXTERNAL_ORIENTATION_270;
+- isRotated = true;
+- break;
+- case GAMESCOPE_CONTROL_DISPLAY_ROTATION_FLAG_UPSIDEDOWN:
+- //m_ChosenOrientation = GAMESCOPE_PANEL_EXTERNAL_ORIENTATION_180;
+- break;
+- default:
+- wl_log.errorf("Invalid target orientation selected");
++ case GAMESCOPE_CONTROL_DISPLAY_ROTATION_FLAG_NORMAL:
++ g_DesiredExternalOrientation = GAMESCOPE_PANEL_ORIENTATION_0;
++ break;
++ case GAMESCOPE_CONTROL_DISPLAY_ROTATION_FLAG_LEFT:
++ g_DesiredExternalOrientation = GAMESCOPE_PANEL_ORIENTATION_90;
++ isRotated = true;
++ break;
++ case GAMESCOPE_CONTROL_DISPLAY_ROTATION_FLAG_RIGHT:
++ g_DesiredExternalOrientation = GAMESCOPE_PANEL_ORIENTATION_270;
++ isRotated = true;
++ break;
++ case GAMESCOPE_CONTROL_DISPLAY_ROTATION_FLAG_UPSIDEDOWN:
++ g_DesiredExternalOrientation = GAMESCOPE_PANEL_ORIENTATION_180;
++ break;
++ default:
++ wl_log.errorf("Invalid target orientation selected");
+ }
+ }
+ //drm_set_orientation(&g_DRM, isRotated);
+@@ -2554,34 +2556,61 @@ const std::shared_ptr& wlserver_surface_swapchai
+ /* Handle the orientation of the touch inputs */
+ static void apply_touchscreen_orientation(double *x, double *y )
+ {
+- double tx = 0;
+- double ty = 0;
++ double tx = 0;
++ double ty = 0;
+
+- // Use internal screen always for orientation purposes.
+- switch ( GetBackend()->GetConnector( gamescope::GAMESCOPE_SCREEN_TYPE_INTERNAL )->GetCurrentOrientation() )
+- {
+- default:
+- case GAMESCOPE_PANEL_ORIENTATION_AUTO:
+- case GAMESCOPE_PANEL_ORIENTATION_0:
+- tx = *x;
+- ty = *y;
+- break;
+- case GAMESCOPE_PANEL_ORIENTATION_90:
+- tx = 1.0 - *y;
+- ty = *x;
+- break;
+- case GAMESCOPE_PANEL_ORIENTATION_180:
+- tx = 1.0 - *x;
+- ty = 1.0 - *y;
+- break;
+- case GAMESCOPE_PANEL_ORIENTATION_270:
+- tx = *y;
+- ty = 1.0 - *x;
+- break;
+- }
++ // Use internal screen always for orientation purposes.
++ if ( g_ForcedScreenType == gamescope::GAMESCOPE_SCREEN_TYPE_INTERNAL || g_ForcedScreenType == gamescope::GAMESCOPE_SCREEN_TYPE_EXTERNAL )
++ {
++ switch ( g_DesiredInternalOrientation )
++ {
++ default:
++ case GAMESCOPE_PANEL_ORIENTATION_AUTO:
++ case GAMESCOPE_PANEL_ORIENTATION_0:
++ tx = *x;
++ ty = *y;
++ break;
++ case GAMESCOPE_PANEL_ORIENTATION_90:
++ tx = 1.0 - *y;
++ ty = *x;
++ break;
++ case GAMESCOPE_PANEL_ORIENTATION_180:
++ tx = 1.0 - *x;
++ ty = 1.0 - *y;
++ break;
++ case GAMESCOPE_PANEL_ORIENTATION_270:
++ tx = *y;
++ ty = 1.0 - *x;
++ break;
++ }
++ }
++ else if (g_ForcedScreenType == gamescope::GAMESCOPE_SCREEN_TYPE_AUTO)
++ {
++ switch (GetBackend()->GetConnector(gamescope::GAMESCOPE_SCREEN_TYPE_INTERNAL)->GetCurrentOrientation())
++ {
++ default:
++ case GAMESCOPE_PANEL_ORIENTATION_AUTO:
++ case GAMESCOPE_PANEL_ORIENTATION_0:
++ tx = *x;
++ ty = *y;
++ break;
++ case GAMESCOPE_PANEL_ORIENTATION_90:
++ tx = 1.0 - *y;
++ ty = *x;
++ break;
++ case GAMESCOPE_PANEL_ORIENTATION_180:
++ tx = 1.0 - *x;
++ ty = 1.0 - *y;
++ break;
++ case GAMESCOPE_PANEL_ORIENTATION_270:
++ tx = *y;
++ ty = 1.0 - *x;
++ break;
++ }
++ }
+
+- *x = tx;
+- *y = ty;
++ *x = tx;
++ *y = ty;
+ }
+
+ void wlserver_touchmotion( double x, double y, int touch_id, uint32_t time, bool bAlwaysWarpCursor )
+--
+2.45.2
+
+
+From 8950969d8c62982f03bf8452a503276960f2fa33 Mon Sep 17 00:00:00 2001
+From: Matthew Anderson
+Date: Sat, 18 May 2024 13:50:57 -0500
+Subject: [PATCH 09/22] Fix an arithmetic error
+
+---
+ src/Backends/DRMBackend.cpp | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/src/Backends/DRMBackend.cpp b/src/Backends/DRMBackend.cpp
+index 7af994e..30150fb 100644
+--- a/src/Backends/DRMBackend.cpp
++++ b/src/Backends/DRMBackend.cpp
+@@ -2023,9 +2023,9 @@ namespace gamescope
+
+ void CDRMConnector::UpdateEffectiveOrientation( const drmModeModeInfo *pMode )
+ {
+- if ( this->GetScreenType() == ( GAMESCOPE_SCREEN_TYPE_INTERNAL && g_DesiredInternalOrientation != GAMESCOPE_PANEL_ORIENTATION_AUTO )
+- || ( GAMESCOPE_SCREEN_TYPE_EXTERNAL && g_DesiredExternalOrientation != GAMESCOPE_PANEL_ORIENTATION_AUTO
+- && g_bExternalForced ) )
++ if ( this->GetScreenType() == GAMESCOPE_SCREEN_TYPE_INTERNAL && g_DesiredInternalOrientation != GAMESCOPE_PANEL_ORIENTATION_AUTO
++ || GAMESCOPE_SCREEN_TYPE_EXTERNAL && g_DesiredExternalOrientation != GAMESCOPE_PANEL_ORIENTATION_AUTO
++ && g_bExternalForced )
+ {
+ m_ChosenOrientation = g_DesiredInternalOrientation;
+ }
+--
+2.45.2
+
+
+From 3e51d6f0ae7603e322024783143329dc46835901 Mon Sep 17 00:00:00 2001
+From: Matthew Anderson
+Date: Sat, 18 May 2024 19:04:48 -0500
+Subject: [PATCH 10/22] Rework the touch gestures to be more smooth
+
+---
+ src/wlserver.cpp | 90 +++++++++++++++++++++++++++++++++++++-----------
+ 1 file changed, 69 insertions(+), 21 deletions(-)
+
+diff --git a/src/wlserver.cpp b/src/wlserver.cpp
+index 959f63b..131cd72 100644
+--- a/src/wlserver.cpp
++++ b/src/wlserver.cpp
+@@ -71,7 +71,8 @@
+ #include
+
+ static LogScope wl_log("wlserver");
+-
++bool pending_gesture = false;
++bool pending_osk = false;
+ //#define GAMESCOPE_SWAPCHAIN_DEBUG
+ gamescope::ConVar cv_touch_gestures( "enable_touch_gestures", false, "Enable/Disable the usage of touch gestures" );
+ extern GamescopePanelOrientation g_DesiredInternalOrientation;
+@@ -421,6 +422,39 @@ void wlserver_open_steam_menu( bool qam )
+ XTestFakeKeyEvent(server->get_xdisplay(), XKeysymToKeycode( server->get_xdisplay(), XK_Control_L ), False, CurrentTime);
+ }
+
++void wlserver_open_steam_osk(bool osk)
++{
++ gamescope_xwayland_server_t *server = wlserver_get_xwayland_server( 0 );
++ if (!server)
++ return;
++
++ uint32_t osk_open = osk;
++
++ if (osk_open)
++ {
++ const char *command = "xdg-open steam://open/keyboard?";
++ int result = system(command);
++ if (result == 0) {
++ printf("Command executed successfully.\n");
++ } else {
++ printf("Error executing command.\n");
++ }
++ pending_osk = false;
++ }
++ else
++ {
++ const char *command = "xdg-open steam://close/keyboard?";
++ int result = system(command);
++ if (result == 0) {
++ printf("Command executed successfully.\n");
++ } else {
++ printf("Error executing command.\n");
++ }
++ pending_osk = false;
++ }
++
++}
++
+ static void wlserver_handle_pointer_button(struct wl_listener *listener, void *data)
+ {
+ struct wlserver_pointer *pointer = wl_container_of( listener, pointer, button );
+@@ -2649,32 +2683,46 @@ void wlserver_touchmotion( double x, double y, int touch_id, uint32_t time, bool
+ if ( bAlwaysWarpCursor )
+ wlserver_mousewarp( tx, ty, time, false );
+
+- if (cv_touch_gestures) {
+- bool start_gesture = false;
+-
+- // Round the x-coordinate to the nearest whole number
++ if ( cv_touch_gestures )
++ {
+ uint32_t roundedCursorX = static_cast(std::round(tx));
+- // Grab 2% of the display to be used for the edge range
+- uint32_t edge_range = static_cast(g_nOutputWidth * 0.02);
+-
+- // Determine if the gesture should start
+- if (roundedCursorX <= edge_range || roundedCursorX >= g_nOutputWidth - edge_range) {
+- start_gesture = true;
+- }
+-
+- // Handle Home gesture
+- if (start_gesture && roundedCursorX >= edge_range) {
++ uint32_t roundedCursorY = static_cast(std::round(ty));
++ uint32_t edge_range_x = static_cast(g_nOutputWidth * 0.02);
++ uint32_t edge_range_y = static_cast(g_nOutputWidth * 0.02);
++ uint32_t gesture_limits_x = edge_range_x * 2;
++ uint32_t gesture_limits_y = edge_range_y * 2;
++
++ // Left to Right and Right to Left
++ if (!pending_gesture && roundedCursorX >= 1 && roundedCursorX < edge_range_x ||
++ !pending_gesture && roundedCursorX >= g_nOutputWidth - edge_range_x )
++ pending_gesture = true;
++
++ //left
++ if (pending_gesture && roundedCursorX >= edge_range_x && roundedCursorX < gesture_limits_x) {
+ wlserver_open_steam_menu(0);
+- start_gesture = false;
++ pending_gesture = false;
+ }
+-
+- // Handle QAM gesture
+- if (start_gesture && roundedCursorX >= g_nOutputWidth - edge_range && roundedCursorX <= g_nOutputWidth) {
++ //right
++ if (pending_gesture && roundedCursorX <= g_nOutputWidth - edge_range_x && roundedCursorX > g_nOutputWidth - gesture_limits_x) {
+ wlserver_open_steam_menu(1);
+- start_gesture = false;
++ pending_gesture = false;
++ }
++ // Top to Bottom and Bottom to Top
++ if (!pending_gesture && roundedCursorY >= 1 && roundedCursorY < edge_range_y ||
++ !pending_gesture && roundedCursorY >= g_nOutputHeight - edge_range_y )
++ pending_gesture = true;
++ // Top
++ if (pending_gesture && roundedCursorY >= edge_range_y && roundedCursorY < gesture_limits_y) {
++ pending_gesture = false;
++ // Top to Bottom function to add
++ }
++ // Bottom
++ if (pending_gesture && !pending_osk && roundedCursorY <= g_nOutputWidth - edge_range_y && roundedCursorY > g_nOutputHeight - gesture_limits_y) {
++ pending_gesture = false;
++ pending_osk = true;
++ //wlserver_open_steam_osk(1);
+ }
+ }
+-
+ }
+ else if ( eMode == gamescope::TouchClickModes::Disabled )
+ {
+--
+2.45.2
+
+
+From d25a36dabc8e1d8144413980d915d0e71d313434 Mon Sep 17 00:00:00 2001
+From: Matthew Anderson
+Date: Sun, 19 May 2024 08:55:28 -0500
+Subject: [PATCH 11/22] Fix a typo for --bypass-steam-resolution
+
+---
+ src/steamcompmgr.cpp | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/src/steamcompmgr.cpp b/src/steamcompmgr.cpp
+index bec4268..10c0a75 100644
+--- a/src/steamcompmgr.cpp
++++ b/src/steamcompmgr.cpp
+@@ -7175,7 +7175,7 @@ steamcompmgr_main(int argc, char **argv)
+ bForceWindowsFullscreen = true;
+ } else if (strcmp(opt_name, "hdr-enabled") == 0) {
+ cv_hdr_enabled = true;
+- } else if (strcmp(opt_name, "bypass_steam_resolution") == 0) {
++ } else if (strcmp(opt_name, "bypass-steam-resolution") == 0) {
+ cv_bypass_steam_resolution = true;
+ } else if (strcmp(opt_name, "hdr-debug-force-support") == 0) {
+ g_bForceHDRSupportDebug = true;
+--
+2.45.2
+
+
+From 6d6afedd56a3f7b578cac1af7eaf93af931e0500 Mon Sep 17 00:00:00 2001
+From: Matthew Anderson
+Date: Sun, 19 May 2024 11:48:52 -0500
+Subject: [PATCH 12/22] Handle gesture cases better to prevent unexpected
+ behavior
+
+---
+ src/wlserver.cpp | 63 +++++++++++++++++++++++++++++++++---------------
+ 1 file changed, 43 insertions(+), 20 deletions(-)
+
+diff --git a/src/wlserver.cpp b/src/wlserver.cpp
+index 131cd72..9afe488 100644
+--- a/src/wlserver.cpp
++++ b/src/wlserver.cpp
+@@ -71,7 +71,8 @@
+ #include
+
+ static LogScope wl_log("wlserver");
+-bool pending_gesture = false;
++bool pending_gesture_x = false;
++bool pending_gesture_y = false;
+ bool pending_osk = false;
+ //#define GAMESCOPE_SWAPCHAIN_DEBUG
+ gamescope::ConVar cv_touch_gestures( "enable_touch_gestures", false, "Enable/Disable the usage of touch gestures" );
+@@ -2647,6 +2648,16 @@ static void apply_touchscreen_orientation(double *x, double *y )
+ *y = ty;
+ }
+
++void wlserver_gesture_flush()
++{
++ pending_gesture_x = false;
++ pending_gesture_y = false;
++}
++
++// Variables to track the direction of the touch motion
++uint32_t previous_tx = 0;
++uint32_t previous_ty = 0;
++
+ void wlserver_touchmotion( double x, double y, int touch_id, uint32_t time, bool bAlwaysWarpCursor )
+ {
+ assert( wlserver_is_lock_held() );
+@@ -2685,43 +2696,55 @@ void wlserver_touchmotion( double x, double y, int touch_id, uint32_t time, bool
+
+ if ( cv_touch_gestures )
+ {
+- uint32_t roundedCursorX = static_cast(std::round(tx));
+- uint32_t roundedCursorY = static_cast(std::round(ty));
+- uint32_t edge_range_x = static_cast(g_nOutputWidth * 0.02);
+- uint32_t edge_range_y = static_cast(g_nOutputWidth * 0.02);
++ uint32_t rounded_tx = static_cast(std::round(tx));
++ uint32_t rounded_ty = static_cast(std::round(ty));
++ uint32_t edge_range_x = static_cast(g_nOutputWidth * 0.05);
++ uint32_t edge_range_y = static_cast(g_nOutputWidth * 0.05);
+ uint32_t gesture_limits_x = edge_range_x * 2;
+ uint32_t gesture_limits_y = edge_range_y * 2;
++ uint32_t threshold_distance_x = gesture_limits_x;
++ uint32_t threshold_distance_y = gesture_limits_y;
+
+ // Left to Right and Right to Left
+- if (!pending_gesture && roundedCursorX >= 1 && roundedCursorX < edge_range_x ||
+- !pending_gesture && roundedCursorX >= g_nOutputWidth - edge_range_x )
+- pending_gesture = true;
++ if (!pending_gesture_x && ((rounded_tx >= 1 && rounded_tx < edge_range_x) || (rounded_tx >= g_nOutputWidth - edge_range_x))) {
++ // Check if the distance moved is greater than the threshold
++ if (rounded_tx - previous_tx > threshold_distance_x) {
++ pending_gesture_x = true;
++ }
++ }
++
++ // Top to Bottom and Bottom to Top
++ if (!pending_gesture_y && ((rounded_ty >= 1 && rounded_ty < edge_range_y) || (rounded_ty >= g_nOutputHeight - edge_range_y))) {
++ // Check if the distance moved is greater than the threshold
++ if (rounded_ty - previous_ty > threshold_distance_y) {
++ pending_gesture_y = true;
++ }
++ }
+
+ //left
+- if (pending_gesture && roundedCursorX >= edge_range_x && roundedCursorX < gesture_limits_x) {
++ if (pending_gesture_x && previous_tx < rounded_tx && rounded_tx >= edge_range_x && rounded_tx < gesture_limits_x) {
+ wlserver_open_steam_menu(0);
+- pending_gesture = false;
++ wlserver_gesture_flush();
+ }
+ //right
+- if (pending_gesture && roundedCursorX <= g_nOutputWidth - edge_range_x && roundedCursorX > g_nOutputWidth - gesture_limits_x) {
++ if (pending_gesture_x && previous_tx > rounded_tx && rounded_tx <= g_nOutputWidth - edge_range_x && rounded_tx > g_nOutputWidth - gesture_limits_x) {
+ wlserver_open_steam_menu(1);
+- pending_gesture = false;
++ wlserver_gesture_flush();
+ }
+- // Top to Bottom and Bottom to Top
+- if (!pending_gesture && roundedCursorY >= 1 && roundedCursorY < edge_range_y ||
+- !pending_gesture && roundedCursorY >= g_nOutputHeight - edge_range_y )
+- pending_gesture = true;
++
+ // Top
+- if (pending_gesture && roundedCursorY >= edge_range_y && roundedCursorY < gesture_limits_y) {
+- pending_gesture = false;
++ if (pending_gesture_y && previous_ty < rounded_ty && rounded_ty >= edge_range_y && rounded_ty < gesture_limits_y) {
++ wlserver_gesture_flush();
+ // Top to Bottom function to add
+ }
+ // Bottom
+- if (pending_gesture && !pending_osk && roundedCursorY <= g_nOutputWidth - edge_range_y && roundedCursorY > g_nOutputHeight - gesture_limits_y) {
+- pending_gesture = false;
++ if (pending_gesture_y && previous_ty > rounded_ty && !pending_osk && rounded_ty <= g_nOutputWidth - edge_range_y && rounded_ty > g_nOutputHeight - gesture_limits_y) {
++ wlserver_gesture_flush();
+ pending_osk = true;
+ //wlserver_open_steam_osk(1);
+ }
++ previous_tx = rounded_tx;
++ previous_ty = rounded_ty;
+ }
+ }
+ else if ( eMode == gamescope::TouchClickModes::Disabled )
+--
+2.45.2
+
+
+From 58e24b2f2ac33eb2388ef734835c6b02e437e563 Mon Sep 17 00:00:00 2001
+From: Matthew Anderson
+Date: Sun, 19 May 2024 18:14:23 -0500
+Subject: [PATCH 13/22] Add references to drm_set_orientation() and g_drm in
+ wlserver for rotation gamescope-control
+
+---
+ src/wlserver.cpp | 5 +++--
+ src/wlserver.hpp | 3 ++-
+ 2 files changed, 5 insertions(+), 3 deletions(-)
+
+diff --git a/src/wlserver.cpp b/src/wlserver.cpp
+index 9afe488..e963bea 100644
+--- a/src/wlserver.cpp
++++ b/src/wlserver.cpp
+@@ -1183,8 +1183,9 @@ static void gamescope_control_rotate_display( struct wl_client *client, struct w
+ wl_log.errorf("Invalid target orientation selected");
+ }
+ }
+- //drm_set_orientation(&g_DRM, isRotated);
+- //g_DRM.out_of_date = 2;
++ drm_set_orientation(&g_DRM, isRotated);
++ GetBackend()->DirtyState( true, true );
++
+ }
+
+ static void gamescope_control_handle_destroy( struct wl_client *client, struct wl_resource *resource )
+diff --git a/src/wlserver.hpp b/src/wlserver.hpp
+index da67bf7..688d05c 100644
+--- a/src/wlserver.hpp
++++ b/src/wlserver.hpp
+@@ -294,7 +294,8 @@ extern std::atomic g_bPendingTouchMovement;
+ extern gamescope::ConVar cv_touch_gestures;
+
+ void wlserver_open_steam_menu( bool qam );
+-
++extern void drm_set_orientation( struct drm_t *drm, bool isRotated);
++extern drm_t g_DRM;
+ uint32_t wlserver_make_new_xwayland_server();
+ void wlserver_destroy_xwayland_server(gamescope_xwayland_server_t *server);
+
+--
+2.45.2
+
+
+From 768e5689e12c2f57766d27d72b4fad03d54fc01c Mon Sep 17 00:00:00 2001
+From: Matthew Anderson
+Date: Mon, 20 May 2024 07:02:52 -0500
+Subject: [PATCH 14/22] Fix an issue where forced panel type orientations
+ weren't being applied
+
+---
+ src/Backends/DRMBackend.cpp | 15 ++++++++-------
+ 1 file changed, 8 insertions(+), 7 deletions(-)
+
+diff --git a/src/Backends/DRMBackend.cpp b/src/Backends/DRMBackend.cpp
+index 30150fb..1a2668f 100644
+--- a/src/Backends/DRMBackend.cpp
++++ b/src/Backends/DRMBackend.cpp
+@@ -2023,20 +2023,19 @@ namespace gamescope
+
+ void CDRMConnector::UpdateEffectiveOrientation( const drmModeModeInfo *pMode )
+ {
+- if ( this->GetScreenType() == GAMESCOPE_SCREEN_TYPE_INTERNAL && g_DesiredInternalOrientation != GAMESCOPE_PANEL_ORIENTATION_AUTO
+- || GAMESCOPE_SCREEN_TYPE_EXTERNAL && g_DesiredExternalOrientation != GAMESCOPE_PANEL_ORIENTATION_AUTO
+- && g_bExternalForced )
+- {
++ if ((this->GetScreenType() == GAMESCOPE_SCREEN_TYPE_INTERNAL && g_DesiredInternalOrientation != GAMESCOPE_PANEL_ORIENTATION_AUTO) ||
++ (this->GetScreenType() == GAMESCOPE_SCREEN_TYPE_EXTERNAL && g_DesiredInternalOrientation != GAMESCOPE_PANEL_ORIENTATION_AUTO && g_bExternalForced)) {
++ drm_log.infof("We are rotating the orientation of the internal or faked external display")
+ m_ChosenOrientation = g_DesiredInternalOrientation;
+- }
+- else if ( this->GetScreenType() == GAMESCOPE_SCREEN_TYPE_EXTERNAL && g_DesiredExternalOrientation != GAMESCOPE_PANEL_ORIENTATION_AUTO )
+- {
++ } else if (this->GetScreenType() == GAMESCOPE_SCREEN_TYPE_EXTERNAL && g_DesiredExternalOrientation != GAMESCOPE_PANEL_ORIENTATION_AUTO) {
++ drm_log.infof("We are rotating the orientation of an external display");
+ m_ChosenOrientation = g_DesiredExternalOrientation;
+ }
+ else
+ {
+ if ( this->GetProperties().panel_orientation )
+ {
++ drm_log.infof("We are using a kernel orientation quirk to rotate the display");
+ switch ( this->GetProperties().panel_orientation->GetCurrentValue() )
+ {
+ case DRM_MODE_PANEL_ORIENTATION_NORMAL:
+@@ -2058,6 +2057,7 @@ namespace gamescope
+
+ if ( this->GetScreenType() == gamescope::GAMESCOPE_SCREEN_TYPE_INTERNAL && pMode )
+ {
++ drm_log.infof("We are using legacy code to rotate the display");
+ // Auto-detect portait mode for internal displays
+ m_ChosenOrientation = pMode->hdisplay < pMode->vdisplay
+ ? GAMESCOPE_PANEL_ORIENTATION_270
+@@ -2065,6 +2065,7 @@ namespace gamescope
+ }
+ else
+ {
++ drm_log.infof("No orientation quirks have been applied");
+ m_ChosenOrientation = GAMESCOPE_PANEL_ORIENTATION_0;
+ }
+ }
+--
+2.45.2
+
+
+From d6e4cf239f0f2113d1f3071a8d4766a810497617 Mon Sep 17 00:00:00 2001
+From: Matthew Anderson
+Date: Mon, 20 May 2024 07:25:29 -0500
+Subject: [PATCH 15/22] add missing curly bracket...
+
+---
+ src/Backends/DRMBackend.cpp | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/src/Backends/DRMBackend.cpp b/src/Backends/DRMBackend.cpp
+index 1a2668f..825812e 100644
+--- a/src/Backends/DRMBackend.cpp
++++ b/src/Backends/DRMBackend.cpp
+@@ -2025,7 +2025,7 @@ namespace gamescope
+ {
+ if ((this->GetScreenType() == GAMESCOPE_SCREEN_TYPE_INTERNAL && g_DesiredInternalOrientation != GAMESCOPE_PANEL_ORIENTATION_AUTO) ||
+ (this->GetScreenType() == GAMESCOPE_SCREEN_TYPE_EXTERNAL && g_DesiredInternalOrientation != GAMESCOPE_PANEL_ORIENTATION_AUTO && g_bExternalForced)) {
+- drm_log.infof("We are rotating the orientation of the internal or faked external display")
++ drm_log.infof("We are rotating the orientation of the internal or faked external display");
+ m_ChosenOrientation = g_DesiredInternalOrientation;
+ } else if (this->GetScreenType() == GAMESCOPE_SCREEN_TYPE_EXTERNAL && g_DesiredExternalOrientation != GAMESCOPE_PANEL_ORIENTATION_AUTO) {
+ drm_log.infof("We are rotating the orientation of an external display");
+--
+2.45.2
+
+
+From 8983b3621dd81d4633a50a798b7794c6ae9d693b Mon Sep 17 00:00:00 2001
+From: Matthew Anderson
+Date: Mon, 20 May 2024 10:17:55 -0500
+Subject: [PATCH 16/22] Fix case where real externals were rotated with faked
+ external panels
+
+---
+ src/Backends/DRMBackend.cpp | 21 +++++++----
+ src/wlserver.cpp | 72 +++++++++++++++++++++++++------------
+ 2 files changed, 64 insertions(+), 29 deletions(-)
+
+diff --git a/src/Backends/DRMBackend.cpp b/src/Backends/DRMBackend.cpp
+index 825812e..2668ad7 100644
+--- a/src/Backends/DRMBackend.cpp
++++ b/src/Backends/DRMBackend.cpp
+@@ -318,13 +318,20 @@ namespace gamescope
+
+ GamescopeScreenType GetScreenType() const override
+ {
+- if ( g_ForcedScreenType != GAMESCOPE_SCREEN_TYPE_AUTO )
+- return g_ForcedScreenType;
+-
+ if ( m_pConnector->connector_type == DRM_MODE_CONNECTOR_eDP ||
+ m_pConnector->connector_type == DRM_MODE_CONNECTOR_LVDS ||
+ m_pConnector->connector_type == DRM_MODE_CONNECTOR_DSI )
+- return GAMESCOPE_SCREEN_TYPE_INTERNAL;
++ {
++ if ( g_bExternalForced )
++ {
++ return g_ForcedScreenType;
++ }
++ else
++ {
++ return GAMESCOPE_SCREEN_TYPE_INTERNAL;
++ }
++ }
++
+
+ return GAMESCOPE_SCREEN_TYPE_EXTERNAL;
+ }
+@@ -2023,11 +2030,11 @@ namespace gamescope
+
+ void CDRMConnector::UpdateEffectiveOrientation( const drmModeModeInfo *pMode )
+ {
+- if ((this->GetScreenType() == GAMESCOPE_SCREEN_TYPE_INTERNAL && g_DesiredInternalOrientation != GAMESCOPE_PANEL_ORIENTATION_AUTO) ||
+- (this->GetScreenType() == GAMESCOPE_SCREEN_TYPE_EXTERNAL && g_DesiredInternalOrientation != GAMESCOPE_PANEL_ORIENTATION_AUTO && g_bExternalForced)) {
++ if ( this->GetScreenType() == GAMESCOPE_SCREEN_TYPE_INTERNAL && g_DesiredInternalOrientation != GAMESCOPE_PANEL_ORIENTATION_AUTO ) {
+ drm_log.infof("We are rotating the orientation of the internal or faked external display");
+ m_ChosenOrientation = g_DesiredInternalOrientation;
+- } else if (this->GetScreenType() == GAMESCOPE_SCREEN_TYPE_EXTERNAL && g_DesiredExternalOrientation != GAMESCOPE_PANEL_ORIENTATION_AUTO) {
++ }
++ else if (this->GetScreenType() == GAMESCOPE_SCREEN_TYPE_EXTERNAL && g_DesiredExternalOrientation != GAMESCOPE_PANEL_ORIENTATION_AUTO) {
+ drm_log.infof("We are rotating the orientation of an external display");
+ m_ChosenOrientation = g_DesiredExternalOrientation;
+ }
+diff --git a/src/wlserver.cpp b/src/wlserver.cpp
+index e963bea..74d8209 100644
+--- a/src/wlserver.cpp
++++ b/src/wlserver.cpp
+@@ -2596,29 +2596,57 @@ static void apply_touchscreen_orientation(double *x, double *y )
+ double ty = 0;
+
+ // Use internal screen always for orientation purposes.
+- if ( g_ForcedScreenType == gamescope::GAMESCOPE_SCREEN_TYPE_INTERNAL || g_ForcedScreenType == gamescope::GAMESCOPE_SCREEN_TYPE_EXTERNAL )
++ if ( g_ForcedScreenType != gamescope::GAMESCOPE_SCREEN_TYPE_AUTO )
+ {
+- switch ( g_DesiredInternalOrientation )
+- {
+- default:
+- case GAMESCOPE_PANEL_ORIENTATION_AUTO:
+- case GAMESCOPE_PANEL_ORIENTATION_0:
+- tx = *x;
+- ty = *y;
+- break;
+- case GAMESCOPE_PANEL_ORIENTATION_90:
+- tx = 1.0 - *y;
+- ty = *x;
+- break;
+- case GAMESCOPE_PANEL_ORIENTATION_180:
+- tx = 1.0 - *x;
+- ty = 1.0 - *y;
+- break;
+- case GAMESCOPE_PANEL_ORIENTATION_270:
+- tx = *y;
+- ty = 1.0 - *x;
+- break;
+- }
++ if ( g_ForcedScreenType == gamescope::GAMESCOPE_SCREEN_TYPE_EXTERNAL )
++ {
++ switch (GetBackend()->GetConnector(gamescope::GAMESCOPE_SCREEN_TYPE_EXTERNAL)->GetCurrentOrientation())
++ {
++ default:
++ case GAMESCOPE_PANEL_ORIENTATION_AUTO:
++ case GAMESCOPE_PANEL_ORIENTATION_0:
++ tx = *x;
++ ty = *y;
++ break;
++ case GAMESCOPE_PANEL_ORIENTATION_90:
++ tx = 1.0 - *y;
++ ty = *x;
++ break;
++ case GAMESCOPE_PANEL_ORIENTATION_180:
++ tx = 1.0 - *x;
++ ty = 1.0 - *y;
++ break;
++ case GAMESCOPE_PANEL_ORIENTATION_270:
++ tx = *y;
++ ty = 1.0 - *x;
++ break;
++ }
++ }
++ else
++ {
++ switch (GetBackend()->GetConnector(gamescope::GAMESCOPE_SCREEN_TYPE_INTERNAL)->GetCurrentOrientation())
++ {
++ default:
++ case GAMESCOPE_PANEL_ORIENTATION_AUTO:
++ case GAMESCOPE_PANEL_ORIENTATION_0:
++ tx = *x;
++ ty = *y;
++ break;
++ case GAMESCOPE_PANEL_ORIENTATION_90:
++ tx = 1.0 - *y;
++ ty = *x;
++ break;
++ case GAMESCOPE_PANEL_ORIENTATION_180:
++ tx = 1.0 - *x;
++ ty = 1.0 - *y;
++ break;
++ case GAMESCOPE_PANEL_ORIENTATION_270:
++ tx = *y;
++ ty = 1.0 - *x;
++ break;
++ }
++ }
++
+ }
+ else if (g_ForcedScreenType == gamescope::GAMESCOPE_SCREEN_TYPE_AUTO)
+ {
+--
+2.45.2
+
+
+From 57057c9e5dc4ac026259726145d5b6e480368699 Mon Sep 17 00:00:00 2001
+From: Matthew Anderson
+Date: Mon, 20 May 2024 16:30:47 -0500
+Subject: [PATCH 17/22] Add verbose panel logs and attempt to address all
+ orientation issues
+
+---
+ src/Backends/DRMBackend.cpp | 18 ++++++++++++++--
+ src/wlserver.cpp | 41 ++++++++++++++++++++-----------------
+ src/wlserver.hpp | 1 +
+ 3 files changed, 39 insertions(+), 21 deletions(-)
+
+diff --git a/src/Backends/DRMBackend.cpp b/src/Backends/DRMBackend.cpp
+index 2668ad7..9df20ae 100644
+--- a/src/Backends/DRMBackend.cpp
++++ b/src/Backends/DRMBackend.cpp
+@@ -56,6 +56,7 @@ static constexpr bool k_bUseCursorPlane = false;
+
+ extern int g_nPreferredOutputWidth;
+ extern int g_nPreferredOutputHeight;
++bool panelTypeChanged = false;
+
+ gamescope::ConVar cv_drm_single_plane_optimizations( "drm_single_plane_optimizations", true, "Whether or not to enable optimizations for single plane usage." );
+
+@@ -324,6 +325,7 @@ namespace gamescope
+ {
+ if ( g_bExternalForced )
+ {
++ panelTypeChanged = true;
+ return g_ForcedScreenType;
+ }
+ else
+@@ -332,7 +334,7 @@ namespace gamescope
+ }
+ }
+
+-
++ panelTypeChanged = false;
+ return GAMESCOPE_SCREEN_TYPE_EXTERNAL;
+ }
+
+@@ -2030,7 +2032,19 @@ namespace gamescope
+
+ void CDRMConnector::UpdateEffectiveOrientation( const drmModeModeInfo *pMode )
+ {
+- if ( this->GetScreenType() == GAMESCOPE_SCREEN_TYPE_INTERNAL && g_DesiredInternalOrientation != GAMESCOPE_PANEL_ORIENTATION_AUTO ) {
++
++ if ( this->GetScreenType() == GAMESCOPE_SCREEN_TYPE_EXTERNAL && panelTypeChanged )
++ drm_log.infof("Display is internal faked as external");
++ if ( this->GetScreenType() == GAMESCOPE_SCREEN_TYPE_INTERNAL && !panelTypeChanged )
++ drm_log.infof("Display is real internal");
++ if (panelTypeChanged){
++ drm_log.infof("Panel type was changed");
++ }
++
++ if (( this->GetScreenType() == GAMESCOPE_SCREEN_TYPE_INTERNAL && g_DesiredInternalOrientation != GAMESCOPE_PANEL_ORIENTATION_AUTO ) ||
++ ( this->GetScreenType() == GAMESCOPE_SCREEN_TYPE_EXTERNAL && g_DesiredInternalOrientation != GAMESCOPE_PANEL_ORIENTATION_AUTO
++ && panelTypeChanged)) {
++
+ drm_log.infof("We are rotating the orientation of the internal or faked external display");
+ m_ChosenOrientation = g_DesiredInternalOrientation;
+ }
+diff --git a/src/wlserver.cpp b/src/wlserver.cpp
+index 74d8209..3d4b239 100644
+--- a/src/wlserver.cpp
++++ b/src/wlserver.cpp
+@@ -2600,26 +2600,29 @@ static void apply_touchscreen_orientation(double *x, double *y )
+ {
+ if ( g_ForcedScreenType == gamescope::GAMESCOPE_SCREEN_TYPE_EXTERNAL )
+ {
+- switch (GetBackend()->GetConnector(gamescope::GAMESCOPE_SCREEN_TYPE_EXTERNAL)->GetCurrentOrientation())
++ if(panelTypeChanged)
+ {
+- default:
+- case GAMESCOPE_PANEL_ORIENTATION_AUTO:
+- case GAMESCOPE_PANEL_ORIENTATION_0:
+- tx = *x;
+- ty = *y;
+- break;
+- case GAMESCOPE_PANEL_ORIENTATION_90:
+- tx = 1.0 - *y;
+- ty = *x;
+- break;
+- case GAMESCOPE_PANEL_ORIENTATION_180:
+- tx = 1.0 - *x;
+- ty = 1.0 - *y;
+- break;
+- case GAMESCOPE_PANEL_ORIENTATION_270:
+- tx = *y;
+- ty = 1.0 - *x;
+- break;
++ switch (GetBackend()->GetConnector(gamescope::GAMESCOPE_SCREEN_TYPE_EXTERNAL)->GetCurrentOrientation())
++ {
++ default:
++ case GAMESCOPE_PANEL_ORIENTATION_AUTO:
++ case GAMESCOPE_PANEL_ORIENTATION_0:
++ tx = *x;
++ ty = *y;
++ break;
++ case GAMESCOPE_PANEL_ORIENTATION_90:
++ tx = 1.0 - *y;
++ ty = *x;
++ break;
++ case GAMESCOPE_PANEL_ORIENTATION_180:
++ tx = 1.0 - *x;
++ ty = 1.0 - *y;
++ break;
++ case GAMESCOPE_PANEL_ORIENTATION_270:
++ tx = *y;
++ ty = 1.0 - *x;
++ break;
++ }
+ }
+ }
+ else
+diff --git a/src/wlserver.hpp b/src/wlserver.hpp
+index 688d05c..ae55963 100644
+--- a/src/wlserver.hpp
++++ b/src/wlserver.hpp
+@@ -296,6 +296,7 @@ extern gamescope::ConVar cv_touch_gestures;
+ void wlserver_open_steam_menu( bool qam );
+ extern void drm_set_orientation( struct drm_t *drm, bool isRotated);
+ extern drm_t g_DRM;
++extern bool panelTypeChanged;
+ uint32_t wlserver_make_new_xwayland_server();
+ void wlserver_destroy_xwayland_server(gamescope_xwayland_server_t *server);
+
+--
+2.45.2
+
+
+From 41242b5ee7fa33cae22f30f5bcf5e27169bd8145 Mon Sep 17 00:00:00 2001
+From: Bouke Sybren Haarsma
+Date: Tue, 28 May 2024 21:56:47 +0200
+Subject: [PATCH 18/22] add closing bracket
+
+---
+ src/main.cpp | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/src/main.cpp b/src/main.cpp
+index 4469ac1..e455225 100644
+--- a/src/main.cpp
++++ b/src/main.cpp
+@@ -465,6 +465,7 @@ static enum gamescope::GamescopeBackend parse_backend_name(const char *str)
+ fprintf( stderr, "gamescope: invalid value for --backend\n" );
+ exit(1);
+ }
++}
+
+ std::vector g_customRefreshRates;
+ // eg: 60,60,90,110-120
+--
+2.45.2
+
+
+From e528844eb590f8183fdfffaf9a7af39f33dc2213 Mon Sep 17 00:00:00 2001
+From: Bouke Sybren Haarsma
+Date: Wed, 3 Jan 2024 17:03:04 +0100
+Subject: [PATCH 19/22] remove hacky texture
+
+This will use more hardware planes, causing some devices to composite yeilding lower framerates
+---
+ src/steamcompmgr.cpp | 62 ++++++++++++--------------------------------
+ 1 file changed, 17 insertions(+), 45 deletions(-)
+
+diff --git a/src/steamcompmgr.cpp b/src/steamcompmgr.cpp
+index 10c0a75..1bc9008 100644
+--- a/src/steamcompmgr.cpp
++++ b/src/steamcompmgr.cpp
+@@ -1579,7 +1579,7 @@ bool MouseCursor::getTexture()
+ {
+ pixels[i * image->width + j] = image->pixels[i * image->width + j];
+ }
+- }
++ }
+ std::vector resizeBuffer( nDesiredWidth * nDesiredHeight );
+ stbir_resize_uint8_srgb( (unsigned char *)pixels.data(), image->width, image->height, 0,
+ (unsigned char *)resizeBuffer.data(), nDesiredWidth, nDesiredHeight, 0,
+@@ -2257,7 +2257,7 @@ paint_all(bool async)
+ }
+ }
+ }
+-
++
+ int nOldLayerCount = frameInfo.layerCount;
+
+ uint32_t flags = 0;
+@@ -2265,7 +2265,7 @@ paint_all(bool async)
+ flags |= PaintWindowFlag::BasePlane;
+ paint_window(w, w, &frameInfo, global_focus.cursor, flags);
+ update_touch_scaling( &frameInfo );
+-
++
+ // paint UI unless it's fully hidden, which it communicates to us through opacity=0
+ // we paint it to extract scaling coefficients above, then remove the layer if one was added
+ if ( w->opacity == TRANSLUCENT && bHasVideoUnderlay && nOldLayerCount < frameInfo.layerCount )
+@@ -2278,7 +2278,7 @@ paint_all(bool async)
+ float opacityScale = g_bPendingFade
+ ? 0.0f
+ : ((currentTime - fadeOutStartTime) / (float)g_FadeOutDuration);
+-
++
+ paint_cached_base_layer(g_HeldCommits[HELD_COMMIT_FADE], g_CachedPlanes[HELD_COMMIT_FADE], &frameInfo, 1.0f - opacityScale, false);
+ paint_window(w, w, &frameInfo, global_focus.cursor, PaintWindowFlag::BasePlane | PaintWindowFlag::FadeTarget | PaintWindowFlag::DrawBorders, opacityScale, override);
+ }
+@@ -2352,34 +2352,6 @@ paint_all(bool async)
+ if ( overlay == global_focus.inputFocusWindow )
+ update_touch_scaling( &frameInfo );
+ }
+- else if ( !GetBackend()->UsesVulkanSwapchain() && GetBackend()->IsSessionBased() )
+- {
+- auto tex = vulkan_get_hacky_blank_texture();
+- if ( tex != nullptr )
+- {
+- // HACK! HACK HACK HACK
+- // To avoid stutter when toggling the overlay on
+- int curLayer = frameInfo.layerCount++;
+-
+- FrameInfo_t::Layer_t *layer = &frameInfo.layers[ curLayer ];
+-
+-
+- layer->scale.x = g_nOutputWidth == tex->width() ? 1.0f : tex->width() / (float)g_nOutputWidth;
+- layer->scale.y = g_nOutputHeight == tex->height() ? 1.0f : tex->height() / (float)g_nOutputHeight;
+- layer->offset.x = 0.0f;
+- layer->offset.y = 0.0f;
+- layer->opacity = 1.0f; // BLAH
+- layer->zpos = g_zposOverlay;
+- layer->applyColorMgmt = g_ColorMgmt.pending.enabled;
+-
+- layer->colorspace = GAMESCOPE_APP_TEXTURE_COLORSPACE_LINEAR;
+- layer->ctm = nullptr;
+- layer->tex = tex;
+-
+- layer->filter = GamescopeUpscaleFilter::NEAREST;
+- layer->blackBorder = true;
+- }
+- }
+
+ if (notification)
+ {
+@@ -2957,7 +2929,7 @@ win_maybe_a_dropdown( steamcompmgr_win_t *w )
+ //
+ // TODO: Come back to me for original Age of Empires HD launcher.
+ // Does that use it? It wants blending!
+- //
++ //
+ // Only do this if we have CONTROLPARENT right now. Some other apps, such as the
+ // Street Fighter V (310950) Splash Screen also use LAYERED and TOOLWINDOW, and we don't
+ // want that to be overlayed.
+@@ -2972,12 +2944,12 @@ win_maybe_a_dropdown( steamcompmgr_win_t *w )
+
+ // Josh:
+ // The logic here is as follows. The window will be treated as a dropdown if:
+- //
++ //
+ // If this window has a fixed position on the screen + static gravity:
+ // - If the window has either skipPage or skipTaskbar
+ // - If the window isn't a dialog, always treat it as a dropdown, as it's
+ // probably meant to be some form of popup.
+- // - If the window is a dialog
++ // - If the window is a dialog
+ // - If the window has transient for, disregard it, as it is trying to redirecting us elsewhere
+ // ie. a settings menu dialog popup or something.
+ // - If the window has both skip taskbar and pager, treat it as a dialog.
+@@ -3069,7 +3041,7 @@ static bool is_good_override_candidate( steamcompmgr_win_t *override, steamcompm
+ return false;
+
+ return override != focus && override->GetGeometry().nX >= 0 && override->GetGeometry().nY >= 0;
+-}
++}
+
+ static bool
+ pick_primary_focus_and_override(focus_t *out, Window focusControlWindow, const std::vector& vecPossibleFocusWindows, bool globalFocus, const std::vector& ctxFocusControlAppIDs)
+@@ -3210,7 +3182,7 @@ found:;
+
+ if ( focus )
+ {
+- if ( window_has_commits( focus ) )
++ if ( window_has_commits( focus ) )
+ out->focusWindow = focus;
+ else
+ focus->outdatedInteractiveFocus = true;
+@@ -3253,9 +3225,9 @@ found:;
+ override_focus = fake_override;
+ goto found2;
+ }
+- }
++ }
+ }
+-
++
+ found2:;
+ resolveTransientOverrides( true );
+ }
+@@ -4514,7 +4486,7 @@ finish_destroy_win(xwayland_ctx_t *ctx, Window id, bool gone)
+ {
+ if (gone)
+ finish_unmap_win (ctx, w);
+-
++
+ {
+ std::unique_lock lock( ctx->list_mutex );
+ *prev = w->xwayland().next;
+@@ -4571,7 +4543,7 @@ destroy_win(xwayland_ctx_t *ctx, Window id, bool gone, bool fade)
+ global_focus.overrideWindow = nullptr;
+ if (x11_win(global_focus.fadeWindow) == id && gone)
+ global_focus.fadeWindow = nullptr;
+-
++
+ MakeFocusDirty();
+
+ finish_destroy_win(ctx, id, gone);
+@@ -5176,7 +5148,7 @@ handle_property_notify(xwayland_ctx_t *ctx, XPropertyEvent *ev)
+ {
+ get_win_type(ctx, w);
+ MakeFocusDirty();
+- }
++ }
+ }
+ if (ev->atom == ctx->atoms.sizeHintsAtom)
+ {
+@@ -6084,7 +6056,7 @@ void handle_done_commits_xdg( bool vblank, uint64_t vblank_idx )
+ commits_before_their_time.push_back( entry );
+ continue;
+ }
+-
++
+ if (!entry.earliestPresentTime)
+ {
+ entry.earliestPresentTime = next_refresh_time;
+@@ -6938,7 +6910,7 @@ void update_mode_atoms(xwayland_ctx_t *root_ctx, bool* needs_flush = nullptr)
+ }
+ XChangeProperty(root_ctx->dpy, root_ctx->root, root_ctx->atoms.gamescopeDisplayModeListExternal, XA_STRING, 8, PropModeReplace,
+ (unsigned char *)modes, strlen(modes) + 1 );
+-
++
+ uint32_t one = 1;
+ XChangeProperty(root_ctx->dpy, root_ctx->root, root_ctx->atoms.gamescopeDisplayIsExternal, XA_CARDINAL, 32, PropModeReplace,
+ (unsigned char *)&one, 1 );
+@@ -7696,7 +7668,7 @@ void steamcompmgr_send_frame_done_to_focus_window()
+ {
+ wlserver_lock();
+ wlserver_send_frame_done( global_focus.focusWindow->xwayland().surface.main_surface , &now );
+- wlserver_unlock();
++ wlserver_unlock();
+ }
+ }
+
+--
+2.45.2
+
+
+From 7865b34c5cd61fa5cc5428ace614e4551fabb6ec Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Joaqu=C3=ADn=20Ignacio=20Aramend=C3=ADa?=
+
+Date: Tue, 9 Jul 2024 18:29:16 -0300
+Subject: [PATCH 20/22] disable explicit sync to avoid graphical artifacts
+
+---
+ src/Backends/DRMBackend.cpp | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/src/Backends/DRMBackend.cpp b/src/Backends/DRMBackend.cpp
+index 9df20ae..ff1858b 100644
+--- a/src/Backends/DRMBackend.cpp
++++ b/src/Backends/DRMBackend.cpp
+@@ -68,7 +68,7 @@ gamescope::ConVar cv_drm_debug_disable_blend_tf( "drm_debug_disable_blend_
+ gamescope::ConVar cv_drm_debug_disable_ctm( "drm_debug_disable_ctm", false, "CTM chicken bit. (Forces CTM off, does not affect other logic)" );
+ gamescope::ConVar cv_drm_debug_disable_color_encoding( "drm_debug_disable_color_encoding", false, "YUV Color Encoding chicken bit. (Forces COLOR_ENCODING to DEFAULT, does not affect other logic)" );
+ gamescope::ConVar cv_drm_debug_disable_color_range( "drm_debug_disable_color_range", false, "YUV Color Range chicken bit. (Forces COLOR_RANGE to DEFAULT, does not affect other logic)" );
+-gamescope::ConVar cv_drm_debug_disable_explicit_sync( "drm_debug_disable_explicit_sync", false, "Force disable explicit sync on the DRM backend." );
++gamescope::ConVar cv_drm_debug_disable_explicit_sync( "drm_debug_disable_explicit_sync", true, "Force disable explicit sync on the DRM backend." );
+ gamescope::ConVar cv_drm_debug_disable_in_fence_fd( "drm_debug_disable_in_fence_fd", false, "Force disable IN_FENCE_FD being set to avoid over-synchronization on the DRM backend." );
+
+ // HACK:
+--
+2.45.2
+
+
+From 1dbcfed76f4b80d8a9f6570819b5af7917c786fc Mon Sep 17 00:00:00 2001
+From: Kyle Gospodnetich
+Date: Tue, 2 Jul 2024 14:12:47 -0700
+Subject: [PATCH 21/22] Only change refresh rates on internal displays
+
+---
+ src/Backends/DRMBackend.cpp | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/src/Backends/DRMBackend.cpp b/src/Backends/DRMBackend.cpp
+index ff1858b..f5a452e 100644
+--- a/src/Backends/DRMBackend.cpp
++++ b/src/Backends/DRMBackend.cpp
+@@ -2152,7 +2152,7 @@ namespace gamescope
+ ( m_Mutable.szMakePNP == "VLV"sv && m_Mutable.szModel == "Jupiter"sv ) ||
+ ( m_Mutable.szMakePNP == "VLV"sv && m_Mutable.szModel == "Galileo"sv );
+
+- if ( g_customRefreshRates.size() > 0 ) {
++ if ( g_customRefreshRates.size() > 0 && GetScreenType() == GAMESCOPE_SCREEN_TYPE_INTERNAL ) {
+ m_Mutable.ValidDynamicRefreshRates = std::span(g_customRefreshRates);
+ return;
+ }
+--
+2.45.2
+
+
+From 3b0408f6ec7307e7a38f2c795b932d0dc05f2d72 Mon Sep 17 00:00:00 2001
+From: Kyle Gospodnetich
+Date: Tue, 2 Jul 2024 15:14:23 -0700
+Subject: [PATCH 22/22] Also check g_bExternalForced
+
+---
+ src/Backends/DRMBackend.cpp | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/src/Backends/DRMBackend.cpp b/src/Backends/DRMBackend.cpp
+index f5a452e..d7f935d 100644
+--- a/src/Backends/DRMBackend.cpp
++++ b/src/Backends/DRMBackend.cpp
+@@ -2152,9 +2152,9 @@ namespace gamescope
+ ( m_Mutable.szMakePNP == "VLV"sv && m_Mutable.szModel == "Jupiter"sv ) ||
+ ( m_Mutable.szMakePNP == "VLV"sv && m_Mutable.szModel == "Galileo"sv );
+
+- if ( g_customRefreshRates.size() > 0 && GetScreenType() == GAMESCOPE_SCREEN_TYPE_INTERNAL ) {
+- m_Mutable.ValidDynamicRefreshRates = std::span(g_customRefreshRates);
+- return;
++ if ( g_customRefreshRates.size() > 0 && ( GetScreenType() == GAMESCOPE_SCREEN_TYPE_INTERNAL || g_bExternalForced ) ) {
++ m_Mutable.ValidDynamicRefreshRates = std::span(g_customRefreshRates);
++ return;
+ }
+ if ( bSteamDeckDisplay )
+ {
+--
+2.45.2
+
diff --git a/anda/games/gamescope/deckhd.patch b/anda/games/gamescope/deckhd.patch
new file mode 100644
index 0000000000..5140e85b0f
--- /dev/null
+++ b/anda/games/gamescope/deckhd.patch
@@ -0,0 +1,136 @@
+diff --git a/src/Backends/DRMBackend.cpp b/src/Backends/DRMBackend.cpp
+index 85e5126..be418b4 100644
+--- a/src/Backends/DRMBackend.cpp
++++ b/src/Backends/DRMBackend.cpp
+@@ -2149,6 +2149,7 @@ namespace gamescope
+ ( m_Mutable.szMakePNP == "WLC"sv && m_Mutable.szModel == "ANX7530 U"sv ) ||
+ ( m_Mutable.szMakePNP == "ANX"sv && m_Mutable.szModel == "ANX7530 U"sv ) ||
+ ( m_Mutable.szMakePNP == "VLV"sv && m_Mutable.szModel == "ANX7530 U"sv ) ||
++ ( m_Mutable.szMakePNP == "DHD"sv && m_Mutable.szModel == "DeckHD-1200p"sv ) ||
+ ( m_Mutable.szMakePNP == "VLV"sv && m_Mutable.szModel == "Jupiter"sv ) ||
+ ( m_Mutable.szMakePNP == "VLV"sv && m_Mutable.szModel == "Galileo"sv );
+
+@@ -2160,6 +2161,7 @@ namespace gamescope
+ {
+ static constexpr uint32_t kPIDGalileoSDC = 0x3003;
+ static constexpr uint32_t kPIDGalileoBOE = 0x3004;
++ static constexpr uint32_t kPIDJupiterDHD = 0x4001;
+
+ if ( pProduct->product == kPIDGalileoSDC )
+ {
+@@ -2171,6 +2173,10 @@ namespace gamescope
+ m_Mutable.eKnownDisplay = GAMESCOPE_KNOWN_DISPLAY_STEAM_DECK_OLED_BOE;
+ m_Mutable.ValidDynamicRefreshRates = std::span( s_kSteamDeckOLEDRates );
+ }
++ else if (pProduct-> product == kPIDJupiterDHD ) {
++ m_Mutable.eKnownDisplay = GAMESCOPE_KNOWN_DISPLAY_STEAM_DECK_LCD_DHD;
++ m_Mutable.ValidDynamicRefreshRates = std::span( s_kSteamDeckLCDRates );
++ }
+ else
+ {
+ m_Mutable.eKnownDisplay = GAMESCOPE_KNOWN_DISPLAY_STEAM_DECK_LCD;
+@@ -2200,7 +2206,8 @@ namespace gamescope
+ drm_log.infof( "[colorimetry]: Steam Deck LCD detected. Using known colorimetry" );
+ m_Mutable.DisplayColorimetry = displaycolorimetry_steamdeck_measured;
+ }
+- else
++ else if (m_Mutable.eKnownDisplay == GAMESCOPE_KNOWN_DISPLAY_STEAM_DECK_OLED_BOE ||
++ m_Mutable.eKnownDisplay == GAMESCOPE_KNOWN_DISPLAY_STEAM_DECK_OLED_SDC )
+ {
+ // Steam Deck OLED has calibrated chromaticity coordinates in the EDID
+ // for each unit.
+@@ -2330,7 +2337,7 @@ namespace gamescope
+ .uMinContentLightLevel = nits_to_u16_dark( 0 ),
+ };
+ }
+- else if ( eKnownDisplay == GAMESCOPE_KNOWN_DISPLAY_STEAM_DECK_LCD )
++ else if ( eKnownDisplay == GAMESCOPE_KNOWN_DISPLAY_STEAM_DECK_LCD || eKnownDisplay == GAMESCOPE_KNOWN_DISPLAY_STEAM_DECK_LCD_DHD )
+ {
+ // Set up some HDR fallbacks for undocking
+ return BackendConnectorHDRInfo
+diff --git a/src/gamescope_shared.h b/src/gamescope_shared.h
+index ed30d8c..3b60774 100644
+--- a/src/gamescope_shared.h
++++ b/src/gamescope_shared.h
+@@ -8,6 +8,7 @@ namespace gamescope
+ {
+ GAMESCOPE_KNOWN_DISPLAY_UNKNOWN,
+ GAMESCOPE_KNOWN_DISPLAY_STEAM_DECK_LCD, // Jupiter
++ GAMESCOPE_KNOWN_DISPLAY_STEAM_DECK_LCD_DHD, // Jupiter Deck HD
+ GAMESCOPE_KNOWN_DISPLAY_STEAM_DECK_OLED_SDC, // Galileo SDC
+ GAMESCOPE_KNOWN_DISPLAY_STEAM_DECK_OLED_BOE, // Galileo BOE
+ };
+diff --git a/src/modegen.cpp b/src/modegen.cpp
+index d174c2d..5dd1136 100644
+--- a/src/modegen.cpp
++++ b/src/modegen.cpp
+@@ -293,13 +293,32 @@ unsigned int galileo_boe_vfp[] =
+ 172,152,136,120,100,84,68,52,36,20,8
+ };
+
+-#define GALILEO_MIN_REFRESH 45
++//SD LCD Stock Timings
++#define JUPITER_BOE_PID 0x3001
++#define JUPITER_B_PID 0x3002
++#define JUPITER_HFP 40
++#define JUPITER_HSYNC 4
++#define JUPITER_HBP 40
++#define JUPITER_VFP 30
++#define JUPITER_VSYNC 4
++#define JUPITER_VBP 8
++//SD LCD DeckHD Timings
++#define JUPITER_DHD_PID 0x4001
++#define JUPITER_DHD_HFP 40
++#define JUPITER_DHD_HSYNC 20
++#define JUPITER_DHD_HBP 40
++#define JUPITER_DHD_VFP 18
++#define JUPITER_DHD_VSYNC 2
++#define JUPITER_DHD_VBP 20
++//SD OLED SDC Timings
+ #define GALILEO_SDC_PID 0x3003
+ #define GALILEO_SDC_VSYNC 1
+ #define GALILEO_SDC_VBP 22
++//SD OLED BOE Timings
+ #define GALILEO_BOE_PID 0x3004
+ #define GALILEO_BOE_VSYNC 2
+ #define GALILEO_BOE_VBP 30
++#define GALILEO_MIN_REFRESH 45
+ #define ARRAY_SIZE(x) (sizeof(x)/sizeof(x[0]))
+
+ unsigned int get_galileo_vfp( int vrefresh, unsigned int * vfp_array, unsigned int num_rates )
+@@ -344,17 +363,28 @@ void generate_fixed_mode(drmModeModeInfo *mode, const drmModeModeInfo *base, int
+ mode->vsync_end = mode->vsync_start + vsync;
+ mode->vtotal = mode->vsync_end + vbp;
+ } else {
+- if ( eKnownDisplay == gamescope::GAMESCOPE_KNOWN_DISPLAY_STEAM_DECK_LCD )
++ if ( eKnownDisplay == gamescope::GAMESCOPE_KNOWN_DISPLAY_STEAM_DECK_LCD_DHD ) {
++ mode->hdisplay = 1200;
++ mode->hsync_start = mode->hdisplay + JUPITER_DHD_HFP;
++ mode->hsync_end = mode->hsync_start + JUPITER_DHD_HSYNC;
++ mode->htotal = mode->hsync_end + JUPITER_DHD_HBP;
++
++ mode->vdisplay = 1920;
++ mode->vsync_start = mode->vdisplay + JUPITER_DHD_VFP;
++ mode->vsync_end = mode->vsync_start + JUPITER_DHD_VSYNC;
++ mode->vtotal = mode->vsync_end + JUPITER_DHD_VBP;
++ }
++ else if ( eKnownDisplay == gamescope::GAMESCOPE_KNOWN_DISPLAY_STEAM_DECK_LCD )
+ {
+ mode->hdisplay = 800;
+- mode->hsync_start = 840;
+- mode->hsync_end = 844;
+- mode->htotal = 884;
++ mode->hsync_start = mode->hdisplay + JUPITER_HFP;
++ mode->hsync_end = mode->hsync_start + JUPITER_HSYNC;
++ mode->htotal = mode->hsync_end + JUPITER_HBP;
+
+ mode->vdisplay = 1280;
+- mode->vsync_start = 1310;
+- mode->vsync_end = 1314;
+- mode->vtotal = 1322;
++ mode->vsync_start = mode->vdisplay + JUPITER_VFP;
++ mode->vsync_end = mode->vsync_start + JUPITER_VSYNC;
++ mode->vtotal = mode->vsync_end + JUPITER_VBP;
+ }
+
+ mode->clock = ( ( mode->htotal * mode->vtotal * vrefresh ) + 999 ) / 1000;
diff --git a/anda/games/gamescope/disable-steam-touch-click-atom.patch b/anda/games/gamescope/disable-steam-touch-click-atom.patch
new file mode 100644
index 0000000000..822b3a8e7e
--- /dev/null
+++ b/anda/games/gamescope/disable-steam-touch-click-atom.patch
@@ -0,0 +1,51 @@
+diff --git a/src/main.cpp b/src/main.cpp
+index 119e043..6c46d97 100644
+--- a/src/main.cpp
++++ b/src/main.cpp
+@@ -148,6 +148,8 @@ const struct option *gamescope_options = (struct option[]){
+ { "reshade-effect", required_argument, nullptr, 0 },
+ { "reshade-technique-idx", required_argument, nullptr, 0 },
+
++ { "disable-touch-click", no_argument, nullptr, 0 },
++
+ // Steam Deck options
+ { "mura-map", required_argument, nullptr, 0 },
+
+@@ -193,6 +195,7 @@ const char usage[] =
+ " -e, --steam enable Steam integration\n"
+ " --bypass-steam-resolution bypass Steam's default 720p/800p default resolution\n"
+ " --touch-gestures enable touch gestures for Steam menus\n"
++ " --disable-touch-click disable touchscreen tap acting as a click\n"
+ " --xwayland-count create N xwayland servers\n"
+ " --prefer-vk-device prefer Vulkan device for compositing (ex: 1002:7300)\n"
+ " --force-orientation rotate the internal display (left, right, normal, upsidedown)\n"
+diff --git a/src/steamcompmgr.cpp b/src/steamcompmgr.cpp
+index 92bf617..d7498e5 100644
+--- a/src/steamcompmgr.cpp
++++ b/src/steamcompmgr.cpp
+@@ -347,6 +347,7 @@ bool g_bHDRItmEnable = false;
+ int g_nCurrentRefreshRate_CachedValue = 0;
+ gamescope::ConVar cv_bypass_steam_resolution{ "bypass_steam_resolution", false, "Workaround the 720p/800p limits Steam uses for games" };
+
++gamescope::ConVar cv_disable_touch_click{ "disable_touch_click", false, "Prevents touchscreen taps acting as clicks" };
+
+ static void
+ update_color_mgmt()
+@@ -5128,7 +5129,7 @@ handle_property_notify(xwayland_ctx_t *ctx, XPropertyEvent *ev)
+ MakeFocusDirty();
+ }
+ }
+- if (ev->atom == ctx->atoms.steamTouchClickModeAtom )
++ if (ev->atom == ctx->atoms.steamTouchClickModeAtom && !cv_disable_touch_click)
+ {
+ gamescope::cv_touch_click_mode = (gamescope::TouchClickMode) get_prop(ctx, ctx->root, ctx->atoms.steamTouchClickModeAtom, 0u );
+ }
+@@ -7301,6 +7302,8 @@ steamcompmgr_main(int argc, char **argv)
+ g_reshade_technique_idx = atoi(optarg);
+ } else if (strcmp(opt_name, "mura-map") == 0) {
+ set_mura_overlay(optarg);
++ } else if (strcmp(opt_name, "disable-touch-click") == 0) {
++ cv_disable_touch_click = true;
+ }
+ break;
+ case '?':
diff --git a/anda/games/gamescope/drm-Separate-BOE-and-SDC-OLED-Deck-panel-rates.patch b/anda/games/gamescope/drm-Separate-BOE-and-SDC-OLED-Deck-panel-rates.patch
new file mode 100644
index 0000000000..f39afdbc4b
--- /dev/null
+++ b/anda/games/gamescope/drm-Separate-BOE-and-SDC-OLED-Deck-panel-rates.patch
@@ -0,0 +1,63 @@
+From 2e4d7ad1bf2cb98eb67ff8f9385cf6657cf2e912 Mon Sep 17 00:00:00 2001
+From: Matthew Schwartz
+Date: Wed, 3 Jul 2024 15:20:08 -0700
+Subject: [PATCH] drm: Separate BOE and SDC OLED Deck panel valid refresh rates
+
+OLED Decks with BOE panels seem to struggle with a few different
+specific modesets (51hz/55hz/65hz) that SDC panels have no issues with.
+To work around this, let's make use of Gamescope recognizing each
+display manufacturer to correct the bad modesets while leaving
+SDC panel units alone. This can be reverted if an underlying cause can
+be found in the kernel in the future.
+---
+ src/Backends/DRMBackend.cpp | 16 +++++++++++++---
+ 1 file changed, 13 insertions(+), 3 deletions(-)
+
+diff --git a/src/Backends/DRMBackend.cpp b/src/Backends/DRMBackend.cpp
+index 97ef446..9f93c7f 100644
+--- a/src/Backends/DRMBackend.cpp
++++ b/src/Backends/DRMBackend.cpp
+@@ -554,7 +554,7 @@ static constexpr uint32_t s_kSteamDeckLCDRates[] =
+ 60,
+ };
+
+-static constexpr uint32_t s_kSteamDeckOLEDRates[] =
++static constexpr uint32_t s_kSteamDeckOLEDSDCRates[] =
+ {
+ 45, 47, 48, 49,
+ 50, 51, 53, 55, 56, 59,
+@@ -564,6 +564,16 @@ static constexpr uint32_t s_kSteamDeckOLEDRates[] =
+ 90,
+ };
+
++static constexpr uint32_t s_kSteamDeckOLEDBOERates[] =
++{
++ 45, 47, 48, 49,
++ 50, 53, 56, 59,
++ 60, 62, 64, 66, 68,
++ 72, 73, 76, 77, 78,
++ 80, 81, 82, 84, 85, 86, 87, 88,
++ 90,
++};
++
+ static void update_connector_display_info_wl(struct drm_t *drm)
+ {
+ wlserver_lock();
+@@ -2128,12 +2138,12 @@ namespace gamescope
+ if ( pProduct->product == kPIDGalileoSDC )
+ {
+ m_Mutable.eKnownDisplay = GAMESCOPE_KNOWN_DISPLAY_STEAM_DECK_OLED_SDC;
+- m_Mutable.ValidDynamicRefreshRates = std::span( s_kSteamDeckOLEDRates );
++ m_Mutable.ValidDynamicRefreshRates = std::span( s_kSteamDeckOLEDSDCRates );
+ }
+ else if ( pProduct->product == kPIDGalileoBOE )
+ {
+ m_Mutable.eKnownDisplay = GAMESCOPE_KNOWN_DISPLAY_STEAM_DECK_OLED_BOE;
+- m_Mutable.ValidDynamicRefreshRates = std::span( s_kSteamDeckOLEDRates );
++ m_Mutable.ValidDynamicRefreshRates = std::span( s_kSteamDeckOLEDBOERates );
+ }
+ else
+ {
+--
+2.45.2
+
diff --git a/anda/games/gamescope/revert-299bc34.patch b/anda/games/gamescope/revert-299bc34.patch
new file mode 100644
index 0000000000..550870fe82
--- /dev/null
+++ b/anda/games/gamescope/revert-299bc34.patch
@@ -0,0 +1,65 @@
+diff --git a/src/steamcompmgr.cpp b/src/steamcompmgr.cpp
+index d7498e5..d1800a8 100644
+--- a/src/steamcompmgr.cpp
++++ b/src/steamcompmgr.cpp
+@@ -3271,7 +3271,7 @@ found:;
+ if ( window_has_commits( focus ) )
+ out->focusWindow = focus;
+ else
+- focus->outdatedInteractiveFocus = true;
++ out->outdatedInteractiveFocus = true;
+
+ // Always update X's idea of focus, but still dirty
+ // the it being outdated so we can resolve that globally later.
+@@ -5995,28 +5995,37 @@ bool handle_done_commit( steamcompmgr_win_t *w, xwayland_ctx_t *ctx, uint64_t co
+ // Window just got a new available commit, determine if that's worth a repaint
+
+ // If this is an overlay that we're presenting, repaint
+- if ( w == global_focus.overlayWindow && w->opacity != TRANSLUCENT )
++ if ( gameFocused )
+ {
+- hasRepaintNonBasePlane = true;
+- }
++ if ( w == global_focus.overlayWindow && w->opacity != TRANSLUCENT )
++ {
++ hasRepaintNonBasePlane = true;
++ }
+
+- if ( w == global_focus.notificationWindow && w->opacity != TRANSLUCENT )
+- {
+- hasRepaintNonBasePlane = true;
++ if ( w == global_focus.notificationWindow && w->opacity != TRANSLUCENT )
++ {
++ hasRepaintNonBasePlane = true;
++ }
+ }
+-
+- // If this is an external overlay, repaint
+- if ( w == global_focus.externalOverlayWindow && w->opacity != TRANSLUCENT )
++ if ( ctx )
+ {
+- hasRepaintNonBasePlane = true;
++ if ( ctx->focus.outdatedInteractiveFocus )
++ {
++ MakeFocusDirty();
++ ctx->focus.outdatedInteractiveFocus = false;
++ }
+ }
+-
+- if ( w->outdatedInteractiveFocus )
++ if ( global_focus.outdatedInteractiveFocus )
+ {
+ MakeFocusDirty();
+- w->outdatedInteractiveFocus = false;
+- }
++ global_focus.outdatedInteractiveFocus = false;
+
++ // If this is an external overlay, repaint
++ if ( w == global_focus.externalOverlayWindow && w->opacity != TRANSLUCENT )
++ {
++ hasRepaintNonBasePlane = true;
++ }
++ }
+ // If this is the main plane, repaint
+ if ( w == global_focus.focusWindow && !w->isSteamStreamingClient )
+ {
diff --git a/anda/games/gamescope/stb.pc b/anda/games/gamescope/stb.pc
new file mode 100644
index 0000000000..02c304a9fa
--- /dev/null
+++ b/anda/games/gamescope/stb.pc
@@ -0,0 +1,7 @@
+prefix=/usr
+includedir=${prefix}/include/stb
+
+Name: stb
+Description: Single-file public domain libraries for C/C++
+Version: 0.1.0
+Cflags: -I${includedir}
diff --git a/anda/games/gamescope/terra-gamescope.spec b/anda/games/gamescope/terra-gamescope.spec
new file mode 100644
index 0000000000..bf92262f3d
--- /dev/null
+++ b/anda/games/gamescope/terra-gamescope.spec
@@ -0,0 +1,139 @@
+%global libliftoff_minver 0.4.1
+
+%global _default_patch_fuzz 2
+%global gamescope_tag 3.14.24
+
+Name: terra-gamescope
+Version: 100.%{gamescope_tag}
+Release: 1%?dist
+Summary: Micro-compositor for video games on Wayland
+
+License: BSD
+URL: https://github.com/ValveSoftware/gamescope
+
+# Create stb.pc to satisfy dependency('stb')
+Source0: stb.pc
+
+# https://github.com/ChimeraOS/gamescope
+Patch0: chimeraos.patch
+# https://hhd.dev/
+Patch1: disable-steam-touch-click-atom.patch
+# https://github.com/ValveSoftware/gamescope/pull/1281
+Patch2: deckhd.patch
+# https://github.com/ValveSoftware/gamescope/issues/1398
+Patch3: drm-Separate-BOE-and-SDC-OLED-Deck-panel-rates.patch
+# https://github.com/ValveSoftware/gamescope/issues/1369
+Patch4: revert-299bc34.patch
+# https://github.com/ValveSoftware/gamescope/pull/1231
+Patch5: 1231.patch
+
+BuildRequires: meson >= 0.54.0
+BuildRequires: ninja-build
+BuildRequires: cmake
+BuildRequires: gcc
+BuildRequires: gcc-c++
+BuildRequires: glm-devel
+BuildRequires: google-benchmark-devel
+BuildRequires: libXmu-devel
+BuildRequires: libXcursor-devel
+BuildRequires: libeis-devel
+BuildRequires: pixman-devel
+BuildRequires: pkgconfig(libdisplay-info)
+BuildRequires: pkgconfig(pixman-1)
+BuildRequires: pkgconfig(x11)
+BuildRequires: pkgconfig(xdamage)
+BuildRequires: pkgconfig(xcomposite)
+BuildRequires: pkgconfig(xrender)
+BuildRequires: pkgconfig(xext)
+BuildRequires: pkgconfig(xfixes)
+BuildRequires: pkgconfig(xxf86vm)
+BuildRequires: pkgconfig(xtst)
+BuildRequires: pkgconfig(xres)
+BuildRequires: pkgconfig(libdrm)
+BuildRequires: pkgconfig(vulkan)
+BuildRequires: pkgconfig(wayland-scanner)
+BuildRequires: pkgconfig(wayland-server)
+BuildRequires: pkgconfig(wayland-protocols) >= 1.17
+BuildRequires: pkgconfig(xkbcommon)
+BuildRequires: pkgconfig(sdl2)
+BuildRequires: pkgconfig(libpipewire-0.3)
+BuildRequires: pkgconfig(libavif)
+#BuildRequires: (pkgconfig(wlroots) >= 0.18.0 with pkgconfig(wlroots) < 0.19.0)
+#BuildRequires: (pkgconfig(libliftoff) >= 0.4.1 with pkgconfig(libliftoff) < 0.5)
+BuildRequires: pkgconfig(libliftoff)
+BuildRequires: pkgconfig(libcap)
+BuildRequires: pkgconfig(hwdata)
+BuildRequires: pkgconfig(libudev)
+BuildRequires: pkgconfig(libseat)
+BuildRequires: pkgconfig(libinput)
+BuildRequires: xcb-util-wm-devel
+BuildRequires: pkgconfig(xcb-errors)
+BuildRequires: spirv-headers-devel
+# Enforce the the minimum EVR to contain fixes for all of:
+# CVE-2021-28021 CVE-2021-42715 CVE-2021-42716 CVE-2022-28041 CVE-2023-43898
+# CVE-2023-45661 CVE-2023-45662 CVE-2023-45663 CVE-2023-45664 CVE-2023-45666
+# CVE-2023-45667
+BuildRequires: stb_image-devel >= 2.28^20231011gitbeebb24-12
+# Header-only library: -static is for tracking per guidelines
+BuildRequires: stb_image-static
+BuildRequires: stb_image_resize-devel
+BuildRequires: stb_image_resize-static
+BuildRequires: stb_image_write-devel
+BuildRequires: stb_image_write-static
+BuildRequires: /usr/bin/glslangValidator
+BuildRequires: libdecor-devel
+BuildRequires: libXdamage-devel
+BuildRequires: xorg-x11-server-Xwayland-devel
+BuildRequires: git
+
+# libliftoff hasn't bumped soname, but API/ABI has changed for 0.2.0 release
+Requires: libliftoff%{?_isa} >= %{libliftoff_minver}
+Requires: xorg-x11-server-Xwayland
+Requires: %{name}-libs = %{version}-%{release}
+%ifarch %{ix86}
+Requires: %{name}-libs(x86-32) = %{version}-%{release}
+%endif
+Recommends: mesa-dri-drivers
+Recommends: mesa-vulkan-drivers
+
+%description
+Gamescope is the micro-compositor optimized for running video games on Wayland.
+
+%package libs
+Summary: libs for Gamescope
+%description libs
+%summary
+
+%prep
+git clone --depth 1 --branch %{gamescope_tag} %{url}.git
+cd gamescope
+git submodule update --init --recursive
+mkdir -p pkgconfig
+cp %{SOURCE0} pkgconfig/stb.pc
+
+# Replace spirv-headers include with the system directory
+sed -i 's^../thirdparty/SPIRV-Headers/include/spirv/^/usr/include/spirv/^' src/meson.build
+
+%autopatch -p1
+
+%build
+cd gamescope
+export PKG_CONFIG_PATH=pkgconfig
+%meson -Dpipewire=enabled -Dinput_emulation=enabled -Ddrm_backend=enabled -Drt_cap=enabled -Davif_screenshots=enabled -Dsdl2_backend=enabled
+%meson_build
+
+%install
+cd gamescope
+%meson_install --skip-subprojects
+
+%files
+%license gamescope/LICENSE
+%doc gamescope/README.md
+%caps(cap_sys_nice=eip) %{_bindir}/gamescope
+%{_bindir}/gamescopectl
+%{_bindir}/gamescopestream
+%{_bindir}/gamescopereaper
+
+%files libs
+%{_libdir}/libVkLayer_FROG_gamescope_wsi_*.so
+%{_datadir}/vulkan/implicit_layer.d/VkLayer_FROG_gamescope_wsi.*.json
diff --git a/anda/games/gamescope/update.rhai b/anda/games/gamescope/update.rhai
new file mode 100644
index 0000000000..74a18ee692
--- /dev/null
+++ b/anda/games/gamescope/update.rhai
@@ -0,0 +1 @@
+rpm.global("gamescope_tag", gh_tag("ValveSoftware/gamescope"));
diff --git a/anda/games/osu-lazer/osu-lazer.spec b/anda/games/osu-lazer/osu-lazer.spec
index 53120c2047..e708e35101 100644
--- a/anda/games/osu-lazer/osu-lazer.spec
+++ b/anda/games/osu-lazer/osu-lazer.spec
@@ -3,7 +3,7 @@
%define __strip /bin/true
Name: osu-lazer
-Version: 2024.625.2
+Version: 2024.718.1
Release: 1%?dist
Summary: The future of osu! and the beginning of an open era! Commonly known by the codename osu!lazer. Pew pew.
ExclusiveArch: x86_64
diff --git a/anda/games/prismlauncher-nightly/prismlauncher-nightly.spec b/anda/games/prismlauncher-nightly/prismlauncher-nightly.spec
index 56dbed40cd..97729503e2 100644
--- a/anda/games/prismlauncher-nightly/prismlauncher-nightly.spec
+++ b/anda/games/prismlauncher-nightly/prismlauncher-nightly.spec
@@ -1,11 +1,11 @@
%global real_name prismlauncher
%global nice_name PrismLauncher
-%global commit 2df5d4012c3822171172ca380d2429e5d836aaf4
+%global commit 6352362907149d297684473f3d606b08ce1b93f5
%global shortcommit %(c=%{commit}; echo ${c:0:7})
%global libnbtplusplus_commit a5e8fd52b8bf4ab5d5bcc042b2a247867589985f
-%global commit_date 20240714
+%global commit_date 20240721
%global snapshot_info %{commit_date}.%{shortcommit}
%bcond_without qt6
diff --git a/anda/langs/crystal/crystal/update.rhai b/anda/langs/crystal/crystal/update.rhai
index f42bf45c60..b2159a6775 100644
--- a/anda/langs/crystal/crystal/update.rhai
+++ b/anda/langs/crystal/crystal/update.rhai
@@ -1,9 +1,9 @@
let v = gh("crystal-lang/crystal");
-let url = `https://github.com/crystal-lang/crystal/releases/download/${v}/crystal-${v}-1-linux-x86_64-bundled.tar.gz`;
-try {
- find(url, get(`https://github.com/crystal-lang/crystal/releases/tag/${v}`), 0);
+let url = `crystal-${v}-1-linux-x86_64-bundled.tar.gz`;
+
+if get(`https://github.com/crystal-lang/crystal/releases/expanded_assets/${v}`).contains(url) {
rpm.version(v);
-} except {
+} else {
print(`crystal: ${v} (waiting for bundle)`);
terminate();
}
diff --git a/anda/langs/kotlin/kotlin-native/kotlin-native.spec b/anda/langs/kotlin/kotlin-native/kotlin-native.spec
index fce3fc1e08..9354172cd7 100644
--- a/anda/langs/kotlin/kotlin-native/kotlin-native.spec
+++ b/anda/langs/kotlin/kotlin-native/kotlin-native.spec
@@ -2,14 +2,14 @@
BuildRoot: %{_tmppath}/%{name}-%{version}-build
Name: kotlin-native
-Version: 2.0.0
+Version: 1.9.25
Release: 1%?dist
Summary: LLVM backend for the Kotlin compiler
ExclusiveArch: x86_64
License: ASL 2.0
URL: https://kotlinlang.org/docs/reference/native-overview.html
-Source0: https://github.com/JetBrains/kotlin/releases/download/v%version/kotlin-native-prebuilt-linux-x86_64-%version.tar.gz
+Source0: https://github.com/JetBrains/kotlin/releases/download/v%version/kotlin-native-linux-x86_64-%version.tar.gz
BuildRequires: tar
BuildRequires: sed
@@ -28,7 +28,7 @@ Kotlin compiler and native implementation of the Kotlin standard library.
%prep
-tar -xf %{SOURCE0} && cd kotlin-native-prebuilt-linux-x86_64-%{version}
+tar -xf %{SOURCE0} && cd kotlin-native-linux-x86_64-%{version}
sed -i "s|\(DIR *= *\).*|\1%{_bindir}|" bin/*
sed -i "s|\(KONAN_HOME *= *\).*|\1%{_datadir}/%{name}|" bin/*
@@ -36,7 +36,7 @@ sed -i "s|\(KONAN_HOME *= *\).*|\1%{_datadir}/%{name}|" bin/*
%build
%install
-rm -rf %{buildroot} && mkdir -p %{buildroot}%{_bindir}/ && cd kotlin-native-prebuilt-linux-x86_64-%{version}
+rm -rf %{buildroot} && mkdir -p %{buildroot}%{_bindir}/ && cd kotlin-native-linux-x86_64-%{version}
install -m 0755 bin/cinterop %{buildroot}%{_bindir}/
install -m 0755 bin/generate-platform %{buildroot}%{_bindir}/
install -m 0755 bin/jsinterop %{buildroot}%{_bindir}/
diff --git a/anda/langs/kotlin/kotlin/kotlin.spec b/anda/langs/kotlin/kotlin/kotlin.spec
index f4ae3089a7..dbb00c9ac2 100644
--- a/anda/langs/kotlin/kotlin/kotlin.spec
+++ b/anda/langs/kotlin/kotlin/kotlin.spec
@@ -1,7 +1,7 @@
BuildRoot: %{_tmppath}/%{name}-%{version}-build
BuildArch: noarch
Name: kotlin
-Version: 2.0.0
+Version: 1.9.25
Release: 1%?dist
Summary: Statically typed programming language
diff --git a/anda/langs/nim/nim-nightly/nim-nightly.spec b/anda/langs/nim/nim-nightly/nim-nightly.spec
index 5316b31c93..5f2b762e16 100644
--- a/anda/langs/nim/nim-nightly/nim-nightly.spec
+++ b/anda/langs/nim/nim-nightly/nim-nightly.spec
@@ -1,8 +1,8 @@
%global csrc_commit 561b417c65791cd8356b5f73620914ceff845d10
-%global commit f6aeca5765bb48abc6efbe35e4ea6accf127d072
+%global commit 881fbb8f81599c6f633158618f05fa05439816ca
%global shortcommit %(c=%{commit}; echo ${c:0:7})
%global ver 2.1.9
-%global commit_date 20240713
+%global commit_date 20240723
%global debug_package %nil
Name: nim-nightly
diff --git a/anda/langs/nim/nim/nim.spec b/anda/langs/nim/nim/nim.spec
index afe2260a3e..1ac2069ca4 100644
--- a/anda/langs/nim/nim/nim.spec
+++ b/anda/langs/nim/nim/nim.spec
@@ -7,12 +7,12 @@ Release: 1%?dist
Summary: Imperative, multi-paradigm, compiled programming language
License: MIT and BSD
URL: https://nim-lang.org
-Source0: https://nim-lang.org/download/nim-%{version}-linux_x64.tar.xz
Source1: nim.1
Source2: nimgrep.1
Source3: nimble.1
Source4: nimsuggest.1
-BuildRequires: gcc mold git gcc-c++ nodejs openssl-devel pkgconfig(bash-completion) gc-devel pcre-devel
+BuildRequires: gcc mold git-core gcc-c++ nodejs openssl-devel pkgconfig(bash-completion) gc-devel pcre-devel
+BuildRequires: redhat-rpm-config
Requires: gcc
@@ -46,7 +46,11 @@ and its standard library.
%prep
-%autosetup -n nim-%{version}
+rm -rf ./*
+# using git clone to include submodules
+git clone --recurse-submodules -j8 https://github.com/nim-lang/Nim -b v%version --depth 1 .
+# hack
+cp /usr/bin/mold /usr/bin/ld
%build
@@ -57,15 +61,18 @@ export FCFLAGS="${FCFLAGS} -Ofast"
export PATH="$(pwd):$(pwd)/bin:${PATH}"
-mold -run nim c -d:danger koch.nim
-mold -run koch boot -d:useLinenoise -t:-fPIE -l:-pie -d:release -d:nativeStacktrace -d:useGnuReadline
+. ci/funs.sh
+nimBuildCsourcesIfNeeded CFLAGS="${CFLAGS} -Ic_code -w -O3 -fno-strict-aliasing -fPIE" LDFLAGS="-ldl -lm -lrt -pie"
+
+nim c --noNimblePath --skipUserCfg --skipParentCfg --hints:off -d:danger koch.nim
+koch boot -d:release -d:nimStrictMode --lib:lib
%ifarch x86_64
-mold -run koch docs &
+koch docs &
%endif
(cd lib && nim c --app:lib -d:createNimRtl -d:release nimrtl.nim) &
-mold -run koch tools -t:-fPIE -l:-pie &
-mold -run nim c -t:-fPIE -l:-pie -d:release nimsuggest/nimsuggest.nim &
+koch tools -t:-fPIE -l:-pie &
+nim c -d:danger -t:-fPIE -l:-pie nimsuggest/nimsuggest.nim &
wait
%ifarch x86_64
@@ -75,24 +82,24 @@ sed -i '/= 4.4
Requires: glib2 >= 2.66.0
Requires: libgee >= 0.20
Requires: tau-helium >= 1.1.25
+Requires: tau-hydrogen
%description
The Application Framework for tauOS apps
@@ -34,7 +37,7 @@ This package contains the libraries and header files that are needed
for writing applications with libhelium.
%prep
-%autosetup -n libhelium-%{version}
+%autosetup -n libhelium-%{ver}
%build
%meson \
diff --git a/anda/lib/libhelium/update.rhai b/anda/lib/libhelium/update.rhai
index 67592e6360..019b70b830 100644
--- a/anda/lib/libhelium/update.rhai
+++ b/anda/lib/libhelium/update.rhai
@@ -1 +1 @@
-rpm.version(gh("tau-OS/libhelium"));
+rpm.global("ver",gh("tau-OS/libhelium"));
diff --git a/anda/system/limine/limine.spec b/anda/system/limine/limine.spec
index fc19d9cf02..304c3b05d2 100644
--- a/anda/system/limine/limine.spec
+++ b/anda/system/limine/limine.spec
@@ -1,5 +1,5 @@
Name: limine
-Version: 7.10.2
+Version: 7.12.0
Release: 1%?dist
Summary: Modern, advanced, portable, multiprotocol bootloader
License: BSD-2-Clause
diff --git a/anda/system/nvidia-patch/nvidia-patch.spec b/anda/system/nvidia-patch/nvidia-patch.spec
index fd5a2efb02..732b84889a 100644
--- a/anda/system/nvidia-patch/nvidia-patch.spec
+++ b/anda/system/nvidia-patch/nvidia-patch.spec
@@ -1,13 +1,13 @@
%global debug_package %{nil}
-%global commit 87fe7b874b3db1489d7313c667130ef22c445bd7
+%global commit c7221dd770279275a06f34e68b39b8d237ea9b7b
%global shortcommit %(c=%{commit}; echo ${c:0:7})
-%global commit_date 20240711
+%global commit_date 20240719
%global patches %{_datadir}/src/nvidia-patch
Name: nvidia-patch
Version: 0^%commit_date.%{shortcommit}
-Release: 1%{?dist}
+Release: 1%?dist
Summary: NVENC and NvFBC patches for NVIDIA drivers
License: EULA
diff --git a/anda/terra/mock-configs/terra-38-aarch64.cfg b/anda/terra/mock-configs/terra-38-aarch64.cfg
deleted file mode 100644
index 42efc70495..0000000000
--- a/anda/terra/mock-configs/terra-38-aarch64.cfg
+++ /dev/null
@@ -1,5 +0,0 @@
-config_opts['releasever'] = '38'
-config_opts['target_arch'] = 'aarch64'
-config_opts['legal_host_arches'] = ('aarch64',)
-
-include('templates/terra.tpl')
diff --git a/anda/terra/mock-configs/terra-38-x86_64.cfg b/anda/terra/mock-configs/terra-38-x86_64.cfg
deleted file mode 100644
index caa7a68cc3..0000000000
--- a/anda/terra/mock-configs/terra-38-x86_64.cfg
+++ /dev/null
@@ -1,5 +0,0 @@
-config_opts['releasever'] = '38'
-config_opts['target_arch'] = 'x86_64'
-config_opts['legal_host_arches'] = ('x86_64',)
-
-include('templates/terra.tpl')
diff --git a/anda/terra/mock-configs/terra-39-aarch64.cfg b/anda/terra/mock-configs/terra-39-aarch64.cfg
deleted file mode 100644
index 4136783d27..0000000000
--- a/anda/terra/mock-configs/terra-39-aarch64.cfg
+++ /dev/null
@@ -1,5 +0,0 @@
-config_opts['releasever'] = '39'
-config_opts['target_arch'] = 'aarch64'
-config_opts['legal_host_arches'] = ('aarch64',)
-
-include('templates/terra.tpl')
diff --git a/anda/terra/mock-configs/terra-39-x86_64.cfg b/anda/terra/mock-configs/terra-39-x86_64.cfg
deleted file mode 100644
index c4cff70d68..0000000000
--- a/anda/terra/mock-configs/terra-39-x86_64.cfg
+++ /dev/null
@@ -1,5 +0,0 @@
-config_opts['releasever'] = '39'
-config_opts['target_arch'] = 'x86_64'
-config_opts['legal_host_arches'] = ('x86_64',)
-
-include('templates/terra.tpl')
diff --git a/anda/terra/mock-configs/terra-mock-configs.spec b/anda/terra/mock-configs/terra-mock-configs.spec
index dfe9dfc468..8e311b7eb3 100644
--- a/anda/terra/mock-configs/terra-mock-configs.spec
+++ b/anda/terra/mock-configs/terra-mock-configs.spec
@@ -1,66 +1,51 @@
Name: terra-mock-configs
-Version: 9
+Version: 1.0.0
Release: 1%{?dist}
+Epoch: 1
Summary: Mock configs for Terra repos
License: MIT
-URL: https://terra.fyralabs.com
-Source0: terra.tpl
-Source1: terra-38-x86_64.cfg
-Source2: terra-38-aarch64.cfg
-Source3: terra-39-x86_64.cfg
-Source4: terra-39-aarch64.cfg
-Source5: terra-rawhide-x86_64.cfg
-Source6: terra-rawhide-aarch64.cfg
+URL: https://github.com/terrapkg/mock-configs
+Source0: %url/archive/refs/tags/v%version.tar.gz
BuildRequires: mock-core-configs
Requires: mock-core-configs
BuildArch: noarch
-Provides: anda-mock-configs = %{version}-%{release}
+Provides: anda-mock-configs = %{epoch}:%{version}-%{release}
Obsoletes: anda-mock-configs < 3-2%{?dist}
%description
%{summary}
%prep
+%autosetup -n mock-configs-%version
%build
-
%install
mkdir -p %{buildroot}%{_sysusersdir}
mkdir -p %{buildroot}%{_sysconfdir}/mock/templates
-
-cp -v %{SOURCE0} %{buildroot}%{_sysconfdir}/mock/templates/
-cp -v %{SOURCE1} %{buildroot}%{_sysconfdir}/mock/
-cp -v %{SOURCE2} %{buildroot}%{_sysconfdir}/mock/
-cp -v %{SOURCE3} %{buildroot}%{_sysconfdir}/mock/
-cp -v %{SOURCE4} %{buildroot}%{_sysconfdir}/mock/
-cp -v %{SOURCE5} %{buildroot}%{_sysconfdir}/mock/
-cp -v %{SOURCE6} %{buildroot}%{_sysconfdir}/mock/
-
-# For legacy compatibility, only while Terra 38 is still alive
-ln -s %{_sysconfdir}/mock/templates/terra.tpl %{buildroot}%{_sysconfdir}/mock/templates/anda.tpl
-ln -s %{_sysconfdir}/mock/terra-38-x86_64.cfg %{buildroot}%{_sysconfdir}/mock/anda-38-x86_64.cfg
-ln -s %{_sysconfdir}/mock/terra-38-aarch64.cfg %{buildroot}%{_sysconfdir}/mock/anda-38-aarch64.cfg
+cp -v terra.tpl %{buildroot}%{_sysconfdir}/mock/templates/
+cp -v *.cfg %{buildroot}%{_sysconfdir}/mock/
%files
%config %{_sysconfdir}/mock/templates/terra.tpl
-%config %{_sysconfdir}/mock/terra-rawhide-x86_64.cfg
-%config %{_sysconfdir}/mock/terra-rawhide-aarch64.cfg
-%config %{_sysconfdir}/mock/terra-39-x86_64.cfg
-%config %{_sysconfdir}/mock/terra-39-aarch64.cfg
-%config %{_sysconfdir}/mock/terra-38-x86_64.cfg
-%config %{_sysconfdir}/mock/terra-38-aarch64.cfg
-%config %{_sysconfdir}/mock/templates/anda.tpl
-%config %{_sysconfdir}/mock/anda-38-x86_64.cfg
-%config %{_sysconfdir}/mock/anda-38-aarch64.cfg
+%config %{_sysconfdir}/mock/terra-*-x86_64.cfg
+%config %{_sysconfdir}/mock/terra-*-aarch64.cfg
+%config %{_sysconfdir}/mock/terra-*-i386.cfg
%changelog
-* Mon Jan 15 2024 madonuko - 9.1
-- Update for Terra rawhide
+* Mon Jul 22 2024 Lleyton Gray - 1:1.0.0-1
+- Migrate to pulling configs from an external repository
+
+* Thu Jul 18 2024 Cappy Ishihara - 11-1
+- Include multilib mock files for x86-based systems (backwards compatibility)
+
+* Wed Jul 10 2024 madonuko - 10-1
+- Include mock files for Terra 40
+- Remove mock files for Terra 38
* Mon Jan 08 2024 Lleyton Gray - 7-1
- Bump ccache max size to 10G
diff --git a/anda/terra/mock-configs/terra-rawhide-aarch64.cfg b/anda/terra/mock-configs/terra-rawhide-aarch64.cfg
deleted file mode 100644
index 659d4c4c38..0000000000
--- a/anda/terra/mock-configs/terra-rawhide-aarch64.cfg
+++ /dev/null
@@ -1,5 +0,0 @@
-config_opts['releasever'] = 'rawhide'
-config_opts['target_arch'] = 'aarch64'
-config_opts['legal_host_arches'] = ('aarch64',)
-
-include('templates/terra.tpl')
diff --git a/anda/terra/mock-configs/terra-rawhide-x86_64.cfg b/anda/terra/mock-configs/terra-rawhide-x86_64.cfg
deleted file mode 100644
index 3402689dac..0000000000
--- a/anda/terra/mock-configs/terra-rawhide-x86_64.cfg
+++ /dev/null
@@ -1,5 +0,0 @@
-config_opts['releasever'] = 'rawhide'
-config_opts['target_arch'] = 'x86_64'
-config_opts['legal_host_arches'] = ('x86_64',)
-
-include('templates/terra.tpl')
diff --git a/anda/terra/mock-configs/terra.tpl b/anda/terra/mock-configs/terra.tpl
deleted file mode 100644
index e3edff879b..0000000000
--- a/anda/terra/mock-configs/terra.tpl
+++ /dev/null
@@ -1,182 +0,0 @@
-config_opts['root'] = 'terra-{{ releasever }}-{{ target_arch }}'
-config_opts['dist'] = 'fc{{ releasever }}' # only useful for --resultdir variable subst
-config_opts['macros']['%dist'] = '.fc{{ releasever }}'
-config_opts['chroot_setup_cmd'] = 'install @buildsys-build'
-config_opts['package_manager'] = 'dnf5'
-config_opts['extra_chroot_dirs'] = [ '/run/lock', ]
-config_opts['bootstrap_image'] = 'registry.fedoraproject.org/fedora:{{ releasever }}'
-config_opts['mirrored'] = True
-config_opts['plugin_conf']['root_cache_enable'] = True
-config_opts['plugin_conf']['yum_cache_enable'] = True
-config_opts['plugin_conf']['ccache_enable'] = True
-config_opts['plugin_conf']['ccache_opts']['compress'] = 'on'
-config_opts['plugin_conf']['ccache_opts']['max_cache_size'] = '10G'
-# repos
-dnf_conf = """
-
-[main]
-keepcache=1
-debuglevel=2a
-reposdir=/dev/null
-logfile=/var/log/yum.log
-retries=20
-obsoletes=1
-gpgcheck=0
-assumeyes=1
-syslog_ident=mock
-syslog_device=
-install_weak_deps=0
-metadata_expire=0
-best=1
-module_platform_id=platform:fc{{ releasever }}
-protected_packages=
-
-[terra]
-name=Terra $releasever
-baseurl=https://repos.fyralabs.com/terra$releasever
-type=rpm
-skip_if_unavailable=True
-gpgcheck=1
-repo_gpgcheck=1
-gpgkey=https://repos.fyralabs.com/terra$releasever/key.asc
-enabled=1
-enabled_metadata=1
-metadata_expire=4h
-
-
-{% if mirrored %}
-[fedora]
-name=fedora
-metalink=https://mirrors.fedoraproject.org/metalink?repo=fedora-$releasever&arch=$basearch
-gpgkey=file:///usr/share/distribution-gpg-keys/fedora/RPM-GPG-KEY-fedora-{{ releasever }}-primary
-gpgcheck=1
-skip_if_unavailable=False
-exclude=fedora-release*
-
-[updates]
-name=updates
-metalink=https://mirrors.fedoraproject.org/metalink?repo=updates-released-f$releasever&arch=$basearch
-gpgkey=file:///usr/share/distribution-gpg-keys/fedora/RPM-GPG-KEY-fedora-{{ releasever }}-primary
-gpgcheck=1
-skip_if_unavailable=False
-
-[updates-testing]
-name=updates-testing
-metalink=https://mirrors.fedoraproject.org/metalink?repo=updates-testing-f$releasever&arch=$basearch
-enabled=0
-gpgkey=file:///usr/share/distribution-gpg-keys/fedora/RPM-GPG-KEY-fedora-{{ releasever }}-primary
-gpgcheck=1
-skip_if_unavailable=False
-
-[fedora-debuginfo]
-name=fedora-debuginfo
-metalink=https://mirrors.fedoraproject.org/metalink?repo=fedora-debug-$releasever&arch=$basearch
-enabled=0
-gpgkey=file:///usr/share/distribution-gpg-keys/fedora/RPM-GPG-KEY-fedora-{{ releasever }}-primary
-gpgcheck=1
-skip_if_unavailable=False
-
-[updates-debuginfo]
-name=updates-debuginfo
-metalink=https://mirrors.fedoraproject.org/metalink?repo=updates-released-debug-f$releasever&arch=$basearch
-enabled=0
-gpgkey=file:///usr/share/distribution-gpg-keys/fedora/RPM-GPG-KEY-fedora-{{ releasever }}-primary
-gpgcheck=1
-skip_if_unavailable=False
-
-[updates-testing-debuginfo]
-name=updates-testing-debuginfo
-metalink=https://mirrors.fedoraproject.org/metalink?repo=updates-testing-debug-f$releasever&arch=$basearch
-enabled=0
-gpgkey=file:///usr/share/distribution-gpg-keys/fedora/RPM-GPG-KEY-fedora-{{ releasever }}-primary
-gpgcheck=1
-skip_if_unavailable=False
-
-[fedora-source]
-name=fedora-source
-metalink=https://mirrors.fedoraproject.org/metalink?repo=fedora-source-$releasever&arch=$basearch
-gpgkey=file:///usr/share/distribution-gpg-keys/fedora/RPM-GPG-KEY-fedora-{{ releasever }}-primary
-gpgcheck=1
-enabled=0
-skip_if_unavailable=False
-
-[updates-source]
-name=updates-source
-metalink=https://mirrors.fedoraproject.org/metalink?repo=updates-released-source-f$releasever&arch=$basearch
-gpgkey=file:///usr/share/distribution-gpg-keys/fedora/RPM-GPG-KEY-fedora-{{ releasever }}-primary
-gpgcheck=1
-enabled=0
-skip_if_unavailable=False
-
-# modular
-
-[fedora-modular]
-name=Fedora Modular $releasever - $basearch
-metalink=https://mirrors.fedoraproject.org/metalink?repo=fedora-modular-$releasever&arch=$basearch
-# if you want to enable it, you should set best=0
-# see https://bugzilla.redhat.com/show_bug.cgi?id=1673851
-enabled=0
-repo_gpgcheck=0
-type=rpm
-gpgcheck=1
-gpgkey=file:///usr/share/distribution-gpg-keys/fedora/RPM-GPG-KEY-fedora-$releasever-primary
-skip_if_unavailable=False
-
-[fedora-modular-debuginfo]
-name=Fedora Modular $releasever - $basearch - Debug
-metalink=https://mirrors.fedoraproject.org/metalink?repo=fedora-modular-debug-$releasever&arch=$basearch
-enabled=0
-repo_gpgcheck=0
-type=rpm
-gpgcheck=1
-gpgkey=file:///usr/share/distribution-gpg-keys/fedora/RPM-GPG-KEY-fedora-$releasever-primary
-skip_if_unavailable=False
-
-[fedora-modular-source]
-name=Fedora Modular $releasever - Source
-metalink=https://mirrors.fedoraproject.org/metalink?repo=fedora-modular-source-$releasever&arch=$basearch
-enabled=0
-repo_gpgcheck=0
-type=rpm
-gpgcheck=1
-gpgkey=file:///usr/share/distribution-gpg-keys/fedora/RPM-GPG-KEY-fedora-$releasever-primary
-skip_if_unavailable=False
-
-[updates-modular]
-name=Fedora Modular $releasever - $basearch - Updates
-#baseurl=http://download.fedoraproject.org/pub/fedora/linux/updates/$releasever/Modular/$basearch/
-metalink=https://mirrors.fedoraproject.org/metalink?repo=updates-released-modular-f$releasever&arch=$basearch
-enabled=0
-repo_gpgcheck=0
-type=rpm
-gpgcheck=1
-gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-fedora-$releasever-$basearch
-skip_if_unavailable=False
-
-[updates-modular-debuginfo]
-name=Fedora Modular $releasever - $basearch - Updates - Debug
-#baseurl=http://download.fedoraproject.org/pub/fedora/linux/updates/$releasever/Modular/$basearch/debug/
-metalink=https://mirrors.fedoraproject.org/metalink?repo=updates-released-modular-debug-f$releasever&arch=$basearch
-enabled=0
-repo_gpgcheck=0
-type=rpm
-gpgcheck=1
-gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-fedora-$releasever-$basearch
-skip_if_unavailable=False
-
-[updates-modular-source]
-name=Fedora Modular $releasever - Updates Source
-#baseurl=http://download.fedoraproject.org/pub/fedora/linux/updates/$releasever/Modular/SRPMS/
-metalink=https://mirrors.fedoraproject.org/metalink?repo=updates-released-modular-source-f$releasever&arch=$basearch
-enabled=0
-repo_gpgcheck=0
-type=rpm
-gpgcheck=1
-gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-fedora-$releasever-$basearch
-skip_if_unavailable=False
-{% endif %}
-"""
-
-
-config_opts['dnf.conf'] = dnf_conf
-config_opts['dnf5.conf'] = dnf_conf
diff --git a/anda/terra/mock-configs/update.rhai b/anda/terra/mock-configs/update.rhai
new file mode 100644
index 0000000000..2bcb94eb78
--- /dev/null
+++ b/anda/terra/mock-configs/update.rhai
@@ -0,0 +1 @@
+rpm.version(gh("terrapkg/mock-configs"));
diff --git a/anda/terra/release/terra-release.spec b/anda/terra/release/terra-release.spec
index ddbddd6f12..599730e79d 100644
--- a/anda/terra/release/terra-release.spec
+++ b/anda/terra/release/terra-release.spec
@@ -1,6 +1,6 @@
Name: terra-release
-Version: 40
-Release: 3
+Version: 41
+Release: 2
Summary: Release package for Terra
License: MIT
@@ -24,6 +24,9 @@ install -D -p -m 0644 -t %{buildroot}%{_sysconfdir}/yum.repos.d %{SOURCE0}
%config(noreplace) %{_sysconfdir}/yum.repos.d/terra.repo
%changelog
+* Thu Nov 16 2023 Lleyton Gray - 41-1
+- Update for Terra 41 (in this case rawhide)
+
* Thu Nov 16 2023 Lleyton Gray - 40-1
- Update for Terra 40 (in this case rawhide)
diff --git a/anda/terra/release/terra.repo b/anda/terra/release/terra.repo
index c1f4d3eccd..084f8e4b06 100644
--- a/anda/terra/release/terra.repo
+++ b/anda/terra/release/terra.repo
@@ -9,6 +9,7 @@ gpgkey=https://repos.fyralabs.com/terra$releasever/key.asc
repo_gpgcheck=1
enabled=1
enabled_metadata=1
+countme=1
[terra-source]
name=Terra $releasever - Source
diff --git a/anda/themes/tau-helium/tau-helium.spec b/anda/themes/tau-helium/tau-helium.spec
index d3b193c8de..9f5f34258c 100644
--- a/anda/themes/tau-helium/tau-helium.spec
+++ b/anda/themes/tau-helium/tau-helium.spec
@@ -1,4 +1,4 @@
-%global ver 1.8.10-11
+%global ver 1.8.12-10
Summary: tauOS GTK/GNOME Shell Themes
Name: tau-helium
diff --git a/anda/tools/buildsys/anda/rust-anda.spec b/anda/tools/buildsys/anda/rust-anda.spec
index 38ab338d32..c838281859 100644
--- a/anda/tools/buildsys/anda/rust-anda.spec
+++ b/anda/tools/buildsys/anda/rust-anda.spec
@@ -5,7 +5,7 @@
%global crate anda
Name: rust-anda
-Version: 0.2.0
+Version: 0.2.2
Release: 1%?dist
Summary: Andaman Build toolchain
@@ -17,7 +17,7 @@ ExclusiveArch: %{rust_arches}
BuildRequires: rust-packaging >= 21
BuildRequires: anda-srpm-macros
-BuildRequires: openssl-devel
+BuildRequires: openssl-devel-engine
BuildRequires: git-core
BuildRequires: libgit2-devel
BuildRequires: libssh2-devel
diff --git a/anda/tools/electron/electron.spec b/anda/tools/electron/electron.spec
index 31202e3967..06721a0599 100644
--- a/anda/tools/electron/electron.spec
+++ b/anda/tools/electron/electron.spec
@@ -12,7 +12,7 @@
%global __provides_exclude_from %{_libdir}/%{name}/.*\\.so
Name: electron
-Version: 31.2.0
+Version: 31.2.1
Release: 1%?dist
Summary: Build cross platform desktop apps with web technologies
License: MIT
diff --git a/anda/tools/yt-dlp/yt-dlp-nightly.spec b/anda/tools/yt-dlp/yt-dlp-nightly.spec
index 6d985eda87..5a52cfa364 100644
--- a/anda/tools/yt-dlp/yt-dlp-nightly.spec
+++ b/anda/tools/yt-dlp/yt-dlp-nightly.spec
@@ -1,8 +1,8 @@
#bcond_without tests
-%global commit 4cd41469243624d90b7a2009b95cbe0609343efe
+%global commit a3bab4752a2b3d56e5a59b4e0411bb8f695c010b
%global shortcommit %(c=%{commit}; echo ${c:0:7})
-%global commit_date 20240714
-%global ver 2024.07.09
+%global commit_date 20240719
+%global ver 2024.07.16
Name: yt-dlp-nightly
Version: %ver^%commit_date.%shortcommit