feat: add window resize handles on linux (#7319)

This commit is contained in:
sgt57
2026-07-04 03:16:08 +00:00
committed by GitHub
parent 4fa2f9a329
commit c4658cff88
4 changed files with 153 additions and 3 deletions
+1
View File
@@ -54,6 +54,7 @@
"core:window:allow-set-cursor-position",
"core:window:allow-set-ignore-cursor-events",
"core:window:allow-start-dragging",
"core:window:allow-start-resize-dragging",
"core:window:allow-maximize",
"core:window:allow-toggle-maximize",
"core:window:allow-unmaximize",
+86
View File
@@ -108,6 +108,92 @@
}
}
.window-resize-handles {
--resize-edge-size: 6px;
--resize-corner-size: 12px;
position: fixed;
inset: 0;
z-index: 10000;
pointer-events: none;
.window-resize-handle {
position: absolute;
pointer-events: auto;
touch-action: none;
&--north,
&--south {
right: var(--resize-corner-size);
left: var(--resize-corner-size);
height: var(--resize-edge-size);
cursor: ns-resize;
}
&--north {
top: 0;
}
&--south {
bottom: 0;
}
&--east,
&--west {
top: var(--resize-corner-size);
bottom: var(--resize-corner-size);
width: var(--resize-edge-size);
cursor: ew-resize;
}
&--east {
right: 0;
}
&--west {
left: 0;
}
&--north-east,
&--north-west,
&--south-east,
&--south-west {
width: var(--resize-corner-size);
height: var(--resize-corner-size);
}
&--north-east,
&--south-west {
cursor: nesw-resize;
}
&--north-west,
&--south-east {
cursor: nwse-resize;
}
&--north-east,
&--north-west {
top: 0;
}
&--south-east,
&--south-west {
bottom: 0;
}
&--north-east,
&--south-east {
right: 0;
}
&--north-west,
&--south-west {
left: 0;
}
}
}
.linux,
.windows,
.unknown {
+59 -1
View File
@@ -1,10 +1,68 @@
import { Close, CropSquare, FilterNone, Minimize } from '@mui/icons-material'
import { Box, IconButton } from '@mui/material'
import { forwardRef, useImperativeHandle } from 'react'
import {
forwardRef,
type PointerEvent,
useCallback,
useImperativeHandle,
} from 'react'
import { useWindowControls } from '@/hooks/use-window'
import getSystem from '@/utils/get-system'
const RESIZE_HANDLES = [
{ direction: 'North', position: 'north' },
{ direction: 'NorthEast', position: 'north-east' },
{ direction: 'East', position: 'east' },
{ direction: 'SouthEast', position: 'south-east' },
{ direction: 'South', position: 'south' },
{ direction: 'SouthWest', position: 'south-west' },
{ direction: 'West', position: 'west' },
{ direction: 'NorthWest', position: 'north-west' },
] as const
export const WindowResizeHandles = () => {
const { currentWindow, maximized } = useWindowControls()
const startResizeDragging = useCallback(
(event: PointerEvent<HTMLDivElement>) => {
if (event.button !== 0) return
event.preventDefault()
const direction = event.currentTarget.dataset.resizeDirection
const handle = RESIZE_HANDLES.find((item) => item.direction === direction)
if (handle) {
void currentWindow
.startResizeDragging(handle.direction)
.catch((error) =>
console.warn('[WindowResizeHandles] 调整窗口大小失败:', error),
)
}
},
[currentWindow],
)
if (getSystem() !== 'linux' || maximized) return null
return (
<div
className="window-resize-handles"
data-tauri-drag-region="false"
aria-hidden="true"
>
{RESIZE_HANDLES.map(({ direction, position }) => (
<div
key={direction}
className={`window-resize-handle window-resize-handle--${position}`}
data-resize-direction={direction}
onPointerDown={startResizeDragging}
/>
))}
</div>
)
}
export const WindowControls = forwardRef(function WindowControls(props, ref) {
const OS = getSystem()
const {
+7 -2
View File
@@ -44,7 +44,10 @@ import { LayoutItem } from '@/components/layout/layout-item'
import { LayoutTraffic } from '@/components/layout/layout-traffic'
import { NoticeManager } from '@/components/layout/notice-manager'
import { UpdateButton } from '@/components/layout/update-button'
import { WindowControls } from '@/components/layout/window-controller'
import {
WindowControls,
WindowResizeHandles,
} from '@/components/layout/window-controller'
import { useI18n } from '@/hooks/use-i18n'
import { useVerge } from '@/hooks/use-verge'
import { useWindowDecorations } from '@/hooks/use-window'
@@ -215,7 +218,7 @@ const Layout = () => {
const customTitlebar = useMemo(
() =>
!decorated ? (
decorated === false ? (
<div className="the_titlebar">
<div
className="the_titlebar-drag-region"
@@ -331,6 +334,8 @@ const Layout = () => {
: {},
]}
>
{decorated === false && <WindowResizeHandles />}
{/* Custom titlebar - rendered only when decorated is false, memoized for performance */}
{customTitlebar}