Skip to content

Commit

Permalink
Fix re locating window after a guiscale change
Browse files Browse the repository at this point in the history
  • Loading branch information
Gasparoken committed Jul 14, 2023
1 parent 7ac225f commit 8a05354
Show file tree
Hide file tree
Showing 3 changed files with 70 additions and 19 deletions.
26 changes: 25 additions & 1 deletion src/app/ini_file.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// Aseprite
// Copyright (C) 2018-2021 Igara Studio S.A.
// Copyright (C) 2018-2023 Igara Studio S.A.
// Copyright (C) 2001-2016 David Capello
//
// This program is distributed under the terms of
Expand Down Expand Up @@ -259,6 +259,30 @@ void set_config_rect(const char* section, const char* name, const Rect& rect)
set_config_string(section, name, buf);
}

RectT<float> get_config_rectf(const char* section, const char* name, const RectT<float>& rect)
{
RectT<float> rect2(rect);
const char* value = get_config_string(section, name, "");
if (value) {
std::vector<std::string> parts;
base::split_string(value, parts, " ");
if (parts.size() == 4) {
rect2.x = strtof(parts[0].c_str(), NULL);
rect2.y = strtof(parts[1].c_str(), NULL);
rect2.w = strtof(parts[2].c_str(), NULL);
rect2.h = strtof(parts[3].c_str(), NULL);
}
}
return rect2;
}

void set_config_rectf(const char* section, const char* name, const RectT<float>& rect)
{
char buf[128];
sprintf(buf, "%f %f %f %f", rect.x, rect.y, rect.w, rect.h);
set_config_string(section, name, buf);
}

app::Color get_config_color(const char* section, const char* name, const app::Color& value)
{
return app::Color::fromString(get_config_string(section, name, value.toString().c_str()));
Expand Down
5 changes: 4 additions & 1 deletion src/app/ini_file.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// Aseprite
// Copyright (C) 2018-2019 Igara Studio S.A.
// Copyright (C) 2018-2023 Igara Studio S.A.
// Copyright (C) 2001-2016 David Capello
//
// This program is distributed under the terms of
Expand Down Expand Up @@ -54,6 +54,9 @@ namespace app {
gfx::Rect get_config_rect(const char* section, const char* name, const gfx::Rect& rect);
void set_config_rect(const char* section, const char* name, const gfx::Rect& rect);

gfx::RectT<float> get_config_rectf(const char* section, const char* name, const gfx::RectT<float>& rect);
void set_config_rectf(const char* section, const char* name, const gfx::RectT<float>& rect);

app::Color get_config_color(const char* section, const char* name, const app::Color& value);
void set_config_color(const char* section, const char* name, const app::Color& value);

Expand Down
58 changes: 41 additions & 17 deletions src/app/modules/gui.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -432,21 +432,31 @@ void load_window_pos(Window* window, const char* section,
window->setBounds(pos);

if (get_multiple_displays()) {
// First try to read the new "WindowFrameUnscaled" field (which is unscaled)
Rect frame = get_config_rect(section, "WindowFrameUnscaled", gfx::Rect());
// First try to read the "WindowFrameNormalized" field
// Meaning =
// x: per unit X center position on screen of the window (0.0 -> 1.0).
// y: per unit Y position on screen of the window (0.0 -> 1.0).
// w: unscaled window width in pixels.
// x: unscaled window height in pixels.
const os::Window* mainNativeWindow = manager->display()->nativeWindow();
int scale = mainNativeWindow->scale() * guiscale();
RectT<float> frame = get_config_rectf(section, "WindowFrameNormalized", gfx::RectT<float>());
if (!frame.isEmpty()) {
// Scale the window size with the UI scaling factor.
frame.w *= guiscale();
frame.h *= guiscale();
// De-normalization of the position and size of the window frame.
frame.x = float(workarea.w) * frame.x - frame.w * scale / 2;
frame.y = float(workarea.h) * frame.y - frame.h * scale / 2;
frame.w *= scale;
frame.h *= scale;
}
// If it's empty read the backward compatible "WindowFrame" field (which is
// already scaled with UI scaling)
else {
frame = get_config_rect(section, "WindowFrame", gfx::Rect());
}
if (!frame.isEmpty()) {
limit_with_workarea(parentDisplay, frame);
window->loadNativeFrame(frame);
Rect rect(frame);
limit_with_workarea(parentDisplay, rect);
window->loadNativeFrame(rect);
}
}
else {
Expand All @@ -456,25 +466,39 @@ void load_window_pos(Window* window, const char* section,

void save_window_pos(Window* window, const char* section)
{
gfx::Rect rc;
gfx::RectT<float> rc;

if (!window->lastNativeFrame().isEmpty()) {
const os::Window* mainNativeWindow = manager->display()->nativeWindow();
if (get_multiple_displays() &&
!window->lastNativeFrame().isEmpty()) {
rc = window->lastNativeFrame();
set_config_rect(section, "WindowFrame", rc);

Display* parentDisplay =
(window->display() ? window->display():
window->manager()->display());
Rect workarea =
(get_multiple_displays() ?
parentDisplay->nativeWindow()->screen()->workarea():
parentDisplay->bounds());
const os::Window* mainNativeWindow = manager->display()->nativeWindow();
int scale = mainNativeWindow->scale() * guiscale();
// Meaning of 'rcNormalized':
// x: per unit X center position on screen of the window (0.0 -> 1.0).
// y: per unit Y position on screen of the window (0.0 -> 1.0).
// w: unscaled window width in pixels.
// x: unscaled window height in pixels.
RectT<float> rcNormalized((rc.x + rc.w/2 ) / float(workarea.w),
(rc.y + rc.h/2 ) / float(workarea.h),
rc.w / scale,
rc.h / scale);
// De-scale the window size to save it normalized.
rc.w /= guiscale();
rc.h /= guiscale();
set_config_rect(section, "WindowFrameUnscaled", rc);
set_config_rectf(section, "WindowFrameNormalized", rcNormalized);
rc.offset(-mainNativeWindow->frame().origin());
rc /= mainNativeWindow->scale();
rc /= scale;
}
else {
del_config_value(section, "WindowFrame");
rc = window->bounds();
// De-scale the window size to save it normalized.
rc.w /= guiscale();
rc.h /= guiscale();
}

set_config_rect(section, "WindowPos", rc);
Expand Down

0 comments on commit 8a05354

Please sign in to comment.