月度归档:2025年02月

苹果系统UTM指定版本安装

只有一台MacMiniM1的系统,如何在虚拟机安装多个MacOS版本

在MacOS系统上,支持M1的虚拟化的有VMWare FussionParallels Desktop以及开源版本UTM

前者不支持在MacOS内部再虚拟化MacOS系统,PD没有安装验证。

UTM支持MacOS系统,但要求Mac12+系统的虚拟化。

在苹果官网上,不支持MacOS11以上的系统ipsw文件下载,线上国内也很少相关的下载。

国外专门有人提供了所有Mac的系统下载。https://ipsw.me/

因此我选择MacOS12.1的版本下载:
https://updates.cdn-apple.com/2021FCSWinter/fullrestores/002-42433/F3F6D5CD-67FE-449C-9212-F7409808B6C4/UniversalMac_12.1_21C52_Restore.ipsw
https://updates.cdn-apple.com/2022FallFCS/fullrestores/012-60270/0A7F49BA-FC31-4AD9-8E45-49B1FB9128A6/UniversalMac_13.1_22C65_Restore.ipsw

Qt6.2.4在多屏显示时存在重大BUG

这是Qt6.2.4版本的多屏代码,在同一品牌和同一型号时会存在BUG.
以下是Qt6.2.3的代码,经检查Qt5.15.2/Qt6.2.5/Qt6.8.2都不会存在该BUG

static bool monitorData(HMONITOR hMonitor, QWindowsScreenData *data)
{
    MONITORINFOEX info;
    memset(&info, 0, sizeof(MONITORINFOEX));
    info.cbSize = sizeof(MONITORINFOEX);
    if (GetMonitorInfo(hMonitor, &info) == FALSE)
        return false;

    data->hMonitor = hMonitor;
    data->geometry = QRect(QPoint(info.rcMonitor.left, info.rcMonitor.top), QPoint(info.rcMonitor.right - 1, info.rcMonitor.bottom - 1));
    data->availableGeometry = QRect(QPoint(info.rcWork.left, info.rcWork.top), QPoint(info.rcWork.right - 1, info.rcWork.bottom - 1));
》》》》》
  问题在这行开始,它通过getPathInfo()获取一个友名,然后如果是相同品牌且同一型号时,其友名是相同的。从而导致data->name被初始化为友名。
    DISPLAYCONFIG_PATH_INFO pathInfo = {};
    const bool hasPathInfo = getPathInfo(info, &pathInfo);
    if (hasPathInfo) {
        DISPLAYCONFIG_TARGET_DEVICE_NAME deviceName = {};
        deviceName.header.type = DISPLAYCONFIG_DEVICE_INFO_GET_TARGET_NAME;
        deviceName.header.size = sizeof(DISPLAYCONFIG_TARGET_DEVICE_NAME);
        deviceName.header.adapterId = pathInfo.targetInfo.adapterId;
        deviceName.header.id = pathInfo.targetInfo.id;
        if (DisplayConfigGetDeviceInfo(&deviceName.header) == ERROR_SUCCESS)
            data->name = QString::fromWCharArray(deviceName.monitorFriendlyDeviceName);
    }
    if (data->name.isEmpty())
        data->name = QString::fromWCharArray(info.szDevice);


《《《《《《
    if (wcscmp(info.szDevice, L"WinDisc") == 0) {
        data->flags |= QWindowsScreenData::LockScreen;
    } else {
        if (const HDC hdc = CreateDC(info.szDevice, nullptr, nullptr, nullptr)) {
            const QDpi dpi = monitorDPI(hMonitor);
            data->dpi = dpi.first > 0 ? dpi : deviceDPI(hdc);
            data->depth = GetDeviceCaps(hdc, BITSPIXEL);
            data->format = data->depth == 16 ? QImage::Format_RGB16 : QImage::Format_RGB32;
            data->physicalSizeMM = QSizeF(GetDeviceCaps(hdc, HORZSIZE), GetDeviceCaps(hdc, VERTSIZE));
            const int refreshRate = GetDeviceCaps(hdc, VREFRESH);
            if (refreshRate > 1) // 0,1 means hardware default.
                data->refreshRateHz = refreshRate;
            DeleteDC(hdc);
        } else {
            qWarning("%s: Unable to obtain handle for monitor '%s', defaulting to %g DPI.",
                     __FUNCTION__, qPrintable(QString::fromWCharArray(info.szDevice)),
                     data->dpi.first);
        } // CreateDC() failed
    } // not lock screen

以下是Qt6.2.3的代码,经检查Qt5.15.2/Qt6.2.5/Qt6.8.2都不会存在该BUG:

static bool monitorData(HMONITOR hMonitor, QWindowsScreenData *data)
{
    MONITORINFOEX info;
    memset(&info, 0, sizeof(MONITORINFOEX));
    info.cbSize = sizeof(MONITORINFOEX);
    if (GetMonitorInfo(hMonitor, &info) == FALSE)
        return false;

    data->hMonitor = hMonitor;
    data->geometry = QRect(QPoint(info.rcMonitor.left, info.rcMonitor.top), QPoint(info.rcMonitor.right - 1, info.rcMonitor.bottom - 1));
    data->availableGeometry = QRect(QPoint(info.rcWork.left, info.rcWork.top), QPoint(info.rcWork.right - 1, info.rcWork.bottom - 1));
    data->name = QString::fromWCharArray(info.szDevice);
    if (data->name == u"WinDisc") {
        data->flags |= QWindowsScreenData::LockScreen;
    } else {
        if (const HDC hdc = CreateDC(info.szDevice, nullptr, nullptr, nullptr)) {
            const QDpi dpi = monitorDPI(hMonitor);
            data->dpi = dpi.first > 0 ? dpi : deviceDPI(hdc);
            data->depth = GetDeviceCaps(hdc, BITSPIXEL);
            data->format = data->depth == 16 ? QImage::Format_RGB16 : QImage::Format_RGB32;
            data->physicalSizeMM = QSizeF(GetDeviceCaps(hdc, HORZSIZE), GetDeviceCaps(hdc, VERTSIZE));
            const int refreshRate = GetDeviceCaps(hdc, VREFRESH);
            if (refreshRate > 1) // 0,1 means hardware default.
                data->refreshRateHz = refreshRate;
            DeleteDC(hdc);
        } else {
            qWarning("%s: Unable to obtain handle for monitor '%s', defaulting to %g DPI.",
                     __FUNCTION__, qPrintable(QString::fromWCharArray(info.szDevice)),
                     data->dpi.first);
        } // CreateDC() failed
    } // not lock screen

安装VS2019

线上只有VS2022的安装下载,而VS2019(Visual studio 2019)版本已经被隐藏起来了,如何找出来呢?

https://learn.microsoft.com/zh-cn/visualstudio/releases/2019/history

在fedora30下安装Qt6.2.4遇到的问题

一、安装编译环境

sudo dnf groupinstall "development tools"
sudo dnf install g++ libxkbcommon-devel libxkbcommon-x11-devel

二、安装Qt6.2.4

./qt-unified-linux-x64-online.run --mirror http://mirrors.ustc.edu.cn/qtproject/
若无法启动,可能需要安装xcb以下:
sudo dnf install xcb-util-cursor xcb-util-cursor-devel 

三、配置cmake环境变量

export PATH=/home/abc/Qt/Tools/CMake/bin:$PATH