Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -323,6 +323,7 @@ Heroic would not be possible without the work done in many other projects:
- Nile: https://github.com/imLinguin/nile
- Comet: https://github.com/imLinguin/comet
- GE-Proton: https://github.com/GloriousEggroll/proton-ge-custom
- Proton-cachyos: https://github.com/CachyOS/proton-cachyos
- umu-launcher: https://github.com/Open-Wine-Components/umu-launcher
- DXVK: https://github.com/doitsujin/dxvk
- VKD3D: https://github.com/HansKristian-Work/vkd3d-proton
Expand All @@ -332,6 +333,6 @@ Heroic would not be possible without the work done in many other projects:
- DXVK-MacOS: https://github.com/Gcenx/DXVK-macOS
- DXMT: https://github.com/3Shain/dxmt
- Heroic-Epic integration exe: https://github.com/Etaash-mathamsetty/heroic-epic-integration
- vulkan helper: https://github.com/imLinguin/vulkan-helper-rs
- vulkan helper: https://github.com/imLinguin/vulkan-helper-rs1

So be sure to follow and support those projects too!
1 change: 1 addition & 0 deletions public/locales/en/translation.json
Original file line number Diff line number Diff line change
Expand Up @@ -1023,6 +1023,7 @@
"size": "Size"
},
"wineExplanation": {
"proton-cachyos": "Proton-cachyos is a Proton variant maintaned by the CachyOS team. It includes extra tools like DXVK-Sarek and D7VK.",
"proton-ge": "GE-Proton is a Proton variant created by Glorious Eggroll. It is meant to be used along with the umu launcher (default in Heroic).",
"wine-ge": "Wine-GE-Proton is a Wine variant created by Glorious Eggroll. It has been deprecated in favor of GE-Proton with the umu launcher."
},
Expand Down
4 changes: 2 additions & 2 deletions src/backend/tools/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -815,7 +815,7 @@ function getDxvkUrl(): string {
}
if (any_gpu_supports_version([1, 1, 0])) {
logInfo(
'The GPU(s) in this system only support Vulkan 1.1/1.2, falling back to DXVK 1.10.3',
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This route shouldnt be called when using Proton. What's the intention here?
Do we want a separate feature for enabling this automatically for Proton CachyOS?

Copy link
Copy Markdown
Collaborator Author

@arielj arielj Apr 7, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We are calling DXVK.getLatest() when heroic opens (and it calls this internally), independent of what we have configured for a game, this prints in the general logs information for the user to know they have a GPU that does not support Vulkan 1.3+.

Then if they see that in the logs they know they have to use proton-cachyos instead of ge-proton.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is also called when running a game with wine I think when it installs DXVK, but I'm adding this information for that use case of the DXVK update when heroic is started

Copy link
Copy Markdown
Collaborator Author

@arielj arielj Apr 7, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I do think we should have something automated in another PR, yes, and make this more visible for the user, I opened an issue here #5425

We could even use this information to default to proton-cachyos with the dxvk-sarek env variable instead of ge-proton if the gpu does not support vulkan 1.3+, but I think all that would be a different feature (would mean moving this check somewhere more global to check once and reuse in other places and also the frontend)

'The GPU(s) in this system only support Vulkan 1.1/1.2, falling back to DXVK 1.10.3 for Wine, or use DXVK-Sarek with proton-cachyos',
LogPrefix.ToolInstaller
)
return 'https://api.github.com/repos/doitsujin/dxvk/releases/tags/v1.10.3'
Expand Down Expand Up @@ -851,7 +851,7 @@ function getVkd3dUrl(): string {
}
if (any_gpu_supports_version([1, 1, 0])) {
logInfo(
'The GPU(s) in this system only support Vulkan 1.1/1.2, falling back to VKD3D 2.6',
'The GPU(s) in this system only support Vulkan 1.1/1.2, falling back to VKD3D 2.6 for Wine, or use DXVK-Sarek with proton-cachyos',
LogPrefix.ToolInstaller
)
return 'https://api.github.com/repos/Heroic-Games-Launcher/vkd3d-proton/releases/tags/v2.6'
Expand Down
4 changes: 4 additions & 0 deletions src/backend/wine/manager/downloader/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,3 +25,7 @@ export const WINESTAGINGMACOS_URL =
/// Url to Game Porting Toolkit from Gcenx github release page
export const GPTK_URL =
'https://api.github.com/repos/Gcenx/game-porting-toolkit/releases'

/// Url to proton-cachyos from the CachyOS team github release page
export const PROTON_CACHYOS_URL =
'https://api.github.com/repos/CachyOS/proton-cachyos/releases'
17 changes: 16 additions & 1 deletion src/backend/wine/manager/downloader/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,8 @@ import {
WINELUTRIS_URL,
WINECROSSOVER_URL,
WINESTAGINGMACOS_URL,
GPTK_URL
GPTK_URL,
PROTON_CACHYOS_URL
} from './constants'
import { VersionInfo, Repositorys, WineVersionInfo } from 'common/types'
import {
Expand Down Expand Up @@ -150,6 +151,20 @@ async function getAvailableVersions({
})
break
}
case Repositorys.PROTONCACHYOS: {
await fetchReleases({
url: PROTON_CACHYOS_URL,
type: 'Proton-Cachyos',
count: count
})
.then((fetchedReleases: VersionInfo[]) => {
releases.push(...fetchedReleases)
})
.catch((error: Error) => {
logError(error, LogPrefix.WineDownloader)
})
break
}
default: {
logWarning(
`Unknown and not supported repository key passed! Skip fetch for ${repo}`,
Expand Down
49 changes: 39 additions & 10 deletions src/backend/wine/manager/downloader/utilities.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,19 @@ function getVersionName(type: string, tag_name: string): string {
}
}

interface ReleasesData {
data: {
tag_name: string
published_at: string
html_url: string
assets: {
name: string
browser_download_url: string
size: number
}[]
}[]
}

/**
* Helper to fetch releases from given url.
*
Expand All @@ -37,7 +50,7 @@ async function fetchReleases({
return new Promise((resolve, reject) => {
axiosClient
.get(url + '?per_page=' + count)
.then((data) => {
.then((data: ReleasesData) => {
for (const release of data.data) {
const release_data = {} as VersionInfo
release_data.version = getVersionName(type, release.tag_name)
Expand All @@ -46,15 +59,31 @@ async function fetchReleases({
release_data.disksize = 0
release_data.release_notes_link = release.html_url

for (const asset of release.assets) {
if (asset.name.endsWith('sha512sum')) {
release_data.checksum = asset.browser_download_url
} else if (
asset.name.endsWith('tar.gz') ||
asset.name.endsWith('tar.xz')
) {
release_data.download = asset.browser_download_url
release_data.downsize = asset.size
// for proton-cachyos we want to always get the main x86 asset,
// the other logic sometimes gets the V3, V4 or arm asset incorrectly
Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

proton-cachyos releases has many assets (arm and different x86 versions). The recommendation is to not use the V3/V4 assets since they may be less stable, we have to ensure we install the stable asset for x86

if (type === 'Proton-Cachyos') {
const shaAsset = release.assets.find((asset) =>
asset.browser_download_url.endsWith('x86_64.sha512sum')
)
if (shaAsset) release_data.checksum = shaAsset.browser_download_url
const tarAsset = release.assets.find((asset) =>
asset.browser_download_url.endsWith('x86_64.tar.xz')
)
if (tarAsset) {
release_data.download = tarAsset.browser_download_url
release_data.downsize = tarAsset.size
}
} else {
for (const asset of release.assets) {
if (asset.name.endsWith('sha512sum')) {
release_data.checksum = asset.browser_download_url
} else if (
asset.name.endsWith('tar.gz') ||
asset.name.endsWith('tar.xz')
) {
release_data.download = asset.browser_download_url
release_data.downsize = asset.size
}
}
}

Expand Down
13 changes: 12 additions & 1 deletion src/backend/wine/manager/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,9 @@ function getLatestLocalVersions(): Record<string, string | undefined> {
?.date,
latestGEProton: localWines.find(
(wine) => wine.version === 'GE-Proton-latest'
)?.date,
latestProtonCachyos: localWines.find(
(wine) => wine.version === 'Proton-Cachyos-latest'
)?.date
}
}
Expand Down Expand Up @@ -104,6 +107,14 @@ export function updateWineListsIfOutdated(releasesData: ReleasesInfo) {
)
)
repositoriesToFetch.push(Repositorys.WINEGE)

if (
localVersionIsOlder(
latestLocalVersions.latestProtonCachyos,
releasesData['proton-cachyos']
)
)
repositoriesToFetch.push(Repositorys.PROTONCACHYOS)
}

if (isMac) {
Expand Down Expand Up @@ -155,7 +166,7 @@ async function updateWineVersionInfos(
Repositorys.WINESTAGINGMACOS,
Repositorys.GPTK
]
: [Repositorys.WINEGE, Repositorys.PROTONGE]
: [Repositorys.WINEGE, Repositorys.PROTONGE, Repositorys.PROTONCACHYOS]
}

await getAvailableVersions({
Expand Down
5 changes: 4 additions & 1 deletion src/common/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -744,6 +744,7 @@ export type Type =
| 'Wine-Crossover'
| 'Wine-Staging-macOS'
| 'Game-Porting-Toolkit'
| 'Proton-Cachyos'

/**
* Interface contains information about a version
Expand Down Expand Up @@ -775,7 +776,8 @@ export enum Repositorys {
WINELUTRIS,
WINECROSSOVER,
WINESTAGINGMACOS,
GPTK
GPTK,
PROTONCACHYOS
}

export type WineManagerStatus =
Expand Down Expand Up @@ -848,6 +850,7 @@ export type ReleasesInfo = Record<
| 'ge-proton'
| 'wine-ge'
| 'game-porting-toolkit'
| 'proton-cachyos'
| 'wine-staging'
| 'wine-crossover'
| 'dxvk'
Expand Down
37 changes: 15 additions & 22 deletions src/frontend/screens/WineManager/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,7 @@ import { UpdateComponent } from 'frontend/components/UI'
import React, { lazy, useContext, useEffect, useMemo, useState } from 'react'
import { useTranslation } from 'react-i18next'
import { Tab, Tabs } from '@mui/material'
import {
TypeCheckedStoreFrontend,
wineDownloaderInfoStore
} from 'frontend/helpers/electronStores'
import { wineDownloaderInfoStore } from 'frontend/helpers/electronStores'
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'
import {
faCheck,
Expand All @@ -25,10 +22,6 @@ const WineItem = lazy(
async () => import('frontend/screens/WineManager/components/WineItem')
)

const configStore = new TypeCheckedStoreFrontend('wineManagerConfigStore', {
cwd: 'store'
})
Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I had to remove the use of this electron store because there's no way to update its stored value and it ignores new repositories added.

I understand this was saved in a store to not have to loop through the other OS repositories when rendering the tabs? but it's not really helping


export default function WineManager(): JSX.Element | null {
const { t } = useTranslation()

Expand Down Expand Up @@ -87,15 +80,14 @@ export default function WineManager(): JSX.Element | null {
getDefaultRepository()
)

const [wineManagerSettings, setWineManagerSettings] = useState<
WineManagerUISettings[]
>([
const wineManagerSettings: WineManagerUISettings[] = [
protonge,
{ type: 'Proton-Cachyos', value: 'protoncachyos', enabled: isLinux },
{ type: 'Wine-GE', value: 'winege', enabled: isLinux },
gamePortingToolkit,
wineCrossover,
wineStagingMacOS
])
]

const getWineVersions = (repo: Type) => {
let versions = wineDownloaderInfoStore.get('wine-releases', [])
Expand All @@ -120,15 +112,6 @@ export default function WineManager(): JSX.Element | null {
setWineVersions(getWineVersions(repo.type))
}

useEffect(() => {
const oldWineManagerSettings = configStore.get_nodefault(
'wine-manager-settings'
)
if (oldWineManagerSettings) {
setWineManagerSettings(oldWineManagerSettings)
}
}, [])

useEffect(() => {
const removeListener = window.api.handleWineVersionsUpdated(() => {
setWineVersions(getWineVersions(repository.type))
Expand Down Expand Up @@ -160,10 +143,20 @@ export default function WineManager(): JSX.Element | null {
)}
</div>
)
case 'Proton-Cachyos':
return (
<div className="infoBox">
<FontAwesomeIcon icon={faCheck} color={'green'} />
{t(
'wineExplanation.proton-cachyos',
'Proton-cachyos is a Proton variant maintaned by the CachyOS team. It includes extra tools like DXVK-Sarek and D7VK.'
)}
</div>
)
default:
return <></>
}
}, [repository])
}, [repository, t])

return (
<>
Expand Down
Loading