Add fullscreen and topmost+fullscreen profile condition modes

New match types for application conditions:
- "fullscreen": app has a fullscreen window on any monitor (detected via
  EnumWindows, works even when another window is focused on a different
  display)
- "topmost_fullscreen": app is the focused foreground window AND fullscreen

Optimizes profile evaluation to only call expensive detection methods when
needed: WMI process enumeration (~3s) is skipped when no condition uses
"running" mode; foreground/fullscreen checks (<1ms each) are called
selectively based on active match types.

Filters false positives from fullscreen detection by excluding desktop/shell
process windows, tool windows, and non-activatable overlay windows.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-02-19 22:26:50 +03:00
parent ff4e054ef8
commit ab8041269e
5 changed files with 204 additions and 25 deletions

View File

@@ -67,7 +67,7 @@ function createProfileCard(profile) {
const parts = profile.conditions.map(c => {
if (c.condition_type === 'application') {
const apps = (c.apps || []).join(', ');
const matchLabel = c.match_type === 'topmost' ? t('profiles.condition.application.match_type.topmost') : t('profiles.condition.application.match_type.running');
const matchLabel = t('profiles.condition.application.match_type.' + (c.match_type || 'running'));
return `<span class="stream-card-prop stream-card-prop-full">${t('profiles.condition.application')}: ${apps} (${matchLabel})</span>`;
}
return `<span class="stream-card-prop">${c.condition_type}</span>`;
@@ -212,6 +212,8 @@ function addProfileConditionRow(condition) {
<select class="condition-match-type">
<option value="running" ${matchType === 'running' ? 'selected' : ''}>${t('profiles.condition.application.match_type.running')}</option>
<option value="topmost" ${matchType === 'topmost' ? 'selected' : ''}>${t('profiles.condition.application.match_type.topmost')}</option>
<option value="topmost_fullscreen" ${matchType === 'topmost_fullscreen' ? 'selected' : ''}>${t('profiles.condition.application.match_type.topmost_fullscreen')}</option>
<option value="fullscreen" ${matchType === 'fullscreen' ? 'selected' : ''}>${t('profiles.condition.application.match_type.fullscreen')}</option>
</select>
</div>
<div class="condition-field">