mirror of
https://github.com/wailsapp/wails.git
synced 2025-05-11 22:49:29 +08:00
[v3 windows] Support frameless drag. Add /wails/flags
endpoint.
This commit is contained in:
parent
c03078ca16
commit
01e2e46e0d
@ -19,6 +19,7 @@ const (
|
||||
ipcJSPath = "/wails/ipc.js"
|
||||
runtimePath = "/wails/runtime"
|
||||
capabilitiesPath = "/wails/capabilities"
|
||||
flagsPath = "/wails/flags"
|
||||
)
|
||||
|
||||
type RuntimeAssets interface {
|
||||
@ -51,6 +52,9 @@ type AssetServer struct {
|
||||
// GetCapabilities returns the capabilities of the runtime
|
||||
GetCapabilities func() []byte
|
||||
|
||||
// GetFlags returns the application flags
|
||||
GetFlags func() []byte
|
||||
|
||||
assetServerWebView
|
||||
}
|
||||
|
||||
@ -156,6 +160,13 @@ func (d *AssetServer) ServeHTTP(rw http.ResponseWriter, req *http.Request) {
|
||||
}
|
||||
d.writeBlob(rw, path, data)
|
||||
|
||||
case flagsPath:
|
||||
var data = []byte("{}")
|
||||
if d.GetFlags != nil {
|
||||
data = d.GetFlags()
|
||||
}
|
||||
d.writeBlob(rw, path, data)
|
||||
|
||||
case runtimePath:
|
||||
if d.runtimeHandler != nil {
|
||||
d.runtimeHandler.HandleRuntimeCall(rw, req)
|
||||
|
@ -11,6 +11,7 @@ The electron alternative for Go
|
||||
/* jshint esversion: 9 */
|
||||
|
||||
import {invoke} from "./invoke";
|
||||
import {GetFlag} from "./flags";
|
||||
|
||||
let shouldDrag = false;
|
||||
|
||||
@ -42,7 +43,24 @@ export function setupDrag() {
|
||||
window.addEventListener('mouseup', onMouseUp);
|
||||
}
|
||||
|
||||
let resizeEdge = null;
|
||||
|
||||
function testResize(e) {
|
||||
if( resizeEdge !== null ) {
|
||||
invoke("resize:" + resizeEdge);
|
||||
return true
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
function onMouseDown(e) {
|
||||
|
||||
// Check for resizing on Windows
|
||||
if( WINDOWS ) {
|
||||
if (testResize()) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (dragTest(e)) {
|
||||
// Ignore drag on scrollbars
|
||||
if (e.offsetX > e.target.clientWidth || e.offsetY > e.target.clientHeight) {
|
||||
@ -66,6 +84,11 @@ export function endDrag() {
|
||||
shouldDrag = false;
|
||||
}
|
||||
|
||||
function setResize(cursor) {
|
||||
document.documentElement.style.cursor = cursor || defaultCursor;
|
||||
resizeEdge = cursor;
|
||||
}
|
||||
|
||||
function onMouseMove(e) {
|
||||
if (shouldDrag) {
|
||||
shouldDrag = false;
|
||||
@ -74,4 +97,37 @@ function onMouseMove(e) {
|
||||
invoke("drag");
|
||||
}
|
||||
}
|
||||
|
||||
if (WINDOWS) {
|
||||
handleResize(e);
|
||||
}
|
||||
}
|
||||
|
||||
let defaultCursor = "auto";
|
||||
|
||||
function handleResize(e) {
|
||||
|
||||
// if (!GetFlag("enableResize")) {
|
||||
// return;
|
||||
// }
|
||||
|
||||
let resizeHandleHeight = GetFlag("system.resizeHandleHeight") || 5;
|
||||
let resizeHandleWidth = GetFlag("system.resizeHandleWidth") || 5;
|
||||
let rightBorder = window.outerWidth - e.clientX < resizeHandleWidth;
|
||||
let leftBorder = e.clientX < resizeHandleWidth;
|
||||
let topBorder = e.clientY < resizeHandleHeight;
|
||||
let bottomBorder = window.outerHeight - e.clientY < resizeHandleHeight;
|
||||
|
||||
// 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");
|
||||
else if (leftBorder) setResize("w-resize");
|
||||
else if (topBorder) setResize("n-resize");
|
||||
else if (bottomBorder) setResize("s-resize");
|
||||
else if (rightBorder) setResize("e-resize");
|
||||
|
||||
}
|
42
v3/internal/runtime/desktop/flags.js
Normal file
42
v3/internal/runtime/desktop/flags.js
Normal file
@ -0,0 +1,42 @@
|
||||
/*
|
||||
_ __ _ __
|
||||
| | / /___ _(_) /____
|
||||
| | /| / / __ `/ / / ___/
|
||||
| |/ |/ / /_/ / / (__ )
|
||||
|__/|__/\__,_/_/_/____/
|
||||
The electron alternative for Go
|
||||
(c) Lea Anthony 2019-present
|
||||
*/
|
||||
|
||||
/* jshint esversion: 9 */
|
||||
|
||||
let flags = new Map();
|
||||
|
||||
fetch("/wails/flags").then((response) => {
|
||||
response.json().then((data) => {
|
||||
flags.Set(data);
|
||||
});
|
||||
});
|
||||
|
||||
function getValueFromMap(keyString) {
|
||||
const keys = keyString.split('.');
|
||||
let value = flags;
|
||||
|
||||
for (const key of keys) {
|
||||
if (value instanceof Map) {
|
||||
value = value.get(key);
|
||||
} else {
|
||||
value = value[key];
|
||||
}
|
||||
|
||||
if (value === undefined) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
export function GetFlag(keyString) {
|
||||
return getValueFromMap(keyString);
|
||||
}
|
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
@ -1,6 +1,7 @@
|
||||
package application
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"github.com/wailsapp/wails/v3/internal/capabilities"
|
||||
"log"
|
||||
"net/http"
|
||||
@ -83,6 +84,15 @@ func New(appOptions Options) *App {
|
||||
return globalApplication.capabilities.AsBytes()
|
||||
}
|
||||
|
||||
srv.GetFlags = func() []byte {
|
||||
updatedOptions := result.impl.GetFlags(appOptions)
|
||||
flags, err := json.Marshal(updatedOptions)
|
||||
if err != nil {
|
||||
log.Fatal("Invalid flags provided to application: ", err.Error())
|
||||
}
|
||||
return flags
|
||||
}
|
||||
|
||||
srv.UseRuntimeHandler(NewMessageProcessor())
|
||||
result.assets = srv
|
||||
|
||||
@ -136,6 +146,7 @@ type (
|
||||
show()
|
||||
getPrimaryScreen() (*Screen, error)
|
||||
getScreens() ([]*Screen, error)
|
||||
GetFlags(options Options) map[string]any
|
||||
}
|
||||
|
||||
runnable interface {
|
||||
|
@ -199,6 +199,13 @@ func (m *macosApp) destroy() {
|
||||
C.destroyApp()
|
||||
}
|
||||
|
||||
func (m *macosApp) GetFlags(options Options) map[string]any {
|
||||
if options.Flags == nil {
|
||||
options.Flags = make(map[string]any)
|
||||
}
|
||||
return options.Flags
|
||||
}
|
||||
|
||||
func newPlatformApp(app *App) *macosApp {
|
||||
C.init()
|
||||
return &macosApp{
|
||||
|
@ -43,6 +43,17 @@ type windowsApp struct {
|
||||
currentWindowID uint
|
||||
}
|
||||
|
||||
func (m *windowsApp) GetFlags(options Options) map[string]any {
|
||||
if options.Flags == nil {
|
||||
options.Flags = make(map[string]any)
|
||||
}
|
||||
options.Flags["system"] = map[string]any{
|
||||
"resizeHandleWidth": w32.GetSystemMetrics(w32.SM_CXSIZEFRAME),
|
||||
"resizeHandleHeight": w32.GetSystemMetrics(w32.SM_CYSIZEFRAME),
|
||||
}
|
||||
return options.Flags
|
||||
}
|
||||
|
||||
func (m *windowsApp) getWindowForHWND(hwnd w32.HWND) *windowsWebviewWindow {
|
||||
m.windowMapLock.RLock()
|
||||
defer m.windowMapLock.RUnlock()
|
||||
|
@ -20,6 +20,7 @@ type Options struct {
|
||||
}
|
||||
Assets AssetOptions
|
||||
Plugins map[string]Plugin
|
||||
Flags map[string]any
|
||||
}
|
||||
|
||||
// AssetOptions defines the configuration of the AssetServer.
|
||||
|
@ -4,6 +4,7 @@ import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"github.com/samber/lo"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
@ -63,6 +64,7 @@ type (
|
||||
openContextMenu(menu *Menu, data *ContextMenuData)
|
||||
nativeWindowHandle() uintptr
|
||||
startDrag() error
|
||||
startResize(border string) error
|
||||
}
|
||||
)
|
||||
|
||||
@ -436,7 +438,6 @@ func (w *WebviewWindow) SetBackgroundColour(colour RGBA) *WebviewWindow {
|
||||
}
|
||||
|
||||
func (w *WebviewWindow) handleMessage(message string) {
|
||||
w.info(message)
|
||||
// Check for special messages
|
||||
if message == "drag" {
|
||||
if !w.IsFullscreen() {
|
||||
@ -447,11 +448,37 @@ func (w *WebviewWindow) handleMessage(message string) {
|
||||
}
|
||||
})
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
if strings.HasPrefix(message, "resize:") {
|
||||
if !w.IsFullscreen() {
|
||||
sl := strings.Split(message, ":")
|
||||
if len(sl) != 2 {
|
||||
w.error("Unknown message returned from dispatcher: %+v", message)
|
||||
return
|
||||
}
|
||||
err := w.startResize(sl[1])
|
||||
if err != nil {
|
||||
w.error(err.Error())
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
w.info("ProcessMessage from front end: %s", message)
|
||||
|
||||
}
|
||||
|
||||
func (w *WebviewWindow) startResize(border string) error {
|
||||
if w.impl == nil {
|
||||
return nil
|
||||
}
|
||||
return invokeSyncWithResult(func() error {
|
||||
return w.impl.startResize(border)
|
||||
})
|
||||
}
|
||||
|
||||
// Center centers the window on the screen
|
||||
func (w *WebviewWindow) Center() {
|
||||
if w.impl == nil {
|
||||
|
@ -26,6 +26,17 @@ import (
|
||||
"github.com/wailsapp/wails/v3/pkg/w32"
|
||||
)
|
||||
|
||||
var edgeMap = map[string]uintptr{
|
||||
"n-resize": w32.HTTOP,
|
||||
"ne-resize": w32.HTTOPRIGHT,
|
||||
"e-resize": w32.HTRIGHT,
|
||||
"se-resize": w32.HTBOTTOMRIGHT,
|
||||
"s-resize": w32.HTBOTTOM,
|
||||
"sw-resize": w32.HTBOTTOMLEFT,
|
||||
"w-resize": w32.HTLEFT,
|
||||
"nw-resize": w32.HTTOPLEFT,
|
||||
}
|
||||
|
||||
var showDevTools = func(chromium *edge.Chromium) {}
|
||||
|
||||
type windowsWebviewWindow struct {
|
||||
@ -47,6 +58,15 @@ type windowsWebviewWindow struct {
|
||||
resizeDebouncer func(func())
|
||||
}
|
||||
|
||||
func (w *windowsWebviewWindow) startResize(border string) error {
|
||||
if !w32.ReleaseCapture() {
|
||||
return fmt.Errorf("unable to release mouse capture")
|
||||
}
|
||||
// Use PostMessage because we don't want to block the caller until resizing has been finished.
|
||||
w32.PostMessage(w.hwnd, w32.WM_NCLBUTTONDOWN, edgeMap[border], 0)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (w *windowsWebviewWindow) startDrag() error {
|
||||
if !w32.ReleaseCapture() {
|
||||
return fmt.Errorf("unable to release mouse capture")
|
||||
@ -1157,9 +1177,9 @@ func (w *windowsWebviewWindow) setupChromium() {
|
||||
chromium.AdditionalBrowserArgs = append(chromium.AdditionalBrowserArgs, "--disable-gpu")
|
||||
}
|
||||
|
||||
if globalApplication.capabilities.HasNativeDrag {
|
||||
chromium.AdditionalBrowserArgs = append(chromium.AdditionalBrowserArgs, "--enable-features=msWebView2EnableDraggableRegions")
|
||||
}
|
||||
//if globalApplication.capabilities.HasNativeDrag {
|
||||
// chromium.AdditionalBrowserArgs = append(chromium.AdditionalBrowserArgs, "--enable-features=msWebView2EnableDraggableRegions")
|
||||
//}
|
||||
|
||||
if len(disableFeatues) > 0 {
|
||||
arg := fmt.Sprintf("--disable-features=%s", strings.Join(disableFeatues, ","))
|
||||
|
Loading…
Reference in New Issue
Block a user