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)