diff -X /usr/src/metacity/.diffignore -rudp metacity-cvs-shakeloose-04-maxconstraint-02-titlebar-03/src/core.c metacity-cvs/src/core.c
--- metacity-cvs-shakeloose-04-maxconstraint-02-titlebar-03/src/core.c	2006-10-03 20:55:42.000000000 +0200
+++ metacity-cvs/src/core.c	2006-10-03 21:08:12.000000000 +0200
@@ -300,6 +300,32 @@ meta_core_maximize (Display *xdisplay,
 }
 
 void
+meta_core_maximize_horizontal (Display *xdisplay,
+                               Window   frame_xwindow)
+{
+  MetaWindow *window = get_window (xdisplay, frame_xwindow);
+
+  if (meta_prefs_get_raise_on_click ())
+    meta_window_raise (window);
+
+  meta_window_maximize (window, 
+                        META_MAXIMIZE_HORIZONTAL);
+}
+
+void
+meta_core_maximize_vertical (Display *xdisplay,
+                             Window   frame_xwindow)
+{
+  MetaWindow *window = get_window (xdisplay, frame_xwindow);
+
+  if (meta_prefs_get_raise_on_click ())
+    meta_window_raise (window);
+
+  meta_window_maximize (window, 
+                        META_MAXIMIZE_VERTICAL);
+}
+
+void
 meta_core_toggle_maximize (Display *xdisplay,
                            Window   frame_xwindow)
 {
@@ -330,6 +356,32 @@ meta_core_unmaximize (Display *xdisplay,
 }
 
 void
+meta_core_unmaximize_horizontal (Display *xdisplay,
+                                 Window   frame_xwindow)
+{
+  MetaWindow *window = get_window (xdisplay, frame_xwindow);
+
+  if (meta_prefs_get_raise_on_click ())
+    meta_window_raise (window);
+
+  meta_window_unmaximize (window,
+                          META_MAXIMIZE_HORIZONTAL);
+}
+
+void
+meta_core_unmaximize_vertical (Display *xdisplay,
+                               Window   frame_xwindow)
+{
+  MetaWindow *window = get_window (xdisplay, frame_xwindow);
+
+  if (meta_prefs_get_raise_on_click ())
+    meta_window_raise (window);
+
+  meta_window_unmaximize (window,
+                          META_MAXIMIZE_VERTICAL);
+}
+
+void
 meta_core_delete (Display *xdisplay,
                   Window   frame_xwindow,
                   guint32  timestamp)
diff -X /usr/src/metacity/.diffignore -rudp metacity-cvs-shakeloose-04-maxconstraint-02-titlebar-03/src/core.h metacity-cvs/src/core.h
--- metacity-cvs-shakeloose-04-maxconstraint-02-titlebar-03/src/core.h	2006-10-03 20:55:42.000000000 +0200
+++ metacity-cvs/src/core.h	2006-10-03 21:09:28.000000000 +0200
@@ -91,8 +91,16 @@ void meta_core_toggle_maximize  (Display
                                  Window   frame_xwindow);
 void meta_core_unmaximize       (Display *xdisplay,
                                  Window   frame_xwindow);
+void meta_core_unmaximize_horizontal (Display *xdisplay,
+                                      Window   frame_xwindow);
+void meta_core_unmaximize_vertical (Display *xdisplay,
+                                    Window   frame_xwindow);
 void meta_core_maximize         (Display *xdisplay,
                                  Window   frame_xwindow);
+void meta_core_maximize_horizontal (Display *xdisplay,
+                                    Window   frame_xwindow);
+void meta_core_maximize_vertical (Display *xdisplay,
+                                  Window   frame_xwindow);
 void meta_core_delete           (Display *xdisplay,
                                  Window   frame_xwindow,
                                  guint32  timestamp);
diff -X /usr/src/metacity/.diffignore -rudp metacity-cvs-shakeloose-04-maxconstraint-02-titlebar-03/src/frame.c metacity-cvs/src/frame.c
--- metacity-cvs-shakeloose-04-maxconstraint-02-titlebar-03/src/frame.c	2006-10-03 14:18:27.000000000 +0200
+++ metacity-cvs/src/frame.c	2006-10-04 05:21:47.000000000 +0200
@@ -267,10 +267,14 @@ meta_frame_get_flags (MetaFrame *frame)
   if (frame->window->on_all_workspaces)
     flags |= META_FRAME_STUCK;
 
-  /* FIXME: Should we have some kind of UI for windows that are just vertically
-   * maximized or just horizontally maximized?
+  /* Use the maximized icon in the maximize button, even for
+   * unidirectionally maximized windows. Setting this flag
+   * also causes a subsequential left-click on the maximize
+   * button to unmaximize again (and not fully maximize).
+   * That is a feature - not a bug.
    */
-  if (META_WINDOW_MAXIMIZED (frame->window))
+  if (frame->window->maximized_horizontally ||
+      frame->window->maximized_vertically)
     flags |= META_FRAME_MAXIMIZED;
 
   if (frame->window->fullscreen)
diff -X /usr/src/metacity/.diffignore -rudp metacity-cvs-shakeloose-04-maxconstraint-02-titlebar-03/src/frames.c metacity-cvs/src/frames.c
--- metacity-cvs-shakeloose-04-maxconstraint-02-titlebar-03/src/frames.c	2006-10-03 20:55:42.000000000 +0200
+++ metacity-cvs/src/frames.c	2006-10-03 21:21:22.000000000 +0200
@@ -1303,12 +1303,13 @@ meta_frames_button_press_event (GtkWidge
       META_GRAB_OP_NONE)
     return FALSE; /* already up to something */  
 
-  if (event->button == 1 &&
-      (control == META_FRAME_CONTROL_MAXIMIZE ||
-       control == META_FRAME_CONTROL_UNMAXIMIZE ||
-       control == META_FRAME_CONTROL_MINIMIZE ||
-       control == META_FRAME_CONTROL_DELETE ||
-       control == META_FRAME_CONTROL_MENU))
+  if ((event->button == 1 &&
+       (control == META_FRAME_CONTROL_MINIMIZE ||
+        control == META_FRAME_CONTROL_DELETE ||
+        control == META_FRAME_CONTROL_MENU)) ||
+      (event->button >= 1 && event->button <= 3 &&
+       (control == META_FRAME_CONTROL_MAXIMIZE ||
+        control == META_FRAME_CONTROL_UNMAXIMIZE)))
     {
       MetaGrabOp op = META_GRAB_OP_NONE;
 
@@ -1547,15 +1548,29 @@ meta_frames_button_release_event    (Gtk
 
         case META_GRAB_OP_CLICKING_MAXIMIZE:
           if (control == META_FRAME_CONTROL_MAXIMIZE)
-            meta_core_maximize (gdk_display, frame->xwindow);
+            {
+              if (event->button == 3)
+                meta_core_maximize_horizontal (gdk_display, frame->xwindow);
+              else if (event->button == 2)
+                meta_core_maximize_vertical (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 == 3)
+                meta_core_unmaximize_horizontal (gdk_display, frame->xwindow);
+              else if (event->button == 2)
+                meta_core_unmaximize_vertical (gdk_display, frame->xwindow);
+              else
+                meta_core_unmaximize (gdk_display, frame->xwindow);
+            }
+
           meta_core_end_grab_op (gdk_display, event->time);
           break;
           
