Как я могу безопасно использовать WebKitGTK из разветвленной ветки?
Я пытаюсь сделать простое приложение на Haskell, используя GTK3 и WebKit. Этот код создает и показывает окно, содержащее WebView
внутри, которое отображает случайное число при каждом нажатии клавиши.
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
Когда я запускаю его в GHCi (7.8.3), он работает нормально. Однако, когда я запускаю его снова, не выходя из GHCi, WebView
никогда ничего не показывает - просто белая область. Это расстраивает, так как мне нравится возиться с кодом в GHCi.
Конечно, все работает отлично, если я не использую forkOS
и запустить все это в главном потоке. В чем причина этого ограничения (я думал, что все функции GTK рассматривали "основной" поток как тот, в котором initGUI
назывался), и можно ли это как-то побороть?
1 ответ
Если это работает как python(я не знаю haskell), вы должны сохранить gtk main loop
в main thread
,
В вашем втором потоке вызовите g_idle_add с обратным вызовом, чтобы внести изменения с помощью gtk, и transport data between
ваш second thread
, а также gtk
, Вы должны начать свой неосновной поток до gtk main
так что это не заблокировано.
Я уверен, что есть обязательство g_idle_add
в хаскеле. Существует также g_timeout_add, который работает для этого тоже.
Это все связано с тем, что gtk не является потокобезопасным.