Skip to content

Commit

Permalink
Fix incorrect position being loaded on linux when using multiple moni…
Browse files Browse the repository at this point in the history
…tors
  • Loading branch information
mircearoata committed Apr 17, 2024
1 parent a50a49c commit b474ea4
Show file tree
Hide file tree
Showing 3 changed files with 64 additions and 19 deletions.
30 changes: 30 additions & 0 deletions backend/utils/display.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package utils

import (
"image"
"runtime"

"github.com/kbinani/screenshot"
)
Expand All @@ -15,5 +16,34 @@ func GetDisplayBounds() []image.Rectangle {
bounds = append(bounds, screenshot.GetDisplayBounds(i))
}

if runtime.GOOS == "linux" {
// gdk_monitor_get_geometry considers 0,0 to be the corner of the bounding box of all the monitors,
// not the 0,0 of the main monitor
boundingBox := bounds[0]
for _, b := range bounds {
boundingBox = boundingBox.Union(b)
}
for i := range bounds {
bounds[i] = bounds[i].Sub(boundingBox.Min)
}
}

return bounds
}

func GetDisplayBoundsAt(x, y int) image.Rectangle {
point := image.Pt(x, y)

displays := GetDisplayBounds()

curDisplay := displays[0] // use main display as fallback

for _, d := range displays {
if point.In(d) {
curDisplay = d
break
}
}

return curDisplay
}
30 changes: 30 additions & 0 deletions backend/wailsextras/window.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package wailsextras

import (
"context"
"runtime"

wailsRuntime "github.com/wailsapp/wails/v2/pkg/runtime"

"github.com/satisfactorymodding/SatisfactoryModManager/backend/utils"
)

// WindowSetPosition wraps Wails's WindowSetPosition,
// but ensures that WindowSetPosition(WindowGetPosition())
// will result in the window remaining stationary
// regardless of OS's behaviour with multiple displays
func WindowSetPosition(ctx context.Context, x, y int) {
if runtime.GOOS == "windows" || runtime.GOOS == "linux" {
// WindowSetPosition expects relative to the current monitor,
// but WindowGetPosition returns absolute
curX, curY := wailsRuntime.WindowGetPosition(ctx)
display := utils.GetDisplayBoundsAt(curX, curY)
x -= display.Min.X
y -= display.Min.Y
}

// It appears that on darwin Wails gets and sets the position
// with values relative to the current monitor

wailsRuntime.WindowSetPosition(ctx, x, y)
}
23 changes: 4 additions & 19 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ import (
"github.com/wailsapp/wails/v2"
"github.com/wailsapp/wails/v2/pkg/options"
"github.com/wailsapp/wails/v2/pkg/options/assetserver"
wailsRuntime "github.com/wailsapp/wails/v2/pkg/runtime"

"github.com/satisfactorymodding/SatisfactoryModManager/backend"
"github.com/satisfactorymodding/SatisfactoryModManager/backend/app"
Expand All @@ -25,6 +24,7 @@ import (
"github.com/satisfactorymodding/SatisfactoryModManager/backend/logging"
"github.com/satisfactorymodding/SatisfactoryModManager/backend/settings"
"github.com/satisfactorymodding/SatisfactoryModManager/backend/utils"
"github.com/satisfactorymodding/SatisfactoryModManager/backend/wailsextras"
"github.com/satisfactorymodding/SatisfactoryModManager/backend/websocket"
)

Expand Down Expand Up @@ -96,7 +96,9 @@ func main() {
appCommon.AppContext = ctx

// Wails doesn't support setting the window position on init, so we do it here
loadWindowLocation(ctx)
if settings.Settings.WindowPosition != nil {
wailsextras.WindowSetPosition(ctx, settings.Settings.WindowPosition.X, settings.Settings.WindowPosition.Y)
}

app.App.WatchWindow() //nolint:contextcheck
go websocket.ListenAndServeWebsocket()
Expand Down Expand Up @@ -137,23 +139,6 @@ func main() {
}
}

func loadWindowLocation(ctx context.Context) {
if settings.Settings.WindowPosition != nil {
// Setting the window location is relative to the current monitor,
// but we save it as absolute position.

wailsRuntime.WindowSetPosition(ctx, 0, 0)

// Get the location the window was actually placed at
monitorLeft, monitorTop := wailsRuntime.WindowGetPosition(ctx)

x := settings.Settings.WindowPosition.X - monitorLeft
y := settings.Settings.WindowPosition.Y - monitorTop

wailsRuntime.WindowSetPosition(ctx, x, y)
}
}

func init() {
// Pass build-time variables to viper
if len(version) > 0 && version[0] == 'v' {
Expand Down

0 comments on commit b474ea4

Please sign in to comment.