mirror of
https://github.com/microsoft/PowerToys.git
synced 2026-04-05 10:46:33 +02:00
ShortcutGuide, FancyZones: split window filtering (#1225)
Splits the code use to filter windows for FancyZones and the "active window" for the ShortcutGuide. The FancyZones logic is preserved and merged into a single function. We keep it in common.h, as it might be also used in other PowerToys, like maximized to new desktop. We do however change the return type to be more descriptive. It also returns a separate flag for if the window has a visible owner. This can be used to implement the approved apps list. For the ShortcutGuide, the logic is relaxed to include more windows. One example are Explorer properties windows. Those are (and should) filtered by the FancyZones, but should appear in the window preview in the SCG. The new return type also includes information if the window will react to the default Windows Snap. This is not ideal though. Currently, SCG can only disable the entire "Windows Controls" group. OTOH windows like "Save As..." dialogs can be snapped to corners etc., but cannot be minimized nor maximized. Until SCG can separately disable those buttons we will display the buttons in the enabled state only if the window supports all settings. In the future, we should integrate FancyZones snap override here too.
This commit is contained in:
committed by
GitHub
parent
f963d28ba8
commit
0fdc1d0a1f
@@ -592,53 +592,20 @@ LRESULT CALLBACK FancyZones::s_WndProc(HWND window, UINT message, WPARAM wparam,
|
||||
DefWindowProc(window, message, wparam, lparam);
|
||||
}
|
||||
|
||||
static bool HasVisibleOwner(HWND window) noexcept
|
||||
{
|
||||
auto owner = GetWindow(window, GW_OWNER);
|
||||
if (owner == nullptr)
|
||||
{
|
||||
return false; // There is no owner at all
|
||||
}
|
||||
if (!IsWindowVisible(owner))
|
||||
{
|
||||
return false; // Owner is invisible
|
||||
}
|
||||
RECT rect;
|
||||
if (!GetWindowRect(owner, &rect))
|
||||
{
|
||||
return true; // Could not get the rect, return true (and filter out the window) just in case
|
||||
}
|
||||
// Return false (and allow the window to be zonable) if the owner window size is zero
|
||||
return rect.top != rect.bottom || rect.left != rect.right;
|
||||
}
|
||||
|
||||
bool FancyZones::IsInterestingWindow(HWND window) noexcept
|
||||
{
|
||||
auto style = GetWindowLongPtr(window, GWL_STYLE);
|
||||
auto exStyle = GetWindowLongPtr(window, GWL_EXSTYLE);
|
||||
// Ignore:
|
||||
if (GetAncestor(window, GA_ROOT) != window || // windows that are not top-level
|
||||
HasVisibleOwner(window) || // windows that have an visible owner - like Save As dialogs
|
||||
(style & WS_CHILD) != 0 || // windows that are child elements of other windows - like buttons
|
||||
(style & WS_DISABLED) != 0 || // windows that are disabled
|
||||
(exStyle & WS_EX_TOOLWINDOW) != 0 || // toolbar windows
|
||||
!IsWindowVisible(window)) // invisible windows
|
||||
{
|
||||
return false;
|
||||
}
|
||||
// Filter some windows like the Start menu or Cortana
|
||||
auto windowAndPath = get_filtered_base_window_and_path(window);
|
||||
if (windowAndPath.hwnd == nullptr)
|
||||
auto filtered = get_fancyzones_filtered_window(window);
|
||||
if (!filtered.zonable)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
// Filter out user specified apps
|
||||
CharUpperBuffW(windowAndPath.process_path.data(), (DWORD)windowAndPath.process_path.length());
|
||||
CharUpperBuffW(filtered.process_path.data(), (DWORD)filtered.process_path.length());
|
||||
if (m_settings)
|
||||
{
|
||||
for (const auto& excluded : m_settings->GetSettings().excludedAppsArray)
|
||||
{
|
||||
if (windowAndPath.process_path.find(excluded) != std::wstring::npos)
|
||||
if (filtered.process_path.find(excluded) != std::wstring::npos)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -210,11 +210,12 @@ D2DOverlayWindow::D2DOverlayWindow() :
|
||||
});
|
||||
}
|
||||
|
||||
void D2DOverlayWindow::show(HWND active_window)
|
||||
void D2DOverlayWindow::show(HWND active_window, bool snappable)
|
||||
{
|
||||
std::unique_lock lock(mutex);
|
||||
tasklist_buttons.clear();
|
||||
this->active_window = active_window;
|
||||
this->active_window_snappable = snappable;
|
||||
auto old_bck = colors.start_color_menu;
|
||||
auto colors_updated = colors.update();
|
||||
auto new_light_mode = (theme_setting == Light) || (theme_setting == System && colors.light_mode);
|
||||
@@ -861,7 +862,7 @@ void D2DOverlayWindow::render(ID2D1DeviceContext5* d2d_dc)
|
||||
down = GET_RESOURCE_STRING(IDS_NO_ACTION);
|
||||
down_disabled = true;
|
||||
}
|
||||
auto text_color = D2D1::ColorF(light_mode ? 0x222222 : 0xDDDDDD, minature_shown || window_state == MINIMIZED ? 1.0f : 0.3f);
|
||||
auto text_color = D2D1::ColorF(light_mode ? 0x222222 : 0xDDDDDD, active_window_snappable && (minature_shown || window_state == MINIMIZED) ? 1.0f : 0.3f);
|
||||
use_overlay->find_element(L"KeyUpGroup")->SetAttributeValue(L"fill-opacity", up_disabled ? 0.3f : 1.0f);
|
||||
text.set_aligment_center().write(d2d_dc, text_color, use_overlay->get_maximize_label(), up);
|
||||
use_overlay->find_element(L"KeyDownGroup")->SetAttributeValue(L"fill-opacity", down_disabled ? 0.3f : 1.0f);
|
||||
|
||||
@@ -47,7 +47,7 @@ class D2DOverlayWindow : public D2DWindow
|
||||
{
|
||||
public:
|
||||
D2DOverlayWindow();
|
||||
void show(HWND active_window);
|
||||
void show(HWND active_window, bool snappable);
|
||||
void animate(int vk_code);
|
||||
~D2DOverlayWindow();
|
||||
void apply_overlay_opacity(float opacity);
|
||||
@@ -84,6 +84,7 @@ private:
|
||||
|
||||
HTHUMBNAIL thumbnail;
|
||||
HWND active_window = nullptr;
|
||||
bool active_window_snappable = false;
|
||||
D2DOverlaySVG landscape, portrait;
|
||||
D2DOverlaySVG* use_overlay = nullptr;
|
||||
D2DSVG no_active;
|
||||
|
||||
@@ -158,8 +158,8 @@ intptr_t OverlayWindow::signal_event(const wchar_t* name, intptr_t data)
|
||||
|
||||
void OverlayWindow::on_held()
|
||||
{
|
||||
auto active_window = get_filtered_active_window();
|
||||
winkey_popup->show(active_window);
|
||||
auto filter = get_shortcutguide_filtered_window();
|
||||
winkey_popup->show(filter.hwnd, filter.snappable);
|
||||
}
|
||||
|
||||
void OverlayWindow::on_held_press(DWORD vkCode)
|
||||
|
||||
Reference in New Issue
Block a user