diff --git a/README.md b/README.md
--- a/README.md
+++ b/README.md
@@ -6,7 +6,7 @@
 
 ## Screenshots
 
-<img src="http://i.imgur.com/QOMXSwo.jpg" width="600" alt="GUI" title= "GUI" />
+![GUI showing Sintel from the Blender Foundation](https://i.imgur.com/SLse3s9.jpg)
 
 ## Documentation
 
@@ -18,23 +18,24 @@
 
 ```bash
 # Install Git
+# Install XQuartz (https://www.xquartz.org/) if using Mac OSX or macOS
+# Install GTK+ 3.* (https://www.gtk.org/download/index.php)
 # Install Haskell
 # Install Haksell Stack
 # Install ExifTool
 git clone https://github.com/lettier/movie-monad.git
 cd movie-monad/
 stack setup
-stack install --dependencies-only
-haskell-gi -o lib/gi-gdkx11/GdkX11.overrides -O lib/gi-gdkx11 GdkX11-3.0
-haskell-gi -o lib/gi-xlib/xlib.overrides     -O lib/gi-xlib xlib
-stack build
 stack install
 stack exec -- movie-monad
+# Or just `movie-monad` if `stack path | grep local-bin-path` is in your `echo $PATH`
 ```
 
 ## License
 
 See [LICENSE](LICENSE).
+
+## Copyright
 
 (C) 2017 David Lettier  
 [lettier.com](http://www.lettier.com/)
diff --git a/movie-monad.cabal b/movie-monad.cabal
--- a/movie-monad.cabal
+++ b/movie-monad.cabal
@@ -1,5 +1,5 @@
 name:                 movie-monad
-version:              0.0.0.0
+version:              0.0.1.0
 synopsis:             Plays videos using GStreamer and GTK+.
 description:          Desktop video player that uses GStreamer and GTK+.
 homepage:             https://github.com/lettier/movie-monad
@@ -32,13 +32,14 @@
                       , process == 1.4.*
                       , MissingH == 1.4.*
                       , haskell-gi-base == 0.20.*
+                      , gi-xlib == 2.0.*
                       , gi-gobject == 2.0.*
-                      , gi-gst == 1.0.*
-                      , gi-gtk == 3.0.*
                       , gi-glib == 2.0.*
-                      , gi-xlib == 0.1.6.*
+                      , gi-gdkx11 == 3.0.*
                       , gi-gstvideo == 1.0.*
-                      , gi-gdkx11 == 0.3.*
+                      , gi-gdk == 3.0.*
+                      , gi-gst == 1.0.*
+                      , gi-gtk == 3.0.*
   ghc-options:        -threaded -with-rtsopts=-N -Wall
   other-modules:      Paths_movie_monad
   hs-source-dirs:     ./src/
diff --git a/src/Main.hs b/src/Main.hs
--- a/src/Main.hs
+++ b/src/Main.hs
@@ -15,17 +15,20 @@
 import System.Exit
 import Control.Monad
 import Control.Exception
+import Text.Read
+import Data.IORef
 import Data.Maybe
 import Data.Int
 import Data.Text
-import Data.String.Utils
 import Data.GI.Base
+import Data.GI.Base.Signals
 import Data.GI.Base.Properties
 import GI.GLib
 import GI.GObject
 import qualified GI.Gtk
 import GI.Gst
 import GI.GstVideo
+import GI.Gdk
 import GI.GdkX11
 import Paths_movie_monad
 
@@ -50,99 +53,49 @@
   onOffSwitch <- builderGetObject GI.Gtk.Switch builder "on-off-switch"
   volumeButton <- builderGetObject GI.Gtk.VolumeButton builder "volume-button"
   desiredVideoWidthComboBox <- builderGetObject GI.Gtk.ComboBoxText builder "desired-video-width-combo-box"
+  fullscreenButton <- builderGetObject GI.Gtk.Button builder "fullscreen-button"
   errorMessageDialog <- builderGetObject GI.Gtk.MessageDialog builder "error-message-dialog"
   aboutButton <- builderGetObject GI.Gtk.Button builder "about-button"
   aboutDialog <- builderGetObject GI.Gtk.AboutDialog builder "about-dialog"
 
   playbin <- fromJust <$> GI.Gst.elementFactoryMake "playbin" (Just "MultimediaPlayer")
 
-  _ <- GI.Gtk.onWidgetRealize drawingArea $ do
-    gdkWindow <- fromJust <$> GI.Gtk.widgetGetWindow drawingArea
-    x11Window <- GI.Gtk.unsafeCastTo GI.GdkX11.X11Window gdkWindow
-
-    xid <- GI.GdkX11.x11WindowGetXid x11Window
-    let xid' = fromIntegral xid :: CUIntPtr
-
-    GI.GstVideo.videoOverlaySetWindowHandle (GstElement playbin) xid'
-
-  _ <- GI.Gtk.onFileChooserButtonFileSet fileChooserButton $ do
-    _ <- GI.Gst.elementSetState playbin GI.Gst.StateNull
-
-    filename <- fromJust <$> GI.Gtk.fileChooserGetFilename fileChooserButton
-    let uri = "file://" ++ filename
-
-    volume <- GI.Gtk.scaleButtonGetValue volumeButton
-    Data.GI.Base.Properties.setObjectPropertyDouble playbin "volume" volume
-    Data.GI.Base.Properties.setObjectPropertyString playbin "uri" (Just $ pack uri)
-
-    desiredVideoWidth <- getDesiredVideoWidth desiredVideoWidthComboBox
-    (success, width, height) <- getWindowSize desiredVideoWidth filename
-
-    if success
-      then do
-        _ <- GI.Gst.elementSetState playbin GI.Gst.StatePlaying
-        GI.Gtk.switchSetActive onOffSwitch True
-        setWindowSize width height fileChooserButton drawingArea window
-      else do
-        _ <- GI.Gst.elementSetState playbin GI.Gst.StatePaused
-        GI.Gtk.switchSetActive onOffSwitch False
-        resetWindowSize desiredVideoWidth fileChooserButton drawingArea window
-        _ <- GI.Gtk.onDialogResponse errorMessageDialog (\ _ -> GI.Gtk.widgetHide errorMessageDialog)
-        void $ GI.Gtk.dialogRun errorMessageDialog
-
-  _ <- GI.Gtk.onSwitchStateSet onOffSwitch $ \ switchOn -> do
-    if switchOn
-      then void $ GI.Gst.elementSetState playbin GI.Gst.StatePlaying
-      else void $ GI.Gst.elementSetState playbin GI.Gst.StatePaused
-    return switchOn
-
-  _ <- GI.Gtk.onScaleButtonValueChanged volumeButton $
-      \ volume -> void $ Data.GI.Base.Properties.setObjectPropertyDouble playbin "volume" volume
+  isWindowFullScreenRef <- newIORef False
 
-  seekScaleHandlerId <- GI.Gtk.onRangeValueChanged seekScale $ do
-    (couldQueryDuration, duration) <- GI.Gst.elementQueryDuration playbin GI.Gst.FormatTime
+  _ <- GI.Gtk.onWidgetRealize drawingArea $ onDrawingAreaRealize drawingArea playbin fullscreenButton
 
-    when couldQueryDuration $ do
-      percentage' <- GI.Gtk.rangeGetValue seekScale
-      let percentage = percentage' / 100.0
-      let position = fromIntegral (round ((fromIntegral duration :: Double) * percentage) :: Int) :: Int64
-      void $ GI.Gst.elementSeekSimple playbin GI.Gst.FormatTime [ GI.Gst.SeekFlagsFlush ] position
+  _ <- GI.Gtk.onFileChooserButtonFileSet fileChooserButton $
+    onFileChooserButtonFileSet
+      playbin
+      fileChooserButton
+      volumeButton
+      isWindowFullScreenRef
+      desiredVideoWidthComboBox
+      onOffSwitch
+      fullscreenButton
+      drawingArea
+      window
+      errorMessageDialog
 
-  _ <- GI.GLib.timeoutAddSeconds GI.GLib.PRIORITY_DEFAULT 1 $ do
-    (couldQueryDuration, duration) <- GI.Gst.elementQueryDuration playbin GI.Gst.FormatTime
-    (couldQueryPosition, position) <- GI.Gst.elementQueryPosition playbin GI.Gst.FormatTime
+  _ <- GI.Gtk.onSwitchStateSet onOffSwitch (onSwitchStateSet playbin)
 
-    let percentage =
-          if couldQueryDuration && couldQueryPosition && duration > 0
-            then 100.0 * (fromIntegral position / fromIntegral duration :: Double)
-            else 0.0
+  _ <- GI.Gtk.onScaleButtonValueChanged volumeButton (onScaleButtonValueChanged playbin)
 
-    GI.GObject.signalHandlerBlock seekScale seekScaleHandlerId
-    GI.Gtk.rangeSetValue seekScale percentage
-    GI.GObject.signalHandlerUnblock seekScale seekScaleHandlerId
+  seekScaleHandlerId <- GI.Gtk.onRangeValueChanged seekScale (onRangeValueChanged playbin seekScale)
 
-    return True
+  _ <- GI.GLib.timeoutAddSeconds GI.GLib.PRIORITY_DEFAULT 1 (updateSeekScale playbin seekScale seekScaleHandlerId)
 
-  _ <- GI.Gtk.onComboBoxChanged desiredVideoWidthComboBox $ do
-    filename' <- GI.Gtk.fileChooserGetFilename fileChooserButton
-    let filename = fromMaybe "" filename'
+  _ <- GI.Gtk.onComboBoxChanged desiredVideoWidthComboBox $
+      onComboBoxChanged fileChooserButton desiredVideoWidthComboBox drawingArea window
 
-    desiredVideoWidth <- getDesiredVideoWidth desiredVideoWidthComboBox
-    (success, width, height) <- getWindowSize desiredVideoWidth filename
+  _ <- GI.Gtk.onWidgetButtonReleaseEvent fullscreenButton
+      (onFullscreenButtonRelease isWindowFullScreenRef desiredVideoWidthComboBox fileChooserButton window)
 
-    if success
-      then setWindowSize width height fileChooserButton drawingArea window
-      else resetWindowSize desiredVideoWidth fileChooserButton drawingArea window
+  _ <- GI.Gtk.onWidgetWindowStateEvent window (onWidgetWindowStateEvent isWindowFullScreenRef)
 
-  _ <- GI.Gtk.onWidgetButtonReleaseEvent aboutButton $ \ _ -> do
-    _ <- GI.Gtk.onDialogResponse aboutDialog (\ _ -> GI.Gtk.widgetHide aboutDialog)
-    void $ GI.Gtk.dialogRun aboutDialog
-    return True
+  _ <- GI.Gtk.onWidgetButtonReleaseEvent aboutButton (onAboutButtonRelease aboutDialog)
 
-  _ <- GI.Gtk.onWidgetDestroy window $ do
-    _ <- GI.Gst.elementSetState playbin GI.Gst.StateNull
-    _ <- GI.Gst.objectUnref playbin
-    GI.Gtk.mainQuit
+  _ <- GI.Gtk.onWidgetDestroy window (onWindowDestroy playbin)
 
   GI.Gtk.widgetShowAll window
   GI.Gtk.main
@@ -157,7 +110,210 @@
   fromJust <$> GI.Gtk.builderGetObject builder (pack objectId) >>=
     GI.Gtk.unsafeCastTo objectTypeClass
 
-getVideoInfo :: Prelude.String -> Prelude.String -> IO (Bool, Prelude.String)
+onDrawingAreaRealize ::
+  GI.Gtk.Widget ->
+  GI.Gst.Element ->
+  GI.Gtk.Button ->
+  GI.Gtk.WidgetRealizeCallback
+onDrawingAreaRealize drawingArea playbin fullscreenButton = do
+  gdkWindow <- fromJust <$> GI.Gtk.widgetGetWindow drawingArea
+  x11Window <- GI.Gtk.unsafeCastTo GI.GdkX11.X11Window gdkWindow
+
+  xid <- GI.GdkX11.x11WindowGetXid x11Window
+  let xid' = fromIntegral xid :: CUIntPtr
+
+  GI.GstVideo.videoOverlaySetWindowHandle (GstElement playbin) xid'
+
+  GI.Gtk.widgetHide fullscreenButton
+
+onFileChooserButtonFileSet ::
+  GI.Gst.Element ->
+  GI.Gtk.FileChooserButton ->
+  GI.Gtk.VolumeButton ->
+  IORef Bool ->
+  GI.Gtk.ComboBoxText ->
+  GI.Gtk.Switch ->
+  GI.Gtk.Button ->
+  GI.Gtk.Widget ->
+  GI.Gtk.Window ->
+  GI.Gtk.MessageDialog ->
+  GI.Gtk.FileChooserButtonFileSetCallback
+onFileChooserButtonFileSet
+  playbin
+  fileChooserButton
+  volumeButton
+  isWindowFullScreenRef
+  desiredVideoWidthComboBox
+  onOffSwitch
+  fullscreenButton
+  drawingArea
+  window
+  errorMessageDialog
+  = do
+  _ <- GI.Gst.elementSetState playbin GI.Gst.StateNull
+
+  filename <- fromJust <$> GI.Gtk.fileChooserGetFilename fileChooserButton
+
+  setPlaybinUriAndVolume playbin filename volumeButton
+
+  isWindowFullScreen <- readIORef isWindowFullScreenRef
+
+  desiredVideoWidth <- getDesiredVideoWidth desiredVideoWidthComboBox
+  maybeWindowSize <- getWindowSize desiredVideoWidth filename
+
+  case maybeWindowSize of
+    Nothing -> do
+      _ <- GI.Gst.elementSetState playbin GI.Gst.StatePaused
+      GI.Gtk.windowUnfullscreen window
+      GI.Gtk.switchSetActive onOffSwitch False
+      GI.Gtk.widgetHide fullscreenButton
+      GI.Gtk.widgetShow desiredVideoWidthComboBox
+      resetWindowSize desiredVideoWidth fileChooserButton drawingArea window
+      _ <- GI.Gtk.onDialogResponse errorMessageDialog (\ _ -> GI.Gtk.widgetHide errorMessageDialog)
+      void $ GI.Gtk.dialogRun errorMessageDialog
+    Just (width, height) -> do
+      _ <- GI.Gst.elementSetState playbin GI.Gst.StatePlaying
+      GI.Gtk.switchSetActive onOffSwitch True
+      GI.Gtk.widgetShow fullscreenButton
+      unless isWindowFullScreen $ setWindowSize width height fileChooserButton drawingArea window
+
+onSwitchStateSet ::
+  GI.Gst.Element ->
+  Bool ->
+  IO Bool
+onSwitchStateSet playbin switchOn = do
+  if switchOn
+    then void $ GI.Gst.elementSetState playbin GI.Gst.StatePlaying
+    else void $ GI.Gst.elementSetState playbin GI.Gst.StatePaused
+  return switchOn
+
+onScaleButtonValueChanged ::
+  GI.Gst.Element ->
+  Double ->
+  IO ()
+onScaleButtonValueChanged playbin volume =
+    void $ Data.GI.Base.Properties.setObjectPropertyDouble playbin "volume" volume
+
+onRangeValueChanged ::
+  GI.Gst.Element ->
+  GI.Gtk.Scale ->
+  IO ()
+onRangeValueChanged playbin seekScale = do
+  (couldQueryDuration, duration) <- GI.Gst.elementQueryDuration playbin GI.Gst.FormatTime
+
+  when couldQueryDuration $ do
+    percentage' <- GI.Gtk.rangeGetValue seekScale
+    let percentage = percentage' / 100.0
+    let position = fromIntegral (round ((fromIntegral duration :: Double) * percentage) :: Int) :: Int64
+    void $ GI.Gst.elementSeekSimple playbin GI.Gst.FormatTime [ GI.Gst.SeekFlagsFlush ] position
+
+updateSeekScale ::
+  GI.Gst.Element ->
+  GI.Gtk.Scale ->
+  Data.GI.Base.Signals.SignalHandlerId ->
+  IO Bool
+updateSeekScale playbin seekScale seekScaleHandlerId = do
+  (couldQueryDuration, duration) <- GI.Gst.elementQueryDuration playbin GI.Gst.FormatTime
+  (couldQueryPosition, position) <- GI.Gst.elementQueryPosition playbin GI.Gst.FormatTime
+
+  let percentage =
+        if couldQueryDuration && couldQueryPosition && duration > 0
+          then 100.0 * (fromIntegral position / fromIntegral duration :: Double)
+          else 0.0
+
+  GI.GObject.signalHandlerBlock seekScale seekScaleHandlerId
+  GI.Gtk.rangeSetValue seekScale percentage
+  GI.GObject.signalHandlerUnblock seekScale seekScaleHandlerId
+
+  return True
+
+onComboBoxChanged ::
+  GI.Gtk.FileChooserButton ->
+  GI.Gtk.ComboBoxText ->
+  GI.Gtk.Widget ->
+  GI.Gtk.Window ->
+  IO ()
+onComboBoxChanged
+  fileChooserButton
+  desiredVideoWidthComboBox
+  drawingArea
+  window
+  = do
+  filename' <- GI.Gtk.fileChooserGetFilename fileChooserButton
+  let filename = fromMaybe "" filename'
+
+  desiredVideoWidth <- getDesiredVideoWidth desiredVideoWidthComboBox
+  maybeWindowSize <- getWindowSize desiredVideoWidth filename
+
+  case maybeWindowSize of
+    Nothing -> resetWindowSize desiredVideoWidth fileChooserButton drawingArea window
+    Just (width, height) -> setWindowSize width height fileChooserButton drawingArea window
+
+onFullscreenButtonRelease ::
+  IORef Bool ->
+  GI.Gtk.ComboBoxText ->
+  GI.Gtk.FileChooserButton ->
+  GI.Gtk.Window ->
+  GI.Gdk.EventButton ->
+  IO Bool
+onFullscreenButtonRelease
+  isWindowFullScreenRef
+  desiredVideoWidthComboBox
+  fileChooserButton
+  window
+  _
+  = do
+  isWindowFullScreen <- readIORef isWindowFullScreenRef
+  if isWindowFullScreen
+    then do
+      GI.Gtk.widgetShow desiredVideoWidthComboBox
+      GI.Gtk.widgetShow fileChooserButton
+      void $ GI.Gtk.windowUnfullscreen window
+    else do
+      GI.Gtk.widgetHide desiredVideoWidthComboBox
+      GI.Gtk.widgetHide fileChooserButton
+      void $ GI.Gtk.windowFullscreen window
+  return True
+
+onWidgetWindowStateEvent ::
+  IORef Bool ->
+  GI.Gdk.EventWindowState ->
+  IO Bool
+onWidgetWindowStateEvent isWindowFullScreenRef eventWindowState = do
+  windowStates <- GI.Gdk.getEventWindowStateNewWindowState eventWindowState
+  let isWindowFullScreen = Prelude.foldl (\ acc x -> acc || GI.Gdk.WindowStateFullscreen == x) False windowStates
+  writeIORef isWindowFullScreenRef isWindowFullScreen
+  return True
+
+onAboutButtonRelease ::
+  GI.Gtk.AboutDialog ->
+  GI.Gdk.EventButton ->
+  IO Bool
+onAboutButtonRelease aboutDialog _ = do
+  _ <- GI.Gtk.onDialogResponse aboutDialog (\ _ -> GI.Gtk.widgetHide aboutDialog)
+  _ <- GI.Gtk.dialogRun aboutDialog
+  return True
+
+onWindowDestroy ::
+  GI.Gst.Element ->
+  IO ()
+onWindowDestroy playbin = do
+  _ <- GI.Gst.elementSetState playbin GI.Gst.StateNull
+  _ <- GI.Gst.objectUnref playbin
+  GI.Gtk.mainQuit
+
+setPlaybinUriAndVolume ::
+  GI.Gst.Element ->
+  Prelude.String ->
+  GI.Gtk.VolumeButton ->
+  IO ()
+setPlaybinUriAndVolume playbin filename volumeButton = do
+  let uri = "file://" ++ filename
+  volume <- GI.Gtk.scaleButtonGetValue volumeButton
+  Data.GI.Base.Properties.setObjectPropertyDouble playbin "volume" volume
+  Data.GI.Base.Properties.setObjectPropertyString playbin "uri" (Just $ pack uri)
+
+getVideoInfo :: Prelude.String -> Prelude.String -> IO (Maybe Prelude.String)
 getVideoInfo flag filename = do
   (code, out, _) <- catch (
       readProcessWithExitCode
@@ -165,40 +321,43 @@
         [flag, "-s", "-S", filename]
         ""
     ) (\ (_ :: Control.Exception.IOException) -> return (ExitFailure 1, "", ""))
-  return (code == System.Exit.ExitSuccess, out)
+  if code == System.Exit.ExitSuccess
+    then return (Just out)
+    else return Nothing
 
 isVideo :: Prelude.String -> IO Bool
 isVideo filename = do
-  (success, out) <- getVideoInfo "-MIMEType" filename
-  return (success && isInfixOf "video" (pack out))
-
-getWindowSize :: Int -> Prelude.String -> IO (Bool, Int32, Int32)
-getWindowSize desiredVideoWidth filename = do
-  let defaultWidth = 800
-  let defaultHeight = 600
-
-  video <- isVideo filename
-
-  if video
-    then do
-      (success, out) <- getVideoInfo "-ImageSize" filename
-      if success && isInfixOf "x" (pack out)
-        then do
-          let (width''':height''':_) =
-                Data.String.Utils.split "x" $ Data.String.Utils.strip out
-
-          let width'' = read width''' :: Int
-          let height'' = read height''' :: Int
-
-          let ratio = fromIntegral height'' / fromIntegral width'' :: Double
-          let width' = fromIntegral desiredVideoWidth :: Double
-          let height' = width' * ratio
-          let width = fromIntegral (round width' :: Int) :: Int32
-          let height = fromIntegral (round height' :: Int) :: Int32
+  maybeOut <- getVideoInfo "-MIMEType" filename
+  case maybeOut of
+    Nothing -> return False
+    Just out -> return ("video" `isInfixOf` pack out)
 
-          return (True, width, height)
-        else return (False, defaultHeight, defaultWidth)
-    else return (False, defaultHeight, defaultWidth)
+getWindowSize :: Int -> Prelude.String -> IO (Maybe (Int32, Int32))
+getWindowSize desiredVideoWidth filename =
+  isVideo filename >>=
+  getWidthHeightString >>=
+  splitWidthHeightString >>=
+  widthHeightToDouble >>=
+  ratio >>=
+  windowSize
+  where
+    getWidthHeightString :: Bool -> IO (Maybe Prelude.String)
+    getWidthHeightString False = return Nothing
+    getWidthHeightString True = getVideoInfo "-ImageSize" filename
+    splitWidthHeightString :: Maybe Prelude.String -> IO (Maybe [Text])
+    splitWidthHeightString Nothing = return Nothing
+    splitWidthHeightString (Just string) = return (Just (Data.Text.splitOn "x" (pack string)))
+    widthHeightToDouble :: Maybe [Text] -> IO (Maybe Double, Maybe Double)
+    widthHeightToDouble (Just (x:y:_)) = return (readMaybe (unpack x) :: Maybe Double, readMaybe (unpack y) :: Maybe Double)
+    widthHeightToDouble _ = return (Nothing, Nothing)
+    ratio :: (Maybe Double, Maybe Double) -> IO (Maybe Double)
+    ratio (Just width, Just height) =
+      if width <= 0.0 then return Nothing else return (Just (height / width))
+    ratio _ = return Nothing
+    windowSize :: Maybe Double -> IO (Maybe (Int32, Int32))
+    windowSize Nothing = return Nothing
+    windowSize (Just ratio') =
+      return (Just (fromIntegral desiredVideoWidth :: Int32, round ((fromIntegral desiredVideoWidth :: Double) *  ratio') :: Int32))
 
 getDesiredVideoWidth :: GI.Gtk.ComboBoxText -> IO Int
 getDesiredVideoWidth = fmap (\ x -> read (Data.Text.unpack x) :: Int) . GI.Gtk.comboBoxTextGetActiveText
@@ -229,4 +388,5 @@
   IO ()
 resetWindowSize width' fileChooserButton drawingArea window = do
   let width = fromIntegral width' :: Int32
+  GI.Gtk.widgetQueueDraw drawingArea
   setWindowSize width 0 fileChooserButton drawingArea window
diff --git a/src/data/gui.glade b/src/data/gui.glade
--- a/src/data/gui.glade
+++ b/src/data/gui.glade
@@ -2,11 +2,21 @@
 <!-- Generated with glade 3.20.0 -->
 <interface>
   <requires lib="gtk+" version="3.20"/>
+  <object class="GtkImage" id="about-image">
+    <property name="visible">True</property>
+    <property name="can_focus">False</property>
+    <property name="stock">gtk-dialog-question</property>
+  </object>
   <object class="GtkAdjustment" id="adjustment1">
     <property name="upper">100</property>
     <property name="step_increment">1</property>
     <property name="page_increment">10</property>
   </object>
+  <object class="GtkImage" id="fullscreen-image">
+    <property name="visible">True</property>
+    <property name="can_focus">False</property>
+    <property name="stock">gtk-fullscreen</property>
+  </object>
   <object class="GtkWindow" id="window">
     <property name="can_focus">False</property>
     <property name="title" translatable="yes">Movie Monad</property>
@@ -22,13 +32,18 @@
           <object class="GtkBox">
             <property name="visible">True</property>
             <property name="can_focus">False</property>
+            <property name="hexpand">True</property>
+            <property name="vexpand">True</property>
             <property name="orientation">vertical</property>
             <child>
               <object class="GtkFileChooserButton" id="file-chooser-button">
                 <property name="width_request">800</property>
                 <property name="visible">True</property>
+                <property name="app_paintable">True</property>
                 <property name="can_focus">False</property>
                 <property name="tooltip_text" translatable="yes">Select a video file.</property>
+                <property name="valign">start</property>
+                <property name="hexpand">True</property>
                 <property name="create_folders">False</property>
                 <property name="title" translatable="yes">Movie Monad</property>
               </object>
@@ -44,10 +59,12 @@
                 <property name="sensitive">False</property>
                 <property name="app_paintable">True</property>
                 <property name="can_focus">False</property>
+                <property name="hexpand">True</property>
+                <property name="vexpand">True</property>
               </object>
               <packing>
-                <property name="expand">False</property>
-                <property name="fill">False</property>
+                <property name="expand">True</property>
+                <property name="fill">True</property>
                 <property name="position">1</property>
               </packing>
             </child>
@@ -55,8 +72,10 @@
               <object class="GtkScale" id="seek-scale">
                 <property name="visible">True</property>
                 <property name="can_focus">True</property>
+                <property name="valign">end</property>
                 <property name="margin_left">5</property>
                 <property name="margin_right">5</property>
+                <property name="hexpand">True</property>
                 <property name="adjustment">adjustment1</property>
                 <property name="show_fill_level">True</property>
                 <property name="fill_level">100</property>
@@ -66,14 +85,14 @@
                 <property name="value_pos">left</property>
               </object>
               <packing>
-                <property name="expand">True</property>
-                <property name="fill">True</property>
+                <property name="expand">False</property>
+                <property name="fill">False</property>
                 <property name="position">2</property>
               </packing>
             </child>
           </object>
           <packing>
-            <property name="expand">False</property>
+            <property name="expand">True</property>
             <property name="fill">True</property>
             <property name="position">0</property>
           </packing>
@@ -82,7 +101,9 @@
           <object class="GtkBox">
             <property name="visible">True</property>
             <property name="can_focus">False</property>
+            <property name="valign">end</property>
             <property name="margin_bottom">5</property>
+            <property name="hexpand">True</property>
             <child>
               <object class="GtkSwitch" id="on-off-switch">
                 <property name="visible">True</property>
@@ -172,12 +193,11 @@
             </child>
             <child>
               <object class="GtkButton" id="about-button">
-                <property name="label">gtk-about</property>
                 <property name="visible">True</property>
                 <property name="can_focus">True</property>
                 <property name="receives_default">True</property>
                 <property name="margin_right">5</property>
-                <property name="use_stock">True</property>
+                <property name="image">about-image</property>
                 <property name="always_show_image">True</property>
               </object>
               <packing>
@@ -187,10 +207,24 @@
                 <property name="position">3</property>
               </packing>
             </child>
+            <child>
+              <object class="GtkButton" id="fullscreen-button">
+                <property name="can_focus">True</property>
+                <property name="receives_default">True</property>
+                <property name="tooltip_text" translatable="yes">Toggle on or off fullscreen.</property>
+                <property name="image">fullscreen-image</property>
+                <property name="always_show_image">True</property>
+              </object>
+              <packing>
+                <property name="expand">False</property>
+                <property name="fill">True</property>
+                <property name="position">4</property>
+              </packing>
+            </child>
           </object>
           <packing>
             <property name="expand">False</property>
-            <property name="fill">True</property>
+            <property name="fill">False</property>
             <property name="position">1</property>
           </packing>
         </child>
@@ -210,7 +244,7 @@
     <property name="transient_for">window</property>
     <property name="attached_to">window</property>
     <property name="program_name">Movie Monad</property>
-    <property name="version">0.0.0.0</property>
+    <property name="version">0.0.1.0</property>
     <property name="copyright" translatable="yes">(C) 2017 David Lettier</property>
     <property name="website">https://github.com/lettier/movie-monad</property>
     <property name="website_label" translatable="yes">Update</property>
