mirror of
https://github.com/microsoft/PowerToys.git
synced 2025-12-16 11:48:06 +01:00
moved utils to common
This commit is contained in:
@@ -11,7 +11,10 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "projects-common", "projects
|
|||||||
projects-common\GuidUtils.h = projects-common\GuidUtils.h
|
projects-common\GuidUtils.h = projects-common\GuidUtils.h
|
||||||
projects-common\json.h = projects-common\json.h
|
projects-common\json.h = projects-common\json.h
|
||||||
projects-common\MonitorEnumerator.h = projects-common\MonitorEnumerator.h
|
projects-common\MonitorEnumerator.h = projects-common\MonitorEnumerator.h
|
||||||
|
projects-common\VirtualDesktop.h = projects-common\VirtualDesktop.h
|
||||||
projects-common\WindowEnumerator.h = projects-common\WindowEnumerator.h
|
projects-common\WindowEnumerator.h = projects-common\WindowEnumerator.h
|
||||||
|
projects-common\WindowFilter.h = projects-common\WindowFilter.h
|
||||||
|
projects-common\WindowUtils.h = projects-common\WindowUtils.h
|
||||||
EndProjectSection
|
EndProjectSection
|
||||||
EndProject
|
EndProject
|
||||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ProjectsLauncher", "ProjectsLauncher\ProjectsLauncher.vcxproj", "{2CAC093E-5FCF-4102-9C2C-AC7DD5D9EB96}"
|
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ProjectsLauncher", "ProjectsLauncher\ProjectsLauncher.vcxproj", "{2CAC093E-5FCF-4102-9C2C-AC7DD5D9EB96}"
|
||||||
|
|||||||
@@ -119,9 +119,6 @@
|
|||||||
<ClInclude Include="OnThreadExecutor.h" />
|
<ClInclude Include="OnThreadExecutor.h" />
|
||||||
<ClInclude Include="PackagedAppUtils.h" />
|
<ClInclude Include="PackagedAppUtils.h" />
|
||||||
<ClInclude Include="pch.h" />
|
<ClInclude Include="pch.h" />
|
||||||
<ClInclude Include="VirtualDesktop.h" />
|
|
||||||
<ClInclude Include="WindowFilter.h" />
|
|
||||||
<ClInclude Include="WindowUtils.h" />
|
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClCompile Include="main.cpp" />
|
<ClCompile Include="main.cpp" />
|
||||||
@@ -131,8 +128,6 @@
|
|||||||
<ClCompile Include="pch.cpp">
|
<ClCompile Include="pch.cpp">
|
||||||
<PrecompiledHeader>Create</PrecompiledHeader>
|
<PrecompiledHeader>Create</PrecompiledHeader>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<ClCompile Include="VirtualDesktop.cpp" />
|
|
||||||
<ClCompile Include="WindowUtils.cpp" />
|
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<None Include="packages.config" />
|
<None Include="packages.config" />
|
||||||
|
|||||||
@@ -18,15 +18,6 @@
|
|||||||
<ClInclude Include="pch.h">
|
<ClInclude Include="pch.h">
|
||||||
<Filter>Header Files</Filter>
|
<Filter>Header Files</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
<ClInclude Include="VirtualDesktop.h">
|
|
||||||
<Filter>Header Files</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="WindowFilter.h">
|
|
||||||
<Filter>Header Files</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="WindowUtils.h">
|
|
||||||
<Filter>Header Files</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="MonitorUtils.h">
|
<ClInclude Include="MonitorUtils.h">
|
||||||
<Filter>Header Files</Filter>
|
<Filter>Header Files</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
@@ -44,12 +35,6 @@
|
|||||||
<ClCompile Include="main.cpp">
|
<ClCompile Include="main.cpp">
|
||||||
<Filter>Source Files</Filter>
|
<Filter>Source Files</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<ClCompile Include="VirtualDesktop.cpp">
|
|
||||||
<Filter>Source Files</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="WindowUtils.cpp">
|
|
||||||
<Filter>Source Files</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="MonitorUtils.cpp">
|
<ClCompile Include="MonitorUtils.cpp">
|
||||||
<Filter>Source Files</Filter>
|
<Filter>Source Files</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
|||||||
@@ -1,39 +0,0 @@
|
|||||||
#include "pch.h"
|
|
||||||
#include "VirtualDesktop.h"
|
|
||||||
|
|
||||||
#include <iostream>
|
|
||||||
|
|
||||||
VirtualDesktop::VirtualDesktop()
|
|
||||||
{
|
|
||||||
auto res = CoCreateInstance(CLSID_VirtualDesktopManager, nullptr, CLSCTX_ALL, IID_PPV_ARGS(&m_vdManager));
|
|
||||||
if (FAILED(res))
|
|
||||||
{
|
|
||||||
// Logger::error("Failed to create VirtualDesktopManager instance");
|
|
||||||
std::cout << "Failed to create VirtualDesktopManager instance\n";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
VirtualDesktop::~VirtualDesktop()
|
|
||||||
{
|
|
||||||
if (m_vdManager)
|
|
||||||
{
|
|
||||||
m_vdManager->Release();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
VirtualDesktop& VirtualDesktop::instance()
|
|
||||||
{
|
|
||||||
static VirtualDesktop self;
|
|
||||||
return self;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool VirtualDesktop::IsWindowOnCurrentDesktop(HWND window) const
|
|
||||||
{
|
|
||||||
BOOL isWindowOnCurrentDesktop = false;
|
|
||||||
if (m_vdManager)
|
|
||||||
{
|
|
||||||
m_vdManager->IsWindowOnCurrentVirtualDesktop(window, &isWindowOnCurrentDesktop);
|
|
||||||
}
|
|
||||||
|
|
||||||
return isWindowOnCurrentDesktop;
|
|
||||||
}
|
|
||||||
@@ -1,20 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include <windows.h>
|
|
||||||
#include <ShObjIdl.h>
|
|
||||||
|
|
||||||
class VirtualDesktop
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
static VirtualDesktop& instance();
|
|
||||||
|
|
||||||
bool IsWindowOnCurrentDesktop(HWND window) const;
|
|
||||||
|
|
||||||
private:
|
|
||||||
VirtualDesktop();
|
|
||||||
~VirtualDesktop();
|
|
||||||
|
|
||||||
IVirtualDesktopManager* m_vdManager{ nullptr };
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
@@ -1,114 +0,0 @@
|
|||||||
#include "pch.h"
|
|
||||||
#include "WindowUtils.h"
|
|
||||||
|
|
||||||
#include <ShellScalingApi.h>
|
|
||||||
|
|
||||||
namespace Common
|
|
||||||
{
|
|
||||||
namespace Display
|
|
||||||
{
|
|
||||||
namespace DPIAware
|
|
||||||
{
|
|
||||||
constexpr inline int DEFAULT_DPI = 96;
|
|
||||||
|
|
||||||
void InverseConvert(HMONITOR monitor_handle, float& width, float& height)
|
|
||||||
{
|
|
||||||
if (monitor_handle == NULL)
|
|
||||||
{
|
|
||||||
const POINT ptZero = { 0, 0 };
|
|
||||||
monitor_handle = MonitorFromPoint(ptZero, MONITOR_DEFAULTTOPRIMARY);
|
|
||||||
}
|
|
||||||
|
|
||||||
UINT dpi_x, dpi_y;
|
|
||||||
if (GetDpiForMonitor(monitor_handle, MDT_EFFECTIVE_DPI, &dpi_x, &dpi_y) == S_OK)
|
|
||||||
{
|
|
||||||
width = width * DPIAware::DEFAULT_DPI / dpi_x;
|
|
||||||
height = height * DPIAware::DEFAULT_DPI / dpi_y;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
namespace WindowUtils
|
|
||||||
{
|
|
||||||
// Non-Localizable strings
|
|
||||||
namespace NonLocalizable
|
|
||||||
{
|
|
||||||
const wchar_t SystemAppsFolder[] = L"SYSTEMAPPS";
|
|
||||||
const wchar_t System[] = L"WINDOWS/SYSTEM";
|
|
||||||
const wchar_t System32[] = L"SYSTEM32";
|
|
||||||
const wchar_t SystemWOW64[] = L"SYSTEMWOW64";
|
|
||||||
const char SplashClassName[] = "MsoSplash";
|
|
||||||
const wchar_t CoreWindow[] = L"WINDOWS.UI.CORE.COREWINDOW";
|
|
||||||
const wchar_t SearchUI[] = L"SEARCHUI.EXE";
|
|
||||||
const wchar_t ProjectsSnapshotTool[] = L"PROJECTSSNAPSHOTTOOL";
|
|
||||||
const wchar_t ProjectsEditor[] = L"PROJECTSEDITOR";
|
|
||||||
const wchar_t ProjectsLauncher[] = L"PROJECTSLAUNCHER";
|
|
||||||
}
|
|
||||||
|
|
||||||
bool IsRoot(HWND window) noexcept
|
|
||||||
{
|
|
||||||
return GetAncestor(window, GA_ROOT) == window;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool IsMaximized(HWND window) noexcept
|
|
||||||
{
|
|
||||||
WINDOWPLACEMENT placement{};
|
|
||||||
if (GetWindowPlacement(window, &placement) &&
|
|
||||||
placement.showCmd == SW_SHOWMAXIMIZED)
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool IsExcludedByDefault(HWND window, const std::wstring& processPath, const std::wstring& title)
|
|
||||||
{
|
|
||||||
std::wstring processPathUpper = processPath;
|
|
||||||
CharUpperBuffW(processPathUpper.data(), static_cast<DWORD>(processPathUpper.length()));
|
|
||||||
|
|
||||||
static std::vector<std::wstring> defaultExcludedFolders = { NonLocalizable::SystemAppsFolder, NonLocalizable::System, NonLocalizable::System32, NonLocalizable::SystemWOW64 };
|
|
||||||
if (Common::Utils::ExcludedApps::find_folder_in_path(processPathUpper, defaultExcludedFolders))
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::array<char, 256> className;
|
|
||||||
GetClassNameA(window, className.data(), static_cast<int>(className.size()));
|
|
||||||
if (Common::Utils::Window::is_system_window(window, className.data()))
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (strcmp(NonLocalizable::SplashClassName, className.data()) == 0)
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
static std::vector<std::wstring> defaultExcludedApps = { NonLocalizable::CoreWindow, NonLocalizable::SearchUI, NonLocalizable::ProjectsEditor, NonLocalizable::ProjectsLauncher, NonLocalizable::ProjectsSnapshotTool };
|
|
||||||
return (Common::Utils::ExcludedApps::check_excluded_app(processPathUpper, title, defaultExcludedApps));
|
|
||||||
}
|
|
||||||
|
|
||||||
RECT GetWindowRect(HWND window)
|
|
||||||
{
|
|
||||||
RECT rect;
|
|
||||||
if (GetWindowRect(window, &rect))
|
|
||||||
{
|
|
||||||
float width = static_cast<float>(rect.right - rect.left);
|
|
||||||
float height = static_cast<float>(rect.bottom - rect.top);
|
|
||||||
float originX = static_cast<float>(rect.left);
|
|
||||||
float originY = static_cast<float>(rect.top);
|
|
||||||
|
|
||||||
Common::Display::DPIAware::InverseConvert(MonitorFromWindow(window, MONITOR_DEFAULTTONULL), width, height);
|
|
||||||
Common::Display::DPIAware::InverseConvert(MonitorFromWindow(window, MONITOR_DEFAULTTONULL), originX, originY);
|
|
||||||
|
|
||||||
return RECT(static_cast<LONG>(std::roundf(originX)),
|
|
||||||
static_cast<LONG>(std::roundf(originY)),
|
|
||||||
static_cast<LONG>(std::roundf(originX + width)),
|
|
||||||
static_cast<LONG>(std::roundf(originY + height)));
|
|
||||||
}
|
|
||||||
|
|
||||||
return rect;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
#include "pch.h"
|
#include "pch.h"
|
||||||
|
|
||||||
#include <chrono>
|
#include <chrono>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
@@ -6,10 +6,10 @@
|
|||||||
#include "../projects-common/Data.h"
|
#include "../projects-common/Data.h"
|
||||||
#include "../projects-common/GuidUtils.h"
|
#include "../projects-common/GuidUtils.h"
|
||||||
#include "../projects-common/WindowEnumerator.h"
|
#include "../projects-common/WindowEnumerator.h"
|
||||||
|
#include "../projects-common/WindowFilter.h"
|
||||||
|
|
||||||
#include "MonitorUtils.h"
|
#include "MonitorUtils.h"
|
||||||
#include "PackagedAppUtils.h"
|
#include "PackagedAppUtils.h"
|
||||||
#include "WindowFilter.h"
|
|
||||||
|
|
||||||
int main(int argc, char* argv[])
|
int main(int argc, char* argv[])
|
||||||
{
|
{
|
||||||
|
|||||||
49
src/modules/Projects/projects-common/VirtualDesktop.h
Normal file
49
src/modules/Projects/projects-common/VirtualDesktop.h
Normal file
@@ -0,0 +1,49 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <windows.h>
|
||||||
|
#include <ShObjIdl.h>
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
class VirtualDesktop
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
static VirtualDesktop& instance()
|
||||||
|
{
|
||||||
|
static VirtualDesktop self;
|
||||||
|
return self;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool IsWindowOnCurrentDesktop(HWND window) const
|
||||||
|
{
|
||||||
|
BOOL isWindowOnCurrentDesktop = false;
|
||||||
|
if (m_vdManager)
|
||||||
|
{
|
||||||
|
m_vdManager->IsWindowOnCurrentVirtualDesktop(window, &isWindowOnCurrentDesktop);
|
||||||
|
}
|
||||||
|
|
||||||
|
return isWindowOnCurrentDesktop;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
VirtualDesktop()
|
||||||
|
{
|
||||||
|
auto res = CoCreateInstance(CLSID_VirtualDesktopManager, nullptr, CLSCTX_ALL, IID_PPV_ARGS(&m_vdManager));
|
||||||
|
if (FAILED(res))
|
||||||
|
{
|
||||||
|
// Logger::error("Failed to create VirtualDesktopManager instance");
|
||||||
|
std::cout << "Failed to create VirtualDesktopManager instance\n";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
~VirtualDesktop()
|
||||||
|
{
|
||||||
|
if (m_vdManager)
|
||||||
|
{
|
||||||
|
m_vdManager->Release();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
IVirtualDesktopManager* m_vdManager{ nullptr };
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
@@ -1,6 +1,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <Windows.h>
|
#include <Windows.h>
|
||||||
|
#include <ShellScalingApi.h>
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
|
||||||
@@ -10,7 +11,23 @@ namespace Common
|
|||||||
{
|
{
|
||||||
namespace DPIAware
|
namespace DPIAware
|
||||||
{
|
{
|
||||||
void InverseConvert(HMONITOR monitor_handle, float& width, float& height);
|
constexpr inline int DEFAULT_DPI = 96;
|
||||||
|
|
||||||
|
inline void InverseConvert(HMONITOR monitor_handle, float& width, float& height)
|
||||||
|
{
|
||||||
|
if (monitor_handle == NULL)
|
||||||
|
{
|
||||||
|
const POINT ptZero = { 0, 0 };
|
||||||
|
monitor_handle = MonitorFromPoint(ptZero, MONITOR_DEFAULTTOPRIMARY);
|
||||||
|
}
|
||||||
|
|
||||||
|
UINT dpi_x, dpi_y;
|
||||||
|
if (GetDpiForMonitor(monitor_handle, MDT_EFFECTIVE_DPI, &dpi_x, &dpi_y) == S_OK)
|
||||||
|
{
|
||||||
|
width = width * DPIAware::DEFAULT_DPI / dpi_x;
|
||||||
|
height = height * DPIAware::DEFAULT_DPI / dpi_y;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -188,17 +205,90 @@ namespace Common
|
|||||||
// FancyZones WindowUtils
|
// FancyZones WindowUtils
|
||||||
namespace WindowUtils
|
namespace WindowUtils
|
||||||
{
|
{
|
||||||
bool IsRoot(HWND window) noexcept;
|
// Non-Localizable strings
|
||||||
bool IsMaximized(HWND window) noexcept;
|
namespace NonLocalizable
|
||||||
|
{
|
||||||
|
const wchar_t SystemAppsFolder[] = L"SYSTEMAPPS";
|
||||||
|
const wchar_t System[] = L"WINDOWS/SYSTEM";
|
||||||
|
const wchar_t System32[] = L"SYSTEM32";
|
||||||
|
const wchar_t SystemWOW64[] = L"SYSTEMWOW64";
|
||||||
|
const char SplashClassName[] = "MsoSplash";
|
||||||
|
const wchar_t CoreWindow[] = L"WINDOWS.UI.CORE.COREWINDOW";
|
||||||
|
const wchar_t SearchUI[] = L"SEARCHUI.EXE";
|
||||||
|
const wchar_t ProjectsSnapshotTool[] = L"PROJECTSSNAPSHOTTOOL";
|
||||||
|
const wchar_t ProjectsEditor[] = L"PROJECTSEDITOR";
|
||||||
|
const wchar_t ProjectsLauncher[] = L"PROJECTSLAUNCHER";
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool IsRoot(HWND window) noexcept
|
||||||
|
{
|
||||||
|
return GetAncestor(window, GA_ROOT) == window;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool IsMaximized(HWND window) noexcept
|
||||||
|
{
|
||||||
|
WINDOWPLACEMENT placement{};
|
||||||
|
if (GetWindowPlacement(window, &placement) &&
|
||||||
|
placement.showCmd == SW_SHOWMAXIMIZED)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
constexpr bool HasStyle(LONG style, LONG styleToCheck) noexcept
|
constexpr bool HasStyle(LONG style, LONG styleToCheck) noexcept
|
||||||
{
|
{
|
||||||
return ((style & styleToCheck) == styleToCheck);
|
return ((style & styleToCheck) == styleToCheck);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool IsExcludedByDefault(HWND window, const std::wstring& processPath, const std::wstring& title);
|
inline bool IsExcludedByDefault(HWND window, const std::wstring& processPath, const std::wstring& title)
|
||||||
|
{
|
||||||
|
std::wstring processPathUpper = processPath;
|
||||||
|
CharUpperBuffW(processPathUpper.data(), static_cast<DWORD>(processPathUpper.length()));
|
||||||
|
|
||||||
RECT GetWindowRect(HWND window);
|
static std::vector<std::wstring> defaultExcludedFolders = { NonLocalizable::SystemAppsFolder, NonLocalizable::System, NonLocalizable::System32, NonLocalizable::SystemWOW64 };
|
||||||
|
if (Common::Utils::ExcludedApps::find_folder_in_path(processPathUpper, defaultExcludedFolders))
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::array<char, 256> className;
|
||||||
|
GetClassNameA(window, className.data(), static_cast<int>(className.size()));
|
||||||
|
if (Common::Utils::Window::is_system_window(window, className.data()))
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (strcmp(NonLocalizable::SplashClassName, className.data()) == 0)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static std::vector<std::wstring> defaultExcludedApps = { NonLocalizable::CoreWindow, NonLocalizable::SearchUI, NonLocalizable::ProjectsEditor, NonLocalizable::ProjectsLauncher, NonLocalizable::ProjectsSnapshotTool };
|
||||||
|
return (Common::Utils::ExcludedApps::check_excluded_app(processPathUpper, title, defaultExcludedApps));
|
||||||
|
}
|
||||||
|
|
||||||
|
inline RECT GetWindowRect(HWND window)
|
||||||
|
{
|
||||||
|
RECT rect;
|
||||||
|
if (GetWindowRect(window, &rect))
|
||||||
|
{
|
||||||
|
float width = static_cast<float>(rect.right - rect.left);
|
||||||
|
float height = static_cast<float>(rect.bottom - rect.top);
|
||||||
|
float originX = static_cast<float>(rect.left);
|
||||||
|
float originY = static_cast<float>(rect.top);
|
||||||
|
|
||||||
|
Common::Display::DPIAware::InverseConvert(MonitorFromWindow(window, MONITOR_DEFAULTTONULL), width, height);
|
||||||
|
Common::Display::DPIAware::InverseConvert(MonitorFromWindow(window, MONITOR_DEFAULTTONULL), originX, originY);
|
||||||
|
|
||||||
|
return RECT(static_cast<LONG>(std::roundf(originX)),
|
||||||
|
static_cast<LONG>(std::roundf(originY)),
|
||||||
|
static_cast<LONG>(std::roundf(originX + width)),
|
||||||
|
static_cast<LONG>(std::roundf(originY + height)));
|
||||||
|
}
|
||||||
|
|
||||||
|
return rect;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// addition for Projects
|
// addition for Projects
|
||||||
Reference in New Issue
Block a user