mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2024-12-04 05:20:30 +00:00
LibCore: Create a system time zone watcher
This creates platform-dependent monitors to detect when the system time zone changes. On Linux, we use a file watcher to monitor files such as /etc/localtime for changes. On macOS, this uses CFNotificationCenter to be notified by the OS when the time zone changes. Note: the macOS implementation requires running in a process which is running the CoreFoundation event loop. Both the AppKit and Qt chromes are doing so in the UI process, but this means we cannot run this monitor in the WebContent process.
This commit is contained in:
parent
b31c11bca5
commit
577efcdc32
Notes:
github-actions[bot]
2024-08-25 07:48:42 +00:00
Author: https://github.com/trflynn89 Commit: https://github.com/LadybirdBrowser/ladybird/commit/577efcdc327 Pull-request: https://github.com/LadybirdBrowser/ladybird/pull/1182
6 changed files with 172 additions and 1 deletions
|
@ -63,21 +63,24 @@ if (NOT WIN32 AND NOT EMSCRIPTEN)
|
|||
list(APPEND SOURCES LocalServer.cpp)
|
||||
endif()
|
||||
|
||||
# FIXME: Implement Core::FileWatcher for *BSD and Windows.
|
||||
# FIXME: Implement these for other systems.
|
||||
if (LINUX AND NOT EMSCRIPTEN)
|
||||
list(APPEND SOURCES
|
||||
FileWatcherLinux.cpp
|
||||
Platform/ProcessStatisticsLinux.cpp
|
||||
TimeZoneWatcherLinux.cpp
|
||||
)
|
||||
elseif (APPLE AND NOT IOS)
|
||||
list(APPEND SOURCES
|
||||
FileWatcherMacOS.mm
|
||||
Platform/ProcessStatisticsMach.cpp
|
||||
TimeZoneWatcherMacOS.mm
|
||||
)
|
||||
else()
|
||||
list(APPEND SOURCES
|
||||
FileWatcherUnimplemented.cpp
|
||||
Platform/ProcessStatisticsUnimplemented.cpp
|
||||
TimeZoneWatcherUnimplemented.cpp
|
||||
)
|
||||
endif()
|
||||
|
||||
|
|
|
@ -45,6 +45,7 @@ class TCPServer;
|
|||
class TCPSocket;
|
||||
class Timer;
|
||||
class TimerEvent;
|
||||
class TimeZoneWatcher;
|
||||
class UDPServer;
|
||||
class UDPSocket;
|
||||
|
||||
|
|
29
Userland/Libraries/LibCore/TimeZoneWatcher.h
Normal file
29
Userland/Libraries/LibCore/TimeZoneWatcher.h
Normal file
|
@ -0,0 +1,29 @@
|
|||
/*
|
||||
* Copyright (c) 2024, Tim Flynn <trflynn89@serenityos.org>
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <AK/Error.h>
|
||||
#include <AK/Function.h>
|
||||
#include <AK/Noncopyable.h>
|
||||
#include <AK/NonnullOwnPtr.h>
|
||||
|
||||
namespace Core {
|
||||
|
||||
class TimeZoneWatcher {
|
||||
AK_MAKE_NONCOPYABLE(TimeZoneWatcher);
|
||||
|
||||
public:
|
||||
static ErrorOr<NonnullOwnPtr<TimeZoneWatcher>> create();
|
||||
virtual ~TimeZoneWatcher() = default;
|
||||
|
||||
Function<void()> on_time_zone_changed;
|
||||
|
||||
protected:
|
||||
TimeZoneWatcher() = default;
|
||||
};
|
||||
|
||||
}
|
62
Userland/Libraries/LibCore/TimeZoneWatcherLinux.cpp
Normal file
62
Userland/Libraries/LibCore/TimeZoneWatcherLinux.cpp
Normal file
|
@ -0,0 +1,62 @@
|
|||
/*
|
||||
* Copyright (c) 2024, Tim Flynn <trflynn89@serenityos.org>
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
||||
#include <AK/Platform.h>
|
||||
#include <LibCore/FileWatcher.h>
|
||||
#include <LibCore/TimeZoneWatcher.h>
|
||||
|
||||
#if !defined(AK_OS_LINUX)
|
||||
static_assert(false, "This file must only be used for Linux");
|
||||
#endif
|
||||
|
||||
namespace Core {
|
||||
|
||||
static constexpr auto time_zone_files = Array {
|
||||
"/etc/localtime"sv,
|
||||
"/etc/timezone"sv,
|
||||
"/etc/TZ"sv,
|
||||
};
|
||||
|
||||
static constexpr auto time_zone_mask = FileWatcherEvent::Type::ContentModified
|
||||
| FileWatcherEvent::Type::Deleted
|
||||
| FileWatcherEvent::Type::DoNotFollowLink;
|
||||
|
||||
class TimeZoneWatcherImpl final : public TimeZoneWatcher {
|
||||
public:
|
||||
static ErrorOr<NonnullOwnPtr<TimeZoneWatcherImpl>> create()
|
||||
{
|
||||
auto file_watcher = TRY(FileWatcher::create());
|
||||
|
||||
for (auto time_zone_file : time_zone_files) {
|
||||
if (auto result = file_watcher->add_watch(time_zone_file, time_zone_mask); !result.is_error())
|
||||
break;
|
||||
}
|
||||
|
||||
return adopt_own(*new TimeZoneWatcherImpl(move(file_watcher)));
|
||||
}
|
||||
|
||||
private:
|
||||
explicit TimeZoneWatcherImpl(NonnullRefPtr<FileWatcher> file_watcher)
|
||||
: m_file_watcher(move(file_watcher))
|
||||
{
|
||||
m_file_watcher->on_change = [this](Core::FileWatcherEvent const& event) {
|
||||
if (on_time_zone_changed)
|
||||
on_time_zone_changed();
|
||||
|
||||
if (has_flag(event.type, FileWatcherEvent::Type::Deleted))
|
||||
(void)m_file_watcher->add_watch(event.event_path, time_zone_mask);
|
||||
};
|
||||
}
|
||||
|
||||
NonnullRefPtr<FileWatcher> m_file_watcher;
|
||||
};
|
||||
|
||||
ErrorOr<NonnullOwnPtr<TimeZoneWatcher>> TimeZoneWatcher::create()
|
||||
{
|
||||
return TimeZoneWatcherImpl::create();
|
||||
}
|
||||
|
||||
}
|
60
Userland/Libraries/LibCore/TimeZoneWatcherMacOS.mm
Normal file
60
Userland/Libraries/LibCore/TimeZoneWatcherMacOS.mm
Normal file
|
@ -0,0 +1,60 @@
|
|||
/*
|
||||
* Copyright (c) 2024, Tim Flynn <trflynn89@serenityos.org>
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
||||
#include <AK/Platform.h>
|
||||
#include <LibCore/TimeZoneWatcher.h>
|
||||
|
||||
#if !defined(AK_OS_MACOS)
|
||||
static_assert(false, "This file must only be used for macOS");
|
||||
#endif
|
||||
|
||||
#include <CoreFoundation/CoreFoundation.h>
|
||||
|
||||
namespace Core {
|
||||
|
||||
class TimeZoneWatcherImpl final : public TimeZoneWatcher {
|
||||
public:
|
||||
static ErrorOr<NonnullOwnPtr<TimeZoneWatcherImpl>> create()
|
||||
{
|
||||
return adopt_own(*new TimeZoneWatcherImpl());
|
||||
}
|
||||
|
||||
virtual ~TimeZoneWatcherImpl() override
|
||||
{
|
||||
CFNotificationCenterRemoveObserver(
|
||||
CFNotificationCenterGetLocalCenter(),
|
||||
this,
|
||||
kCFTimeZoneSystemTimeZoneDidChangeNotification,
|
||||
nullptr);
|
||||
}
|
||||
|
||||
private:
|
||||
explicit TimeZoneWatcherImpl()
|
||||
{
|
||||
CFNotificationCenterAddObserver(
|
||||
CFNotificationCenterGetLocalCenter(),
|
||||
this,
|
||||
time_zone_changed,
|
||||
kCFTimeZoneSystemTimeZoneDidChangeNotification,
|
||||
nullptr,
|
||||
CFNotificationSuspensionBehaviorDeliverImmediately);
|
||||
}
|
||||
|
||||
static void time_zone_changed(CFNotificationCenterRef, void* observer, CFStringRef, void const*, CFDictionaryRef)
|
||||
{
|
||||
auto const& time_zone_watcher = *reinterpret_cast<TimeZoneWatcherImpl*>(observer);
|
||||
|
||||
if (time_zone_watcher.on_time_zone_changed)
|
||||
time_zone_watcher.on_time_zone_changed();
|
||||
}
|
||||
};
|
||||
|
||||
ErrorOr<NonnullOwnPtr<TimeZoneWatcher>> TimeZoneWatcher::create()
|
||||
{
|
||||
return TimeZoneWatcherImpl::create();
|
||||
}
|
||||
|
||||
}
|
16
Userland/Libraries/LibCore/TimeZoneWatcherUnimplemented.cpp
Normal file
16
Userland/Libraries/LibCore/TimeZoneWatcherUnimplemented.cpp
Normal file
|
@ -0,0 +1,16 @@
|
|||
/*
|
||||
* Copyright (c) 2024, Tim Flynn <trflynn89@serenityos.org>
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
||||
#include <LibCore/TimeZoneWatcher.h>
|
||||
|
||||
namespace Core {
|
||||
|
||||
ErrorOr<NonnullOwnPtr<TimeZoneWatcher>> TimeZoneWatcher::create()
|
||||
{
|
||||
return Error::from_errno(ENOTSUP);
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in a new issue