Index: src/window.cpp =================================================================== --- src/window.cpp (revision 13332) +++ src/window.cpp (working copy) @@ -721,9 +721,14 @@ } /** - * Find a nice spot for this window and resize it towards the default size. + * Resize window towards the default size. + * Prior to construction, a position for the new window (for its default size) + * has been found with LocalGetWindowPlacement(). Initially, the window is + * constructed with minimal size. Resizing the window to its default size is + * done here. * @param def_width default width in pixels of the window * @param def_height default height in pixels of the window + * @see Window::Window(), Window::Initialize() */ void Window::FindWindowPlacementAndResize(int def_width, int def_height) { @@ -802,7 +807,17 @@ this->Initialize(x, y, width, height, cls, widget, 0); } - +/** + * Decide whether a given rectangle is a good place to open a completely visible new window. + * The new window should be within screen borders, and not overlap with another already + * existing window (except for the main window in the background). + * @param left Left edge of the rectangle + * @param top Top edge of the rectangle + * @param width Width of the rectangle + * @param height Height of the rectangle + * @param pos If rectangle is good, use this parameter to return the top-left corner of the new window + * @return Boolean indication that the rectangle is a good place for the new window + */ static bool IsGoodAutoPlace1(int left, int top, int width, int height, Point &pos) { Window* const *wz; @@ -830,11 +845,26 @@ return true; } +/** + * Decide whether a given rectangle is a good place to open a mostly visible new window. + * The new window should be mostly within screen borders, and not overlap with another already + * existing window (except for the main window in the background). + * @param left Left edge of the rectangle + * @param top Top edge of the rectangle + * @param width Width of the rectangle + * @param height Height of the rectangle + * @param pos If rectangle is good, use this parameter to return the top-left corner of the new window + * @return Boolean indication that the rectangle is a good place for the new window + */ static bool IsGoodAutoPlace2(int left, int top, int width, int height, Point &pos) { Window* const *wz; + /* Left part of the rectangle may be at most 1/4 off-screen, + * right part of the rectangle may be at most 1/2 off-screen + */ if (left < -(width>>2) || left > _screen.width - (width>>1)) return false; + /* Bottom part of the rectangle may be at most 1/4 off-screen */ if (top < 22 || top > _screen.height - (height>>2)) return false; /* Make sure it is not obscured by any window. */ @@ -855,13 +885,24 @@ return true; } +/** + * Find a good place for opening a new window of a given width and height. + * @param width Width of the new window + * @param height Height of the new window + * @return Top-left coordinate of the new window + */ static Point GetAutoPlacePosition(int width, int height) { Window* const *wz; Point pt; + /* First attempt, try top-left of the screen */ if (IsGoodAutoPlace1(0, 24, width, height, pt)) return pt; + /* Second attempt, try around all existing windows with a distance of 2 pixels. + * The new window must be entirely on-screen, and not overlap with an existing window. + * Eight starting points are tried, two at each corner. + */ FOR_ALL_WINDOWS(wz) { const Window *w = *wz; if (w->window_class == WC_MAIN_WINDOW) continue; @@ -876,6 +917,10 @@ if (IsGoodAutoPlace1(w->left + w->width - width, w->top - height - 2, width, height, pt)) return pt; } + /* Third attempt, try around all existing windows with a distance of 2 pixels. + * The new window may be partly off-screen, and must not overlap with an existing window. + * Only four starting points are tried. + */ FOR_ALL_WINDOWS(wz) { const Window *w = *wz; if (w->window_class == WC_MAIN_WINDOW) continue; @@ -886,6 +931,9 @@ if (IsGoodAutoPlace2(w->left, w->top - height - 2, width, height, pt)) return pt; } + /* Fourth and final attempt, put window at diagonal starting from (0, 24), try multiples + * of (+5, +5) + */ { int left = 0, top = 24;