1
0
Fork 0
mirror of https://github.com/beefytech/Beef.git synced 2025-06-08 03:28:20 +02:00

Multi-monitor fixes

This commit is contained in:
Brian Fiete 2020-05-07 08:39:40 -07:00
parent 7f0a81b5b3
commit 26604017f8
8 changed files with 133 additions and 32 deletions

View file

@ -81,6 +81,9 @@ namespace Beefy
[StdCall, CLink]
static extern void BFApp_GetWorkspaceRect(out int32 x, out int32 y, out int32 width, out int32 height);
[StdCall, CLink]
static extern void BFApp_GetWorkspaceRectFrom(int32 x, int32 y, int32 width, int32 height, out int32 outX, out int32 outY, out int32 outWidth, out int32 outHeight);
[StdCall, CLink]
static extern void BFApp_Create();
@ -447,6 +450,19 @@ namespace Beefy
height = heightOut;
}
public void GetWorkspaceRectFrom(int fromX, int fromY, int fromWidth, int fromHeight, out int outX, out int outY, out int outWidth, out int outHeight)
{
int32 xOut;
int32 yOut;
int32 widthOut;
int32 heightOut;
BFApp_GetWorkspaceRectFrom((.)fromX, (.)fromY, (.)fromWidth, (.)fromHeight, out xOut, out yOut, out widthOut, out heightOut);
outX = xOut;
outY = yOut;
outWidth = widthOut;
outHeight = heightOut;
}
public bool HasModalDialogs()
{
for (var window in mWindows)

View file

@ -51,7 +51,7 @@ namespace Beefy.theme.dark
mText = new String(text);
mAllowResize = allowResize;
BFApp.sApp.GetWorkspaceRect(var workspaceX, var workspaceY, var workspaceWidth, var workspaceHeight);
BFApp.sApp.GetWorkspaceRectFrom((.)x, (.)y, 0, 0, var workspaceX, var workspaceY, var workspaceWidth, var workspaceHeight);
float maxWidth = workspaceWidth - GS!(32);
FontMetrics fontMetrics = .();

View file

@ -178,7 +178,7 @@ namespace Beefy.widgets
base.Resize(x, y, width, height);
}
public virtual void CalcContainerSize(MenuContainer menuContainer, bool allowScrollable, ref float screenX, ref float screenY, out float width, out float height)
public virtual void CalcContainerSize(float x, float y, MenuContainer menuContainer, bool allowScrollable, ref float screenX, ref float screenY, out float width, out float height)
{
Rect menuRect = menuContainer.CalcRectFromContent();
width = Math.Min(mMaxContainerWidth, Math.Max(mMinContainerWidth, menuRect.mWidth));
@ -188,7 +188,7 @@ namespace Beefy.widgets
int workspaceY;
int workspaceWidth;
int workspaceHeight;
BFApp.sApp.GetWorkspaceRect(out workspaceX, out workspaceY, out workspaceWidth, out workspaceHeight);
BFApp.sApp.GetWorkspaceRectFrom((.)x, (.)y, 0, 0, out workspaceX, out workspaceY, out workspaceWidth, out workspaceHeight);
float maxY = workspaceY + workspaceHeight;
@ -250,13 +250,14 @@ namespace Beefy.widgets
float screenX;
float screenY;
relativeWidget.SelfToRootTranslate(0, curY, out screenX, out screenY);
screenX += relativeWidget.mWidgetWindow.mClientX;
screenY += relativeWidget.mWidgetWindow.mClientY;
int wsX;
int wsY;
int wsWidth;
int wsHeight;
BFApp.sApp.GetWorkspaceRect(out wsX, out wsY, out wsWidth, out wsHeight);
BFApp.sApp.GetWorkspaceRectFrom((.)screenX, (.)screenY, 0, 0, out wsX, out wsY, out wsWidth, out wsHeight);
float spaceLeft = (wsY + wsHeight) - (screenY);
if (spaceLeft < minHeight)
{
@ -299,7 +300,10 @@ namespace Beefy.widgets
float screenWidth;
float screenHeight;
CalcContainerSize(menuContainer, allowScrollable, ref screenX, ref screenY, out screenWidth, out screenHeight);
CalcContainerSize(screenX, screenY, menuContainer, allowScrollable, ref screenX, ref screenY, out screenWidth, out screenHeight);
screenWidth = Math.Max(screenWidth, 32);
screenHeight = Math.Max(screenHeight, 32);
WidgetWindow parentWindow = (relativeWidget != null) ? relativeWidget.mWidgetWindow : null;
curWidgetWindow = new WidgetWindow(parentWindow,
@ -332,7 +336,7 @@ namespace Beefy.widgets
float screenWidth;
float screenHeight;
CalcContainerSize(menuContainer, allowScrollable, ref screenX, ref screenY, out screenWidth, out screenHeight);
CalcContainerSize(x, y, menuContainer, allowScrollable, ref screenX, ref screenY, out screenWidth, out screenHeight);
curWidgetWindow.Resize((int32)(screenX), (int32)(screenY),
(int32)screenWidth, (int32)screenHeight);

View file

@ -88,6 +88,7 @@ public:
virtual void SetCursor(int cursor);
virtual void GetDesktopResolution(int& width, int& height) = 0;
virtual void GetWorkspaceRect(int& x, int& y, int& width, int& height) = 0;
virtual void GetWorkspaceRectFrom(int fromX, int fromY, int fromWidth, int fromHeight, int& outX, int& outY, int& outWidth, int& outHeight) { GetWorkspaceRect(outX, outY, outWidth, outHeight); }
virtual BFWindow* CreateNewWindow(BFWindow* parent, const StringImpl& title, int x, int y, int width, int height, int windowFlags) = 0;
virtual void RemoveWindow(BFWindow* window);

View file

@ -79,6 +79,11 @@ BF_EXPORT void BF_CALLTYPE BFApp_GetWorkspaceRect(int& x, int& y, int& width, in
gBFApp->GetWorkspaceRect(x, y, width, height);
}
BF_EXPORT void BF_CALLTYPE BFApp_GetWorkspaceRectFrom(int fromX, int fromY, int fromWidth, int fromHeight, int& outX, int& outY, int& outWidth, int& outHeight)
{
gBFApp->GetWorkspaceRectFrom(fromX, fromY, fromWidth, fromHeight, outX, outY, outWidth, outHeight);
}
BF_EXPORT void BF_CALLTYPE BFApp_Create()
{
new PlatformBFApp();

View file

@ -43,6 +43,38 @@ static BOOL CALLBACK BFEnumResNameProc(
return FALSE;
}
struct AdjustedMonRect
{
int mMonCount;
int mX;
int mY;
int mWidth;
int mHeight;
};
static BOOL ClipToMonitor(HMONITOR mon, HDC hdc, LPRECT monRect, LPARAM userArg)
{
AdjustedMonRect* outRect = (AdjustedMonRect*)userArg;
MONITORINFO monitorInfo = { sizeof(MONITORINFO) };
if (::GetMonitorInfo(mon, &monitorInfo) == 0)
return TRUE;
outRect->mMonCount++;
if (outRect->mX < monitorInfo.rcWork.left)
outRect->mX = monitorInfo.rcWork.left;
else if (outRect->mX + outRect->mWidth >= monitorInfo.rcWork.right)
outRect->mX = BF_MAX((int)monitorInfo.rcWork.left, monitorInfo.rcWork.right - outRect->mWidth);
if (outRect->mY < monitorInfo.rcWork.top)
outRect->mY = monitorInfo.rcWork.top;
else if (outRect->mY + outRect->mHeight >= monitorInfo.rcWork.bottom)
outRect->mY = BF_MAX((int)monitorInfo.rcWork.top, monitorInfo.rcWork.bottom - outRect->mHeight);
return TRUE;
}
WinBFWindow::WinBFWindow(BFWindow* parent, const StringImpl& title, int x, int y, int width, int height, int windowFlags)
{
HINSTANCE hInstance = GetModuleHandle(NULL);
@ -128,18 +160,16 @@ WinBFWindow::WinBFWindow(BFWindow* parent, const StringImpl& title, int x, int y
if (windowFlags & BFWINDOW_POPUP_POSITION)
{
RECT desktopRect;
::SystemParametersInfo(SPI_GETWORKAREA, NULL, &desktopRect, NULL);
AdjustedMonRect adjustRect = { 0, x, y, width, height };
RECT wantRect = { x, y, x + width, y + height };
if (x < desktopRect.left)
x = desktopRect.left;
else if (x + width >= desktopRect.right)
x = BF_MAX((int)desktopRect.left, desktopRect.right - width);
if (y < desktopRect.top)
y = desktopRect.top;
else if (y + height >= desktopRect.bottom)
y = BF_MAX((int)desktopRect.top, desktopRect.bottom - height);
EnumDisplayMonitors(NULL, &wantRect, ClipToMonitor, (LPARAM)&adjustRect);
if (adjustRect.mMonCount == 0)
EnumDisplayMonitors(NULL, NULL, ClipToMonitor, (LPARAM)&adjustRect);
x = adjustRect.mX;
y = adjustRect.mY;
width = adjustRect.mWidth;
height = adjustRect.mHeight;
}
mFlags = windowFlags;
@ -1128,26 +1158,70 @@ void WinBFApp::GetDesktopResolution(int& width, int& height)
height = ::GetSystemMetrics(SM_CYSCREEN);
}
void WinBFApp::GetWorkspaceRect(int& x, int& y, int& width, int& height)
static BOOL InflateRectToMonitor(HMONITOR mon, HDC hdc, LPRECT monRect, LPARAM userArg)
{
RECT desktopRect;
AdjustedMonRect* inflatedRect = (AdjustedMonRect*)userArg;
if (::GetSystemMetrics(SM_CMONITORS) > 1)
MONITORINFO monitorInfo = { sizeof(MONITORINFO) };
if (::GetMonitorInfo(mon, &monitorInfo) == 0)
return TRUE;
inflatedRect->mMonCount++;
if (inflatedRect->mMonCount == 1)
{
desktopRect.left = ::GetSystemMetrics(SM_XVIRTUALSCREEN);
desktopRect.right = ::GetSystemMetrics(SM_CXVIRTUALSCREEN);
desktopRect.top = ::GetSystemMetrics(SM_YVIRTUALSCREEN);
desktopRect.bottom = ::GetSystemMetrics(SM_CYVIRTUALSCREEN);
inflatedRect->mX = monitorInfo.rcWork.left;
inflatedRect->mY = monitorInfo.rcWork.top;
inflatedRect->mWidth = monitorInfo.rcWork.right - monitorInfo.rcWork.left;
inflatedRect->mHeight = monitorInfo.rcWork.bottom - monitorInfo.rcWork.top;
}
else
{
::SystemParametersInfo(SPI_GETWORKAREA, NULL, &desktopRect, NULL);
int minLeft = BF_MIN(inflatedRect->mX, monitorInfo.rcWork.left);
int minTop = BF_MIN(inflatedRect->mY, monitorInfo.rcWork.top);
int maxRight = BF_MAX(inflatedRect->mX + inflatedRect->mWidth, monitorInfo.rcWork.right);
int maxBottom = BF_MAX(inflatedRect->mY + inflatedRect->mHeight, monitorInfo.rcWork.bottom);
inflatedRect->mX = minLeft;
inflatedRect->mY = minTop;
inflatedRect->mWidth = maxRight - minLeft;
inflatedRect->mHeight = maxBottom - minTop;
}
x = desktopRect.left;
y = desktopRect.top;
width = desktopRect.right - desktopRect.left;
height = desktopRect.bottom - desktopRect.top;
return TRUE;
}
void WinBFApp::GetWorkspaceRect(int& x, int& y, int& width, int& height)
{
AdjustedMonRect inflateRect = { 0 };
EnumDisplayMonitors(NULL, NULL, InflateRectToMonitor, (LPARAM)&inflateRect);
x = inflateRect.mX;
y = inflateRect.mY;
width = inflateRect.mWidth;
height = inflateRect.mHeight;
}
void WinBFApp::GetWorkspaceRectFrom(int fromX, int fromY, int fromWidth, int fromHeight, int & outX, int & outY, int & outWidth, int & outHeight)
{
AdjustedMonRect inflateRect = { 0 };
RECT wantRect;
wantRect.left = fromX;
wantRect.top = fromY;
wantRect.right = fromX + BF_MAX(fromWidth, 1);
wantRect.bottom = fromY + BF_MAX(fromHeight, 1);
EnumDisplayMonitors(NULL, &wantRect, InflateRectToMonitor, (LPARAM)&inflateRect);
if (inflateRect.mMonCount == 0)
{
GetWorkspaceRect(outX, outY, outWidth, outHeight);
return;
}
outX = inflateRect.mX;
outY = inflateRect.mY;
outWidth = inflateRect.mWidth;
outHeight = inflateRect.mHeight;
}
BFWindow* WinBFApp::CreateNewWindow(BFWindow* parent, const StringImpl& title, int x, int y, int width, int height, int windowFlags)

View file

@ -105,8 +105,9 @@ public:
virtual void Init() override;
virtual void Run() override;
virtual void GetDesktopResolution(int& width, int& height);
virtual void GetWorkspaceRect(int& x, int& y, int& width, int& height);
virtual void GetDesktopResolution(int& width, int& height) override;
virtual void GetWorkspaceRect(int& x, int& y, int& width, int& height) override;
virtual void GetWorkspaceRectFrom(int fromX, int fromY, int fromWidth, int fromHeight, int& outX, int& outY, int& outWidth, int& outHeight) override;
virtual BFWindow* CreateNewWindow(BFWindow* parent, const StringImpl& title, int x, int y, int width, int height, int windowFlags) override;
virtual DrawLayer* CreateDrawLayer(BFWindow* window);

View file

@ -10572,7 +10572,7 @@ namespace IDE
//
{
BFWindow.Flags flags = .Border | .ThickFrame | .Resizable | .SysMenu |
.Caption | .Minimize | .Maximize | .QuitOnClose | .Menu;
.Caption | .Minimize | .Maximize | .QuitOnClose | .Menu | .PopupPosition;
if (mRunningTestScript)
flags |= .NoActivate;