2

I wrote a simple clock program that worked fine under winxp. When run under linux it behaves weirdly. The program draws a label with the text set to "00:00", and then updates it once per second with the same text.

To run the program I specify a font size in the command line. If I set it really small (200.0 and lower for my screen, it may be different to yours) it works fine. If I set it too big and the text doesn't fit the screen (500.0 in my case), it works fine as well. However when I pick the size in the middle (say, 300.0 or 400.0) it displays "00:00", however once updateClock sets the text it becomes " :00" on the screen (it's not shifted to the left, just the two leading zeroes are replaced with empty space)

Here is the simplified code that demonstrates the problem:

import System.Environment
import System.Time
import System.Locale
import Data.Time
import Graphics.Rendering.Cairo
import Graphics.UI.Gtk hiding (fill)
import Graphics.UI.Gtk.Gdk.EventM

parseArgs [str] = case reads str::[(Double, String)] of
  [(number, "")] -> Just number
  _ -> Nothing 

parseArgs _ = Nothing

updateClock labl = do
  labelSetText labl "00:00"
  return True


main = do
  args <- getArgs
  case (parseArgs args) of
    Just size -> 
      showGui size
    _ -> putStrLn "\nUsage: test fontSize"

  where
    showGui size = do
      initGUI
      window <- windowNew
      onDestroy window mainQuit

      window `on` keyPressEvent $ tryEvent $ do
        "Escape" <- eventKeyName
        liftIO mainQuit

      labl <- labelNew Nothing
      fd <- fontDescriptionNew

      containerAdd window labl

      windowFullscreen window

      fontDescriptionSetSize fd size
      widgetModifyFont labl $ Just fd

      timeoutAdd (updateClock labl >> return True) 1000

      widgetShowAll window
      mainGUI

I use libghc-gtk-dev 0.12.4-3,

ghc 7.6.3

and libgtk2.0-0 2.24.23-0ubuntu1.2.

I compile with ghc --make --threaded

I'm having trouble figuring out what's going on here. I would appreciate any help

Anton
  • 279
  • 2
  • 9
  • 3
    As I understand it, all GTK calls have to go in the same thread. Does wrapping your timer callback in `postInGuiThread` fix the problem? – MathematicalOrchid Apr 13 '15 at 08:26
  • I don't know what postInGuiThread is (can't find it in the docs), but replacing labelSetText labl "00:00" with postGUIAsync $ labelSetText labl "00:00" has no effect. Still threading issue is the only viable hypothesis right now, I'll look more into that. Thank you for your help! – Anton Apr 13 '15 at 20:42
  • I wasn't sure of the precise function name off the top of my head, and I can't seem to lay my hands on the Gtk2hs documentation right now... – MathematicalOrchid Apr 14 '15 at 08:10
  • 1
    `timeoutAdd` is fine; the callback you hand it will run on the `mainGUI` thread, and assuming you use the `timeoutAdd` from the `gtk` package (and not the `timeoutAdd` from the `glib` package) will hold the GUI lock. This is a pretty bizarre problem -- you are not doing anything obviously weird, so it should Just Work. Haven't looked into it in detail yet, though. – Daniel Wagner Apr 14 '15 at 17:01
  • 1
    I dunno. I can't reproduce your problem on my machine (also Linux, though different versions of everything). It's probably just a bug in gtk. – Daniel Wagner Apr 14 '15 at 23:22

0 Answers0