Allow enabling or disabling custom decorations on windows

This commit is contained in:
Lncvrt committed 2026-09-27 18:46:00 -07:00
1 parent 84e45bf408
commit 11d695d50a
9 files changed
+139 -68

No files matched your search

+15 -8
View File
@@ -674,6 +674,19 @@ fn remove_stale_executable(app: AppHandle, version: String, executable: String)
} }
} }
#[allow(unused)]
#[tauri::command]
fn enable_custom_decorations_windows(app: AppHandle) {
#[cfg(target_os = "windows")]
{
use tauri_plugin_decorum::WebviewWindowExt;
let window = app.get_webview_window("main").unwrap();
window.set_decorations(false);
let _ = window.create_overlay_titlebar();
}
}
#[cfg_attr(mobile, tauri::mobile_entry_point)] #[cfg_attr(mobile, tauri::mobile_entry_point)]
pub fn run() { pub fn run() {
#[allow(unused)] #[allow(unused)]
@@ -714,7 +727,8 @@ pub fn run() {
cancel_download, cancel_download,
move_game_data, move_game_data,
open_game_folder, open_game_folder,
remove_stale_executable remove_stale_executable,
enable_custom_decorations_windows
]) ])
.setup(|app| { .setup(|app| {
let custom_dir = app let custom_dir = app
@@ -745,13 +759,6 @@ pub fn run() {
} }
}); });
#[cfg(target_os = "windows")]
{
use tauri_plugin_decorum::WebviewWindowExt;
if let Err(e) = window.create_overlay_titlebar() {
eprintln!("Failed to create overlay titlebar: {:?}", e);
}
}
#[cfg(not(debug_assertions))] #[cfg(not(debug_assertions))]
{ {
use tauri_plugin_cli::CliExt; use tauri_plugin_cli::CliExt;
+1 -3
View File
@@ -18,9 +18,7 @@
"width": 1000, "width": 1000,
"height": 532, "height": 532,
"minWidth": 1000, "minWidth": 1000,
"minHeight": 532, "minHeight": 532
"decorations": false,
"shadow": true
} }
], ],
"security": { "security": {
+2 -1
View File
@@ -30,6 +30,7 @@ export default function GamePage () {
needsRevisionUpdate, needsRevisionUpdate,
launchGame, launchGame,
developerMode, developerMode,
useNativeDecorations,
theme, theme,
accountSession, accountSession,
accountId, accountId,
@@ -187,7 +188,7 @@ export default function GamePage () {
</div> </div>
<div <div
className={`main-container main-flex ${ className={`main-container main-flex ${
platform() == 'windows' platform() == 'windows' && !useNativeDecorations
? 'h-[calc(100vh-116px)]' ? 'h-[calc(100vh-116px)]'
: 'h-[calc(100vh-84px)]' : 'h-[calc(100vh-84px)]'
}`} }`}
+14 -1
View File
@@ -93,6 +93,8 @@ export default function RootLayout ({
const [theme, setTheme] = useState<string>('dark') const [theme, setTheme] = useState<string>('dark')
const [customDataLocation, setCustomDataLocation] = useState<string>('') const [customDataLocation, setCustomDataLocation] = useState<string>('')
const [developerMode, setDeveloperMode] = useState<boolean>(false) const [developerMode, setDeveloperMode] = useState<boolean>(false)
const [useNativeDecorations, setUseNativeDecorations] =
useState<boolean>(false)
const [versionsList, setVersionsList] = useState<Record<string, number>>({}) const [versionsList, setVersionsList] = useState<Record<string, number>>({})
const [modsList, setModsList] = useState< const [modsList, setModsList] = useState<
@@ -765,6 +767,13 @@ export default function RootLayout ({
await requestPermission() await requestPermission()
} }
if (
platform() == 'windows' &&
!(settingsLocal.get<boolean>('useNativeDecorations') ?? false)
) {
invoke('enable_custom_decorations_windows')
}
setLoading(false) setLoading(false)
})() })()
}, []) }, [])
@@ -839,6 +848,9 @@ export default function RootLayout ({
setCustomDataLocation(v ?? '') setCustomDataLocation(v ?? '')
) )
watchSettings<boolean>('developerMode', v => setDeveloperMode(v ?? false)) watchSettings<boolean>('developerMode', v => setDeveloperMode(v ?? false))
watchSettings<boolean>('useNativeDecorations', v =>
setUseNativeDecorations(v ?? false)
)
watchVersions<Record<string, number>>('list', v => setVersionsList(v ?? {})) watchVersions<Record<string, number>>('list', v => setVersionsList(v ?? {}))
watchVersions<Record<string, Record<string, number>>>('mods', v => watchVersions<Record<string, Record<string, number>>>('mods', v =>
@@ -902,6 +914,7 @@ export default function RootLayout ({
theme, theme,
customDataLocation, customDataLocation,
developerMode, developerMode,
useNativeDecorations,
versionsList, versionsList,
modsList, modsList,
launchesList, launchesList,
@@ -923,7 +936,7 @@ export default function RootLayout ({
}} }}
> >
<Sidebar /> <Sidebar />
{platformName == 'windows' && ( {platformName == 'windows' && !useNativeDecorations && (
<div className='relative z-2 ml-59.75 w-[calc(100vw-239px)] border-b border-b-(--col3) h-8.25 bg-(--col1)' /> <div className='relative z-2 ml-59.75 w-[calc(100vw-239px)] border-b border-b-(--col3) h-8.25 bg-(--col1)' />
)} )}
<div className='relative z-0'> <div className='relative z-0'>
+3 -2
View File
@@ -23,7 +23,8 @@ export default function LibraryPage () {
setSelectedGame, setSelectedGame,
setCategory, setCategory,
setManagingGame, setManagingGame,
developerMode developerMode,
useNativeDecorations
} = useGlobal() } = useGlobal()
const router = useRouter() const router = useRouter()
@@ -59,7 +60,7 @@ export default function LibraryPage () {
</div> </div>
<div <div
className={`main-container main-flex ${ className={`main-container main-flex ${
platform() == 'windows' platform() == 'windows' && !useNativeDecorations
? 'h-[calc(100vh-116px)]' ? 'h-[calc(100vh-116px)]'
: 'h-[calc(100vh-84px)]' : 'h-[calc(100vh-84px)]'
}`} }`}
+72 -20
View File
@@ -4,7 +4,7 @@ import { Setting } from '@/components/Setting'
import { useGlobal } from '@/providers/GlobalProvider' import { useGlobal } from '@/providers/GlobalProvider'
import { copyToClipboard } from '@/lib/clipboard' import { copyToClipboard } from '@/lib/clipboard'
import { platform } from '@tauri-apps/plugin-os' import { platform } from '@tauri-apps/plugin-os'
import { confirm, message, open } from '@tauri-apps/plugin-dialog' import { ask, confirm, message, open } from '@tauri-apps/plugin-dialog'
import { invoke } from '@tauri-apps/api/core' import { invoke } from '@tauri-apps/api/core'
import Dropdown from '@/components/Dropdown' import Dropdown from '@/components/Dropdown'
import { WebviewWindow } from '@tauri-apps/api/webviewWindow' import { WebviewWindow } from '@tauri-apps/api/webviewWindow'
@@ -12,7 +12,7 @@ import { exit, relaunch } from '@tauri-apps/plugin-process'
import { BaseDirectory, exists, readDir, remove } from '@tauri-apps/plugin-fs' import { BaseDirectory, exists, readDir, remove } from '@tauri-apps/plugin-fs'
import { openPath } from '@tauri-apps/plugin-opener' import { openPath } from '@tauri-apps/plugin-opener'
import { appLocalDataDir } from '@tauri-apps/api/path' import { appLocalDataDir } from '@tauri-apps/api/path'
import { getCurrentWindow } from '@tauri-apps/api/window' import { getCurrentWindow, LogicalSize } from '@tauri-apps/api/window'
export default function SettingsPage () { export default function SettingsPage () {
const { const {
@@ -24,6 +24,7 @@ export default function SettingsPage () {
linuxUseWine, linuxUseWine,
linuxWineCommand, linuxWineCommand,
theme, theme,
useNativeDecorations,
customDataLocation, customDataLocation,
downloadProgress downloadProgress
} = useGlobal() } = useGlobal()
@@ -33,25 +34,76 @@ export default function SettingsPage () {
<p className='text-3xl ml-4 mt-4'>Settings</p> <p className='text-3xl ml-4 mt-4'>Settings</p>
<div className='flex flex-row p-4 gap-4'> <div className='flex flex-row p-4 gap-4'>
<div className='bg-(--col1) border border-(--col3) rounded-lg p-4 w-fit h-fit'> <div className='bg-(--col1) border border-(--col3) rounded-lg p-4 w-fit h-fit'>
<Setting {platform() == 'linux' && (
label='Use wine if needed'
value={linuxUseWine}
onChange={async () => {
await settings?.set('linuxUseWine', !linuxUseWine)
}}
className={platform() == 'linux' ? '' : 'hidden'}
/>
{platform() == 'linux' && linuxUseWine && (
<> <>
<p>Wine Command:</p> <Setting
<input label='Use wine if needed'
type='text' value={linuxUseWine}
value={linuxWineCommand} onChange={async () => {
onChange={async e => await settings?.set('linuxUseWine', !linuxUseWine)
await settings?.set('linuxWineCommand', e.target.value) }}
} />
className='input-field my-1' {linuxUseWine && (
></input> <>
<p>Wine Command:</p>
<input
type='text'
value={linuxWineCommand}
onChange={async e =>
await settings?.set('linuxWineCommand', e.target.value)
}
className='input-field my-1'
></input>
</>
)}
</>
)}
{platform() == 'windows' && (
<>
<Setting
label='Use native window decorations'
value={useNativeDecorations}
onChange={async () => {
if (useNativeDecorations) {
invoke('enable_custom_decorations_windows')
const appWindow = getCurrentWindow()
const size = await appWindow.innerSize()
const newHeight = size.height - 32
await appWindow.setSize(
new LogicalSize(size.width, newHeight)
)
await settings?.set(
'useNativeDecorations',
!useNativeDecorations
)
} else {
if (
!(await ask(
'Turning this off will require a launcher restart. If you have active downloads, you may want to wait before doing this.',
'Are you sure?'
))
) {
return
}
const appWindow = getCurrentWindow()
appWindow.setDecorations(true)
const size = await appWindow.innerSize()
const newHeight = size.height + 32
await appWindow.setSize(
new LogicalSize(size.width, newHeight)
)
await settings?.set(
'useNativeDecorations',
!useNativeDecorations
)
await relaunch()
}
}}
/>
</> </>
)} )}
<Setting <Setting
+1 -8
View File
@@ -24,14 +24,7 @@ export default function RootLayout ({
<> <>
<html lang='en' className={roboto.className}> <html lang='en' className={roboto.className}>
<body className='dark-theme'> <body className='dark-theme'>
{platformName == 'windows' && ( <div className='w-screen h-screen flex items-center justify-center'>
<div className='relative z-2 w-screen border-b border-b-(--col3) h-8.25 bg-(--col1)' />
)}
<div
className={`w-screen ${
platformName == 'windows' ? 'h-[calc(100vh-64px)]' : 'h-screen'
} flex items-center justify-center`}
>
{children} {children}
</div> </div>
</body> </body>
+30 -25
View File
@@ -44,6 +44,7 @@ export default function Sidebar () {
setManagingGame, setManagingGame,
settings, settings,
developerMode, developerMode,
useNativeDecorations,
accountName, accountName,
accountAdmin, accountAdmin,
sidebarShowGames sidebarShowGames
@@ -71,32 +72,36 @@ export default function Sidebar () {
}} }}
/> />
)} )}
<div {!(platform() == 'windows' && useNativeDecorations) && (
className={ <div
'flex items-center h-10 w-60 ' + className={
(platform() == 'windows' ? 'pl-1 pt-1' : 'pl-2 pt-2') + 'flex items-center h-10 w-60 ' +
(platform() == 'macos' (platform() == 'windows' ? 'pl-1 pt-1' : 'pl-2 pt-2') +
? // ? Number(version().split('.')[0]) >= 26 (platform() == 'macos'
// ? ' mt-6' ? // ? Number(version().split('.')[0]) >= 26
' mt-5' // ? ' mt-6'
: '') ' mt-5'
} : '')
onMouseDown={async e => {
if (platform() != 'macos') return
if (e.buttons === 1) {
if (e.detail === 2) {
await getCurrentWindow().toggleMaximize()
} else {
await getCurrentWindow().startDragging()
}
} }
}} onMouseDown={async e => {
> if (platform() != 'macos') return
<Image draggable={false} src={Icon} width={36} height={36} alt='' /> if (e.buttons === 1) {
<p className={`ml-1 text-[16px] whitespace-nowrap ${lexend.className}`}> if (e.detail === 2) {
Lncvrt Games Launcher await getCurrentWindow().toggleMaximize()
</p> } else {
</div> await getCurrentWindow().startDragging()
}
}
}}
>
<Image draggable={false} src={Icon} width={36} height={36} alt='' />
<p
className={`ml-1 text-[16px] whitespace-nowrap ${lexend.className}`}
>
Lncvrt Games Launcher
</p>
</div>
)}
<nav className='nav-links overflow-auto'> <nav className='nav-links overflow-auto'>
<Link <Link
draggable={false} draggable={false}
+1
View File
@@ -60,6 +60,7 @@ type GlobalCtxType = {
theme: string theme: string
customDataLocation: string customDataLocation: string
developerMode: boolean developerMode: boolean
useNativeDecorations: boolean
versionsList: Record<string, number> versionsList: Record<string, number>
modsList: Record<string, Record<string, number>> modsList: Record<string, Record<string, number>>
launchesList: Record<string, Record<string, number>> launchesList: Record<string, Record<string, number>>