Sto provando a creare una semplice app in Haskell usando GTK3 e WebKit. Questo codice crea e mostra una finestra contenente uno WebView
all'interno, che visualizza un numero casuale ogni volta che viene premuto un tasto.Come posso utilizzare WebKitGTK in modo sicuro da un thread a forcella?
import Control.Monad.Trans (lift)
import Control.Concurrent (forkOS)
import System.Random (randomIO)
import Graphics.UI.Gtk -- gtk3
import Graphics.UI.Gtk.WebKit.WebView -- webkitgtk3
main = forkOS $ do
-- Init GTK.
initGUI
-- Create a window which would finish the GTK loop
-- after being closed.
window <- windowNew
window `after` objectDestroy $
mainQuit
-- Create a WebView inside.
webView <- webViewNew
set window [containerChild := webView]
-- Make the WebView display a random number on key press.
webView `on` keyReleaseEvent $ lift $ do
x <- randomIO :: IO Int
webViewLoadString webView (show x) Nothing Nothing ""
return True
-- Run GTK.
widgetShowAll window
mainGUI
Quando lo eseguo in GHCi (7.8.3), funziona correttamente. Tuttavia, quando lo eseguo di nuovo senza uscire da GHCi, lo WebView
non mostra mai nulla - solo un'area bianca. Questo è sconvolgente, perché mi piace armeggiare con il codice in GHCi.
Ovviamente, tutto funziona perfettamente se non utilizzo forkOS
ed eseguo il tutto nel thread principale. Qual è la ragione di questa limitazione (ho pensato che tutte le funzioni GTK consideravano il thread "principale" quello in cui è stato chiamato lo initGUI
) e può essere superato in qualche modo?
Potrebbe essere necessario eseguire esplicitamente il thread associato con 'Control.Concurrent.runInBoundThread'. – vivian
@vivian: potresti ampliarlo? Ho pensato a questo, ma aggiungendo 'runInBoundThread' poco prima o dopo' forkOS' non ha aiutato, e l'aggiunta di 'print = << isCurrentThreadBound' ha dimostrato che il thread era già limitato. – Artyom
Funziona come previsto al di fuori di GHCi? Probabilmente alcuni loop di eventi vengono arrestati e non riavviati quando lo si esegue due volte all'interno di un singolo processo. –