[VCM]Support dpi scaling on the toolbar (#24411)
* [VCM]Support dpi scaling on the toolbar
|
Before Width: | Height: | Size: 1.3 KiB After Width: | Height: | Size: 13 KiB |
|
Before Width: | Height: | Size: 1.3 KiB After Width: | Height: | Size: 13 KiB |
|
Before Width: | Height: | Size: 1.2 KiB After Width: | Height: | Size: 11 KiB |
|
Before Width: | Height: | Size: 1.2 KiB After Width: | Height: | Size: 11 KiB |
|
Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 5.5 KiB |
|
Before Width: | Height: | Size: 1.2 KiB After Width: | Height: | Size: 5.5 KiB |
|
Before Width: | Height: | Size: 1.2 KiB After Width: | Height: | Size: 5.9 KiB |
|
Before Width: | Height: | Size: 1.2 KiB After Width: | Height: | Size: 6.2 KiB |
|
Before Width: | Height: | Size: 1.2 KiB After Width: | Height: | Size: 5.7 KiB |
|
Before Width: | Height: | Size: 1.2 KiB After Width: | Height: | Size: 10 KiB |
|
Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 4.9 KiB |
|
Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 4.9 KiB |
@@ -4,6 +4,7 @@
|
|||||||
#include <windowsx.h>
|
#include <windowsx.h>
|
||||||
|
|
||||||
#include <common/Themes/windows_colors.h>
|
#include <common/Themes/windows_colors.h>
|
||||||
|
#include <common/Display/dpi_aware.h>
|
||||||
|
|
||||||
#include "Logging.h"
|
#include "Logging.h"
|
||||||
#include "VideoConferenceModule.h"
|
#include "VideoConferenceModule.h"
|
||||||
@@ -14,6 +15,7 @@ const int REFRESH_RATE = 100;
|
|||||||
const int OVERLAY_SHOW_TIME = 500;
|
const int OVERLAY_SHOW_TIME = 500;
|
||||||
const int BORDER_OFFSET = 12;
|
const int BORDER_OFFSET = 12;
|
||||||
const int TOP_RIGHT_BORDER_OFFSET = 40;
|
const int TOP_RIGHT_BORDER_OFFSET = 40;
|
||||||
|
std::wstring cached_position = L"";
|
||||||
|
|
||||||
Toolbar::Toolbar()
|
Toolbar::Toolbar()
|
||||||
{
|
{
|
||||||
@@ -43,6 +45,44 @@ void Toolbar::scheduleGeneralSettingsUpdate()
|
|||||||
generalSettingsUpdateScheduled = true;
|
generalSettingsUpdateScheduled = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline POINT calculateToolbarPositioning(Box const& screenSize, std::wstring& position, const int desiredWidth, const int desiredHeight)
|
||||||
|
{
|
||||||
|
POINT p;
|
||||||
|
p.x = p.y = 0;
|
||||||
|
|
||||||
|
if (position == L"Top left corner")
|
||||||
|
{
|
||||||
|
p.x = screenSize.left() + BORDER_OFFSET;
|
||||||
|
p.y = screenSize.top() + BORDER_OFFSET;
|
||||||
|
}
|
||||||
|
else if (position == L"Top center")
|
||||||
|
{
|
||||||
|
p.x = screenSize.middle().x - desiredWidth / 2;
|
||||||
|
p.y = screenSize.top() + BORDER_OFFSET;
|
||||||
|
}
|
||||||
|
else if (position == L"Bottom left corner")
|
||||||
|
{
|
||||||
|
p.x = screenSize.left() + BORDER_OFFSET;
|
||||||
|
p.y = screenSize.bottom() - desiredHeight - BORDER_OFFSET;
|
||||||
|
}
|
||||||
|
else if (position == L"Bottom center")
|
||||||
|
{
|
||||||
|
p.x = screenSize.middle().x - desiredWidth / 2;
|
||||||
|
p.y = screenSize.bottom() - desiredHeight - BORDER_OFFSET;
|
||||||
|
}
|
||||||
|
else if (position == L"Bottom right corner")
|
||||||
|
{
|
||||||
|
p.x = screenSize.right() - desiredWidth - BORDER_OFFSET;
|
||||||
|
p.y = screenSize.bottom() - desiredHeight - BORDER_OFFSET;
|
||||||
|
}
|
||||||
|
else //"Top right corner" or non-present
|
||||||
|
{
|
||||||
|
p.x = screenSize.right() - desiredWidth - BORDER_OFFSET;
|
||||||
|
p.y = screenSize.top() + TOP_RIGHT_BORDER_OFFSET;
|
||||||
|
}
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
|
||||||
LRESULT Toolbar::WindowProcessMessages(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam)
|
LRESULT Toolbar::WindowProcessMessages(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam)
|
||||||
{
|
{
|
||||||
switch (msg)
|
switch (msg)
|
||||||
@@ -53,8 +93,10 @@ LRESULT Toolbar::WindowProcessMessages(HWND hwnd, UINT msg, WPARAM wparam, LPARA
|
|||||||
{
|
{
|
||||||
int x = GET_X_LPARAM(lparam);
|
int x = GET_X_LPARAM(lparam);
|
||||||
int y = GET_Y_LPARAM(lparam);
|
int y = GET_Y_LPARAM(lparam);
|
||||||
|
UINT dpi = DPIAware::DEFAULT_DPI;
|
||||||
|
DPIAware::GetScreenDPIForWindow(hwnd, dpi);
|
||||||
|
|
||||||
if (x < 322 / 2)
|
if (x < 322 * static_cast<int>(dpi) / static_cast<int>(DPIAware::DEFAULT_DPI) / 2)
|
||||||
{
|
{
|
||||||
VideoConferenceModule::reverseMicrophoneMute();
|
VideoConferenceModule::reverseMicrophoneMute();
|
||||||
}
|
}
|
||||||
@@ -65,11 +107,41 @@ LRESULT Toolbar::WindowProcessMessages(HWND hwnd, UINT msg, WPARAM wparam, LPARA
|
|||||||
|
|
||||||
return DefWindowProcW(hwnd, msg, wparam, lparam);
|
return DefWindowProcW(hwnd, msg, wparam, lparam);
|
||||||
}
|
}
|
||||||
|
case WM_DPICHANGED:
|
||||||
|
{
|
||||||
|
UINT dpi = LOWORD(dpi);
|
||||||
|
RECT* prcNewWindow = reinterpret_cast<RECT*>(lparam);
|
||||||
|
|
||||||
|
POINT suggestedPosition;
|
||||||
|
suggestedPosition.x = prcNewWindow->left;
|
||||||
|
suggestedPosition.y = prcNewWindow->top;
|
||||||
|
|
||||||
|
int desiredWidth = prcNewWindow->right - prcNewWindow->left;
|
||||||
|
int desiredHeight = prcNewWindow->bottom - prcNewWindow->top;
|
||||||
|
|
||||||
|
HMONITOR hMonitor = MonitorFromPoint(suggestedPosition, MONITOR_DEFAULTTONEAREST);
|
||||||
|
|
||||||
|
MonitorInfo info{ hMonitor };
|
||||||
|
|
||||||
|
suggestedPosition = calculateToolbarPositioning(info.GetScreenSize(false), cached_position, desiredWidth, desiredHeight);
|
||||||
|
|
||||||
|
SetWindowPos(hwnd,
|
||||||
|
NULL,
|
||||||
|
suggestedPosition.x,
|
||||||
|
suggestedPosition.y,
|
||||||
|
desiredWidth,
|
||||||
|
desiredHeight,
|
||||||
|
SWP_NOZORDER | SWP_NOACTIVATE);
|
||||||
|
return DefWindowProcW(hwnd, msg, wparam, lparam);
|
||||||
|
}
|
||||||
case WM_CREATE:
|
case WM_CREATE:
|
||||||
case WM_PAINT:
|
case WM_PAINT:
|
||||||
{
|
{
|
||||||
PAINTSTRUCT ps;
|
PAINTSTRUCT ps;
|
||||||
HDC hdc;
|
HDC hdc;
|
||||||
|
UINT dpi = DPIAware::DEFAULT_DPI;
|
||||||
|
|
||||||
|
DPIAware::GetScreenDPIForWindow(hwnd, dpi);
|
||||||
|
|
||||||
hdc = BeginPaint(hwnd, &ps);
|
hdc = BeginPaint(hwnd, &ps);
|
||||||
|
|
||||||
@@ -119,7 +191,8 @@ LRESULT Toolbar::WindowProcessMessages(HWND hwnd, UINT msg, WPARAM wparam, LPARA
|
|||||||
toolbarImage = themeImages->camOnMicOn;
|
toolbarImage = themeImages->camOnMicOn;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
graphic.DrawImage(toolbarImage, 0, 0, toolbarImage->GetWidth(), toolbarImage->GetHeight());
|
// Images are scaled by 4 to support higher dpi values.
|
||||||
|
graphic.DrawImage(toolbarImage, 0, 0, toolbarImage->GetWidth() / 4 * dpi / DPIAware::DEFAULT_DPI, toolbarImage->GetHeight() / 4 * dpi / DPIAware::DEFAULT_DPI);
|
||||||
|
|
||||||
EndPaint(hwnd, &ps);
|
EndPaint(hwnd, &ps);
|
||||||
break;
|
break;
|
||||||
@@ -194,14 +267,16 @@ LRESULT Toolbar::WindowProcessMessages(HWND hwnd, UINT msg, WPARAM wparam, LPARA
|
|||||||
|
|
||||||
void Toolbar::show(std::wstring position, std::wstring monitorString)
|
void Toolbar::show(std::wstring position, std::wstring monitorString)
|
||||||
{
|
{
|
||||||
|
cached_position = position;
|
||||||
for (auto& hwnd : hwnds)
|
for (auto& hwnd : hwnds)
|
||||||
{
|
{
|
||||||
PostMessageW(hwnd, WM_CLOSE, 0, 0);
|
PostMessageW(hwnd, WM_CLOSE, 0, 0);
|
||||||
}
|
}
|
||||||
hwnds.clear();
|
hwnds.clear();
|
||||||
|
|
||||||
int overlayWidth = darkImages.camOffMicOff->GetWidth();
|
// Images are scaled by 4 to support higher dpi values.
|
||||||
int overlayHeight = darkImages.camOffMicOff->GetHeight();
|
int overlayWidth = darkImages.camOffMicOff->GetWidth() / 4;
|
||||||
|
int overlayHeight = darkImages.camOffMicOff->GetHeight() / 4;
|
||||||
|
|
||||||
// Register the window class
|
// Register the window class
|
||||||
LPCWSTR CLASS_NAME = L"MuteNotificationWindowClass";
|
LPCWSTR CLASS_NAME = L"MuteNotificationWindowClass";
|
||||||
@@ -231,39 +306,13 @@ void Toolbar::show(std::wstring position, std::wstring monitorString)
|
|||||||
for (auto& monitorInfo : monitorInfos)
|
for (auto& monitorInfo : monitorInfos)
|
||||||
{
|
{
|
||||||
const auto screenSize = monitorInfo.GetScreenSize(false);
|
const auto screenSize = monitorInfo.GetScreenSize(false);
|
||||||
int positionX = 0;
|
UINT dpi = DPIAware::DEFAULT_DPI;
|
||||||
int positionY = 0;
|
DPIAware::GetScreenDPIForMonitor(monitorInfo.GetHandle(), dpi);
|
||||||
|
|
||||||
if (position == L"Top left corner")
|
int scaledOverlayWidth = overlayWidth * dpi / DPIAware::DEFAULT_DPI;
|
||||||
{
|
int scaledOverlayHeight = overlayHeight * dpi / DPIAware::DEFAULT_DPI;
|
||||||
positionX = screenSize.left() + BORDER_OFFSET;
|
|
||||||
positionY = screenSize.top() + BORDER_OFFSET;
|
POINT p = calculateToolbarPositioning(screenSize, position, scaledOverlayWidth, scaledOverlayHeight);
|
||||||
}
|
|
||||||
else if (position == L"Top center")
|
|
||||||
{
|
|
||||||
positionX = screenSize.middle().x - overlayWidth / 2;
|
|
||||||
positionY = screenSize.top() + BORDER_OFFSET;
|
|
||||||
}
|
|
||||||
else if (position == L"Bottom left corner")
|
|
||||||
{
|
|
||||||
positionX = screenSize.left() + BORDER_OFFSET;
|
|
||||||
positionY = screenSize.bottom() - overlayHeight - BORDER_OFFSET;
|
|
||||||
}
|
|
||||||
else if (position == L"Bottom center")
|
|
||||||
{
|
|
||||||
positionX = screenSize.middle().x - overlayWidth / 2;
|
|
||||||
positionY = screenSize.bottom() - overlayHeight - BORDER_OFFSET;
|
|
||||||
}
|
|
||||||
else if (position == L"Bottom right corner")
|
|
||||||
{
|
|
||||||
positionX = screenSize.right() - overlayWidth - BORDER_OFFSET;
|
|
||||||
positionY = screenSize.bottom() - overlayHeight - BORDER_OFFSET;
|
|
||||||
}
|
|
||||||
else //"Top right corner" or non-present
|
|
||||||
{
|
|
||||||
positionX = screenSize.right() - overlayWidth - BORDER_OFFSET;
|
|
||||||
positionY = screenSize.top() + TOP_RIGHT_BORDER_OFFSET;
|
|
||||||
}
|
|
||||||
|
|
||||||
HWND hwnd;
|
HWND hwnd;
|
||||||
hwnd = CreateWindowExW(
|
hwnd = CreateWindowExW(
|
||||||
@@ -271,10 +320,10 @@ void Toolbar::show(std::wstring position, std::wstring monitorString)
|
|||||||
CLASS_NAME,
|
CLASS_NAME,
|
||||||
CLASS_NAME,
|
CLASS_NAME,
|
||||||
WS_POPUP,
|
WS_POPUP,
|
||||||
positionX,
|
static_cast<int>(p.x),
|
||||||
positionY,
|
static_cast<int>(p.y),
|
||||||
overlayWidth,
|
scaledOverlayWidth,
|
||||||
overlayHeight,
|
scaledOverlayHeight,
|
||||||
nullptr,
|
nullptr,
|
||||||
nullptr,
|
nullptr,
|
||||||
GetModuleHandleW(nullptr),
|
GetModuleHandleW(nullptr),
|
||||||
|
|||||||