5
0
mirror of https://github.com/wailsapp/wails.git synced 2025-05-19 18:39:30 +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) { positionMenu.Add("Center").OnClick(func(ctx *application.Context) {
currentWindow(func(w *application.WebviewWindow) { currentWindow(func(w *application.WebviewWindow) {
w.Center() w.Center()

View File

@ -68,6 +68,8 @@ type (
startResize(border string) error startResize(border string) error
print() error print() error
setEnabled(enabled bool) setEnabled(enabled bool)
absolutePosition() (int, int)
setAbsolutePosition(x int, y int)
} }
) )
@ -586,6 +588,18 @@ func (w *WebviewWindow) RelativePosition() (int, int) {
return x, y 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() { func (w *WebviewWindow) Destroy() {
if w.impl == nil { if w.impl == nil {
return return
@ -932,3 +946,13 @@ func (w *WebviewWindow) SetEnabled(enabled bool) {
w.impl.setEnabled(enabled) 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 // 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; WebviewWindow* window = (WebviewWindow*)nsWindow;
NSScreen* screen = [window screen]; NSScreen* screen = [window screen];
if( screen == NULL ) { if( screen == NULL ) {
@ -492,7 +492,7 @@ int windowGetHeight(void* nsWindow) {
} }
// Get window position // Get window position
void windowGetPosition(void* nsWindow, int* x, int* y) { void windowGetRelativePosition(void* nsWindow, int* x, int* y) {
WebviewWindow* window = (WebviewWindow*)nsWindow; WebviewWindow* window = (WebviewWindow*)nsWindow;
NSRect frame = [window frame]; NSRect frame = [window frame];
*x = frame.origin.x; *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; *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 // Destroy window
void windowDestroy(void* nsWindow) { void windowDestroy(void* nsWindow) {
[(WebviewWindow*)nsWindow close]; [(WebviewWindow*)nsWindow close];
@ -942,9 +956,12 @@ func (w *macosWebviewWindow) size() (int, int) {
} }
func (w *macosWebviewWindow) setRelativePosition(x, y 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 { func (w *macosWebviewWindow) width() int {
var width C.int var width C.int
var wg sync.WaitGroup 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)) 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 var x, y C.int
invokeSync(func() { 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) return int(x), int(y)

View File

@ -630,6 +630,18 @@ func (w *linuxWebviewWindow) height() int {
return height 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() { func (w *linuxWebviewWindow) run() {
for eventId := range w.parent.eventListeners { for eventId := range w.parent.eventListeners {
w.on(eventId) 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) 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 x, y C.int
var wg sync.WaitGroup var wg sync.WaitGroup
wg.Add(1) wg.Add(1)
go globalApplication.dispatchOnMainThread(func() { go globalApplication.dispatchOnMainThread(func() {
C.gtk_window_get_position((*C.GtkWindow)(w.window), &x, &y) 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.Done()
}) })
wg.Wait() wg.Wait()

View File

@ -706,6 +706,27 @@ func (w *linuxWebviewWindow) relativePosition() (int, int) {
wg.Add(1) wg.Add(1)
go globalApplication.dispatchOnMainThread(func() { go globalApplication.dispatchOnMainThread(func() {
getPosition(w.window, &x, &y) 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.Done()
}) })
wg.Wait() wg.Wait()

View File

@ -63,6 +63,17 @@ type windowsWebviewWindow struct {
resizeBorderHeight int32 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) { func (w *windowsWebviewWindow) setEnabled(enabled bool) {
w32.EnableWindow(w.hwnd, enabled) w32.EnableWindow(w.hwnd, enabled)
} }
@ -335,9 +346,20 @@ func (w *windowsWebviewWindow) height() int {
} }
func (w *windowsWebviewWindow) relativePosition() (int, 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) 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() { func (w *windowsWebviewWindow) destroy() {