Index: src/prefs.c
===================================================================
--- src/prefs.c	(revision 3281)
+++ src/prefs.c	(working copy)
@@ -77,6 +77,7 @@
 #define KEY_CURSOR_THEME "/desktop/gnome/peripherals/mouse/cursor_theme"
 #define KEY_CURSOR_SIZE "/desktop/gnome/peripherals/mouse/cursor_size"
 #define KEY_COMPOSITING_MANAGER "/apps/metacity/general/compositing_manager"
+#define KEY_ONEWAY_MAXIMIZE "/apps/metacity/general/oneway_maximize"
 
 #ifdef HAVE_GCONF
 static GConfClient *default_client = NULL;
@@ -107,6 +108,7 @@
 static char *cursor_theme = NULL;
 static int   cursor_size = 24;
 static gboolean compositing_manager = FALSE;
+static gboolean oneway_maximize = FALSE;
 
 static MetaVisualBellType visual_bell_type = META_VISUAL_BELL_FULLSCREEN_FLASH;
 static MetaButtonLayout button_layout;
@@ -156,6 +158,7 @@
 static gboolean update_cursor_theme       (const char *value);
 static gboolean update_cursor_size        (int size);
 static gboolean update_compositing_manager (gboolean	value);
+static gboolean update_oneway_maximize    (gboolean	value);
 
 static void change_notify (GConfClient    *client,
                            guint           cnxn_id,
@@ -482,6 +485,10 @@
   if (get_bool (KEY_COMPOSITING_MANAGER, &bool_val))
     update_compositing_manager (bool_val);
   
+  bool_val = oneway_maximize;
+  if (get_bool (KEY_ONEWAY_MAXIMIZE, &bool_val))
+    update_oneway_maximize (bool_val);
+  
   str_val = gconf_client_get_string (default_client, KEY_VISUAL_BELL_TYPE,
                                      &err);
   cleanup_error (&err);
@@ -1062,6 +1069,22 @@
       if (update_compositing_manager (b))
         queue_changed (META_PREF_COMPOSITING_MANAGER);
     }
+  else if (strcmp (key, KEY_ONEWAY_MAXIMIZE) == 0)
+    {
+      gboolean b;
+
+      if (value && value->type != GCONF_VALUE_BOOL)
+        {
+          meta_warning (_("GConf key \"%s\" is set to an invalid type\n"),
+                       KEY_ONEWAY_MAXIMIZE);
+          goto out;
+        }
+
+      b = value ? gconf_value_get_bool (value) : oneway_maximize;
+
+      if (update_oneway_maximize (b))
+        queue_changed (META_PREF_ONEWAY_MAXIMIZE);
+    }
   else
     {
       meta_topic (META_DEBUG_PREFS, "Key %s doesn't mean anything to Metacity\n",
@@ -1847,6 +1870,9 @@
 
     case META_PREF_COMPOSITING_MANAGER:
       return "COMPOSITING_MANAGER";
+
+    case META_PREF_ONEWAY_MAXIMIZE:
+      return "ONEWAY_MAXIMIZE";
     }
 
   return "(unknown)";
@@ -3034,6 +3060,16 @@
   
   return old != compositing_manager;
 }
+
+static gboolean
+update_oneway_maximize (gboolean value)
+{
+  gboolean old = oneway_maximize;
+
+  oneway_maximize = value;
+  
+  return old != oneway_maximize;
+}
 #endif
 
 gboolean
@@ -3042,6 +3078,12 @@
   return compositing_manager;
 }
 
+gboolean
+meta_prefs_get_oneway_maximize (void)
+{
+  return oneway_maximize;
+}
+
 static void
 init_button_layout(void)
 {
Index: src/prefs.h
===================================================================
--- src/prefs.h	(revision 3281)
+++ src/prefs.h	(working copy)
@@ -58,7 +58,8 @@
   META_PREF_GNOME_ACCESSIBILITY,
   META_PREF_CURSOR_THEME,
   META_PREF_CURSOR_SIZE,
-  META_PREF_COMPOSITING_MANAGER
+  META_PREF_COMPOSITING_MANAGER,
+  META_PREF_ONEWAY_MAXIMIZE
 } MetaPreference;
 
 typedef void (* MetaPrefsChangedFunc) (MetaPreference pref,
@@ -110,6 +111,7 @@
 const char* meta_prefs_get_cursor_theme      (void);
 int         meta_prefs_get_cursor_size       (void);
 gboolean    meta_prefs_get_compositing_manager (void);
+gboolean    meta_prefs_get_oneway_maximize   (void);
 
 /* Screen bindings */
 #define META_KEYBINDING_WORKSPACE_1              "switch_to_workspace_1"
Index: src/frames.c
===================================================================
--- src/frames.c	(revision 3281)
+++ src/frames.c	(working copy)
@@ -1370,7 +1370,7 @@
       META_GRAB_OP_NONE)
     return FALSE; /* already up to something */  
 
-  if (event->button == 1 &&
+  if ((event->button == 1 &&
       (control == META_FRAME_CONTROL_MAXIMIZE ||
        control == META_FRAME_CONTROL_UNMAXIMIZE ||
        control == META_FRAME_CONTROL_MINIMIZE ||
@@ -1381,7 +1381,11 @@
        control == META_FRAME_CONTROL_UNABOVE ||
        control == META_FRAME_CONTROL_STICK ||
        control == META_FRAME_CONTROL_UNSTICK ||
-       control == META_FRAME_CONTROL_MENU))
+       control == META_FRAME_CONTROL_MENU)) ||
+     (meta_prefs_get_oneway_maximize() &&
+      (event->button == 2 || event->button == 3) &&
+      (control == META_FRAME_CONTROL_MAXIMIZE ||
+       control == META_FRAME_CONTROL_UNMAXIMIZE)))
     {
       MetaGrabOp op = META_GRAB_OP_NONE;
 
@@ -1629,6 +1633,7 @@
       
       switch (op)
         {
+
         case META_GRAB_OP_CLICKING_MINIMIZE:
           if (control == META_FRAME_CONTROL_MINIMIZE)
             meta_core_minimize (gdk_display, frame->xwindow);
@@ -1643,15 +1648,28 @@
             meta_core_user_focus (gdk_display,
                             frame->xwindow,
                             event->time);      
-            meta_core_maximize (gdk_display, frame->xwindow);
+
+            if (event->button == 2 && meta_prefs_get_oneway_maximize())
+              meta_core_toggle_maximize_vert (gdk_display, frame->xwindow);
+            else if (event->button == 3 && meta_prefs_get_oneway_maximize())
+              meta_core_toggle_maximize_horiz (gdk_display, frame->xwindow);
+            else
+              meta_core_maximize (gdk_display, frame->xwindow);
           }
           meta_core_end_grab_op (gdk_display, event->time);
           break;
 
         case META_GRAB_OP_CLICKING_UNMAXIMIZE:
           if (control == META_FRAME_CONTROL_UNMAXIMIZE)
-            meta_core_unmaximize (gdk_display, frame->xwindow);
-          
+            {
+              if (event->button == 2 && meta_prefs_get_oneway_maximize())
+                meta_core_toggle_maximize_vert (gdk_display, frame->xwindow);
+              else if (event->button == 3 && meta_prefs_get_oneway_maximize())
+                meta_core_toggle_maximize_horiz (gdk_display, frame->xwindow);
+              else
+                meta_core_unmaximize (gdk_display, frame->xwindow);
+            }
+
           meta_core_end_grab_op (gdk_display, event->time);
           break;
           
Index: src/core.c
===================================================================
--- src/core.c	(revision 3281)
+++ src/core.c	(working copy)
@@ -345,6 +345,34 @@
                           META_MAXIMIZE_HORIZONTAL | META_MAXIMIZE_VERTICAL);
 }
 
+void meta_core_toggle_maximize_vert (Display *xdisplay,
+                                     Window   frame_xwindow)
+{
+  MetaWindow *window = get_window (xdisplay, frame_xwindow);
+
+  if (meta_prefs_get_raise_on_click ())
+    meta_window_raise (window);
+
+  if (window->maximized_vertically)
+    meta_window_unmaximize (window, META_MAXIMIZE_VERTICAL);
+  else
+    meta_window_maximize (window, META_MAXIMIZE_VERTICAL);
+}
+
+void meta_core_toggle_maximize_horiz (Display *xdisplay,
+                                      Window   frame_xwindow)
+{
+  MetaWindow *window = get_window (xdisplay, frame_xwindow);
+
+  if (meta_prefs_get_raise_on_click ())
+    meta_window_raise (window);
+
+  if (window->maximized_horizontally)
+    meta_window_unmaximize (window, META_MAXIMIZE_HORIZONTAL);
+  else
+    meta_window_maximize (window, META_MAXIMIZE_HORIZONTAL);
+}
+
 void
 meta_core_unmaximize (Display *xdisplay,
                       Window   frame_xwindow)
Index: src/core.h
===================================================================
--- src/core.h	(revision 3281)
+++ src/core.h	(working copy)
@@ -120,6 +120,10 @@
                                  Window   frame_xwindow);
 void meta_core_toggle_maximize  (Display *xdisplay,
                                  Window   frame_xwindow);
+void meta_core_toggle_maximize_vert  (Display *xdisplay,
+                                      Window   frame_xwindow);
+void meta_core_toggle_maximize_horiz (Display *xdisplay,
+                                      Window   frame_xwindow);
 void meta_core_unmaximize       (Display *xdisplay,
                                  Window   frame_xwindow);
 void meta_core_maximize         (Display *xdisplay,
Index: src/metacity.schemas.in
===================================================================
--- src/metacity.schemas.in	(revision 3281)
+++ src/metacity.schemas.in	(working copy)
@@ -339,6 +339,21 @@
     </schema>
 
     <schema>
+      <key>/schemas/apps/metacity/general/oneway_maximize</key>
+      <applyto>/apps/metacity/general/oneway_maximize</applyto>
+      <owner>metacity</owner>
+      <type>bool</type>
+      <default>false</default>
+      <locale name="C">
+        <short>One Way Maximize on Click</short>
+        <long>
+          Determines whether mouse buttons 2 and 3 maximize only vertically or
+		  horizontally respectively.
+        </long>
+      </locale>
+    </schema>
+
+    <schema>
       <key>/schemas/apps/metacity/workspace_names/name</key>
       <applyto>/apps/metacity/workspace_names/name_1</applyto>
       <applyto>/apps/metacity/workspace_names/name_2</applyto>
