summaryrefslogtreecommitdiffstats
path: root/widget/windows
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-19 01:14:29 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-19 01:14:29 +0000
commitfbaf0bb26397aa498eb9156f06d5a6fe34dd7dd8 (patch)
tree4c1ccaf5486d4f2009f9a338a98a83e886e29c97 /widget/windows
parentReleasing progress-linux version 124.0.1-1~progress7.99u1. (diff)
downloadfirefox-fbaf0bb26397aa498eb9156f06d5a6fe34dd7dd8.tar.xz
firefox-fbaf0bb26397aa498eb9156f06d5a6fe34dd7dd8.zip
Merging upstream version 125.0.1.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'widget/windows')
-rw-r--r--widget/windows/GfxInfo.cpp69
-rw-r--r--widget/windows/JumpListBuilder.cpp12
-rw-r--r--widget/windows/JumpListBuilder.h2
-rw-r--r--widget/windows/WinTaskbar.cpp5
-rw-r--r--widget/windows/WindowsSMTCProvider.cpp179
-rw-r--r--widget/windows/WindowsSMTCProvider.h12
-rw-r--r--widget/windows/filedialog/WinFileDialogChild.cpp7
-rw-r--r--widget/windows/filedialog/WinFileDialogCommands.cpp2
-rw-r--r--widget/windows/nsFilePicker.cpp14
-rw-r--r--widget/windows/nsFilePicker.h6
-rw-r--r--widget/windows/nsLookAndFeel.cpp3
-rw-r--r--widget/windows/nsWindow.cpp136
-rw-r--r--widget/windows/nsWindow.h4
13 files changed, 340 insertions, 111 deletions
diff --git a/widget/windows/GfxInfo.cpp b/widget/windows/GfxInfo.cpp
index 6f033785f5..0e1b4002d3 100644
--- a/widget/windows/GfxInfo.cpp
+++ b/widget/windows/GfxInfo.cpp
@@ -1092,25 +1092,20 @@ void GfxInfo::AddCrashReportAnnotations() {
}
nsString deviceID, vendorID, driverVersion, subsysID;
- nsCString narrowDeviceID, narrowVendorID, narrowDriverVersion, narrowSubsysID;
GetAdapterDeviceID(deviceID);
- CopyUTF16toUTF8(deviceID, narrowDeviceID);
GetAdapterVendorID(vendorID);
- CopyUTF16toUTF8(vendorID, narrowVendorID);
GetAdapterDriverVersion(driverVersion);
- CopyUTF16toUTF8(driverVersion, narrowDriverVersion);
GetAdapterSubsysID(subsysID);
- CopyUTF16toUTF8(subsysID, narrowSubsysID);
- CrashReporter::AnnotateCrashReport(CrashReporter::Annotation::AdapterVendorID,
- narrowVendorID);
- CrashReporter::AnnotateCrashReport(CrashReporter::Annotation::AdapterDeviceID,
- narrowDeviceID);
- CrashReporter::AnnotateCrashReport(
- CrashReporter::Annotation::AdapterDriverVersion, narrowDriverVersion);
- CrashReporter::AnnotateCrashReport(CrashReporter::Annotation::AdapterSubsysID,
- narrowSubsysID);
+ CrashReporter::RecordAnnotationNSString(
+ CrashReporter::Annotation::AdapterVendorID, vendorID);
+ CrashReporter::RecordAnnotationNSString(
+ CrashReporter::Annotation::AdapterDeviceID, deviceID);
+ CrashReporter::RecordAnnotationNSString(
+ CrashReporter::Annotation::AdapterDriverVersion, driverVersion);
+ CrashReporter::RecordAnnotationNSString(
+ CrashReporter::Annotation::AdapterSubsysID, subsysID);
/* Add an App Note, this contains extra information. */
nsAutoCString note;
@@ -1741,24 +1736,6 @@ const nsTArray<GfxDriverInfo>& GfxInfo::GetGfxDriverInfo() {
"FEATURE_UNQUALIFIED_P010_NVIDIA");
////////////////////////////////////
- // FEATURE_VIDEO_OVERLAY - ALLOWLIST
-#ifdef EARLY_BETA_OR_EARLIER
- APPEND_TO_DRIVER_BLOCKLIST2(
- OperatingSystem::Windows, DeviceFamily::All,
- nsIGfxInfo::FEATURE_VIDEO_OVERLAY, nsIGfxInfo::FEATURE_ALLOW_ALWAYS,
- DRIVER_COMPARISON_IGNORED, V(0, 0, 0, 0), "FEATURE_ROLLOUT_ALL");
-#else
- APPEND_TO_DRIVER_BLOCKLIST2(
- OperatingSystem::Windows, DeviceFamily::IntelAll,
- nsIGfxInfo::FEATURE_VIDEO_OVERLAY, nsIGfxInfo::FEATURE_ALLOW_ALWAYS,
- DRIVER_COMPARISON_IGNORED, V(0, 0, 0, 0), "FEATURE_ROLLOUT_INTEL");
- APPEND_TO_DRIVER_BLOCKLIST2(
- OperatingSystem::Windows, DeviceFamily::NvidiaAll,
- nsIGfxInfo::FEATURE_VIDEO_OVERLAY, nsIGfxInfo::FEATURE_ALLOW_ALWAYS,
- DRIVER_COMPARISON_IGNORED, V(0, 0, 0, 0), "FEATURE_ROLLOUT_NVIDIA");
-#endif
-
- ////////////////////////////////////
// FEATURE_HW_DECODED_VIDEO_ZERO_COPY
APPEND_TO_DRIVER_BLOCKLIST_RANGE(
@@ -1801,9 +1778,13 @@ const nsTArray<GfxDriverInfo>& GfxInfo::GetGfxDriverInfo() {
////////////////////////////////////
// FEATURE_HW_DECODED_VIDEO_ZERO_COPY - ALLOWLIST
-
- // XXX ZeroCopyNV12Texture is disabled with non-intel GPUs for now.
- // See Bug 1798242
+#ifdef EARLY_BETA_OR_EARLIER
+ APPEND_TO_DRIVER_BLOCKLIST2(
+ OperatingSystem::Windows, DeviceFamily::NvidiaAll,
+ nsIGfxInfo::FEATURE_HW_DECODED_VIDEO_ZERO_COPY,
+ nsIGfxInfo::FEATURE_ALLOW_ALWAYS, DRIVER_COMPARISON_IGNORED,
+ V(0, 0, 0, 0), "FEATURE_ROLLOUT_ALL");
+#endif
APPEND_TO_DRIVER_BLOCKLIST2(
OperatingSystem::Windows, DeviceFamily::IntelAll,
nsIGfxInfo::FEATURE_HW_DECODED_VIDEO_ZERO_COPY,
@@ -1828,6 +1809,26 @@ const nsTArray<GfxDriverInfo>& GfxInfo::GetGfxDriverInfo() {
"Intel driver 10.18.15.*");
////////////////////////////////////
+ // FEATURE_OVERLAY_VP_AUTO_HDR
+
+ APPEND_TO_DRIVER_BLOCKLIST(
+ OperatingSystem::Windows, DeviceFamily::NvidiaAll,
+ nsIGfxInfo::FEATURE_OVERLAY_VP_AUTO_HDR,
+ nsIGfxInfo::FEATURE_BLOCKED_DRIVER_VERSION, DRIVER_LESS_THAN_OR_EQUAL,
+ V(31, 0, 15, 5050), "FEATURE_FAILURE_VP_AUTO_HDR",
+ "nVidia driver > 550.50");
+
+ ////////////////////////////////////
+ // FEATURE_OVERLAY_VP_SUPER_RESOLUTION
+
+ APPEND_TO_DRIVER_BLOCKLIST(
+ OperatingSystem::Windows, DeviceFamily::NvidiaAll,
+ nsIGfxInfo::FEATURE_OVERLAY_VP_SUPER_RESOLUTION,
+ nsIGfxInfo::FEATURE_BLOCKED_DRIVER_VERSION, DRIVER_LESS_THAN_OR_EQUAL,
+ V(31, 0, 15, 3000), "FEATURE_FAILURE_VP_AUTO_HDR",
+ "nVidia driver > 530.00");
+
+ ////////////////////////////////////
// FEATURE_WEBRENDER
// Block 8.56.1.15/16
APPEND_TO_DRIVER_BLOCKLIST2(OperatingSystem::Windows, DeviceFamily::AtiAll,
diff --git a/widget/windows/JumpListBuilder.cpp b/widget/windows/JumpListBuilder.cpp
index 80b1c29aa7..e25c8c038f 100644
--- a/widget/windows/JumpListBuilder.cpp
+++ b/widget/windows/JumpListBuilder.cpp
@@ -176,8 +176,9 @@ JumpListBuilder::JumpListBuilder(const nsAString& aAppUserModelId,
// the app, as it is set in the package manifest instead.
if (!mozilla::widget::WinUtils::HasPackageIdentity()) {
mIOThread->Dispatch(
- NewRunnableMethod<nsString>(
- "SetAppID", this, &JumpListBuilder::DoSetAppID, aAppUserModelId),
+ NewRunnableMethod<nsString>("SetAppID", this,
+ &JumpListBuilder::DoSetAppIDIfAvailable,
+ aAppUserModelId),
NS_DISPATCH_NORMAL);
}
}
@@ -203,10 +204,13 @@ void JumpListBuilder::DoShutdownBackend() {
mJumpListBackend = nullptr;
}
-void JumpListBuilder::DoSetAppID(nsString aAppUserModelID) {
+void JumpListBuilder::DoSetAppIDIfAvailable(nsString aAppUserModelID) {
MOZ_ASSERT(!NS_IsMainThread());
MOZ_ASSERT(mJumpListBackend);
- mJumpListBackend->SetAppID(aAppUserModelID.get());
+
+ if (mJumpListBackend->IsAvailable()) {
+ mJumpListBackend->SetAppID(aAppUserModelID.get());
+ }
}
NS_IMETHODIMP
diff --git a/widget/windows/JumpListBuilder.h b/widget/windows/JumpListBuilder.h
index e228669f11..b8d5253153 100644
--- a/widget/windows/JumpListBuilder.h
+++ b/widget/windows/JumpListBuilder.h
@@ -64,7 +64,7 @@ class JumpListBuilder : public nsIJumpListBuilder, public nsIObserver {
void DoSetupBackend();
void DoSetupTestingBackend(RefPtr<JumpListBackend> aTestingBackend);
void DoShutdownBackend();
- void DoSetAppID(nsString aAppUserModelID);
+ void DoSetAppIDIfAvailable(nsString aAppUserModelID);
void DoIsAvailable(const nsMainThreadPtrHandle<dom::Promise>& aPromiseHolder);
void DoCheckForRemovals(
const nsMainThreadPtrHandle<dom::Promise>& aPromiseHolder);
diff --git a/widget/windows/WinTaskbar.cpp b/widget/windows/WinTaskbar.cpp
index 56608503da..66854f3ee2 100644
--- a/widget/windows/WinTaskbar.cpp
+++ b/widget/windows/WinTaskbar.cpp
@@ -223,6 +223,11 @@ bool WinTaskbar::GenerateAppUserModelID(nsAString& aAppUserModelId,
id.AppendInt(HashString(path));
if (!id.IsEmpty()) {
aAppUserModelId.Assign(id);
+
+ if (aPrivateBrowsing) {
+ aAppUserModelId.AppendLiteral(";PrivateBrowsingAUMID");
+ }
+
return true;
}
}
diff --git a/widget/windows/WindowsSMTCProvider.cpp b/widget/windows/WindowsSMTCProvider.cpp
index 04d833a8e7..69915cafd8 100644
--- a/widget/windows/WindowsSMTCProvider.cpp
+++ b/widget/windows/WindowsSMTCProvider.cpp
@@ -255,6 +255,25 @@ void WindowsSMTCProvider::UnregisterEvents() {
if (mControls && mButtonPressedToken.value != 0) {
mControls->remove_ButtonPressed(mButtonPressedToken);
}
+
+ if (mControls && mSeekRegistrationToken.value != 0) {
+ ComPtr<ISystemMediaTransportControls2> smtc2;
+ HRESULT hr = mControls.As(&smtc2);
+ if (FAILED(hr)) {
+ LOG("Failed to cast controls to ISystemMediaTransportControls2 (hr=%lx)",
+ hr);
+ return;
+ }
+ MOZ_ASSERT(smtc2);
+
+ hr = smtc2->remove_PlaybackPositionChangeRequested(mSeekRegistrationToken);
+ if (FAILED(hr)) {
+ LOG("SystemMediaTransportControls: Failed unregister position change "
+ "event (hr=%lx)",
+ hr);
+ return;
+ }
+ }
}
bool WindowsSMTCProvider::RegisterEvents() {
@@ -289,6 +308,48 @@ bool WindowsSMTCProvider::RegisterEvents() {
return false;
}
+ ComPtr<ISystemMediaTransportControls2> smtc2;
+ HRESULT hr = mControls.As(&smtc2);
+ if (FAILED(hr)) {
+ LOG("Failed to cast controls to ISystemMediaTransportControls2 (hr=%lx)",
+ hr);
+ return false;
+ }
+ MOZ_ASSERT(smtc2);
+
+ auto positionChangeRequested =
+ Callback<ITypedEventHandler<SystemMediaTransportControls*,
+ PlaybackPositionChangeRequestedEventArgs*>>(
+ [this, self](
+ ISystemMediaTransportControls*,
+ IPlaybackPositionChangeRequestedEventArgs* pArgs) -> HRESULT {
+ MOZ_ASSERT(pArgs);
+
+ TimeSpan value;
+ HRESULT hr = pArgs->get_RequestedPlaybackPosition(&value);
+ if (FAILED(hr)) {
+ LOG("SystemMediaTransportControls: Playback Position Change - "
+ "failed to get requested position (hr=%lx)",
+ hr);
+ return S_OK; // Propagating the error probably wouldn't help.
+ }
+
+ double position =
+ static_cast<double>(value.Duration) / (1e6 * 10.0);
+ this->OnPositionChangeRequested(position);
+
+ return S_OK;
+ });
+
+ hr = smtc2->add_PlaybackPositionChangeRequested(positionChangeRequested.Get(),
+ &mSeekRegistrationToken);
+ if (FAILED(hr)) {
+ LOG("SystemMediaTransportControls: Failed to register position change "
+ "event (hr=%lx)",
+ hr);
+ return false;
+ }
+
return true;
}
@@ -309,12 +370,14 @@ bool WindowsSMTCProvider::EnableControl(bool aEnabled) const {
return SUCCEEDED(mControls->put_IsEnabled(aEnabled));
}
-bool WindowsSMTCProvider::UpdateButtons() const {
+bool WindowsSMTCProvider::UpdateButtons() {
static const mozilla::dom::MediaControlKey kKeys[] = {
- mozilla::dom::MediaControlKey::Play, mozilla::dom::MediaControlKey::Pause,
+ mozilla::dom::MediaControlKey::Play,
+ mozilla::dom::MediaControlKey::Pause,
mozilla::dom::MediaControlKey::Previoustrack,
mozilla::dom::MediaControlKey::Nexttrack,
- mozilla::dom::MediaControlKey::Stop};
+ mozilla::dom::MediaControlKey::Stop,
+ mozilla::dom::MediaControlKey::Seekto};
bool success = true;
for (const mozilla::dom::MediaControlKey& key : kKeys) {
@@ -347,12 +410,28 @@ bool WindowsSMTCProvider::EnableKey(mozilla::dom::MediaControlKey aKey,
return SUCCEEDED(mControls->put_IsNextEnabled(aEnable));
case mozilla::dom::MediaControlKey::Stop:
return SUCCEEDED(mControls->put_IsStopEnabled(aEnable));
+ case mozilla::dom::MediaControlKey::Seekto:
+ // The callback for the event checks if the key is supported
+ return mSeekRegistrationToken.value != 0;
default:
LOG("No button for %s", ToMediaControlKeyStr(aKey));
return false;
}
}
+void WindowsSMTCProvider::OnPositionChangeRequested(double aPosition) const {
+ if (!IsKeySupported(mozilla::dom::MediaControlKey::Seekto)) {
+ LOG("Seekto is not supported");
+ return;
+ }
+
+ for (const auto& listener : mListeners) {
+ listener->OnActionPerformed(
+ mozilla::dom::MediaControlAction(mozilla::dom::MediaControlKey::Seekto,
+ mozilla::dom::SeekDetails(aPosition)));
+ }
+}
+
bool WindowsSMTCProvider::InitDisplayAndControls() {
// As Open() might be called multiple times, "cache" the results of the COM
// API
@@ -422,6 +501,100 @@ bool WindowsSMTCProvider::SetMusicMetadata(const nsString& aArtist,
return true;
}
+void WindowsSMTCProvider::SetPositionState(
+ const mozilla::Maybe<mozilla::dom::PositionState>& aState) {
+ ComPtr<ISystemMediaTransportControls2> smtc2;
+ HRESULT hr = mControls.As(&smtc2);
+ if (FAILED(hr)) {
+ LOG("Failed to cast controls to ISystemMediaTransportControls2 (hr=%lx)",
+ hr);
+ return;
+ }
+ MOZ_ASSERT(smtc2);
+
+ ComPtr<ISystemMediaTransportControlsTimelineProperties> properties;
+ hr = RoActivateInstance(
+ HStringReference(
+ RuntimeClass_Windows_Media_SystemMediaTransportControlsTimelineProperties)
+ .Get(),
+ &properties);
+ if (FAILED(hr)) {
+ LOG("Failed to create timeline properties (hr=%lx)", hr);
+ return;
+ }
+ MOZ_ASSERT(properties);
+
+ // Converts a value in seconds to a TimeSpan
+ // The TimeSpan's Duration is a value in 100ns ticks
+ // https://learn.microsoft.com/en-us/windows/win32/api/windows.foundation/ns-windows-foundation-timespan#members
+ auto toTimeSpan = [this](double seconds) {
+ constexpr double kMaxMicroseconds =
+ static_cast<double>(std::numeric_limits<LONG64>::max() / 10);
+
+ double microseconds = seconds * 1e6;
+
+ if (microseconds > kMaxMicroseconds) {
+ LOG("Failed to convert %f microseconds to TimeSpan (overflow)",
+ microseconds);
+ return TimeSpan{0};
+ }
+
+ return TimeSpan{static_cast<LONG64>(microseconds * 10.0)};
+ };
+
+ TimeSpan endTime{0};
+ TimeSpan position{0};
+ double playbackRate = 1.0;
+
+ if (aState) {
+ endTime = toTimeSpan(aState->mDuration);
+ position = toTimeSpan(aState->CurrentPlaybackPosition());
+ playbackRate = aState->mPlaybackRate;
+ }
+
+ hr = properties->put_StartTime({0});
+ if (FAILED(hr)) {
+ LOG("Failed to set the start time (hr=%lx)", hr);
+ return;
+ }
+
+ hr = properties->put_MinSeekTime({0});
+ if (FAILED(hr)) {
+ LOG("Failed to set the min seek time (hr=%lx)", hr);
+ return;
+ }
+
+ hr = properties->put_EndTime(endTime);
+ if (FAILED(hr)) {
+ LOG("Failed to set the end time (hr=%lx)", hr);
+ return;
+ }
+
+ hr = properties->put_MaxSeekTime(endTime);
+ if (FAILED(hr)) {
+ LOG("Failed to set the max seek time (hr=%lx)", hr);
+ return;
+ }
+
+ hr = properties->put_Position(position);
+ if (FAILED(hr)) {
+ LOG("Failed to set the playback position (hr=%lx)", hr);
+ return;
+ }
+
+ hr = smtc2->UpdateTimelineProperties(properties.Get());
+ if (FAILED(hr)) {
+ LOG("Failed to update timeline properties (hr=%lx)", hr);
+ return;
+ }
+
+ hr = smtc2->put_PlaybackRate(playbackRate);
+ if (FAILED(hr)) {
+ LOG("Failed to set the playback rate (hr=%lx)", hr);
+ return;
+ }
+}
+
void WindowsSMTCProvider::LoadThumbnail(
const nsTArray<mozilla::dom::MediaImage>& aArtwork) {
MOZ_ASSERT(NS_IsMainThread());
diff --git a/widget/windows/WindowsSMTCProvider.h b/widget/windows/WindowsSMTCProvider.h
index 3926618d1f..2f0d1f8344 100644
--- a/widget/windows/WindowsSMTCProvider.h
+++ b/widget/windows/WindowsSMTCProvider.h
@@ -46,6 +46,9 @@ class WindowsSMTCProvider final : public mozilla::dom::MediaControlKeySource {
void SetSupportedMediaKeys(const MediaKeysArray& aSupportedKeys) override;
+ void SetPositionState(
+ const mozilla::Maybe<mozilla::dom::PositionState>& aState) override;
+
private:
~WindowsSMTCProvider();
void UnregisterEvents();
@@ -54,12 +57,14 @@ class WindowsSMTCProvider final : public mozilla::dom::MediaControlKeySource {
void OnButtonPressed(mozilla::dom::MediaControlKey aKey) const;
// Enable the SMTC interface
bool EnableControl(bool aEnabled) const;
- // Sets the play, pause, next, previous buttons on the SMTC interface by
- // mSupportedKeys
- bool UpdateButtons() const;
+ // Sets the play, pause, next, previous, seekto buttons on the SMTC interface
+ // by mSupportedKeys
+ bool UpdateButtons();
bool IsKeySupported(mozilla::dom::MediaControlKey aKey) const;
bool EnableKey(mozilla::dom::MediaControlKey aKey, bool aEnable) const;
+ void OnPositionChangeRequested(double aPosition) const;
+
bool InitDisplayAndControls();
// Sets the Metadata for the currently playing media and sets the playback
@@ -122,6 +127,7 @@ class WindowsSMTCProvider final : public mozilla::dom::MediaControlKeySource {
// EventRegistrationTokens are used to have a handle on a callback (to remove
// it again)
EventRegistrationToken mButtonPressedToken;
+ EventRegistrationToken mSeekRegistrationToken;
};
#endif // __MINGW32__
diff --git a/widget/windows/filedialog/WinFileDialogChild.cpp b/widget/windows/filedialog/WinFileDialogChild.cpp
index 1a2903f8ec..a41018ff0e 100644
--- a/widget/windows/filedialog/WinFileDialogChild.cpp
+++ b/widget/windows/filedialog/WinFileDialogChild.cpp
@@ -40,11 +40,8 @@ WinFileDialogChild::~WinFileDialogChild() {
template <size_t N>
WinFileDialogChild::IPCResult WinFileDialogChild::MakeIpcFailure(
HRESULT hr, const char (&what)[N]) {
- // The crash-report annotator stringifies integer values anyway. We do so
- // eagerly here to avoid questions about C int/long conversion semantics.
- nsPrintfCString data("%lu", hr);
- CrashReporter::AnnotateCrashReport(
- CrashReporter::Annotation::WindowsFileDialogErrorCode, data);
+ CrashReporter::RecordAnnotationU32(
+ CrashReporter::Annotation::WindowsFileDialogErrorCode, hr);
return IPC_FAIL(this, what);
}
diff --git a/widget/windows/filedialog/WinFileDialogCommands.cpp b/widget/windows/filedialog/WinFileDialogCommands.cpp
index f0503ab8f0..838856893d 100644
--- a/widget/windows/filedialog/WinFileDialogCommands.cpp
+++ b/widget/windows/filedialog/WinFileDialogCommands.cpp
@@ -294,7 +294,7 @@ void LogProcessingError(LogModule* aModule, ipc::IProtocol* aCaller,
ipc::SandboxingKind::WINDOWS_FILE_DIALOG);
} else {
// ... which (presumably) is us
- CrashReporter::AnnotateCrashReport(
+ CrashReporter::AutoRecordAnnotation(
CrashReporter::Annotation::ipc_channel_error, reason);
MOZ_CRASH("IPC error");
diff --git a/widget/windows/nsFilePicker.cpp b/widget/windows/nsFilePicker.cpp
index 310c54bb40..fb4c6e80b5 100644
--- a/widget/windows/nsFilePicker.cpp
+++ b/widget/windows/nsFilePicker.cpp
@@ -19,6 +19,7 @@
#include "mozilla/BackgroundHangMonitor.h"
#include "mozilla/Components.h"
#include "mozilla/dom/BrowsingContext.h"
+#include "mozilla/dom/CanonicalBrowsingContext.h"
#include "mozilla/dom/Directory.h"
#include "mozilla/Logging.h"
#include "mozilla/ipc/UtilityProcessManager.h"
@@ -94,19 +95,14 @@ nsFilePicker::nsFilePicker() : mSelectedType(1) {}
NS_IMPL_ISUPPORTS(nsFilePicker, nsIFilePicker)
NS_IMETHODIMP nsFilePicker::Init(
- mozIDOMWindowProxy* aParent, const nsAString& aTitle,
- nsIFilePicker::Mode aMode,
- mozilla::dom::BrowsingContext* aBrowsingContext) {
+ mozilla::dom::BrowsingContext* aBrowsingContext, const nsAString& aTitle,
+ nsIFilePicker::Mode aMode) {
// Don't attempt to open a real file-picker in headless mode.
if (gfxPlatform::IsHeadless()) {
return nsresult::NS_ERROR_NOT_AVAILABLE;
}
- nsCOMPtr<nsPIDOMWindowOuter> window = do_QueryInterface(aParent);
- nsIDocShell* docShell = window ? window->GetDocShell() : nullptr;
- mLoadContext = do_QueryInterface(docShell);
-
- return nsBaseFilePicker::Init(aParent, aTitle, aMode, aBrowsingContext);
+ return nsBaseFilePicker::Init(aBrowsingContext, aTitle, aMode);
}
namespace mozilla::detail {
@@ -1053,7 +1049,7 @@ void nsFilePicker::RememberLastUsedDirectory() {
}
bool nsFilePicker::IsPrivacyModeEnabled() {
- return mLoadContext && mLoadContext->UsePrivateBrowsing();
+ return mBrowsingContext && mBrowsingContext->UsePrivateBrowsing();
}
bool nsFilePicker::IsDefaultPathLink() {
diff --git a/widget/windows/nsFilePicker.h b/widget/windows/nsFilePicker.h
index 1938b8bcb6..59108bc0dd 100644
--- a/widget/windows/nsFilePicker.h
+++ b/widget/windows/nsFilePicker.h
@@ -66,9 +66,8 @@ class nsFilePicker final : public nsBaseWinFilePicker {
public:
nsFilePicker();
- NS_IMETHOD Init(mozIDOMWindowProxy* aParent, const nsAString& aTitle,
- nsIFilePicker::Mode aMode,
- mozilla::dom::BrowsingContext* aBrowsingContext) override;
+ NS_IMETHOD Init(mozilla::dom::BrowsingContext* aBrowsingContext,
+ const nsAString& aTitle, nsIFilePicker::Mode aMode) override;
NS_DECL_ISUPPORTS
@@ -117,7 +116,6 @@ class nsFilePicker final : public nsBaseWinFilePicker {
bool IsDefaultPathLink();
bool IsDefaultPathHtml();
- nsCOMPtr<nsILoadContext> mLoadContext;
nsCOMPtr<nsIWidget> mParentWidget;
nsString mTitle;
nsCString mFile;
diff --git a/widget/windows/nsLookAndFeel.cpp b/widget/windows/nsLookAndFeel.cpp
index 01b126cd42..6122000c9e 100644
--- a/widget/windows/nsLookAndFeel.cpp
+++ b/widget/windows/nsLookAndFeel.cpp
@@ -409,9 +409,6 @@ nsresult nsLookAndFeel::NativeGetInt(IntID aID, int32_t& aResult) {
// (400ms) on error.
aResult = GetSystemParam(SPI_GETMENUSHOWDELAY, 400);
break;
- case IntID::TooltipDelay:
- aResult = 500;
- break;
case IntID::MenusCanOverlapOSBar:
// we want XUL popups to be able to overlap the task bar.
aResult = 1;
diff --git a/widget/windows/nsWindow.cpp b/widget/windows/nsWindow.cpp
index 1a8646d620..b304d2efac 100644
--- a/widget/windows/nsWindow.cpp
+++ b/widget/windows/nsWindow.cpp
@@ -175,12 +175,11 @@
#include <zmouse.h>
#include <richedit.h>
-#if defined(ACCESSIBILITY)
-
+#ifdef ACCESSIBILITY
# ifdef DEBUG
# include "mozilla/a11y/Logging.h"
# endif
-
+# include "mozilla/a11y/Compatibility.h"
# include "oleidl.h"
# include <winuser.h>
# include "nsAccessibilityService.h"
@@ -190,7 +189,7 @@
# if !defined(WINABLEAPI)
# include <winable.h>
# endif // !defined(WINABLEAPI)
-#endif // defined(ACCESSIBILITY)
+#endif
#include "WindowsUIUtils.h"
@@ -1221,18 +1220,19 @@ static LPWSTR const gStockApplicationIcon = MAKEINTRESOURCEW(32512);
/* static */
const wchar_t* nsWindow::ChooseWindowClass(WindowType aWindowType) {
- switch (aWindowType) {
- case WindowType::Invisible:
- return RegisterWindowClass(kClassNameHidden, 0, gStockApplicationIcon);
- case WindowType::Dialog:
- return RegisterWindowClass(kClassNameDialog, 0, nullptr);
- case WindowType::Popup:
- return RegisterWindowClass(kClassNameDropShadow, 0,
- gStockApplicationIcon);
- default:
- return RegisterWindowClass(GetMainWindowClass(), 0,
- gStockApplicationIcon);
- }
+ const wchar_t* className = [aWindowType] {
+ switch (aWindowType) {
+ case WindowType::Invisible:
+ return kClassNameHidden;
+ case WindowType::Dialog:
+ return kClassNameDialog;
+ case WindowType::Popup:
+ return kClassNameDropShadow;
+ default:
+ return GetMainWindowClass();
+ }
+ }();
+ return RegisterWindowClass(className, 0, gStockApplicationIcon);
}
/**************************************************************
@@ -1310,13 +1310,6 @@ DWORD nsWindow::WindowStyle() {
if (mBorderStyle == BorderStyle::None ||
!(mBorderStyle & BorderStyle::Maximize))
style &= ~WS_MAXIMIZEBOX;
-
- if (IsPopupWithTitleBar()) {
- style |= WS_CAPTION;
- if (mBorderStyle & BorderStyle::Close) {
- style |= WS_SYSMENU;
- }
- }
}
if (mIsChildWindow) {
@@ -1332,7 +1325,6 @@ DWORD nsWindow::WindowStyle() {
// Return nsWindow extended styles
DWORD nsWindow::WindowExStyle() {
- MOZ_ASSERT_IF(mIsAlert, mWindowType == WindowType::Dialog);
switch (mWindowType) {
case WindowType::Child:
return 0;
@@ -1343,18 +1335,18 @@ DWORD nsWindow::WindowExStyle() {
}
return extendedStyle;
}
- case WindowType::Dialog: {
- if (mIsAlert) {
- return WS_EX_TOOLWINDOW | WS_EX_TOPMOST;
- }
- return WS_EX_WINDOWEDGE | WS_EX_DLGMODALFRAME;
- }
case WindowType::Sheet:
MOZ_FALLTHROUGH_ASSERT("Sheets are macOS specific");
+ case WindowType::Dialog:
case WindowType::TopLevel:
case WindowType::Invisible:
break;
}
+ if (mIsAlert) {
+ MOZ_ASSERT(mWindowType == WindowType::Dialog,
+ "Expect alert windows to have type=dialog");
+ return WS_EX_TOOLWINDOW | WS_EX_TOPMOST;
+ }
return WS_EX_WINDOWEDGE;
}
@@ -3058,9 +3050,7 @@ void nsWindow::SetTransparencyMode(TransparencyMode aMode) {
void nsWindow::UpdateWindowDraggingRegion(
const LayoutDeviceIntRegion& aRegion) {
- if (mDraggableRegion != aRegion) {
- mDraggableRegion = aRegion;
- }
+ mDraggableRegion = aRegion;
}
/**************************************************************
@@ -3674,7 +3664,7 @@ LayoutDeviceIntPoint nsWindow::WidgetToScreenOffset() {
}
LayoutDeviceIntMargin nsWindow::ClientToWindowMargin() {
- if (mWindowType == WindowType::Popup && !IsPopupWithTitleBar()) {
+ if (mWindowType == WindowType::Popup) {
return {};
}
@@ -4420,6 +4410,17 @@ HWND nsWindow::GetTopLevelForFocus(HWND aCurWnd) {
}
void nsWindow::DispatchFocusToTopLevelWindow(bool aIsActivate) {
+ if (aIsActivate && mPickerDisplayCount) {
+ // We disable the root window when a picker opens. See PickerOpen. When the
+ // picker closes (but before PickerClosed is called), our window will get
+ // focus, but it will still be disabled. This confuses the focus system.
+ // Therefore, we ignore this focus and explicitly call this function once
+ // we re-enable the window. Rarely, the picker seems to re-enable our root
+ // window before we do, but for simplicity, we always ignore focus before
+ // the final call to PickerClosed. See bug 1883568 for further details.
+ return;
+ }
+
if (aIsActivate) {
sJustGotActivate = false;
}
@@ -5039,6 +5040,44 @@ bool nsWindow::ProcessMessageInternal(UINT msg, WPARAM& wParam, LPARAM& lParam,
break;
}
+ case WM_GETTITLEBARINFOEX: {
+ if (!mCustomNonClient) {
+ break;
+ }
+ auto* info = reinterpret_cast<TITLEBARINFOEX*>(lParam);
+ const LayoutDeviceIntPoint origin = WidgetToScreenOffset();
+ auto GeckoClientToWinScreenRect =
+ [&origin](LayoutDeviceIntRect aRect) -> RECT {
+ aRect.MoveBy(origin);
+ return {
+ .left = aRect.x,
+ .top = aRect.y,
+ .right = aRect.XMost(),
+ .bottom = aRect.YMost(),
+ };
+ };
+ auto SetButton = [&](size_t aIndex, WindowButtonType aType) {
+ info->rgrect[aIndex] =
+ GeckoClientToWinScreenRect(mWindowBtnRect[aType]);
+ DWORD& state = info->rgstate[aIndex];
+ if (mWindowBtnRect[aType].IsEmpty()) {
+ state = STATE_SYSTEM_INVISIBLE;
+ } else {
+ state = STATE_SYSTEM_FOCUSABLE;
+ }
+ };
+ info->rgrect[0] = info->rcTitleBar =
+ GeckoClientToWinScreenRect(mDraggableRegion.GetBounds());
+ info->rgstate[0] = 0;
+ SetButton(2, WindowButtonType::Minimize);
+ SetButton(3, WindowButtonType::Maximize);
+ SetButton(5, WindowButtonType::Close);
+ // We don't have a help button.
+ info->rgstate[4] = STATE_SYSTEM_INVISIBLE;
+ info->rgrect[4] = {0, 0, 0, 0};
+ result = true;
+ } break;
+
case WM_NCHITTEST: {
if (mInputRegion.mFullyTransparent) {
// Treat this window as transparent.
@@ -6169,6 +6208,9 @@ int32_t nsWindow::ClientMarginHitTestPoint(int32_t aX, int32_t aY) {
if (mWindowBtnRect[WindowButtonType::Minimize].Contains(pt)) {
testResult = HTMINBUTTON;
} else if (mWindowBtnRect[WindowButtonType::Maximize].Contains(pt)) {
+#ifdef ACCESSIBILITY
+ a11y::Compatibility::SuppressA11yForSnapLayouts();
+#endif
testResult = HTMAXBUTTON;
} else if (mWindowBtnRect[WindowButtonType::Close].Contains(pt)) {
testResult = HTCLOSE;
@@ -8168,8 +8210,23 @@ WPARAM nsWindow::wParamFromGlobalMouseState() {
return result;
}
+// WORKAROUND FOR UNDOCUMENTED BEHAVIOR: `IFileDialog::Show` disables the
+// top-level ancestor of its provided owner-window. If the modal window's
+// container process crashes, it will never get a chance to undo that.
+//
+// For simplicity's sake we simply unconditionally perform both the disabling
+// and reenabling here, synchronously, on the main thread, rather than leaving
+// it to happen in our asynchronously-operated IFileDialog.
+
void nsWindow::PickerOpen() {
AssertIsOnMainThread();
+
+ // Disable the root-level window synchronously before any file-dialogs get a
+ // chance to fight over doing it asynchronously.
+ if (!mPickerDisplayCount) {
+ ::EnableWindow(::GetAncestor(GetWindowHandle(), GA_ROOT), FALSE);
+ }
+
mPickerDisplayCount++;
}
@@ -8179,16 +8236,10 @@ void nsWindow::PickerClosed() {
if (!mPickerDisplayCount) return;
mPickerDisplayCount--;
- // WORKAROUND FOR UNDOCUMENTED BEHAVIOR: `IFileDialog::Show` disables the
- // top-level ancestor of its provided owner-window. If the modal window's
- // container process crashes, it will never get a chance to undo that, so we
- // do it manually here.
- //
- // Note that this may cause problems in the embedded case if you reparent a
- // subtree of the native window hierarchy containing a Gecko window while that
- // Gecko window has a file-dialog open.
+ // Once all the file-dialogs are gone, reenable the root-level window.
if (!mPickerDisplayCount) {
::EnableWindow(::GetAncestor(GetWindowHandle(), GA_ROOT), TRUE);
+ DispatchFocusToTopLevelWindow(true);
}
if (!mPickerDisplayCount && mDestroyCalled) {
@@ -8528,6 +8579,7 @@ void nsWindow::ChangedDPI() {
presShell->BackingScaleFactorChanged();
}
}
+ NotifyAPZOfDPIChange();
}
static Result<POINTER_FLAGS, nsresult> PointerStateToFlag(
diff --git a/widget/windows/nsWindow.h b/widget/windows/nsWindow.h
index c75c9d174d..3a521fb978 100644
--- a/widget/windows/nsWindow.h
+++ b/widget/windows/nsWindow.h
@@ -887,8 +887,8 @@ class nsWindow final : public nsBaseWidget {
mozilla::UniquePtr<mozilla::widget::DirectManipulationOwner> mDmOwner;
// Client rect for minimize, maximize and close buttons.
- mozilla::EnumeratedArray<WindowButtonType, WindowButtonType::Count,
- LayoutDeviceIntRect>
+ mozilla::EnumeratedArray<WindowButtonType, LayoutDeviceIntRect,
+ size_t(WindowButtonType::Count)>
mWindowBtnRect;
mozilla::DataMutex<Desktop> mDesktopId;