Skip to content

Commit 8515fb3

Browse files
committed
Calculate pixel_ratio based on users' display
1 parent 3c03ddd commit 8515fb3

File tree

4 files changed

+73
-25
lines changed

4 files changed

+73
-25
lines changed

example/simpleDemo/main.go

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,6 @@ func main() {
3636
gutter.ApplicationICUDataPath(dir + "/icudtl.dat"),
3737
gutter.ApplicationWindowDimension(initialApplicationWidth, initialApplicationHeight),
3838
gutter.OptionWindowInitializer(setIcon),
39-
gutter.OptionPixelRatio(1.2),
4039
gutter.OptionVMArguments([]string{"--dart-non-checked-mode", "--observatory-port=50300"}),
4140
gutter.OptionAddPluginReceiver(ownPlugin, "plugin_demo"),
4241
// Default keyboard is Qwerty, if you want to change it, you can check keyboard.go in gutter package.

flutter/flutter.go

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,6 @@ type EngineOpenGL struct {
5959
FPlatfromMessage func(message *PlatformMessage, window unsafe.Pointer) bool
6060

6161
// Engine arguments
62-
PixelRatio float64
6362
AssetsPath string
6463
IcuDataPath string
6564
}

gutter.go

Lines changed: 70 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package gutter
22

33
import (
44
"encoding/json"
5+
"fmt"
56
"log"
67
"time"
78
"unsafe"
@@ -10,6 +11,9 @@ import (
1011
"github.com/go-gl/glfw/v3.2/glfw"
1112
)
1213

14+
// dpPerInch defines the amount of display pixels per inch as defined for Flutter.
15+
const dpPerInch = 160.0
16+
1317
// Run executes a flutter application with the provided options.
1418
// given limitations this method must be called by the main function directly.
1519
func Run(options ...Option) (err error) {
@@ -76,18 +80,28 @@ func glfwCursorPositionCallbackAtPhase(
7680

7781
func glfwMouseButtonCallback(window *glfw.Window, key glfw.MouseButton, action glfw.Action, mods glfw.ModifierKey) {
7882

79-
if key == glfw.MouseButton1 && action == glfw.Press {
83+
if key == glfw.MouseButton1 {
8084
x, y := window.GetCursorPos()
81-
glfwCursorPositionCallbackAtPhase(window, flutter.KDown, x, y)
82-
window.SetCursorPosCallback(func(window *glfw.Window, x float64, y float64) {
83-
glfwCursorPositionCallbackAtPhase(window, flutter.KMove, x, y)
84-
})
85-
}
8685

87-
if key == glfw.MouseButton1 && action == glfw.Release {
88-
x, y := window.GetCursorPos()
89-
glfwCursorPositionCallbackAtPhase(window, flutter.KUp, x, y)
90-
window.SetCursorPosCallback(nil)
86+
// recalculate x and y from screen cordinates to pixels
87+
widthPx, _ := window.GetFramebufferSize()
88+
width, _ := window.GetSize()
89+
pixelsPerScreenCoordinate := float64(widthPx) / float64(width)
90+
x = x * pixelsPerScreenCoordinate
91+
y = y * pixelsPerScreenCoordinate
92+
93+
if action == glfw.Press {
94+
glfwCursorPositionCallbackAtPhase(window, flutter.KDown, x, y)
95+
window.SetCursorPosCallback(func(window *glfw.Window, x float64, y float64) {
96+
glfwCursorPositionCallbackAtPhase(window, flutter.KMove, x, y)
97+
})
98+
}
99+
100+
if action == glfw.Release {
101+
x, y := window.GetCursorPos()
102+
glfwCursorPositionCallbackAtPhase(window, flutter.KUp, x, y)
103+
window.SetCursorPosCallback(nil)
104+
}
91105
}
92106

93107
}
@@ -164,17 +178,31 @@ func glfwKey(keyboardLayout KeyboardShortcuts) func(w *glfw.Window, key glfw.Key
164178
}
165179
}
166180

167-
func glfwWindowSizeCallback(window *glfw.Window, width int, height int) {
168-
169-
index := *(*int)(window.GetUserPointer())
170-
flutterOGL := flutter.SelectEngine(index)
181+
func newGLFWFramebufferSizeCallback(pixelRatio float64, monitorScreenCoordinatesPerInch float64) func(*glfw.Window, int, int) {
182+
return func(window *glfw.Window, widthPx int, heightPx int) {
183+
index := *(*int)(window.GetUserPointer())
184+
flutterOGL := flutter.SelectEngine(index)
185+
186+
if pixelRatio == 0 {
187+
width, _ := window.GetSize()
188+
pixelsPerScreenCoordinate := float64(widthPx) / float64(width)
189+
dpi := pixelsPerScreenCoordinate * monitorScreenCoordinatesPerInch
190+
pixelRatio = dpi / dpPerInch
191+
192+
// Limit the ratio to 1 to avoid rendering a smaller UI in standard resolution monitors.
193+
if pixelRatio < 1.0 {
194+
fmt.Println("calculated pixelRatio limited to a minimum of 1.0")
195+
pixelRatio = 1.0
196+
}
197+
}
171198

172-
event := flutter.WindowMetricsEvent{
173-
Width: width,
174-
Height: height,
175-
PixelRatio: flutterOGL.PixelRatio,
199+
event := flutter.WindowMetricsEvent{
200+
Width: widthPx,
201+
Height: heightPx,
202+
PixelRatio: pixelRatio,
203+
}
204+
flutterOGL.EngineSendWindowMetricsEvent(event)
176205
}
177-
flutterOGL.EngineSendWindowMetricsEvent(event)
178206
}
179207

180208
func glfwCharCallback(w *glfw.Window, char rune) {
@@ -211,7 +239,6 @@ func runFlutter(window *glfw.Window, c config) *flutter.EngineOpenGL {
211239
flutterOGL.FMakeResourceCurrent = func(v unsafe.Pointer) bool {
212240
return false
213241
}
214-
flutterOGL.PixelRatio = c.PixelRatio
215242

216243
// PlatformMessage
217244
flutterOGL.FPlatfromMessage = func(platMessage *flutter.PlatformMessage, window unsafe.Pointer) bool {
@@ -242,8 +269,9 @@ func runFlutter(window *glfw.Window, c config) *flutter.EngineOpenGL {
242269
panic("Couldn't launch the FlutterEngine")
243270
}
244271

272+
glfwFramebufferSizeCallback := newGLFWFramebufferSizeCallback(c.PixelRatio, getScreenCoordinatesPerInch())
245273
width, height := window.GetFramebufferSize()
246-
glfwWindowSizeCallback(window, width, height)
274+
glfwFramebufferSizeCallback(window, width, height)
247275
var glfwKeyCallback func(w *glfw.Window, key glfw.Key, scancode int, action glfw.Action, mods glfw.ModifierKey)
248276

249277
if c.KeyboardLayout != nil {
@@ -253,12 +281,32 @@ func runFlutter(window *glfw.Window, c config) *flutter.EngineOpenGL {
253281
}
254282

255283
window.SetKeyCallback(glfwKeyCallback)
256-
window.SetFramebufferSizeCallback(glfwWindowSizeCallback)
284+
window.SetFramebufferSizeCallback(glfwFramebufferSizeCallback)
257285
window.SetMouseButtonCallback(glfwMouseButtonCallback)
258286
window.SetCharCallback(glfwCharCallback)
259287
return flutterOGL
260288
}
261289

290+
// getScreenCoordinatesPerInch returns the number of screen coordinates per
291+
// inch for the main monitor. If the information is unavailable it returns
292+
// a default value that assumes that a screen coordinate is one dp.
293+
func getScreenCoordinatesPerInch() float64 {
294+
// TODO: multi-monitor support (#74)
295+
primaryMonitor := glfw.GetPrimaryMonitor()
296+
if primaryMonitor == nil {
297+
return dpPerInch
298+
}
299+
primaryMonitorMode := primaryMonitor.GetVideoMode()
300+
if primaryMonitorMode == nil {
301+
return dpPerInch
302+
}
303+
primaryMonitorWidthMM, _ := primaryMonitor.GetPhysicalSize()
304+
if primaryMonitorWidthMM == 0 {
305+
return dpPerInch
306+
}
307+
return float64(primaryMonitorMode.Width) / (float64(primaryMonitorWidthMM) / 25.4)
308+
}
309+
262310
// Update the TextInput with the current state
263311
func updateEditingState(window *glfw.Window) {
264312

option.go

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,9 @@ func OptionWindowInitializer(ini func(*glfw.Window) error) Option {
6666
}
6767
}
6868

69-
// OptionPixelRatio specify the scale factor for the physical screen.
69+
// OptionPixelRatio forces the the scale factor for the screen.
70+
// By default, go-flutter will calculate the correct pixel ratio for the user, based
71+
// on their monitor DPI. Setting this option is not advised.
7072
func OptionPixelRatio(ratio float64) Option {
7173
return func(c *config) {
7274
c.PixelRatio = ratio

0 commit comments

Comments
 (0)