Files
obs-studio/plugins/obs-vst/win/EditorWidget-win.cpp
xlinshan 542cb876dc obs-vst: Fix incorrect VST window size on HiDPI display
On Windows, the VST plugins' window sizes are rendered larger than the
actual content on displays that have UI scale factor. The sizes are
larger by the scale factor, for example, 100x100 content will have a
200x200 window on a 200% scaled screen, and 150x150 on a 150% scaled
screen. This change adjust the window size to fit the content size.
2023-12-09 11:30:39 +11:00

92 lines
3.3 KiB
C++

/*****************************************************************************
Copyright (C) 2016-2017 by Colin Edwards.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*****************************************************************************/
#include <QGridLayout>
#include "../headers/EditorWidget.h"
void EditorWidget::buildEffectContainer(AEffect *effect)
{
WNDCLASSEXW wcex{sizeof(wcex)};
wcex.lpfnWndProc = DefWindowProcW;
wcex.hInstance = GetModuleHandleW(nullptr);
wcex.lpszClassName = L"Minimal VST host - Guest VST Window Frame";
RegisterClassExW(&wcex);
const auto style = WS_CAPTION | WS_THICKFRAME | WS_OVERLAPPEDWINDOW;
windowHandle = CreateWindowW(wcex.lpszClassName, TEXT(""), style, 0, 0,
0, 0, nullptr, nullptr, nullptr, nullptr);
// set pointer to vst effect for window long
LONG_PTR wndPtr = (LONG_PTR)effect;
SetWindowLongPtr(windowHandle, -21 /*GWLP_USERDATA*/, wndPtr);
QWidget *widget = QWidget::createWindowContainer(
QWindow::fromWinId((WId)windowHandle), nullptr);
widget->move(0, 0);
QGridLayout *layout = new QGridLayout();
layout->setContentsMargins(0, 0, 0, 0);
layout->setSpacing(0);
setLayout(layout);
layout->addWidget(widget);
effect->dispatcher(effect, effEditOpen, 0, 0, windowHandle, 0);
VstRect *vstRect = nullptr;
effect->dispatcher(effect, effEditGetRect, 0, 0, &vstRect, 0);
if (vstRect) {
// on Windows, the size reported by 'effect' is larger than
// its actuall size by a factor of the monitor's ui scale,
// so the window size should be divided by the factor
qreal scale_factor = devicePixelRatioF();
int width = vstRect->right - vstRect->left;
int height = vstRect->bottom - vstRect->top;
width = static_cast<int>(width / scale_factor);
height = static_cast<int>(height / scale_factor);
widget->resize(width, height);
resize(width, height);
} else {
widget->resize(300, 300);
}
}
void EditorWidget::handleResizeRequest(int, int)
{
// Some plugins can't resize automatically (like SPAN by Voxengo),
// so we must resize window manually
// get pointer to vst effect from window long
LONG_PTR wndPtr = (LONG_PTR)GetWindowLongPtrW(windowHandle,
-21 /*GWLP_USERDATA*/);
AEffect *effect = (AEffect *)(wndPtr);
VstRect *rec = nullptr;
effect->dispatcher(effect, effEditGetRect, 0, 0, &rec, 0);
if (rec) {
// on Windows, the size reported by 'effect' is larger than
// its actuall size by a factor of the monitor's ui scale,
// so the window size should be divided by the factor
qreal scale_factor = devicePixelRatioF();
int width = rec->right - rec->left;
int height = rec->bottom - rec->top;
width = static_cast<int>(width / scale_factor);
height = static_cast<int>(height / scale_factor);
resize(width, height);
}
}