mirror of
https://gitlab.com/ArkHost/HelixNotes.git
synced 2026-07-24 07:45:57 +02:00
Fix unreliable window resize on Linux with custom resize handles (#77)
This commit is contained in:
@@ -1,5 +1,10 @@
|
|||||||
node_modules
|
node_modules
|
||||||
|
|
||||||
|
# Foreign lockfiles - this project uses pnpm (pnpm-lock.yaml is the only lockfile)
|
||||||
|
package-lock.json
|
||||||
|
yarn.lock
|
||||||
|
bun.lockb
|
||||||
|
|
||||||
# Output
|
# Output
|
||||||
.output
|
.output
|
||||||
.vercel
|
.vercel
|
||||||
|
|||||||
@@ -7,6 +7,7 @@
|
|||||||
"core:default",
|
"core:default",
|
||||||
"core:window:default",
|
"core:window:default",
|
||||||
"core:window:allow-start-dragging",
|
"core:window:allow-start-dragging",
|
||||||
|
"core:window:allow-start-resize-dragging",
|
||||||
"core:window:allow-minimize",
|
"core:window:allow-minimize",
|
||||||
"core:window:allow-toggle-maximize",
|
"core:window:allow-toggle-maximize",
|
||||||
"core:window:allow-close",
|
"core:window:allow-close",
|
||||||
|
|||||||
@@ -6075,6 +6075,12 @@
|
|||||||
position: relative;
|
position: relative;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Inset the scrollbar off the window's right edge so the window resize handle
|
||||||
|
(ResizeHandles in +layout) has clean space and doesn't swallow the scrollbar. */
|
||||||
|
.editor-container:not(.mobile) .editor-body {
|
||||||
|
margin-right: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
.editor-body::-webkit-scrollbar {
|
.editor-body::-webkit-scrollbar {
|
||||||
width: 8px;
|
width: 8px;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,69 @@
|
|||||||
|
<script lang="ts">
|
||||||
|
import { onMount } from 'svelte';
|
||||||
|
import { getCurrentWindow } from '@tauri-apps/api/window';
|
||||||
|
import { isMobile } from '$lib/platform';
|
||||||
|
|
||||||
|
type Dir =
|
||||||
|
| 'North' | 'South' | 'East' | 'West'
|
||||||
|
| 'NorthEast' | 'NorthWest' | 'SouthEast' | 'SouthWest';
|
||||||
|
|
||||||
|
// Resolved only on the client (onMount), so SSR/prerender never calls Tauri APIs.
|
||||||
|
let appWindow = $state<ReturnType<typeof getCurrentWindow> | null>(null);
|
||||||
|
let maximized = $state(false);
|
||||||
|
|
||||||
|
onMount(() => {
|
||||||
|
if (isMobile) return;
|
||||||
|
const win = getCurrentWindow();
|
||||||
|
appWindow = win;
|
||||||
|
const refresh = () => win.isMaximized().then((m) => (maximized = m)).catch(() => {});
|
||||||
|
refresh();
|
||||||
|
const unlisten = win.onResized(() => refresh());
|
||||||
|
return () => { unlisten.then((fn) => fn()); };
|
||||||
|
});
|
||||||
|
|
||||||
|
function start(e: MouseEvent, dir: Dir) {
|
||||||
|
if (e.button !== 0 || !appWindow) return;
|
||||||
|
e.preventDefault();
|
||||||
|
appWindow.startResizeDragging(dir);
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
{#if appWindow && !maximized}
|
||||||
|
<div class="resize-layer" aria-hidden="true">
|
||||||
|
<div class="rz rz-n" onmousedown={(e) => start(e, 'North')}></div>
|
||||||
|
<div class="rz rz-s" onmousedown={(e) => start(e, 'South')}></div>
|
||||||
|
<div class="rz rz-w" onmousedown={(e) => start(e, 'West')}></div>
|
||||||
|
<div class="rz rz-e" onmousedown={(e) => start(e, 'East')}></div>
|
||||||
|
<div class="rz rz-nw" onmousedown={(e) => start(e, 'NorthWest')}></div>
|
||||||
|
<div class="rz rz-ne" onmousedown={(e) => start(e, 'NorthEast')}></div>
|
||||||
|
<div class="rz rz-sw" onmousedown={(e) => start(e, 'SouthWest')}></div>
|
||||||
|
<div class="rz rz-se" onmousedown={(e) => start(e, 'SouthEast')}></div>
|
||||||
|
</div>
|
||||||
|
{/if}
|
||||||
|
|
||||||
|
<style>
|
||||||
|
/* Transparent overlay; only the strips capture events, the rest passes through. */
|
||||||
|
.resize-layer {
|
||||||
|
position: fixed;
|
||||||
|
inset: 0;
|
||||||
|
pointer-events: none;
|
||||||
|
z-index: 99999;
|
||||||
|
}
|
||||||
|
|
||||||
|
.rz {
|
||||||
|
position: fixed;
|
||||||
|
pointer-events: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Edges, inset by the corner size so corners win at the corners. */
|
||||||
|
.rz-n { top: 0; left: 14px; right: 14px; height: 6px; cursor: ns-resize; }
|
||||||
|
.rz-s { bottom: 0; left: 14px; right: 14px; height: 6px; cursor: ns-resize; }
|
||||||
|
.rz-w { left: 0; top: 14px; bottom: 14px; width: 6px; cursor: ew-resize; }
|
||||||
|
.rz-e { right: 0; top: 14px; bottom: 14px; width: 6px; cursor: ew-resize; }
|
||||||
|
|
||||||
|
/* Corners: larger, reliable grab targets. */
|
||||||
|
.rz-nw { top: 0; left: 0; width: 14px; height: 14px; cursor: nwse-resize; }
|
||||||
|
.rz-ne { top: 0; right: 0; width: 14px; height: 14px; cursor: nesw-resize; }
|
||||||
|
.rz-sw { bottom: 0; left: 0; width: 14px; height: 14px; cursor: nesw-resize; }
|
||||||
|
.rz-se { bottom: 0; right: 0; width: 14px; height: 14px; cursor: nwse-resize; }
|
||||||
|
</style>
|
||||||
@@ -4,6 +4,7 @@
|
|||||||
import { theme, appConfig, activeNote, activeNotePath, installType, checkForUpdate, checkForUpdateMobile } from '$lib/stores/app';
|
import { theme, appConfig, activeNote, activeNotePath, installType, checkForUpdate, checkForUpdateMobile } from '$lib/stores/app';
|
||||||
import { openFile, openUrl, readNote, getInstallType } from '$lib/api';
|
import { openFile, openUrl, readNote, getInstallType } from '$lib/api';
|
||||||
import { get } from 'svelte/store';
|
import { get } from 'svelte/store';
|
||||||
|
import ResizeHandles from '$lib/components/ResizeHandles.svelte';
|
||||||
|
|
||||||
let { children } = $props();
|
let { children } = $props();
|
||||||
|
|
||||||
@@ -194,3 +195,5 @@
|
|||||||
</svelte:head>
|
</svelte:head>
|
||||||
|
|
||||||
{@render children()}
|
{@render children()}
|
||||||
|
|
||||||
|
<ResizeHandles />
|
||||||
|
|||||||
Reference in New Issue
Block a user