Save/load main window layout correctly and limit to current workarea

* Now the restored frame position/maximized flag are saved correctly.
* We've improved the default size to the current workarea of the main
  screen.
* Limit the initial frame position to the current available screens
  (e.g. the saved frame position could be invalid if the user
  unplugged a monitor)
This commit is contained in:
David Capello 2021-04-29 16:13:45 -03:00
parent 0934a78db6
commit d6acb9e20f
2 changed files with 67 additions and 34 deletions

2
laf

@ -1 +1 @@
Subproject commit 45e9450b2481c07cec0aa523d77416e293f08ebe Subproject commit 8943fafde16671798814c937f64953b7ecfdf2cb

View File

@ -43,6 +43,7 @@
#include "base/string.h" #include "base/string.h"
#include "doc/sprite.h" #include "doc/sprite.h"
#include "os/error.h" #include "os/error.h"
#include "os/screen.h"
#include "os/surface.h" #include "os/surface.h"
#include "os/system.h" #include "os/system.h"
#include "os/window.h" #include "os/window.h"
@ -110,17 +111,15 @@ static ui::Timer* defered_invalid_timer = nullptr;
static gfx::Region defered_invalid_region; static gfx::Region defered_invalid_region;
// Load & save graphics configuration // Load & save graphics configuration
static void load_gui_config(int& w, int& h, bool& maximized, static void load_gui_config(os::WindowSpec& spec, bool& maximized);
std::string& windowLayout);
static void save_gui_config(); static void save_gui_config();
static bool create_main_window(bool gpuAccel, static bool create_main_window(bool gpuAccel,
bool& maximized, bool& maximized,
std::string& lastError) std::string& lastError)
{ {
int w, h; os::WindowSpec spec;
std::string windowLayout; load_gui_config(spec, maximized);
load_gui_config(w, h, maximized, windowLayout);
// Scale is equal to 0 when it's the first time the program is // Scale is equal to 0 when it's the first time the program is
// executed. // executed.
@ -129,9 +128,10 @@ static bool create_main_window(bool gpuAccel,
os::instance()->setGpuAcceleration(gpuAccel); os::instance()->setGpuAcceleration(gpuAccel);
try { try {
if (w > 0 && h > 0) { if (!spec.frame().isEmpty() ||
main_window = os::instance()->makeWindow( !spec.contentRect().isEmpty()) {
w, h, (scale == 0 ? 2: base::clamp(scale, 1, 4))); spec.scale(scale == 0 ? 2: base::clamp(scale, 1, 4));
main_window = os::instance()->makeWindow(spec);
} }
} }
catch (const os::WindowCreationException& e) { catch (const os::WindowCreationException& e) {
@ -141,11 +141,13 @@ static bool create_main_window(bool gpuAccel,
if (!main_window) { if (!main_window) {
for (int c=0; try_resolutions[c].width; ++c) { for (int c=0; try_resolutions[c].width; ++c) {
try { try {
main_window = spec.frame();
os::instance()->makeWindow( spec.position(os::WindowSpec::Position::Default);
try_resolutions[c].width, spec.scale(scale == 0 ? try_resolutions[c].scale: scale);
try_resolutions[c].height, spec.contentRect(gfx::Rect(0, 0,
(scale == 0 ? try_resolutions[c].scale: scale)); try_resolutions[c].width * spec.scale(),
try_resolutions[c].height * spec.scale()));
main_window = os::instance()->makeWindow(spec);
break; break;
} }
catch (const os::WindowCreationException& e) { catch (const os::WindowCreationException& e) {
@ -160,11 +162,8 @@ static bool create_main_window(bool gpuAccel,
if (scale == 0) if (scale == 0)
Preferences::instance().general.screenScale(main_window->scale()); Preferences::instance().general.screenScale(main_window->scale());
if (!windowLayout.empty()) { if (main_window->isMinimized())
main_window->setLayout(windowLayout); main_window->maximize();
if (main_window->isMinimized())
main_window->maximize();
}
} }
return (main_window != nullptr); return (main_window != nullptr);
@ -286,15 +285,49 @@ void update_windows_color_profile_from_preferences()
} }
} }
static void load_gui_config(int& w, int& h, bool& maximized, static void load_gui_config(os::WindowSpec& spec, bool& maximized)
std::string& windowLayout)
{ {
gfx::Size defSize = os::instance()->defaultNewWindowSize(); os::ScreenRef screen = os::instance()->mainScreen();
spec.screen(screen);
w = get_config_int("GfxMode", "Width", defSize.w); gfx::Rect frame;
h = get_config_int("GfxMode", "Height", defSize.h); frame = get_config_rect("GfxMode", "Frame", frame);
maximized = get_config_bool("GfxMode", "Maximized", false); if (!frame.isEmpty()) {
windowLayout = get_config_string("GfxMode", "WindowLayout", ""); spec.position(os::WindowSpec::Position::Frame);
// Limit the content rect position into the available workarea,
// e.g. this is needed in case that the user closed Aseprite in a
// 2nd monitor that then unplugged and start Aseprite again.
bool ok = false;
os::ScreenList screens;
os::instance()->listScreens(screens);
for (const auto& screen : screens) {
gfx::Rect wa = screen->workarea();
gfx::Rect intersection = (frame & wa);
if (intersection.w >= 32 &&
intersection.h >= 32) {
ok = true;
break;
}
}
// Reset content rect
if (!ok) {
spec.position(os::WindowSpec::Position::Default);
frame = gfx::Rect();
}
}
if (frame.isEmpty()) {
frame = screen->workarea().shrink(64);
// Try to get Width/Height from previous Aseprite versions
frame.w = get_config_int("GfxMode", "Width", frame.w);
frame.h = get_config_int("GfxMode", "Height", frame.h);
}
spec.frame(frame);
maximized = get_config_bool("GfxMode", "Maximized", true);
ui::set_multiple_displays(Preferences::instance().experimental.multipleWindows()); ui::set_multiple_displays(Preferences::instance().experimental.multipleWindows());
} }
@ -303,13 +336,13 @@ static void save_gui_config()
{ {
os::Window* window = manager->display()->nativeWindow(); os::Window* window = manager->display()->nativeWindow();
if (window) { if (window) {
set_config_bool("GfxMode", "Maximized", window->isMaximized()); const bool maximized = (window->isMaximized() ||
set_config_int("GfxMode", "Width", window->originalWidth()); window->isFullscreen());
set_config_int("GfxMode", "Height", window->originalHeight()); const gfx::Rect frame = (maximized ? window->restoredFrame():
window->frame());
std::string windowLayout = window->getLayout(); set_config_bool("GfxMode", "Maximized", maximized);
if (!windowLayout.empty()) set_config_rect("GfxMode", "Frame", frame);
set_config_string("GfxMode", "WindowLayout", windowLayout.c_str());
} }
} }