5
0
mirror of https://github.com/wailsapp/wails.git synced 2025-05-20 19:09:29 +08:00

[v3 windows] Fix frameless window drag. Add better resize for corners.

This commit is contained in:
Lea Anthony 2023-06-15 21:06:14 +10:00
parent 01e2e46e0d
commit 367ca745c3
No known key found for this signature in database
GPG Key ID: 33DAF7BB90A58405
9 changed files with 108 additions and 89 deletions

View File

@ -16,9 +16,9 @@ import {GetFlag} from "./flags";
let shouldDrag = false;
export function dragTest(e) {
if (window.wails.Capabilities['HasNativeDrag'] === true) {
return false;
}
// if (window.wails.Capabilities['HasNativeDrag'] === true) {
// return false;
// }
let val = window.getComputedStyle(e.target).getPropertyValue("app-region");
if (val) {
@ -46,7 +46,7 @@ export function setupDrag() {
let resizeEdge = null;
function testResize(e) {
if( resizeEdge !== null ) {
if( resizeEdge ) {
invoke("resize:" + resizeEdge);
return true
}
@ -96,6 +96,7 @@ function onMouseMove(e) {
if (mousePressed > 0) {
invoke("drag");
}
return;
}
if (WINDOWS) {
@ -106,28 +107,34 @@ function onMouseMove(e) {
let defaultCursor = "auto";
function handleResize(e) {
// if (!GetFlag("enableResize")) {
// return;
// }
let resizeHandleHeight = GetFlag("system.resizeHandleHeight") || 5;
let resizeHandleWidth = GetFlag("system.resizeHandleWidth") || 5;
// Extra pixels for the corner areas
let cornerExtra = GetFlag("resizeCornerExtra") || 3;
let rightBorder = window.outerWidth - e.clientX < resizeHandleWidth;
let leftBorder = e.clientX < resizeHandleWidth;
let topBorder = e.clientY < resizeHandleHeight;
let bottomBorder = window.outerHeight - e.clientY < resizeHandleHeight;
// Adjust for corners
let rightCorner = window.outerWidth - e.clientX < (resizeHandleWidth + cornerExtra);
let leftCorner = e.clientX < (resizeHandleWidth + cornerExtra);
let topCorner = e.clientY < (resizeHandleHeight + cornerExtra);
let bottomCorner = window.outerHeight - e.clientY < (resizeHandleHeight + cornerExtra);
// If we aren't on an edge, but were, reset the cursor to default
if (!leftBorder && !rightBorder && !topBorder && !bottomBorder && resizeEdge !== undefined) {
setResize();
} else if (rightBorder && bottomBorder) setResize("se-resize");
else if (leftBorder && bottomBorder) setResize("sw-resize");
else if (leftBorder && topBorder) setResize("nw-resize");
else if (topBorder && rightBorder) setResize("ne-resize");
}
// Adjusted for corner areas
else if (rightCorner && bottomCorner) setResize("se-resize");
else if (leftCorner && bottomCorner) setResize("sw-resize");
else if (leftCorner && topCorner) setResize("nw-resize");
else if (topCorner && rightCorner) setResize("ne-resize");
else if (leftBorder) setResize("w-resize");
else if (topBorder) setResize("n-resize");
else if (bottomBorder) setResize("s-resize");
else if (rightBorder) setResize("e-resize");
}
}

View File

@ -12,12 +12,27 @@ The electron alternative for Go
let flags = new Map();
function convertToMap(obj) {
const map = new Map();
for (const [key, value] of Object.entries(obj)) {
if (typeof value === 'object' && value !== null) {
map.set(key, convertToMap(value)); // Recursively convert nested object
} else {
map.set(key, value);
}
}
return map;
}
fetch("/wails/flags").then((response) => {
response.json().then((data) => {
flags.Set(data);
flags = convertToMap(data);
});
});
function getValueFromMap(keyString) {
const keys = keyString.split('.');
let value = flags;

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -56,6 +56,10 @@ type windowsWebviewWindow struct {
chromium *edge.Chromium
hasStarted bool
resizeDebouncer func(func())
// resizeBorder* is the width/height of the resize border in pixels.
resizeBorderWidth int32
resizeBorderHeight int32
}
func (w *windowsWebviewWindow) startResize(border string) error {
@ -567,7 +571,9 @@ func (w *windowsWebviewWindow) setFrameless(b bool) {
func newWindowImpl(parent *WebviewWindow) *windowsWebviewWindow {
result := &windowsWebviewWindow{
parent: parent,
parent: parent,
resizeBorderWidth: int32(w32.GetSystemMetrics(w32.SM_CXSIZEFRAME)),
resizeBorderHeight: int32(w32.GetSystemMetrics(w32.SM_CYSIZEFRAME)),
}
return result
@ -680,6 +686,13 @@ func (w *windowsWebviewWindow) WndProc(msg uint32, wparam, lparam uintptr) uintp
getNativeApplication().currentWindowID = w.parent.id
w.parent.emit(events.Common.WindowFocus)
}
// If we want to have a frameless window but with the default frame decorations, extend the DWM client area.
// This Option is not affected by returning 0 in WM_NCCALCSIZE.
// As a result we have hidden the titlebar but still have the default window frame styling.
// See: https://docs.microsoft.com/en-us/windows/win32/api/dwmapi/nf-dwmapi-dwmextendframeintoclientarea#remarks
if w.framelessWithDecorations() {
w32.ExtendFrameIntoClientArea(w.hwnd, true)
}
case w32.WM_CLOSE:
if w.parent.options.HideOnClose {
w.hide()
@ -691,8 +704,6 @@ func (w *windowsWebviewWindow) WndProc(msg uint32, wparam, lparam uintptr) uintp
windowsApp.unregisterWindow(w)
case w32.WM_NCLBUTTONDOWN:
w32.SetFocus(w.hwnd)
case w32.WM_NCLBUTTONUP:
case w32.WM_MOVE, w32.WM_MOVING:
_ = w.chromium.NotifyParentWindowPositionChanged()
case w32.WM_SIZE:
@ -799,52 +810,6 @@ func (w *windowsWebviewWindow) WndProc(msg uint32, wparam, lparam uintptr) uintp
if w.framelessWithDecorations() {
w32.ExtendFrameIntoClientArea(w.hwnd, true)
}
case w32.WM_NCHITTEST:
// Get the cursor position
x := int32(w32.LOWORD(uint32(lparam)))
y := int32(w32.HIWORD(uint32(lparam)))
ptCursor := w32.POINT{X: x, Y: y}
// Get the window rectangle
rcWindow := w32.GetWindowRect(w.hwnd)
// Determine if the cursor is in a resize area
bOnResizeBorder := false
resizeBorderWidth := int32(5) // change this to adjust the resize border width
if ptCursor.X >= rcWindow.Right-resizeBorderWidth {
bOnResizeBorder = true // right edge
}
if ptCursor.Y >= rcWindow.Bottom-resizeBorderWidth {
bOnResizeBorder = true // bottom edge
}
if ptCursor.X <= rcWindow.Left+resizeBorderWidth {
bOnResizeBorder = true // left edge
}
if ptCursor.Y <= rcWindow.Top+resizeBorderWidth {
bOnResizeBorder = true // top edge
}
// Return the appropriate value
if bOnResizeBorder {
if ptCursor.X >= rcWindow.Right-resizeBorderWidth && ptCursor.Y >= rcWindow.Bottom-resizeBorderWidth {
return w32.HTBOTTOMRIGHT
} else if ptCursor.X <= rcWindow.Left+resizeBorderWidth && ptCursor.Y >= rcWindow.Bottom-resizeBorderWidth {
return w32.HTBOTTOMLEFT
} else if ptCursor.X >= rcWindow.Right-resizeBorderWidth && ptCursor.Y <= rcWindow.Top+resizeBorderWidth {
return w32.HTTOPRIGHT
} else if ptCursor.X <= rcWindow.Left+resizeBorderWidth && ptCursor.Y <= rcWindow.Top+resizeBorderWidth {
return w32.HTTOPLEFT
} else if ptCursor.X >= rcWindow.Right-resizeBorderWidth {
return w32.HTRIGHT
} else if ptCursor.Y >= rcWindow.Bottom-resizeBorderWidth {
return w32.HTBOTTOM
} else if ptCursor.X <= rcWindow.Left+resizeBorderWidth {
return w32.HTLEFT
} else if ptCursor.Y <= rcWindow.Top+resizeBorderWidth {
return w32.HTTOP
}
}
return w32.HTCLIENT
case w32.WM_NCCALCSIZE:
// Disable the standard frame by allowing the client area to take the full
@ -863,7 +828,7 @@ func (w *windowsWebviewWindow) WndProc(msg uint32, wparam, lparam uintptr) uintp
// If the window is maximized we must adjust the client area to the work area of the monitor. Otherwise
// some content goes beyond the visible part of the monitor.
// Make sure to use the provided RECT to get the monitor, because during maximizig there might be
// a wrong monitor returned in multi screen mode when using MonitorFromWindow.
// a wrong monitor returned in multiscreen mode when using MonitorFromWindow.
// See: https://github.com/MicrosoftEdge/WebView2Feedback/issues/2549
monitor := w32.MonitorFromRect(rgrc, w32.MONITOR_DEFAULTTONULL)