Limit loaded windows frame position with active workarea

This commit is contained in:
David Capello 2021-03-19 20:20:24 -03:00
parent d93fdfd49e
commit cf21f78d8d
4 changed files with 34 additions and 25 deletions

View File

@ -361,7 +361,7 @@ void load_window_pos(Window* window, const char* section,
if (get_multiple_displays()) {
Rect frame = get_config_rect(section, "WindowFrame", gfx::Rect());
if (!frame.isEmpty()) {
// TODO limit window area to current workspace / all available screen limits (?)
limit_with_workarea(frame);
window->loadNativeFrame(frame);
}
}

View File

@ -13,6 +13,8 @@
#include "base/clamp.h"
#include "gfx/rect.h"
#include "os/screen.h"
#include "os/system.h"
#include "ui/base.h"
#include "ui/display.h"
#include "ui/system.h"
@ -134,4 +136,31 @@ void fit_bounds(Display* parentDisplay,
}
}
// Limit window position using the union of all workareas
//
// TODO at least the title bar should be visible so we can
// resize it, because workareas can form an irregular shape
// (not rectangular) the calculation is a little more
// complex
void limit_with_workarea(gfx::Rect& frame)
{
if (!get_multiple_displays())
return;
gfx::Region wa;
os::ScreenList screens;
os::instance()->listScreens(screens);
for (const auto& screen : screens)
wa |= gfx::Region(screen->workarea());
// TODO use a "visibleFrameRegion = frame & wa" to check the
// visible regions and calculate if we should move the frame
// position
gfx::Rect waBounds = wa.bounds();
if (frame.x < waBounds.x) frame.x = waBounds.x;
if (frame.y < waBounds.y) frame.y = waBounds.y;
if (frame.x2() > waBounds.x2()) frame.w -= frame.x2() - waBounds.x2();
if (frame.y2() > waBounds.y2()) frame.h -= frame.y2() - waBounds.y2();
}
} // namespace ui

View File

@ -37,6 +37,9 @@ namespace ui {
gfx::Rect& bounds,
std::function<gfx::Rect(Widget*)> getWidgetBounds)> fitLogic = nullptr);
// The "frame" is a native windows frame bounds.
void limit_with_workarea(gfx::Rect& frame);
} // namespace ui
#endif

View File

@ -24,7 +24,6 @@
#include "base/time.h"
#include "os/event.h"
#include "os/event_queue.h"
#include "os/screen.h"
#include "os/surface.h"
#include "os/system.h"
#include "os/window.h"
@ -1311,29 +1310,7 @@ void Manager::_openWindow(Window* window, bool center)
frame.offset(relativeToFrame.origin());
}
// Limit window position using the union of all workareas
//
// TODO at least the title bar should be visible so we can
// resize it, because workareas can form an irregular shape
// (not rectangular) the calculation is a little more
// complex
{
gfx::Region wa;
os::ScreenList screens;
os::instance()->listScreens(screens);
for (const auto& screen : screens)
wa |= gfx::Region(screen->workarea());
// TODO use a "visibleFrameRegion = frame & wa" to check the
// visible regions and calculate if we should move the frame
// position
gfx::Rect waBounds = wa.bounds();
if (frame.x < waBounds.x) frame.x = waBounds.x;
if (frame.y < waBounds.y) frame.y = waBounds.y;
if (frame.x2() > waBounds.x2()) frame.w -= frame.x2() - waBounds.x2();
if (frame.y2() > waBounds.y2()) frame.h -= frame.y2() - waBounds.y2();
}
limit_with_workarea(frame);
spec.position(os::WindowSpec::Position::Frame);
spec.frame(frame);