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)]
pub fn run() {
#[allow(unused)]
@@ -714,7 +727,8 @@ pub fn run() {
cancel_download,
move_game_data,
open_game_folder,
remove_stale_executable
remove_stale_executable,
enable_custom_decorations_windows
])
.setup(|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))]
{
use tauri_plugin_cli::CliExt;
+1 -3
View File
@@ -18,9 +18,7 @@
"width": 1000,
"height": 532,
"minWidth": 1000,
"minHeight": 532,
"decorations": false,
"shadow": true
"minHeight": 532
}
],
"security": {
+2 -1
View File
@@ -30,6 +30,7 @@ export default function GamePage () {
needsRevisionUpdate,
launchGame,
developerMode,
useNativeDecorations,
theme,
accountSession,
accountId,
@@ -187,7 +188,7 @@ export default function GamePage () {
</div>
<div
className={`main-container main-flex ${
platform() == 'windows'
platform() == 'windows' && !useNativeDecorations
? 'h-[calc(100vh-116px)]'
: 'h-[calc(100vh-84px)]'
}`}
+14 -1
View File
@@ -93,6 +93,8 @@ export default function RootLayout ({
const [theme, setTheme] = useState<string>('dark')
const [customDataLocation, setCustomDataLocation] = useState<string>('')
const [developerMode, setDeveloperMode] = useState<boolean>(false)
const [useNativeDecorations, setUseNativeDecorations] =
useState<boolean>(false)
const [versionsList, setVersionsList] = useState<Record<string, number>>({})
const [modsList, setModsList] = useState<
@@ -765,6 +767,13 @@ export default function RootLayout ({
await requestPermission()
}
if (
platform() == 'windows' &&
!(settingsLocal.get<boolean>('useNativeDecorations') ?? false)
) {
invoke('enable_custom_decorations_windows')
}
setLoading(false)
})()
}, [])
@@ -839,6 +848,9 @@ export default function RootLayout ({
setCustomDataLocation(v ?? '')
)
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, Record<string, number>>>('mods', v =>
@@ -902,6 +914,7 @@ export default function RootLayout ({
theme,
customDataLocation,
developerMode,
useNativeDecorations,
versionsList,
modsList,
launchesList,
@@ -923,7 +936,7 @@ export default function RootLayout ({
}}
>
<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-0'>
+3 -2
View File
@@ -23,7 +23,8 @@ export default function LibraryPage () {
setSelectedGame,
setCategory,
setManagingGame,
developerMode
developerMode,
useNativeDecorations
} = useGlobal()
const router = useRouter()
@@ -59,7 +60,7 @@ export default function LibraryPage () {
</div>
<div
className={`main-container main-flex ${
platform() == 'windows'
platform() == 'windows' && !useNativeDecorations
? 'h-[calc(100vh-116px)]'
: 'h-[calc(100vh-84px)]'
}`}
+72 -20
View File
@@ -4,7 +4,7 @@ import { Setting } from '@/components/Setting'
import { useGlobal } from '@/providers/GlobalProvider'
import { copyToClipboard } from '@/lib/clipboard'
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 Dropdown from '@/components/Dropdown'
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 { openPath } from '@tauri-apps/plugin-opener'
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 () {
const {
@@ -24,6 +24,7 @@ export default function SettingsPage () {
linuxUseWine,
linuxWineCommand,
theme,
useNativeDecorations,
customDataLocation,
downloadProgress
} = useGlobal()
@@ -33,25 +34,76 @@ export default function SettingsPage () {
<p className='text-3xl ml-4 mt-4'>Settings</p>
<div className='flex flex-row p-4 gap-4'>
<div className='bg-(--col1) border border-(--col3) rounded-lg p-4 w-fit h-fit'>
<Setting
label='Use wine if needed'
value={linuxUseWine}
onChange={async () => {
await settings?.set('linuxUseWine', !linuxUseWine)
}}
className={platform() == 'linux' ? '' : 'hidden'}
/>
{platform() == 'linux' && linuxUseWine && (
{platform() == 'linux' && (
<>
<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>
<Setting
label='Use wine if needed'
value={linuxUseWine}
onChange={async () => {
await settings?.set('linuxUseWine', !linuxUseWine)
}}
/>
{linuxUseWine && (
<>
<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
+1 -8
View File
@@ -24,14 +24,7 @@ export default function RootLayout ({
<>
<html lang='en' className={roboto.className}>
<body className='dark-theme'>
{platformName == 'windows' && (
<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`}
>
<div className='w-screen h-screen flex items-center justify-center'>
{children}
</div>
</body>
+30 -25
View File
@@ -44,6 +44,7 @@ export default function Sidebar () {
setManagingGame,
settings,
developerMode,
useNativeDecorations,
accountName,
accountAdmin,
sidebarShowGames
@@ -71,32 +72,36 @@ export default function Sidebar () {
}}
/>
)}
<div
className={
'flex items-center h-10 w-60 ' +
(platform() == 'windows' ? 'pl-1 pt-1' : 'pl-2 pt-2') +
(platform() == 'macos'
? // ? Number(version().split('.')[0]) >= 26
// ? ' 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()
}
{!(platform() == 'windows' && useNativeDecorations) && (
<div
className={
'flex items-center h-10 w-60 ' +
(platform() == 'windows' ? 'pl-1 pt-1' : 'pl-2 pt-2') +
(platform() == 'macos'
? // ? Number(version().split('.')[0]) >= 26
// ? ' mt-6'
' mt-5'
: '')
}
}}
>
<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>
onMouseDown={async e => {
if (platform() != 'macos') return
if (e.buttons === 1) {
if (e.detail === 2) {
await getCurrentWindow().toggleMaximize()
} else {
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'>
<Link
draggable={false}
+1
View File
@@ -60,6 +60,7 @@ type GlobalCtxType = {
theme: string
customDataLocation: string
developerMode: boolean
useNativeDecorations: boolean
versionsList: Record<string, number>
modsList: Record<string, Record<string, number>>
launchesList: Record<string, Record<string, number>>