owickstrom / gi-gtk-declarative

Declarative GTK+ programming in Haskell
https://owickstrom.github.io/gi-gtk-declarative/
288 stars 35 forks source link

Realize signal fails to trigger. #46

Open joecrayne opened 5 years ago

joecrayne commented 5 years ago

Below is the same program written in vanilla gi-gtk and then again using gi-gtk-declarative. The vanilla gtk behaves as expected, outputting "Realized!" to the console. The declarative version fails to trigger the realize signal.

Working vanilla version:

{-# LANGUAGE OverloadedStrings, OverloadedLabels #-}
import GI.Gtk as Gtk hiding (main)
import qualified GI.Gtk as Gtk

onRealize :: IO ()
onRealize = putStrLn "Realized!"

main = do
    _ <- Gtk.init Nothing

    let mkChild = do
            gl <- gLAreaNew
            _ <- on gl #realize onRealize
            return gl

    window <- do
        w <- windowNew WindowTypeToplevel
        windowSetDefaultSize    w 600 600
        windowSetTitle          w "This triggers realize signal."
        _ <- on w #deleteEvent $ \_ -> mainQuit >> return True
        child <- mkChild
        containerAdd w child
        return w

    widgetShowAll window
    Gtk.main

Non-working declarative version:

{-# LANGUAGE OverloadedStrings, OverloadedLists, OverloadedLabels, LambdaCase #-}
import qualified GI.Gtk as Gtk
import GI.Gtk.Declarative
import GI.Gtk.Declarative.EventSource
import GI.Gtk.Declarative.State

onRealize :: IO Bool
onRealize = putStrLn "Realized!" >> return True

main = do
    _ <- Gtk.init Nothing

    let child = widget Gtk.GLArea [onM #realize $ \_ -> onRealize]

    window <- do
        let w :: Bin Gtk.Window Bool
            w = bin Gtk.Window
                    [ #title := "This fails to trigger realize signal."
                    , #widthRequest := 600
                    , #heightRequest := 600
                    , on #deleteEvent $ \_ -> (True,False)
                    ]
                    child
        someState <- create w
        sub <- subscribe w someState $ \case
            False -> Gtk.mainQuit
            True  -> return ()
        someStateWidget someState
    Gtk.widgetShowAll window
    Gtk.main

I first encountered the problem while using the gi-gtk-declarative-app-simple framework as this seems to be the only documented way to use gi-gtk-declarative. (Is that a bug?) But I removed that layer while trying to debug this issue.

owickstrom commented 5 years ago

This is strange. I'm not too familiar with the realize signal and how it should work. I'm thinking that it might be some ordering problem with the showing of widgets (perhaps containers), but I don't know. Are you getting the same problem with widgets other than GLArea?

joecrayne commented 5 years ago

From examples for GLArea, the ::realize signal is the logical/typical place to set up the rendering GL state that does not change much so that ::render can more efficiently render the scene and be called frequently for animations. It's the only widget I have in my project currently, so no, I'm not getting the problem otherwise, but that doesn't mean much. I wanted to use gtk over glfw or something more graphics-oriented merely for the freedom of using widgets later if I want them.