Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Window is not destroyed when event loop stops, only when program exits #105

Open
miguel-negrao opened this issue Sep 30, 2021 · 0 comments · May be fixed by #117
Open

Window is not destroyed when event loop stops, only when program exits #105

miguel-negrao opened this issue Sep 30, 2021 · 0 comments · May be fixed by #117

Comments

@miguel-negrao
Copy link

In the code below, after clicking the close button of the window, the window will not close, staying open while the program is still running. Only after pressing enter on the command prompt, unblocking the getLine function, does the window close when the process exits. For my use case I need the window to close when the "run" function returns.

{-# LANGUAGE OverloadedLabels  #-}
{-# LANGUAGE OverloadedLists   #-}
{-# LANGUAGE OverloadedStrings #-}

module Main where

import           Data.Function                  ( (&) )
import           Data.Text                      ( Text )
import           Pipes
import qualified Pipes.Extras                  as Pipes
import           Control.Monad                  ( void )

import           GI.Gtk                         ( Label(..)
                                                , Window(..)
                                                )
import           GI.Gtk.Declarative
import           GI.Gtk.Declarative.App.Simple

type State = ()

data Event = Closed

view' :: State -> AppView Window Event
view' _ =
  bin
      Window
      [ #title := "Hello"
      , on #deleteEvent (const (True, Closed))
      , #widthRequest := 400
      , #heightRequest := 300
      ]
    $ widget Label [#label := "Nothing here yet."]

update' :: State -> Event -> Transition State Event
update' _ Closed      = Exit

main' :: IO ()
main' = void $ run App { view         = view'
                      , update       = update'
                      , inputs       = []
                      , initialState = ()
                      }

main = do
    main'
    getLine

In the following gi-gtk program that does not happen:

{-# LANGUAGE OverloadedStrings, OverloadedLabels #-}

{-# OPTIONS_GHC -fno-warn-unused-do-bind #-}

{- Hello World example of GTK+ documentation. For information please refer to README -}

module Main where

-- import qualified Data.Text as T
import Data.Text ()

import qualified GI.Gio as Gio
import qualified GI.Gtk as Gtk
import Data.GI.Base
import Control.Concurrent

printHello :: IO ()
printHello = putStrLn "Hello, World!"

activateApp :: Gtk.Application -> IO ()
activateApp app = do
  w <- new Gtk.ApplicationWindow [ #application := app
                                 , #title := "Haskell Gi - Examples - Hello World"
                                 , #defaultHeight := 200
                                 , #defaultWidth := 200
                                 ]

  bbox <- new Gtk.ButtonBox [ #orientation := Gtk.OrientationHorizontal ]
  #add w bbox
  
  btn <- new Gtk.Button [ #label := "Hello World!"]
  on btn #clicked printHello
  --on btn #clicked $ Gtk.widgetDestroy w
  #add bbox btn
  
  #showAll w
  return ()

main' :: IO ()
main' = do
  app <- new Gtk.Application [ #applicationId := "haskell-gi.examples.hello-world"
                             , #flags := [ Gio.ApplicationFlagsFlagsNone ]
                             ]
  on app #activate $ activateApp app
  Gio.applicationRun app Nothing
  return ()

main = do
    main'
    getLine
rvl added a commit to rvl/gi-gtk-declarative that referenced this issue Sep 17, 2024
Gtk doesn't destroy its windows when `gtk_main_exit()` is called. It
relies on the X server to DestroyAll resources when the app's
connection to the X server is closed.

This can result in zombie windows for programs which don't immediately
exit after the Gtk main loop finishes.

We solve it by explicitly destroying the window widget in response to
the `Exit` transition.

Also, for gtk_widget_destroy() to have any effect, the Gtk main loop
needs to be still running. Thankfully, the `run` function provided by
`GI.Gtk.Declarative.App.Simple` will ensure that is the case.

Resolves owickstrom#105
@rvl rvl linked a pull request Sep 17, 2024 that will close this issue
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

1 participant