Skip to content

Commit 91bdb4c

Browse files
committed
Update glfw.go
1 parent 5de0dea commit 91bdb4c

File tree

1 file changed

+89
-2
lines changed

1 file changed

+89
-2
lines changed

glfw.go

Lines changed: 89 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,10 @@
11
package flutter
22

33
import (
4+
"encoding/json"
45
"fmt"
6+
"runtime"
7+
"sync"
58
"unsafe"
69

710
"github.com/go-flutter-desktop/go-flutter/embedder"
@@ -26,6 +29,9 @@ type windowManager struct {
2629

2730
// caching of ppsc to avoid re-calculating every event
2831
pixelsPerScreenCoordinate float64
32+
33+
// sync.Once to limit pixelRatio warning messages.
34+
oncePrintPixelRatioLimit sync.Once
2935
}
3036

3137
func newWindowManager(forcedPixelRatio float64) *windowManager {
@@ -202,8 +208,11 @@ func (m *windowManager) glfwRefreshCallback(window *glfw.Window) {
202208
if m.forcedPixelRatio != 0 {
203209
pixelRatio = m.forcedPixelRatio
204210
} else {
205-
xscale, _ := window.GetContentScale()
206-
pixelRatio = float64(xscale)
211+
if runtime.GOOS == "linux" {
212+
pixelRatio = m.getPixelRatioLinux(window)
213+
} else {
214+
pixelRatio = m.getPixelRatioOther(window)
215+
}
207216
}
208217

209218
event := embedder.WindowMetricsEvent{
@@ -217,3 +226,81 @@ func (m *windowManager) glfwRefreshCallback(window *glfw.Window) {
217226

218227
flutterEngine.SendWindowMetricsEvent(event)
219228
}
229+
230+
// getPixelRatioOther, getPixelRatioLinux isn't well working on other platform.
231+
// GLFW window.GetContentScale() works better:
232+
// https://github.com/go-flutter-desktop/go-flutter/pull/458
233+
func (m *windowManager) getPixelRatioOther(window *glfw.Window) float64 {
234+
xscale, _ := window.GetContentScale()
235+
return float64(xscale)
236+
}
237+
238+
// getPixelRatioLinux returns the Flutter pixel_ratio is defined as DPI/dp
239+
// given framebuffer size and the current window information.
240+
// Same as defined in the official LINUX embedder:
241+
// https://github.com/flutter/engine/blob/master/shell/platform/glfw/flutter_glfw.cc
242+
// Fallback to getPixelRatioOther if error occur.
243+
func (m *windowManager) getPixelRatioLinux(window *glfw.Window) float64 {
244+
widthPx, heightPx := window.GetFramebufferSize()
245+
width, _ := window.GetSize()
246+
247+
var selectedMonitor *glfw.Monitor
248+
winX, winY := window.GetPos()
249+
winCenterX, winCenterY := winX+widthPx/2, winY+heightPx/2
250+
251+
monitors := glfw.GetMonitors()
252+
for _, monitor := range monitors {
253+
monX1, monY1 := monitor.GetPos()
254+
monMode := monitor.GetVideoMode()
255+
if monMode == nil {
256+
continue
257+
}
258+
monX2, monY2 := monX1+monMode.Width, monY1+monMode.Height
259+
if (monX1 <= winCenterX && winCenterX <= monX2) &&
260+
(monY1 <= winCenterY && winCenterY <= monY2) {
261+
selectedMonitor = monitor
262+
break
263+
}
264+
}
265+
266+
if selectedMonitor == nil {
267+
// when no monitor was selected, try fallback to primary monitor
268+
// TODO: ? perhaps select monitor that is "closest" to the window ?
269+
selectedMonitor = glfw.GetPrimaryMonitor()
270+
}
271+
if selectedMonitor == nil {
272+
return m.getPixelRatioOther(window)
273+
}
274+
selectedMonitorMode := selectedMonitor.GetVideoMode()
275+
if selectedMonitorMode == nil {
276+
return m.getPixelRatioOther(window)
277+
}
278+
selectedMonitorWidthMM, _ := selectedMonitor.GetPhysicalSize()
279+
if selectedMonitorWidthMM == 0 {
280+
return m.getPixelRatioOther(window)
281+
}
282+
monitorScreenCoordinatesPerInch := float64(selectedMonitorMode.Width) / (float64(selectedMonitorWidthMM) / 25.4)
283+
284+
dpi := m.pixelsPerScreenCoordinate * monitorScreenCoordinatesPerInch
285+
pixelRatio := dpi / dpPerInch
286+
287+
// Limit the ratio to 1 to avoid rendering a smaller UI in standard resolution monitors.
288+
if pixelRatio < 1.0 {
289+
m.oncePrintPixelRatioLimit.Do(func() {
290+
metrics := map[string]interface{}{
291+
"ppsc": m.pixelsPerScreenCoordinate,
292+
"windowWidthPx": widthPx,
293+
"windowWidthSc": width,
294+
"mscpi": monitorScreenCoordinatesPerInch,
295+
"dpi": dpi,
296+
"pixelRatio": pixelRatio,
297+
"monitorWidthMm": selectedMonitorWidthMM,
298+
"monitorWidthSc": selectedMonitorMode.Width,
299+
}
300+
metricsBytes, _ := json.Marshal(metrics)
301+
fmt.Println("go-flutter: calculated pixelRatio limited to a minimum of 1.0. metrics: " + string(metricsBytes))
302+
})
303+
pixelRatio = 1.0
304+
}
305+
return pixelRatio
306+
}

0 commit comments

Comments
 (0)