ladybird/Libraries/LibCore/TimeZoneWatcherWindows.cpp
ayeteadoe f4c8fd4bef LibCore+LibWebView+UI/Qt: Support TimeZoneWatcher on Windows
To detect system time zone changes on Windows, the event we need to look
for is WM_TIMECHANGE. The problem is how the callback with said message
actually gets invoked is very particular. (1) We must have an active
message pump (event loop) for the message to ever be processed. (2) We
must be a GUI application as WM_TIMECHANGE messages are seemingly sent
to top level windows only. It doesn't say that in the docs for the
event, but attempts of creating a LibTest-based application with a
message pump and a message only window and never receiving the event
point to that probably being true.

This workaround is built off the fact that Qt's message pump defined
internally in QEventDispatcherWin32::processEvents does in fact receive
WM_TIMECHANGE events, even though it is not exposed as a QEvent::Type.
Given the requirements stated above it makes sense that it works here as
the message pump is executing in a QGuiApplication context. So we use a
native event filter to hook into the unexposed WM_TIMECHANGE event and
forward it along to the on_time_zone_changed() callback.

Note that if a Windows GUI framework is done in the future, we'll have
to re-add support to ensure the TimeZoneWatcher still gets invoked.
2025-10-05 15:46:15 +02:00

32 lines
652 B
C++

/*
* Copyright (c) 2025, ayeteadoe <ayeteadoe@gmail.com>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#include <AK/Platform.h>
#include <LibCore/TimeZoneWatcher.h>
#if !defined(AK_OS_WINDOWS)
static_assert(false, "This file must only be used for Windows");
#endif
namespace Core {
class TimeZoneWatcherImpl final : public TimeZoneWatcher {
public:
static ErrorOr<NonnullOwnPtr<TimeZoneWatcherImpl>> create()
{
return adopt_own(*new TimeZoneWatcherImpl());
}
private:
TimeZoneWatcherImpl() = default;
};
ErrorOr<NonnullOwnPtr<TimeZoneWatcher>> TimeZoneWatcher::create()
{
return TimeZoneWatcherImpl::create();
}
}