Introduce custom title bar

This commit is contained in:
onkofonko 2024-08-30 22:27:31 +02:00
parent 9cfdd02b91
commit 30578016b0
3 changed files with 181 additions and 35 deletions

View file

@ -1,42 +1,113 @@
<script> <script>
import { persisted } from 'svelte-persisted-store' import { persisted } from "svelte-persisted-store";
import { getContext } from 'svelte' import { getContext } from "svelte";
import { click } from '@/modules/click.js' import { click } from "@/modules/click.js";
import IPC from '@/modules/ipc.js' import IPC from "@/modules/ipc.js";
export let page export let page;
const view = getContext('view') const view = getContext("view");
function close () { function close() {
$view = null $view = null;
page = 'home' page = "home";
} }
const debug = persisted('debug', '', { const debug = persisted("debug", "", {
serializer: { serializer: {
parse: e => e, parse: (e) => e,
stringify: e => e stringify: (e) => e,
} },
}) });
function minimize() {
window.ipcRenderer.send("minimize");
}
function maximize() {
window.ipcRenderer.send("maximize");
}
function closeapp() {
window.ipcRenderer.send("closeapp");
}
</script> </script>
<div class='w-full z-101 navbar bg-transparent border-0 p-0 d-flex'> <div class="w-full z-101 navbar bg-transparent border-0 p-0 d-flex">
<div class='d-flex h-full draggable align-items-center text-center'> <div class="d-flex h-full draggable align-items-center text-center">
{#if window.version?.platform !== 'darwin'} {#if window.version?.platform !== "darwin"}
<img src='./logo_filled.png' class='position-absolute w-50 h-50 m-10 pointer d-md-block d-none p-5' alt='ico' use:click={close} /> <img
src="./logo_filled.png"
class="position-absolute w-50 h-50 m-10 pointer d-md-block d-none p-5"
alt="ico"
use:click={close}
/>
{/if} {/if}
</div> </div>
<div class='h-full bg-dark flex-grow-1'> <div id="window-controls">
{#if window.version?.platform === 'linux'} <button class="button" id="max-button" on:click={minimize}>
<div class='d-flex align-items-center close h-full' use:click={() => IPC.emit('close')}> <svg
<svg viewBox='0 0 24 24'> class="svg-controls"
<path d='M19 6.41 17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12 19 6.41z' /> role="img"
width="12"
height="12"
viewBox="0 0 12 12"
><rect fill="currentColor" width="10" height="1" x="1" y="6"
></rect></svg
></button
>
<button class="button" id="restore-button" on:click={maximize}
><svg
class="svg-controls"
role="img"
width="12"
height="12"
viewBox="0 0 12 12"
><rect
width="9"
height="9"
x="1.5"
y="1.5"
fill="none"
stroke="currentColor"
></rect></svg
></button
>
<button class="button" id="close-button" on:click={closeapp}>
<svg
class="svg-controls"
role="img"
width="12"
height="12"
viewBox="0 0 12 12"
>
<polygon
fill="currentColor"
fill-rule="evenodd"
points="11 1.576 6.583 6 11 10.424 10.424 11 6 6.583 1.576 11 1 10.424 5.417 6 1 1.576 1.576 1 6 5.417 10.424 1"
></polygon></svg
></button
>
</div>
<div class="h-full bg-dark flex-grow-1">
{#if window.version?.platform === "linux"}
<div
class="d-flex align-items-center close h-full"
use:click={() => IPC.emit("close")}
>
<svg viewBox="0 0 24 24">
<path
d="M19 6.41 17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12 19 6.41z"
/>
</svg> </svg>
</div> </div>
{/if} {/if}
</div> </div>
</div> </div>
{#if $debug} {#if $debug}
<div class='ribbon right z-101 text-center position-fixed font-size-16 font-weight-bold'>Debug Mode!</div> <div
class="ribbon right z-101 text-center position-fixed font-size-16 font-weight-bold"
>
Debug Mode!
</div>
{/if} {/if}
<style> <style>
@ -51,10 +122,10 @@
transform: translate(-29.3%) rotate(-45deg); transform: translate(-29.3%) rotate(-45deg);
} }
.navbar { .navbar {
--navbar-height: 28px !important; --navbar-height: 32px !important;
} }
.z-101 { .z-101 {
z-index: 101 !important z-index: 101 !important;
} }
.draggable { .draggable {
-webkit-app-region: drag; -webkit-app-region: drag;
@ -64,7 +135,7 @@
} }
img { img {
top: 0; top: 0;
-webkit-app-region: no-drag -webkit-app-region: no-drag;
} }
.close { .close {
width: 40px; width: 40px;
@ -81,7 +152,7 @@
fill: currentColor; fill: currentColor;
} }
.navbar { .navbar {
left: unset !important left: unset !important;
} }
@media (pointer: none), (pointer: coarse) { @media (pointer: none), (pointer: coarse) {
.navbar { .navbar {
@ -89,4 +160,52 @@
height: 0; height: 0;
} }
} }
#window-controls {
display: grid;
grid-template-columns: repeat(3, 46px);
position: absolute;
top: 0;
right: 0;
height: 100%;
}
#window-controls {
-webkit-app-region: no-drag;
}
#window-controls .button {
grid-row: 1 / span 1;
display: flex;
justify-content: center;
align-items: center;
width: 46px;
height: 32px;
background: transparent;
border: none;
color: #ffffff;
}
#window-controls .button {
user-select: none;
}
#window-controls .button:hover {
background: rgba(24, 24, 28, 0.2);
}
#window-controls .button:active {
background: rgba(24, 24, 28, 0.4);
}
#close-button:hover {
background: #e81123 !important;
}
#close-button:active {
background: #f1707a !important;
}
.svg-controls {
width: 12px;
height: 12px;
}
</style> </style>

View file

@ -29,11 +29,6 @@ export default class App {
height: 900, height: 900,
frame: process.platform === 'darwin', // Only keep the native frame on Mac frame: process.platform === 'darwin', // Only keep the native frame on Mac
titleBarStyle: 'hidden', titleBarStyle: 'hidden',
titleBarOverlay: {
color: '#17191c',
symbolColor: '#eee',
height: 28
},
backgroundColor: '#17191c', backgroundColor: '#17191c',
autoHideMenuBar: true, autoHideMenuBar: true,
webPreferences: { webPreferences: {
@ -41,7 +36,9 @@ export default class App {
allowRunningInsecureContent: false, allowRunningInsecureContent: false,
enableBlinkFeatures: 'FontAccess, AudioVideoTracks', enableBlinkFeatures: 'FontAccess, AudioVideoTracks',
backgroundThrottling: false, backgroundThrottling: false,
preload: join(__dirname, '/preload.js') preload: join(__dirname, '/preload.js'),
contextIsolation: true,
nodeIntegration: false
}, },
icon: join(__dirname, '/logo_filled.png'), icon: join(__dirname, '/logo_filled.png'),
show: false show: false
@ -159,3 +156,28 @@ export default class App {
if (!this.updater.install(forceRunAfter)) app.quit() if (!this.updater.install(forceRunAfter)) app.quit()
} }
} }
ipcMain.on('minimize', (event) => {
const focusedWindow = BrowserWindow.getFocusedWindow();
if (focusedWindow) {
focusedWindow.minimize();
}
});
ipcMain.on('maximize', (event) => {
const focusedWindow = BrowserWindow.getFocusedWindow();
if (focusedWindow) {
if (focusedWindow.isMaximized()) {
focusedWindow.unmaximize();
} else {
focusedWindow.maximize();
}
}
});
ipcMain.on('closeapp', (event) => {
const focusedWindow = BrowserWindow.getFocusedWindow();
if (focusedWindow) {
focusedWindow.close();
}
});

View file

@ -29,4 +29,9 @@ ipcRenderer.once('port', ({ ports }) => {
ports[0].postMessage(a, b) ports[0].postMessage(a, b)
} }
}) })
}) })
contextBridge.exposeInMainWorld('ipcRenderer', {
send: (channel, data) => ipcRenderer.send(channel, data),
on: (channel, callback) => ipcRenderer.on(channel, (event, ...args) => callback(...args)),
});