diff --git a/src/client.c b/src/client.c
index a214b00a3db7e003f9d6e88f98836be8fcdbb58c..2f9d312a18bc70a33e2092d3070465aa6dbd560e 100644
--- a/src/client.c
+++ b/src/client.c
@@ -2726,28 +2726,82 @@ clientRemoveMaximizeFlag (Client * c)
     clientSetNetState (c);
 }
 
-void
-clientToggleMaximized (Client * c, int mode, gboolean restore_position)
+static void
+clientNewMaxState (Client * c, XWindowChanges *wc, int mode, gboolean restore_position)
+{
+    /*
+     * We treat differently full maximization from vertical or horizontal maximization.
+     * This is for usability concerns, otherwise maximization acts like a toggle, 
+     * switching from horizontal to vertical instead of switching to full maximization.
+     * 
+     * The full size is not computed yet, as full maximization removes borders
+     * while either horizontal or vertical maximization still shows decorations...
+     */
+
+    if (!FLAG_TEST (c->flags, CLIENT_FLAG_MAXIMIZED) && (restore_position))
+    {
+        c->old_x = c->x;
+        c->old_y = c->y;
+        c->old_width = c->width;
+        c->old_height = c->height;
+    }
+
+    if ((mode & WIN_STATE_MAXIMIZED) == WIN_STATE_MAXIMIZED)
+    {
+        if (!FLAG_TEST (c->flags, CLIENT_FLAG_MAXIMIZED))
+        {
+            c->win_state |= WIN_STATE_MAXIMIZED;
+            FLAG_SET (c->flags, CLIENT_FLAG_MAXIMIZED);
+            return;
+        }
+    }
+
+    if (mode & WIN_STATE_MAXIMIZED_HORIZ)
+    {
+        if (!FLAG_TEST (c->flags, CLIENT_FLAG_MAXIMIZED_HORIZ))
+        {
+            c->win_state |= WIN_STATE_MAXIMIZED_HORIZ;
+            FLAG_SET (c->flags, CLIENT_FLAG_MAXIMIZED_HORIZ);
+            return;
+        }
+    }
+
+    if (mode & WIN_STATE_MAXIMIZED_VERT)
+    {
+        if (!FLAG_TEST (c->flags, CLIENT_FLAG_MAXIMIZED_VERT))
+        {
+            c->win_state |= WIN_STATE_MAXIMIZED_VERT;
+            FLAG_SET (c->flags, CLIENT_FLAG_MAXIMIZED_VERT);
+            return;
+        }
+    }
+
+    c->win_state &= ~WIN_STATE_MAXIMIZED;
+    FLAG_UNSET (c->flags, CLIENT_FLAG_MAXIMIZED);
+    wc->x = c->old_x;
+    wc->y = c->old_y;
+    wc->width = c->old_width;
+    wc->height = c->old_height;
+}
+
+static void 
+clientNewMaxSize (Client * c, XWindowChanges *wc)
 {
     ScreenInfo *screen_info;
     GdkRectangle rect;
-    XWindowChanges wc;
     int cx, cy, full_x, full_y, full_w, full_h;
+    int tmp_x, tmp_y, tmp_w, tmp_h;
     gint monitor_nbr;
 
-    g_return_if_fail (c != NULL);
-    TRACE ("entering clientToggleMaximized");
-    TRACE ("maximzing/unmaximizing client \"%s\" (0x%lx)", c->name, c->window);
+    tmp_x = frameX (c);
+    tmp_y = frameY (c); 
+    tmp_h = frameHeight (c);
+    tmp_w = frameWidth (c);
 
-    screen_info = c->screen_info;
+    cx = tmp_x + (tmp_w / 2);
+    cy = tmp_y + (tmp_h / 2);
 
-    if (!CLIENT_CAN_MAXIMIZE_WINDOW (c))
-    {
-        return;
-    }
-
-    cx = frameX (c) + (frameWidth (c) / 2);
-    cy = frameY (c) + (frameHeight (c) / 2);
+    screen_info = c->screen_info;
 
     monitor_nbr = find_monitor_at_point (screen_info->gscr, cx, cy);
     gdk_screen_get_monitor_geometry (screen_info->gscr, monitor_nbr, &rect);
@@ -2759,102 +2813,65 @@ clientToggleMaximized (Client * c, int mode, gboolean restore_position)
     full_h = MIN (screen_info->height - screen_info->params->xfwm_margins[BOTTOM],
                   rect.y + rect.height) - full_y;
 
-    wc.x = c->x;
-    wc.y = c->y;
-    wc.width = c->width;
-    wc.height = c->height;
-
-    if ((mode & WIN_STATE_MAXIMIZED_HORIZ) && (mode & WIN_STATE_MAXIMIZED_VERT))
+    if (FLAG_TEST_ALL (c->flags, CLIENT_FLAG_MAXIMIZED))
     {
-        if (!FLAG_TEST (c->flags, CLIENT_FLAG_MAXIMIZED))
-        {
-            if (restore_position)
-            {
-                c->old_x = c->x;
-                c->old_y = c->y;
-                c->old_width = c->width;
-                c->old_height = c->height;
-            }
-            c->win_state |= (WIN_STATE_MAXIMIZED_HORIZ | WIN_STATE_MAXIMIZED_VERT);
-            FLAG_SET (c->flags, CLIENT_FLAG_MAXIMIZED);
-            /* Adjust size to the largest size available, not covering struts */
-            clientMaxSpace (screen_info, &full_x, &full_y, &full_w, &full_h);
-            wc.x = full_x + frameLeft (c);
-            wc.y = full_y + frameTop (c);
-            wc.width = full_w - frameLeft (c) - frameRight (c);
-            wc.height = full_h - frameTop (c) - frameBottom (c);
-        }
-        else
-        {
-            c->win_state &= ~(WIN_STATE_MAXIMIZED_HORIZ | WIN_STATE_MAXIMIZED_VERT);
-            FLAG_UNSET (c->flags, CLIENT_FLAG_MAXIMIZED);
-            wc.x = c->old_x;
-            wc.y = c->old_y;
-            wc.width = c->old_width;
-            wc.height = c->old_height;
-        }
+        /* Adjust size to the largest size available, not covering struts */
+        clientMaxSpace (screen_info, &full_x, &full_y, &full_w, &full_h);
+        wc->x = full_x + frameLeft (c);
+        wc->y = full_y + frameTop (c);
+        wc->width = full_w - frameLeft (c) - frameRight (c);
+        wc->height = full_h - frameTop (c) - frameBottom (c);
+
+        return;
     }
-    else if (mode & WIN_STATE_MAXIMIZED_HORIZ)
+
+    if (FLAG_TEST (c->flags, CLIENT_FLAG_MAXIMIZED_HORIZ))
     {
-        if (!FLAG_TEST (c->flags, CLIENT_FLAG_MAXIMIZED_HORIZ))
-        {
-            int tmp_y, tmp_h;
+        /* Adjust size to the widest size available, for the current vertical position/height */
+        clientMaxSpace (screen_info, &full_x, &tmp_y, &full_w, &tmp_h);
+        wc->x = full_x + frameLeft (c);
+        wc->width = full_w - frameLeft (c) - frameRight (c);
 
-            if (restore_position)
-            {
-                c->old_x = c->x;
-                c->old_width = c->width;
-            }
-            c->win_state |= WIN_STATE_MAXIMIZED_HORIZ;
-            FLAG_SET (c->flags, CLIENT_FLAG_MAXIMIZED_HORIZ);
-            tmp_y = frameY (c); 
-            tmp_h = frameHeight (c);
-            /* Adjust size to the widest size available, for the current vertical position/height */
-            clientMaxSpace (screen_info, &full_x, &tmp_y, &full_w, &tmp_h);
-            wc.x = full_x + frameLeft (c);
-            wc.width = full_w - frameLeft (c) - frameRight (c);
-        }
-        else
-        {
-            c->win_state &= ~WIN_STATE_MAXIMIZED_HORIZ;
-            FLAG_UNSET (c->flags, CLIENT_FLAG_MAXIMIZED_HORIZ);
-            wc.x = c->old_x;
-            wc.width = c->old_width;
-        }
+        return;
     }
-    else if (mode & WIN_STATE_MAXIMIZED_VERT)
+
+    if (FLAG_TEST (c->flags, CLIENT_FLAG_MAXIMIZED_VERT))
     {
-        if (!FLAG_TEST (c->flags, CLIENT_FLAG_MAXIMIZED_VERT))
-        {
-            int tmp_x, tmp_w;
+        /* Adjust size to the tallest size available, for the current horizontal position/width */
+        clientMaxSpace (screen_info, &tmp_x, &full_y, &tmp_w, &full_h);
+        wc->y = full_y + frameTop (c);
+        wc->height = full_h - frameTop (c) - frameBottom (c);
 
-            if (restore_position)
-            {
-                c->old_y = c->y;
-                c->old_height = c->height;
-            }
-            c->win_state |= WIN_STATE_MAXIMIZED_VERT;
-            FLAG_SET (c->flags, CLIENT_FLAG_MAXIMIZED_VERT);
-            tmp_x = frameX (c);
-            tmp_w = frameWidth (c);
-            /* Adjust size to the tallest size available, for the current horizontal position/width */
-            clientMaxSpace (screen_info, &tmp_x, &full_y, &tmp_w, &full_h);
-            wc.y = full_y + frameTop (c);
-            wc.height = full_h - frameTop (c) - frameBottom (c);
-        }
-        else
-        {
-            c->win_state &= ~WIN_STATE_MAXIMIZED_VERT;
-            FLAG_UNSET (c->flags, CLIENT_FLAG_MAXIMIZED_VERT);
-            wc.y = c->old_y;
-            wc.height = c->old_height;
-        }
+        return;
+    }
+}
+
+void
+clientToggleMaximized (Client * c, int mode, gboolean restore_position)
+{
+    XWindowChanges wc;
+
+    g_return_if_fail (c != NULL);
+    TRACE ("entering clientToggleMaximized");
+    TRACE ("maximzing/unmaximizing client \"%s\" (0x%lx)", c->name, c->window);
+
+    if (!CLIENT_CAN_MAXIMIZE_WINDOW (c))
+    {
+        return;
     }
 
-    c->x = wc.x;
-    c->y = wc.y;
-    c->height = wc.height;
-    c->width = wc.width;
+    wc.x = c->x;
+    wc.y = c->y;
+    wc.width = c->width;
+    wc.height = c->height;
+
+    /* 1) Compute the new state */
+    clientNewMaxState (c, &wc, mode, restore_position);
+       
+    /* 2) Compute the new size, based on the state */
+    clientNewMaxSize (c, &wc);
+
+    /* 3) Update window fields */
     clientSetNetState (c);
 
     if (FLAG_TEST (c->xfwm_flags, XFWM_FLAG_MANAGED))
@@ -2867,11 +2884,18 @@ clientToggleMaximized (Client * c, int mode, gboolean restore_position)
                grab focus in focus follow mouse mode. Grab the pointer to
                avoid these effects
              */
-            myScreenGrabPointer (screen_info, EnterWindowMask, None, CurrentTime);
+            myScreenGrabPointer (c->screen_info, EnterWindowMask, None, CurrentTime);
             clientConfigure (c, &wc, CWWidth | CWHeight | CWX | CWY, CFG_NOTIFY);
-            myScreenUngrabPointer (screen_info, CurrentTime);
+            myScreenUngrabPointer (c->screen_info, CurrentTime);
         }
+        return;
     }
+
+    /* Window is not managed yet, just update its fields */
+    c->x = wc.x;
+    c->y = wc.y;
+    c->height = wc.height;
+    c->width = wc.width;
 }
 
 void
@@ -4630,19 +4654,17 @@ clientButtonPress (Client * c, Window w, XButtonEvent * bev)
             case MAXIMIZE_BUTTON:
                 if (CLIENT_CAN_MAXIMIZE_WINDOW (c))
                 {
-                    unsigned long mode = c->win_state & WIN_STATE_MAXIMIZED;
-
                     if (bev->button == Button1)
                     {
-                        clientToggleMaximized (c, mode ? mode : WIN_STATE_MAXIMIZED, TRUE);
+                        clientToggleMaximized (c, WIN_STATE_MAXIMIZED, TRUE);
                     }
                     else if (bev->button == Button2)
                     {
-                        clientToggleMaximized (c, mode ? mode : WIN_STATE_MAXIMIZED_VERT, TRUE);
+                        clientToggleMaximized (c, WIN_STATE_MAXIMIZED_VERT, TRUE);
                     }
                     else if (bev->button == Button3)
                     {
-                        clientToggleMaximized (c, mode ? mode : WIN_STATE_MAXIMIZED_HORIZ, TRUE);
+                        clientToggleMaximized (c, WIN_STATE_MAXIMIZED_HORIZ, TRUE);
                     }
                 }
                 break;
diff --git a/src/events.c b/src/events.c
index b64fe396bf53d056966830f281e41b5202c790f1..4b8f5b86d2f7292893dc0ec39d54a7a757642318 100644
--- a/src/events.c
+++ b/src/events.c
@@ -353,20 +353,17 @@ getKeyPressed (ScreenInfo *screen_info, XKeyEvent * ev)
 static void
 handleKeyPress (DisplayInfo *display_info, XKeyEvent * ev)
 {
-    unsigned long mode;
     ScreenInfo *screen_info;
     Client *c;
     int key;
 
     TRACE ("entering handleKeyEvent");
 
-    mode = 0;
     c = clientGetFocus ();
     if (c)
     {
         screen_info = c->screen_info;
         key = getKeyPressed (screen_info, ev);
-        mode = c->win_state & WIN_STATE_MAXIMIZED;
 
         switch (key)
         {
@@ -398,13 +395,13 @@ handleKeyPress (DisplayInfo *display_info, XKeyEvent * ev)
                 }
                 break;
             case KEY_MAXIMIZE_WINDOW:
-                clientToggleMaximized (c, mode ? mode : WIN_STATE_MAXIMIZED, TRUE);
+                clientToggleMaximized (c, WIN_STATE_MAXIMIZED, TRUE);
                 break;
             case KEY_MAXIMIZE_VERT:
-                clientToggleMaximized (c, mode ? mode : WIN_STATE_MAXIMIZED_VERT, TRUE);
+                clientToggleMaximized (c, WIN_STATE_MAXIMIZED_VERT, TRUE);
                 break;
             case KEY_MAXIMIZE_HORIZ:
-                clientToggleMaximized (c, mode ? mode : WIN_STATE_MAXIMIZED_HORIZ, TRUE);
+                clientToggleMaximized (c, WIN_STATE_MAXIMIZED_HORIZ, TRUE);
                 break;
             case KEY_SHADE_WINDOW:
                 clientToggleShaded (c);
@@ -591,7 +588,6 @@ edgeButton (Client * c, int part, XButtonEvent * ev)
 static void
 button1Action (Client * c, XButtonEvent * ev)
 {
-    unsigned long mode;
     ScreenInfo *screen_info;
     DisplayInfo *display_info;
     XEvent copy_event;
@@ -602,7 +598,6 @@ button1Action (Client * c, XButtonEvent * ev)
 
     screen_info = c->screen_info;
     display_info = screen_info->display_info;
-    mode = c->win_state & WIN_STATE_MAXIMIZED;
 
     if (!(c->type & WINDOW_TYPE_DONT_FOCUS))
     {
@@ -623,7 +618,7 @@ button1Action (Client * c, XButtonEvent * ev)
         switch (screen_info->params->double_click_action)
         {
             case ACTION_MAXIMIZE:
-                clientToggleMaximized (c, mode ? mode : WIN_STATE_MAXIMIZED, TRUE);
+                clientToggleMaximized (c, WIN_STATE_MAXIMIZED, TRUE);
                 break;
             case ACTION_SHADE:
                 clientToggleShaded (c);
@@ -2247,7 +2242,6 @@ xfwm4_event_filter (XEvent * xevent, gpointer data)
 static void
 menu_callback (Menu * menu, MenuOp op, Window xid, gpointer menu_data, gpointer item_data)
 {
-    unsigned long mode;
     Client *c;
 
     TRACE ("entering menu_callback");
@@ -2267,7 +2261,6 @@ menu_callback (Menu * menu, MenuOp op, Window xid, gpointer menu_data, gpointer
     if (c)
     {
         c->button_pressed[MENU_BUTTON] = FALSE;
-        mode = c->win_state & WIN_STATE_MAXIMIZED;
 
         switch (op)
         {
@@ -2278,7 +2271,7 @@ menu_callback (Menu * menu, MenuOp op, Window xid, gpointer menu_data, gpointer
             case MENU_OP_UNMAXIMIZE:
                 if (CLIENT_CAN_MAXIMIZE_WINDOW (c))
                 {
-                    clientToggleMaximized (c, mode ? mode : WIN_STATE_MAXIMIZED, TRUE);
+                    clientToggleMaximized (c, WIN_STATE_MAXIMIZED, TRUE);
                 }
                 break;
             case MENU_OP_MINIMIZE:
diff --git a/src/hints.h b/src/hints.h
index f39645b421b2ff935a130229068ce0022c888d0a..bdb10bc15c5d90d754424b26e8c8e5bc724f9253 100644
--- a/src/hints.h
+++ b/src/hints.h
@@ -70,7 +70,8 @@
 #define WIN_STATE_STICKY                        (1L<<0)
 #define WIN_STATE_MAXIMIZED_VERT                (1L<<2)
 #define WIN_STATE_MAXIMIZED_HORIZ               (1L<<3)
-#define WIN_STATE_MAXIMIZED                     ((1L<<2)|(1L<<3))
+#define WIN_STATE_MAXIMIZED                     (WIN_STATE_MAXIMIZED_VERT | \
+                                                 WIN_STATE_MAXIMIZED_HORIZ)
 #define WIN_STATE_SHADED                        (1L<<5)
 
 #define WIN_HINTS_SKIP_FOCUS                    (1L<<0)