@@ -12,7 +12,6 @@ import (
12
12
13
13
"github.com/go-flutter-desktop/go-flutter/embedder"
14
14
"github.com/go-flutter-desktop/go-flutter/internal/execpath"
15
- "github.com/go-flutter-desktop/go-flutter/internal/tasker"
16
15
)
17
16
18
17
// Run executes a flutter application with the provided options.
@@ -105,7 +104,7 @@ func (a *Application) Run() error {
105
104
glfw .WindowHint (glfw .OpenGLProfile , glfw .OpenGLCoreProfile )
106
105
glfw .WindowHint (glfw .OpenGLForwardCompatible , glfw .True )
107
106
108
- if a .config .windowInitialLocations .xpos != 0 {
107
+ if a .config .windowInitialLocation .xpos != 0 {
109
108
// To create the window at a specific position, make it initially invisible
110
109
// using the Visible window hint, set its position and then show it.
111
110
glfw .WindowHint (glfw .Visible , glfw .False )
@@ -115,12 +114,11 @@ func (a *Application) Run() error {
115
114
if err != nil {
116
115
return errors .Wrap (err , "creating glfw window" )
117
116
}
118
- glfw .DefaultWindowHints ()
119
117
defer a .window .Destroy ()
118
+ glfw .DefaultWindowHints ()
120
119
121
- if a .config .windowInitialLocations .xpos != 0 {
122
- a .window .SetPos (a .config .windowInitialLocations .xpos ,
123
- a .config .windowInitialLocations .ypos )
120
+ if a .config .windowInitialLocation .xpos != 0 {
121
+ a .window .SetPos (a .config .windowInitialLocation .xpos , a .config .windowInitialLocation .ypos )
124
122
a .window .Show ()
125
123
}
126
124
@@ -157,6 +155,7 @@ func (a *Application) Run() error {
157
155
158
156
a .engine = embedder .NewFlutterEngine ()
159
157
158
+ // Create a messenger and init plugins
160
159
messenger := newMessenger (a .engine )
161
160
for _ , p := range a .config .plugins {
162
161
err = p .InitPlugin (messenger )
@@ -173,6 +172,16 @@ func (a *Application) Run() error {
173
172
}
174
173
}
175
174
175
+ // Create a TextureRegistry
176
+ texturer := newTextureRegistry (a .engine , a .window )
177
+
178
+ // Create a new eventloop
179
+ eventLoop := newEventLoop (
180
+ glfw .PostEmptyEvent , // Wakeup GLFW
181
+ a .engine .RunTask , // Flush tasks
182
+ )
183
+
184
+ // Set configuration values to engine, with fallbacks to sane defaults.
176
185
if a .config .flutterAssetsPath != "" {
177
186
a .engine .AssetsPath = a .config .flutterAssetsPath
178
187
} else {
@@ -182,7 +191,6 @@ func (a *Application) Run() error {
182
191
}
183
192
a .engine .AssetsPath = filepath .Join (filepath .Dir (execPath ), "flutter_assets" )
184
193
}
185
-
186
194
if a .config .icuDataPath != "" {
187
195
a .engine .IcuDataPath = a .config .icuDataPath
188
196
} else {
@@ -193,7 +201,7 @@ func (a *Application) Run() error {
193
201
a .engine .IcuDataPath = filepath .Join (filepath .Dir (execPath ), "icudtl.dat" )
194
202
}
195
203
196
- // Render callbacks
204
+ // Attach GL callback functions onto the engine
197
205
a .engine .GLMakeCurrent = func () bool {
198
206
a .window .MakeContextCurrent ()
199
207
return true
@@ -219,29 +227,29 @@ func (a *Application) Run() error {
219
227
a .engine .GLProcResolver = func (procName string ) unsafe.Pointer {
220
228
return glfw .GetProcAddress (procName )
221
229
}
230
+ a .engine .GLExternalTextureFrameCallback = texturer .handleExternalTexture
222
231
223
- eventLoop := newEventLoop (
224
- glfw .PostEmptyEvent , // Wakeup GLFW
225
- a .engine .RunTask , // Flush tasks
226
- )
232
+ // Attach TaskRunner callback functions onto the engine
227
233
a .engine .TaskRunnerRunOnCurrentThread = eventLoop .RunOnCurrentThread
228
234
a .engine .TaskRunnerPostTask = eventLoop .PostTask
229
235
236
+ // Attach PlatformMessage callback functions onto the engine
230
237
a .engine .PlatfromMessage = messenger .handlePlatformMessage
231
238
232
- texturer := newRegistry (a .engine , a .window )
233
- a .engine .GLExternalTextureFrameCallback = texturer .handleExternalTexture
234
-
235
239
// Not very nice, but we can only really fix this when there's a pluggable
236
240
// renderer.
237
241
defaultTextinputPlugin .keyboardLayout = a .config .keyboardLayout
238
242
243
+ // Set the glfw window user pointer to point to the FlutterEngine so that
244
+ // callback functions may obtain the FlutterEngine from the glfw window
245
+ // user pointer.
239
246
flutterEnginePointer := uintptr (unsafe .Pointer (a .engine ))
240
247
defer func () {
241
248
runtime .KeepAlive (flutterEnginePointer )
242
249
}()
243
250
a .window .SetUserPointer (unsafe .Pointer (& flutterEnginePointer ))
244
251
252
+ // Start the engine
245
253
result := a .engine .Run (unsafe .Pointer (& flutterEnginePointer ), a .config .vmArguments )
246
254
if result != embedder .ResultSuccess {
247
255
switch result {
@@ -255,40 +263,48 @@ func (a *Application) Run() error {
255
263
os .Exit (1 )
256
264
}
257
265
258
- defaultPlatformPlugin . glfwTasker = tasker . New ()
259
-
260
- m := newWindowManager ()
261
- m . forcedPixelRatio = a . config . forcePixelRatio
262
-
263
- m . glfwRefreshCallback ( a . window )
264
- a .window .SetRefreshCallback (m .glfwRefreshCallback )
265
- a .window .SetPosCallback (m .glfwPosCallback )
266
+ // Setup a new windowManager to handle windows pixel ratio's and pointer
267
+ // devices.
268
+ windowManager := newWindowManager (a . config . forcePixelRatio )
269
+ // force first refresh
270
+ windowManager . glfwRefreshCallback ( a . window )
271
+ // Attach glfw window callbacks for refresh and position changes
272
+ a .window .SetRefreshCallback (windowManager .glfwRefreshCallback )
273
+ a .window .SetPosCallback (windowManager .glfwPosCallback )
266
274
275
+ // TODO: Can this only be done here? Why not in the plugin/glfwPlugin init loop above?
267
276
for _ , p := range a .config .plugins {
268
277
// Extra init call for plugins that satisfy the PluginTexture interface.
269
- if glfwPlugin , ok := p .(PluginTexture ); ok {
270
- err = glfwPlugin .InitPluginTexture (texturer )
278
+ if texturePlugin , ok := p .(PluginTexture ); ok {
279
+ err = texturePlugin .InitPluginTexture (texturer )
271
280
if err != nil {
272
281
return errors .Wrap (err , "failed to initialize texture plugin" + fmt .Sprintf ("%T" , p ))
273
282
}
274
283
}
275
284
}
276
285
286
+ // Attach glfw window callbacks for text input
277
287
a .window .SetKeyCallback (
278
288
func (window * glfw.Window , key glfw.Key , scancode int , action glfw.Action , mods glfw.ModifierKey ) {
279
289
defaultTextinputPlugin .glfwKeyCallback (window , key , scancode , action , mods )
280
290
defaultKeyeventsPlugin .sendKeyEvent (window , key , scancode , action , mods )
281
291
})
282
292
a .window .SetCharCallback (defaultTextinputPlugin .glfwCharCallback )
283
293
294
+ // Attach glfw window callback for iconification
284
295
a .window .SetIconifyCallback (defaultLifecyclePlugin .glfwIconifyCallback )
285
296
286
- a .window .SetCursorEnterCallback (m .glfwCursorEnterCallback )
287
- a .window .SetCursorPosCallback (m .glfwCursorPosCallback )
288
- a .window .SetMouseButtonCallback (m .glfwMouseButtonCallback )
289
- a .window .SetScrollCallback (m .glfwScrollCallback )
297
+ // Attach glfw window callbacks for mouse input
298
+ a .window .SetCursorEnterCallback (windowManager .glfwCursorEnterCallback )
299
+ a .window .SetCursorPosCallback (windowManager .glfwCursorPosCallback )
300
+ a .window .SetMouseButtonCallback (windowManager .glfwMouseButtonCallback )
301
+ a .window .SetScrollCallback (windowManager .glfwScrollCallback )
302
+
303
+ // Shutdown the engine if we return from this function (on purpose or panic)
290
304
defer a .engine .Shutdown ()
291
305
306
+ // Handle events until the window indicates we should stop. An event may tell the window to stop, in which case
307
+ // we'll exit on next iteration.
292
308
for ! a .window .ShouldClose () {
293
309
eventLoop .WaitForEvents (func (duration float64 ) {
294
310
glfw .WaitEventsTimeout (duration )
@@ -297,6 +313,9 @@ func (a *Application) Run() error {
297
313
messenger .engineTasker .ExecuteTasks ()
298
314
}
299
315
316
+ // TODO: What if the window indicates to stop, but there are tasks left on
317
+ // the queue?
318
+
300
319
fmt .Println ("go-flutter: closing application" )
301
320
302
321
return nil
0 commit comments