Skip to content

Commit

Permalink
Restore main window position using SetWindowPlacement()
Browse files Browse the repository at this point in the history
In e579712, the code used to create the
main window was updated to pass the saved window position directly to
CreateWindow().

The problem with that is that CreateWindow() accepts the position in
screen coordinates, while the window position is retrieved using
GetWindowPlacement() and is therefore saved in workspace coordinates.

Mixing these two coordinate systems meant that if the taskbar was in a
different position, the window would move each time the application
started. For example, if the taskbar was shown on the left of the
screen, the window would move to the left each time the application was
started, since workspace coordinates treated as screen coordinates would
be further to the left.

To fix this, the window position is now restored using
SetWindowPlacement().

Additionally, there is no longer an explicit check to see whether the
window is visible, since SetWindowPlacement() will adjust the
coordinates if they would result in the window being completely off
screen.
  • Loading branch information
derceg committed Dec 25, 2024
1 parent 7fe0398 commit 44bda34
Show file tree
Hide file tree
Showing 5 changed files with 14 additions and 35 deletions.
4 changes: 0 additions & 4 deletions Documentation/User/History.txt
Original file line number Diff line number Diff line change
Expand Up @@ -144,10 +144,6 @@ Bug fixes:
- If a filtered item is renamed, it will now be shown again if it
no longer needs to be filtered. Previously, the item would
remain hidden until filtering was disabled.
- When starting the application, the previous window position
will only be used if it's visible. If the saved position is
off-screen (e.g. because the monitor configuration has
changed), the default position will be used instead.
- A saved dialog position will now only be used if the saved
position is visible on screen.
- When renaming an item, the item is updated immediately if the
Expand Down
36 changes: 11 additions & 25 deletions Explorer++/Explorer++/Explorer++.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -110,21 +110,19 @@ HWND Explorerplusplus::CreateMainWindow(const WindowStorageData *storageData)
mainWindowClassRegistered = true;
}

RECT finalBounds;
HWND hwnd = CreateWindow(WINDOW_CLASS_NAME, App::APP_NAME, WS_OVERLAPPEDWINDOW, CW_USEDEFAULT,
CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, nullptr, nullptr, GetModuleHandle(nullptr),
nullptr);
CHECK(hwnd);

if (storageData)
{
finalBounds = GetValidatedMainWindowBounds(&storageData->bounds);
}
else
{
finalBounds = GetDefaultMainWindowBounds();
}
WINDOWPLACEMENT placement = {};
placement.length = sizeof(placement);
BOOL res = GetWindowPlacement(hwnd, &placement);
CHECK(res);

HWND hwnd = CreateWindow(WINDOW_CLASS_NAME, App::APP_NAME, WS_OVERLAPPEDWINDOW,
finalBounds.left, finalBounds.top, GetRectWidth(&finalBounds), GetRectHeight(&finalBounds),
nullptr, nullptr, GetModuleHandle(nullptr), nullptr);
CHECK(hwnd);
placement.showCmd = SW_HIDE;
placement.rcNormalPosition = storageData ? storageData->bounds : GetDefaultMainWindowBounds();
SetWindowPlacement(hwnd, &placement);

return hwnd;
}
Expand All @@ -149,18 +147,6 @@ ATOM Explorerplusplus::RegisterMainWindowClass(HINSTANCE instance)
return RegisterClassEx(&windowClass);
}

RECT Explorerplusplus::GetValidatedMainWindowBounds(const RECT *requestedBounds)
{
// When shown in its normal size, the window should at least be on screen somewhere, even if
// it's not completely visible.
if (!IsRectVisible(requestedBounds))
{
return GetDefaultMainWindowBounds();
}

return *requestedBounds;
}

RECT Explorerplusplus::GetDefaultMainWindowBounds()
{
RECT workArea;
Expand Down
1 change: 0 additions & 1 deletion Explorer++/Explorer++/Explorer++.h
Original file line number Diff line number Diff line change
Expand Up @@ -208,7 +208,6 @@ class Explorerplusplus :

static HWND CreateMainWindow(const WindowStorageData *storageData);
static ATOM RegisterMainWindowClass(HINSTANCE instance);
static RECT GetValidatedMainWindowBounds(const RECT *requestedBounds);
static RECT GetDefaultMainWindowBounds();

LRESULT WindowProcedure(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);
Expand Down
5 changes: 0 additions & 5 deletions Explorer++/Explorer++/MsgHandler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -869,11 +869,6 @@ void Explorerplusplus::OnNewWindow()
RECT bounds = placement.rcNormalPosition;
OffsetRect(&bounds, windowOffsetInPixels, windowOffsetInPixels);

if (!IsRectVisible(&bounds))
{
bounds = placement.rcNormalPosition;
}

WindowStorageData initialData = {};
initialData.bounds = bounds;
initialData.showState = NativeShowStateToShowState(placement.showCmd);
Expand Down
3 changes: 3 additions & 0 deletions Explorer++/Explorer++/WindowStorage.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,10 @@ BETTER_ENUM(WindowShowState, int,

struct WindowStorageData
{
// The size and position of the window, with the position being in workspace coordinates (i.e.
// those returned by GetWindowPlacement()).
RECT bounds;

WindowShowState showState;
std::vector<TabStorageData> tabs;
int selectedTab;
Expand Down

0 comments on commit 44bda34

Please sign in to comment.