File: Embedded.hs

package info (click to toggle)
haskell-gtk 0.15.7-1
  • links: PTS, VCS
  • area: main
  • in suites: bookworm
  • size: 3,964 kB
  • sloc: haskell: 3,346; ansic: 826; makefile: 161
file content (87 lines) | stat: -rw-r--r-- 2,520 bytes parent folder | download | duplicates (9)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
-- Use GtkSocket and GtkPlug for cross-process embedded.
-- Just startup program, press 'm' to create tab with new button.
-- Click button for hang to simulate plug hanging process,
-- but socket process still running, can switch to other tab.

module Main where

import System.Process
import System.Environment
import System.Directory
import System.FilePath ((</>))
import Control.Monad
import Control.Monad.Trans
import Control.Concurrent
import Data.Text (unpack)

import Graphics.UI.Gtk
import Graphics.UI.Gtk.Gdk.DrawWindow
import Graphics.UI.Gtk.Gdk.EventM

-- | Main.
main :: IO ()
main = do
  -- Get program arguments.
  args <- getArgs

  case args of
    -- Entry plug main when have two arguments.
    [id] -> plugMain (toNativeWindowId $ read id :: NativeWindowId) -- get GtkSocket id
    -- Othersise entry socket main when no arguments.
    _ -> socketMain

-- | GtkSocekt main.
socketMain :: IO ()
socketMain = do
  initGUI

  -- Create top-level window.
  window <- windowNew
  windowSetPosition window WinPosCenter
  windowSetDefaultSize window 600 400
  set window [windowTitle := "Press `m` to new tab, press `q` exit."]
  on window objectDestroy mainQuit

  -- Create notebook to contain GtkSocekt.
  notebook <- notebookNew
  window `containerAdd` notebook

  -- Handle key press.
  window `on` keyPressEvent $ tryEvent $ do
    keyName <- eventKeyName
    liftIO $
      case unpack keyName of
        "m" -> do
               -- Create new GtkSocket.
               socket <- socketNew
               widgetShow socket                          -- must show before add GtkSocekt to container
               notebookAppendPage notebook socket "Tab"   -- add to GtkSocekt notebook
               id <- socketGetId socket                    -- get GtkSocket id

               -- Fork process to add GtkPlug into GtkSocekt.
               path <- liftM2 (</>) getCurrentDirectory getProgName -- get program full path
               runCommand $ path ++ " " ++ (show $ fromNativeWindowId id) -- don't use `forkProcess`
               return ()
        "q" -> mainQuit          -- quit

  widgetShowAll window

  mainGUI

-- | GtkPlug main.
plugMain :: NativeWindowId -> IO ()
plugMain id = do
  initGUI

  plug <- plugNew $ Just id
  on plug objectDestroy $ mainQuit

  button <- buttonNewWithLabel "Click me to hang."
  plug `containerAdd` button

  -- Simulate a plugin hanging to see if it blocks the outer process.
  on button buttonActivated $ threadDelay 5000000

  widgetShowAll plug

  mainGUI