mirror of
https://github.com/clash-verge-rev/clash-verge-rev.git
synced 2026-10-30 10:42:09 +08:00
feat: add window resize handles on linux (#7319)
This commit is contained in:
@@ -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",
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user