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

[v3] Add Window AbsolutePosition/SetAbsolutePosition

This commit is contained in:
Lea Anthony 2023-06-23 21:14:26 +10:00
parent 989ef1b4a8
commit c96cccab2e
No known key found for this signature in database
GPG Key ID: 33DAF7BB90A58405
6 changed files with 144 additions and 8 deletions

View File

@ -203,6 +203,25 @@ func main() {
})
})
positionMenu.Add("Set Absolute Position (0,0)").OnClick(func(ctx *application.Context) {
currentWindow(func(w *application.WebviewWindow) {
w.SetAbsolutePosition(0, 0)
})
})
positionMenu.Add("Set Absolute Position (Random)").OnClick(func(ctx *application.Context) {
currentWindow(func(w *application.WebviewWindow) {
w.SetAbsolutePosition(rand.Intn(1000), rand.Intn(800))
})
})
positionMenu.Add("Get Absolute Position").OnClick(func(ctx *application.Context) {
currentWindow(func(w *application.WebviewWindow) {
x, y := w.AbsolutePosition()
app.InfoDialog().SetTitle("Current WebviewWindow Position").SetMessage("X: " + strconv.Itoa(x) + " Y: " + strconv.Itoa(y)).Show()
})
})
positionMenu.Add("Center").OnClick(func(ctx *application.Context) {
currentWindow(func(w *application.WebviewWindow) {
w.Center()

View File

@ -68,6 +68,8 @@ type (
startResize(border string) error
print() error
setEnabled(enabled bool)
absolutePosition() (int, int)
setAbsolutePosition(x int, y int)
}
)
@ -586,6 +588,18 @@ func (w *WebviewWindow) RelativePosition() (int, int) {
return x, y
}
// AbsolutePosition returns the absolute position of the window to the screen
func (w *WebviewWindow) AbsolutePosition() (int, int) {
if w.impl == nil {
return 0, 0
}
var x, y int
invokeSync(func() {
x, y = w.impl.absolutePosition()
})
return x, y
}
func (w *WebviewWindow) Destroy() {
if w.impl == nil {
return
@ -932,3 +946,13 @@ func (w *WebviewWindow) SetEnabled(enabled bool) {
w.impl.setEnabled(enabled)
})
}
func (w *WebviewWindow) SetAbsolutePosition(x int, y int) {
// set absolute position
if w.impl == nil {
return
}
invokeSync(func() {
w.impl.setAbsolutePosition(x, y)
})
}

View File

@ -278,7 +278,7 @@ void windowZoomOut(void* nsWindow) {
}
// set the window position relative to the screen
void windowSetrelativePosition(void* nsWindow, int x, int y) {
void windowSetRelativePosition(void* nsWindow, int x, int y) {
WebviewWindow* window = (WebviewWindow*)nsWindow;
NSScreen* screen = [window screen];
if( screen == NULL ) {
@ -492,7 +492,7 @@ int windowGetHeight(void* nsWindow) {
}
// Get window position
void windowGetPosition(void* nsWindow, int* x, int* y) {
void windowGetRelativePosition(void* nsWindow, int* x, int* y) {
WebviewWindow* window = (WebviewWindow*)nsWindow;
NSRect frame = [window frame];
*x = frame.origin.x;
@ -506,6 +506,20 @@ void windowGetPosition(void* nsWindow, int* x, int* y) {
*y = screenFrame.size.height - frame.origin.y - frame.size.height;
}
// Get absolute window position
void windowGetAbsolutePosition(void* nsWindow, int* x, int* y) {
NSRect frame = [(WebviewWindow*)nsWindow frame];
*x = frame.origin.x;
*y = frame.origin.y;
}
void windowSetAbsolutePosition(void* nsWindow, int x, int y) {
NSRect frame = [(WebviewWindow*)nsWindow frame];
frame.origin.x = x;
frame.origin.y = y;
[(WebviewWindow*)nsWindow setFrame:frame display:YES];
}
// Destroy window
void windowDestroy(void* nsWindow) {
[(WebviewWindow*)nsWindow close];
@ -942,9 +956,12 @@ func (w *macosWebviewWindow) size() (int, int) {
}
func (w *macosWebviewWindow) setRelativePosition(x, y int) {
C.windowSetrelativePosition(w.nsWindow, C.int(x), C.int(y))
C.windowSetRelativePosition(w.nsWindow, C.int(x), C.int(y))
}
func (w *macosWebviewWindow) setRelativePosition(x, y int) {
C.windowSetAbsolutePosition(w.nsWindow, C.int(x), C.int(y))
}
func (w *macosWebviewWindow) width() int {
var width C.int
var wg sync.WaitGroup
@ -1080,10 +1097,19 @@ func (w *macosWebviewWindow) setBackgroundColour(colour RGBA) {
C.windowSetBackgroundColour(w.nsWindow, C.int(colour.Red), C.int(colour.Green), C.int(colour.Blue), C.int(colour.Alpha))
}
func (w *macosWebviewWindow) position() (int, int) {
func (w *macosWebviewWindow) relativePosition() (int, int) {
var x, y C.int
invokeSync(func() {
C.windowGetPosition(w.nsWindow, &x, &y)
C.windowGetRelativePosition(w.nsWindow, &x, &y)
})
return int(x), int(y)
}
func (w *macosWebviewWindow) absolutePosition() (int, int) {
var x, y C.int
invokeSync(func() {
C.windowGetAbsolutePosition(w.nsWindow, &x, &y)
})
return int(x), int(y)

View File

@ -630,6 +630,18 @@ func (w *linuxWebviewWindow) height() int {
return height
}
func (w *linuxWebviewWindow) absolutePosition() (int, int) {
var x, y C.int
var wg sync.WaitGroup
wg.Add(1)
globalApplication.dispatchOnMainThread(func() {
C.gtk_window_get_position((*C.GtkWindow)(w.window), &x, &y)
wg.Done()
})
wg.Wait()
return int(x), int(y)
}
func (w *linuxWebviewWindow) run() {
for eventId := range w.parent.eventListeners {
w.on(eventId)
@ -738,12 +750,24 @@ func (w *linuxWebviewWindow) setBackgroundColour(colour RGBA) {
C.webkit_web_view_set_background_color((*C.WebKitWebView)(w.webview), &rgba)
}
func (w *linuxWebviewWindow) position() (int, int) {
func (w *linuxWebviewWindow) relativePosition() (int, int) {
var x, y C.int
var wg sync.WaitGroup
wg.Add(1)
go globalApplication.dispatchOnMainThread(func() {
C.gtk_window_get_position((*C.GtkWindow)(w.window), &x, &y)
// The position must be relative to the screen it is on
// We need to get the screen it is on
screen := C.gtk_widget_get_screen((*C.GtkWidget)(w.window))
monitor := C.gdk_screen_get_monitor_at_window(screen, (*C.GdkWindow)(w.window))
geometry := C.GdkRectangle{}
C.gdk_screen_get_monitor_geometry(screen, monitor, &geometry)
x = x - geometry.x
y = y - geometry.y
// TODO: Scale based on DPI
wg.Done()
})
wg.Wait()

View File

@ -706,6 +706,27 @@ func (w *linuxWebviewWindow) relativePosition() (int, int) {
wg.Add(1)
go globalApplication.dispatchOnMainThread(func() {
getPosition(w.window, &x, &y)
// Get the position of the window relative to the screen
var getOrigin func(uintptr, *int, *int)
purego.RegisterLibFunc(&getOrigin, gtk, "gtk_widget_translate_coordinates")
getOrigin(w.window, &x, &y)
wg.Done()
})
wg.Wait()
return x, y
}
func (w *linuxWebviewWindow) absolutePosition() (int, int) {
var getOrigin func(uintptr, *int, *int)
purego.RegisterLibFunc(&getOrigin, gtk, "gtk_widget_translate_coordinates")
var x, y int
var wg sync.WaitGroup
wg.Add(1)
go globalApplication.dispatchOnMainThread(func() {
getOrigin(w.window, nil, nil)
wg.Done()
})
wg.Wait()

View File

@ -63,6 +63,17 @@ type windowsWebviewWindow struct {
resizeBorderHeight int32
}
func (w *windowsWebviewWindow) setAbsolutePosition(x int, y int) {
// Set the window's absolute position
w32.SetWindowPos(w.hwnd, 0, x, y, 0, 0, w32.SWP_NOSIZE|w32.SWP_NOZORDER)
}
func (w *windowsWebviewWindow) absolutePosition() (int, int) {
rect := w32.GetWindowRect(w.hwnd)
left, right := w.scaleToDefaultDPI(int(rect.Left), int(rect.Right))
return left, right
}
func (w *windowsWebviewWindow) setEnabled(enabled bool) {
w32.EnableWindow(w.hwnd, enabled)
}
@ -335,9 +346,20 @@ func (w *windowsWebviewWindow) height() int {
}
func (w *windowsWebviewWindow) relativePosition() (int, int) {
// Get monitor for window
monitor := w32.MonitorFromWindow(w.hwnd, w32.MONITOR_DEFAULTTONEAREST)
var monitorInfo w32.MONITORINFO
monitorInfo.CbSize = uint32(unsafe.Sizeof(monitorInfo))
w32.GetMonitorInfo(monitor, &monitorInfo)
// Get window rect
rect := w32.GetWindowRect(w.hwnd)
left, right := w.scaleToDefaultDPI(int(rect.Left), int(rect.Right))
return left, right
// Calculate relative position
x := int(rect.Left) - int(monitorInfo.RcWork.Left)
y := int(rect.Top) - int(monitorInfo.RcWork.Top)
return w.scaleToDefaultDPI(x, y)
}
func (w *windowsWebviewWindow) destroy() {