/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ /* vim: set ts=8 sts=2 et sw=2 tw=80: */ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
// borrowed from devblogs.microsoft.com/oldnewthing/20041025-00/?p=37483, by way // of the Chromium sandboxing code's "current_module.h" extern"C" IMAGE_DOS_HEADER __ImageBase; #define CURRENT_MODULE() reinterpret_cast<HMODULE>(&__ImageBase)
if (sHiddenWindow) return; if (sHiddenWindowShutdown) return;
HMODULE const hSelf = CURRENT_MODULE();
WNDCLASSW const wc = {.lpfnWndProc = WinEventWindow::WndProc,
.hInstance = hSelf,
.lpszClassName = kClassNameHidden};
ATOM const atom = ::RegisterClassW(&wc); if (!atom) { // This is known to be possible when the atom table no longer has free // entries, which unfortunately happens more often than one might expect. // See bug 1571516. autovolatileconst err [[maybe_unused]] = ::GetLastError();
MOZ_CRASH("could not register broadcast-receiver window-class");
}
// It should be harmless to leak this window until destruction -- but other // parts of Gecko may expect all windows to be destroyed, so do that.
mozilla::RunOnShutdown([]() {
InputDeviceUtils::UnregisterNotification(sDeviceNotifyHandle);
// Callbacks for individual event types. These are private and internal // implementation details of WinEventWindow. namespace { namespace evtwin_details {
staticvoid OnSessionChange(WPARAM wParam, LPARAM lParam) { if (wParam == WTS_SESSION_LOCK || wParam == WTS_SESSION_UNLOCK) {
DWORD currentSessionId; BOOLconst rv =
::ProcessIdToSessionId(::GetCurrentProcessId(), ¤tSessionId); if (!rv) { // A process should always have the relevant access privileges for itself, // but the above call could still fail if, e.g., someone's playing games // with function imports. If so, just assert and/or skip out. // // Should this turn out to somehow be a real concern, we could do // ``` // DWORD const currentSessionId = // ::NtCurrentTeb()->ProcessEnvironmentBlock->SessionId; // ``` // instead, which is actually documented (albeit abjured against).
MOZ_ASSERT(false, "::ProcessIdToSessionId() failed"); return;
}
// Ignore lock/unlock messages for other sessions -- which Windows actually // _does_ send in some scenarios; see review of Chromium changeset 1929489: // // https://chromium-review.googlesource.com/c/chromium/src/+/1929489 if (currentSessionId != (DWORD)lParam) { return;
}
if (auto* wwot = WinWindowOcclusionTracker::Get()) {
wwot->OnSessionChange(wParam);
}
}
}
staticvoid OnSettingsChange(WPARAM wParam, LPARAM lParam) { switch (wParam) { case SPI_SETCLIENTAREAANIMATION: case SPI_SETKEYBOARDDELAY: case SPI_SETMOUSEVANISH: case MOZ_SPI_SETCURSORSIZE: // These need to update LookAndFeel cached values. // // They affect reduced motion settings / caret blink count / show pointer // while typing / tooltip offset, so no need to invalidate style / layout.
NotifyThemeChanged(widget::ThemeChangeKind::MediaQueriesOnly); return;
case SPI_SETFONTSMOOTHING: case SPI_SETFONTSMOOTHINGTYPE:
gfxDWriteFont::UpdateSystemTextVars(); return;
case SPI_SETWORKAREA: // NB: We also refresh screens on WM_DISPLAYCHANGE, but the rcWork // values are sometimes wrong at that point. This message then arrives // soon afterward, when we can get the right rcWork values.
ScreenHelperWin::RefreshScreens(); return;
default: break;
}
if (lParam == 0) { return;
}
nsDependentString lParamString{reinterpret_cast<constwchar_t*>(lParam)};
if (lParamString == u"ImmersiveColorSet"_ns) { // This affects system colors (-moz-win-accentcolor), so gotta pass the // style flag.
NotifyThemeChanged(widget::ThemeChangeKind::Style); return;
}
// UserInteractionMode, ConvertibleSlateMode, and SystemDockMode may cause // @media(pointer) queries to change, which layout needs to know about. // // The former two of those also imply that the current tablet-mode state needs // to be updated.
if (lParamString == u"UserInteractionMode"_ns) { // Documentation implies, and testing shows, that this is seen on Win10 // only.
Unused << NS_WARN_IF(mozilla::IsWin11OrLater());
WindowsUIUtils::UpdateInWin10TabletMode();
NotifyThemeChanged(widget::ThemeChangeKind::MediaQueriesOnly); return;
}
if (lParamString == u"ConvertibleSlateMode"_ns) { // Documentation implies, and testing shows, that this is not seen on Win10.
Unused << NS_WARN_IF(!mozilla::IsWin11OrLater());
WindowsUIUtils::UpdateInWin11TabletMode();
NotifyThemeChanged(widget::ThemeChangeKind::MediaQueriesOnly); return;
}
if (lParamString == u"SystemDockMode"_ns) {
NotifyThemeChanged(widget::ThemeChangeKind::MediaQueriesOnly); return;
}
}
staticvoid OnDeviceChange(WPARAM wParam, LPARAM lParam) { if (wParam == DBT_DEVICEARRIVAL || wParam == DBT_DEVICEREMOVECOMPLETE) {
DEV_BROADCAST_HDR* hdr = reinterpret_cast<DEV_BROADCAST_HDR*>(lParam); // Check dbch_devicetype explicitly since we will get other device types // (e.g. DBT_DEVTYP_VOLUME) for some reason, even if we specify // DBT_DEVTYP_DEVICEINTERFACE in the filter for RegisterDeviceNotification. if (hdr->dbch_devicetype == DBT_DEVTYP_DEVICEINTERFACE) { // This can only change media queries (any-hover/any-pointer).
NotifyThemeChanged(widget::ThemeChangeKind::MediaQueriesOnly);
}
}
}
switch (msg) { case WM_WINDOWPOSCHANGING: { // prevent rude external programs from making hidden window visible
LPWINDOWPOS info = (LPWINDOWPOS)lParam;
info->flags &= ~SWP_SHOWWINDOW;
} break;
case WM_WTSSESSION_CHANGE: {
evtwin_details::OnSessionChange(wParam, lParam);
} break;
case WM_POWERBROADCAST: {
evtwin_details::OnPowerBroadcast(wParam, lParam);
} break;
case WM_SYSCOLORCHANGE: { // No need to invalidate layout for system color changes, but we need to // invalidate style.
evtwin_details::NotifyThemeChanged(widget::ThemeChangeKind::Style);
} break;
case WM_THEMECHANGED: { // We assume pretty much everything could've changed here.
evtwin_details::NotifyThemeChanged(
widget::ThemeChangeKind::StyleAndLayout);
} break;
case WM_FONTCHANGE: { // update the global font list
gfxPlatform::GetPlatform()->UpdateFontList();
} break;
case WM_SETTINGCHANGE: {
evtwin_details::OnSettingsChange(wParam, lParam);
} break;
case WM_DEVICECHANGE: {
evtwin_details::OnDeviceChange(wParam, lParam);
} break;
case WM_DISPLAYCHANGE: {
ScreenHelperWin::RefreshScreens(); break;
}
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung ist noch experimentell.