mirror of
https://github.com/microsoft/PowerToys.git
synced 2025-06-07 01:08:18 +08:00
[FancyZones] Implement File Watcher (#8603)
* Implement File Watcher in FancyZones * Simplify code, address PR comments * Add check to result of CreateEventW * Rebase fix Removed unneeded newline. If we keep it now, VS will just remove it some other time.
This commit is contained in:
parent
540e16b179
commit
e2ca4177dd
@ -10,6 +10,7 @@
|
||||
#include "lib/ZoneWindow.h"
|
||||
#include "lib/FancyZonesData.h"
|
||||
#include "lib/ZoneSet.h"
|
||||
#include "lib/FileWatcher.h"
|
||||
#include "lib/WindowMoveHandler.h"
|
||||
#include "lib/FancyZonesWinHookEventIDs.h"
|
||||
#include "lib/util.h"
|
||||
@ -50,6 +51,9 @@ public:
|
||||
m_settings(settings),
|
||||
m_windowMoveHandler(settings, [this]() {
|
||||
PostMessageW(m_window, WM_PRIV_LOCATIONCHANGE, NULL, NULL);
|
||||
}),
|
||||
m_fileWatcher(FancyZonesDataInstance().GetZonesSettingsFileName(), [this]() {
|
||||
PostMessageW(m_window, WM_PRIV_FILE_UPDATE, NULL, NULL);
|
||||
})
|
||||
{
|
||||
m_settings->SetCallback(this);
|
||||
@ -221,6 +225,7 @@ private:
|
||||
void MoveWindowIntoZone(HWND window, winrt::com_ptr<IZoneWindow> zoneWindow, const std::vector<size_t>& zoneIndexSet) noexcept;
|
||||
|
||||
void OnEditorExitEvent() noexcept;
|
||||
void UpdateZoneSets() noexcept;
|
||||
bool ShouldProcessSnapHotkey(DWORD vkCode) noexcept;
|
||||
|
||||
std::vector<std::pair<HMONITOR, RECT>> GetRawMonitorData() noexcept;
|
||||
@ -232,6 +237,7 @@ private:
|
||||
HWND m_window{};
|
||||
WindowMoveHandler m_windowMoveHandler;
|
||||
MonitorWorkAreaHandler m_workAreaHandler;
|
||||
FileWatcher m_fileWatcher;
|
||||
|
||||
winrt::com_ptr<IFancyZonesSettings> m_settings{};
|
||||
GUID m_previousDesktopId{}; // UUID of previously active virtual desktop.
|
||||
@ -249,6 +255,7 @@ private:
|
||||
static UINT WM_PRIV_VD_SWITCH; // Scheduled when virtual desktop switch occurs
|
||||
static UINT WM_PRIV_VD_UPDATE; // Scheduled on virtual desktops update (creation/deletion)
|
||||
static UINT WM_PRIV_EDITOR; // Scheduled when the editor exits
|
||||
static UINT WM_PRIV_FILE_UPDATE; // Scheduled when the a watched file is updated
|
||||
|
||||
static UINT WM_PRIV_LOWLEVELKB; // Scheduled when we receive a key down press
|
||||
|
||||
@ -266,6 +273,7 @@ UINT FancyZones::WM_PRIV_VD_INIT = RegisterWindowMessage(L"{469818a8-00fa-4069-b
|
||||
UINT FancyZones::WM_PRIV_VD_SWITCH = RegisterWindowMessage(L"{128c2cb0-6bdf-493e-abbe-f8705e04aa95}");
|
||||
UINT FancyZones::WM_PRIV_VD_UPDATE = RegisterWindowMessage(L"{b8b72b46-f42f-4c26-9e20-29336cf2f22e}");
|
||||
UINT FancyZones::WM_PRIV_EDITOR = RegisterWindowMessage(L"{87543824-7080-4e91-9d9c-0404642fc7b6}");
|
||||
UINT FancyZones::WM_PRIV_FILE_UPDATE = RegisterWindowMessage(L"{632f17a9-55a7-45f1-a4db-162e39271d92}");
|
||||
UINT FancyZones::WM_PRIV_LOWLEVELKB = RegisterWindowMessage(L"{763c03a3-03d9-4cde-8d71-f0358b0b4b52}");
|
||||
|
||||
// IFancyZones
|
||||
@ -856,6 +864,11 @@ LRESULT FancyZones::WndProc(HWND window, UINT message, WPARAM wparam, LPARAM lpa
|
||||
auto hwnd = reinterpret_cast<HWND>(wparam);
|
||||
WindowCreated(hwnd);
|
||||
}
|
||||
else if (message == WM_PRIV_FILE_UPDATE)
|
||||
{
|
||||
FancyZonesDataInstance().LoadFancyZonesData();
|
||||
UpdateZoneSets();
|
||||
}
|
||||
else
|
||||
{
|
||||
return DefWindowProc(window, message, wparam, lparam);
|
||||
@ -1296,7 +1309,11 @@ void FancyZones::OnEditorExitEvent() noexcept
|
||||
{
|
||||
// Collect information about changes in zone layout after editor exited.
|
||||
FancyZonesDataInstance().ParseDataFromTmpFiles();
|
||||
UpdateZoneSets();
|
||||
}
|
||||
|
||||
void FancyZones::UpdateZoneSets() noexcept
|
||||
{
|
||||
for (auto workArea : m_workAreaHandler.GetAllWorkAreas())
|
||||
{
|
||||
workArea->UpdateActiveZoneSet();
|
||||
|
@ -59,6 +59,11 @@ public:
|
||||
return appZoneHistoryMap;
|
||||
}
|
||||
|
||||
inline const std::wstring& GetZonesSettingsFileName() const
|
||||
{
|
||||
return zonesSettingsFileName;
|
||||
}
|
||||
|
||||
bool AddDevice(const std::wstring& deviceId);
|
||||
void CloneDeviceInfo(const std::wstring& source, const std::wstring& destination);
|
||||
void UpdatePrimaryDesktopData(const std::wstring& desktopId);
|
||||
|
@ -40,6 +40,7 @@
|
||||
<ClInclude Include="FancyZones.h" />
|
||||
<ClInclude Include="FancyZonesDataTypes.h" />
|
||||
<ClInclude Include="FancyZonesWinHookEventIDs.h" />
|
||||
<ClInclude Include="FileWatcher.h" />
|
||||
<ClInclude Include="GenericKeyHook.h" />
|
||||
<ClInclude Include="FancyZonesData.h" />
|
||||
<ClInclude Include="JsonHelpers.h" />
|
||||
@ -64,6 +65,7 @@
|
||||
<ClCompile Include="FancyZonesDataTypes.cpp" />
|
||||
<ClCompile Include="FancyZonesWinHookEventIDs.cpp" />
|
||||
<ClCompile Include="FancyZonesData.cpp" />
|
||||
<ClCompile Include="FileWatcher.cpp" />
|
||||
<ClCompile Include="JsonHelpers.cpp" />
|
||||
<ClCompile Include="MonitorWorkAreaHandler.cpp" />
|
||||
<ClCompile Include="OnThreadExecutor.cpp" />
|
||||
|
@ -78,6 +78,9 @@
|
||||
<ClInclude Include="ZoneWindowDrawing.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="FileWatcher.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="pch.cpp">
|
||||
@ -134,6 +137,9 @@
|
||||
<ClCompile Include="OnThreadExecutor.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="FileWatcher.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="packages.config" />
|
||||
|
68
src/modules/fancyzones/lib/FileWatcher.cpp
Normal file
68
src/modules/fancyzones/lib/FileWatcher.cpp
Normal file
@ -0,0 +1,68 @@
|
||||
#include "pch.h"
|
||||
#include "FileWatcher.h"
|
||||
|
||||
std::optional<FILETIME> FileWatcher::MyFileTime()
|
||||
{
|
||||
HANDLE hFile = CreateFileW(m_path.c_str(), FILE_READ_ATTRIBUTES, FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE, nullptr, OPEN_EXISTING, 0, nullptr);
|
||||
std::optional<FILETIME> result;
|
||||
if (hFile != INVALID_HANDLE_VALUE)
|
||||
{
|
||||
FILETIME lastWrite;
|
||||
if (GetFileTime(hFile, nullptr, nullptr, &lastWrite))
|
||||
{
|
||||
result = lastWrite;
|
||||
}
|
||||
|
||||
CloseHandle(hFile);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void FileWatcher::Run()
|
||||
{
|
||||
while (1)
|
||||
{
|
||||
auto lastWrite = MyFileTime();
|
||||
if (!m_lastWrite.has_value())
|
||||
{
|
||||
m_lastWrite = lastWrite;
|
||||
}
|
||||
else if (lastWrite.has_value())
|
||||
{
|
||||
if (m_lastWrite->dwHighDateTime != lastWrite->dwHighDateTime ||
|
||||
m_lastWrite->dwLowDateTime != lastWrite->dwLowDateTime)
|
||||
{
|
||||
m_lastWrite = lastWrite;
|
||||
m_callback();
|
||||
}
|
||||
}
|
||||
|
||||
if (WaitForSingleObject(m_abortEvent, m_refreshPeriod) == WAIT_OBJECT_0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
FileWatcher::FileWatcher(const std::wstring& path, std::function<void()> callback, DWORD refreshPeriod) :
|
||||
m_refreshPeriod(refreshPeriod),
|
||||
m_path(path),
|
||||
m_callback(callback)
|
||||
{
|
||||
m_abortEvent = CreateEventW(nullptr, TRUE, FALSE, nullptr);
|
||||
if (m_abortEvent)
|
||||
{
|
||||
m_thread = std::thread([this]() { Run(); });
|
||||
}
|
||||
}
|
||||
|
||||
FileWatcher::~FileWatcher()
|
||||
{
|
||||
if (m_abortEvent)
|
||||
{
|
||||
SetEvent(m_abortEvent);
|
||||
m_thread.join();
|
||||
CloseHandle(m_abortEvent);
|
||||
}
|
||||
}
|
19
src/modules/fancyzones/lib/FileWatcher.h
Normal file
19
src/modules/fancyzones/lib/FileWatcher.h
Normal file
@ -0,0 +1,19 @@
|
||||
#pragma once
|
||||
|
||||
#include "pch.h"
|
||||
|
||||
class FileWatcher
|
||||
{
|
||||
DWORD m_refreshPeriod;
|
||||
std::wstring m_path;
|
||||
std::optional<FILETIME> m_lastWrite;
|
||||
std::function<void()> m_callback;
|
||||
HANDLE m_abortEvent;
|
||||
std::thread m_thread;
|
||||
|
||||
std::optional<FILETIME> MyFileTime();
|
||||
void Run();
|
||||
public:
|
||||
FileWatcher(const std::wstring& path, std::function<void()> callback, DWORD refreshPeriod = 1000);
|
||||
~FileWatcher();
|
||||
};
|
@ -21,6 +21,7 @@
|
||||
#include <functional>
|
||||
#include <unordered_set>
|
||||
#include <ShObjIdl.h>
|
||||
#include <optional>
|
||||
|
||||
#pragma comment(lib, "windowsapp")
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user