Sophie

Sophie

distrib > Fedora > 13 > i386 > media > updates-src > by-pkgid > 7ded9ce0a427d2a57e8ba7a0921be680 > files > 3

lxterminal-0.1.7-2.fc13.src.rpm

From 20d518389a6d2e2cac761d62890c8321397d292a Mon Sep 17 00:00:00 2001
From: Marty Jack <martyj@linux.local>
Date: Mon, 29 Mar 2010 16:50:48 -0400
Subject: [PATCH 09/60] Major rework
 - -e and --command now consume arguments to the end of the line (--command= is unchanged)
 - Preference dialog now GtkBuilder based, must have external XML file to operate successfully
 - 2973537 Failure to either connect or bind to the communication socket now handled gracefully; the LXTerminal will run standalone
 - Terminal failed to resize when font changed from larger to smaller
 - Failed to honor --working-directory with --command
 - Configuration now applies immediately
 - User preference for cursor shape
 - User preference for audible bell
 - 2977944 User preference for allow bold
 - 2842542 User preference for hide Close button
 - 2842542 Middle click on tab closes it; consistent with other applications such as Firefox
 - 2845142 User can edit tab labels

---
 AUTHORS                           |    1 +
 configure.ac                      |    2 +-
 data/Makefile.am                  |   15 +
 data/lxterminal-preferences.glade |  512 ++++++++++
 data/lxterminal.conf.in           |    1 +
 man/lxterminal.xml                |   30 +-
 src/Makefile.am                   |    7 +-
 src/lxterminal.c                  | 2017 ++++++++++++++++++++-----------------
 src/lxterminal.h                  |  111 ++-
 src/preferences.c                 |  526 ++++------
 src/preferences.h                 |   78 +-
 src/setting.c                     |  208 ++--
 src/setting.h                     |   58 +-
 src/tab.c                         |  112 +--
 src/tab.h                         |   29 +-
 src/unixsocket.c                  |  361 ++++---
 src/unixsocket.h                  |   22 +-
 17 files changed, 2361 insertions(+), 1729 deletions(-)
 create mode 100644 data/lxterminal-preferences.glade

diff --git a/AUTHORS b/AUTHORS
index 975d44a..e976153 100644
--- a/AUTHORS
+++ b/AUTHORS
@@ -4,6 +4,7 @@ Alessandro Pellizzari <alex_shu@users.sourceforge.net>
 Micahel <metsger@users.sourceforge.net>
 Yotam Medini <yotam.medini@gmail.com>
 Liu Yubao <yubao.liu@gmail.com>
+Marty Jack <martyj19@comcast.net>
 
 Icon:
 Taken from "nuoveXT 2" icon theme created by Alexandre Moore (saki)
diff --git a/configure.ac b/configure.ac
index d3942c2..120deea 100644
--- a/configure.ac
+++ b/configure.ac
@@ -21,7 +21,7 @@ AC_ARG_ENABLE(man,
 )
 # Checks for libraries.
 PKG_CHECK_MODULES(glib, [glib-2.0 >= 2.6.0])
-PKG_CHECK_MODULES(gtk, [gtk+-2.0 >= 2.6.0])
+PKG_CHECK_MODULES(gtk, [gtk+-2.0 >= 2.12.0])
 PKG_CHECK_MODULES(vte, [vte >= 0.17.1])
 CFLAGS="$CFLAGS $glib_CFLAGS $gtk_CFLAGS $vte_CFLAGS"
 LIBS="$LIBS $glib_LIBS $gtk_LIBS $vte_LIBS"
diff --git a/data/Makefile.am b/data/Makefile.am
index a0eacd4..046918a 100644
--- a/data/Makefile.am
+++ b/data/Makefile.am
@@ -1,6 +1,20 @@
 default_config_DATA = lxterminal.conf
 default_configdir = $(datadir)/lxterminal
 
+uidir=$(datadir)/lxterminal
+ui_in_files= \
+	lxterminal-preferences.glade
+
+ui_DATA = $(ui_in_files:.glade=.ui)
+
+# Generate GtkBuilder UI files from Glade files
+%.ui: %.glade
+	cp $< $@
+	$(top_builddir)/src/xml-purge $@
+
+CLEANFILES = \
+        $(ui_DATA)
+
 lxterminal.desktop_in_files = lxterminal.desktop.in
 lxterminal.desktop.in_DATA = $(lxterminal.desktop_in_files:.desktop.in=.desktop)
 @INTLTOOL_DESKTOP_RULE@
@@ -13,4 +27,5 @@ EXTRA_DIST = \
 	lxterminal.conf.in \
 	$(lxterminal_images_DATA) \
 	$(lxterminal.desktop.in_DATA) \
+	$(ui_DATA) \
 	$(default_config_DATA)
diff --git a/data/lxterminal-preferences.glade b/data/lxterminal-preferences.glade
new file mode 100644
index 0000000..6b9ebaf
--- /dev/null
+++ b/data/lxterminal-preferences.glade
@@ -0,0 +1,512 @@
+<?xml version="1.0"?>
+<interface>
+  <!-- interface-requires gtk+ 2.12 -->
+  <!-- interface-naming-policy project-wide -->
+  <object class="GtkListStore" id="liststore1">
+    <columns>
+      <!-- column-name gchararray1 -->
+      <column type="gchararray"/>
+    </columns>
+    <data>
+      <row>
+        <col id="0" translatable="yes">Top</col>
+      </row>
+      <row>
+        <col id="0" translatable="yes">Bottom</col>
+      </row>
+      <row>
+        <col id="0" translatable="yes">Left</col>
+      </row>
+      <row>
+        <col id="0" translatable="yes">Right</col>
+      </row>
+    </data>
+  </object>
+  <object class="GtkDialog" id="lxterminal_preferences">
+    <property name="border_width">5</property>
+    <property name="type_hint">normal</property>
+    <property name="has_separator">False</property>
+    <child internal-child="vbox">
+      <object class="GtkVBox" id="dialog-vbox1">
+        <property name="visible">True</property>
+        <property name="orientation">vertical</property>
+        <property name="spacing">2</property>
+        <child>
+          <object class="GtkNotebook" id="notebook1">
+            <property name="visible">True</property>
+            <property name="can_focus">True</property>
+            <child>
+              <object class="GtkTable" id="table1">
+                <property name="visible">True</property>
+                <property name="n_rows">8</property>
+                <property name="n_columns">2</property>
+                <property name="column_spacing">5</property>
+                <property name="row_spacing">3</property>
+                <child>
+                  <object class="GtkLabel" id="label4">
+                    <property name="visible">True</property>
+                    <property name="xalign">1</property>
+                    <property name="label" translatable="yes">Terminal font</property>
+                  </object>
+                </child>
+                <child>
+                  <object class="GtkFontButton" id="terminal_font">
+                    <property name="visible">True</property>
+                    <property name="can_focus">True</property>
+                    <property name="receives_default">True</property>
+                  </object>
+                  <packing>
+                    <property name="left_attach">1</property>
+                    <property name="right_attach">2</property>
+                  </packing>
+                </child>
+                <child>
+                  <object class="GtkLabel" id="label5">
+                    <property name="visible">True</property>
+                    <property name="xalign">1</property>
+                    <property name="label" translatable="yes">Background</property>
+                  </object>
+                  <packing>
+                    <property name="top_attach">1</property>
+                    <property name="bottom_attach">2</property>
+                  </packing>
+                </child>
+                <child>
+                  <object class="GtkColorButton" id="background_color">
+                    <property name="visible">True</property>
+                    <property name="can_focus">True</property>
+                    <property name="receives_default">True</property>
+                    <property name="use_alpha">True</property>
+                    <property name="color">#000000000000</property>
+                  </object>
+                  <packing>
+                    <property name="left_attach">1</property>
+                    <property name="right_attach">2</property>
+                    <property name="top_attach">1</property>
+                    <property name="bottom_attach">2</property>
+                  </packing>
+                </child>
+                <child>
+                  <object class="GtkColorButton" id="foreground_color">
+                    <property name="visible">True</property>
+                    <property name="can_focus">True</property>
+                    <property name="receives_default">True</property>
+                    <property name="color">#000000000000</property>
+                  </object>
+                  <packing>
+                    <property name="left_attach">1</property>
+                    <property name="right_attach">2</property>
+                    <property name="top_attach">2</property>
+                    <property name="bottom_attach">3</property>
+                  </packing>
+                </child>
+                <child>
+                  <object class="GtkLabel" id="label6">
+                    <property name="visible">True</property>
+                    <property name="xalign">1</property>
+                    <property name="label" translatable="yes">Foreground</property>
+                  </object>
+                  <packing>
+                    <property name="top_attach">2</property>
+                    <property name="bottom_attach">3</property>
+                  </packing>
+                </child>
+                <child>
+                  <object class="GtkLabel" id="label8">
+                    <property name="visible">True</property>
+                    <property name="xalign">1</property>
+                    <property name="label" translatable="yes">Allow bold font</property>
+                  </object>
+                  <packing>
+                    <property name="top_attach">3</property>
+                    <property name="bottom_attach">4</property>
+                  </packing>
+                </child>
+                <child>
+                  <object class="GtkCheckButton" id="allow_bold">
+                    <property name="visible">True</property>
+                    <property name="can_focus">True</property>
+                    <property name="receives_default">False</property>
+                    <property name="draw_indicator">True</property>
+                  </object>
+                  <packing>
+                    <property name="left_attach">1</property>
+                    <property name="right_attach">2</property>
+                    <property name="top_attach">3</property>
+                    <property name="bottom_attach">4</property>
+                  </packing>
+                </child>
+                <child>
+                  <object class="GtkLabel" id="label7">
+                    <property name="visible">True</property>
+                    <property name="xalign">1</property>
+                    <property name="label" translatable="yes">Cursor blink</property>
+                  </object>
+                  <packing>
+                    <property name="top_attach">4</property>
+                    <property name="bottom_attach">5</property>
+                  </packing>
+                </child>
+                <child>
+                  <object class="GtkCheckButton" id="cursor_blink">
+                    <property name="visible">True</property>
+                    <property name="can_focus">True</property>
+                    <property name="receives_default">False</property>
+                    <property name="draw_indicator">True</property>
+                  </object>
+                  <packing>
+                    <property name="left_attach">1</property>
+                    <property name="right_attach">2</property>
+                    <property name="top_attach">4</property>
+                    <property name="bottom_attach">5</property>
+                  </packing>
+                </child>
+                <child>
+                  <object class="GtkLabel" id="label13">
+                    <property name="visible">True</property>
+                    <property name="xalign">1</property>
+                    <property name="label" translatable="yes">Cursor style</property>
+                  </object>
+                  <packing>
+                    <property name="top_attach">5</property>
+                    <property name="bottom_attach">7</property>
+                  </packing>
+                </child>
+                <child>
+                  <object class="GtkRadioButton" id="cursor_style_block">
+                    <property name="label" translatable="yes">Block</property>
+                    <property name="visible">True</property>
+                    <property name="can_focus">True</property>
+                    <property name="receives_default">False</property>
+                    <property name="active">True</property>
+                    <property name="draw_indicator">True</property>
+                  </object>
+                  <packing>
+                    <property name="left_attach">1</property>
+                    <property name="right_attach">2</property>
+                    <property name="top_attach">5</property>
+                    <property name="bottom_attach">6</property>
+                  </packing>
+                </child>
+                <child>
+                  <object class="GtkRadioButton" id="cursor_style_underline">
+                    <property name="label" translatable="yes">Underline</property>
+                    <property name="visible">True</property>
+                    <property name="can_focus">True</property>
+                    <property name="receives_default">False</property>
+                    <property name="active">True</property>
+                    <property name="draw_indicator">True</property>
+                    <property name="group">cursor_style_block</property>
+                  </object>
+                  <packing>
+                    <property name="left_attach">1</property>
+                    <property name="right_attach">2</property>
+                    <property name="top_attach">6</property>
+                    <property name="bottom_attach">7</property>
+                  </packing>
+                </child>
+                <child>
+                  <object class="GtkLabel" id="label17">
+                    <property name="visible">True</property>
+                    <property name="xalign">1</property>
+                    <property name="label" translatable="yes">Audible bell</property>
+                  </object>
+                  <packing>
+                    <property name="top_attach">7</property>
+                    <property name="bottom_attach">8</property>
+                  </packing>
+                </child>
+                <child>
+                  <object class="GtkCheckButton" id="audible_bell">
+                    <property name="visible">True</property>
+                    <property name="can_focus">True</property>
+                    <property name="receives_default">False</property>
+                    <property name="draw_indicator">True</property>
+                  </object>
+                  <packing>
+                    <property name="left_attach">1</property>
+                    <property name="right_attach">2</property>
+                    <property name="top_attach">7</property>
+                    <property name="bottom_attach">8</property>
+                  </packing>
+                </child>
+              </object>
+            </child>
+            <child type="tab">
+              <object class="GtkLabel" id="label1">
+                <property name="visible">True</property>
+                <property name="label" translatable="yes">Style</property>
+              </object>
+              <packing>
+                <property name="tab_fill">False</property>
+              </packing>
+            </child>
+            <child>
+              <object class="GtkTable" id="table2">
+                <property name="visible">True</property>
+                <property name="n_rows">5</property>
+                <property name="n_columns">2</property>
+                <property name="column_spacing">5</property>
+                <property name="row_spacing">3</property>
+                <child>
+                  <object class="GtkLabel" id="label9">
+                    <property name="visible">True</property>
+                    <property name="xalign">1</property>
+                    <property name="label" translatable="yes">Tab panel position</property>
+                  </object>
+                </child>
+                <child>
+                  <object class="GtkLabel" id="label10">
+                    <property name="visible">True</property>
+                    <property name="xalign">1</property>
+                    <property name="label" translatable="yes">Scrollback lines</property>
+                  </object>
+                  <packing>
+                    <property name="top_attach">1</property>
+                    <property name="bottom_attach">2</property>
+                  </packing>
+                </child>
+                <child>
+                  <object class="GtkLabel" id="label11">
+                    <property name="visible">True</property>
+                    <property name="xalign">1</property>
+                    <property name="label" translatable="yes">Hide scroll bar</property>
+                  </object>
+                  <packing>
+                    <property name="top_attach">2</property>
+                    <property name="bottom_attach">3</property>
+                  </packing>
+                </child>
+                <child>
+                  <object class="GtkLabel" id="label12">
+                    <property name="visible">True</property>
+                    <property name="xalign">1</property>
+                    <property name="label" translatable="yes">Hide menu bar</property>
+                  </object>
+                  <packing>
+                    <property name="top_attach">3</property>
+                    <property name="bottom_attach">4</property>
+                  </packing>
+                </child>
+                <child>
+                  <object class="GtkCheckButton" id="hide_menu_bar">
+                    <property name="visible">True</property>
+                    <property name="can_focus">True</property>
+                    <property name="receives_default">False</property>
+                    <property name="draw_indicator">True</property>
+                  </object>
+                  <packing>
+                    <property name="left_attach">1</property>
+                    <property name="right_attach">2</property>
+                    <property name="top_attach">3</property>
+                    <property name="bottom_attach">4</property>
+                  </packing>
+                </child>
+                <child>
+                  <object class="GtkComboBox" id="tab_position">
+                    <property name="visible">True</property>
+                    <property name="model">liststore1</property>
+                    <child>
+                      <object class="GtkCellRendererText" id="cellrenderertext2"/>
+                      <attributes>
+                        <attribute name="text">0</attribute>
+                      </attributes>
+                    </child>
+                  </object>
+                  <packing>
+                    <property name="left_attach">1</property>
+                    <property name="right_attach">2</property>
+                    <property name="y_options">GTK_SHRINK</property>
+                  </packing>
+                </child>
+                <child>
+                  <object class="GtkSpinButton" id="scrollback_lines">
+                    <property name="visible">True</property>
+                    <property name="can_focus">True</property>
+                    <property name="invisible_char">&#x2022;</property>
+                    <property name="adjustment">scrollback_lines_adjustment</property>
+                  </object>
+                  <packing>
+                    <property name="left_attach">1</property>
+                    <property name="right_attach">2</property>
+                    <property name="top_attach">1</property>
+                    <property name="bottom_attach">2</property>
+                  </packing>
+                </child>
+                <child>
+                  <object class="GtkCheckButton" id="hide_scroll_bar">
+                    <property name="visible">True</property>
+                    <property name="can_focus">True</property>
+                    <property name="receives_default">False</property>
+                    <property name="draw_indicator">True</property>
+                  </object>
+                  <packing>
+                    <property name="left_attach">1</property>
+                    <property name="right_attach">2</property>
+                    <property name="top_attach">2</property>
+                    <property name="bottom_attach">3</property>
+                  </packing>
+                </child>
+                <child>
+                  <object class="GtkLabel" id="label16">
+                    <property name="visible">True</property>
+                    <property name="xalign">1</property>
+                    <property name="label" translatable="yes">Hide Close buttons</property>
+                  </object>
+                  <packing>
+                    <property name="top_attach">4</property>
+                    <property name="bottom_attach">5</property>
+                  </packing>
+                </child>
+                <child>
+                  <object class="GtkCheckButton" id="hide_close_button">
+                    <property name="visible">True</property>
+                    <property name="can_focus">True</property>
+                    <property name="receives_default">False</property>
+                    <property name="draw_indicator">True</property>
+                  </object>
+                  <packing>
+                    <property name="left_attach">1</property>
+                    <property name="right_attach">2</property>
+                    <property name="top_attach">4</property>
+                    <property name="bottom_attach">5</property>
+                  </packing>
+                </child>
+              </object>
+              <packing>
+                <property name="position">1</property>
+              </packing>
+            </child>
+            <child type="tab">
+              <object class="GtkLabel" id="label2">
+                <property name="visible">True</property>
+                <property name="label" translatable="yes">Display</property>
+              </object>
+              <packing>
+                <property name="position">1</property>
+                <property name="tab_fill">False</property>
+              </packing>
+            </child>
+            <child>
+              <object class="GtkTable" id="table3">
+                <property name="visible">True</property>
+                <property name="n_rows">2</property>
+                <property name="n_columns">2</property>
+                <property name="column_spacing">5</property>
+                <property name="row_spacing">3</property>
+                <child>
+                  <object class="GtkLabel" id="label14">
+                    <property name="visible">True</property>
+                    <property name="xalign">1</property>
+                    <property name="label" translatable="yes">Select-by-word characters</property>
+                  </object>
+                </child>
+                <child>
+                  <object class="GtkLabel" id="label15">
+                    <property name="visible">True</property>
+                    <property name="xalign">1</property>
+                    <property name="label" translatable="yes">Disable menu shortcut key (F10 by default)</property>
+                  </object>
+                  <packing>
+                    <property name="top_attach">1</property>
+                    <property name="bottom_attach">2</property>
+                  </packing>
+                </child>
+                <child>
+                  <object class="GtkCheckButton" id="disable_f10">
+                    <property name="visible">True</property>
+                    <property name="can_focus">True</property>
+                    <property name="receives_default">False</property>
+                    <property name="draw_indicator">True</property>
+                  </object>
+                  <packing>
+                    <property name="left_attach">1</property>
+                    <property name="right_attach">2</property>
+                    <property name="top_attach">1</property>
+                    <property name="bottom_attach">2</property>
+                  </packing>
+                </child>
+                <child>
+                  <object class="GtkEntry" id="select_by_word">
+                    <property name="visible">True</property>
+                    <property name="can_focus">True</property>
+                    <property name="invisible_char">&#x2022;</property>
+                  </object>
+                  <packing>
+                    <property name="left_attach">1</property>
+                    <property name="right_attach">2</property>
+                  </packing>
+                </child>
+              </object>
+              <packing>
+                <property name="position">2</property>
+              </packing>
+            </child>
+            <child type="tab">
+              <object class="GtkLabel" id="label3">
+                <property name="visible">True</property>
+                <property name="label" translatable="yes">Advanced</property>
+              </object>
+              <packing>
+                <property name="position">2</property>
+                <property name="tab_fill">False</property>
+              </packing>
+            </child>
+          </object>
+          <packing>
+            <property name="position">1</property>
+          </packing>
+        </child>
+        <child internal-child="action_area">
+          <object class="GtkHButtonBox" id="dialog-action_area1">
+            <property name="visible">True</property>
+            <property name="layout_style">end</property>
+            <child>
+              <object class="GtkButton" id="Cancel_button">
+                <property name="label" translatable="yes">gtk-cancel</property>
+                <property name="visible">True</property>
+                <property name="can_focus">True</property>
+                <property name="receives_default">True</property>
+                <property name="use_stock">True</property>
+              </object>
+              <packing>
+                <property name="expand">False</property>
+                <property name="fill">False</property>
+                <property name="position">0</property>
+              </packing>
+            </child>
+            <child>
+              <object class="GtkButton" id="OK_button">
+                <property name="label" translatable="yes">gtk-ok</property>
+                <property name="visible">True</property>
+                <property name="can_focus">True</property>
+                <property name="receives_default">True</property>
+                <property name="use_stock">True</property>
+              </object>
+              <packing>
+                <property name="expand">False</property>
+                <property name="fill">False</property>
+                <property name="position">1</property>
+              </packing>
+            </child>
+          </object>
+          <packing>
+            <property name="expand">False</property>
+            <property name="pack_type">end</property>
+            <property name="position">0</property>
+          </packing>
+        </child>
+      </object>
+    </child>
+    <action-widgets>
+      <action-widget response="-6">Cancel_button</action-widget>
+      <action-widget response="-5">OK_button</action-widget>
+    </action-widgets>
+  </object>
+  <object class="GtkAdjustment" id="scrollback_lines_adjustment">
+    <property name="value">1000</property>
+    <property name="upper">100000</property>
+    <property name="step_increment">10</property>
+    <property name="page_increment">10</property>
+  </object>
+</interface>
diff --git a/data/lxterminal.conf.in b/data/lxterminal.conf.in
index 74ec5cb..2621a08 100644
--- a/data/lxterminal.conf.in
+++ b/data/lxterminal.conf.in
@@ -1,3 +1,4 @@
 [general]
 fontname=Monospace 10
 selchars=-A-Za-z0-9,./?%&#:_
+scrollback=1000
diff --git a/man/lxterminal.xml b/man/lxterminal.xml
index c2124eb..e0977cf 100644
--- a/man/lxterminal.xml
+++ b/man/lxterminal.xml
@@ -29,8 +29,7 @@
 
     <para><command>lxterminal</command> is a program that provides a terminal
     emulator
-    for the desktop, usually for LXDE. It is a lightweight GTK+ 2.x based desktop 
-    panel.
+    for the desktop, usually for LXDE.
     </para>
    
   </refsect1>
@@ -44,19 +43,11 @@
 
     <variablelist>      <varlistentry>        <term>	  <option>-e <replaceable>STRING</replaceable></option>
           <option>--command=<replaceable>STRING</replaceable></option>
+          <option>--command <replaceable>STRING</replaceable></option>
+
         </term>
-        <listitem>          <para>Execute the argument to this option inside the terminal.</para>
-        </listitem>
-      </varlistentry>
-      <varlistentry>	<term>	  <option>-t <replaceable>STRING</replaceable></option>
-	  <option>--title=<replaceable>STRING</replaceable></option>
-	</term>
-	<listitem>	  <para>Set the terminal's title.</para>
-	</listitem>
-      </varlistentry>
-      <varlistentry>        <term>          <option>--working-directory=<replaceable>DIRECTORY</replaceable></option>
-        </term>
-        <listitem>          <para>Set the terminal's working directory.</para>
+        <listitem>          <para>This option specifies the program (and its command line arguments) to be run in the terminal.
+Except in the <option>--command=</option> form, this must be the last option on the command line.</para>
         </listitem>
       </varlistentry>
       <varlistentry>	<term>	  <option>--geometry=<replaceable>CHARACTERS</replaceable>x<replaceable>LINES</replaceable></option>
@@ -70,6 +61,17 @@
 	<listitem>	  <para>Executes login shell.</para>
 	</listitem>
       </varlistentry>
+      <varlistentry>	<term>	  <option>-t <replaceable>STRING</replaceable></option>
+	  <option>--title=<replaceable>STRING</replaceable></option>
+	</term>
+	<listitem>	  <para>Set the terminal's title.</para>
+	</listitem>
+      </varlistentry>
+      <varlistentry>        <term>          <option>--working-directory=<replaceable>DIRECTORY</replaceable></option>
+        </term>
+        <listitem>          <para>Set the terminal's working directory.</para>
+        </listitem>
+      </varlistentry>
     </variablelist>
   </refsect1>
 
diff --git a/src/Makefile.am b/src/Makefile.am
index ca2b3db..af9efd4 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -15,8 +15,6 @@ lxterminal_SOURCES = \
 	unixsocket.c \
 	setting.h \
 	setting.c \
-	tab.h \
-	tab.c \
 	lxterminal.h \
 	lxterminal.c \
 	preferences.h \
@@ -25,3 +23,8 @@ lxterminal_SOURCES = \
 lxterminal_LDADD = \
 		$(PACKAGE_LIBS) \
 		$(INTLLIBS)
+
+noinst_PROGRAMS=xml-purge
+xml_purge_SOURCES=xml-purge.c
+xml_purge_CFLAGS=@CFLAGS@
+xml_purge_LDADD=@LIBS@
diff --git a/src/lxterminal.c b/src/lxterminal.c
index 37e0253..60712bb 100644
--- a/src/lxterminal.c
+++ b/src/lxterminal.c
@@ -1,5 +1,6 @@
-/*
+/**
  *      Copyright 2008 Fred Chien <cfsghost@gmail.com>
+ *      Copyright (c) 2010 LxDE Developers, see the file AUTHORS for details.
  *
  *      This program is free software; you can redistribute it and/or modify
  *      it under the terms of the GNU General Public License as published by
@@ -18,7 +19,7 @@
  */
 
 #ifdef HAVE_CONFIG_H
-	#include <config.h>
+#include <config.h>
 #endif
 
 #include <X11/Xutil.h>
@@ -29,14 +30,14 @@
 #include <vte/vte.h>
 #include <langinfo.h>
 #include <locale.h>
+#include <sys/stat.h>
 
 #include "lxterminal.h"
 #include "setting.h"
-#include "tab.h"
 #include "preferences.h"
 #include "unixsocket.h"
 
-/* Linux color for palette */
+/* Linux color for palette. */
 static const GdkColor linux_color[16] =
 {
   { 0, 0x0000, 0x0000, 0x0000 },
@@ -57,1100 +58,1272 @@ static const GdkColor linux_color[16] =
   { 0, 0xffff, 0xffff, 0xffff }
 };
 
-static void terminal_childexit(VteTerminal *vte, Term *term);
-
-static Term *terminal_new(LXTerminal *terminal, const gchar *label, const gchar *pwd, gchar **env, const gchar *exec);
-static void terminal_free(Term* term);
-
-/* menu accel saved when the user disables it */
-static char *saved_menu_accel = NULL;
-
-static gchar helpmsg[] = {
+/* X accessor. */
+static void gdk_window_get_geometry_hints(GdkWindow * window, GdkGeometry * geometry, GdkWindowHints * geometry_mask);
+
+/* Utilities. */
+static void terminal_get_padding(Term * term, GtkBorder * border);
+static void terminal_geometry_restore(Term * term);
+static void terminal_tab_set_position(GtkWidget * notebook, gint tab_position);
+
+/* Menu and accelerator event handlers. */
+static void terminal_initialize_switch_tab_accelerator(Term * term);
+static void terminal_switch_tab_accelerator(Term * term);
+static void terminal_new_window_activate_event(GtkAction * action, LXTerminal * terminal);
+static void terminal_new_window_accelerator(LXTerminal * terminal, guint action, GtkWidget * item);
+static void terminal_new_tab_activate_event(GtkAction * action, LXTerminal * terminal);
+static void terminal_new_tab_accelerator(LXTerminal * terminal, guint action, GtkWidget * item);
+static void terminal_close_tab_activate_event(GtkAction * action, LXTerminal * terminal);
+static void terminal_close_tab_accelerator(LXTerminal * terminal, guint action, GtkWidget * item);
+static void terminal_copy_activate_event(GtkAction * action, LXTerminal * terminal);
+static void terminal_copy_accelerator(LXTerminal * terminal, guint action, GtkWidget * item);
+static void terminal_paste_activate_event(GtkAction * action, LXTerminal * terminal);
+static void terminal_paste_accelerator(LXTerminal * terminal, guint action, GtkWidget * item);
+static void terminal_name_tab_response_event(GtkWidget * dialog, gint response, LXTerminal * terminal);
+static void terminal_name_tab_activate_event(GtkAction * action, LXTerminal * terminal);
+static void terminal_name_tab_accelerator(LXTerminal * terminal, guint action, GtkWidget * item);
+static void terminal_previous_tab_activate_event(GtkAction * action, LXTerminal * terminal);
+static void terminal_previous_tab_accelerator(LXTerminal * terminal, guint action, GtkWidget * item);
+static void terminal_next_tab_activate_event(GtkAction * action, LXTerminal * terminal);
+static void terminal_next_tab_accelerator(LXTerminal * terminal, guint action, GtkWidget * item);
+static void terminal_move_tab_execute(LXTerminal * terminal, gint direction);
+static void terminal_move_tab_left_activate_event(GtkAction * action, LXTerminal * terminal);
+static void terminal_move_tab_left_accelerator(LXTerminal * terminal, guint action, GtkWidget * item);
+static void terminal_move_tab_right_activate_event(GtkAction * action, LXTerminal * terminal);
+static void terminal_move_tab_right_accelerator(LXTerminal * terminal, guint action, GtkWidget * item);
+static void terminal_about_activate_event(GtkAction * action, LXTerminal * terminal);
+
+/* Window creation, destruction, and control. */
+static gboolean terminal_window_size_request_event(GtkWidget * widget, GtkRequisition * requisition, LXTerminal * terminal);
+static void terminal_window_set_fixed_size(LXTerminal * terminal);
+static void terminal_switch_page_event(GtkNotebook * notebook, GtkNotebookPage * page, guint num, LXTerminal * terminal);
+static void terminal_window_title_changed_event(GtkWidget * vte, Term * term);
+static void terminal_window_exit(LXTerminal * terminal, GObject * where_the_object_was);
+static void terminal_child_exited_event(VteTerminal * vte, Term * term);
+static gboolean terminal_tab_button_press_event(GtkWidget * widget, GdkEventButton * event, Term * term);
+static gboolean terminal_vte_button_press_event(VteTerminal * vte, GdkEventButton * event, Term * term);
+static void terminal_settings_apply_to_term(LXTerminal * terminal, Term * term);
+static Term * terminal_new(LXTerminal * terminal, const gchar * label, const gchar * pwd, gchar * * env, const gchar * exec);
+static void terminal_free(Term * term);
+static void terminal_menubar_initialize(LXTerminal * terminal);
+static void terminal_accelerator_initialize(LXTerminal * terminal);
+static void terminal_menu_accelerator_update(LXTerminal * terminal);
+static void terminal_settings_apply(LXTerminal * terminal);
+
+/* Menu accelerator saved when the user disables it. */
+static char * saved_menu_accelerator = NULL;
+
+/* Help when user enters an invalid command. */
+static gchar usage_display[] = {
 	"Usage:\n"
 	"  lxterminal [Options...] - LXTerminal is a terminal emulator\n\n"
 	"Options:\n"
 	"  -e, --command=STRING             Execute the argument to this option inside the terminal\n"
-	"  -t, -T, --title=STRING               Set the terminal's title\n"
+	"  --geometry=COLUMNSxROWS          Set the terminal's size\n"
+	"  -l, --loginshell                 Execute login shell\n"
+	"  -t, -T, --title=STRING           Set the terminal's title\n"
 	"  --working-directory=DIRECTORY    Set the terminal's working directory\n"
-	"  --geometry=GEOMETRY              X geometry specification (see \"X\" man page), can be specified once per window to be opened.\n"
-	"  -l, --loginshell                 Executes login shell.\n"
 };
 
+/* Descriptors for menu top level. */
 static GtkActionEntry menus[] =
 {
 	{ "File", NULL, N_("_File") },
 	{ "Edit", NULL, N_("_Edit") },
-//	{ "View", NULL, N_("_View") },
 	{ "Tabs", NULL, N_("_Tabs") },
 	{ "Help", NULL, N_("_Help") }
 };
 #define MENUBAR_MENU_COUNT G_N_ELEMENTS(menus)
 
-static void
-gdk_window_get_geometry_hints(GdkWindow *window,
-								GdkGeometry *geometry,
-								GdkWindowHints *geom_mask)
+/* Descriptors for menu bar items. */
+static GtkActionEntry menu_items[] =
 {
-	XSizeHints size_hints;
-	glong junk_size_mask = 0;
-
-	g_return_if_fail (GDK_IS_WINDOW (window));
-	g_return_if_fail (geometry != NULL);
-	g_return_if_fail (geom_mask != NULL);
-
-	*geom_mask = 0;
-
-	if (GDK_WINDOW_DESTROYED (window))
-		return;
-
-	if (!XGetWMNormalHints (GDK_WINDOW_XDISPLAY (window),
-							GDK_WINDOW_XID (window),
-							&size_hints,
-							&junk_size_mask))
-	return;
-
-	if (size_hints.flags & PMinSize) {
-		*geom_mask |= GDK_HINT_MIN_SIZE;
-		geometry->min_width = size_hints.min_width;
-		geometry->min_height = size_hints.min_height;
-	}
-
-	if (size_hints.flags & PMaxSize) {
-		*geom_mask |= GDK_HINT_MAX_SIZE;
-		geometry->max_width = MAX (size_hints.max_width, 1);
-		geometry->max_height = MAX (size_hints.max_height, 1);
-	}
-
-	if (size_hints.flags & PResizeInc) {
-		*geom_mask |= GDK_HINT_RESIZE_INC;
-		geometry->width_inc = size_hints.width_inc;
-		geometry->height_inc = size_hints.height_inc;
-	}
-
-	if (size_hints.flags & PAspect) {
-		*geom_mask |= GDK_HINT_ASPECT;
-		geometry->min_aspect = (gdouble) size_hints.min_aspect.x / (gdouble) size_hints.min_aspect.y;
-		geometry->max_aspect = (gdouble) size_hints.max_aspect.x / (gdouble) size_hints.max_aspect.y;
-	}
-
-	if (size_hints.flags & PWinGravity) {
-		*geom_mask |= GDK_HINT_WIN_GRAVITY;
-		geometry->win_gravity = size_hints.win_gravity;
-	}
-}
+	{ "File_NewWindow", GTK_STOCK_ADD, N_("New _Window"), NEW_WINDOW_ACCEL, "New Window", G_CALLBACK(terminal_new_window_activate_event) },
+	{ "File_NewTab", GTK_STOCK_ADD, N_("New _Tab"), NEW_TAB_ACCEL, "New Tab", G_CALLBACK(terminal_new_tab_activate_event) },
+	{ "File_Sep1", NULL, "Sep" },
+	{ "File_CloseTab", GTK_STOCK_CLOSE, N_("_Close Tab"), CLOSE_TAB_ACCEL, "Close Tab", G_CALLBACK(terminal_close_tab_activate_event) },
+	{ "File_Quit", GTK_STOCK_QUIT, N_("_Quit"), QUIT_ACCEL, "Quit", G_CALLBACK(gtk_main_quit) },
+	{ "Edit_Copy", GTK_STOCK_COPY, N_("Cop_y"), COPY_ACCEL, "Copy", G_CALLBACK(terminal_copy_activate_event) },
+	{ "Edit_Paste", GTK_STOCK_PASTE, N_("_Paste"), PASTE_ACCEL, "Paste", G_CALLBACK(terminal_paste_activate_event) },
+	{ "Edit_Sep1", NULL, "Sep" },
+	{ "Edit_Preferences", GTK_STOCK_EXECUTE, N_("Preference_s"), NULL, "Preferences", G_CALLBACK(terminal_preferences_dialog) },
+	{ "Tabs_NameTab", GTK_STOCK_INFO, N_("Na_me Tab"), NAME_TAB_ACCEL, "Name Tab", G_CALLBACK(terminal_name_tab_activate_event) },
+	{ "Tabs_PreviousTab", GTK_STOCK_GO_BACK, N_("Pre_vious Tab"), PREVIOUS_TAB_ACCEL, "Previous Tab", G_CALLBACK(terminal_previous_tab_activate_event) },
+	{ "Tabs_NextTab", GTK_STOCK_GO_FORWARD, N_("Ne_xt Tab"), NEXT_TAB_ACCEL, "Next Tab", G_CALLBACK(terminal_next_tab_activate_event) },
+	{ "Tabs_MoveTabLeft", NULL, N_("Move Tab _Left"), MOVE_TAB_LEFT_ACCEL, "Move Tab Left", G_CALLBACK(terminal_move_tab_left_activate_event) },
+	{ "Tabs_MoveTabRight", NULL, N_("Move Tab _Right"), MOVE_TAB_RIGHT_ACCEL, "Move Tab Right", G_CALLBACK(terminal_move_tab_right_activate_event) },
+	{ "Help_About", GTK_STOCK_ABOUT, N_("_About"), NULL, "About", G_CALLBACK(terminal_about_activate_event) }
+};
+#define MENUBAR_MENUITEM_COUNT G_N_ELEMENTS(menu_items)
 
-static gboolean terminal_window_resize(GtkWidget *widget, GtkRequisition *requisition, LXTerminal *terminal)
+/* Descriptors for popup menu items, accessed via right click on the terminal. */
+static GtkActionEntry vte_menu_items[] =
 {
-	Term *term;
-	GdkGeometry hints;
-	gint xpad;
-	gint ypad;
-	gint i;
-
-	if (!terminal->fixedsize) {
-		return FALSE;
-	}
-
-	terminal->fixedsize = FALSE;
-
-	/* getting window size by fixed */
-	term = g_ptr_array_index(terminal->terms, 0);
-	vte_terminal_get_padding(VTE_TERMINAL(term->vte), &xpad, &ypad);
-	hints.width_inc = VTE_TERMINAL(term->vte)->char_width;
-	hints.height_inc = VTE_TERMINAL(term->vte)->char_height;
-	hints.base_width = xpad;
-	hints.base_height = ypad;
-	hints.min_width = hints.base_width + hints.width_inc * 4;
-	hints.min_height = hints.base_height + hints.height_inc * 2;
-
-	/* allow resizing by user */
-	for (i=0;i<terminal->terms->len;i++) {
-		term = g_ptr_array_index(terminal->terms, i);
-
-		gtk_window_set_geometry_hints(GTK_WINDOW(terminal->mainw),
-									term->vte,
-									&hints,
-									GDK_HINT_RESIZE_INC
-									| GDK_HINT_MIN_SIZE
-									| GDK_HINT_BASE_SIZE);
-	}
-
-	/* setting fixed size */
-	gtk_window_resize(GTK_WINDOW(terminal->mainw), requisition->width, requisition->height);
-
-	return FALSE;
-}
+	{ "VTEMenu", NULL, "VTEMenu" },
+	{ "NewWindow", GTK_STOCK_ADD, N_("New _Window"), NULL, "New Window", G_CALLBACK(terminal_new_window_activate_event) },
+	{ "NewTab", GTK_STOCK_ADD, N_("New _Tab"), NULL, "New Tab", G_CALLBACK(terminal_new_tab_activate_event) },
+	{ "Sep1", NULL, "Sep" },
+	{ "Copy", GTK_STOCK_COPY, N_("Cop_y"), NULL, "Copy", G_CALLBACK(terminal_copy_activate_event) },
+	{ "Paste", GTK_STOCK_PASTE, N_("_Paste"), NULL, "Paste", G_CALLBACK(terminal_paste_activate_event) },
+	{ "Sep2", NULL, "Sep" },
+	{ "Preferences", GTK_STOCK_EXECUTE, N_("Preference_s"), NULL, "Preferences", G_CALLBACK(terminal_preferences_dialog) },
+	{ "Sep3", NULL, "Sep" },
+	{ "NameTab", GTK_STOCK_INFO, N_("Na_me Tab"), NULL, "Name Tab", G_CALLBACK(terminal_name_tab_activate_event) },
+	{ "PreviousTab", GTK_STOCK_GO_BACK, N_("Pre_vious Tab"), NULL, "Previous Tab", G_CALLBACK(terminal_previous_tab_activate_event) },
+	{ "NextTab", GTK_STOCK_GO_FORWARD, N_("Ne_xt Tab"), NULL, "Next Tab", G_CALLBACK(terminal_next_tab_activate_event) },
+	{ "Tabs_MoveTabLeft", NULL, N_("Move Tab _Left"), NULL, "Move Tab Left", G_CALLBACK(terminal_move_tab_left_activate_event) },
+	{ "Tabs_MoveTabRight", NULL, N_("Move Tab _Right"), NULL, "Move Tab Right", G_CALLBACK(terminal_move_tab_right_activate_event) },
+	{ "CloseTab", GTK_STOCK_CLOSE, N_("_Close Tab"), NULL, "Close Tab", G_CALLBACK(terminal_close_tab_activate_event) }
+};
+#define VTE_MENUITEM_COUNT G_N_ELEMENTS(vte_menu_items)
 
-static void terminal_window_set_fixed_size(LXTerminal *terminal)
+/* Copied out of static function in gdk_window.
+ * A wrapper around XGetWMNormalHints. */
+static void gdk_window_get_geometry_hints(GdkWindow * window, GdkGeometry * geometry, GdkWindowHints * geometry_mask)
 {
-	Term *term;
-	gint i;
+    g_return_if_fail(GDK_IS_WINDOW (window));
+    g_return_if_fail(geometry != NULL);
+    g_return_if_fail(geometry_mask != NULL);
 
-	terminal->fixedsize = TRUE;
+    *geometry_mask = 0;
 
-	for (i=0;i<terminal->terms->len;i++) {
-		term = g_ptr_array_index(terminal->terms, i);
+    if (GDK_WINDOW_DESTROYED(window))
+        return;
 
-		gtk_window_set_geometry_hints(GTK_WINDOW(terminal->mainw),
-									term->vte,
-									&terminal->geometry,
-									terminal->geom_mask);
-	}
-}
+    XSizeHints size_hints;
+    glong junk_size_mask = 0;
+    if ( ! XGetWMNormalHints(GDK_WINDOW_XDISPLAY(window), GDK_WINDOW_XID(window), &size_hints, &junk_size_mask))
+        return;
 
-static gboolean term_switchtab(Term *term)
-{
-	LXTerminal *terminal = term->parent;        
-	gtk_notebook_set_current_page(GTK_NOTEBOOK(terminal->notebook), term->index);
-	return TRUE;
-}
+    if (size_hints.flags & PMinSize)
+    {
+        *geometry_mask |= GDK_HINT_MIN_SIZE;
+        geometry->min_width = size_hints.min_width;
+        geometry->min_height = size_hints.min_height;
+    }
 
-static gboolean terminal_copy(GtkAction *action, gpointer data)
-{
-	LXTerminal *terminal = (LXTerminal *)data;
-	Term *term;
+    if (size_hints.flags & PMaxSize)
+    {
+        *geometry_mask |= GDK_HINT_MAX_SIZE;
+        geometry->max_width = MAX (size_hints.max_width, 1);
+        geometry->max_height = MAX (size_hints.max_height, 1);
+    }
 
-	/* getting current vte */
-	term = g_ptr_array_index(terminal->terms, gtk_notebook_get_current_page(GTK_NOTEBOOK(terminal->notebook)));
+    if (size_hints.flags & PResizeInc)
+    {
+        *geometry_mask |= GDK_HINT_RESIZE_INC;
+        geometry->width_inc = size_hints.width_inc;
+        geometry->height_inc = size_hints.height_inc;
+    }
 
-	/* copy from vte */
-	vte_terminal_copy_clipboard(VTE_TERMINAL(term->vte));
+    if (size_hints.flags & PAspect)
+    {
+        *geometry_mask |= GDK_HINT_ASPECT;
+        geometry->min_aspect = (gdouble) size_hints.min_aspect.x / (gdouble) size_hints.min_aspect.y;
+        geometry->max_aspect = (gdouble) size_hints.max_aspect.x / (gdouble) size_hints.max_aspect.y;
+    }
 
-	return TRUE;
+    if (size_hints.flags & PWinGravity)
+    {
+        *geometry_mask |= GDK_HINT_WIN_GRAVITY;
+        geometry->win_gravity = size_hints.win_gravity;
+    }
 }
 
-static gboolean terminal_copy_accel(gpointer data, guint action, GtkWidget *item)
+/* Accessor for border values from VteTerminal. */
+static GtkBorder * terminal_get_border(Term * term)
 {
-	return terminal_copy(NULL, data);
+#if VTE_CHECK_VERSION(0, 24, 0)
+    /* Style property, new in 0.24.0, replaces the function below. */
+    GtkBorder * border;
+    gtk_widget_style_get(term->vte, "inner-border", &border, NULL);
+    return gtk_border_copy(border);
+#else
+    /* Deprecated function produces a warning. */
+    GtkBorder * border = gtk_border_new();
+    vte_terminal_get_padding(VTE_TERMINAL(term->vte), &border->left, &border->top);
+    return border;
+#endif
 }
 
-static gboolean terminal_paste(GtkAction *action, gpointer data)
+/* Restore the terminal geometry after a font size change or hiding the tab bar. */
+static void terminal_geometry_restore(Term * term)
 {
-	LXTerminal *terminal = (LXTerminal *)data;
-	Term *term;
-
-	/* getting current vte */
-	term = g_ptr_array_index(terminal->terms, gtk_notebook_get_current_page(GTK_NOTEBOOK(terminal->notebook)));
-
-	/* copy from vte */
-	vte_terminal_paste_clipboard(VTE_TERMINAL(term->vte));
+    /* Set fixed VTE size. */
+    terminal_window_set_fixed_size(term->parent);
+
+    /* Recover the window size. */
+    GtkBorder * border = terminal_get_border(term);
+    vte_terminal_set_size(VTE_TERMINAL(term->vte),
+        vte_terminal_get_column_count(VTE_TERMINAL(term->vte)),
+        vte_terminal_get_row_count(VTE_TERMINAL(term->vte)));
+    gtk_window_resize(GTK_WINDOW(term->parent->window),
+        border->left + VTE_TERMINAL(term->vte)->char_width,
+        border->top + VTE_TERMINAL(term->vte)->char_height);
+    gtk_border_free(border);
+}
 
-	return TRUE;
+/* Set the position of the tabs on the main window. */
+static void terminal_tab_set_position(GtkWidget * notebook, gint tab_position)
+{
+    switch (tab_position)
+    {
+        case 0:
+            gtk_notebook_set_tab_pos(GTK_NOTEBOOK(notebook), GTK_POS_TOP);
+            break;
+        case 1:
+            gtk_notebook_set_tab_pos(GTK_NOTEBOOK(notebook), GTK_POS_BOTTOM);
+            break;
+        case 2:
+            gtk_notebook_set_tab_pos(GTK_NOTEBOOK(notebook), GTK_POS_LEFT);
+            break;
+        default:
+            gtk_notebook_set_tab_pos(GTK_NOTEBOOK(notebook), GTK_POS_RIGHT);
+            break;
+    }
 }
 
-static gboolean terminal_paste_accel(gpointer data, guint action, GtkWidget *item)
+/* Initialize the <ALT> n accelerators, where n is a digit.
+ * These switch to the tab selected by the digit, if it exists. */
+static void terminal_initialize_switch_tab_accelerator(Term * term)
 {
-	return terminal_paste(NULL, data);
+    if ((term->index + 1) < 10)
+    {
+        /* Formulate the accelerator name. */
+        char switch_tab_accel[1 + 3 + 1 + 1 + 1]; /* "<ALT>n" */
+        sprintf(switch_tab_accel, "<ALT>%d", term->index + 1);
+
+        /* Parse the accelerator name. */
+        guint key;
+        GdkModifierType mods;
+        gtk_accelerator_parse(switch_tab_accel, &key, &mods);
+
+        /* Define the accelerator. */
+        term->closure = g_cclosure_new_swap(G_CALLBACK(terminal_switch_tab_accelerator), term, NULL);
+        gtk_accel_group_connect(term->parent->accel_group, key, mods, GTK_ACCEL_LOCKED, term->closure);
+    }
 }
 
-static void terminal_nexttab(GtkAction *action, gpointer data)
+/* Handler for accelerator <ALT> n, where n is a digit.
+ * Switch to the tab selected by the digit, if it exists. */
+static void terminal_switch_tab_accelerator(Term * term)
 {
-	LXTerminal *terminal = (LXTerminal *)data;
+    LXTerminal * terminal = term->parent;
+    if (term->index < gtk_notebook_get_n_pages(GTK_NOTEBOOK(terminal->notebook)))
+        gtk_notebook_set_current_page(GTK_NOTEBOOK(terminal->notebook), term->index);
+}
 
-	/* cycle */
-	if (gtk_notebook_get_current_page(GTK_NOTEBOOK(terminal->notebook))==gtk_notebook_get_n_pages(GTK_NOTEBOOK(terminal->notebook))-1)
-		gtk_notebook_set_current_page(GTK_NOTEBOOK(terminal->notebook), 0);
-	else
-		gtk_notebook_next_page(GTK_NOTEBOOK(terminal->notebook));
+/* Handler for "activate" signal on File/New Window menu item.
+ * Open a new window. */
+static void terminal_new_window_activate_event(GtkAction * action, LXTerminal * terminal)
+{
+    CommandArguments arguments;
+    memset(&arguments, 0, sizeof(arguments));
+    lxterminal_initialize(terminal->parent, &arguments, terminal->setting);
 }
 
-static void terminal_nexttab_accel(gpointer data, guint action, GtkWidget *item)
+/* Handler for accelerator <SHIFT><CTRL> N.  Open a new window. */
+static void terminal_new_window_accelerator(LXTerminal * terminal, guint action, GtkWidget * item)
 {
-	terminal_nexttab(NULL, data);
+    terminal_new_window_activate_event(NULL, terminal);
 }
 
-static void terminal_prevtab(GtkAction *action, gpointer data)
+/* Handler for "activate" signal on File/New Tab menu item.
+ * Open a new tab. */
+static void terminal_new_tab_activate_event(GtkAction * action, LXTerminal * terminal)
 {
-	LXTerminal *terminal = (LXTerminal *)data;
+    gchar * proc_cwd = NULL;
+
+#ifdef __linux
+    /* Try to get the working directory from /proc. */
+    gint current = gtk_notebook_get_current_page(GTK_NOTEBOOK(terminal->notebook));
+    if (current != -1)
+    {
+        /* Search for the Term structure corresponding to the current tab. */
+        int i;
+        for (i = 0; i < terminal->terms->len; i += 1)
+        {
+            Term * term = g_ptr_array_index(terminal->terms, i);
+            if (term->index == current)
+            {
+                /* Get the working directory corresponding to the process ID. */
+                gchar proc_cwd_link[PATH_MAX];
+                g_snprintf(proc_cwd_link, PATH_MAX, "/proc/%d/cwd", term->pid);
+                proc_cwd = g_file_read_link(proc_cwd_link, NULL);
+                break;
+            }
+        }
+
+    }
+#endif
 
-	/* cycle */
-	if (gtk_notebook_get_current_page(GTK_NOTEBOOK(terminal->notebook))==0)
-		gtk_notebook_set_current_page(GTK_NOTEBOOK(terminal->notebook), -1);
-	else
-		gtk_notebook_prev_page(GTK_NOTEBOOK(terminal->notebook));
+    /* Propagate the working directory of the current tab to the new tab.
+     * If the working directory was determined above, use it; otherwise default to the working directory of the process.
+     * Create the new terminal. */
+    if (proc_cwd == NULL)
+        proc_cwd = g_get_current_dir();
+    Term * term = terminal_new(terminal, _("LXTerminal"), proc_cwd, NULL, NULL);
+    g_free(proc_cwd);
+
+    /* Add a tab to the notebook and the "terms" array. */
+    gtk_notebook_append_page(GTK_NOTEBOOK(terminal->notebook), term->box, term->tab);
+    term->index = gtk_notebook_get_n_pages(GTK_NOTEBOOK(terminal->notebook)) - 1;
+    g_ptr_array_add(terminal->terms, term);
+
+    /* Redraw the terminal. */
+    gtk_widget_queue_draw(term->vte);
+
+    /* Make the new terminal's tab current and, if we went from one to more than one tab,
+     * turn the tab display on. */
+    gtk_notebook_set_current_page(GTK_NOTEBOOK(term->parent->notebook), term->index);
+    if (term->index > 0)
+    {
+        terminal_window_set_fixed_size(terminal);
+        gtk_notebook_set_show_tabs(GTK_NOTEBOOK(term->parent->notebook), TRUE);
+    }
+    terminal_initialize_switch_tab_accelerator(term);
 }
 
-static void terminal_prevtab_accel(gpointer data, guint action, GtkWidget *item)
+/* Handler for accelerator <SHIFT><CTRL> T.  Open a new tab. */
+static void terminal_new_tab_accelerator(LXTerminal * terminal, guint action, GtkWidget * item)
 {
-	terminal_prevtab(NULL, data);
+    terminal_new_tab_activate_event(NULL, terminal);
 }
 
-/* direction: -1=left 1=right */
-static void terminal_movetab(GtkAction *action, gpointer data, gint direction)
+/* Handler for "activate" signal on File/Close Tab menu item.
+ * Close the current tab. */
+static void terminal_close_tab_activate_event(GtkAction * action, LXTerminal * terminal)
 {
-	LXTerminal *terminal = (LXTerminal *)data;
-	GtkNotebook *notebook = GTK_NOTEBOOK(terminal->notebook);
-	gint curPageNum = gtk_notebook_get_current_page( notebook );
-
-	gtk_notebook_reorder_child(
-		notebook,
-		gtk_notebook_get_nth_page(notebook, curPageNum),
-		curPageNum + direction
-		);
+    Term * term = g_ptr_array_index(terminal->terms, gtk_notebook_get_current_page(GTK_NOTEBOOK(terminal->notebook)));
+    terminal_child_exited_event(VTE_TERMINAL(term->vte), term);
 }
 
-static void terminal_movetableft(GtkAction *action, gpointer data)
+/* Handler for accelerator <SHIFT><CTRL> W.  Close the current tab. */
+static void terminal_close_tab_accelerator(LXTerminal * terminal, guint action, GtkWidget * item)
 {
-	terminal_movetab(action, data, -1);
+    terminal_close_tab_activate_event(NULL, terminal);
 }
 
-static void terminal_movetableft_accel(gpointer data, guint action, GtkWidget *item)
+/* Handler for "activate" signal on Edit/Copy menu item.
+ * Copy to the clipboard. */
+static void terminal_copy_activate_event(GtkAction * action, LXTerminal * terminal)
 {
-	terminal_movetableft(NULL, data);
+    Term * term = g_ptr_array_index(terminal->terms, gtk_notebook_get_current_page(GTK_NOTEBOOK(terminal->notebook)));
+    vte_terminal_copy_clipboard(VTE_TERMINAL(term->vte));
 }
 
-static void terminal_movetabright(GtkAction *action, gpointer data)
+/* Handler for accelerator <CTRL><SHIFT> C.  Copy to the clipboard. */
+static void terminal_copy_accelerator(LXTerminal * terminal, guint action, GtkWidget * item)
 {
-	terminal_movetab(action, data, 1);
+    terminal_copy_activate_event(NULL, terminal);
 }
 
-static void terminal_movetabright_accel(gpointer data, guint action, GtkWidget *item)
+/* Handler for "activate" signal on Edit/Paste menu item.
+ * Paste from the clipboard. */
+static void terminal_paste_activate_event(GtkAction * action, LXTerminal * terminal)
 {
-	terminal_movetabright(NULL, data);
+    Term * term = g_ptr_array_index(terminal->terms, gtk_notebook_get_current_page(GTK_NOTEBOOK(terminal->notebook)));
+    vte_terminal_paste_clipboard(VTE_TERMINAL(term->vte));
 }
 
-static void terminal_closetab(GtkAction *action, gpointer data)
+/* Handler for accelerator <CTRL><SHIFT> V.  Paste from the clipboard. */
+static void terminal_paste_accelerator(LXTerminal * terminal, guint action, GtkWidget * item)
 {
-	LXTerminal *terminal = (LXTerminal *)data;
-	Term *term;
-
-	/* getting current vte */
-	term = g_ptr_array_index(terminal->terms, gtk_notebook_get_current_page(GTK_NOTEBOOK(terminal->notebook)));
-
-	/* release child */
-	terminal_childexit(VTE_TERMINAL(term->vte), term);
+    terminal_paste_activate_event(NULL, terminal);
 }
 
-static void terminal_closetab_accel(gpointer data, guint action, GtkWidget *item)
+/* Handler for "response" signal on Name Tab dialog. */
+static void terminal_name_tab_response_event(GtkWidget * dialog, gint response, LXTerminal * terminal)
 {
-	terminal_closetab(NULL, data);
+    if (response == GTK_RESPONSE_OK)
+    {
+        GtkWidget * dialog_item = g_object_get_data(G_OBJECT(dialog), "entry");
+
+        gint current = gtk_notebook_get_current_page(GTK_NOTEBOOK(terminal->notebook));
+        if (current != -1)
+        {
+            /* Search for the Term structure corresponding to the current tab. */
+            int i;
+            for (i = 0; i < terminal->terms->len; i += 1)
+            {
+                Term * term = g_ptr_array_index(terminal->terms, i);
+                if (term->index == current)
+                {
+                /* If Term structure found, set the tab's label and mark it so we will never overwrite it. */
+                    term->user_specified_label = TRUE;
+                    gtk_label_set_text(GTK_LABEL(term->label), g_strdup(gtk_entry_get_text(GTK_ENTRY(dialog_item))));
+                    break;
+                }
+            }
+        }
+    }
+
+    /* Dismiss dialog. */
+    gtk_widget_destroy(dialog);
 }
 
-static void terminal_newwindow(GtkAction *action, gpointer data)
+/* Handler for "activate" signal on Tabs/Name Tab menu item.
+ * Put up a dialog to get a user specified name for the tab. */
+static void terminal_name_tab_activate_event(GtkAction * action, LXTerminal * terminal)
 {
-	LXTerminal *terminal = (LXTerminal *)data;
-
-	lxterminal_init(terminal->parent, 0, NULL, terminal->setting);
+    GtkWidget * dialog = gtk_dialog_new_with_buttons(
+        _("Name Tab"),
+        GTK_WINDOW(terminal->window),
+        0,
+        GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
+        GTK_STOCK_OK, GTK_RESPONSE_OK,
+        NULL);
+    gtk_window_set_icon_from_file(GTK_WINDOW(dialog), PACKAGE_DATA_DIR "/pixmaps/lxterminal.png", NULL);
+    g_signal_connect(G_OBJECT(dialog), "response", G_CALLBACK(terminal_name_tab_response_event), terminal);
+    GtkWidget * dialog_item = gtk_entry_new();
+    g_object_set_data(G_OBJECT(dialog), "entry", (gpointer) dialog_item);
+    gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox), dialog_item, FALSE, FALSE, 2);
+    gint current = gtk_notebook_get_current_page(GTK_NOTEBOOK(terminal->notebook));
+    if (current != -1)
+    {
+        /* Search for the Term structure corresponding to the current tab. */
+        int i;
+        for (i = 0; i < terminal->terms->len; i += 1)
+        {
+            Term * term = g_ptr_array_index(terminal->terms, i);
+            if (term->index == current)
+            {
+                gtk_entry_set_text(GTK_ENTRY(dialog_item), gtk_label_get_text(GTK_LABEL(term->label)));
+                break;
+            }
+        }
+    }        
+    gtk_widget_show_all(dialog);
 }
 
-static void terminal_newwindow_accel(gpointer data, guint action, GtkWidget *item)
+/* Handler for accelerator <CTRL><SHIFT> R.  Name the tab. */
+static void terminal_name_tab_accelerator(LXTerminal * terminal, guint action, GtkWidget * item)
 {
-	terminal_newwindow(NULL, data);
+    terminal_name_tab_activate_event(NULL, terminal);
 }
 
-static void term_set_swicth_accel(Term *term)
+/* Handler for "activate" signal on Tabs/Previous Tab menu item.
+ * Cycle through tabs in the reverse direction. */
+static void terminal_previous_tab_activate_event(GtkAction * action, LXTerminal * terminal)
 {
-	if (term->index + 1 < 10) {
-    	char switch_tab_accel[1 + 3 + 1 + 1 + 1]; /* "<ALT>n" */
-		guint key;
-		GdkModifierType mods;
-        GtkAccelGroup *accel_group = term->parent->menubar->accel_group;
-
-		sprintf(switch_tab_accel, "<ALT>%d", term->index + 1);
-		gtk_accelerator_parse(switch_tab_accel, &key, &mods);
-        term->closure = g_cclosure_new_swap(G_CALLBACK(term_switchtab), term, NULL);
-		gtk_accel_group_connect(accel_group, key, mods, GTK_ACCEL_LOCKED, 
-                                term->closure);
-	}
+    /* Cycle through tabs. */
+    if (gtk_notebook_get_current_page(GTK_NOTEBOOK(terminal->notebook)) == 0)
+        gtk_notebook_set_current_page(GTK_NOTEBOOK(terminal->notebook), -1);
+    else
+        gtk_notebook_prev_page(GTK_NOTEBOOK(terminal->notebook));
 }
 
-static void terminal_newtab(GtkWidget *widget, gpointer data)
+/* Handler for accelerator <CTRL><PAGE UP>.  Cycle through tabs in the reverse direction. */
+static void terminal_previous_tab_accelerator(LXTerminal * terminal, guint action, GtkWidget * item)
 {
-	LXTerminal *terminal = (LXTerminal *)data;
-	Term *term;
-
-#ifdef __linux
-	gchar cwd[PATH_MAX];
-
-	gint current = gtk_notebook_get_current_page(GTK_NOTEBOOK(terminal->notebook));
-	if (current != -1) {
-		gchar proc_cwd_link[PATH_MAX];
-		gchar *proc_cwd;
-		gint i;
-		for (i=0;i<terminal->terms->len;i++) {
-			term = g_ptr_array_index(terminal->terms, i);
-			if (term->index == current)
-				break;
-		}
-
-		g_message("%d", term->pid);
-		g_snprintf(proc_cwd_link, PATH_MAX, "/proc/%d/cwd", term->pid);
-		proc_cwd = g_file_read_link(proc_cwd_link, NULL);
-		if (proc_cwd) {
-			g_strlcpy(cwd, proc_cwd, PATH_MAX);
-			g_free(proc_cwd);
-		} else {
-			g_strlcpy(cwd, g_get_current_dir(), PATH_MAX);
-		}
-	} else {
-		g_strlcpy(cwd, g_get_current_dir(), PATH_MAX);
-	}
-
-	term = terminal_new(terminal, _("LXTerminal"), cwd, NULL, NULL);
-#else
-	term = terminal_new(terminal, _("LXTerminal"), g_get_current_dir(), NULL, NULL);
-#endif
+    terminal_previous_tab_activate_event(NULL, terminal);
+}
 
-	/* add page to notebook */
-	gtk_notebook_append_page(GTK_NOTEBOOK(terminal->notebook), term->box, term->label->main);
-	term->index = gtk_notebook_get_n_pages(GTK_NOTEBOOK(terminal->notebook)) - 1;
-	g_ptr_array_add(terminal->terms, term);
+/* Handler for "activate" signal on Tabs/Next Tab menu item.
+ * Cycle through tabs in the forward direction. */
+static void terminal_next_tab_activate_event(GtkAction * action, LXTerminal * terminal)
+{
+    /* Cycle through tabs. */
+    if (gtk_notebook_get_current_page(GTK_NOTEBOOK(terminal->notebook)) == gtk_notebook_get_n_pages(GTK_NOTEBOOK(terminal->notebook)) - 1)
+        gtk_notebook_set_current_page(GTK_NOTEBOOK(terminal->notebook), 0);
+    else
+        gtk_notebook_next_page(GTK_NOTEBOOK(terminal->notebook));
+}
 
-	/* push VTE to queue */
-	gtk_widget_queue_draw(term->vte);
+/* Handler for accelerator <CTRL><PAGE DOWN>.  Cycle through tabs in the forward direction. */
+static void terminal_next_tab_accelerator(LXTerminal * terminal, guint action, GtkWidget * item)
+{
+    terminal_next_tab_activate_event(NULL, terminal);
+}
 
-	gtk_notebook_set_current_page(GTK_NOTEBOOK(term->parent->notebook), term->index);
+/* Helper for move tab left and right. */
+static void terminal_move_tab_execute(LXTerminal * terminal, gint direction)
+{
+    GtkNotebook * notebook = GTK_NOTEBOOK(terminal->notebook);
+    gint current_page_number = gtk_notebook_get_current_page(notebook);
+    gtk_notebook_reorder_child(notebook, gtk_notebook_get_nth_page(notebook, current_page_number), current_page_number + direction);
+}
 
-	if (term->index > 0) {
-		/* fixed VTE size */
-		terminal_window_set_fixed_size(terminal);
+/* Handler for "activate" signal on Tabs/Move Tab Left menu item.
+ * Move the tab one position in the reverse direction. */
+static void terminal_move_tab_left_activate_event(GtkAction * action, LXTerminal * terminal)
+{
+    terminal_move_tab_execute(terminal, -1);
+}
 
-		/* show tab */
-		gtk_notebook_set_show_tabs(GTK_NOTEBOOK(term->parent->notebook), TRUE);
-	}
-    term_set_swicth_accel(term);
+/* Handler for accelerator <SHIFT><CTRL><PAGE UP>.  Move the tab one position in the reverse direction. */
+static void terminal_move_tab_left_accelerator(LXTerminal * terminal, guint action, GtkWidget * item)
+{
+    terminal_move_tab_execute(terminal, -1);
 }
 
-static void terminal_newtab_accel(gpointer data, guint action, GtkWidget *item)
+/* Handler for "activate" signal on Tabs/Move Tab Right menu item.
+ * Move the tab one position in the forward direction. */
+static void terminal_move_tab_right_activate_event(GtkAction * action, LXTerminal * terminal)
 {
-	terminal_newtab(NULL, data);
+    terminal_move_tab_execute(terminal, 1);
 }
 
-static void open_url( GtkAboutDialog* dlg, const gchar* url, gpointer data )
+/* Handler for accelerator <SHIFT><CTRL><PAGE DOWN>.  Move the tab one position in the forward direction. */
+static void terminal_move_tab_right_accelerator(LXTerminal * terminal, guint action, GtkWidget * item)
 {
-    /* FIXME: */
+    terminal_move_tab_execute(terminal, 1);
 }
 
-static void terminal_about(GtkAction *action, gpointer data)
+/* Handler for "activate" signal on Help/About menu item. */ 
+static void terminal_about_activate_event(GtkAction * action, LXTerminal * terminal)
 {
-    GtkWidget * about_dlg;
-    const gchar *authors[] =
+    const gchar * authors[] =
     {
         "Fred Chien <cfsghost@gmail.com>",
+        "Marty Jack <martyj19@comcast.net>",
         NULL
     };
     /* TRANSLATORS: Replace this string with your names, one name per line. */
-    gchar *translators = _( "translator-credits" );
-
-    gtk_about_dialog_set_url_hook( open_url, NULL, NULL);
-
-    about_dlg = gtk_about_dialog_new ();
-
-    gtk_container_set_border_width ( ( GtkContainer*)about_dlg , 2 );
-    gtk_about_dialog_set_version ( (GtkAboutDialog*)about_dlg, VERSION );
-    gtk_about_dialog_set_name ( (GtkAboutDialog*)about_dlg, _( "LXTerminal" ) );
-    gtk_about_dialog_set_logo( (GtkAboutDialog*)about_dlg, gdk_pixbuf_new_from_file(  PACKAGE_DATA_DIR"/pixmaps/lxterminal.png", NULL ) );
-    gtk_about_dialog_set_copyright ( (GtkAboutDialog*)about_dlg, _( "Copyright (C) 2008" ) );
-    gtk_about_dialog_set_comments ( (GtkAboutDialog*)about_dlg, _( "Terminal emulator for LXDE project" ) );
-    gtk_about_dialog_set_license ( (GtkAboutDialog*)about_dlg, "This program is free software; you can redistribute it and/or\nmodify it under the terms of the GNU General Public License\nas published by the Free Software Foundation; either version 2\nof the License, or (at your option) any later version.\n\nThis program is distributed in the hope that it will be useful,\nbut WITHOUT ANY WARRANTY; without even the implied warranty of\nMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\nGNU General Public License for more details.\n\nYou should have received a copy of the GNU General Public License\nalong with this program; if not, write to the Free Software\nFoundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA." );
-    gtk_about_dialog_set_website ( (GtkAboutDialog*)about_dlg, "http://lxde.org/" );
-    gtk_about_dialog_set_authors ( (GtkAboutDialog*)about_dlg, authors );
-    gtk_about_dialog_set_translator_credits ( (GtkAboutDialog*)about_dlg, translators );
-
-    gtk_dialog_run( ( GtkDialog*)about_dlg );
-    gtk_widget_destroy( about_dlg );
+    gchar * translators = _("translator-credits");
+
+    /* Create and initialize the dialog. */
+    GtkWidget * about_dlg = gtk_about_dialog_new();
+    gtk_about_dialog_set_url_hook(NULL, NULL, NULL);
+    gtk_container_set_border_width(GTK_CONTAINER(about_dlg), 2);
+    gtk_about_dialog_set_version(GTK_ABOUT_DIALOG(about_dlg), VERSION);
+    gtk_about_dialog_set_name (GTK_ABOUT_DIALOG(about_dlg), _("LXTerminal"));
+    gtk_about_dialog_set_logo(GTK_ABOUT_DIALOG(about_dlg), gdk_pixbuf_new_from_file(PACKAGE_DATA_DIR "/pixmaps/lxterminal.png", NULL));
+    gtk_about_dialog_set_copyright(GTK_ABOUT_DIALOG(about_dlg), _("Copyright (C) 2008-2010"));
+    gtk_about_dialog_set_comments(GTK_ABOUT_DIALOG(about_dlg), _("Terminal emulator for LXDE project"));
+    gtk_about_dialog_set_license(GTK_ABOUT_DIALOG(about_dlg), "This program is free software; you can redistribute it and/or\nmodify it under the terms of the GNU General Public License\nas published by the Free Software Foundation; either version 2\nof the License, or (at your option) any later version.\n\nThis program is distributed in the hope that it will be useful,\nbut WITHOUT ANY WARRANTY; without even the implied warranty of\nMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\nGNU General Public License for more details.\n\nYou should have received a copy of the GNU General Public License\nalong with this program; if not, write to the Free Software\nFoundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.");
+    gtk_about_dialog_set_website(GTK_ABOUT_DIALOG(about_dlg), "http://lxde.org/");
+    gtk_about_dialog_set_authors(GTK_ABOUT_DIALOG(about_dlg), authors);
+    gtk_about_dialog_set_translator_credits(GTK_ABOUT_DIALOG(about_dlg), translators);
+
+    /* Display the dialog, wait for the user to click OK, and dismiss the dialog. */
+    gtk_dialog_run(GTK_DIALOG(about_dlg));
+    gtk_widget_destroy(about_dlg);
 }
 
-static GtkActionEntry menu_items[] =
+/* Handler for "size-request" signal on the top level window. */
+static gboolean terminal_window_size_request_event(GtkWidget * widget, GtkRequisition * requisition, LXTerminal * terminal)
 {
-	{ "File_NewWindow", GTK_STOCK_ADD, N_("New _Window"), NEW_WINDOW_ACCEL, "New Window", G_CALLBACK(terminal_newwindow)},
-	{ "File_NewTab", GTK_STOCK_ADD, N_("New _Tab"), NEW_TAB_ACCEL, "New Tab", G_CALLBACK(terminal_newtab)},
-	{ "File_Sep1", NULL, "Sep" },
-	{ "File_CloseTab", GTK_STOCK_CLOSE, N_("_Close Tab"), CLOSE_TAB_ACCEL, "Close Tab", G_CALLBACK(terminal_closetab)},
-	{ "File_Quit", GTK_STOCK_QUIT, N_("_Quit"), QUIT_ACCEL, "Quit", G_CALLBACK(gtk_main_quit)},
-	{ "Edit_Copy", GTK_STOCK_COPY, N_("Cop_y"), COPY_ACCEL, "Copy", G_CALLBACK(terminal_copy)},
-	{ "Edit_Paste", GTK_STOCK_PASTE, N_("_Paste"), PASTE_ACCEL, "Paste", G_CALLBACK(terminal_paste)},
-	{ "Edit_Sep1", NULL, "Sep" },
-	{ "Edit_Preferences", GTK_STOCK_EXECUTE, N_("Preference_s"), NULL, "Preferences", G_CALLBACK(lxterminal_preferences_dialog)},
-//	{ "View_CharacterEncoding", NULL, N_("_Character Encoding"), NULL, "Character Encoding", NULL},
-	{ "Tabs_PreviousTab", GTK_STOCK_GO_BACK, N_("Pre_vious Tab"), PREVIOUS_TAB_ACCEL, "Previous Tab", G_CALLBACK(terminal_prevtab)},
-	{ "Tabs_NextTab", GTK_STOCK_GO_FORWARD, N_("Ne_xt Tab"), NEXT_TAB_ACCEL, "Next Tab", G_CALLBACK(terminal_nexttab)},
-	{ "Tabs_MoveTabLeft", NULL, N_("Move Tab _Left"), MOVE_TAB_LEFT_ACCEL, "Move Tab Left", G_CALLBACK(terminal_movetableft)},
-	{ "Tabs_MoveTabRight", NULL, N_("Move Tab _Right"), MOVE_TAB_RIGHT_ACCEL, "Move Tab Right", G_CALLBACK(terminal_movetabright)},
-	{ "Help_About", GTK_STOCK_ABOUT, N_("_About"), NULL, "About", G_CALLBACK(terminal_about)}
-};
-#define MENUBAR_MENUITEM_COUNT G_N_ELEMENTS(menu_items)
+    /* Only do this once. */
+    if (terminal->fixed_size)
+    {
+        /* No longer fixed size. */
+        terminal->fixed_size = FALSE;
+
+        /* Initialize geometry hints structure. */
+        Term * term = g_ptr_array_index(terminal->terms, 0);
+        GtkBorder * border = terminal_get_border(term);
+        GdkGeometry hints;
+        hints.width_inc = VTE_TERMINAL(term->vte)->char_width;
+        hints.height_inc = VTE_TERMINAL(term->vte)->char_height;
+        hints.base_width = border->left;
+        hints.base_height = border->top;
+        hints.min_width = hints.base_width + hints.width_inc * 4;
+        hints.min_height = hints.base_height + hints.height_inc * 2;
+        gtk_border_free(border);
+
+        /* Set hints into all terminals.  This makes sure we resize on character cell boundaries. */
+        int i;
+        for (i = 0; i < terminal->terms->len; i += 1)
+        {
+            Term * term = g_ptr_array_index(terminal->terms, i);
+            gtk_window_set_geometry_hints(GTK_WINDOW(terminal->window),
+	        term->vte,
+	        &hints,
+                GDK_HINT_RESIZE_INC | GDK_HINT_MIN_SIZE | GDK_HINT_BASE_SIZE);
+        }
+
+        /* Resize the window. */
+        gtk_window_resize(GTK_WINDOW(terminal->window), requisition->width, requisition->height);
+    }
+    return FALSE;
+}
 
-static GtkActionEntry vte_menu_items[] =
+/* Set geometry hints for the fixed size case. */
+static void terminal_window_set_fixed_size(LXTerminal * terminal)
 {
-	{ "VTEMenu", NULL, "VTEMenu" },
-	{ "NewWindow", GTK_STOCK_ADD, N_("New _Window"), NULL, "New Window", G_CALLBACK(terminal_newwindow)},
-	{ "NewTab", GTK_STOCK_ADD, N_("New _Tab"), NULL, "New Tab", G_CALLBACK(terminal_newtab)},
-	{ "Sep1", NULL, "Sep" },
-	{ "Copy", GTK_STOCK_COPY, N_("Cop_y"), NULL, "Copy", G_CALLBACK(terminal_copy)},
-	{ "Paste", GTK_STOCK_PASTE, N_("_Paste"), NULL, "Paste", G_CALLBACK(terminal_paste)},
-	{ "Sep2", NULL, "Sep" },
-	{ "Preferences", GTK_STOCK_EXECUTE, N_("Preference_s"), NULL, "Preferences", G_CALLBACK(lxterminal_preferences_dialog)},
-	{ "Sep3", NULL, "Sep" },
-	{ "PreviousTab", GTK_STOCK_GO_BACK, N_("Pre_vious Tab"), NULL, "Previous Tab", G_CALLBACK(terminal_prevtab)},
-	{ "NextTab", GTK_STOCK_GO_FORWARD, N_("Ne_xt Tab"), NULL, "Next Tab", G_CALLBACK(terminal_nexttab)},
-	{ "Tabs_MoveTabLeft", NULL, N_("Move Tab _Left"), NULL, "Move Tab Left", G_CALLBACK(terminal_prevtab)},
-	{ "Tabs_MoveTabRight", NULL, N_("Move Tab _Right"), NULL, "Move Tab Right", G_CALLBACK(terminal_nexttab)},
-	{ "CloseTab", GTK_STOCK_CLOSE, N_("_Close Tab"), NULL, "Close Tab", G_CALLBACK(terminal_closetab)}
-};
-#define VTE_MENUITEM_COUNT G_N_ELEMENTS(vte_menu_items)
+    terminal->fixed_size = TRUE;
+    int i;
+    for (i = 0; i < terminal->terms->len; i += 1)
+    {
+        Term * term = g_ptr_array_index(terminal->terms, i);
+        gtk_window_set_geometry_hints(GTK_WINDOW(terminal->window),
+            term->vte,
+            &terminal->geometry,
+            terminal->geometry_mask);
+    }
+}
 
-static void terminal_switch_tab(GtkNotebook *notebook, GtkNotebookPage *page, guint num, gpointer data)
+/* Handler for "switch-page" event on the tab notebook. */
+static void terminal_switch_page_event(GtkNotebook * notebook, GtkNotebookPage * page, guint num, LXTerminal * terminal)
 {
-	const gchar *title;
-	Term *term;
-	LXTerminal *terminal = (LXTerminal *)data;
-
-	if (terminal->terms->len <= num)
-		return;
-
-	term = g_ptr_array_index(terminal->terms, num);
-
-	/* if title of VTE is NULL */
-	if ((title = vte_terminal_get_window_title(VTE_TERMINAL(term->vte))) == NULL)
-		gtk_window_set_title(GTK_WINDOW(terminal->mainw), _("LXTerminal"));
-	else
-		gtk_window_set_title(GTK_WINDOW(terminal->mainw), title);
+    if (terminal->terms->len > num)
+    {
+        /* Propagate the title to the toplevel window. */
+	Term * term = g_ptr_array_index(terminal->terms, num);
+	const gchar * title = vte_terminal_get_window_title(VTE_TERMINAL(term->vte));
+        gtk_window_set_title(GTK_WINDOW(terminal->window), ((title != NULL) ? title : _("LXTerminal")));
+    }
 }
 
-static void terminal_title_changed(VteTerminal *vte, Term *term)
+/* Handler for "window-title-changed" signal on a Term. */
+static void terminal_window_title_changed_event(GtkWidget * vte, Term * term)
 {
-	/* setting label */
-	lxterminal_tab_label_set_text(term->label, vte_terminal_get_window_title(VTE_TERMINAL(vte)));
-	lxterminal_tab_label_set_tooltip_text(term->label, vte_terminal_get_window_title(VTE_TERMINAL(vte)));
-
-	/* setting window title */
-	gtk_window_set_title(GTK_WINDOW(term->parent->mainw), vte_terminal_get_window_title(VTE_TERMINAL(vte)));
+    /* Copy the VTE data out into the tab and the window title, unless the user edited the tab label. */
+    if ( ! term->user_specified_label)
+    {
+        gtk_label_set_text(GTK_LABEL(term->label), vte_terminal_get_window_title(VTE_TERMINAL(vte)));
+        gtk_widget_set_tooltip_text(term->label, vte_terminal_get_window_title(VTE_TERMINAL(vte)));
+    }
+    gtk_window_set_title(GTK_WINDOW(term->parent->window), vte_terminal_get_window_title(VTE_TERMINAL(vte)));
 }
 
-static void terminal_windowexit(gpointer terminal_p, GObject *where_the_object_was)
+/* Weak-notify callback for LXTerminal object. */
+static void terminal_window_exit(LXTerminal * terminal, GObject * where_the_object_was)
 {
-	LXTerminal * terminal = (LXTerminal *) terminal_p;
+    /* If last window, exit main loop. */
+    if (terminal->parent->windows->len == 1)
+        gtk_main_quit();
+
+    else
+    {
+        /* Remove the element and decrease the index number of each succeeding element. */
+        g_ptr_array_remove_index(terminal->parent->windows, terminal->index);
 	int i;
+        for (i = terminal->index; i < terminal->parent->windows->len; i += 1)
+        {
+            LXTerminal * t = g_ptr_array_index(terminal->parent->windows, i);
+            t->index -= 1;
+        }
+    }
+}
 
-	if (terminal->parent->windows->len==1) {
-		gtk_main_quit();
-	} else {
-		g_ptr_array_remove_index(terminal->parent->windows, terminal->index);
+/* Handler for "child-exited" signal on VTE.
+ * Also handler for "activate" signal on Close button of tab and File/Close Tab menu item and accelerator. */
+static void terminal_child_exited_event(VteTerminal * vte, Term * term)
+{
+    LXTerminal * terminal = term->parent;
 
-		/* decreasing index number after the window be removed */
-		for (i=terminal->index;i<terminal->parent->windows->len;i++) {
-			LXTerminal *t = g_ptr_array_index(terminal->parent->windows, i);
-			t->index--;
-		}
+    /* Last tab being deleted.  Deallocate memory and close the window. */
+    if (gtk_notebook_get_n_pages(GTK_NOTEBOOK(terminal->notebook)) == 1)
+    {
+        g_ptr_array_free(terminal->terms, TRUE);
+        gtk_widget_destroy(terminal->window);
+    } 
 
-	}
+    /* Not last tab being deleted. */
+    else
+    {
+        /* Remove the element and decrease the index number of each succeeding element. */
+        g_ptr_array_remove_index(terminal->terms, term->index);
+        int i;
+        for (i = term->index; i < terminal->terms->len; i++)
+        {
+            Term * t = g_ptr_array_index(terminal->terms, i);
+            t->index -= 1;
+        }
+
+        /* Delete the tab and free the Term structure. */
+        gtk_notebook_remove_page(GTK_NOTEBOOK(terminal->notebook), term->index);
+        terminal_free(term);
+
+        /* If only one page is left, hide the tab and correct the geometry. */
+        if (gtk_notebook_get_n_pages(GTK_NOTEBOOK(terminal->notebook)) == 1)
+        {
+            gtk_notebook_set_show_tabs(GTK_NOTEBOOK(terminal->notebook), FALSE);
+            terminal_geometry_restore(g_ptr_array_index(terminal->terms, 0));
+        }
+    }
 }
 
-static void terminal_childexit(VteTerminal *vte, Term *term)
+/* Handler for "button-press-event" signal on a notebook tab. */
+static gboolean terminal_tab_button_press_event(GtkWidget * widget, GdkEventButton * event, Term * term)
 {
-	int i;
-	LXTerminal *terminal = term->parent;
-
-	if(gtk_notebook_get_n_pages(GTK_NOTEBOOK(terminal->notebook))==1) {
-		/* release */
-		g_ptr_array_free(terminal->terms, TRUE);
-
-		/* quit */
-		gtk_widget_destroy(terminal->mainw);
-	} else {
-		/* remove page */
-		g_ptr_array_remove_index(terminal->terms, term->index);
-
-		/* decreasing index number after the page be removed */
-		for (i=term->index;i<terminal->terms->len;i++) {
-			Term *t = g_ptr_array_index(terminal->terms, i);
-			t->index--;
-		}
-
-		/* release */
-		gtk_notebook_remove_page(GTK_NOTEBOOK(terminal->notebook), term->index);
-		terminal_free(term);
-
-		/* if only one page, hide tab */
-		if (gtk_notebook_get_n_pages(GTK_NOTEBOOK(terminal->notebook)) == 1) {
-			gint xpad;
-			gint ypad;
-			gint cols;
-			gint rows;
-
-			/* get original info of VTE */
-			Term *t = g_ptr_array_index(terminal->terms, 0);
-			vte_terminal_get_padding(VTE_TERMINAL(t->vte), &xpad, &ypad);
-			cols = vte_terminal_get_column_count(VTE_TERMINAL(t->vte));
-			rows = vte_terminal_get_row_count(VTE_TERMINAL(t->vte));
-
-			/* fixed VTE size */
-			terminal_window_set_fixed_size(terminal);
-
-			/* hide tab */
-			gtk_notebook_set_show_tabs(GTK_NOTEBOOK(terminal->notebook), FALSE);
-
-			/* recovery window size */
-			vte_terminal_set_size(VTE_TERMINAL(t->vte), cols, rows);
-			gtk_window_resize(GTK_WINDOW(terminal->mainw),
-				xpad + VTE_TERMINAL(t->vte)->char_width,
-				ypad + VTE_TERMINAL(t->vte)->char_height);
-		}
-	}
+    if (event->button == 2)
+    {
+        /* Middle click closes the tab. */
+        terminal_child_exited_event(NULL, term);
+        return TRUE;
+    }
+    return FALSE;
 }
 
-static gboolean terminal_vte_button_press(VteTerminal *vte, GdkEventButton *event, gpointer data)
+/* Handler for "button-press-event" signal on VTE. */
+static gboolean terminal_vte_button_press_event(VteTerminal * vte, GdkEventButton * event, Term * term)
 {
-	LXTerminal *terminal = (LXTerminal *)data;
-	GtkWidget *menu_item;
-	GtkActionGroup *action_group;
-	GtkUIManager *manager;
-	guint merge_id;
-	gint i;
-
-	/* right-click */
-	if (event->button == 3) {
-		/* initializing UI manager */
-		manager = gtk_ui_manager_new();
-		action_group = gtk_action_group_new("VTEMenu");
-		gtk_action_group_set_translation_domain(action_group, GETTEXT_PACKAGE);
-		gtk_action_group_add_actions(action_group, vte_menu_items, VTE_MENUITEM_COUNT, terminal);
-		gtk_ui_manager_insert_action_group(manager, action_group, 0);
-
-		merge_id = gtk_ui_manager_new_merge_id(manager);
-
-		gtk_ui_manager_add_ui(manager, merge_id, "/", "VTEMenu", NULL, GTK_UI_MANAGER_POPUP, FALSE);
-		for (i=1;i<VTE_MENUITEM_COUNT;i++) {
-			if (strcmp(vte_menu_items[i].label, "Sep")==0)
-				gtk_ui_manager_add_ui(manager, merge_id, "/VTEMenu", vte_menu_items[i].name, NULL, GTK_UI_MANAGER_SEPARATOR, FALSE);
-			else
-				gtk_ui_manager_add_ui(manager, merge_id, "/VTEMenu", vte_menu_items[i].name, vte_menu_items[i].name, GTK_UI_MANAGER_MENUITEM, FALSE);
-		}
-
-		gtk_menu_popup(GTK_MENU(gtk_ui_manager_get_widget(manager, "/VTEMenu")), NULL, NULL, NULL, NULL, event->button, event->time);
-	} else if (event->button == 1) { /* left click */
-		/* steal from tilda-0.09.6/src/tilda_terminal.c:743 */
-		gint tag;
-		gint xpad, ypad;
-		gchar* match;
-		gchar* cmd;
-		gboolean ret = FALSE;
-
-		vte_terminal_get_padding(vte, &xpad, &ypad);
-		match = vte_terminal_match_check(vte,
-				(event->x - xpad) / vte->char_width,
-				(event->y - ypad) / vte->char_height,
-				&tag);
-
-		/* Check if we can launch a web browser, and do so if possible */
-		if ((event->state & GDK_CONTROL_MASK) && match != NULL) {
-#if DEBUG
-			g_print("Got a Ctrl+Left Click -- Matched: `%s' (%d)\n", match, tag);
-#endif
-			cmd = g_strdup_printf("%s %s", "xdg-open", match);
-#if DEBUG
-			g_print("Launching command: `%s'\n", cmd);
-#endif
-			ret = g_spawn_command_line_async(cmd, NULL);
-
-			/* Check that the command launched */
-			if (!ret) {
-				g_printerr(_("Failed to launch the web browser. The command was `%s'\n"), cmd);
-			}
-
-			g_free(cmd);
-		}
-
-		/* Always free match if it is non NULL */
-		if (match)
-			g_free(match);
-	}
-
-#if 0
-	GtkItemFactory *item_factory;
-
-	/* right-click */
-	if (event->button == 3) {
-		item_factory = gtk_item_factory_new(GTK_TYPE_MENU, "<main>", NULL);
-		gtk_item_factory_set_translate_func(item_factory, gettext, NULL, NULL);
-		gtk_item_factory_create_items(item_factory, sizeof(vte_menu_items) / sizeof(vte_menu_items[0]), vte_menu_items, data);
-		gtk_menu_popup(GTK_MENU(gtk_item_factory_get_widget(item_factory, "<main>")), NULL, NULL, NULL, NULL, event->button, event->time);
-	}
-#endif
-	return FALSE;
+    /* Right-click. */
+    if (event->button == 3)
+    {
+        /* Generate popup menu. */
+        GtkUIManager * manager = gtk_ui_manager_new();
+        GtkActionGroup * action_group = gtk_action_group_new("VTEMenu");
+        gtk_action_group_set_translation_domain(action_group, GETTEXT_PACKAGE);
+        gtk_action_group_add_actions(action_group, vte_menu_items, VTE_MENUITEM_COUNT, term->parent);
+        gtk_ui_manager_insert_action_group(manager, action_group, 0);
+
+        guint merge_id = gtk_ui_manager_new_merge_id(manager);
+        gtk_ui_manager_add_ui(manager, merge_id, "/", "VTEMenu", NULL, GTK_UI_MANAGER_POPUP, FALSE);
+
+        int i;
+        for (i = 1; i < VTE_MENUITEM_COUNT; i += 1)
+        {
+            if (strcmp(vte_menu_items[i].label, "Sep") == 0)
+                gtk_ui_manager_add_ui(manager, merge_id, "/VTEMenu", vte_menu_items[i].name, NULL, GTK_UI_MANAGER_SEPARATOR, FALSE);
+                else gtk_ui_manager_add_ui(manager, merge_id, "/VTEMenu", vte_menu_items[i].name, vte_menu_items[i].name, GTK_UI_MANAGER_MENUITEM, FALSE);
+        }
+        gtk_menu_popup(GTK_MENU(gtk_ui_manager_get_widget(manager, "/VTEMenu")), NULL, NULL, NULL, NULL, event->button, event->time);
+    }
+
+    /* Control left click. */
+    else if ((event->button == 1) && (event->state & GDK_CONTROL_MASK))
+    {
+        /* steal from tilda-0.09.6/src/tilda_terminal.c:743
+         * See if the terminal has matched the regular expression. */
+        GtkBorder * border = terminal_get_border(term);
+        gint tag;
+        gchar * match = vte_terminal_match_check(vte,
+            (event->x - border->left) / vte->char_width,
+            (event->y - border->top) / vte->char_height,
+            &tag);
+        gtk_border_free(border);
+
+        /* Launch xdg-open with the match string. */
+        if (match != NULL)
+        {
+            gchar * cmd = g_strdup_printf("xdg-open %s", match);
+            if ( ! g_spawn_command_line_async(cmd, NULL))
+                g_warning("Failed to launch xdg-open. The command was `%s'\n", cmd);
+            g_free(cmd);
+            g_free(match);
+        }
+    }
+    return FALSE;
 }
 
-void terminal_term_setting_update(Term *term, LXTerminal *terminal){
-	vte_terminal_reset((VteTerminal *)term->vte, FALSE, FALSE);
-
-	vte_terminal_set_font_from_string((VteTerminal *)term->vte, terminal->setting->fontname);
-	vte_terminal_set_word_chars((VteTerminal *)term->vte, terminal->setting->selchars);
-	vte_terminal_set_scrollback_lines((VteTerminal *)term->vte, terminal->setting->scrollback);
-
-	vte_terminal_set_cursor_blink_mode((VteTerminal *)term->vte, terminal->setting->cursorblinks?VTE_CURSOR_BLINK_ON:VTE_CURSOR_BLINK_OFF);
-
-	/* background transparency */
-	if( terminal->rgba ){
-		/* dirty hack - vte_terminal_queue_background_update
-		 * doesn't run without changing background */
-		vte_terminal_set_color_background((VteTerminal *)term->vte, &terminal->foreground);
-		vte_terminal_set_background_transparent((VteTerminal *)term->vte, FALSE);
-		vte_terminal_set_opacity((VteTerminal *)term->vte, terminal->setting->bgalpha);
-	} else {
-		vte_terminal_set_background_transparent((VteTerminal *)term->vte, terminal->setting->bgalpha == 65535 ? FALSE : TRUE);
-		vte_terminal_set_background_saturation((VteTerminal *)term->vte, 1-((double)terminal->setting->bgalpha/65535));
-	}
-
-	vte_terminal_set_colors((VteTerminal *)term->vte, &terminal->foreground, &terminal->background, &linux_color[0], 16);
-
-	/* update scrollbar */
-	if( terminal->setting->hidescrollbar )
-		gtk_widget_hide( term->scrollbar );
-	else
-		gtk_widget_show( term->scrollbar );
+/* Apply new settings in an LXTerminal to its tab Term. */
+static void terminal_settings_apply_to_term(LXTerminal * terminal, Term * term)
+{
+    Setting * setting = terminal->setting;
+
+    /* Terminal properties. */
+    vte_terminal_reset(VTE_TERMINAL(term->vte), FALSE, FALSE);
+    vte_terminal_set_font_from_string(VTE_TERMINAL(term->vte), setting->font_name);
+    vte_terminal_set_word_chars(VTE_TERMINAL(term->vte), setting->word_selection_characters);
+    vte_terminal_set_scrollback_lines(VTE_TERMINAL(term->vte), setting->scrollback);
+    vte_terminal_set_allow_bold(VTE_TERMINAL(term->vte), ! setting->disallow_bold);
+    vte_terminal_set_cursor_blink_mode(VTE_TERMINAL(term->vte), ((setting->cursor_blink) ? VTE_CURSOR_BLINK_ON : VTE_CURSOR_BLINK_OFF));
+    vte_terminal_set_cursor_shape(VTE_TERMINAL(term->vte), ((setting->cursor_underline) ? VTE_CURSOR_SHAPE_UNDERLINE : VTE_CURSOR_SHAPE_BLOCK));
+    vte_terminal_set_audible_bell(VTE_TERMINAL(term->vte), setting->audible_bell);
+
+    /* Background and foreground colors. */
+    if (terminal->rgba)
+    {
+        /* vte_terminal_queue_background_update doesn't run without changing background. */
+        vte_terminal_set_color_background(VTE_TERMINAL(term->vte), &setting->foreground_color);
+        vte_terminal_set_background_transparent(VTE_TERMINAL(term->vte), FALSE);
+        vte_terminal_set_opacity(VTE_TERMINAL(term->vte), setting->background_alpha);
+    }
+    else
+    {
+        vte_terminal_set_background_transparent(VTE_TERMINAL(term->vte), setting->background_alpha == 65535 ? FALSE : TRUE);
+        vte_terminal_set_background_saturation(VTE_TERMINAL(term->vte), 1 - ((double) setting->background_alpha / 65535));
+    }
+    vte_terminal_set_colors(VTE_TERMINAL(term->vte), &setting->foreground_color, &setting->background_color, &linux_color[0], 16);
+
+    /* Hide or show scrollbar. */
+    if (setting->hide_scroll_bar)
+        gtk_widget_hide(term->scrollbar);
+        else gtk_widget_show(term->scrollbar);
+
+    /* Hide or show Close button. */
+    if (setting->hide_close_button)
+        gtk_widget_hide(term->close_button);
+        else gtk_widget_show(term->close_button);
+
+    /* If terminal geometry changed, react to it. */
+    if (setting->geometry_change)
+        terminal_geometry_restore(term);
 }
 
-static Term *terminal_new(LXTerminal *terminal, const gchar *label, const gchar *pwd, gchar **env, const gchar *exec)
+/* Create a new terminal. */
+static Term * terminal_new(LXTerminal * terminal, const gchar * label, const gchar * pwd, gchar * * env, const gchar * exec)
 {
-	gint ret;
-	GRegex *dingus1, *dingus2;
-	Term *term;
-
-	/* create terminal */
-	term = g_new0(Term, 1);
-	term->parent = terminal;
-	term->vte = vte_terminal_new();
-	term->box = gtk_hbox_new(FALSE, 0);
-	term->scrollbar = gtk_vscrollbar_new(NULL);
-	gtk_box_pack_start(GTK_BOX(term->box), term->vte, TRUE, TRUE, 0);
-	gtk_box_pack_start(GTK_BOX(term->box), term->scrollbar, FALSE, TRUE, 0);
-
-	/* setting terminal */
-	vte_terminal_set_emulation((VteTerminal *)term->vte, "xterm");
-
-	/* Set encoding from locale. */
-	setlocale(LC_ALL, "");
-	vte_terminal_set_encoding((VteTerminal *)term->vte, nl_langinfo(CODESET));
-
-	/* fixing bugs for specific environment */
-	vte_terminal_set_backspace_binding((VteTerminal *)term->vte, VTE_ERASE_ASCII_DELETE);
-	vte_terminal_set_delete_binding((VteTerminal *)term->vte, VTE_ERASE_DELETE_SEQUENCE);
-
-	/* disable beeping */
-	vte_terminal_set_audible_bell((VteTerminal *)term->vte, FALSE);
-
-	if (!gdk_color_parse(terminal->setting->bgcolor, &terminal->background)) {
-		terminal->background = (GdkColor){ 0, 0, 0, 0 };
-		printf("Bad bgcolor string in config: %s\n", terminal->setting->bgcolor);
-	}
-	
-	if (!gdk_color_parse(terminal->setting->fgcolor, &terminal->foreground)) {
-		terminal->foreground = (GdkColor){ 0, 0xaaaa, 0xaaaa, 0xaaaa};
-		printf("Bad fgcolor string in config: %s\n", terminal->setting->fgcolor);
-	}
-
-	/* steal from tilda-0.09.6/src/tilda_terminal.c:145 */
-	/* Match URL's, etc */
-	dingus1 = g_regex_new(DINGUS1, G_REGEX_OPTIMIZE, 0, NULL);
-	dingus2 = g_regex_new(DINGUS2, G_REGEX_OPTIMIZE, 0, NULL);
-	ret = vte_terminal_match_add_gregex((VteTerminal *)term->vte, dingus1, 0);
-	vte_terminal_match_set_cursor_type((VteTerminal *)term->vte, ret, GDK_HAND2);
-	ret = vte_terminal_match_add_gregex((VteTerminal *)term->vte, dingus2, 0);
-	vte_terminal_match_set_cursor_type((VteTerminal *)term->vte, ret, GDK_HAND2);
-	g_regex_unref(dingus1);
-	g_regex_unref(dingus2);
-
-	/* create label for tab */
-	if (label)
-		term->label = lxterminal_tab_label_new(label);
-	else
-		term->label = lxterminal_tab_label_new(pwd);
-
-	lxterminal_tab_label_close_button_clicked(G_CALLBACK(terminal_childexit), term);
-
-	/* setting scrollbar */
-	gtk_range_set_adjustment(GTK_RANGE(term->scrollbar), VTE_TERMINAL(term->vte)->adjustment);
-
-	/* terminal fork */
-	if (exec) {
-		gchar **command;
-		g_shell_parse_argv(exec, NULL, &command, NULL);
-		term->pid = vte_terminal_fork_command(VTE_TERMINAL(term->vte), (const char *)*(command), command, env, "/tmp", FALSE, TRUE, TRUE);
-		g_strfreev(command);
-	} else {
-		term->pid = vte_terminal_fork_command(VTE_TERMINAL(term->vte), NULL, NULL, env, pwd, FALSE, TRUE, TRUE);
-	}
-
-	/* signal handler */
-	g_signal_connect(term->vte, "child-exited", G_CALLBACK(terminal_childexit), term);
-	g_signal_connect(term->vte, "window-title-changed", G_CALLBACK(terminal_title_changed), term);
-	g_signal_connect(term->vte, "button-press-event", G_CALLBACK(terminal_vte_button_press), terminal);
-
-	gtk_widget_show_all(term->box);
-
-	/* apply other settings */
-	terminal_term_setting_update(term, terminal);
-
-	return term;
+    /* Create and initialize Term structure for new terminal. */
+    Term * term = g_new0(Term, 1);
+    term->parent = terminal;
+
+    /* Create a VTE and a vertical scrollbar, and place them inside a horizontal box. */
+    term->vte = vte_terminal_new();
+    term->box = gtk_hbox_new(FALSE, 0);
+    term->scrollbar = gtk_vscrollbar_new(NULL);
+    gtk_box_pack_start(GTK_BOX(term->box), term->vte, TRUE, TRUE, 0);
+    gtk_box_pack_start(GTK_BOX(term->box), term->scrollbar, FALSE, TRUE, 0);
+
+    /* Set up the VTE. */
+    setlocale(LC_ALL, "");
+    vte_terminal_set_emulation(VTE_TERMINAL(term->vte), "xterm");
+    vte_terminal_set_encoding(VTE_TERMINAL(term->vte), nl_langinfo(CODESET));
+    vte_terminal_set_backspace_binding(VTE_TERMINAL(term->vte), VTE_ERASE_ASCII_DELETE);
+    vte_terminal_set_delete_binding(VTE_TERMINAL(term->vte), VTE_ERASE_DELETE_SEQUENCE);
+
+    /* steal from tilda-0.09.6/src/tilda_terminal.c:145 */
+    /* Match URL's, etc. */
+    GRegex * dingus1 = g_regex_new(DINGUS1, G_REGEX_OPTIMIZE, 0, NULL);
+    GRegex * dingus2 = g_regex_new(DINGUS2, G_REGEX_OPTIMIZE, 0, NULL);
+    gint ret = vte_terminal_match_add_gregex(VTE_TERMINAL(term->vte), dingus1, 0);
+    vte_terminal_match_set_cursor_type(VTE_TERMINAL(term->vte), ret, GDK_HAND2);
+    ret = vte_terminal_match_add_gregex(VTE_TERMINAL(term->vte), dingus2, 0);
+    vte_terminal_match_set_cursor_type(VTE_TERMINAL(term->vte), ret, GDK_HAND2);
+    g_regex_unref(dingus1);
+    g_regex_unref(dingus2);
+
+    /* Create a horizontal box inside an event box as the toplevel for the tab label. */
+    term->tab = gtk_event_box_new();
+    gtk_widget_set_events(term->tab, GDK_BUTTON_PRESS_MASK);
+    GtkWidget * hbox = gtk_hbox_new(FALSE, 4);
+    gtk_container_add(GTK_CONTAINER(term->tab), hbox);
+
+    /* Create the Close button. */
+    term->close_button = gtk_button_new();
+    gtk_button_set_relief(GTK_BUTTON(term->close_button), GTK_RELIEF_NONE);
+    gtk_button_set_focus_on_click(GTK_BUTTON(term->close_button), FALSE);
+    gtk_container_add(GTK_CONTAINER(term->close_button), gtk_image_new_from_stock(GTK_STOCK_CLOSE, GTK_ICON_SIZE_MENU));
+
+    /* Make the button as small as possible. */
+    GtkRcStyle * rcstyle = gtk_rc_style_new();
+    rcstyle->xthickness = rcstyle->ythickness = 0;
+    gtk_widget_modify_style(term->close_button, rcstyle);
+    gtk_rc_style_unref(rcstyle),
+
+    /* Create the label. */
+    term->label = gtk_label_new((label != NULL) ? label : pwd);
+    gtk_widget_set_size_request(GTK_WIDGET(term->label), 100, -1);
+    gtk_label_set_ellipsize(GTK_LABEL(term->label), PANGO_ELLIPSIZE_END);
+    gtk_misc_set_alignment(GTK_MISC(term->label), 0.0, 0.5);
+    gtk_misc_set_padding(GTK_MISC(term->label), 0, 0);
+
+    /* Pack everything and show the widget. */
+    gtk_box_pack_start(GTK_BOX(hbox), term->label, TRUE, TRUE, 0);
+    gtk_box_pack_start(GTK_BOX(hbox), term->close_button, FALSE, FALSE, 0);
+    gtk_widget_show_all(term->tab);
+
+    /* Set up scrollbar. */
+    gtk_range_set_adjustment(GTK_RANGE(term->scrollbar), VTE_TERMINAL(term->vte)->adjustment);
+
+    /* Fork the process that will have the VTE as its controlling terminal. */
+    if (exec != NULL)
+    {
+        gchar * * command;
+        g_shell_parse_argv(exec, NULL, &command, NULL);
+        term->pid = vte_terminal_fork_command(VTE_TERMINAL(term->vte), (const char *) command[0], command, env, pwd, FALSE, TRUE, TRUE);
+        g_strfreev(command);
+    }
+    else
+        term->pid = vte_terminal_fork_command(VTE_TERMINAL(term->vte), NULL, NULL, env, pwd, FALSE, TRUE, TRUE);
+
+    /* Connect signals. */
+    g_signal_connect(G_OBJECT(term->tab), "button-press-event", G_CALLBACK(terminal_tab_button_press_event), term);
+    g_signal_connect(G_OBJECT(term->close_button), "clicked", G_CALLBACK(terminal_child_exited_event), term);
+    g_signal_connect(G_OBJECT(term->vte), "button-press-event", G_CALLBACK(terminal_vte_button_press_event), term);
+    g_signal_connect(G_OBJECT(term->vte), "child-exited", G_CALLBACK(terminal_child_exited_event), term);
+    g_signal_connect(G_OBJECT(term->vte), "window-title-changed", G_CALLBACK(terminal_window_title_changed_event), term);
+
+    /* Show the widget and return. */
+    gtk_widget_show_all(term->box);
+
+    /* Apply user preferences. */
+    terminal_settings_apply_to_term(terminal, term);
+    return term;
 }
 
-void terminal_free(Term* term)
+/* Deallocate a Term structure. */
+static void terminal_free(Term * term)
 {
-    GtkAccelGroup *accel_group = term->parent->menubar->accel_group;
-    gtk_accel_group_disconnect(accel_group, term->closure);
+    gtk_accel_group_disconnect(term->parent->accel_group, term->closure);
     g_free(term);
 }
 
-static Menu *menubar_init(LXTerminal *terminal)
+/* Initialize the menu bar. */
+static void terminal_menubar_initialize(LXTerminal * terminal)
 {
-	Menu *menubar;
-	GtkWidget *menu_item;
-	GtkActionGroup *action_group;
-	GtkAction *encoding_action;
-	GtkUIManager *manager;
-	guint merge_id;
-	gint i;
-	gchar *path, *path_ptr;
-
-	/* initializing menu */
-	menubar = g_new0(Menu, 1);
-
-	/* initializing encoding Action */
-//	encoding_action = encoding_action_new("CharacterEncoding");
-
-	/* initializing UI manager */
-	manager = gtk_ui_manager_new();
-	action_group = gtk_action_group_new("MenuBar");
-	gtk_action_group_set_translation_domain(action_group, GETTEXT_PACKAGE);
-	gtk_action_group_add_actions(action_group, menus, MENUBAR_MENU_COUNT, terminal);
-	gtk_action_group_add_actions(action_group, menu_items, MENUBAR_MENUITEM_COUNT, terminal);
-//	gtk_action_group_add_action(action_group, encoding_action);
-	gtk_ui_manager_insert_action_group(manager, action_group, 0);
-
-	merge_id = gtk_ui_manager_new_merge_id(manager);
-
-	gtk_ui_manager_add_ui(manager, merge_id, "/", "MenuBar", NULL, GTK_UI_MANAGER_MENUBAR, FALSE);
-
-	/* menus */
-	for (i=0;i<MENUBAR_MENU_COUNT;i++) {
-		path = g_strdup_printf("/MenuBar/%s", menus[i].name);
-		for (path_ptr=path;*path_ptr!='\0';path_ptr++) {
-			if (*path_ptr=='_')
-				*path_ptr = '/';
-		}
-
-		path_ptr = g_path_get_dirname(path);
-		gtk_ui_manager_add_ui(manager, merge_id, path_ptr, menus[i].name, menus[i].name, GTK_UI_MANAGER_MENU, FALSE);
-		g_free(path);
-		g_free(path_ptr);
-	}
-
-	/* items */
-	for (i=0;i<MENUBAR_MENUITEM_COUNT;i++) {
-		path = g_strdup_printf("/MenuBar/%s", menu_items[i].name);
-		for (path_ptr=path;*path_ptr!='\0';path_ptr++) {
-			if (*path_ptr=='_')
-				*path_ptr = '/';
-		}
-
-		path_ptr = g_path_get_dirname(path);
-
-		if (strcmp(menu_items[i].label, "Sep")==0) {
-			gtk_ui_manager_add_ui(manager, merge_id, path_ptr, menu_items[i].name, NULL, GTK_UI_MANAGER_SEPARATOR, FALSE);
-#if 0
-		/* Encoding */
-		} else if (strcmp(menu_items[i].name, "View_CharacterEncoding")==0) {
-			gtk_ui_manager_add_ui(manager, merge_id, path_ptr, menu_items[i].name, "CharacterEncoding", GTK_UI_MANAGER_MENUITEM, FALSE);
-#endif
-		} else {
-			gtk_ui_manager_add_ui(manager, merge_id, path_ptr, menu_items[i].name, menu_items[i].name, GTK_UI_MANAGER_MENUITEM, FALSE);
-		}
-
-		g_free(path);
-		g_free(path_ptr);
-	}
-
-	menubar->menu = gtk_ui_manager_get_widget(manager, "/MenuBar");
-
-	return menubar;
+    /* Initialize UI manager. */
+    GtkUIManager * manager = gtk_ui_manager_new();
+    GtkActionGroup * action_group = gtk_action_group_new("MenuBar");
+    gtk_action_group_set_translation_domain(action_group, GETTEXT_PACKAGE);
+    gtk_action_group_add_actions(action_group, menus, MENUBAR_MENU_COUNT, terminal);
+    gtk_action_group_add_actions(action_group, menu_items, MENUBAR_MENUITEM_COUNT, terminal);
+    gtk_ui_manager_insert_action_group(manager, action_group, 0);
+
+    guint merge_id = gtk_ui_manager_new_merge_id(manager);
+    gtk_ui_manager_add_ui(manager, merge_id, "/", "MenuBar", NULL, GTK_UI_MANAGER_MENUBAR, FALSE);
+
+    /* Menus. */
+    int i;
+    for (i = 0; i < MENUBAR_MENU_COUNT; i += 1)
+    {
+        gchar * path = g_strdup_printf("/MenuBar/%s", menus[i].name);
+        gchar * path_ptr;
+        for (path_ptr = path; *path_ptr != '\0'; path_ptr += 1)
+        {
+            if (*path_ptr == '_')
+                *path_ptr = '/';
+        }
+        path_ptr = g_path_get_dirname(path);
+        gtk_ui_manager_add_ui(manager, merge_id, path_ptr, menus[i].name, menus[i].name, GTK_UI_MANAGER_MENU, FALSE);
+        g_free(path);
+        g_free(path_ptr);
+    }
+
+    /* Items. */
+    for (i = 0; i < MENUBAR_MENUITEM_COUNT; i += 1)
+    {
+        gchar * path = g_strdup_printf("/MenuBar/%s", menu_items[i].name);
+        gchar * path_ptr;
+        for (path_ptr = path; *path_ptr != '\0'; path_ptr += 1)
+        {
+            if (*path_ptr == '_')
+                *path_ptr = '/';
+        }
+        path_ptr = g_path_get_dirname(path);
+        if (strcmp(menu_items[i].label, "Sep") == 0)
+            gtk_ui_manager_add_ui(manager, merge_id, path_ptr, menu_items[i].name, NULL, GTK_UI_MANAGER_SEPARATOR, FALSE);
+            else gtk_ui_manager_add_ui(manager, merge_id, path_ptr, menu_items[i].name, menu_items[i].name, GTK_UI_MANAGER_MENUITEM, FALSE);
+
+        g_free(path);
+        g_free(path_ptr);
+    }
+
+    terminal->menu = gtk_ui_manager_get_widget(manager, "/MenuBar");
 }
 
-static void lxterminal_accelerator_init(LXTerminal *terminal)
+/* Allocate, initialize, and connect up an accelerator group for the accelerators on a new terminal. */
+static void terminal_accelerator_initialize(LXTerminal * terminal)
 {
-	guint key;
-	GdkModifierType mods;
+    guint key;
+    GdkModifierType mods;
+
+    terminal->accel_group = gtk_accel_group_new();
 
-	terminal->menubar->accel_group = gtk_accel_group_new();
+    gtk_accelerator_parse(NEW_WINDOW_ACCEL, &key, &mods);
+    gtk_accel_group_connect(terminal->accel_group, key, mods, GTK_ACCEL_LOCKED, g_cclosure_new_swap(G_CALLBACK(terminal_new_window_accelerator), terminal, NULL));
 
-	gtk_accelerator_parse(NEW_WINDOW_ACCEL, &key, &mods);
-	gtk_accel_group_connect(terminal->menubar->accel_group, key, mods, GTK_ACCEL_LOCKED, g_cclosure_new_swap(G_CALLBACK(terminal_newwindow_accel), terminal, NULL));
+    gtk_accelerator_parse(QUIT_ACCEL, &key, &mods);
+    gtk_accel_group_connect(terminal->accel_group, key, mods, GTK_ACCEL_LOCKED, g_cclosure_new_swap(G_CALLBACK(gtk_main_quit), NULL, NULL));
 
-	gtk_accelerator_parse(QUIT_ACCEL, &key, &mods);
-	gtk_accel_group_connect(terminal->menubar->accel_group, key, mods, GTK_ACCEL_LOCKED, g_cclosure_new_swap(G_CALLBACK(gtk_main_quit), NULL, NULL));
+    gtk_accelerator_parse(NEW_TAB_ACCEL, &key, &mods);
+    gtk_accel_group_connect(terminal->accel_group, key, mods, GTK_ACCEL_LOCKED, g_cclosure_new_swap(G_CALLBACK(terminal_new_tab_accelerator), terminal, NULL));
 
-	gtk_accelerator_parse(NEW_TAB_ACCEL, &key, &mods);
-	gtk_accel_group_connect(terminal->menubar->accel_group, key, mods, GTK_ACCEL_LOCKED, g_cclosure_new_swap(G_CALLBACK(terminal_newtab_accel), terminal, NULL));
+    gtk_accelerator_parse(CLOSE_TAB_ACCEL, &key, &mods);
+    gtk_accel_group_connect(terminal->accel_group, key, mods, GTK_ACCEL_LOCKED, g_cclosure_new_swap(G_CALLBACK(terminal_close_tab_accelerator), terminal, NULL));
 
-	gtk_accelerator_parse(CLOSE_TAB_ACCEL, &key, &mods);
-	gtk_accel_group_connect(terminal->menubar->accel_group, key, mods, GTK_ACCEL_LOCKED, g_cclosure_new_swap(G_CALLBACK(terminal_closetab_accel), terminal, NULL));
+    gtk_accelerator_parse(COPY_ACCEL, &key, &mods);
+    gtk_accel_group_connect(terminal->accel_group, key, mods, GTK_ACCEL_LOCKED, g_cclosure_new_swap(G_CALLBACK(terminal_copy_accelerator), terminal, NULL));
 
-	gtk_accelerator_parse(COPY_ACCEL, &key, &mods);
-	gtk_accel_group_connect(terminal->menubar->accel_group, key, mods, GTK_ACCEL_LOCKED, g_cclosure_new_swap(G_CALLBACK(terminal_copy_accel), terminal, NULL));
+    gtk_accelerator_parse(PASTE_ACCEL, &key, &mods);
+    gtk_accel_group_connect(terminal->accel_group, key, mods, GTK_ACCEL_LOCKED, g_cclosure_new_swap(G_CALLBACK(terminal_paste_accelerator), terminal, NULL));
 
-	gtk_accelerator_parse(PASTE_ACCEL, &key, &mods);
-	gtk_accel_group_connect(terminal->menubar->accel_group, key, mods, GTK_ACCEL_LOCKED, g_cclosure_new_swap(G_CALLBACK(terminal_paste_accel), terminal, NULL));
+    gtk_accelerator_parse(NAME_TAB_ACCEL, &key, &mods);
+    gtk_accel_group_connect(terminal->accel_group, key, mods, GTK_ACCEL_LOCKED, g_cclosure_new_swap(G_CALLBACK(terminal_name_tab_accelerator), terminal, NULL));
 
-	gtk_accelerator_parse(NEXT_TAB_ACCEL, &key, &mods);
-	gtk_accel_group_connect(terminal->menubar->accel_group, key, mods, GTK_ACCEL_LOCKED, g_cclosure_new_swap(G_CALLBACK(terminal_nexttab_accel), terminal, NULL));
+    gtk_accelerator_parse(PREVIOUS_TAB_ACCEL, &key, &mods);
+    gtk_accel_group_connect(terminal->accel_group, key, mods, GTK_ACCEL_LOCKED, g_cclosure_new_swap(G_CALLBACK(terminal_previous_tab_accelerator), terminal, NULL));
 
-	gtk_accelerator_parse(PREVIOUS_TAB_ACCEL, &key, &mods);
-	gtk_accel_group_connect(terminal->menubar->accel_group, key, mods, GTK_ACCEL_LOCKED, g_cclosure_new_swap(G_CALLBACK(terminal_prevtab_accel), terminal, NULL));
+    gtk_accelerator_parse(NEXT_TAB_ACCEL, &key, &mods);
+    gtk_accel_group_connect(terminal->accel_group, key, mods, GTK_ACCEL_LOCKED, g_cclosure_new_swap(G_CALLBACK(terminal_next_tab_accelerator), terminal, NULL));
 
-	gtk_accelerator_parse(MOVE_TAB_LEFT_ACCEL, &key, &mods);
-	gtk_accel_group_connect(terminal->menubar->accel_group, key, mods, GTK_ACCEL_LOCKED, g_cclosure_new_swap(G_CALLBACK(terminal_movetableft_accel), terminal, NULL));
+    gtk_accelerator_parse(MOVE_TAB_LEFT_ACCEL, &key, &mods);
+    gtk_accel_group_connect(terminal->accel_group, key, mods, GTK_ACCEL_LOCKED, g_cclosure_new_swap(G_CALLBACK(terminal_move_tab_left_accelerator), terminal, NULL));
 
-	gtk_accelerator_parse(MOVE_TAB_RIGHT_ACCEL, &key, &mods);
-	gtk_accel_group_connect(terminal->menubar->accel_group, key, mods, GTK_ACCEL_LOCKED, g_cclosure_new_swap(G_CALLBACK(terminal_movetabright_accel), terminal, NULL));
+    gtk_accelerator_parse(MOVE_TAB_RIGHT_ACCEL, &key, &mods);
+    gtk_accel_group_connect(terminal->accel_group, key, mods, GTK_ACCEL_LOCKED, g_cclosure_new_swap(G_CALLBACK(terminal_move_tab_right_accelerator), terminal, NULL));
 
-	gtk_window_add_accel_group(GTK_WINDOW(terminal->mainw), terminal->menubar->accel_group);
+    gtk_window_add_accel_group(GTK_WINDOW(terminal->window), terminal->accel_group);
 }
 
-void lxterminal_menuaccel_update(LXTerminal *terminal)
+/* Update the accelerator that brings up the menu.
+ * We have a user preference as to whether F10 (or a style-supplied alternate) is used for this purpose.
+ * Technique taken from gnome-terminal. */
+static void terminal_menu_accelerator_update(LXTerminal * terminal)
 {
-	/* update F10 status */
-	/* hack took from gnome-terminal */
-	
-	if (saved_menu_accel == NULL) {
-		g_object_get (G_OBJECT (gtk_settings_get_default ()),
-					"gtk-menu-bar-accel",
-					&saved_menu_accel,
-					NULL);
-		/* FIXME if gtkrc is reparsed we don't catch on,
-		 * I guess.
-		 */
-	}
-
-	
-	if (terminal->setting->disablef10) {
-		gtk_settings_set_string_property (gtk_settings_get_default(),
-										"gtk-menu-bar-accel",
-										/* no one will ever press this ;-) */
-										"<Shift><Control><Mod1><Mod2><Mod3><Mod4><Mod5>F10",
-										"lxterminal");
-	} else {
-		gtk_settings_set_string_property (gtk_settings_get_default(),
-										"gtk-menu-bar-accel",
-										saved_menu_accel,
-										"lxterminal");
-	}
+    /* Ensure that saved_menu_accelerator is initialized. */
+    if (saved_menu_accelerator == NULL)
+        g_object_get(G_OBJECT(gtk_settings_get_default()), "gtk-menu-bar-accel", &saved_menu_accelerator, NULL);
+
+    /* If F10 is disabled, set the accelerator to a key combination that is not F10 and unguessable. */
+    gtk_settings_set_string_property(
+        gtk_settings_get_default(),
+        "gtk-menu-bar-accel",
+        ((terminal->setting->disable_f10) ? "<Shift><Control><Mod1><Mod2><Mod3><Mod4><Mod5>F10" : saved_menu_accelerator),
+        "lxterminal");
 }
 
-void terminal_setting_update(LXTerminal *terminal)
+/* Process the argument vector into the CommandArguments structure.
+ * This is called from the main entry, and also from the controlling socket flow. */
+gboolean lxterminal_process_arguments(gint argc, gchar * * argv, CommandArguments * arguments)
 {
-	gint i;
+    /* Loop over the argument vector to produce the CommandArguments structure. */
+    memset(arguments, 0, sizeof(CommandArguments));
+    arguments->executable = argv[0];
+
+    gboolean login_shell = FALSE;
+    char * * argv_cursor = argv + 1;
+    argc -= 1;
+    while (argc > 0)
+    {
+        char * argument = *argv_cursor;
+
+        /* --command=<command> */
+        if (strncmp(argument, "--command=", 10) == 0)
+        {
+            g_free(arguments->command);
+            arguments->command = g_strdup(&argument[10]);
+        }
+
+        /* -e <rest of arguments>, --command <rest of arguments>
+         * The <rest of arguments> behavior is demanded by distros who insist on this xterm feature. */
+        else if ((strcmp(argument, "--command") == 0) || (strcmp(argument, "-e") == 0))
+        {
+            while (argc > 1)
+            {
+                argc -= 1;
+                argv_cursor += 1;
+                if (arguments->command == NULL)
+                    arguments->command = g_strdup(*argv_cursor);
+                else
+                {
+                    gchar * new_command = g_strconcat(arguments->command, " ", *argv_cursor, NULL);
+                    g_free(arguments->command);
+                    arguments->command = new_command;
+                }
+            }
+        }
+
+        /* --geometry=<columns>x<rows> */
+        else if (strncmp(argument, "--geometry=", 11) == 0)
+        {
+            int result = sscanf(&argument[11], "%dx%d", &arguments->geometry_columns, &arguments->geometry_rows);
+            if (result != 2)
+                return FALSE;
+        }
+
+        /* -l, --loginshell */
+        else if ((strcmp(argument, "--loginshell") == 0) || (strcmp(argument, "-l") == 0))
+            login_shell = TRUE;
+
+        /* --title=<title> */
+	else if (strncmp(argument, "--title=", 8) == 0)
+	    arguments->title = &argument[8];
+
+        /* -t <title>, -T <title>, --title <title>
+         * The -T form is demanded by distros who insist on this xterm feature. */
+        else if (((strcmp(argument, "--title") == 0) || (strcmp(argument, "-t") == 0) || (strcmp(argument, "-T") == 0))
+        && (argc > 1))
+        {
+            argc -= 1;
+            argv_cursor += 1;
+            arguments->title = *argv_cursor;
+        }
+
+        /* --working-directory=<working directory> */
+        else if (strncmp(argument, "--working-directory=", 20) == 0)
+            arguments->working_directory = &argument[20];
+
+        /* Undefined argument. */
+        else
+            return FALSE;
+
+        argc -= 1;
+        argv_cursor += 1;
+    }
+
+    /* Handle --loginshell. */
+    if (login_shell)
+    {
+        if (arguments->command == NULL)
+            arguments->command = g_strdup("sh -l");
+        else
+            {
+            gchar * escaped_command = g_shell_quote(arguments->command);
+            gchar * new_command = g_strdup_printf("sh -l -c %s", escaped_command);
+            g_free(escaped_command);
+            g_free(arguments->command);
+            arguments->command = new_command;
+            }
+    }
+    return TRUE;
+}
+
+/* Initialize a new LXTerminal.
+ * This is a toplevel window that may contain tabs, each of which will contain a VTE controlled by a process. */
+LXTerminal * lxterminal_initialize(LXTermWindow * lxtermwin, CommandArguments * arguments, Setting * setting)
+{
+    /* Allocate and initialize the LXTerminal structure. */
+    LXTerminal * terminal = g_new0(LXTerminal, 1);
+    terminal->parent = lxtermwin;
+    terminal->terms = g_ptr_array_new();
+    terminal->fixed_size = TRUE;
+    g_ptr_array_add(lxtermwin->windows, terminal);
+    terminal->index = terminal->parent->windows->len - 1;
+    terminal->setting = setting;
+
+    /* Create toplevel window. */
+    terminal->window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
+
+    /* Try to get an RGBA colormap and assign it to the new window. */
+    GdkColormap * colormap = gdk_screen_get_rgba_colormap(gtk_widget_get_screen(GTK_WIDGET(terminal->window)));
+    if (colormap != NULL)
+        gtk_widget_set_colormap(terminal->window, colormap);
+
+    /* Set window title. */
+    gtk_window_set_title(GTK_WINDOW(terminal->window), ((arguments->title != NULL) ? arguments->title : _("LXTerminal")));
+
+    /* Set window icon. */
+    gtk_window_set_icon_from_file(GTK_WINDOW(terminal->window), PACKAGE_DATA_DIR "/pixmaps/lxterminal.png", NULL);
+    g_object_weak_ref(G_OBJECT(terminal->window), (GWeakNotify) terminal_window_exit, terminal);
+
+    /* Create a vertical box as the child of the toplevel window. */
+    terminal->box = gtk_vbox_new(FALSE, 1);
+    gtk_container_add(GTK_CONTAINER(terminal->window), terminal->box);
+
+    /* Create the menu bar as the child of the vertical box. */
+    terminal_menubar_initialize(terminal);
+    gtk_box_pack_start(GTK_BOX(terminal->box), terminal->menu, FALSE, TRUE, 0);
+
+    /* Create a notebook as the child of the vertical box. */
+    terminal->notebook = gtk_notebook_new();
+    gtk_notebook_set_scrollable(GTK_NOTEBOOK(terminal->notebook), TRUE);
+    gtk_notebook_set_show_tabs(GTK_NOTEBOOK(terminal->notebook), FALSE);
+    gtk_notebook_set_show_border(GTK_NOTEBOOK(terminal->notebook), FALSE);
+    gtk_box_pack_start(GTK_BOX(terminal->box), terminal->notebook, TRUE, TRUE, 0);
+
+    /* Initialize tab position. */
+    terminal->tab_position = terminal_tab_get_position_id(terminal->setting->tab_position);
+
+    /* Connect signals. */
+    g_signal_connect_swapped(G_OBJECT(terminal->window), "composited-changed", G_CALLBACK(terminal_settings_apply), terminal);
+    g_signal_connect(G_OBJECT(terminal->notebook), "switch-page", G_CALLBACK(terminal_switch_page_event), terminal);
+
+    /* Create the first terminal. */
+    gchar * local_working_directory = NULL;
+    if (arguments->working_directory == NULL)
+        local_working_directory = g_get_current_dir();
+    Term * term = terminal_new(
+        terminal,
+        _("LXTerminal"),
+        ((arguments->working_directory != NULL) ? arguments->working_directory : local_working_directory),
+        NULL,
+        arguments->command);
+    g_free(local_working_directory);
+
+    /* Set the terminal geometry. */
+    if ((arguments->geometry_columns != 0) && (arguments->geometry_rows != 0))
+        vte_terminal_set_size(VTE_TERMINAL(term->vte), arguments->geometry_columns, arguments->geometry_rows);
+
+    /* Add the first terminal to the notebook and the data structures. */
+    gtk_notebook_append_page(GTK_NOTEBOOK(terminal->notebook), term->box, term->tab);
+    term->index = gtk_notebook_get_n_pages(GTK_NOTEBOOK(terminal->notebook)) - 1;
+    g_ptr_array_add(terminal->terms, term);
+
+    /* Initialize accelerators. */
+    terminal_accelerator_initialize(terminal);
+    terminal_initialize_switch_tab_accelerator(term);
+
+    /* Update terminal settings. */
+    terminal_settings_apply(terminal);
+
+    /* Show the widget, so it is realized and has a window. */
+    gtk_widget_show_all(terminal->window);
+
+    /* Initialize the geometry hints. */
+    gdk_window_get_geometry_hints(GTK_WIDGET(term->vte)->window, &terminal->geometry, &terminal->geometry_mask);
+
+    /* Connect signals. */
+    g_signal_connect(G_OBJECT(terminal->window), "size-request", G_CALLBACK(terminal_window_size_request_event), terminal);
+    return terminal;
+}
 
-	/* know if it is composited */
-	terminal->rgba = gtk_widget_is_composited( GTK_WIDGET(terminal->mainw) );
+/* Apply new settings to a terminal. */
+static void terminal_settings_apply(LXTerminal * terminal)
+{
+    /* Reinitialize "composited". */
+    terminal->rgba = gtk_widget_is_composited(terminal->window);
 
-	/* update all of terminals */
-	for (i=0;i<terminal->terms->len;i++)
-		terminal_term_setting_update(g_ptr_array_index(terminal->terms, i), terminal);
+    /* Apply settings to all windows. */
+    int i;
+    for (i = 0; i < terminal->terms->len; i += 1)
+        terminal_settings_apply_to_term(terminal, g_ptr_array_index(terminal->terms, i));
 
-	/* update tab position */
-	lxterminal_tab_set_position(terminal->notebook, terminal->tabpos);
+    /* Update tab position. */
+    terminal->tab_position = terminal_tab_get_position_id(terminal->setting->tab_position);
+    terminal_tab_set_position(terminal->notebook, terminal->tab_position);
 
-	/* update menu accel */
-	lxterminal_menuaccel_update(terminal);
+    /* Update menu accelerators. */
+    terminal_menu_accelerator_update(terminal);
 
-	/* update menubar */
-	if( terminal->setting->hidemenubar )
-		gtk_widget_hide( terminal->menubar->menu );
-	else
-		gtk_widget_show( terminal->menubar->menu );
+    /* Hide or show menubar. */
+    if (terminal->setting->hide_menu_bar)
+        gtk_widget_hide(terminal->menu);
+        else gtk_widget_show(terminal->menu);
 }
 
-LXTerminal *lxterminal_init(LXTermWindow *lxtermwin, gint argc, gchar **argv, Setting *setting)
+/* Apply terminal settings to all tabs in all terminals. */
+void terminal_settings_apply_to_all(LXTerminal * terminal)
 {
-	LXTerminal *terminal;
-	Term *term = NULL;
-	gchar *cmd = NULL;
-	gchar *workdir = NULL;
-	gchar *title = NULL;
-	gint cols = 0, rows = 0;
-
-	/* argument */
-	if (argc>1) {
-		int i;
-
-		for (i=1;i<argc;i++) {
-			if (strncmp(argv[i],"--command=", 10)==0) {
-				cmd = argv[i]+10;
-				continue;
-			} else if ((strcmp(argv[i],"--command")==0 || strcmp(argv[i],"-e") == 0) && (i+1<argc) ) {
-				cmd = argv[++i];
-				continue;
-			} else if (strncmp(argv[i],"--title=", 8)==0) {
-				title = argv[i]+8;
-				continue;
-			} else if ((strcmp(argv[i],"--title")==0 || strcmp(argv[i],"-t")==0 || strcmp(argv[i],"-T")==0)&&(i+1<argc)) {
-				title = argv[++i];
-				continue;
-			} else if (strncmp(argv[i],"--working-directory=", 20)==0) {
-				workdir = g_strdup(argv[i]+20);
-				continue;
-			} else if (strncmp(argv[i],"--geometry=", 11)==0) {
-				sscanf(argv[i]+11, "%dx%d", &cols, &rows);
-				continue;
-			} else if ((strcmp(argv[i],"--loginshell")==0 || strcmp(argv[i],"-l")==0)&&cmd==NULL) {
-				cmd = "sh -l";
-			}
-		}
-	}
-
-	terminal = g_new0(LXTerminal, 1);
-	terminal->parent = lxtermwin;
-	terminal->terms = g_ptr_array_new();
-	terminal->fixedsize = TRUE;
-
-	g_ptr_array_add(lxtermwin->windows, terminal);
-	terminal->index = terminal->parent->windows->len - 1;
-
-	/* Setting */
-	if (setting)
-		terminal->setting = setting;
-
-	/* create window */
-	terminal->mainw = gtk_window_new(GTK_WINDOW_TOPLEVEL);
-
-	/* colormap assign */
-	GdkColormap *colormap = gdk_screen_get_rgba_colormap( gtk_widget_get_screen( GTK_WIDGET(terminal->mainw) ) );
-	if (colormap) gtk_widget_set_colormap( GTK_WIDGET(terminal->mainw), colormap );
-
-	/* when composited changed, reload the terminal settings */
-	g_signal_connect_swapped(GTK_WIDGET(terminal->mainw), "composited-changed", G_CALLBACK(terminal_setting_update), terminal);
-	
-	if (!title)
-		gtk_window_set_title(GTK_WINDOW(terminal->mainw), _("LXTerminal"));
-	else
-		gtk_window_set_title(GTK_WINDOW(terminal->mainw), title);
-
-	gtk_window_set_icon_from_file(GTK_WINDOW(terminal->mainw), PACKAGE_DATA_DIR "/pixmaps/lxterminal.png", NULL);
-	g_object_weak_ref((GObject *) terminal->mainw, terminal_windowexit, terminal);
-
-	/* create box for putting menubar and notebook */
-	terminal->box = gtk_vbox_new(FALSE, 1);
-	gtk_container_add(GTK_CONTAINER(terminal->mainw), terminal->box);
-
-	/* create menubar */
-	terminal->menubar = menubar_init(terminal);
-	gtk_box_pack_start(GTK_BOX(terminal->box), terminal->menubar->menu, FALSE, TRUE, 0);
-
-	/* create notebook */
-	terminal->notebook = gtk_notebook_new();
-	gtk_notebook_set_scrollable(GTK_NOTEBOOK(terminal->notebook), TRUE);
-	gtk_notebook_set_show_tabs(GTK_NOTEBOOK(terminal->notebook), FALSE);
-	gtk_notebook_set_show_border(GTK_NOTEBOOK(terminal->notebook), FALSE);
-
-	/* Tab Position */
-	terminal->tabpos = lxterminal_tab_get_position_id(terminal->setting->tabpos);
-
-	g_signal_connect(terminal->notebook, "switch-page", G_CALLBACK(terminal_switch_tab), terminal);
-	gtk_box_pack_start(GTK_BOX(terminal->box), terminal->notebook, TRUE, TRUE, 0);
-
-	if ( ! workdir) workdir = g_get_current_dir();
-	term = terminal_new(terminal, _("LXTerminal"), workdir, NULL, cmd);
-	g_free(workdir);
-
-	/* set default cols and rows */
-	if (cols&&rows)
-		vte_terminal_set_size(VTE_TERMINAL(term->vte), cols, rows);
-
-	gtk_notebook_append_page(GTK_NOTEBOOK(terminal->notebook), term->box, term->label->main);
-	term->index = gtk_notebook_get_n_pages(GTK_NOTEBOOK(terminal->notebook)) - 1;
-	g_ptr_array_add(terminal->terms, term);
-
-	/* initializing accelerator */
-	lxterminal_accelerator_init(terminal);
-        term_set_swicth_accel(term);
-
-	gtk_widget_show_all(terminal->mainw);
-
-	/* update terminal settings */
-	terminal_setting_update(terminal);
-
-	/* original hints of VTE */
-	gdk_window_get_geometry_hints(GTK_WIDGET(term->vte)->window,
-										&terminal->geometry,
-										&terminal->geom_mask);
-
-	/* resizing terminal with window size */
-	g_signal_connect(terminal->mainw, "size-request", G_CALLBACK(terminal_window_resize), terminal);
-
-	return terminal;
+    /* Apply settings to all open windows. */
+    g_ptr_array_foreach(terminal->parent->windows, (GFunc) terminal_settings_apply, terminal->setting);
+    terminal->setting->geometry_change = FALSE;
 }
 
-int main(gint argc, gchar** argv)
+/* Main entry point. */
+int main(gint argc, gchar * * argv)
 {
-	LXTermWindow *lxtermwin;
-	Setting *setting;
-	gchar *dir, *path;
-	gint i;
-
-	gtk_init(&argc, &argv);
+    /* Initialize GTK. */
+    gtk_init(&argc, &argv);
 
 #ifdef ENABLE_NLS
-	bindtextdomain ( GETTEXT_PACKAGE, PACKAGE_LOCALE_DIR );
-	bind_textdomain_codeset ( GETTEXT_PACKAGE, "UTF-8" );
-	textdomain ( GETTEXT_PACKAGE );
+    bindtextdomain(GETTEXT_PACKAGE, PACKAGE_LOCALE_DIR);
+    bind_textdomain_codeset(GETTEXT_PACKAGE, "UTF-8");
+    textdomain(GETTEXT_PACKAGE);
 #endif
 
-	if (argc>1) {
-		for (i=1;i<argc;i++) {
-			if (strncmp(argv[i],"--command=", 10)==0) {
-				continue;
-			} else if ((strcmp(argv[i],"--command")==0||strcmp(argv[i],"-e")==0)&&(i+1<argc)) {
-				i++;
-				continue;
-			} else if (strncmp(argv[i],"--title=", 8)==0) {
-				continue;
-			} else if ((strcmp(argv[i],"--title")==0||strcmp(argv[i],"-t")==0||strcmp(argv[i],"-T")==0)&&(i+1<argc)) {
-				i++;
-				continue;
-			} else if (strncmp(argv[i],"--working-directory=", 20)==0) {
-				continue;
-			} else if (strncmp(argv[i],"--geometry=", 11)==0) {
-				continue;
-			} else if ((strcmp(argv[i],"--loginshell")==0 || strcmp(argv[i],"-l")==0)) {
-				continue;
-			}
-
-			printf("%s\n", helpmsg);
-			return 0;
-		}
-	}
-
-	/* initializing Window Array */
-	lxtermwin = g_new0(LXTermWindow, 1);
-
-	/* initializing socket */
-	if (!lxterminal_socket_init(lxtermwin, argc, argv))
-		return 0;
-
-	/* load config file */
-	dir = g_build_filename(g_get_user_config_dir(), "lxterminal" , NULL);
-	g_mkdir_with_parents(dir, 0700);
-	path = g_build_filename(dir, "lxterminal.conf", NULL);
-	g_free(dir);
-
-	if (!g_file_test(path, G_FILE_TEST_EXISTS)) {
-		setting = load_setting_from_file(PACKAGE_DATA_DIR "/lxterminal/lxterminal.conf");
-		/* save to user's directory */
-		setting_save(setting);
-	} else {
-		setting = load_setting_from_file(path);
-	}
-
-	g_free(path);
-
-	/* initializing something */
-	lxtermwin->windows = g_ptr_array_new();
-	lxtermwin->setting = setting;
-
-	/* initializing LXTerminal */
-	lxterminal_init(lxtermwin, argc, argv, setting);
-
-	gtk_main();
+    /* Parse the command arguments.  If there is an error, display usage help and exit. */
+    CommandArguments arguments;
+    if ( ! lxterminal_process_arguments(argc, argv, &arguments))
+    {
+        printf("%s\n", usage_display);
+        return 0;
+    }
+
+    /* Initialize impure storage. */
+    LXTermWindow * lxtermwin = g_new0(LXTermWindow, 1);
+
+    /* Initialize socket.  If we were able to get another LXTerminal to manage the window, exit. */
+    if ( ! lxterminal_socket_initialize(lxtermwin, &arguments))
+        return 0;
+
+    /* Load user preferences. */
+    gchar * dir = g_build_filename(g_get_user_config_dir(), "lxterminal" , NULL);
+    g_mkdir_with_parents(dir, S_IRUSR | S_IWUSR | S_IXUSR);
+    gchar * path = g_build_filename(dir, "lxterminal.conf", NULL);
+    g_free(dir);
+
+    if ( ! g_file_test(path, G_FILE_TEST_EXISTS))
+    {
+        /* Copy the system-wide settings to the user's configuration. */
+        lxtermwin->setting = load_setting_from_file(PACKAGE_DATA_DIR "/lxterminal/lxterminal.conf");
+        setting_save(lxtermwin->setting);
+    }
+    else
+        lxtermwin->setting = load_setting_from_file(path);
+
+    g_free(path);
+
+    /* Finish initializing the impure area and start the first LXTerminal. */
+    lxtermwin->windows = g_ptr_array_new();
+    lxterminal_initialize(lxtermwin, &arguments, lxtermwin->setting);
+
+    /* Run the main loop. */
+    gtk_main();
 
     return 0;
 }
diff --git a/src/lxterminal.h b/src/lxterminal.h
index 175d5a3..2e5e873 100644
--- a/src/lxterminal.h
+++ b/src/lxterminal.h
@@ -1,3 +1,23 @@
+/**
+ *      Copyright 2008 Fred Chien <cfsghost@gmail.com>
+ *      Copyright (c) 2010 LxDE Developers, see the file AUTHORS for details.
+ *
+ *      This program is free software; you can redistribute it and/or modify
+ *      it under the terms of the GNU General Public License as published by
+ *      the Free Software Foundation; either version 2 of the License, or
+ *      (at your option) any later version.
+ *
+ *      This program is distributed in the hope that it will be useful,
+ *      but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *      GNU General Public License for more details.
+ *
+ *      You should have received a copy of the GNU General Public License
+ *      along with this program; if not, write to the Free Software
+ *      Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ *      MA 02110-1301, USA.
+ */
+
 #ifndef LXTERMINAL_H
 #define LXTERMINAL_H
 
@@ -9,7 +29,7 @@
 #define QUIT_ACCEL "<CTRL><SHIFT>Q"
 #define COPY_ACCEL "<CTRL><SHIFT>C"
 #define PASTE_ACCEL "<CTRL><SHIFT>V"
-#define RENAME_TAB_ACCEL "<CTRL><SHIFT>R"
+#define NAME_TAB_ACCEL "<CTRL><SHIFT>I"
 #define PREVIOUS_TAB_ACCEL "<CTRL>Page_Up"
 #define NEXT_TAB_ACCEL "<CTRL>Page_Down"
 #define MOVE_TAB_LEFT_ACCEL "<CTRL><SHIFT>Page_Up"
@@ -19,58 +39,59 @@
 #define DINGUS1 "(((news|telnet|nttp|file|http|ftp|https)://)|(www|ftp)[-A-Za-z0-9]*\\.)[-A-Za-z0-9\\.]+(:[0-9]*)?"
 #define DINGUS2 "(((news|telnet|nttp|file|http|ftp|https)://)|(www|ftp)[-A-Za-z0-9]*\\.)[-A-Za-z0-9\\.]+(:[0-9]*)?/[-A-Za-z0-9_\\$\\.\\+\\!\\*\\(\\),;:@&=\\?/~\\#\\%]*[^]'\\.}>\\) ,\\\"]"
 
+/* Top level application context. */
 typedef struct _lxtermwindow {
-	Setting   *setting;
-	GPtrArray *windows;
+    Setting * setting;				/* Pointer to current user preferences */
+    GPtrArray * windows;			/* Array of pointers to LXTerminal structures */
 } LXTermWindow;
 
-typedef struct _menu {
-	GtkWidget      *menu;
-	GtkItemFactory *item_factory;
-	GtkAccelGroup  *accel_group;
-} Menu;
-
+/* Representative of a toplevel window. */
 typedef struct _lxterminal {
-	LXTermWindow *parent;
-	gint       index;
-	GtkWidget *mainw;
-	GtkWidget *box;
-	Menu      *menubar;
-	GtkWidget *notebook;
-	GPtrArray *terms;
-	gint       resize_idle_id;
-	Setting   *setting;
-	GdkGeometry geometry;
-	GdkWindowHints geom_mask;
-	gboolean fixedsize;
-	gboolean rgba;
-	GdkColor background;
-	GdkColor foreground;
-	gint     tabpos;
-	gboolean hidemenubar;
-	gboolean hidescrollbar;
-	gint cursormode;
-	gboolean cursorblinks;
+    LXTermWindow * parent;			/* Back pointer to top level context */
+    gint index;					/* Index of this element in parent->windows */
+    GtkWidget * window;				/* Toplevel window */
+    GtkWidget * box;				/* Vertical box, child of toplevel window */
+    GtkWidget * menu;				/* Menu bar, child of vertical box */
+    GtkAccelGroup * accel_group;		/* Accelerator group for accelerators on this window */
+    GtkWidget * notebook;			/* Notebook, child of vertical box */
+    GPtrArray * terms;				/* Array of pointers to Term structures */
+    Setting * setting;				/* A copy of parent->setting */
+    GdkGeometry geometry;			/* Geometry hints (see XGetWMNormalHints) */
+    GdkWindowHints geometry_mask;		/* Mask of valid data in geometry hints */
+    gboolean fixed_size;			/* True if the terminal is fixed size */
+    gboolean rgba;				/* True if colormap is RGBA */
+    GdkColor background;			/* User preference background color converted to GdkColor */
+    GdkColor foreground;			/* User preference foreground color converted to GdkColor */
+    gint tab_position;				/* Tab position as an integer value */
 } LXTerminal;
 
-typedef struct _tab {
-	GtkWidget *main;
-	GtkWidget *label;
-	GtkWidget *close_btn;
-} LXTab;
-
+/* Representative of a tab within a toplevel window. */
 typedef struct _term {
-	gint index;
-	LXTerminal *parent;
-	LXTab *label;
-	GtkWidget *vte;
-	GtkWidget *scrollbar;
-	GtkWidget *box;
-	pid_t pid;
-	GClosure* closure;
+    LXTerminal * parent;			/* Back pointer to LXTerminal */
+    gint index;					/* Index of this element in parent->terms */
+    GtkWidget * tab;				/* Toplevel of the tab */
+    GtkWidget * label;				/* Label of the tab, child of the toplevel */
+    gboolean user_specified_label;		/* User did "Name Tab", so we will never overwrite this with the window title */
+    GtkWidget * close_button;			/* Close button for the tab, child of the toplevel */
+    GtkWidget * box;				/* Horizontal box, child of notebook */
+    GtkWidget * vte;				/* VteTerminal, child of horizontal box */
+    GtkWidget * scrollbar;			/* Scroll bar, child of horizontal box */
+    pid_t pid;					/* Process ID of the process that has this as its terminal */
+    GClosure * closure;				/* Accelerator structure */
 } Term;
 
-LXTerminal *lxterminal_init(LXTermWindow *lxtermwin, gint argc, gchar **argv, Setting *setting);
-void terminal_setting_update(LXTerminal *terminal);
+/* Output of lxterminal_process_arguments. */
+typedef struct _command_arguments {
+    char * executable;				/* Value of argv[0]; points into argument vector */
+    gchar * command;				/* Value of -e, --command; memory allocated by glib */
+    int geometry_columns;			/* Value of --geometry */
+    int geometry_rows;
+    char * title;				/* Value of -t, -T, --title; points into argument vector */
+    char * working_directory;			/* Value of --working-directory; points into argument vector */
+} CommandArguments;
+
+extern gboolean lxterminal_process_arguments(gint argc, gchar * * argv, CommandArguments * arguments);
+extern LXTerminal * lxterminal_initialize(LXTermWindow * lxtermwin, CommandArguments * arguments, Setting * setting);
+extern void terminal_settings_apply_to_all(LXTerminal * terminal);
 
 #endif
diff --git a/src/preferences.c b/src/preferences.c
index 502cd13..913e686 100644
--- a/src/preferences.c
+++ b/src/preferences.c
@@ -1,5 +1,6 @@
-/*
+/**
  *      Copyright 2008 Fred Chien <cfsghost@gmail.com>
+ *      Copyright (c) 2010 LxDE Developers, see the file AUTHORS for details.
  *
  *      This program is free software; you can redistribute it and/or modify
  *      it under the terms of the GNU General Public License as published by
@@ -25,378 +26,241 @@
 #include "setting.h"
 #include "preferences.h"
 
-#if (GTK_MINOR_VERSION < 12)
-gchar *gdk_color_to_string(const GdkColor *color)
+static void preferences_dialog_response_event(GtkWidget * dialog, gint response, LXTerminal * terminal);
+static void preferences_dialog_font_set_event(GtkFontButton * widget, LXTerminal * terminal);
+static void preferences_dialog_background_color_set_event(GtkColorButton * widget, LXTerminal * terminal);
+static void preferences_dialog_foreground_color_set_event(GtkColorButton * widget, LXTerminal * terminal);
+static void preferences_dialog_allow_bold_toggled_event(GtkToggleButton * widget, LXTerminal * terminal);
+static void preferences_dialog_cursor_blink_toggled_event(GtkToggleButton * widget, LXTerminal * terminal);
+static void preferences_dialog_cursor_underline_toggled_event(GtkToggleButton * widget, LXTerminal * terminal);
+static void preferences_dialog_audible_bell_toggled_event(GtkToggleButton * widget, LXTerminal * terminal);
+static void preferences_dialog_tab_position_changed_event(GtkComboBox * widget, LXTerminal * terminal);
+static void preferences_dialog_scrollback_value_changed_event(GtkSpinButton * widget, LXTerminal * terminal);
+static void preferences_dialog_hide_scroll_bar_toggled_event(GtkToggleButton * widget, LXTerminal * terminal);
+static void preferences_dialog_hide_menu_bar_toggled_event(GtkToggleButton * widget, LXTerminal * terminal);
+static void preferences_dialog_hide_close_button_toggled_event(GtkToggleButton * widget, LXTerminal * terminal);
+static gboolean preferences_dialog_selection_focus_out_event(GtkWidget * widget, GdkEventFocus * event, LXTerminal * terminal);
+static void preferences_dialog_disable_f10_toggled_event(GtkToggleButton * widget, LXTerminal * terminal);
+
+/* Handler for "response" signal on preferences dialog. */
+static void preferences_dialog_response_event(GtkWidget * dialog, gint response, LXTerminal * terminal)
 {
-    return g_strdup_printf("#%04x%04x%04x", color->red, color->green, color->blue);
+    if (response == GTK_RESPONSE_OK)
+        setting_save(terminal->setting);
+
+    /* Dismiss dialog. */
+    gtk_widget_destroy(dialog);
 }
-#endif
-
-void lxterminal_preferences_style_constructor(Prefer *prefer, TabWidget *tab);
-void lxterminal_preferences_style_destructor(Prefer *prefer, TabWidget *tab);
-void lxterminal_preferences_style_save(Prefer *prefer, TabWidget *tab);
-void lxterminal_preferences_display_constructor(Prefer *prefer, TabWidget *tab);
-void lxterminal_preferences_display_destructor(Prefer *prefer, TabWidget *tab);
-void lxterminal_preferences_display_save(Prefer *prefer, TabWidget *tab);
-void lxterminal_preferences_misc_constructor(Prefer *prefer, TabWidget *tab);
-void lxterminal_preferences_misc_destructor(Prefer *prefer, TabWidget *tab);
-void lxterminal_preferences_misc_save(Prefer *prefer, TabWidget *tab);
-
-static TabGroup tabs[] = {
-	{
-		N_("Style"),
-		"preferences-style.png",
-		lxterminal_preferences_style_constructor,
-		lxterminal_preferences_style_destructor,
-		lxterminal_preferences_style_save
-	},
-	{
-		N_("Display"),
-		"preferences-display.png",
-		lxterminal_preferences_display_constructor,
-		lxterminal_preferences_display_destructor,
-		lxterminal_preferences_display_save
-	},
-	{
-		N_("Misc"),
-		"preferences-misc.png",
-		lxterminal_preferences_misc_constructor,
-		lxterminal_preferences_misc_destructor,
-		lxterminal_preferences_misc_save
-	}
-};
-
-void lxterminal_preferences_style_constructor(Prefer *prefer, TabWidget *tab)
+
+/* Handler for "font-set" signal on Terminal Font font button. */
+static void preferences_dialog_font_set_event(GtkFontButton * widget, LXTerminal * terminal)
 {
-	PreferStyle *ps;
-
-	/* create general data structure */
-	ps = g_new0(PreferStyle, 1);
-	tab->childs = ps;
-
-	ps->box = gtk_table_new(4, 4, FALSE);
-	gtk_table_set_row_spacings(GTK_TABLE(ps->box), 3);
-	gtk_table_set_col_spacings(GTK_TABLE(ps->box), 5);
-
-	/* terminal font */
-	ps->font_label = gtk_label_new(_("Terminal Font:"));
-	gtk_misc_set_alignment(GTK_MISC(ps->font_label), 1, 0.5);
-	ps->font_button = gtk_font_button_new_with_font(prefer->terminal->setting->fontname);
-	gtk_table_attach_defaults(GTK_TABLE(ps->box), ps->font_label, 0,2, 0,1);
-	gtk_table_attach_defaults(GTK_TABLE(ps->box), ps->font_button, 2,4, 0,1);
-
-	/* Background color */
-	ps->bgcolor_label = gtk_label_new(_("Background:"));
-	gtk_misc_set_alignment(GTK_MISC(ps->bgcolor_label), 1, 0.5);
-	ps->bgcolor_entry = gtk_color_button_new_with_color(&prefer->terminal->background);
-	gtk_color_button_set_use_alpha(GTK_COLOR_BUTTON(ps->bgcolor_entry), TRUE);
-	gtk_color_button_set_alpha(GTK_COLOR_BUTTON(ps->bgcolor_entry), prefer->terminal->setting->bgalpha);
-	gtk_table_attach_defaults(GTK_TABLE(ps->box), ps->bgcolor_label, 0,2, 1,2);
-	gtk_table_attach_defaults(GTK_TABLE(ps->box), ps->bgcolor_entry, 2,4, 1,2);
-
-	/* Foreground color */
-	ps->fgcolor_label = gtk_label_new(_("Foreground:"));
-	gtk_misc_set_alignment(GTK_MISC(ps->fgcolor_label), 1, 0.5);
-	ps->fgcolor_entry = gtk_color_button_new_with_color(&prefer->terminal->foreground);
-	gtk_table_attach_defaults(GTK_TABLE(ps->box), ps->fgcolor_label, 0,2, 2,3);
-	gtk_table_attach_defaults(GTK_TABLE(ps->box), ps->fgcolor_entry, 2,4, 2,3);
-
-	/* Cursor Blinks */
-	ps->cursorblinks_label = gtk_label_new(_("Cursor Blinks:"));
-	gtk_misc_set_alignment(GTK_MISC(ps->cursorblinks_label), 1, 0.5);
-	ps->cursorblinks_checkbox = gtk_check_button_new();
-	gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(ps->cursorblinks_checkbox), prefer->terminal->setting->cursorblinks);
-	gtk_table_attach_defaults(GTK_TABLE(ps->box), ps->cursorblinks_label, 0,2,3,4);
-	gtk_table_attach_defaults(GTK_TABLE(ps->box), ps->cursorblinks_checkbox, 2,4,3,4);
-
-	/* adding to page */
-	gtk_container_add(GTK_CONTAINER(tab->page), ps->box);
+    g_free(terminal->setting->font_name);
+    terminal->setting->font_name = g_strdup(gtk_font_button_get_font_name(widget));
+    terminal->setting->geometry_change = TRUE;		/* Force the terminals to resize */
+    terminal_settings_apply_to_all(terminal);
 }
 
-void lxterminal_preferences_display_constructor(Prefer *prefer, TabWidget *tab)
+/* Handler for "color-set" signal on Background Color color button. */
+static void preferences_dialog_background_color_set_event(GtkColorButton * widget, LXTerminal * terminal)
 {
-	PreferDisplay *pd;
-
-	/* create general data structure */
-	pd = g_new0(PreferDisplay, 1);
-	tab->childs = pd;
-
-	pd->box = gtk_table_new(4,4, FALSE);
-	gtk_table_set_row_spacings(GTK_TABLE(pd->box), 3);
-	gtk_table_set_col_spacings(GTK_TABLE(pd->box), 5);
-
-	/* tab-panel position */
-	pd->tabpos_label = gtk_label_new(_("Tab panel position:"));
-	gtk_misc_set_alignment(GTK_MISC(pd->tabpos_label), 1, 0.5);
-	pd->tabpos_combobox = gtk_combo_box_new_text();
-	gtk_combo_box_append_text(GTK_COMBO_BOX (pd->tabpos_combobox), _("Top"));
-	gtk_combo_box_append_text(GTK_COMBO_BOX (pd->tabpos_combobox), _("Bottom"));
-	gtk_combo_box_append_text(GTK_COMBO_BOX (pd->tabpos_combobox), _("Left"));
-	gtk_combo_box_append_text(GTK_COMBO_BOX (pd->tabpos_combobox), _("Right"));
-	gtk_combo_box_set_active (GTK_COMBO_BOX (pd->tabpos_combobox), prefer->terminal->tabpos);
-	gtk_table_attach_defaults(GTK_TABLE(pd->box), pd->tabpos_label, 0,2, 0,1);
-	gtk_table_attach_defaults(GTK_TABLE(pd->box), pd->tabpos_combobox, 2,4, 0,1);
-
-	/* Scrollback buffer */
-	pd->scrollback_label = gtk_label_new(_("Scrollback lines:"));
-	gtk_misc_set_alignment(GTK_MISC(pd->scrollback_label), 1, 0.5);
-	pd->scrollback_entry = gtk_spin_button_new_with_range(100, 100000, 10);
-	gtk_spin_button_set_value(GTK_SPIN_BUTTON(pd->scrollback_entry), (gdouble)prefer->terminal->setting->scrollback);
-	gtk_table_attach_defaults(GTK_TABLE(pd->box), pd->scrollback_label, 0,2, 1,2);
-	gtk_table_attach_defaults(GTK_TABLE(pd->box), pd->scrollback_entry, 2,4, 1,2);
-
-	/* Hide scroll bar */
-	pd->hidescrollbar_label = gtk_label_new(_("Hide scroll bar:"));
-	gtk_misc_set_alignment(GTK_MISC(pd->hidescrollbar_label), 1, 0.5);
-	pd->hidescrollbar_checkbox = gtk_check_button_new();
-	gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(pd->hidescrollbar_checkbox), prefer->terminal->setting->hidescrollbar);
-	gtk_table_attach_defaults(GTK_TABLE(pd->box), pd->hidescrollbar_label, 0,2,2,3);
-	gtk_table_attach_defaults(GTK_TABLE(pd->box), pd->hidescrollbar_checkbox, 2,4,2,3);
-
-	/* Hide menu bar */
-	pd->hidemenubar_label = gtk_label_new(_("Hide menu bar:"));
-	gtk_misc_set_alignment(GTK_MISC(pd->hidemenubar_label), 1, 0.5);
-	pd->hidemenubar_checkbox = gtk_check_button_new();
-	gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(pd->hidemenubar_checkbox), prefer->terminal->setting->hidemenubar);
-	gtk_table_attach_defaults(GTK_TABLE(pd->box), pd->hidemenubar_label, 0,2,3,4);
-	gtk_table_attach_defaults(GTK_TABLE(pd->box), pd->hidemenubar_checkbox, 2,4,3,4);
-
-	/* adding to page */
-	gtk_container_add(GTK_CONTAINER(tab->page), pd->box);
+    gtk_color_button_get_color(widget, &terminal->setting->background_color);
+    terminal->setting->background_alpha = gtk_color_button_get_alpha(widget);
+    terminal_settings_apply_to_all(terminal);
 }
 
-void lxterminal_preferences_misc_constructor(Prefer *prefer, TabWidget *tab)
+/* Handler for "color-set" signal on Foreground Color color button. */
+static void preferences_dialog_foreground_color_set_event(GtkColorButton * widget, LXTerminal * terminal)
 {
-	PreferMisc *pm;
-
-	/* create general data structure */
-	pm = g_new0(PreferMisc, 1);
-	tab->childs = pm;
-
-	pm->box = gtk_table_new(2,4, FALSE);
-	gtk_table_set_row_spacings(GTK_TABLE(pm->box), 3);
-	gtk_table_set_col_spacings(GTK_TABLE(pm->box), 5);
-
-	/* Select-by-word */
-	pm->selchars_label = gtk_label_new(_("Select-by-word characters:"));
-	gtk_misc_set_alignment(GTK_MISC(pm->selchars_label), 1, 0.5);
-	pm->selchars_entry = gtk_entry_new();
-	gtk_entry_set_text(GTK_ENTRY(pm->selchars_entry), prefer->terminal->setting->selchars);
-	gtk_table_attach_defaults(GTK_TABLE(pm->box), pm->selchars_label, 0,2, 0,1);
-	gtk_table_attach_defaults(GTK_TABLE(pm->box), pm->selchars_entry, 2,4, 0,1);
-
-	/* Disable F10 for menu */
-	pm->disablef10_label = gtk_label_new(_("Disable F10 shortcut for menu:"));
-	gtk_misc_set_alignment(GTK_MISC(pm->disablef10_label), 1, 0.5);
-	pm->disablef10_checkbox = gtk_check_button_new();
-	gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(pm->disablef10_checkbox), prefer->terminal->setting->disablef10);
-	gtk_table_attach_defaults(GTK_TABLE(pm->box), pm->disablef10_label, 0,2, 1,2);
-	gtk_table_attach_defaults(GTK_TABLE(pm->box), pm->disablef10_checkbox, 2,4, 1,2);
-
-	/* adding to page */
-	gtk_container_add(GTK_CONTAINER(tab->page), pm->box);
+    gtk_color_button_get_color(widget, &terminal->setting->foreground_color);
+    terminal_settings_apply_to_all(terminal);
 }
 
-void lxterminal_preferences_style_destructor(Prefer *prefer, TabWidget *tab)
+/* Handler for "toggled" signal on Allow Bold toggle button.
+ * Use the complement so the default is FALSE. */
+static void preferences_dialog_allow_bold_toggled_event(GtkToggleButton * widget, LXTerminal * terminal)
 {
-	PreferStyle *ps = tab->childs;
-
-	g_free(ps);
+    terminal->setting->disallow_bold = ! gtk_toggle_button_get_active(widget);
+    terminal_settings_apply_to_all(terminal);
 }
 
-void lxterminal_preferences_display_destructor(Prefer *prefer, TabWidget *tab)
+/* Handler for "toggled" signal on Cursor Blink toggle button. */
+static void preferences_dialog_cursor_blink_toggled_event(GtkToggleButton * widget, LXTerminal * terminal)
 {
-	PreferDisplay *pd = tab->childs;
-
-	g_free(pd);
+    terminal->setting->cursor_blink = gtk_toggle_button_get_active(widget);
+    terminal_settings_apply_to_all(terminal);
 }
 
-void lxterminal_preferences_misc_destructor(Prefer *prefer, TabWidget *tab)
+/* Handler for "toggled" signal on Cursor Underline radio button. */
+static void preferences_dialog_cursor_underline_toggled_event(GtkToggleButton * widget, LXTerminal * terminal)
 {
-	PreferMisc *pm = tab->childs;
-
-	g_free(pm);
+    terminal->setting->cursor_underline = gtk_toggle_button_get_active(widget);
+    terminal_settings_apply_to_all(terminal);
 }
 
-void lxterminal_preferences_style_save(Prefer *prefer, TabWidget *tab)
+/* Handler for "toggled" signal on Audible Bell radio button. */
+static void preferences_dialog_audible_bell_toggled_event(GtkToggleButton * widget, LXTerminal * terminal)
 {
-	PreferStyle *ps = tab->childs;
-
-	g_free( prefer->terminal->setting->fontname );
-	g_free( prefer->terminal->setting->selchars );
-	prefer->terminal->setting->fontname = g_strdup( gtk_font_button_get_font_name((GtkFontButton *)ps->font_button) );
-	prefer->terminal->setting->bgalpha = (guint16)gtk_color_button_get_alpha(GTK_COLOR_BUTTON(ps->bgcolor_entry));
-	prefer->terminal->setting->cursorblinks = (gboolean)gtk_toggle_button_get_active((GtkToggleButton *)ps->cursorblinks_checkbox);
-
-	/* background and foreground */
-	gtk_color_button_get_color( GTK_COLOR_BUTTON(ps->bgcolor_entry), &prefer->terminal->background);
-	prefer->terminal->setting->bgcolor = g_strdup( gdk_color_to_string(&prefer->terminal->background) );
-	gtk_color_button_get_color(GTK_COLOR_BUTTON(ps->fgcolor_entry), &prefer->terminal->foreground);
-	prefer->terminal->setting->fgcolor = g_strdup( gdk_color_to_string(&prefer->terminal->foreground) );
+    terminal->setting->audible_bell = gtk_toggle_button_get_active(widget);
+    terminal_settings_apply_to_all(terminal);
 }
 
-void lxterminal_preferences_display_save(Prefer *prefer, TabWidget *tab)
+/* Handler for "changed" signal on Tab Position combo box. */
+static void preferences_dialog_tab_position_changed_event(GtkComboBox * widget, LXTerminal * terminal)
 {
-	PreferDisplay *pd = tab->childs;
-
-	prefer->terminal->setting->scrollback = (glong)gtk_spin_button_get_value_as_int((GtkSpinButton *)pd->scrollback_entry);
-	prefer->terminal->setting->hidemenubar = (gboolean)gtk_toggle_button_get_active((GtkToggleButton *)pd->hidemenubar_checkbox);
-	prefer->terminal->setting->hidescrollbar = (gboolean)gtk_toggle_button_get_active((GtkToggleButton *)pd->hidescrollbar_checkbox);
-
-	/* Tab position */
-	g_free( prefer->terminal->setting->tabpos );
-	prefer->terminal->tabpos = gtk_combo_box_get_active((GtkComboBox *)pd->tabpos_combobox);
-	switch(prefer->terminal->tabpos) {
-		case 0:
-			prefer->terminal->setting->tabpos = g_strdup("top");
-			break;
-		case 1:
-			prefer->terminal->setting->tabpos = g_strdup("bottom");
-			break;
-		case 2:
-			prefer->terminal->setting->tabpos = g_strdup("left");
-			break;
-		case 3:
-			prefer->terminal->setting->tabpos = g_strdup("right");
-			break;
-	}
+    /* Convert the index into a string, which is what we put in the configuration file. */
+    char * p = NULL;
+    switch (gtk_combo_box_get_active(widget))
+    {
+        case 0:		p = "top";		break;
+        case 1:		p = "bottom";		break;
+        case 2:		p = "left";		break;
+        case 3:		p = "right";		break;
+    }
+    if (p != NULL)
+    {
+        g_free(terminal->setting->tab_position);
+        terminal->setting->tab_position = g_strdup(p);
+    }
+    terminal_settings_apply_to_all(terminal);
 }
 
-void lxterminal_preferences_misc_save(Prefer *prefer, TabWidget *tab)
+/* Handler for "value-changed" signal on Scrollback spin button. */
+static void preferences_dialog_scrollback_value_changed_event(GtkSpinButton * widget, LXTerminal * terminal)
 {
-	PreferMisc *pm = tab->childs;
-
-	prefer->terminal->setting->selchars = g_strdup( gtk_entry_get_text((GtkEntry *)pm->selchars_entry) );
-	prefer->terminal->setting->disablef10 = (gboolean)gtk_toggle_button_get_active((GtkToggleButton *)pm->disablef10_checkbox);
+    terminal->setting->scrollback = gtk_spin_button_get_value_as_int(widget);
+    terminal_settings_apply_to_all(terminal);
 }
 
-TabWidget *lxterminal_preferences_page_new(TabGroup *tabgroup)
+/* Handler for "toggled" signal on Hide Scroll Bar toggle button. */
+static void preferences_dialog_hide_scroll_bar_toggled_event(GtkToggleButton * widget, LXTerminal * terminal)
 {
-	TabWidget *tab;
-
-	tab = g_new0(TabWidget, 1);
-
-	/* create container without window */
-	tab->page = gtk_event_box_new();
-	GTK_WIDGET_SET_FLAGS(tab->page, GTK_NO_WINDOW);
-
-	/* Sets the border width of the container. */
-	gtk_container_set_border_width(GTK_CONTAINER(tab->page), 10);
-
-	/* create container for label */
-	tab->label_box = gtk_hbox_new(FALSE, 4);
-
-	/* create icon */
-	/* tab->icon = gtk_image_new_from_file(tabgroup->icon); */
-
-	/* create label */
-	tab->label = gtk_label_new(_(tabgroup->name));
-	gtk_misc_set_alignment(GTK_MISC(tab->label), 0.0, 0.5);
-	gtk_misc_set_padding(GTK_MISC(tab->label), 2, 2);
-
-	/* add all of widgets to label box */
-	/* gtk_box_pack_start(GTK_BOX(tab->label_box), tab->icon, FALSE, FALSE, 0); */
-	gtk_box_pack_start(GTK_BOX(tab->label_box), tab->label, FALSE, FALSE, 0);
-
-	gtk_widget_show_all(tab->label_box);
-
-	return tab;
+    terminal->setting->hide_scroll_bar = gtk_toggle_button_get_active(widget);
+    terminal_settings_apply_to_all(terminal);
 }
 
-void lxterminal_preferences_page_init(Prefer *prefer)
+/* Handler for "toggled" signal on Hide Menu Bar toggle button. */
+static void preferences_dialog_hide_menu_bar_toggled_event(GtkToggleButton * widget, LXTerminal * terminal)
 {
-	TabWidget *tab;
-	int i;
-
-	/* initializing all of tabs */
-	for (i=0;i<G_N_ELEMENTS(tabs);i++) {
-		tab = lxterminal_preferences_page_new(&tabs[i]);
-		tabs[i].constructor(prefer, tab);
-
-		/* add to Array */
-		g_ptr_array_add(prefer->tab, tab);
-
-		/* add to gtknotebook */
-		gtk_notebook_append_page(GTK_NOTEBOOK(prefer->notebook), tab->page, tab->label_box);
-	}
+    terminal->setting->hide_menu_bar = gtk_toggle_button_get_active(widget);
+    terminal_settings_apply_to_all(terminal);
 }
 
-void lxterminal_preferences_free(gpointer prefer_p, GObject * where_the_object_was)
+/* Handler for "toggled" signal on Hide Close Button toggle button. */
+static void preferences_dialog_hide_close_button_toggled_event(GtkToggleButton * widget, LXTerminal * terminal)
 {
-	Prefer * prefer = (Prefer *) prefer_p;
-	TabWidget *tab;
-	int i;
-
-	for (i=0;i<prefer->tab->len;i++) {
-		tab = g_ptr_array_index(prefer->tab, i);
-		tabs[i].destructor(prefer, tab);
+    terminal->setting->hide_close_button = gtk_toggle_button_get_active(widget);
+    terminal_settings_apply_to_all(terminal);
+}
 
-		g_free(tab);
-	}
+/* Handler for "focus-out-event" on Selection Characters entry. */
+static gboolean preferences_dialog_selection_focus_out_event(GtkWidget * widget, GdkEventFocus * event, LXTerminal * terminal)
+{
+    const gchar * new_text = gtk_entry_get_text(GTK_ENTRY(widget));
+    g_free(terminal->setting->word_selection_characters);
+    terminal->setting->word_selection_characters = g_strdup(new_text);
+    terminal_settings_apply_to_all(terminal);
+    return FALSE;
+}
 
-	g_ptr_array_free(prefer->tab, TRUE);
-	gtk_widget_destroy(prefer->dialog);
-	g_free(prefer);
+/* Handler for "toggled" signal on Disable F10 toggle button. */
+static void preferences_dialog_disable_f10_toggled_event(GtkToggleButton * widget, LXTerminal * terminal)
+{
+    terminal->setting->disable_f10 = gtk_toggle_button_get_active(widget);
+    terminal_settings_apply_to_all(terminal);
 }
 
-void lxterminal_preferences_on_response(GtkDialog* dlg, gint response, Prefer *prefer)
+/* Convert the user preference on tab position, expressed as a string, to the internal representation.
+ * These have to match the order in the .glade file. */
+gint terminal_tab_get_position_id(gchar * position)
 {
-	gint i;
-	TabWidget *tab;
-
-	if(G_LIKELY(response == GTK_RESPONSE_OK)) {
-		for (i=0;i<prefer->tab->len;i++) {
-			tab = g_ptr_array_index(prefer->tab, i);
-			tabs[i].save(prefer, tab);
-		}
-
-		/* saving perferences */
-		setting_save(prefer->terminal->setting);
-
-		/* update NOW! */
-		/* update all terminals in all windows */
-		g_ptr_array_foreach(prefer->terminal->parent->windows,
-					(GFunc) terminal_setting_update,
-					prefer->terminal->setting);
-	}
-
-	gtk_widget_destroy((GtkWidget *)dlg);
+    if (strcmp(position, "bottom") == 0)
+        return 1;
+    else if (strcmp(position, "left") == 0)
+        return 2;
+    else if (strcmp(position, "right") == 0)
+        return 3;
+    else
+        return 0;
 }
 
-void lxterminal_preferences_dialog(GtkAction *action, gpointer data)
+/* Initialize and display the preferences dialog. */
+void terminal_preferences_dialog(GtkAction * action, LXTerminal * terminal)
 {
-	LXTerminal *terminal = (LXTerminal *)data;
-	Prefer *prefer;
-	GtkWidget *pdialog;
-	GtkWidget *tab;
-
-	prefer = g_new0(Prefer, 1);
-	prefer->terminal = terminal;
-	prefer->tab = g_ptr_array_new();
-
-	/* create window */
-	prefer->dialog = gtk_dialog_new_with_buttons(_("Preferences"),
-                                       NULL,
-                                       GTK_DIALOG_NO_SEPARATOR,
-                                       GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
-                                       GTK_STOCK_OK, GTK_RESPONSE_OK,
-                                       NULL );
-	gtk_dialog_set_alternative_button_order((GtkDialog *)prefer->dialog, GTK_RESPONSE_OK, GTK_RESPONSE_CANCEL, -1);
-	gtk_dialog_set_default_response((GtkDialog *)prefer->dialog, GTK_RESPONSE_OK);
-	gtk_window_set_position(GTK_WINDOW(prefer->dialog), GTK_WIN_POS_CENTER);
-
-	/* g_signal */
-	g_signal_connect(prefer->dialog, "response", G_CALLBACK(lxterminal_preferences_on_response), prefer);
-	g_object_weak_ref((GObject *)prefer->dialog, lxterminal_preferences_free, prefer);
-
-	/* create notebook */
-	prefer->notebook = gtk_notebook_new();
-	gtk_notebook_set_scrollable(GTK_NOTEBOOK(prefer->notebook), TRUE);
-	gtk_notebook_set_show_tabs(GTK_NOTEBOOK(prefer->notebook), TRUE);
-	gtk_box_pack_start(GTK_BOX(((GtkDialog *)prefer->dialog)->vbox), prefer->notebook, FALSE, FALSE, 0);
-
-	/* initializing pages */
-	lxterminal_preferences_page_init(prefer);
-
-	gtk_widget_show_all(prefer->dialog);
+    Setting * setting = terminal->setting;
+
+    GtkBuilder * builder = gtk_builder_new();
+    if ( ! gtk_builder_add_from_file(builder, PACKAGE_DATA_DIR "/lxterminal/lxterminal-preferences.ui", NULL))
+    {
+        g_object_unref(builder);
+        return;
+    }
+
+    GtkWidget * dialog = GTK_WIDGET(gtk_builder_get_object(builder, "lxterminal_preferences"));
+    gtk_window_set_title(GTK_WINDOW(dialog), _("LXTerminal"));
+    gtk_window_set_icon_from_file(GTK_WINDOW(dialog), PACKAGE_DATA_DIR "/pixmaps/lxterminal.png", NULL);
+    g_signal_connect(G_OBJECT(dialog), "response", G_CALLBACK(preferences_dialog_response_event), terminal);
+
+    GtkWidget * w = GTK_WIDGET(gtk_builder_get_object(builder, "terminal_font"));
+    gtk_font_button_set_font_name(GTK_FONT_BUTTON(w), setting->font_name);
+    g_signal_connect(G_OBJECT(w), "font-set", G_CALLBACK(preferences_dialog_font_set_event), terminal);
+
+    w = GTK_WIDGET(gtk_builder_get_object(builder, "background_color"));
+    gtk_color_button_set_color(GTK_COLOR_BUTTON(w), &setting->background_color);
+    gtk_color_button_set_alpha(GTK_COLOR_BUTTON(w), setting->background_alpha);
+    g_signal_connect(G_OBJECT(w), "color-set", G_CALLBACK(preferences_dialog_background_color_set_event), terminal);
+
+    w = GTK_WIDGET(gtk_builder_get_object(builder, "foreground_color"));
+    gtk_color_button_set_color(GTK_COLOR_BUTTON(w), &setting->foreground_color);
+    g_signal_connect(G_OBJECT(w), "color-set", G_CALLBACK(preferences_dialog_foreground_color_set_event), terminal);
+
+    w = GTK_WIDGET(gtk_builder_get_object(builder, "allow_bold"));
+    gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(w), ! setting->disallow_bold);
+    g_signal_connect(G_OBJECT(w), "toggled", G_CALLBACK(preferences_dialog_allow_bold_toggled_event), terminal);
+
+    w = GTK_WIDGET(gtk_builder_get_object(builder, "cursor_blink"));
+    gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(w), setting->cursor_blink);
+    g_signal_connect(G_OBJECT(w), "toggled", G_CALLBACK(preferences_dialog_cursor_blink_toggled_event), terminal);
+
+    w = GTK_WIDGET(gtk_builder_get_object(builder, "cursor_style_block"));
+    gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(w), ! setting->cursor_underline);
+
+    w = GTK_WIDGET(gtk_builder_get_object(builder, "cursor_style_underline"));
+    gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(w), setting->cursor_underline);
+    g_signal_connect(G_OBJECT(w), "toggled", G_CALLBACK(preferences_dialog_cursor_underline_toggled_event), terminal);
+
+    w = GTK_WIDGET(gtk_builder_get_object(builder, "audible_bell"));
+    gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(w), setting->audible_bell);
+    g_signal_connect(G_OBJECT(w), "toggled", G_CALLBACK(preferences_dialog_audible_bell_toggled_event), terminal);
+
+    w = GTK_WIDGET(gtk_builder_get_object(builder, "tab_position"));
+    gtk_combo_box_set_active(GTK_COMBO_BOX(w), terminal_tab_get_position_id(setting->tab_position));
+    g_signal_connect(G_OBJECT(w), "changed", G_CALLBACK(preferences_dialog_tab_position_changed_event), terminal);
+
+    w = GTK_WIDGET(gtk_builder_get_object(builder, "scrollback_lines"));
+    gtk_spin_button_set_value(GTK_SPIN_BUTTON(w), setting->scrollback);
+    g_signal_connect(G_OBJECT(w), "value-changed", G_CALLBACK(preferences_dialog_scrollback_value_changed_event), terminal);
+
+    w = GTK_WIDGET(gtk_builder_get_object(builder, "hide_scroll_bar"));
+    gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(w), setting->hide_scroll_bar);
+    g_signal_connect(G_OBJECT(w), "toggled", G_CALLBACK(preferences_dialog_hide_scroll_bar_toggled_event), terminal);
+
+    w = GTK_WIDGET(gtk_builder_get_object(builder, "hide_menu_bar"));
+    gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(w), setting->hide_menu_bar);
+    g_signal_connect(G_OBJECT(w), "toggled", G_CALLBACK(preferences_dialog_hide_menu_bar_toggled_event), terminal);
+
+    w = GTK_WIDGET(gtk_builder_get_object(builder, "hide_close_button"));
+    gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(w), setting->hide_close_button);
+    g_signal_connect(G_OBJECT(w), "toggled", G_CALLBACK(preferences_dialog_hide_close_button_toggled_event), terminal);
+
+    w = GTK_WIDGET(gtk_builder_get_object(builder, "select_by_word"));
+    gtk_entry_set_text(GTK_ENTRY(w), setting->word_selection_characters);
+    g_signal_connect(G_OBJECT(w), "focus-out-event", G_CALLBACK(preferences_dialog_selection_focus_out_event), terminal);
+
+    w = GTK_WIDGET(gtk_builder_get_object(builder, "disable_f10"));
+    gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(w), setting->disable_f10);
+    g_signal_connect(G_OBJECT(w), "toggled", G_CALLBACK(preferences_dialog_disable_f10_toggled_event), terminal);
+
+    gtk_widget_show_all(dialog);
+    g_object_unref(builder);
 }
diff --git a/src/preferences.h b/src/preferences.h
index 6f86315..f1665e7 100644
--- a/src/preferences.h
+++ b/src/preferences.h
@@ -1,61 +1,27 @@
+/**
+ *      Copyright 2008 Fred Chien <cfsghost@gmail.com>
+ *      Copyright (c) 2010 LxDE Developers, see the file AUTHORS for details.
+ *
+ *      This program is free software; you can redistribute it and/or modify
+ *      it under the terms of the GNU General Public License as published by
+ *      the Free Software Foundation; either version 2 of the License, or
+ *      (at your option) any later version.
+ *
+ *      This program is distributed in the hope that it will be useful,
+ *      but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *      GNU General Public License for more details.
+ *
+ *      You should have received a copy of the GNU General Public License
+ *      along with this program; if not, write to the Free Software
+ *      Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ *      MA 02110-1301, USA.
+ */
+
 #ifndef LXTERMINAL_PREFERENCES_H
 #define LXTERMINAL_PREFERENCES_H
 
-typedef struct {
-	GtkWidget *label_box;
-	GtkWidget *icon;
-	GtkWidget *label;
-	GtkWidget *page;
-	void *childs;
-} TabWidget; 
-
-typedef struct {
-	LXTerminal *terminal;
-	GtkWidget *dialog;
-	GtkWidget *notebook;
-	GPtrArray *tab;
-} Prefer;
-
-typedef struct {
-	gchar *name;
-	gchar *icon;
-	void (*constructor)(Prefer *prefer, TabWidget *tab);
-	void (*destructor)(Prefer *prefer, TabWidget *tab);
-	void (*save)(Prefer *prefer, TabWidget *tab);
-} TabGroup;
-
-typedef struct {
-	GtkWidget *box;
-	GtkWidget *font_label;
-	GtkWidget *font_button;
-	GtkWidget *bgcolor_label;
-	GtkWidget *bgcolor_entry;
-	GtkWidget *fgcolor_label;
-	GtkWidget *fgcolor_entry;
-	GtkWidget *cursorblinks_label;
-	GtkWidget *cursorblinks_checkbox;
-} PreferStyle;
-
-typedef struct {
-	GtkWidget *box;
-	GtkWidget *tabpos_label;
-	GtkWidget *tabpos_combobox;
-	GtkWidget *scrollback_label;
-	GtkWidget *scrollback_entry;
-	GtkWidget *hidescrollbar_label;
-	GtkWidget *hidescrollbar_checkbox;
-	GtkWidget *hidemenubar_label;
-	GtkWidget *hidemenubar_checkbox;
-} PreferDisplay;
-
-typedef struct {
-	GtkWidget *box;
-	GtkWidget *selchars_label;
-	GtkWidget *selchars_entry;
-	GtkWidget *disablef10_label;
-	GtkWidget *disablef10_checkbox;
-} PreferMisc;
-
-void lxterminal_preferences_dialog(GtkAction *action, gpointer data);
+extern void terminal_preferences_dialog(GtkAction * action, LXTerminal * terminal);
+extern gint terminal_tab_get_position_id(gchar * position);
 
 #endif
diff --git a/src/setting.c b/src/setting.c
index f4a3187..7c225b9 100644
--- a/src/setting.c
+++ b/src/setting.c
@@ -1,5 +1,6 @@
-/*
+/**
  *      Copyright 2008 Fred Chien <cfsghost@gmail.com>
+ *      Copyright (c) 2010 LxDE Developers, see the file AUTHORS for details.
  *
  *      This program is free software; you can redistribute it and/or modify
  *      it under the terms of the GNU General Public License as published by
@@ -20,121 +21,106 @@
 #include <glib.h>
 #include <gtk/gtk.h>
 #include <glib/gi18n.h>
+#include <glib/gstdio.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <unistd.h>
 
 #include "setting.h"
 
-void setting_save_to_file(const char *path, const char *data)
+/* Save settings to configuration file. */
+void setting_save(Setting * setting)
 {
-	FILE *fp;
-
-	if (!g_file_test(path, G_FILE_TEST_EXISTS))
-		g_creat(path, 0700);
-
-	/* open config file */
-	fp = fopen(path, "w");
-	if (fp != NULL)
-	{
-	    fputs(data, fp);
-	    fclose(fp);
-	}
+    /* Push settings to GKeyFile. */
+    g_key_file_set_string(setting->keyfile, "general", "fontname", setting->font_name);
+    gchar * p = gdk_color_to_string(&setting->background_color);
+    if (p != NULL)
+        g_key_file_set_string(setting->keyfile, "general", "bgcolor", p);
+    g_free(p);
+    g_key_file_set_integer(setting->keyfile, "general", "bgalpha", setting->background_alpha);
+    p = gdk_color_to_string(&setting->foreground_color);
+    if (p != NULL)
+        g_key_file_set_string(setting->keyfile, "general", "fgcolor", p);
+    g_free(p);
+    g_key_file_set_boolean(setting->keyfile, "general", "disallowbold", setting->disallow_bold);
+    g_key_file_set_boolean(setting->keyfile, "general", "cursorblinks", setting->cursor_blink);
+    g_key_file_set_boolean(setting->keyfile, "general", "cursorunderline", setting->cursor_underline);
+    g_key_file_set_boolean(setting->keyfile, "general", "audiblebell", setting->audible_bell);
+    g_key_file_set_string(setting->keyfile, "general", "tabpos", setting->tab_position);
+    g_key_file_set_integer(setting->keyfile, "general", "scrollback", setting->scrollback);
+    g_key_file_set_boolean(setting->keyfile, "general", "hidescrollbar", setting->hide_scroll_bar);
+    g_key_file_set_boolean(setting->keyfile, "general", "hidemenubar", setting->hide_menu_bar);
+    g_key_file_set_boolean(setting->keyfile, "general", "hideclosebutton", setting->hide_close_button);
+    g_key_file_set_string(setting->keyfile, "general", "selchars", setting->word_selection_characters);
+    g_key_file_set_boolean(setting->keyfile, "general", "disablef10", setting->disable_f10);
+
+    /* Convert GKeyFile to text and build path to configuration file. */
+    gchar * file_data = g_key_file_to_data(setting->keyfile, NULL, NULL);
+    gchar * path = g_build_filename(g_get_user_config_dir(), "lxterminal/lxterminal.conf", NULL);
+
+    if ((file_data != NULL) && (path != NULL))
+    {
+        /* Create the file if necessary. */
+        int fd = open(path, O_CREAT | O_WRONLY, S_IRUSR | S_IWUSR);
+        if (fd < 0)
+            g_warning("Configuration file create failed: %s\n", g_strerror(errno));
+        else
+        {
+            write(fd, file_data, strlen(file_data));
+            close(fd);
+        }
+    }
+
+    /* Deallocate memory. */
+    g_free(file_data);
+    g_free(path);
 }
 
-void setting_save(Setting *setting)
+/* Load settings from configuration file. */
+Setting * load_setting_from_file(const char * filename)
 {
-	gchar *path;
-	gchar *file_data;
-
-	/* build config path */
-	path = g_build_filename(g_get_user_config_dir(), "lxterminal/lxterminal.conf", NULL);
-
-	/* push settings to GKeyFile */
-	g_key_file_set_string(setting->keyfile, "general", "fontname", setting->fontname);
-	g_key_file_set_string(setting->keyfile, "general", "selchars", setting->selchars);
-	g_key_file_set_string(setting->keyfile, "general", "bgcolor", setting->bgcolor);
-	g_key_file_set_integer(setting->keyfile, "general", "bgalpha", setting->bgalpha);
-	g_key_file_set_string(setting->keyfile, "general", "fgcolor", setting->fgcolor);
-	g_key_file_set_string(setting->keyfile, "general", "tabpos", setting->tabpos);
-	g_key_file_set_integer(setting->keyfile, "general", "scrollback", (gint)setting->scrollback);
-	g_key_file_set_boolean(setting->keyfile, "general", "disablef10", setting->disablef10);
-	g_key_file_set_boolean(setting->keyfile, "general", "hidemenubar", setting->hidemenubar);
-	g_key_file_set_boolean(setting->keyfile, "general", "hidescrollbar", setting->hidescrollbar);
-	g_key_file_set_boolean(setting->keyfile, "general", "cursorblinks", setting->cursorblinks);
-
-	/* generate config data */
-	file_data = g_key_file_to_data(setting->keyfile, NULL, NULL);
-
-	/* save to config file */
-	setting_save_to_file(path, file_data);
-
-	/* release */
-	g_free(file_data);
-}
-
-Setting *load_setting_from_file(const char *filename)
-{
-	GKeyFileFlags flags;
-	GError *error = NULL;
-	Setting *setting;
-
-	setting = (Setting *)malloc(sizeof(Setting));
-
-	/* initiate key_file */
-	setting->keyfile = g_key_file_new();
-	flags = G_KEY_FILE_KEEP_COMMENTS | G_KEY_FILE_KEEP_TRANSLATIONS;
-
-	/* Load config */
-	if (g_file_test(filename, G_FILE_TEST_EXISTS)) {
-		if (!g_key_file_load_from_file(setting->keyfile, filename, flags, &error))
-			goto setting_default;
-
-		/* general setting */
-		setting->fontname = g_key_file_get_string(setting->keyfile, "general", "fontname", NULL);
-		setting->selchars = g_key_file_get_string(setting->keyfile, "general", "selchars", NULL);
-		setting->bgcolor = g_key_file_get_string(setting->keyfile, "general", "bgcolor", NULL);
-		setting->bgalpha = g_key_file_get_integer(setting->keyfile, "general", "bgalpha", NULL);
-		setting->fgcolor = g_key_file_get_string(setting->keyfile, "general", "fgcolor", NULL);
-		setting->tabpos = g_key_file_get_string(setting->keyfile, "general", "tabpos", NULL);
-		setting->scrollback = (glong)g_key_file_get_integer(setting->keyfile, "general", "scrollback", NULL);
-		setting->disablef10 = g_key_file_get_boolean(setting->keyfile, "general", "disablef10", NULL);
-		setting->hidemenubar = g_key_file_get_boolean(setting->keyfile, "general", "hidemenubar", NULL);
-		setting->hidescrollbar = g_key_file_get_boolean(setting->keyfile, "general", "hidescrollbar", NULL);
-		setting->cursorblinks = g_key_file_get_boolean(setting->keyfile, "general", "cursorblinks", NULL);
-	}
-
-setting_default:
-
-	if (!setting->fontname)
-		setting->fontname = g_strdup("monospace 10");
-
-	if (!setting->selchars)
-		setting->selchars = g_strdup("-A-Za-z0-9,./?%&#:_");
-
-	if (!setting->bgcolor)
-		setting->bgcolor = g_strdup("#000000");
-	
-	if (!setting->bgalpha)
-		setting->bgalpha = (guint16) 0xFFFF;
-
-	if (!setting->fgcolor)
-		setting->fgcolor = g_strdup("#aaaaaa");
-
-	if (!setting->tabpos)
-		setting->tabpos = g_strdup("top");
-
-	if (!setting->scrollback)
-		setting->scrollback = (glong)1000;
-
-	if (!setting->disablef10)
-		setting->disablef10 = FALSE;
-
-	if (!setting->hidemenubar)
-		setting->hidemenubar = FALSE;
-
-	if (!setting->hidescrollbar)
-		setting->hidescrollbar = FALSE;
-
-	if (!setting->cursorblinks)
-		setting->cursorblinks = FALSE;
-
-	return setting;
+    /* Allocate structure. */
+    Setting * setting = g_new0(Setting, 1);
+
+    /* Initialize nonzero integer values to defaults. */
+    setting->background_alpha = 65535;
+    setting->foreground_color.red = setting->foreground_color.green = setting->foreground_color.blue = 0xaaaa;
+
+    /* Load configuration. */
+    setting->keyfile = g_key_file_new();
+    GError * error = NULL;
+    if ((g_file_test(filename, G_FILE_TEST_EXISTS))
+    && (g_key_file_load_from_file(setting->keyfile, filename, G_KEY_FILE_KEEP_COMMENTS | G_KEY_FILE_KEEP_TRANSLATIONS, &error)))
+    {
+        setting->font_name = g_key_file_get_string(setting->keyfile, "general", "fontname", NULL);
+        char * p = g_key_file_get_string(setting->keyfile, "general", "bgcolor", NULL);
+        if (p != NULL)
+            gdk_color_parse(p, &setting->background_color);
+        setting->background_alpha = g_key_file_get_integer(setting->keyfile, "general", "bgalpha", NULL);
+        p = g_key_file_get_string(setting->keyfile, "general", "fgcolor", NULL);
+        if (p != NULL)
+            gdk_color_parse(p, &setting->foreground_color);
+        setting->disallow_bold = g_key_file_get_boolean(setting->keyfile, "general", "disallowbold", NULL);
+        setting->cursor_blink = g_key_file_get_boolean(setting->keyfile, "general", "cursorblinks", NULL);
+        setting->cursor_underline = g_key_file_get_boolean(setting->keyfile, "general", "cursorunderline", NULL);
+        setting->audible_bell = g_key_file_get_boolean(setting->keyfile, "general", "audiblebell", NULL);
+        setting->tab_position = g_key_file_get_string(setting->keyfile, "general", "tabpos", NULL);
+        setting->scrollback = g_key_file_get_integer(setting->keyfile, "general", "scrollback", NULL);
+        setting->hide_scroll_bar = g_key_file_get_boolean(setting->keyfile, "general", "hidescrollbar", NULL);
+        setting->hide_menu_bar = g_key_file_get_boolean(setting->keyfile, "general", "hidemenubar", NULL);
+        setting->hide_close_button = g_key_file_get_boolean(setting->keyfile, "general", "hideclosebutton", NULL);
+        setting->word_selection_characters = g_key_file_get_string(setting->keyfile, "general", "selchars", NULL);
+        setting->disable_f10 = g_key_file_get_boolean(setting->keyfile, "general", "disablef10", NULL);
+    }
+
+    /* Default configuration strings. */
+    if (setting->font_name == NULL)
+        setting->font_name = g_strdup("monospace 10");
+    if (setting->tab_position == NULL)
+        setting->tab_position = g_strdup("top");
+    if (setting->word_selection_characters == NULL)
+        setting->word_selection_characters = g_strdup("-A-Za-z0-9,./?%&#:_");
+    return setting;
 }
diff --git a/src/setting.h b/src/setting.h
index 7ae28b1..f10e904 100644
--- a/src/setting.h
+++ b/src/setting.h
@@ -1,21 +1,53 @@
+/**
+ *      Copyright 2008 Fred Chien <cfsghost@gmail.com>
+ *      Copyright (c) 2010 LxDE Developers, see the file AUTHORS for details.
+ *
+ *      This program is free software; you can redistribute it and/or modify
+ *      it under the terms of the GNU General Public License as published by
+ *      the Free Software Foundation; either version 2 of the License, or
+ *      (at your option) any later version.
+ *
+ *      This program is distributed in the hope that it will be useful,
+ *      but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *      GNU General Public License for more details.
+ *
+ *      You should have received a copy of the GNU General Public License
+ *      along with this program; if not, write to the Free Software
+ *      Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ *      MA 02110-1301, USA.
+ */
+
 #ifndef LXTERMINAL_SETTING_H
 #define LXTERMINAL_SETTING_H
 
+#include <gtk/gtk.h>
+
+/* User preferences. */
 typedef struct _setting {
-	char *fontname;
-	char *selchars;
-	char *bgcolor;
-	char *fgcolor;
-	char *tabpos;
-	guint16 bgalpha;
-	glong scrollback;
-	gboolean disablef10;
-	GKeyFile *keyfile;
-	gboolean hidemenubar;
-	gboolean hidescrollbar;
-	gboolean cursorblinks;
+
+    GKeyFile * keyfile;			/* Pointer to GKeyFile containing settings */
+    char * font_name;			/* Font name */
+    GdkColor background_color;		/* Background color */
+    guint16 background_alpha;		/* Alpha value to go with background color */
+    GdkColor foreground_color;		/* Foreground color */
+    gboolean disallow_bold;		/* Disallow bolding by VTE */
+    gboolean cursor_blink;		/* True if cursor blinks */
+    gboolean cursor_underline;		/* True if underline cursor; false if block cursor */
+    gboolean audible_bell;		/* True if audible bell */
+    char * tab_position;		/* Position of tabs on main window (top, bottom, left, right) */
+    gint scrollback;			/* Scrollback buffer size in lines */
+    gboolean hide_scroll_bar;		/* True if scroll bar is NOT visible */
+    gboolean hide_menu_bar;		/* True if menu bar is NOT visible */
+    gboolean hide_close_button;		/* True if close buttons are NOT visible */
+    char * word_selection_characters;	/* Characters that act as word breaks during selection by word */
+    gboolean disable_f10;		/* True if F10 will be passed to program; false if it brings up File menu */
+
+    gboolean geometry_change;		/* True if there is a geometry change, until it has been acted on */
+
 } Setting;
 
-Setting *load_setting_from_file(const char *filename);
+extern void setting_save(Setting * setting);
+extern Setting * load_setting_from_file(const char * filename);
 
 #endif
diff --git a/src/tab.c b/src/tab.c
index 4745bcd..11f44c8 100644
--- a/src/tab.c
+++ b/src/tab.c
@@ -1,4 +1,4 @@
-/*
+/**
  *      Copyright 2008 Fred Chien <cfsghost@gmail.com>
  *
  *      This program is free software; you can redistribute it and/or modify
@@ -24,83 +24,55 @@
 #include "lxterminal.h"
 #include "tab.h"
 
-void lxterminal_tab_set_position(GtkWidget *notebook, gint tabpos)
+/* Set the "clicked" signal handler on a tab. */
+void lxterminal_tab_label_close_button_clicked(GCallback func, Term * term)
 {
-	switch(tabpos) {
-		case 0:
-			gtk_notebook_set_tab_pos(GTK_NOTEBOOK(notebook), GTK_POS_TOP);
-			break;
-		case 1:
-			gtk_notebook_set_tab_pos(GTK_NOTEBOOK(notebook), GTK_POS_BOTTOM);
-			break;
-		case 2:
-			gtk_notebook_set_tab_pos(GTK_NOTEBOOK(notebook), GTK_POS_LEFT);
-			break;
-		default:
-			gtk_notebook_set_tab_pos(GTK_NOTEBOOK(notebook), GTK_POS_RIGHT);
-	}
+    g_signal_connect(G_OBJECT(term->label->close_btn), "clicked", func, term);
 }
 
-gint lxterminal_tab_get_position_id(gchar *position)
+/* Set the label on a tab. */
+void lxterminal_tab_label_set_text(LXTab * tab, const gchar * str)
 {
-	if (strcmp(position, "top")==0)
-		return 0;
-	else if (strcmp(position, "bottom")==0)
-		return 1;
-	else if (strcmp(position, "left")==0)
-		return 2;
-	else
-		return 3;
+    gtk_label_set_text(GTK_LABEL(tab->label), str);
 }
 
-void lxterminal_tab_label_close_button_clicked(GCallback func, Term *term)
+/* Set the tooltip on a tab. */
+void lxterminal_tab_label_set_tooltip_text(LXTab * tab, const gchar * str)
 {
-	g_signal_connect(term->label->close_btn, "clicked", func, term);
+    gtk_widget_set_tooltip_text(tab->label, str);
 }
 
-void lxterminal_tab_label_set_text(LXTab *tab, const gchar *str)
+/* Create a new tab. */
+LXTab * lxterminal_tab_label_new(const gchar * str)
 {
-	gtk_label_set_text((GtkLabel *)tab->label, str);
-}
-
-void lxterminal_tab_label_set_tooltip_text(LXTab *tab, const gchar *str)
-{
-	gtk_widget_set_tooltip_text(tab->label, str);
-}
-
-LXTab *lxterminal_tab_label_new(const gchar *str)
-{
-	LXTab *tab;
-	GtkRcStyle *rcstyle;
-
-	tab = malloc(sizeof(LXTab));
-
-	tab->main = gtk_hbox_new(FALSE, 4);
-
-	/* create button */
-	tab->close_btn = gtk_button_new();
-	gtk_button_set_relief(GTK_BUTTON(tab->close_btn), GTK_RELIEF_NONE);
-	gtk_button_set_focus_on_click(GTK_BUTTON(tab->close_btn), FALSE);
-	gtk_container_add(GTK_CONTAINER(tab->close_btn), gtk_image_new_from_stock(GTK_STOCK_CLOSE, GTK_ICON_SIZE_MENU));
-
-	/* make button as small as possible */
-	rcstyle = gtk_rc_style_new();
-	rcstyle->xthickness = rcstyle->ythickness = 0;
-	gtk_widget_modify_style(tab->close_btn, rcstyle);
-	gtk_rc_style_unref(rcstyle),
-
-	/* create label for tab */
-	tab->label = gtk_label_new(str);
-	gtk_widget_set_size_request(GTK_WIDGET(tab->label), 100, -1);
-	gtk_label_set_ellipsize(GTK_LABEL(tab->label), PANGO_ELLIPSIZE_END);
-	gtk_misc_set_alignment(GTK_MISC(tab->label), 0.0, 0.5);
-	gtk_misc_set_padding(GTK_MISC(tab->label), 0, 0);
-
-	gtk_box_pack_start(GTK_BOX(tab->main), tab->label, TRUE, TRUE, 0);
-	gtk_box_pack_start(GTK_BOX(tab->main), gtk_label_new(""), TRUE, TRUE, 0);
-	gtk_box_pack_start(GTK_BOX(tab->main), tab->close_btn, FALSE, FALSE, 0);
-
-	gtk_widget_show_all(tab->main);
-
-	return tab;
+    /* Allocate LXTab structure. */
+    LXTab * tab = g_new0(LXTab, 1);
+
+    /* Create a horizontal box as the toplevel. */
+    tab->main = gtk_hbox_new(FALSE, 4);
+
+    /* Create the Close button. */
+    tab->close_btn = gtk_button_new();
+    gtk_button_set_relief(GTK_BUTTON(tab->close_btn), GTK_RELIEF_NONE);
+    gtk_button_set_focus_on_click(GTK_BUTTON(tab->close_btn), FALSE);
+    gtk_container_add(GTK_CONTAINER(tab->close_btn), gtk_image_new_from_stock(GTK_STOCK_CLOSE, GTK_ICON_SIZE_MENU));
+
+    /* Make the button as small as possible. */
+    GtkRcStyle * rcstyle = gtk_rc_style_new();
+    rcstyle->xthickness = rcstyle->ythickness = 0;
+    gtk_widget_modify_style(tab->close_btn, rcstyle);
+    gtk_rc_style_unref(rcstyle),
+
+    /* Create the label. */
+    tab->label = gtk_label_new(str);
+    gtk_widget_set_size_request(GTK_WIDGET(tab->label), 100, -1);
+    gtk_label_set_ellipsize(GTK_LABEL(tab->label), PANGO_ELLIPSIZE_END);
+    gtk_misc_set_alignment(GTK_MISC(tab->label), 0.0, 0.5);
+    gtk_misc_set_padding(GTK_MISC(tab->label), 0, 0);
+
+    /* Pack everything, show the widget and return. */
+    gtk_box_pack_start(GTK_BOX(tab->main), tab->label, TRUE, TRUE, 0);
+    gtk_box_pack_start(GTK_BOX(tab->main), tab->close_btn, FALSE, FALSE, 0);
+    gtk_widget_show_all(tab->main);
+    return tab;
 }
diff --git a/src/tab.h b/src/tab.h
index 129ab2b..d36ac90 100644
--- a/src/tab.h
+++ b/src/tab.h
@@ -1,12 +1,33 @@
+/**
+ *      Copyright 2008 Fred Chien <cfsghost@gmail.com>
+ *
+ *      This program is free software; you can redistribute it and/or modify
+ *      it under the terms of the GNU General Public License as published by
+ *      the Free Software Foundation; either version 2 of the License, or
+ *      (at your option) any later version.
+ *
+ *      This program is distributed in the hope that it will be useful,
+ *      but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *      GNU General Public License for more details.
+ *
+ *      You should have received a copy of the GNU General Public License
+ *      along with this program; if not, write to the Free Software
+ *      Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ *      MA 02110-1301, USA.
+ */
+
 #ifndef LXTERMINAL_TAB_H
 #define LXTERMINAL_TAB_H
 
 #include "lxterminal.h"
 
-void lxterminal_tab_label_close_button_clicked(GCallback func, Term *term);
-void lxterminal_tab_label_set_text(LXTab *tab, const gchar *str);
-void lxterminal_tab_label_set_tooltip_text(LXTab *tab, const gchar *str);
-LXTab *lxterminal_tab_label_new(const gchar *str);
+extern void lxterminal_tab_set_position(GtkWidget * notebook, gint tabpos);
+extern gint lxterminal_tab_get_position_id(gchar * position);
+extern void lxterminal_tab_label_close_button_clicked(GCallback func, Term * term);
+extern void lxterminal_tab_label_set_text(LXTab * tab, const gchar * str);
+extern void lxterminal_tab_label_set_tooltip_text(LXTab * tab, const gchar * str);
+extern LXTab * lxterminal_tab_label_new(const gchar * str);
 
 #endif
 
diff --git a/src/unixsocket.c b/src/unixsocket.c
index b6ca767..88f6e18 100644
--- a/src/unixsocket.c
+++ b/src/unixsocket.c
@@ -1,5 +1,6 @@
-/*
+/**
  *      Copyright 2008 Fred Chien <cfsghost@gmail.com>
+ *      Copyright (c) 2010 LxDE Developers, see the file AUTHORS for details.
  *
  *      This program is free software; you can redistribute it and/or modify
  *      it under the terms of the GNU General Public License as published by
@@ -17,7 +18,6 @@
  *      MA 02110-1301, USA.
  */
 
-#include <sys/time.h>
 #include <sys/socket.h>
 #include <sys/un.h>
 #include <unistd.h>
@@ -25,172 +25,215 @@
 #include <errno.h>
 #include <glib.h>
 #include <gtk/gtk.h>
-#include <glib/gi18n.h>
 
 #include "lxterminal.h"
 #include "unixsocket.h"
 
-static gboolean
-lxterminal_socket_read_channel(GIOChannel *gio, GIOCondition condition, gpointer lxtermwin)
-{
-	GIOStatus ret;
-	GError *err = NULL;
-	gchar *msg;
-	gsize len;
-	gsize term;
-
-	/* read messages */
-	ret = g_io_channel_read_line(gio, &msg, &len, &term, &err);
-	if (ret == G_IO_STATUS_ERROR)
-		g_error("Error reading: %s\n", err->message);
-
-	if (len > 0) {
-		gchar **argv;
-		gint argc;
-
-		msg[term] = '\0';
-
-		/* generate args */
-		g_shell_parse_argv(msg, &argc, &argv, NULL);
+static gboolean lxterminal_socket_read_channel(GIOChannel * gio, GIOCondition condition, LXTermWindow * lxtermwin);
+static gboolean lxterminal_socket_accept_client(GIOChannel * source, GIOCondition condition, LXTermWindow * lxtermwin);
 
-		/* initializing LXTerminal and create a new window */
-		lxterminal_init(lxtermwin, argc, argv, ((LXTermWindow *) lxtermwin)->setting);
-
-		/* release */
-		g_strfreev(argv);
-	}
-	g_free(msg);
-
-	if (condition & G_IO_HUP)
-		return FALSE;
-
-	return TRUE;
+/* Handler for successful read on communication socket. */
+static gboolean lxterminal_socket_read_channel(GIOChannel * gio, GIOCondition condition, LXTermWindow * lxtermwin)
+{
+    /* Read message. */
+    gchar * msg = NULL;
+    gsize len = 0;
+    gsize term = 0;
+    GError * err = NULL;
+    GIOStatus ret = g_io_channel_read_line(gio, &msg, &len, &term, &err);
+    if (ret == G_IO_STATUS_ERROR)
+        g_warning("Error reading socket: %s\n", err->message);
+
+    /* Process message. */
+    if (len > 0)
+    {
+        /* Overwrite the line termination with a NUL. */
+        msg[term] = '\0';
+
+        /* Parse arguments.
+         * Initialize a new LXTerminal and create a new window. */
+        gint argc;
+        gchar * * argv;
+        g_shell_parse_argv(msg, &argc, &argv, NULL);
+        CommandArguments arguments;
+        lxterminal_process_arguments(argc, argv, &arguments);
+        lxterminal_initialize(lxtermwin, &arguments, lxtermwin->setting);
+        g_strfreev(argv);
+    }
+    g_free(msg);
+
+    /* If there was a disconnect, discontinue read.  Otherwise, continue. */
+    if (condition & G_IO_HUP)
+        return FALSE;
+    return TRUE;
 }
 
-static gboolean
-lxterminal_socket_accept_client(GIOChannel *source, GIOCondition condition, gpointer lxtermwin)
+/* Handler for successful listen on communication socket. */
+static gboolean lxterminal_socket_accept_client(GIOChannel * source, GIOCondition condition, LXTermWindow * lxtermwin)
 {
-	if (condition & G_IO_IN) {
-		GIOChannel *gio;
-		int fd;
-		int flags;
-
-		/* new connection */
-		fd = accept(g_io_channel_unix_get_fd(source), NULL, NULL);
-		if (fd < 0)
-			g_error("Accept failed: %s\n", g_strerror(errno));
-
-		flags = fcntl(fd, F_GETFL, 0);
-		fcntl(fd, F_SETFL, flags | O_NONBLOCK);
-
-		gio = g_io_channel_unix_new(fd);
-		if (!gio)
-			g_error("Cannot create new GIOChannel!\n");
-
-		g_io_channel_set_encoding(gio, NULL, NULL);
-
-		g_io_add_watch(gio, G_IO_IN | G_IO_HUP, lxterminal_socket_read_channel, lxtermwin);
-
-		g_io_channel_unref(gio);
-	}
-
-	/* our listener socket hung up - we are dead */
-	if (condition & G_IO_HUP)
-		g_error("Server listening socket died!\n");
-
-	return TRUE;
+    if (condition & G_IO_IN)
+    {
+        /* Accept the new connection. */
+        int fd = accept(g_io_channel_unix_get_fd(source), NULL, NULL);
+        if (fd < 0)
+            g_warning("Accept failed: %s\n", g_strerror(errno));
+
+        /* Add O_NONBLOCK to the flags. */
+        fcntl(fd, F_SETFL, fcntl(fd, F_GETFL, 0) | O_NONBLOCK);
+
+        /* Create a glib I/O channel. */
+        GIOChannel * gio = g_io_channel_unix_new(fd);
+        if (gio == NULL)
+            g_warning("Cannot create new GIOChannel\n");
+        else
+        {
+            /* Set up the glib I/O channel and add it to the event loop. */
+            g_io_channel_set_encoding(gio, NULL, NULL);
+            g_io_add_watch(gio, G_IO_IN | G_IO_HUP, (GIOFunc) lxterminal_socket_read_channel, lxtermwin);
+            g_io_channel_unref(gio);
+        }
+    }
+
+    /* Our listening socket hung up - we are dead. */
+    if (condition & G_IO_HUP)
+        g_error("Server listening socket closed unexpectedly\n");
+
+    return TRUE;
 }
 
-gboolean
-lxterminal_socket_init(LXTermWindow *lxtermwin, int argc, char **argv)
+gboolean lxterminal_socket_initialize(LXTermWindow * lxtermwin, CommandArguments * arguments)
 {
-	struct sockaddr_un skaddr;
-	GIOChannel *gio;
-	int skfd;
-	gchar *socket_path;
-
-	socket_path = g_strdup_printf("/tmp/.lxterminal-socket%s-%s", gdk_get_display(), g_get_user_name());
-
-	/* create socket */
-	skfd = socket(PF_UNIX, SOCK_STREAM, 0);
-	if (skfd < 0) {
-		if (g_file_test(socket_path, G_FILE_TEST_EXISTS)) {
-			unlink(socket_path);
-		}
-
-		skfd = socket(PF_UNIX, SOCK_STREAM, 0);
-		if (skfd < 0)
-			g_error("Cannot create socket!");
-	}
-
-	/* Initiate socket */
-	bzero(&skaddr, sizeof(skaddr));
-
-	/* setting UNIX socket */
-	skaddr.sun_family = AF_UNIX;
-	snprintf(skaddr.sun_path, sizeof(skaddr.sun_path), "%s", socket_path);
-
-	/* try to connect to current LXTerminal */
-	if (connect(skfd, (struct sockaddr *)&skaddr, sizeof(skaddr)) < 0) {
-		unlink(socket_path);
-
-		/* bind to socket */
-		if (bind(skfd, (struct sockaddr *)&skaddr, sizeof(skaddr)) < 0)
-			g_error("Bind on socket failed: %s\n", g_strerror(errno));
-
-		/* listen on socket */
-		if (listen(skfd, 5) < 0)
-			g_error("Listen on socket failed: %s\n", g_strerror(errno));
-
-		/* create I/O channel */
-		gio = g_io_channel_unix_new(skfd);
-		if (!gio)
-			g_error("Cannot create new GIOChannel!\n");
-
-		/* setting encoding */
-		g_io_channel_set_encoding(gio, NULL, NULL);
-		g_io_channel_set_buffered(gio, FALSE);
-		g_io_channel_set_close_on_unref(gio, TRUE);
-
-		/* I/O channel into the main event loop */
-		if (!g_io_add_watch(gio, G_IO_IN | G_IO_HUP, lxterminal_socket_accept_client, lxtermwin))
-			g_error("Cannot add watch on GIOChannel\n");
-
-		/* channel will automatically shutdown when the watch returns FALSE */
-		g_io_channel_set_close_on_unref(gio, TRUE);
-		g_io_channel_unref(gio);
-
-		g_free(socket_path);
-		return TRUE;
-	} else {
-		int i;
-		gboolean setworkdir = FALSE;
-
-		gio = g_io_channel_unix_new(skfd);
-		g_io_channel_set_encoding(gio, NULL, NULL);
-
-		for (i=0;i<argc;i++) {
-			if (strncmp(argv[i],"--working-directory=", 20)==0) {
-				setworkdir = TRUE;
-			}
-
-			g_io_channel_write_chars(gio, g_shell_quote(*(argv+i)), -1, NULL, NULL);
-			if (i+1!=argc) {
-				g_io_channel_write_chars(gio, " ", -1, NULL, NULL);
-			} else {
-				if (!setworkdir) {
-					gchar *workdir = g_get_current_dir();
-					g_io_channel_write_chars(gio, " --working-directory=", -1, NULL, NULL);
-					g_io_channel_write_chars(gio, workdir, -1, NULL, NULL);
-					g_free(workdir);
-				}
-			}
-		}
-
-		g_io_channel_write_chars(gio, "\n", -1, NULL, NULL);
-		g_io_channel_flush(gio, NULL);
-		g_io_channel_unref(gio);
-		g_free(socket_path);
-		return FALSE;
-	}
+    /* Normally, LXTerminal uses one process to control all of its windows.
+     * The first process to start will create a Unix domain socket in /tmp.
+     * It will then bind and listen on this socket.
+     * The subsequent processes will connect to the controller that owns the Unix domain socket.
+     * They will pass their command line over the socket and exit.
+     *
+     * If for any reason both the connect and bind fail, we will fall back to having that
+     * process be standalone; it will not be either the controller or a user of the controller.
+     * This behavior was introduced in response to a problem report (2973537).
+     *
+     * This function returns TRUE if this process should keep running and FALSE if it should exit. */
+
+    /* Formulate the path for the Unix domain socket. */
+    gchar * socket_path = g_strdup_printf("/tmp/.lxterminal-socket%s-%s", gdk_get_display(), g_get_user_name());
+
+    /* Create socket. */
+    int fd = socket(PF_UNIX, SOCK_STREAM, 0);
+    if (fd < 0)
+    {
+        g_warning("Socket create failed: %s\n", g_strerror(errno));
+        g_free(socket_path);
+        return TRUE;
+    }
+
+    /* Initialize socket address for Unix domain socket. */
+    struct sockaddr_un sock_addr;
+    memset(&sock_addr, 0, sizeof(sock_addr));
+    sock_addr.sun_family = AF_UNIX;
+    snprintf(sock_addr.sun_path, sizeof(sock_addr.sun_path), "%s", socket_path);
+
+    /* Try to connect to an existing LXTerminal process. */
+    if (connect(fd, (struct sockaddr *) &sock_addr, sizeof(sock_addr)) < 0)
+    {
+        /* Connect failed.  We are the controller, unless something fails. */
+        unlink(socket_path);
+        g_free(socket_path);
+
+        /* Bind to socket. */
+        if (bind(fd, (struct sockaddr *) &sock_addr, sizeof(sock_addr)) < 0)
+        {
+            g_warning("Bind on socket failed: %s\n", g_strerror(errno));
+            close(fd);
+            return TRUE;
+        }
+
+        /* Listen on socket. */
+        if (listen(fd, 5) < 0)
+        {
+            g_warning("Listen on socket failed: %s\n", g_strerror(errno));
+            close(fd);
+            return TRUE;
+        }
+
+        /* Create a glib I/O channel. */
+        GIOChannel * gio = g_io_channel_unix_new(fd);
+        if (gio == NULL)
+        {
+            g_warning("Cannot create GIOChannel\n");
+            close(fd);
+            return TRUE;
+        }
+
+        /* Set up GIOChannel. */
+        g_io_channel_set_encoding(gio, NULL, NULL);
+        g_io_channel_set_buffered(gio, FALSE);
+        g_io_channel_set_close_on_unref(gio, TRUE);
+
+        /* Add I/O channel to the main event loop. */
+        if ( ! g_io_add_watch(gio, G_IO_IN | G_IO_HUP, (GIOFunc) lxterminal_socket_accept_client, lxtermwin))
+        {
+            g_warning("Cannot add watch on GIOChannel\n");
+            close(fd);
+            g_io_channel_unref(gio);
+            return TRUE;
+        }
+
+        /* Channel will automatically shut down when the watch returns FALSE. */
+        g_io_channel_set_close_on_unref(gio, TRUE);
+        g_io_channel_unref(gio);
+        return TRUE;
+    }
+    else
+    {
+        g_free(socket_path);
+
+        /* Create a glib I/O channel. */
+        GIOChannel * gio = g_io_channel_unix_new(fd);
+        g_io_channel_set_encoding(gio, NULL, NULL);
+
+        /* Reissue arguments to the socket.  Start with the name of the executable. */
+	g_io_channel_write_chars(gio, arguments->executable, -1, NULL, NULL);
+
+        /* --command or -e. */
+        if (arguments->command != NULL)
+        {
+            gchar * command = g_shell_quote(arguments->command);
+            gchar * command_argument = g_strdup_printf(" --command=%s", command);
+            g_io_channel_write_chars(gio, command_argument, -1, NULL, NULL);
+            g_free(command);
+            g_free(command_argument);
+        }
+
+        /* --geometry. */
+        if ((arguments->geometry_columns != 0) && (arguments->geometry_rows != 0))
+        {
+            gchar * geometry = g_strdup_printf(" --geometry=%dx%d", arguments->geometry_columns, arguments->geometry_rows);
+            g_io_channel_write_chars(gio, geometry, -1, NULL, NULL);
+            g_free(geometry);
+        }
+
+        /* -t, -T, or --title. */
+        if (arguments->title != NULL)
+        {
+            gchar * title = g_shell_quote(arguments->title);
+            gchar * title_argument = g_strdup_printf(" --title=%s", title);
+            g_io_channel_write_chars(gio, title_argument, -1, NULL, NULL);
+            g_free(title);
+            g_free(title_argument);
+        }
+
+        /* Always issue a --working-directory, either from the user's specification or the current directory. */
+        gchar * working_directory = ((arguments->working_directory != NULL) ? g_shell_quote(arguments->working_directory) : g_get_current_dir());
+        gchar * working_directory_argument = g_strdup_printf(" --working-directory=%s", working_directory);
+        g_io_channel_write_chars(gio, working_directory_argument, -1, NULL, NULL);
+        g_free(working_directory);
+        g_free(working_directory_argument);
+
+        /* Finish up the transaction on the Unix domain socket. */
+        g_io_channel_write_chars(gio, "\n", -1, NULL, NULL);
+        g_io_channel_flush(gio, NULL);
+        g_io_channel_unref(gio);
+        return FALSE;
+    }
 }
diff --git a/src/unixsocket.h b/src/unixsocket.h
index ac32e3f..db8f73c 100644
--- a/src/unixsocket.h
+++ b/src/unixsocket.h
@@ -1,7 +1,27 @@
+/**
+ *      Copyright 2008 Fred Chien <cfsghost@gmail.com>
+ *      Copyright (c) 2010 LxDE Developers, see the file AUTHORS for details.
+ *
+ *      This program is free software; you can redistribute it and/or modify
+ *      it under the terms of the GNU General Public License as published by
+ *      the Free Software Foundation; either version 2 of the License, or
+ *      (at your option) any later version.
+ *
+ *      This program is distributed in the hope that it will be useful,
+ *      but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *      GNU General Public License for more details.
+ *
+ *      You should have received a copy of the GNU General Public License
+ *      along with this program; if not, write to the Free Software
+ *      Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ *      MA 02110-1301, USA.
+ */
+
 #ifndef LXTERMINAL_UNIXSOCKET_H
 #define LXTERMINAL_UNIXSOCKET_H
 
-gboolean lxterminal_socket_init(LXTermWindow *lxtermwin, int argc, char **argv);
+extern gboolean lxterminal_socket_initialize(LXTermWindow * lxtermwin, CommandArguments * arguments);
 
 #endif
 
-- 
1.7.0.1