diff --git a/effects/presentwindows/presentwindows.h b/effects/presentwindows/presentwindows.h --- a/effects/presentwindows/presentwindows.h +++ b/effects/presentwindows/presentwindows.h @@ -87,6 +87,7 @@ Q_PROPERTY(int leftButtonDesktop READ leftButtonDesktop) Q_PROPERTY(int middleButtonDesktop READ middleButtonDesktop) Q_PROPERTY(int rightButtonDesktop READ rightButtonDesktop) + Q_PROPERTY(bool preciseMatch READ isPreciseMatch) // TODO: electric borders private: // Structures @@ -186,6 +187,9 @@ bool isShowPanel() const { return m_showPanel; } + bool isPreciseMatch() const { + return m_preciseMatch; + } int leftButtonWindow() const { return m_leftButtonWindow; } @@ -288,6 +292,7 @@ bool m_fillGaps; double m_fadeDuration; bool m_showPanel; + bool m_preciseMatch; // Activation bool m_activated; diff --git a/effects/presentwindows/presentwindows.cpp b/effects/presentwindows/presentwindows.cpp --- a/effects/presentwindows/presentwindows.cpp +++ b/effects/presentwindows/presentwindows.cpp @@ -162,6 +162,7 @@ m_leftButtonDesktop = (DesktopMouseAction)PresentWindowsConfig::leftButtonDesktop(); m_middleButtonDesktop = (DesktopMouseAction)PresentWindowsConfig::middleButtonDesktop(); m_rightButtonDesktop = (DesktopMouseAction)PresentWindowsConfig::rightButtonDesktop(); + m_preciseMatch = PresentWindowsConfig::preciseMatch(); // touch screen edges const QVector relevantBorders{ElectricLeft, ElectricTop, ElectricRight, ElectricBottom}; @@ -904,6 +905,39 @@ //----------------------------------------------------------------------------- // Window rearranging +namespace { + bool titleMatchesUnpreciseFilter(const QString& title, const QString& filter) { + auto it = std::begin(title); + + for (const QChar f: filter) { + it = std::find_if(it, std::end(title), [f](QChar c){ return c.toLower() == f.toLower(); }); + + if (it == std::end(title)) + return false; + + it++; + } + + return true; + } + + bool preciseMatchFilter(EffectWindow *w, const QString& filter) { + return w->caption().contains(filter, Qt::CaseInsensitive) || + w->windowClass().contains(filter, Qt::CaseInsensitive) || + w->windowRole().contains(filter, Qt::CaseInsensitive); + } + + bool impreciseMatchFilter(EffectWindow *w, const QString& filter) { + return titleMatchesUnpreciseFilter(w->caption(), filter) || + titleMatchesUnpreciseFilter(w->windowClass(), filter) || + titleMatchesUnpreciseFilter(w->windowRole(), filter); + } + + bool titleMatchesFilter(EffectWindow *w, const QString& filter, bool preciseMatch) { + return preciseMatch ? preciseMatchFilter(w, filter) : impreciseMatchFilter(w, filter); + } +} + void PresentWindowsEffect::rearrangeWindows() { if (!m_activated) @@ -934,9 +968,7 @@ DataHash::iterator winData = m_windowData.find(w); if (winData == m_windowData.end() || winData->deleted) continue; // don't include closed windows - if (w->caption().contains(m_windowFilter, Qt::CaseInsensitive) || - w->windowClass().contains(m_windowFilter, Qt::CaseInsensitive) || - w->windowRole().contains(m_windowFilter, Qt::CaseInsensitive)) { + if (titleMatchesFilter(w, m_windowFilter, m_preciseMatch)) { windowlist.append(w); windowlists[w->screen()].append(w); winData->visible = true; diff --git a/effects/presentwindows/presentwindows.kcfg b/effects/presentwindows/presentwindows.kcfg --- a/effects/presentwindows/presentwindows.kcfg +++ b/effects/presentwindows/presentwindows.kcfg @@ -23,6 +23,9 @@ false + + true + 1 diff --git a/effects/presentwindows/presentwindows_config.ui b/effects/presentwindows/presentwindows_config.ui --- a/effects/presentwindows/presentwindows_config.ui +++ b/effects/presentwindows/presentwindows_config.ui @@ -418,6 +418,13 @@ + + + + Use precise match + + + @@ -474,6 +481,7 @@ kcfg_DrawWindowIcons kcfg_AllowClosingWindows kcfg_IgnoreMinimized + kcfg_PreciseMatch kcfg_Accuracy kcfg_FillGaps