diff --git a/ChangeLog b/ChangeLog index ca8e08b6..7eef9a06 100644 --- a/ChangeLog +++ b/ChangeLog @@ -88,7 +88,7 @@ Changes since version 0.80.2: - Xinerama support for Solaris - Added global menu support (see NEWS) - Fixed sloppy focus bug -- Made maximizing behaves differently with keyboard/mouse for xinerama +- Made maximize behave differently with keyboard/mouse for xinerama (Peter Zijlstra ) - A few leftover xinerama fixes (Peter Zijlstra ) - Extended the 'strut' to multiple heads @@ -102,6 +102,10 @@ Changes since version 0.80.2: - Fixed aspect of window list menu (window name was too close to workspace indicator) - Fixed menu panel in WPrefs.app. Explanatory text did not fit into the label +- Implemented a better logic to preserve the window's old geometry when + maximizing to support succesive maximizations in different directions + without the need to do an intermediary un-maximize step (eliminates flicker) +- Made keyboard/mouse maximization behavior consinstent relative to each other Changes since version 0.80.1: diff --git a/src/actions.c b/src/actions.c index de8faaa9..5bd83623 100644 --- a/src/actions.c +++ b/src/actions.c @@ -409,6 +409,7 @@ void wMaximizeWindow(WWindow *wwin, int directions) { int new_width, new_height, new_x, new_y; + int changed_h, changed_v, shrink_h, shrink_v; WArea usableArea, totalArea; if (WFLAGP(wwin, no_resizable)) @@ -440,11 +441,33 @@ wMaximizeWindow(WWindow *wwin, int directions) wwin->flags.skip_next_animation = 1; wUnshadeWindow(wwin); } + /* Only save directions, not kbd or xinerama hints */ + directions &= (MAX_HORIZONTAL|MAX_VERTICAL); + + changed_h = ((wwin->flags.maximized ^ directions) & MAX_HORIZONTAL); + changed_v = ((wwin->flags.maximized ^ directions) & MAX_VERTICAL); + shrink_h = (changed_h && (directions & MAX_HORIZONTAL)==0); + shrink_v = (changed_v && (directions & MAX_VERTICAL)==0); + + if (wwin->flags.maximized) { + /* if already maximized in some direction, we only update the + * appropriate old x, old y coordinates. This is necessary to + * allow succesive maximizations in different directions without + * the need to first do an un-maximize (to avoid flicker). + */ + if (!(wwin->flags.maximized & MAX_HORIZONTAL)) { + wwin->old_geometry.x = wwin->frame_x; + } + if (!(wwin->flags.maximized & MAX_VERTICAL)) { + wwin->old_geometry.y = wwin->frame_y; + } + } else { + wwin->old_geometry.width = wwin->client.width; + wwin->old_geometry.height = wwin->client.height; + wwin->old_geometry.x = wwin->frame_x; + wwin->old_geometry.y = wwin->frame_y; + } wwin->flags.maximized = directions; - wwin->old_geometry.width = wwin->client.width; - wwin->old_geometry.height = wwin->client.height; - wwin->old_geometry.x = wwin->frame_x; - wwin->old_geometry.y = wwin->frame_y; #ifdef KWM_HINTS wKWMUpdateClientGeometryRestore(wwin); @@ -453,6 +476,9 @@ wMaximizeWindow(WWindow *wwin, int directions) if (directions & MAX_HORIZONTAL) { new_width = (usableArea.x2-usableArea.x1)-FRAME_BORDER_WIDTH*2; new_x = usableArea.x1; + } else if (shrink_h) { + new_x = wwin->old_geometry.x; + new_width = wwin->old_geometry.width; } else { new_x = wwin->frame_x; new_width = wwin->frame->core->width; @@ -465,6 +491,9 @@ wMaximizeWindow(WWindow *wwin, int directions) new_y -= wwin->frame->top_width; new_height += wwin->frame->bottom_width - 1; } + } else if (shrink_v) { + new_y = wwin->old_geometry.y; + new_height = wwin->old_geometry.height; } else { new_y = wwin->frame_y; new_height = wwin->frame->core->height; diff --git a/src/event.c b/src/event.c index 76a4b594..1b2bf1f6 100644 --- a/src/event.c +++ b/src/event.c @@ -1444,35 +1444,41 @@ handleKeyPress(XEvent *event) break; case WKBD_MAXIMIZE: if (ISMAPPED(wwin) && ISFOCUSED(wwin) && !WFLAGP(wwin, no_resizable)) { - CloseWindowMenu(scr); - - if (wwin->flags.maximized) { + int newdir = (MAX_VERTICAL|MAX_HORIZONTAL); + + CloseWindowMenu(scr); + + if (wwin->flags.maximized == newdir) { wUnmaximizeWindow(wwin); - } else { - wMaximizeWindow(wwin, MAX_VERTICAL|MAX_HORIZONTAL|MAX_KEYBOARD); + } else { + wMaximizeWindow(wwin, newdir|MAX_KEYBOARD); } } break; case WKBD_VMAXIMIZE: if (ISMAPPED(wwin) && ISFOCUSED(wwin) && !WFLAGP(wwin, no_resizable)) { + int newdir = (MAX_VERTICAL ^ wwin->flags.maximized); + CloseWindowMenu(scr); - - if (wwin->flags.maximized) { - wUnmaximizeWindow(wwin); + + if (newdir) { + wMaximizeWindow(wwin, newdir|MAX_KEYBOARD); } else { - wMaximizeWindow(wwin, MAX_VERTICAL|MAX_KEYBOARD); - } + wUnmaximizeWindow(wwin); + } } break; case WKBD_HMAXIMIZE: if (ISMAPPED(wwin) && ISFOCUSED(wwin) && !WFLAGP(wwin, no_resizable)) { + int newdir = (MAX_HORIZONTAL ^ wwin->flags.maximized); + CloseWindowMenu(scr); - - if (wwin->flags.maximized) { - wUnmaximizeWindow(wwin); + + if (newdir) { + wMaximizeWindow(wwin, newdir|MAX_KEYBOARD); } else { - wMaximizeWindow(wwin, MAX_HORIZONTAL|MAX_KEYBOARD); - } + wUnmaximizeWindow(wwin); + } } break; case WKBD_RAISE: diff --git a/src/gnome.c b/src/gnome.c index 8506abff..b97b295e 100644 --- a/src/gnome.c +++ b/src/gnome.c @@ -609,14 +609,11 @@ wGNOMEProcessClientMessage(XClientMessageEvent *event) } if (maximize != wwin->flags.maximized) { -#define both (MAX_HORIZONTAL|MAX_VERTICAL) - if (!(maximize & both) && (wwin->flags.maximized & both)) { - wUnmaximizeWindow(wwin); - } - if ((maximize & both) && !(wwin->flags.maximized & both)) { + if (maximize) { wMaximizeWindow(wwin, maximize); - } -#undef both + } else { + wUnmaximizeWindow(wwin); + } } if (mask & WIN_STATE_SHADED) { diff --git a/src/window.c b/src/window.c index bee7d63c..3eaf09f0 100644 --- a/src/window.c +++ b/src/window.c @@ -3095,10 +3095,12 @@ titlebarDblClick(WCoreWindow *sender, void *data, XEvent *event) /* maximize window */ if (dir!=0 && !WFLAGP(wwin, no_resizable)) { int ndir = dir ^ wwin->flags.maximized; - if (wwin->flags.maximized != 0) - wUnmaximizeWindow(wwin); - if (ndir != 0) - wMaximizeWindow(wwin, ndir); + + if (ndir != 0) { + wMaximizeWindow(wwin, ndir); + } else { + wUnmaximizeWindow(wwin); + } } } } else if (event->xbutton.button==Button3) {