Skip to content

Conform Per-Monitor DPI v2 protocol in Windows #831

Open
4 of 4 issues completed
Open

Description

@yukawa

Description

Currently Mozc binaries fall into System DPI Awareness category in Windows.

We'd like to make them run under Per-Monitor v2 Awareness mode.

Version or commit-id

af20906

Environment

  • OS: Windows 11 22H2

Additional Context

src/gui/tool/mozc_tool.exe.manifest

<asmv3:windowsSettings xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">
<dpiAware>true</dpiAware>
</asmv3:windowsSettings>

Needs PerMonitorV2 declaration.

      <dpiAwareness xmlns="http://schemas.microsoft.com/SMI/2016/WindowsSettings">PerMonitorV2</dpiAwareness>

Also, it'd be safer to switch to Qt 6.6 or later version, which contains qt/qtbase@5e0d9a0.


src/renderer/win32/mozc_renderer.exe.manifest

<asmv3:windowsSettings xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">
<dpiAware>true</dpiAware>
</asmv3:windowsSettings>

Needs PerMonitorV2 declaration.

      <dpiAwareness xmlns="http://schemas.microsoft.com/SMI/2016/WindowsSettings">PerMonitorV2</dpiAwareness>

src/renderer/win32/indicator_window.cc

double GetDPIScaling() {
CDC desktop_dc(::GetDC(nullptr));
const int dpi_x = desktop_dc.GetDeviceCaps(LOGPIXELSX);
return static_cast<double>(dpi_x) / kDefaultDPI;
}

We can no longer assume this is a runtime constant.

BEGIN_MSG_MAP_EX(WindowImpl)
MSG_WM_CREATE(OnCreate)
MSG_WM_TIMER(OnTimer)
MSG_WM_SETTINGCHANGE(OnSettingChange)
END_MSG_MAP()

We also need to handle WM_DPICHANGED.


src/renderer/win32/candidate_window.h

BEGIN_MSG_MAP_EX(CandidateWindow)
MSG_WM_CREATE(OnCreate)
MSG_WM_DESTROY(OnDestroy)
MSG_WM_ERASEBKGND(OnEraseBkgnd)
MSG_WM_GETMINMAXINFO(OnGetMinMaxInfo)
MSG_WM_LBUTTONDOWN(OnLButtonDown)
MSG_WM_LBUTTONUP(OnLButtonUp)
MSG_WM_MOUSEMOVE(OnMouseMove)
MSG_WM_SETTINGCHANGE(OnSettingChange)
MSG_WM_PAINT(OnPaint)
MSG_WM_PRINTCLIENT(OnPrintClient)
END_MSG_MAP()

We also need to handle WM_DPICHANGED.


src/renderer/win32/candidate_window.cc

double scale_factor_x = 1.0;
double scale_factor_y = 1.0;
RendererStyleHandler::GetDPIScalingFactor(&scale_factor_x, &scale_factor_y);
double image_scale_factor = 1.0;
if (scale_factor_x < 1.125 || scale_factor_y < 1.125) {
footer_logo_.Attach(LoadBitmapFromResource(::GetModuleHandle(nullptr),
IDB_FOOTER_LOGO_COLOR_100));
image_scale_factor = 1.0;
} else if (scale_factor_x < 1.375 || scale_factor_y < 1.375) {
footer_logo_.Attach(LoadBitmapFromResource(::GetModuleHandle(nullptr),
IDB_FOOTER_LOGO_COLOR_125));
image_scale_factor = 1.25;
} else if (scale_factor_x < 1.75 || scale_factor_y < 1.75) {
footer_logo_.Attach(LoadBitmapFromResource(::GetModuleHandle(nullptr),
IDB_FOOTER_LOGO_COLOR_150));
image_scale_factor = 1.5;
} else {
footer_logo_.Attach(LoadBitmapFromResource(::GetModuleHandle(nullptr),
IDB_FOOTER_LOGO_COLOR_200));
image_scale_factor = 2.0;
}
// If DPI is not default value, re-calculate the size based on the DPI.
if (!footer_logo_.IsNull()) {
CSize size;
footer_logo_.GetSize(size);
size.cx *= (scale_factor_x / image_scale_factor);
size.cy *= (scale_factor_y / image_scale_factor);
footer_logo_display_size_ = Size(size.cx, size.cy);
}
indicator_width_ = kIndicatorWidthInDefaultDPI * scale_factor_x;

scale_factor_x and scale_factor_y are no longer the runtime constants. We need to re-calculate these values every time WM_DPICHANGED is received.


src/win32/tip/tip_lang_bar_menu.cc

LoadIconFromResource should use GetSystemMetricsForDpi with primary display's DPI no matter which display is used to show the application, because the IME mode icon is shown only on the primary display.

HICON LoadIconFromResource(HINSTANCE instance, UINT icon_id) {
const auto icon_size = ::GetSystemMetrics(SM_CYSMICON);
// Replace some text icons with on-the-fly image drawn with MS-Gothic.
const auto &icon_text = GetIconStringIfNecessary(icon_id);
if (!icon_text.empty()) {
const COLORREF text_color = ::GetSysColor(COLOR_WINDOWTEXT);
return TextIcon::CreateMonochromeIcon(icon_size, icon_size, icon_text,
kTextIconFont, text_color);
}
return static_cast<HICON>(::LoadImage(instance, MAKEINTRESOURCE(icon_id),
IMAGE_ICON, icon_size, icon_size,
LR_CREATEDIBSECTION));
}

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions