Skip to content

Commit

Permalink
Modifying the startup behaviour of the FancyZones Layout Editor
Browse files Browse the repository at this point in the history
Add setting to allow to choose if the FZ editor opens in the screen where mouse cursor is or where the active windows is.
  • Loading branch information
cedi authored and enricogior committed Sep 28, 2019
1 parent a8f0d32 commit faf1fae
Show file tree
Hide file tree
Showing 7 changed files with 108 additions and 72 deletions.
12 changes: 12 additions & 0 deletions src/common/dpi_aware.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,18 @@ HRESULT DPIAware::GetScreenDPIForWindow(HWND hwnd, UINT &dpi_x, UINT &dpi_y) {
}
}

HRESULT DPIAware::GetScreenDPIForPoint(POINT p, UINT& dpi_x, UINT& dpi_y) {
auto monitor_handle = MonitorFromPoint(p, MONITOR_DEFAULTTONEAREST);
dpi_x = 0;
dpi_y = 0;
if (monitor_handle != nullptr) {
return GetDpiForMonitor(monitor_handle, MDT_EFFECTIVE_DPI, &dpi_x, &dpi_y);
}
else {
return E_FAIL;
}
}

void DPIAware::Convert(HMONITOR monitor_handle, int &width, int &height) {
if (monitor_handle == NULL) {
const POINT ptZero = { 0, 0 };
Expand Down
1 change: 1 addition & 0 deletions src/common/dpi_aware.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,6 @@ class DPIAware {

public:
static HRESULT GetScreenDPIForWindow(HWND hwnd, UINT & dpi_x, UINT & dpi_y);
static HRESULT GetScreenDPIForPoint(POINT p, UINT& dpi_x, UINT& dpi_y);
static void Convert(HMONITOR monitor_handle, int &width, int &height);
};
154 changes: 87 additions & 67 deletions src/modules/fancyzones/lib/FancyZones.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -237,75 +237,95 @@ void FancyZones::ToggleEditor() noexcept
m_terminateEditorEvent.reset(CreateEvent(nullptr, true, false, nullptr));
}

const HWND foregroundWindow = GetForegroundWindow();
if (const HMONITOR monitor = MonitorFromWindow(foregroundWindow, MONITOR_DEFAULTTOPRIMARY))
HMONITOR monitor{};
UINT dpi_x = 96;
UINT dpi_y = 96;

if (m_settings->GetSettings().use_cursorpos_editor_startupscreen)
{
std::shared_lock readLock(m_lock);
auto iter = m_zoneWindowMap.find(monitor);
if (iter != m_zoneWindowMap.end())
POINT currentCursorPos{};
GetCursorPos(&currentCursorPos);

monitor = MonitorFromPoint(currentCursorPos, MONITOR_DEFAULTTOPRIMARY);
DPIAware::GetScreenDPIForPoint(currentCursorPos, dpi_x, dpi_y);
}
else
{
const HWND foregroundWindow = GetForegroundWindow();
monitor = MonitorFromWindow(foregroundWindow, MONITOR_DEFAULTTOPRIMARY);
DPIAware::GetScreenDPIForWindow(foregroundWindow, dpi_x, dpi_y);
}


if (!monitor)
{
return;
}

std::shared_lock readLock(m_lock);
auto iter = m_zoneWindowMap.find(monitor);
if (iter == m_zoneWindowMap.end())
{
return;
}

MONITORINFOEX mi;
mi.cbSize = sizeof(mi);
GetMonitorInfo(monitor, &mi);

// X/Y need to start in unscaled screen coordinates to get to the proper top/left of the monitor
// From there, we need to scale the difference between the monitor and workarea rects to get the
// appropriate offset where the overlay should appear.
// This covers the cases where the taskbar is not at the bottom of the screen.
const auto x = mi.rcMonitor.left + MulDiv(mi.rcWork.left - mi.rcMonitor.left, 96, dpi_x);
const auto y = mi.rcMonitor.top + MulDiv(mi.rcWork.top - mi.rcMonitor.top, 96, dpi_y);

// Location that the editor should occupy, scaled by DPI
std::wstring editorLocation =
std::to_wstring(x) + L"_" +
std::to_wstring(y) + L"_" +
std::to_wstring(MulDiv(mi.rcWork.right - mi.rcWork.left, 96, dpi_x)) + L"_" +
std::to_wstring(MulDiv(mi.rcWork.bottom - mi.rcWork.top, 96, dpi_y));

const std::wstring params =
iter->second->UniqueId() + L" " +
std::to_wstring(iter->second->ActiveZoneSet()->LayoutId()) + L" " +
std::to_wstring(reinterpret_cast<UINT_PTR>(monitor)) + L" " +
editorLocation + L" " +
iter->second->WorkAreaKey() + L" " +
std::to_wstring(static_cast<float>(dpi_x) / 96.0f);

SHELLEXECUTEINFO sei{ sizeof(sei) };
sei.fMask = { SEE_MASK_NOCLOSEPROCESS | SEE_MASK_FLAG_NO_UI };
sei.lpFile = L"modules\\FancyZonesEditor.exe";
sei.lpParameters = params.c_str();
sei.nShow = SW_SHOWNORMAL;
ShellExecuteEx(&sei);

// Launch the editor on a background thread
// Wait for the editor's process to exit
// Post back to the main thread to update
std::thread waitForEditorThread([window = m_window, processHandle = sei.hProcess, terminateEditorEvent = m_terminateEditorEvent.get()]()
{
HANDLE waitEvents[2] = { processHandle, terminateEditorEvent };
auto result = WaitForMultipleObjects(2, waitEvents, false, INFINITE);
if (result == WAIT_OBJECT_0 + 0)
{
UINT dpi_x = 96;
UINT dpi_y = 96;
DPIAware::GetScreenDPIForWindow(foregroundWindow, dpi_x, dpi_y);

MONITORINFOEX mi;
mi.cbSize = sizeof(mi);
GetMonitorInfo(monitor, &mi);

// X/Y need to start in unscaled screen coordinates to get to the proper top/left of the monitor
// From there, we need to scale the difference between the monitor and workarea rects to get the
// appropriate offset where the overlay should appear.
// This covers the cases where the taskbar is not at the bottom of the screen.
const auto x = mi.rcMonitor.left + MulDiv(mi.rcWork.left - mi.rcMonitor.left, 96, dpi_x);
const auto y = mi.rcMonitor.top + MulDiv(mi.rcWork.top - mi.rcMonitor.top, 96, dpi_y);

// Location that the editor should occupy, scaled by DPI
std::wstring editorLocation =
std::to_wstring(x) + L"_" +
std::to_wstring(y) + L"_" +
std::to_wstring(MulDiv(mi.rcWork.right - mi.rcWork.left, 96, dpi_x)) + L"_" +
std::to_wstring(MulDiv(mi.rcWork.bottom - mi.rcWork.top, 96, dpi_y));

const std::wstring params =
iter->second->UniqueId() + L" " +
std::to_wstring(iter->second->ActiveZoneSet()->LayoutId()) + L" " +
std::to_wstring(reinterpret_cast<UINT_PTR>(monitor)) + L" " +
editorLocation + L" " +
iter->second->WorkAreaKey() + L" " +
std::to_wstring(static_cast<float>(dpi_x) / 96.0f);

SHELLEXECUTEINFO sei{ sizeof(sei) };
sei.fMask = { SEE_MASK_NOCLOSEPROCESS | SEE_MASK_FLAG_NO_UI };
sei.lpFile = L"modules\\FancyZonesEditor.exe";
sei.lpParameters = params.c_str();
sei.nShow = SW_SHOWNORMAL;
ShellExecuteEx(&sei);

// Launch the editor on a background thread
// Wait for the editor's process to exit
// Post back to the main thread to update
std::thread waitForEditorThread([window = m_window, processHandle = sei.hProcess, terminateEditorEvent = m_terminateEditorEvent.get()]()
{
HANDLE waitEvents[2] = { processHandle, terminateEditorEvent };
auto result = WaitForMultipleObjects(2, waitEvents, false, INFINITE);
if (result == WAIT_OBJECT_0 + 0)
{
// Editor exited
// Update any changes it may have made
PostMessage(window, WM_PRIV_EDITOR, 0, static_cast<LPARAM>(EditorExitKind::Exit));
}
else if (result == WAIT_OBJECT_0 + 1)
{
// User hit Win+~ while editor is already running
// Shut it down
TerminateProcess(processHandle, 2);
PostMessage(window, WM_PRIV_EDITOR, 0, static_cast<LPARAM>(EditorExitKind::Terminate));
}
CloseHandle(processHandle);
});
waitForEditorThread.detach();
// Editor exited
// Update any changes it may have made
PostMessage(window, WM_PRIV_EDITOR, 0, static_cast<LPARAM>(EditorExitKind::Exit));
}
}
else if (result == WAIT_OBJECT_0 + 1)
{
// User hit Win+~ while editor is already running
// Shut it down
TerminateProcess(processHandle, 2);
PostMessage(window, WM_PRIV_EDITOR, 0, static_cast<LPARAM>(EditorExitKind::Terminate));
}
CloseHandle(processHandle);
});

waitForEditorThread.detach();
}

// IZoneWindowHost
Expand Down Expand Up @@ -723,4 +743,4 @@ void FancyZones::MoveSizeUpdateInternal(HMONITOR monitor, POINT const& ptScreen,
winrt::com_ptr<IFancyZones> MakeFancyZones(HINSTANCE hinstance, IFancyZonesSettings* settings) noexcept
{
return winrt::make_self<FancyZones>(hinstance, settings);
}
}
3 changes: 2 additions & 1 deletion src/modules/fancyzones/lib/Settings.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ struct FancyZonesSettings : winrt::implements<FancyZonesSettings, IFancyZonesSet
PCWSTR name;
bool* value;
int resourceId;
} m_configBools[8] = {
} m_configBools[9] = {
{ L"fancyzones_shiftDrag", &m_settings.shiftDrag, IDS_SETTING_DESCRIPTION_SHIFTDRAG },
{ L"fancyzones_overrideSnapHotkeys", &m_settings.overrideSnapHotkeys, IDS_SETTING_DESCRIPTION_OVERRIDE_SNAP_HOTKEYS },
{ L"fancyzones_zoneSetChange_flashZones", &m_settings.zoneSetChange_flashZones, IDS_SETTING_DESCRIPTION_ZONESETCHANGE_FLASHZONES },
Expand All @@ -41,6 +41,7 @@ struct FancyZonesSettings : winrt::implements<FancyZonesSettings, IFancyZonesSet
{ L"fancyzones_virtualDesktopChange_moveWindows", &m_settings.virtualDesktopChange_moveWindows, IDS_SETTING_DESCRIPTION_VIRTUALDESKTOPCHANGE_MOVEWINDOWS },
{ L"fancyzones_appLastZone_moveWindows", &m_settings.appLastZone_moveWindows, IDS_SETTING_DESCRIPTION_APPLASTZONE_MOVEWINDOWS },
{ L"fancyzones_use_standalone_editor", &m_settings.use_standalone_editor, IDS_SETTING_DESCRIPTION_USE_STANDALONE_EDITOR },
{ L"use_cursorpos_editor_startupscreen", &m_settings.use_cursorpos_editor_startupscreen, IDS_SETTING_DESCRIPTION_USE_CURSORPOS_EDITOR_STARTUPSCREEN },
};

struct
Expand Down
1 change: 1 addition & 0 deletions src/modules/fancyzones/lib/Settings.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ struct Settings
bool overrideSnapHotkeys = false;
bool appLastZone_moveWindows = false;
bool use_standalone_editor = true;
bool use_cursorpos_editor_startupscreen = true;
std::wstring zoneHightlightColor = L"#0078D7";
};

Expand Down
Binary file modified src/modules/fancyzones/lib/fancyzones.rc
Binary file not shown.
9 changes: 5 additions & 4 deletions src/modules/fancyzones/lib/resource.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@
#define IDS_SETTING_DESCRIPTION_ZONEHIGHLIGHTCOLOR 107
#define IDS_SETTING_DESCRIPTION_APPLASTZONE_MOVEWINDOWS 108
#define IDS_SETTING_DESCRIPTION_USE_STANDALONE_EDITOR 109
#define IDS_SETTING_DESCRIPTION 110
#define IDS_SETTING_LAUNCH_EDITOR_LABEL 111
#define IDS_SETTING_LAUNCH_EDITOR_BUTTON 112
#define IDS_SETTING_LAUNCH_EDITOR_DESCRIPTION 113
#define IDS_SETTING_DESCRIPTION_USE_CURSORPOS_EDITOR_STARTUPSCREEN 110
#define IDS_SETTING_DESCRIPTION 111
#define IDS_SETTING_LAUNCH_EDITOR_LABEL 112
#define IDS_SETTING_LAUNCH_EDITOR_BUTTON 113
#define IDS_SETTING_LAUNCH_EDITOR_DESCRIPTION 114

0 comments on commit faf1fae

Please sign in to comment.