Make windowview replace present windows
* give windowview the ability to show windows from current desktop, all desktops or current class * invokable from shortcuts screen edges or gestures * add a search field to quickly filter * current present windows effect still present but only internal as is used by desktop grid, which should eventually be ported as well This can be done either from windowview or overview, tough note that some of the duplication from overview added in windowview is necessary regardless, as WindowHeap, the shared qml part needs some properties exposed from the c++ part. Implementation wise I'm ok for it being in either place, but i think the functionality of present windows needs to be preserved, otherwise would be a completely unacceptable regression, namely: * Behavior of what now are the ctrl+f7,f10 and f11 global shortcuts, showing windows of current app (invokable by shoortcut instead of having to use the pointer), windows of current desktop (the only thing overview does atm) or all desktops * filter on typing, as opposed to invoking krunner. main use case of present windows is quickly switching, and filtering is the most helpful feature, some people do like krunner instead, but is completely out of place for my use case, and i suspect for many other users as well * also clicking on a taskbar group should be possible to filter * the view that opens by clicking on a taskbar group should follow the same layout strategy used elsewhere and currently being an effect used only there and not accessible form the list can't even be configured
This commit is contained in:
parent
2c514ac593
commit
376ee357db
20 changed files with 789 additions and 237 deletions
|
@ -70,6 +70,6 @@
|
||||||
},
|
},
|
||||||
"X-KDE-ConfigModule": "kwin_presentwindows_config",
|
"X-KDE-ConfigModule": "kwin_presentwindows_config",
|
||||||
"org.kde.kwin.effect": {
|
"org.kde.kwin.effect": {
|
||||||
"video": "https://files.kde.org/plasma/kwin/effect-videos/present_windows.mp4"
|
"internal": true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -52,9 +52,6 @@ PresentWindowsEffect::PresentWindowsEffect()
|
||||||
, m_lastPresentTime(std::chrono::milliseconds::zero())
|
, m_lastPresentTime(std::chrono::milliseconds::zero())
|
||||||
, m_filterFrame(nullptr)
|
, m_filterFrame(nullptr)
|
||||||
, m_closeView(nullptr)
|
, m_closeView(nullptr)
|
||||||
, m_exposeAction(new QAction(this))
|
|
||||||
, m_exposeAllAction(new QAction(this))
|
|
||||||
, m_exposeClassAction(new QAction(this))
|
|
||||||
{
|
{
|
||||||
initConfig<PresentWindowsConfig>();
|
initConfig<PresentWindowsConfig>();
|
||||||
|
|
||||||
|
@ -66,43 +63,6 @@ PresentWindowsEffect::PresentWindowsEffect()
|
||||||
announceSupportProperties();
|
announceSupportProperties();
|
||||||
connect(effects, &EffectsHandler::xcbConnectionChanged, this, announceSupportProperties);
|
connect(effects, &EffectsHandler::xcbConnectionChanged, this, announceSupportProperties);
|
||||||
|
|
||||||
QAction *exposeAction = m_exposeAction;
|
|
||||||
exposeAction->setObjectName(QStringLiteral("Expose"));
|
|
||||||
exposeAction->setText(i18n("Toggle Present Windows (Current desktop)"));
|
|
||||||
KGlobalAccel::self()->setDefaultShortcut(exposeAction, QList<QKeySequence>() << (Qt::CTRL | Qt::Key_F9));
|
|
||||||
KGlobalAccel::self()->setShortcut(exposeAction, QList<QKeySequence>() << (Qt::CTRL | Qt::Key_F9));
|
|
||||||
shortcut = KGlobalAccel::self()->shortcut(exposeAction);
|
|
||||||
effects->registerGlobalShortcut(Qt::CTRL | Qt::Key_F9, exposeAction);
|
|
||||||
connect(exposeAction, &QAction::triggered, this, &PresentWindowsEffect::toggleActive);
|
|
||||||
|
|
||||||
QAction *exposeAllAction = m_exposeAllAction;
|
|
||||||
exposeAllAction->setObjectName(QStringLiteral("ExposeAll"));
|
|
||||||
exposeAllAction->setText(i18n("Toggle Present Windows (All desktops)"));
|
|
||||||
KGlobalAccel::self()->setDefaultShortcut(exposeAllAction, QList<QKeySequence>() << (Qt::CTRL | Qt::Key_F10) << Qt::Key_LaunchC);
|
|
||||||
KGlobalAccel::self()->setShortcut(exposeAllAction, QList<QKeySequence>() << (Qt::CTRL | Qt::Key_F10) << Qt::Key_LaunchC);
|
|
||||||
shortcutAll = KGlobalAccel::self()->shortcut(exposeAllAction);
|
|
||||||
effects->registerGlobalShortcut(Qt::CTRL + Qt::Key_F10, exposeAllAction);
|
|
||||||
connect(exposeAllAction, &QAction::triggered, this, &PresentWindowsEffect::toggleActiveAllDesktops);
|
|
||||||
|
|
||||||
effects->registerRealtimeTouchpadSwipeShortcut(SwipeDirection::Down, 4, new QAction(this), [this](qreal progress) {
|
|
||||||
m_mode = ModeAllDesktops;
|
|
||||||
if (progress > .2 && !m_activated) {
|
|
||||||
setActive(true);
|
|
||||||
} else if (progress <= .2 && m_activated) {
|
|
||||||
setActive(false);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
QAction *exposeClassAction = m_exposeClassAction;
|
|
||||||
exposeClassAction->setObjectName(QStringLiteral("ExposeClass"));
|
|
||||||
exposeClassAction->setText(i18n("Toggle Present Windows (Window class)"));
|
|
||||||
KGlobalAccel::self()->setDefaultShortcut(exposeClassAction, QList<QKeySequence>() << (Qt::CTRL | Qt::Key_F7));
|
|
||||||
KGlobalAccel::self()->setShortcut(exposeClassAction, QList<QKeySequence>() << (Qt::CTRL | Qt::Key_F7));
|
|
||||||
effects->registerGlobalShortcut(Qt::CTRL | Qt::Key_F7, exposeClassAction);
|
|
||||||
connect(exposeClassAction, &QAction::triggered, this, &PresentWindowsEffect::toggleActiveClass);
|
|
||||||
shortcutClass = KGlobalAccel::self()->shortcut(exposeClassAction);
|
|
||||||
connect(KGlobalAccel::self(), &KGlobalAccel::globalShortcutChanged, this, &PresentWindowsEffect::globalShortcutChanged);
|
|
||||||
|
|
||||||
reconfigure(ReconfigureAll);
|
reconfigure(ReconfigureAll);
|
||||||
connect(effects, &EffectsHandler::windowAdded, this, &PresentWindowsEffect::slotWindowAdded);
|
connect(effects, &EffectsHandler::windowAdded, this, &PresentWindowsEffect::slotWindowAdded);
|
||||||
connect(effects, &EffectsHandler::windowClosed, this, &PresentWindowsEffect::slotWindowClosed);
|
connect(effects, &EffectsHandler::windowClosed, this, &PresentWindowsEffect::slotWindowClosed);
|
||||||
|
@ -132,30 +92,6 @@ PresentWindowsEffect::~PresentWindowsEffect()
|
||||||
void PresentWindowsEffect::reconfigure(ReconfigureFlags)
|
void PresentWindowsEffect::reconfigure(ReconfigureFlags)
|
||||||
{
|
{
|
||||||
PresentWindowsConfig::self()->read();
|
PresentWindowsConfig::self()->read();
|
||||||
for (ElectricBorder border : qAsConst(m_borderActivate)) {
|
|
||||||
effects->unreserveElectricBorder(border, this);
|
|
||||||
}
|
|
||||||
for (ElectricBorder border : qAsConst(m_borderActivateAll)) {
|
|
||||||
effects->unreserveElectricBorder(border, this);
|
|
||||||
}
|
|
||||||
m_borderActivate.clear();
|
|
||||||
m_borderActivateAll.clear();
|
|
||||||
|
|
||||||
const auto borderActivate = PresentWindowsConfig::borderActivate();
|
|
||||||
for (int i : borderActivate) {
|
|
||||||
m_borderActivate.append(ElectricBorder(i));
|
|
||||||
effects->reserveElectricBorder(ElectricBorder(i), this);
|
|
||||||
}
|
|
||||||
const auto activateAll = PresentWindowsConfig::borderActivateAll();
|
|
||||||
for (int i : activateAll) {
|
|
||||||
m_borderActivateAll.append(ElectricBorder(i));
|
|
||||||
effects->reserveElectricBorder(ElectricBorder(i), this);
|
|
||||||
}
|
|
||||||
const auto activateClass = PresentWindowsConfig::borderActivateClass();
|
|
||||||
for (int i : activateClass) {
|
|
||||||
m_borderActivateClass.append(ElectricBorder(i));
|
|
||||||
effects->reserveElectricBorder(ElectricBorder(i), this);
|
|
||||||
}
|
|
||||||
|
|
||||||
m_layoutMode = PresentWindowsConfig::layoutMode();
|
m_layoutMode = PresentWindowsConfig::layoutMode();
|
||||||
m_showCaptions = PresentWindowsConfig::drawWindowCaptions();
|
m_showCaptions = PresentWindowsConfig::drawWindowCaptions();
|
||||||
|
@ -178,25 +114,6 @@ void PresentWindowsEffect::reconfigure(ReconfigureFlags)
|
||||||
m_leftButtonDesktop = (DesktopMouseAction)PresentWindowsConfig::leftButtonDesktop();
|
m_leftButtonDesktop = (DesktopMouseAction)PresentWindowsConfig::leftButtonDesktop();
|
||||||
m_middleButtonDesktop = (DesktopMouseAction)PresentWindowsConfig::middleButtonDesktop();
|
m_middleButtonDesktop = (DesktopMouseAction)PresentWindowsConfig::middleButtonDesktop();
|
||||||
m_rightButtonDesktop = (DesktopMouseAction)PresentWindowsConfig::rightButtonDesktop();
|
m_rightButtonDesktop = (DesktopMouseAction)PresentWindowsConfig::rightButtonDesktop();
|
||||||
|
|
||||||
// touch screen edges
|
|
||||||
const QVector<ElectricBorder> relevantBorders{ElectricLeft, ElectricTop, ElectricRight, ElectricBottom};
|
|
||||||
for (auto e : relevantBorders) {
|
|
||||||
effects->unregisterTouchBorder(e, m_exposeAction);
|
|
||||||
effects->unregisterTouchBorder(e, m_exposeAllAction);
|
|
||||||
effects->unregisterTouchBorder(e, m_exposeClassAction);
|
|
||||||
}
|
|
||||||
auto touchEdge = [&relevantBorders](const QList<int> touchBorders, QAction *action) {
|
|
||||||
for (int i : touchBorders) {
|
|
||||||
if (!relevantBorders.contains(ElectricBorder(i))) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
effects->registerTouchBorder(ElectricBorder(i), action);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
touchEdge(PresentWindowsConfig::touchBorderActivate(), m_exposeAction);
|
|
||||||
touchEdge(PresentWindowsConfig::touchBorderActivateAll(), m_exposeAllAction);
|
|
||||||
touchEdge(PresentWindowsConfig::touchBorderActivateClass(), m_exposeClassAction);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void *PresentWindowsEffect::proxy()
|
void *PresentWindowsEffect::proxy()
|
||||||
|
@ -583,35 +500,6 @@ void PresentWindowsEffect::slotWindowFrameGeometryChanged(EffectWindow *w, const
|
||||||
rearrangeWindows();
|
rearrangeWindows();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool PresentWindowsEffect::borderActivated(ElectricBorder border)
|
|
||||||
{
|
|
||||||
int mode = 0;
|
|
||||||
if (m_borderActivate.contains(border)) {
|
|
||||||
mode |= 1;
|
|
||||||
} else if (m_borderActivateAll.contains(border)) {
|
|
||||||
mode |= 2;
|
|
||||||
} else if (m_borderActivateClass.contains(border)) {
|
|
||||||
mode |= 4;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!mode) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (effects->activeFullScreenEffect() && effects->activeFullScreenEffect() != this) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (mode & 1) {
|
|
||||||
toggleActive();
|
|
||||||
} else if (mode & 2) {
|
|
||||||
toggleActiveAllDesktops();
|
|
||||||
} else if (mode & 4) {
|
|
||||||
toggleActiveClass();
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void PresentWindowsEffect::windowInputMouseEvent(QEvent *e)
|
void PresentWindowsEffect::windowInputMouseEvent(QEvent *e)
|
||||||
{
|
{
|
||||||
QMouseEvent *me = dynamic_cast<QMouseEvent *>(e);
|
QMouseEvent *me = dynamic_cast<QMouseEvent *>(e);
|
||||||
|
@ -820,21 +708,6 @@ void PresentWindowsEffect::mouseActionDesktop(DesktopMouseAction &action)
|
||||||
void PresentWindowsEffect::grabbedKeyboardEvent(QKeyEvent *e)
|
void PresentWindowsEffect::grabbedKeyboardEvent(QKeyEvent *e)
|
||||||
{
|
{
|
||||||
if (e->type() == QEvent::KeyPress) {
|
if (e->type() == QEvent::KeyPress) {
|
||||||
// check for global shortcuts
|
|
||||||
// HACK: keyboard grab disables the global shortcuts so we have to check for global shortcut (bug 156155)
|
|
||||||
if (m_mode == ModeCurrentDesktop && shortcut.contains(e->key() | e->modifiers())) {
|
|
||||||
toggleActive();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (m_mode == ModeAllDesktops && shortcutAll.contains(e->key() | e->modifiers())) {
|
|
||||||
toggleActiveAllDesktops();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (m_mode == ModeWindowClass && shortcutClass.contains(e->key() | e->modifiers())) {
|
|
||||||
toggleActiveClass();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (e->key()) {
|
switch (e->key()) {
|
||||||
// Wrap only if not auto-repeating
|
// Wrap only if not auto-repeating
|
||||||
case Qt::Key_Left:
|
case Qt::Key_Left:
|
||||||
|
@ -2132,20 +2005,6 @@ EffectWindow *PresentWindowsEffect::findFirstWindow() const
|
||||||
return topLeft;
|
return topLeft;
|
||||||
}
|
}
|
||||||
|
|
||||||
void PresentWindowsEffect::globalShortcutChanged(QAction *action, const QKeySequence &seq)
|
|
||||||
{
|
|
||||||
if (action->objectName() == QStringLiteral("Expose")) {
|
|
||||||
shortcut.clear();
|
|
||||||
shortcut.append(seq);
|
|
||||||
} else if (action->objectName() == QStringLiteral("ExposeAll")) {
|
|
||||||
shortcutAll.clear();
|
|
||||||
shortcutAll.append(seq);
|
|
||||||
} else if (action->objectName() == QStringLiteral("ExposeClass")) {
|
|
||||||
shortcutClass.clear();
|
|
||||||
shortcutClass.append(seq);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool PresentWindowsEffect::isActive() const
|
bool PresentWindowsEffect::isActive() const
|
||||||
{
|
{
|
||||||
return (m_activated || m_motionManager.managingWindows()) && !effects->isScreenLocked();
|
return (m_activated || m_motionManager.managingWindows()) && !effects->isScreenLocked();
|
||||||
|
|
|
@ -100,7 +100,6 @@ public:
|
||||||
void paintWindow(EffectWindow *w, int mask, QRegion region, WindowPaintData &data) override;
|
void paintWindow(EffectWindow *w, int mask, QRegion region, WindowPaintData &data) override;
|
||||||
|
|
||||||
// User interaction
|
// User interaction
|
||||||
bool borderActivated(ElectricBorder border) override;
|
|
||||||
void windowInputMouseEvent(QEvent *e) override;
|
void windowInputMouseEvent(QEvent *e) override;
|
||||||
void grabbedKeyboardEvent(QKeyEvent *e) override;
|
void grabbedKeyboardEvent(QKeyEvent *e) override;
|
||||||
bool isActive() const override;
|
bool isActive() const override;
|
||||||
|
@ -218,9 +217,6 @@ public Q_SLOTS:
|
||||||
}
|
}
|
||||||
void toggleActiveClass();
|
void toggleActiveClass();
|
||||||
|
|
||||||
// slots for global shortcut changed
|
|
||||||
// needed to toggle the effect
|
|
||||||
void globalShortcutChanged(QAction *action, const QKeySequence &seq);
|
|
||||||
// EffectsHandler
|
// EffectsHandler
|
||||||
void slotWindowAdded(KWin::EffectWindow *w);
|
void slotWindowAdded(KWin::EffectWindow *w);
|
||||||
void slotWindowClosed(KWin::EffectWindow *w);
|
void slotWindowClosed(KWin::EffectWindow *w);
|
||||||
|
@ -282,9 +278,6 @@ private:
|
||||||
friend class PresentWindowsEffectProxy;
|
friend class PresentWindowsEffectProxy;
|
||||||
|
|
||||||
// User configuration settings
|
// User configuration settings
|
||||||
QList<ElectricBorder> m_borderActivate;
|
|
||||||
QList<ElectricBorder> m_borderActivateAll;
|
|
||||||
QList<ElectricBorder> m_borderActivateClass;
|
|
||||||
int m_layoutMode;
|
int m_layoutMode;
|
||||||
bool m_showCaptions;
|
bool m_showCaptions;
|
||||||
bool m_showIcons;
|
bool m_showIcons;
|
||||||
|
@ -321,11 +314,6 @@ private:
|
||||||
EffectFrame *m_filterFrame;
|
EffectFrame *m_filterFrame;
|
||||||
QString m_windowFilter;
|
QString m_windowFilter;
|
||||||
|
|
||||||
// Shortcut - needed to toggle the effect
|
|
||||||
QList<QKeySequence> shortcut;
|
|
||||||
QList<QKeySequence> shortcutAll;
|
|
||||||
QList<QKeySequence> shortcutClass;
|
|
||||||
|
|
||||||
// Atoms
|
// Atoms
|
||||||
// Present windows for all windows of given desktop
|
// Present windows for all windows of given desktop
|
||||||
// -1 for all desktops
|
// -1 for all desktops
|
||||||
|
@ -348,10 +336,6 @@ private:
|
||||||
qint32 id = 0;
|
qint32 id = 0;
|
||||||
bool active = false;
|
bool active = false;
|
||||||
} m_touch;
|
} m_touch;
|
||||||
|
|
||||||
QAction *m_exposeAction;
|
|
||||||
QAction *m_exposeAllAction;
|
|
||||||
QAction *m_exposeClassAction;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
|
@ -47,13 +47,5 @@
|
||||||
<entry name="RightButtonDesktop" type="Int">
|
<entry name="RightButtonDesktop" type="Int">
|
||||||
<default>0</default>
|
<default>0</default>
|
||||||
</entry>
|
</entry>
|
||||||
<entry name="BorderActivate" type="IntList" />
|
|
||||||
<entry name="BorderActivateAll" type="IntList">
|
|
||||||
<default code="true">QList<int>() << int(ElectricTopLeft)</default>
|
|
||||||
</entry>
|
|
||||||
<entry name="BorderActivateClass" type="IntList" />
|
|
||||||
<entry name="TouchBorderActivate" type="IntList" />
|
|
||||||
<entry name="TouchBorderActivateAll" type="IntList"/>
|
|
||||||
<entry name="TouchBorderActivateClass" type="IntList" />
|
|
||||||
</group>
|
</group>
|
||||||
</kcfg>
|
</kcfg>
|
||||||
|
|
|
@ -29,12 +29,19 @@ FocusScope {
|
||||||
property bool dragEnabled: true
|
property bool dragEnabled: true
|
||||||
property real padding: 0
|
property real padding: 0
|
||||||
property var showOnly: []
|
property var showOnly: []
|
||||||
|
property string activeClass
|
||||||
|
readonly property alias count: windowsRepeater.count
|
||||||
|
|
||||||
required property bool organized
|
required property bool organized
|
||||||
readonly property bool effectiveOrganized: expoLayout.ready && organized
|
readonly property bool effectiveOrganized: expoLayout.ready && organized
|
||||||
|
|
||||||
signal activated()
|
signal activated()
|
||||||
|
|
||||||
|
function activateIndex(index) {
|
||||||
|
KWinComponents.Workspace.activeClient = windowsRepeater.itemAt(index).client;
|
||||||
|
activated();
|
||||||
|
}
|
||||||
|
|
||||||
ExpoLayout {
|
ExpoLayout {
|
||||||
id: expoLayout
|
id: expoLayout
|
||||||
x: heap.padding
|
x: heap.padding
|
||||||
|
@ -54,7 +61,25 @@ FocusScope {
|
||||||
|
|
||||||
readonly property bool selected: heap.selectedIndex == index
|
readonly property bool selected: heap.selectedIndex == index
|
||||||
readonly property bool hidden: {
|
readonly property bool hidden: {
|
||||||
return heap.showOnly.length && heap.showOnly.indexOf(client.internalId) == -1;
|
if (heap.showOnly === "activeClass") {
|
||||||
|
return heap.activeClass !== String(thumb.client.resourceName); // thumb.client.resourceName is not an actual String as comes from a QByteArray so === would fail
|
||||||
|
} else {
|
||||||
|
return heap.showOnly.length && heap.showOnly.indexOf(client.internalId) == -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Component.onCompleted: {
|
||||||
|
if (thumb.client.active) {
|
||||||
|
heap.activeClass = thumb.client.resourceName;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Connections {
|
||||||
|
target: thumb.client
|
||||||
|
function onActiveChanged() {
|
||||||
|
if (thumb.client.active) {
|
||||||
|
heap.activeClass = thumb.client.resourceName;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
state: {
|
state: {
|
||||||
|
|
|
@ -2,18 +2,26 @@
|
||||||
#
|
#
|
||||||
# SPDX-License-Identifier: BSD-3-Clause
|
# SPDX-License-Identifier: BSD-3-Clause
|
||||||
|
|
||||||
|
if (KWIN_BUILD_KCMS)
|
||||||
|
add_subdirectory(kcm)
|
||||||
|
endif()
|
||||||
|
|
||||||
set(windowview_SOURCES
|
set(windowview_SOURCES
|
||||||
main.cpp
|
main.cpp
|
||||||
windowvieweffect.cpp
|
windowvieweffect.cpp
|
||||||
)
|
)
|
||||||
|
|
||||||
|
kconfig_add_kcfg_files(windowview_SOURCES
|
||||||
|
windowviewconfig.kcfgc
|
||||||
|
)
|
||||||
|
|
||||||
qt_add_dbus_adaptor(windowview_SOURCES org.kde.KWin.Effect.WindowView1.xml windowvieweffect.h KWin::WindowViewEffect)
|
qt_add_dbus_adaptor(windowview_SOURCES org.kde.KWin.Effect.WindowView1.xml windowvieweffect.h KWin::WindowViewEffect)
|
||||||
|
|
||||||
kwin4_add_effect_module(kwin4_effect_windowview ${windowview_SOURCES})
|
kwin4_add_effect_module(kwin4_effect_windowview ${windowview_SOURCES})
|
||||||
|
|
||||||
target_link_libraries(kwin4_effect_windowview PRIVATE
|
target_link_libraries(kwin4_effect_windowview PRIVATE
|
||||||
kwineffects
|
kwineffects
|
||||||
|
|
||||||
KF5::ConfigGui
|
KF5::ConfigGui
|
||||||
KF5::GlobalAccel
|
KF5::GlobalAccel
|
||||||
KF5::I18n
|
KF5::I18n
|
||||||
|
|
17
src/effects/windowview/kcm/CMakeLists.txt
Normal file
17
src/effects/windowview/kcm/CMakeLists.txt
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
# SPDX-FileCopyrightText: 2021 Vlad Zahorodnii <vlad.zahorodnii@kde.org>
|
||||||
|
#
|
||||||
|
# SPDX-License-Identifier: BSD-3-Clause
|
||||||
|
|
||||||
|
set(kwin_windowview_config_SOURCES windowvieweffectkcm.cpp)
|
||||||
|
ki18n_wrap_ui(kwin_windowview_config_SOURCES windowvieweffectkcm.ui)
|
||||||
|
kconfig_add_kcfg_files(kwin_windowview_config_SOURCES ../windowviewconfig.kcfgc)
|
||||||
|
|
||||||
|
kwin_add_effect_config(kwin_windowview_config ${kwin_windowview_config_SOURCES})
|
||||||
|
target_link_libraries(kwin_windowview_config
|
||||||
|
KF5::ConfigWidgets
|
||||||
|
KF5::CoreAddons
|
||||||
|
KF5::GlobalAccel
|
||||||
|
KF5::I18n
|
||||||
|
KF5::XmlGui
|
||||||
|
KWinEffectsInterface
|
||||||
|
)
|
89
src/effects/windowview/kcm/windowvieweffectkcm.cpp
Normal file
89
src/effects/windowview/kcm/windowvieweffectkcm.cpp
Normal file
|
@ -0,0 +1,89 @@
|
||||||
|
/*
|
||||||
|
SPDX-FileCopyrightText: 2021 Vlad Zahorodnii <vlad.zahorodnii@kde.org>
|
||||||
|
|
||||||
|
SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
*/
|
||||||
|
#include "windowvieweffectkcm.h"
|
||||||
|
|
||||||
|
#include <config-kwin.h>
|
||||||
|
|
||||||
|
#include "windowviewconfig.h"
|
||||||
|
|
||||||
|
#include <kwineffects_interface.h>
|
||||||
|
|
||||||
|
#include <KActionCollection>
|
||||||
|
#include <KGlobalAccel>
|
||||||
|
#include <KLocalizedString>
|
||||||
|
#include <KPluginFactory>
|
||||||
|
|
||||||
|
#include <QAction>
|
||||||
|
|
||||||
|
K_PLUGIN_CLASS(KWin::WindowViewEffectConfig)
|
||||||
|
|
||||||
|
namespace KWin
|
||||||
|
{
|
||||||
|
|
||||||
|
WindowViewEffectConfig::WindowViewEffectConfig(QWidget *parent, const QVariantList &args)
|
||||||
|
: KCModule(parent, args)
|
||||||
|
{
|
||||||
|
ui.setupUi(this);
|
||||||
|
WindowViewConfig::instance(KWIN_CONFIG);
|
||||||
|
addConfig(WindowViewConfig::self(), this);
|
||||||
|
|
||||||
|
auto actionCollection = new KActionCollection(this, QStringLiteral("kwin"));
|
||||||
|
|
||||||
|
actionCollection->setComponentDisplayName(i18n("KWin"));
|
||||||
|
actionCollection->setConfigGroup(QStringLiteral("windowview"));
|
||||||
|
actionCollection->setConfigGlobal(true);
|
||||||
|
|
||||||
|
const QKeySequence defaultToggleShortcut = Qt::CTRL | Qt::Key_F9;
|
||||||
|
QAction *toggleAction = actionCollection->addAction(QStringLiteral("Expose"));
|
||||||
|
toggleAction->setText(i18n("Toggle Present Windows (Current desktop)"));
|
||||||
|
toggleAction->setProperty("isConfigurationAction", true);
|
||||||
|
KGlobalAccel::self()->setDefaultShortcut(toggleAction, {defaultToggleShortcut});
|
||||||
|
KGlobalAccel::self()->setShortcut(toggleAction, {defaultToggleShortcut});
|
||||||
|
|
||||||
|
const QKeySequence defaultToggleShortcutAll = Qt::CTRL | Qt::Key_F10;
|
||||||
|
toggleAction = actionCollection->addAction(QStringLiteral("ExposeAll"));
|
||||||
|
toggleAction->setText(i18n("Toggle Present Windows (All desktops)"));
|
||||||
|
toggleAction->setProperty("isConfigurationAction", true);
|
||||||
|
KGlobalAccel::self()->setDefaultShortcut(toggleAction, {defaultToggleShortcutAll});
|
||||||
|
KGlobalAccel::self()->setShortcut(toggleAction, {defaultToggleShortcutAll});
|
||||||
|
|
||||||
|
const QKeySequence defaultToggleShortcutClass = Qt::CTRL | Qt::Key_F7;
|
||||||
|
toggleAction = actionCollection->addAction(QStringLiteral("ExposeClass"));
|
||||||
|
toggleAction->setText(i18n("Toggle Present Windows (Window class)"));
|
||||||
|
toggleAction->setProperty("isConfigurationAction", true);
|
||||||
|
KGlobalAccel::self()->setDefaultShortcut(toggleAction, {defaultToggleShortcutClass});
|
||||||
|
KGlobalAccel::self()->setShortcut(toggleAction, {defaultToggleShortcutClass});
|
||||||
|
|
||||||
|
ui.shortcutsEditor->addCollection(actionCollection);
|
||||||
|
connect(ui.shortcutsEditor, &KShortcutsEditor::keyChange, this, &WindowViewEffectConfig::markAsChanged);
|
||||||
|
}
|
||||||
|
|
||||||
|
WindowViewEffectConfig::~WindowViewEffectConfig()
|
||||||
|
{
|
||||||
|
// If save() is called, undo() has no effect.
|
||||||
|
ui.shortcutsEditor->undo();
|
||||||
|
}
|
||||||
|
|
||||||
|
void WindowViewEffectConfig::save()
|
||||||
|
{
|
||||||
|
KCModule::save();
|
||||||
|
ui.shortcutsEditor->save();
|
||||||
|
|
||||||
|
OrgKdeKwinEffectsInterface interface(QStringLiteral("org.kde.KWin"),
|
||||||
|
QStringLiteral("/Effects"),
|
||||||
|
QDBusConnection::sessionBus());
|
||||||
|
interface.reconfigureEffect(QStringLiteral("windowview"));
|
||||||
|
}
|
||||||
|
|
||||||
|
void WindowViewEffectConfig::defaults()
|
||||||
|
{
|
||||||
|
ui.shortcutsEditor->allDefault();
|
||||||
|
KCModule::defaults();
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace KWin
|
||||||
|
|
||||||
|
#include "windowvieweffectkcm.moc"
|
32
src/effects/windowview/kcm/windowvieweffectkcm.h
Normal file
32
src/effects/windowview/kcm/windowvieweffectkcm.h
Normal file
|
@ -0,0 +1,32 @@
|
||||||
|
/*
|
||||||
|
SPDX-FileCopyrightText: 2021 Vlad Zahorodnii <vlad.zahorodnii@kde.org>
|
||||||
|
|
||||||
|
SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <KCModule>
|
||||||
|
|
||||||
|
#include "ui_windowvieweffectkcm.h"
|
||||||
|
|
||||||
|
namespace KWin
|
||||||
|
{
|
||||||
|
|
||||||
|
class WindowViewEffectConfig : public KCModule
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit WindowViewEffectConfig(QWidget *parent = nullptr, const QVariantList &args = QVariantList());
|
||||||
|
~WindowViewEffectConfig() override;
|
||||||
|
|
||||||
|
public Q_SLOTS:
|
||||||
|
void save() override;
|
||||||
|
void defaults() override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
::Ui::WindowViewEffectConfig ui;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace KWin
|
68
src/effects/windowview/kcm/windowvieweffectkcm.ui
Normal file
68
src/effects/windowview/kcm/windowvieweffectkcm.ui
Normal file
|
@ -0,0 +1,68 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!--
|
||||||
|
SPDX-FileCopyrightText: 2021 Vlad Zahorodnii <vlad.zahorodnii@kde.org>
|
||||||
|
|
||||||
|
SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
|
||||||
|
-->
|
||||||
|
<ui version="4.0">
|
||||||
|
<class>WindowViewEffectConfig</class>
|
||||||
|
<widget class="QWidget" name="WindowViewEffectConfig">
|
||||||
|
<property name="geometry">
|
||||||
|
<rect>
|
||||||
|
<x>0</x>
|
||||||
|
<y>0</y>
|
||||||
|
<width>455</width>
|
||||||
|
<height>177</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<layout class="QFormLayout" name="formLayout">
|
||||||
|
<item row="0" column="0">
|
||||||
|
<widget class="QLabel" name="label_LayoutMode">
|
||||||
|
<property name="text">
|
||||||
|
<string>Layout mode:</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="0" column="1">
|
||||||
|
<widget class="QComboBox" name="kcfg_LayoutMode">
|
||||||
|
<item>
|
||||||
|
<property name="text">
|
||||||
|
<string>Closest</string>
|
||||||
|
</property>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<property name="text">
|
||||||
|
<string>Natural</string>
|
||||||
|
</property>
|
||||||
|
</item>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="2" column="0" colspan="2">
|
||||||
|
<widget class="KShortcutsEditor" name="shortcutsEditor">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
<property name="actionTypes">
|
||||||
|
<enum>KShortcutsEditor::GlobalAction</enum>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="1" column="1">
|
||||||
|
<widget class="QCheckBox" name="kcfg_BlurBackground"/>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
<customwidgets>
|
||||||
|
<customwidget>
|
||||||
|
<class>KShortcutsEditor</class>
|
||||||
|
<extends>QWidget</extends>
|
||||||
|
<header>kshortcutseditor.h</header>
|
||||||
|
<container>1</container>
|
||||||
|
</customwidget>
|
||||||
|
</customwidgets>
|
||||||
|
<resources/>
|
||||||
|
<connections/>
|
||||||
|
</ui>
|
|
@ -1,54 +1,72 @@
|
||||||
{
|
{
|
||||||
"KPlugin": {
|
"KPlugin": {
|
||||||
"Category": "Window Management",
|
"Category": "Window Management",
|
||||||
"Description": "Helper effect for the task manager",
|
"Description": "Zoom out until all opened windows can be displayed side-by-side",
|
||||||
"Description[ar]": "تأثير مساعدة لمدير المهام",
|
"Description[ar]": "بعِّد إلى أن يصير بالإمكان عرض كل النوافذ المفتوحة جبناً إلى جنب",
|
||||||
"Description[az]": "Tapşırıq meneceri üçün köməkçi effekti",
|
"Description[az]": "Bütün açıq pəncərələrin miniatürünü yan-yana göstərir",
|
||||||
"Description[ca@valencia]": "Efecte auxiliar per al gestor de tasques",
|
"Description[ca@valencia]": "Redueix fins que totes les finestres obertes es poden mostrar una al costat de l'altra",
|
||||||
"Description[ca]": "Efecte auxiliar per al gestor de tasques",
|
"Description[ca]": "Redueix fins que totes les finestres obertes es poden mostrar una al costat de l'altra",
|
||||||
"Description[en_GB]": "Helper effect for the task manager",
|
"Description[cs]": "Oddálí plochu, aby byla vidět všechna okna",
|
||||||
"Description[es]": "Efecto auxiliar para el gestor de tareas",
|
"Description[de]": "Verkleinert Fenster auf der Arbeitsfläche, sodass sie alle nebeneinander sichtbar sind",
|
||||||
"Description[fr]": "Effet d'assistance pour le gestionnaire de tâches",
|
"Description[en_GB]": "Zoom out until all opened windows can be displayed side-by-side",
|
||||||
"Description[ia]": "Effecto adjutante per le gerente de carga",
|
"Description[es]": "Reducir hasta que todas las ventanas abiertas se puedan mostrar una al lado de la otra",
|
||||||
"Description[it]": "Effetto di assistenza per il gestore delle applicazioni",
|
"Description[fi]": "Loitontaa työpöytää kunnes avoimet ikkunat voi esittää rinnakkain",
|
||||||
"Description[ko]": "작업 관리자용 도우미 효과",
|
"Description[fr]": "Faire un zoom arrière jusqu'à ce que toutes les fenêtres ouvertes puissent être affichées côte à côte",
|
||||||
"Description[nl]": "Effect van hulp voor de takenbeheerder",
|
"Description[hu]": "Kinagyítja a nézetet, hogy az összes megnyitott ablak áttekinthető legyen",
|
||||||
"Description[pl]": "Efekt pomocniczy dla zarządzania zadaniami",
|
"Description[ia]": "Zoom foras usque omne fenestras aperite pote esser monstrate flanco a flanco",
|
||||||
"Description[pt]": "Efeito auxiliar para o gestor de tarefas",
|
"Description[id]": "Zoom keluar hingga semua window yang terbuka bisa ditampilkan sisi demi sisi",
|
||||||
"Description[pt_BR]": "Efeito auxiliar para o gerenciador de tarefas",
|
"Description[it]": "Arretra per far vedere tutte le finestre aperte fianco a fianco",
|
||||||
"Description[sl]": "Učinki pomočnika za upravljalnika nalog",
|
"Description[ko]": "모든 열린 창을 축소시켜서 한 화면에 보이도록 합니다",
|
||||||
"Description[sv]": "Hjälpeffekt för aktivitetshanteraren",
|
"Description[nl]": "Zoomt uit totdat alle geopende vensters zij-aan-zij kunnen worden getoond",
|
||||||
"Description[tr]": "Görev yöneticisi için yardımcı etkisi",
|
"Description[nn]": "Forminsk skjermflata heilt til alle dei opne vindauga kan visast side om side",
|
||||||
"Description[uk]": "Допоміжний ефект для керування завданнями",
|
"Description[pl]": "Pomniejsza do chwili, aż wszystkie otwarte okna będą widoczne obok siebie",
|
||||||
"Description[vi]": "Hiệu ứng trợ giúp cho trình quản lí tác vụ",
|
"Description[pt]": "Reduz até que todas as janelas abertas possam aparecer lado-a-lado",
|
||||||
"Description[x-test]": "xxHelper effect for the task managerxx",
|
"Description[pt_BR]": "Reduz até que todas as janelas abertas possam ser apresentadas lado a lado",
|
||||||
"Description[zh_CN]": "任务管理器的辅助特效",
|
"Description[ro]": "Îndepărtează până toate ferestrele deschise se pot afișa una lângă alta",
|
||||||
|
"Description[ru]": "Просмотр миниатюр всех открытых окон рядом друг с другом",
|
||||||
|
"Description[sk]": "Oddiali všetky otvorené okná a zobrazí ich vedľa seba",
|
||||||
|
"Description[sl]": "Oddaljite, dokler se ne vsa odprta okna ne prikažejo eno poleg drugega",
|
||||||
|
"Description[sv]": "Zooma ut till alla öppnade fönster kan visas sida vid sida",
|
||||||
|
"Description[ta]": "அனைத்து சாளரங்களையும் பக்கத்து பக்கத்தில் சிறிதாக்கி காட்டும்",
|
||||||
|
"Description[tr]": "Tüm açık pencereler yan yana görüntülenebilene dek uzaklaştır",
|
||||||
|
"Description[uk]": "Зменшення масштабу вікон так, щоб всі відкриті вікна можна було розташувати поряд",
|
||||||
|
"Description[vi]": "Thu nhỏ cho đến khi tất cả các cửa sổ đang mở hiển thị được cạnh nhau",
|
||||||
|
"Description[x-test]": "xxZoom out until all opened windows can be displayed side-by-sidexx",
|
||||||
|
"Description[zh_CN]": "所有窗口缩小后平铺显示在一个画面上",
|
||||||
"EnabledByDefault": true,
|
"EnabledByDefault": true,
|
||||||
"Id": "windowview",
|
"Id": "windowview",
|
||||||
"License": "GPL",
|
"License": "GPL",
|
||||||
"Name": "Window View",
|
"Name": "Present Windows",
|
||||||
"Name[ar]": "عرض النافذة",
|
"Name[ar]": "النوافذ الحاضرة",
|
||||||
"Name[az]": "Pəncərənin görünüşü",
|
"Name[az]": "Hazırkı pəncərələr",
|
||||||
"Name[ca@valencia]": "Vista de finestres",
|
"Name[ca@valencia]": "Presenta les finestres",
|
||||||
"Name[ca]": "Vista de finestres",
|
"Name[ca]": "Presenta les finestres",
|
||||||
"Name[en_GB]": "Window View",
|
"Name[cs]": "Prezentace oken",
|
||||||
"Name[es]": "Vista de ventanas",
|
"Name[de]": "Fenster zeigen",
|
||||||
"Name[fr]": "Affichage en fenêtres",
|
"Name[en_GB]": "Present Windows",
|
||||||
"Name[ia]": "Vista de fenestra",
|
"Name[es]": "Presentar ventanas",
|
||||||
"Name[it]": "Vista della finestra",
|
"Name[fi]": "Ikkunoiden esittäminen",
|
||||||
"Name[ko]": "창 보기",
|
"Name[fr]": "Fenêtres actuelles",
|
||||||
"Name[nl]": "Weergave met vensters",
|
"Name[hu]": "Ablakáttekintő",
|
||||||
"Name[pl]": "Widok okna",
|
"Name[ia]": "Fenestras actual",
|
||||||
"Name[pt]": "Vista da Janela",
|
"Name[it]": "Presenta le finestre",
|
||||||
"Name[sl]": "Pogled okna",
|
"Name[ko]": "창 진열하기",
|
||||||
"Name[sv]": "Fönstervy",
|
"Name[nl]": "Vensters presenteren",
|
||||||
"Name[tr]": "Pencere Görünümü",
|
"Name[nn]": "Presenter vindauge",
|
||||||
"Name[uk]": "Перегляд вікон",
|
"Name[pl]": "Prezentacja okien",
|
||||||
"Name[vi]": "Khung xem cửa sổ",
|
"Name[pt]": "Apresentar as Janelas",
|
||||||
"Name[x-test]": "xxWindow Viewxx",
|
"Name[pt_BR]": "Apresentar janelas",
|
||||||
"Name[zh_CN]": "窗口视图"
|
"Name[ro]": "Prezintă ferestrele",
|
||||||
|
"Name[ru]": "Все окна",
|
||||||
|
"Name[sk]": "Súčasné okná",
|
||||||
|
"Name[sl]": "Prikaži okna",
|
||||||
|
"Name[sv]": "Befintliga fönster",
|
||||||
|
"Name[ta]": "சாளரங்களை முன்வை",
|
||||||
|
"Name[tr]": "Pencereleri Sun",
|
||||||
|
"Name[uk]": "Показ вікон",
|
||||||
|
"Name[vi]": "Các cửa sổ hiện thời",
|
||||||
|
"Name[x-test]": "xxPresent Windowsxx",
|
||||||
|
"Name[zh_CN]": "窗口平铺展示"
|
||||||
},
|
},
|
||||||
"org.kde.kwin.effect": {
|
"X-KDE-ConfigModule": "kwin_windowview_config"
|
||||||
"internal": true
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,10 +5,13 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import QtQuick 2.12
|
import QtQuick 2.12
|
||||||
|
import QtQuick.Layouts 1.4
|
||||||
import QtGraphicalEffects 1.12
|
import QtGraphicalEffects 1.12
|
||||||
import org.kde.kwin 3.0 as KWinComponents
|
import org.kde.kwin 3.0 as KWinComponents
|
||||||
import org.kde.kwin.private.effects 1.0
|
import org.kde.kwin.private.effects 1.0
|
||||||
import org.kde.plasma.core 2.0 as PlasmaCore
|
import org.kde.plasma.core 2.0 as PlasmaCore
|
||||||
|
import org.kde.plasma.extras 2.0 as PlasmaExtras
|
||||||
|
import org.kde.KWin.Effect.WindowView 1.0
|
||||||
|
|
||||||
Item {
|
Item {
|
||||||
id: container
|
id: container
|
||||||
|
@ -61,26 +64,70 @@ Item {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
WindowHeap {
|
ColumnLayout {
|
||||||
width: targetScreen.geometry.width
|
width: targetScreen.geometry.width
|
||||||
height: targetScreen.geometry.height
|
height: targetScreen.geometry.height
|
||||||
focus: true
|
PlasmaExtras.SearchField {
|
||||||
padding: PlasmaCore.Units.largeSpacing
|
id: searchField
|
||||||
animationDuration: container.animationDuration
|
Layout.alignment: Qt.AlignCenter
|
||||||
animationEnabled: container.animationEnabled
|
Layout.topMargin: PlasmaCore.Units.gridUnit
|
||||||
dragEnabled: false
|
Layout.preferredWidth: Math.min(parent.width, 20 * PlasmaCore.Units.gridUnit)
|
||||||
organized: container.organized
|
focus: true
|
||||||
showOnly: selectedIds
|
Keys.priority: Keys.AfterItem
|
||||||
model: KWinComponents.ClientFilterModel {
|
Keys.onPressed: {
|
||||||
activity: KWinComponents.Workspace.currentActivity
|
switch (event.key) {
|
||||||
desktop: KWinComponents.Workspace.currentVirtualDesktop
|
case Qt.Key_Down:
|
||||||
screenName: targetScreen.name
|
heap.forceActiveFocus();
|
||||||
clientModel: stackModel
|
break;
|
||||||
windowType: ~KWinComponents.ClientFilterModel.Dock &
|
case Qt.Key_Return:
|
||||||
~KWinComponents.ClientFilterModel.Desktop &
|
case Qt.Key_Enter:
|
||||||
~KWinComponents.ClientFilterModel.Notification;
|
heap.forceActiveFocus();
|
||||||
|
if (heap.count === 1) {
|
||||||
|
heap.activateIndex(0);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Keys.onEnterPressed: {
|
||||||
|
heap.forceActiveFocus();
|
||||||
|
if (heap.count === 1) {
|
||||||
|
heap.activateCurrentClient();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
onActivated: effect.deactivate(animationDuration);
|
WindowHeap {
|
||||||
|
id: heap
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Layout.fillHeight: true
|
||||||
|
focus: true
|
||||||
|
padding: PlasmaCore.Units.largeSpacing
|
||||||
|
animationDuration: container.animationDuration
|
||||||
|
animationEnabled: container.animationEnabled
|
||||||
|
dragEnabled: false
|
||||||
|
organized: container.organized
|
||||||
|
showOnly: container.effect.mode === WindowView.ModeWindowClass ? "activeClass" : selectedIds
|
||||||
|
layout: effect.layout
|
||||||
|
model: KWinComponents.ClientFilterModel {
|
||||||
|
activity: KWinComponents.Workspace.currentActivity
|
||||||
|
desktop: container.effect.mode == WindowView.ModeCurrentDesktop ? KWinComponents.Workspace.currentVirtualDesktop : undefined
|
||||||
|
screenName: targetScreen.name
|
||||||
|
clientModel: stackModel
|
||||||
|
filter: searchField.text
|
||||||
|
windowType: ~KWinComponents.ClientFilterModel.Dock &
|
||||||
|
~KWinComponents.ClientFilterModel.Desktop &
|
||||||
|
~KWinComponents.ClientFilterModel.Notification;
|
||||||
|
}
|
||||||
|
onActivated: effect.deactivate(animationDuration);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
PlasmaExtras.PlaceholderMessage {
|
||||||
|
anchors.centerIn: parent
|
||||||
|
width: parent.width - (PlasmaCore.Units.gridUnit * 8)
|
||||||
|
visible: heap.count === 0
|
||||||
|
iconName: "edit-none"
|
||||||
|
text: searchField.text.length > 0 ? i18nd("kwin_effects", "No Matches") : i18nd("kwin_effects", "No Windows")
|
||||||
}
|
}
|
||||||
|
|
||||||
Repeater {
|
Repeater {
|
||||||
|
|
27
src/effects/windowview/windowviewconfig.kcfg
Normal file
27
src/effects/windowview/windowviewconfig.kcfg
Normal file
|
@ -0,0 +1,27 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!--
|
||||||
|
SPDX-FileCopyrightText: 2021 Vlad Zahorodnii <vlad.zahorodnii@kde.org>
|
||||||
|
|
||||||
|
SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
|
||||||
|
-->
|
||||||
|
<kcfg xmlns="http://www.kde.org/standards/kcfg/1.0"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://www.kde.org/standards/kcfg/1.0
|
||||||
|
http://www.kde.org/standards/kcfg/1.0/kcfg.xsd" >
|
||||||
|
<kcfgfile arg="true"/>
|
||||||
|
<group name="Effect-windowview">
|
||||||
|
<entry name="LayoutMode" type="Int">
|
||||||
|
<default>1</default>
|
||||||
|
</entry>
|
||||||
|
|
||||||
|
<entry name="BorderActivate" type="IntList" />
|
||||||
|
<entry name="BorderActivateAll" type="IntList">
|
||||||
|
<default code="true">QList<int>() << int(ElectricTopLeft)</default>
|
||||||
|
</entry>
|
||||||
|
<entry name="BorderActivateClass" type="IntList" />
|
||||||
|
|
||||||
|
<entry name="TouchBorderActivate" type="IntList" />
|
||||||
|
<entry name="TouchBorderActivateAll" type="IntList" />
|
||||||
|
<entry name="TouchBorderActivateClass" type="IntList" />
|
||||||
|
</group>
|
||||||
|
</kcfg>
|
10
src/effects/windowview/windowviewconfig.kcfgc
Normal file
10
src/effects/windowview/windowviewconfig.kcfgc
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
# SPDX-FileCopyrightText: 2021 Vlad Zahorodnii <vlad.zahorodnii@kde.org>
|
||||||
|
#
|
||||||
|
# SPDX-License-Identifier: CC-0
|
||||||
|
|
||||||
|
File=windowviewconfig.kcfg
|
||||||
|
ClassName=WindowViewConfig
|
||||||
|
NameSpace=KWin
|
||||||
|
Singleton=true
|
||||||
|
Mutators=true
|
||||||
|
IncludeFiles=kwinglobals.h
|
|
@ -6,10 +6,15 @@
|
||||||
|
|
||||||
#include "windowvieweffect.h"
|
#include "windowvieweffect.h"
|
||||||
#include "windowview1adaptor.h"
|
#include "windowview1adaptor.h"
|
||||||
|
#include "windowviewconfig.h"
|
||||||
|
|
||||||
|
#include <QAction>
|
||||||
#include <QQuickItem>
|
#include <QQuickItem>
|
||||||
#include <QTimer>
|
#include <QTimer>
|
||||||
|
|
||||||
|
#include <KGlobalAccel>
|
||||||
|
#include <KLocalizedString>
|
||||||
|
|
||||||
namespace KWin
|
namespace KWin
|
||||||
{
|
{
|
||||||
|
|
||||||
|
@ -18,7 +23,12 @@ static const QString s_dbusObjectPath = QStringLiteral("/org/kde/KWin/Effect/Win
|
||||||
|
|
||||||
WindowViewEffect::WindowViewEffect()
|
WindowViewEffect::WindowViewEffect()
|
||||||
: m_shutdownTimer(new QTimer(this))
|
: m_shutdownTimer(new QTimer(this))
|
||||||
|
, m_exposeAction(new QAction(this))
|
||||||
|
, m_exposeAllAction(new QAction(this))
|
||||||
|
, m_exposeClassAction(new QAction(this))
|
||||||
{
|
{
|
||||||
|
qmlRegisterUncreatableType<WindowViewEffect>("org.kde.KWin.Effect.WindowView", 1, 0, "WindowView", QStringLiteral("WindowView cannot be created in QML"));
|
||||||
|
initConfig<WindowViewConfig>();
|
||||||
new WindowView1Adaptor(this);
|
new WindowView1Adaptor(this);
|
||||||
|
|
||||||
QDBusConnection::sessionBus().registerObject(s_dbusObjectPath, this);
|
QDBusConnection::sessionBus().registerObject(s_dbusObjectPath, this);
|
||||||
|
@ -29,6 +39,91 @@ WindowViewEffect::WindowViewEffect()
|
||||||
connect(effects, &EffectsHandler::screenAboutToLock, this, &WindowViewEffect::realDeactivate);
|
connect(effects, &EffectsHandler::screenAboutToLock, this, &WindowViewEffect::realDeactivate);
|
||||||
|
|
||||||
setSource(QUrl::fromLocalFile(QStandardPaths::locate(QStandardPaths::GenericDataLocation, QStringLiteral("kwin/effects/windowview/qml/main.qml"))));
|
setSource(QUrl::fromLocalFile(QStandardPaths::locate(QStandardPaths::GenericDataLocation, QStringLiteral("kwin/effects/windowview/qml/main.qml"))));
|
||||||
|
|
||||||
|
m_realtimeToggleAction = new QAction(this);
|
||||||
|
connect(m_realtimeToggleAction, &QAction::triggered, this, [this]() {
|
||||||
|
if (isRunning() && m_partialActivationFactor > 0.5) {
|
||||||
|
activate();
|
||||||
|
} else {
|
||||||
|
deactivate(0);
|
||||||
|
}
|
||||||
|
m_partialActivationFactor = 0;
|
||||||
|
Q_EMIT gestureInProgressChanged();
|
||||||
|
Q_EMIT partialActivationFactorChanged();
|
||||||
|
});
|
||||||
|
|
||||||
|
m_exposeAction->setObjectName(QStringLiteral("Expose"));
|
||||||
|
m_exposeAction->setText(i18n("Toggle Present Windows (Current desktop)"));
|
||||||
|
KGlobalAccel::self()->setDefaultShortcut(m_exposeAction, QList<QKeySequence>() << (Qt::CTRL | Qt::Key_F9));
|
||||||
|
KGlobalAccel::self()->setShortcut(m_exposeAction, QList<QKeySequence>() << (Qt::CTRL | Qt::Key_F9));
|
||||||
|
m_shortcut = KGlobalAccel::self()->shortcut(m_exposeAction);
|
||||||
|
effects->registerGlobalShortcut(Qt::CTRL | Qt::Key_F9, m_exposeAction);
|
||||||
|
connect(m_exposeAction, &QAction::triggered, this, [this]() {
|
||||||
|
if (!isRunning()) {
|
||||||
|
setMode(ModeCurrentDesktop);
|
||||||
|
activate();
|
||||||
|
} else {
|
||||||
|
deactivate(animationDuration());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
m_exposeAllAction->setObjectName(QStringLiteral("ExposeAll"));
|
||||||
|
m_exposeAllAction->setText(i18n("Toggle Present Windows (All desktops)"));
|
||||||
|
KGlobalAccel::self()->setDefaultShortcut(m_exposeAllAction, QList<QKeySequence>() << (Qt::CTRL | Qt::Key_F10) << Qt::Key_LaunchC);
|
||||||
|
KGlobalAccel::self()->setShortcut(m_exposeAllAction, QList<QKeySequence>() << (Qt::CTRL | Qt::Key_F10) << Qt::Key_LaunchC);
|
||||||
|
m_shortcutAll = KGlobalAccel::self()->shortcut(m_exposeAllAction);
|
||||||
|
effects->registerGlobalShortcut(Qt::CTRL + Qt::Key_F10, m_exposeAllAction);
|
||||||
|
connect(m_exposeAllAction, &QAction::triggered, this, [this]() {
|
||||||
|
if (!isRunning()) {
|
||||||
|
setMode(ModeAllDesktops);
|
||||||
|
activate();
|
||||||
|
} else {
|
||||||
|
deactivate(animationDuration());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
m_exposeClassAction->setObjectName(QStringLiteral("ExposeClass"));
|
||||||
|
m_exposeClassAction->setText(i18n("Toggle Present Windows (Window class)"));
|
||||||
|
KGlobalAccel::self()->setDefaultShortcut(m_exposeClassAction, QList<QKeySequence>() << (Qt::CTRL | Qt::Key_F7));
|
||||||
|
KGlobalAccel::self()->setShortcut(m_exposeClassAction, QList<QKeySequence>() << (Qt::CTRL | Qt::Key_F7));
|
||||||
|
effects->registerGlobalShortcut(Qt::CTRL | Qt::Key_F7, m_exposeClassAction);
|
||||||
|
connect(m_exposeClassAction, &QAction::triggered, this, [this]() {
|
||||||
|
if (!isRunning()) {
|
||||||
|
setMode(ModeWindowClass);
|
||||||
|
activate();
|
||||||
|
} else {
|
||||||
|
deactivate(animationDuration());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
connect(KGlobalAccel::self(), &KGlobalAccel::globalShortcutChanged, this, [this](QAction *action, const QKeySequence &seq) {
|
||||||
|
if (action->objectName() == QStringLiteral("Expose")) {
|
||||||
|
m_shortcut.clear();
|
||||||
|
m_shortcut.append(seq);
|
||||||
|
} else if (action->objectName() == QStringLiteral("ExposeAll")) {
|
||||||
|
m_shortcutAll.clear();
|
||||||
|
m_shortcutAll.append(seq);
|
||||||
|
} else if (action->objectName() == QStringLiteral("ExposeClass")) {
|
||||||
|
m_shortcutClass.clear();
|
||||||
|
m_shortcutClass.append(seq);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
effects->registerRealtimeTouchpadSwipeShortcut(SwipeDirection::Up, 4, m_realtimeToggleAction, [this](qreal progress) {
|
||||||
|
if (m_status == Status::Active) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const bool wasInProgress = m_partialActivationFactor > 0;
|
||||||
|
m_partialActivationFactor = progress;
|
||||||
|
Q_EMIT partialActivationFactorChanged();
|
||||||
|
if (!wasInProgress) {
|
||||||
|
Q_EMIT gestureInProgressChanged();
|
||||||
|
}
|
||||||
|
if (!isRunning()) {
|
||||||
|
partialActivate();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
reconfigure(ReconfigureAll);
|
||||||
}
|
}
|
||||||
|
|
||||||
WindowViewEffect::~WindowViewEffect()
|
WindowViewEffect::~WindowViewEffect()
|
||||||
|
@ -46,13 +141,164 @@ QVariantMap WindowViewEffect::initialProperties(EffectScreen *screen)
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int WindowViewEffect::animationDuration() const
|
||||||
|
{
|
||||||
|
return m_animationDuration;
|
||||||
|
}
|
||||||
|
|
||||||
|
void WindowViewEffect::setAnimationDuration(int duration)
|
||||||
|
{
|
||||||
|
if (m_animationDuration != duration) {
|
||||||
|
m_animationDuration = duration;
|
||||||
|
Q_EMIT animationDurationChanged();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int WindowViewEffect::layout() const
|
||||||
|
{
|
||||||
|
return m_layout;
|
||||||
|
}
|
||||||
|
|
||||||
|
void WindowViewEffect::setLayout(int layout)
|
||||||
|
{
|
||||||
|
if (m_layout != layout) {
|
||||||
|
m_layout = layout;
|
||||||
|
Q_EMIT layoutChanged();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
int WindowViewEffect::requestedEffectChainPosition() const
|
int WindowViewEffect::requestedEffectChainPosition() const
|
||||||
{
|
{
|
||||||
return 70;
|
return 70;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void WindowViewEffect::reconfigure(ReconfigureFlags)
|
||||||
|
{
|
||||||
|
WindowViewConfig::self()->read();
|
||||||
|
setAnimationDuration(animationTime(200));
|
||||||
|
setLayout(WindowViewConfig::layoutMode());
|
||||||
|
|
||||||
|
for (ElectricBorder border : qAsConst(m_borderActivate)) {
|
||||||
|
effects->unreserveElectricBorder(border, this);
|
||||||
|
}
|
||||||
|
for (ElectricBorder border : qAsConst(m_borderActivateAll)) {
|
||||||
|
effects->unreserveElectricBorder(border, this);
|
||||||
|
}
|
||||||
|
|
||||||
|
m_borderActivate.clear();
|
||||||
|
m_borderActivateAll.clear();
|
||||||
|
m_borderActivateClass.clear();
|
||||||
|
|
||||||
|
const auto borderActivate = WindowViewConfig::borderActivate();
|
||||||
|
for (int i : borderActivate) {
|
||||||
|
m_borderActivate.append(ElectricBorder(i));
|
||||||
|
effects->reserveElectricBorder(ElectricBorder(i), this);
|
||||||
|
}
|
||||||
|
const auto activateAll = WindowViewConfig::borderActivateAll();
|
||||||
|
for (int i : activateAll) {
|
||||||
|
m_borderActivateAll.append(ElectricBorder(i));
|
||||||
|
effects->reserveElectricBorder(ElectricBorder(i), this);
|
||||||
|
}
|
||||||
|
const auto activateClass = WindowViewConfig::borderActivateClass();
|
||||||
|
for (int i : activateClass) {
|
||||||
|
m_borderActivateClass.append(ElectricBorder(i));
|
||||||
|
effects->reserveElectricBorder(ElectricBorder(i), this);
|
||||||
|
}
|
||||||
|
|
||||||
|
auto touchCallback = [this](ElectricBorder border, const QSizeF &deltaProgress, const EffectScreen *screen) {
|
||||||
|
Q_UNUSED(screen)
|
||||||
|
if (m_status == Status::Active) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (m_touchBorderActivate.contains(border)) {
|
||||||
|
setMode(ModeCurrentDesktop);
|
||||||
|
} else if (m_touchBorderActivateAll.contains(border)) {
|
||||||
|
setMode(ModeAllDesktops);
|
||||||
|
} else if (m_touchBorderActivateClass.contains(border)) {
|
||||||
|
setMode(ModeWindowClass);
|
||||||
|
}
|
||||||
|
const bool wasInProgress = m_partialActivationFactor > 0;
|
||||||
|
const int maxDelta = 500; // Arbitrary logical pixels value seems to behave better than scaledScreenSize
|
||||||
|
if (border == ElectricTop || border == ElectricBottom) {
|
||||||
|
m_partialActivationFactor = std::min(1.0, qAbs(deltaProgress.height()) / maxDelta);
|
||||||
|
} else {
|
||||||
|
m_partialActivationFactor = std::min(1.0, qAbs(deltaProgress.width()) / maxDelta);
|
||||||
|
}
|
||||||
|
Q_EMIT partialActivationFactorChanged();
|
||||||
|
if (!wasInProgress) {
|
||||||
|
Q_EMIT gestureInProgressChanged();
|
||||||
|
}
|
||||||
|
if (!isRunning()) {
|
||||||
|
partialActivate();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
QList<int> touchActivateBorders = WindowViewConfig::touchBorderActivate();
|
||||||
|
for (const int &border : touchActivateBorders) {
|
||||||
|
m_touchBorderActivate.append(ElectricBorder(border));
|
||||||
|
effects->registerRealtimeTouchBorder(ElectricBorder(border), m_realtimeToggleAction, touchCallback);
|
||||||
|
}
|
||||||
|
touchActivateBorders = WindowViewConfig::touchBorderActivateAll();
|
||||||
|
for (const int &border : touchActivateBorders) {
|
||||||
|
m_touchBorderActivateAll.append(ElectricBorder(border));
|
||||||
|
effects->registerRealtimeTouchBorder(ElectricBorder(border), m_realtimeToggleAction, touchCallback);
|
||||||
|
}
|
||||||
|
touchActivateBorders = WindowViewConfig::touchBorderActivateClass();
|
||||||
|
for (const int &border : touchActivateBorders) {
|
||||||
|
m_touchBorderActivateAll.append(ElectricBorder(border));
|
||||||
|
effects->registerRealtimeTouchBorder(ElectricBorder(border), m_realtimeToggleAction, touchCallback);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void WindowViewEffect::grabbedKeyboardEvent(QKeyEvent *e)
|
||||||
|
{
|
||||||
|
if (e->type() == QEvent::KeyPress) {
|
||||||
|
// check for global shortcuts
|
||||||
|
// HACK: keyboard grab disables the global shortcuts so we have to check for global shortcut (bug 156155)
|
||||||
|
if (m_mode == ModeCurrentDesktop && m_shortcut.contains(e->key() | e->modifiers())) {
|
||||||
|
if (!isRunning()) {
|
||||||
|
setMode(ModeCurrentDesktop);
|
||||||
|
activate();
|
||||||
|
} else {
|
||||||
|
deactivate(animationDuration());
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
} else if (m_mode == ModeAllDesktops && m_shortcutAll.contains(e->key() | e->modifiers())) {
|
||||||
|
if (!isRunning()) {
|
||||||
|
setMode(ModeAllDesktops);
|
||||||
|
activate();
|
||||||
|
} else {
|
||||||
|
deactivate(animationDuration());
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
} else if (m_mode == ModeWindowClass && m_shortcutClass.contains(e->key() | e->modifiers())) {
|
||||||
|
if (!isRunning()) {
|
||||||
|
setMode(ModeWindowClass);
|
||||||
|
activate();
|
||||||
|
} else {
|
||||||
|
deactivate(animationDuration());
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
} else if (e->key() == Qt::Key_Escape) {
|
||||||
|
deactivate(animationDuration());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
QuickSceneEffect::grabbedKeyboardEvent(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
qreal WindowViewEffect::partialActivationFactor() const
|
||||||
|
{
|
||||||
|
return m_partialActivationFactor;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool WindowViewEffect::gestureInProgress() const
|
||||||
|
{
|
||||||
|
return m_partialActivationFactor > 0;
|
||||||
|
}
|
||||||
|
|
||||||
void WindowViewEffect::activate(const QStringList &windowIds)
|
void WindowViewEffect::activate(const QStringList &windowIds)
|
||||||
{
|
{
|
||||||
|
setMode(ModeWindowGroup);
|
||||||
QList<QUuid> internalIds;
|
QList<QUuid> internalIds;
|
||||||
internalIds.reserve(windowIds.count());
|
internalIds.reserve(windowIds.count());
|
||||||
for (const QString &windowId : windowIds) {
|
for (const QString &windowId : windowIds) {
|
||||||
|
@ -75,6 +321,25 @@ void WindowViewEffect::activate(const QStringList &windowIds)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void WindowViewEffect::activate()
|
||||||
|
{
|
||||||
|
if (effects->isScreenLocked()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
m_windowIds.clear();
|
||||||
|
m_status = Status::Active;
|
||||||
|
setRunning(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
void WindowViewEffect::partialActivate()
|
||||||
|
{
|
||||||
|
if (effects->isScreenLocked()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
m_status = Status::Activating;
|
||||||
|
setRunning(true);
|
||||||
|
}
|
||||||
|
|
||||||
void WindowViewEffect::deactivate(int timeout)
|
void WindowViewEffect::deactivate(int timeout)
|
||||||
{
|
{
|
||||||
const auto screenViews = views();
|
const auto screenViews = views();
|
||||||
|
@ -82,11 +347,52 @@ void WindowViewEffect::deactivate(int timeout)
|
||||||
QMetaObject::invokeMethod(view->rootItem(), "stop");
|
QMetaObject::invokeMethod(view->rootItem(), "stop");
|
||||||
}
|
}
|
||||||
m_shutdownTimer->start(timeout);
|
m_shutdownTimer->start(timeout);
|
||||||
|
m_status = Status::Inactive;
|
||||||
}
|
}
|
||||||
|
|
||||||
void WindowViewEffect::realDeactivate()
|
void WindowViewEffect::realDeactivate()
|
||||||
{
|
{
|
||||||
setRunning(false);
|
setRunning(false);
|
||||||
|
m_status = Status::Inactive;
|
||||||
|
}
|
||||||
|
|
||||||
|
void WindowViewEffect::setMode(WindowViewEffect::PresentWindowsMode mode)
|
||||||
|
{
|
||||||
|
if (mode == m_mode) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mode != ModeWindowGroup) {
|
||||||
|
m_windowIds.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
m_mode = mode;
|
||||||
|
Q_EMIT modeChanged();
|
||||||
|
}
|
||||||
|
|
||||||
|
WindowViewEffect::PresentWindowsMode WindowViewEffect::mode() const
|
||||||
|
{
|
||||||
|
return m_mode;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool WindowViewEffect::borderActivated(ElectricBorder border)
|
||||||
|
{
|
||||||
|
if (effects->activeFullScreenEffect() && effects->activeFullScreenEffect() != this) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_borderActivate.contains(border)) {
|
||||||
|
setMode(ModeCurrentDesktop);
|
||||||
|
} else if (m_borderActivateAll.contains(border)) {
|
||||||
|
setMode(ModeAllDesktops);
|
||||||
|
} else if (m_borderActivateClass.contains(border)) {
|
||||||
|
setMode(ModeWindowClass);
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
activate();
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace KWin
|
} // namespace KWin
|
||||||
|
|
|
@ -8,23 +8,71 @@
|
||||||
|
|
||||||
#include <kwinquickeffect.h>
|
#include <kwinquickeffect.h>
|
||||||
|
|
||||||
|
#include <QKeySequence>
|
||||||
|
|
||||||
|
class QAction;
|
||||||
|
|
||||||
namespace KWin
|
namespace KWin
|
||||||
{
|
{
|
||||||
|
|
||||||
class WindowViewEffect : public QuickSceneEffect
|
class WindowViewEffect : public QuickSceneEffect
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
Q_PROPERTY(int animationDuration READ animationDuration NOTIFY animationDurationChanged)
|
||||||
|
Q_PROPERTY(int layout READ layout NOTIFY layoutChanged)
|
||||||
|
Q_PROPERTY(PresentWindowsMode mode READ mode NOTIFY modeChanged)
|
||||||
|
Q_PROPERTY(qreal partialActivationFactor READ partialActivationFactor NOTIFY partialActivationFactorChanged)
|
||||||
|
Q_PROPERTY(bool gestureInProgress READ gestureInProgress NOTIFY gestureInProgressChanged)
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
enum PresentWindowsMode {
|
||||||
|
ModeAllDesktops, // Shows windows of all desktops
|
||||||
|
ModeCurrentDesktop, // Shows windows on current desktop
|
||||||
|
ModeWindowGroup, // Shows windows selected via property
|
||||||
|
ModeWindowClass // Shows all windows of same class as selected class
|
||||||
|
};
|
||||||
|
Q_ENUM(PresentWindowsMode)
|
||||||
|
|
||||||
|
enum class Status {
|
||||||
|
Inactive,
|
||||||
|
Activating,
|
||||||
|
Active
|
||||||
|
};
|
||||||
|
|
||||||
WindowViewEffect();
|
WindowViewEffect();
|
||||||
~WindowViewEffect() override;
|
~WindowViewEffect() override;
|
||||||
|
|
||||||
|
int animationDuration() const;
|
||||||
|
void setAnimationDuration(int duration);
|
||||||
|
|
||||||
|
int layout() const;
|
||||||
|
void setLayout(int layout);
|
||||||
|
|
||||||
|
void reconfigure(ReconfigureFlags) override;
|
||||||
int requestedEffectChainPosition() const override;
|
int requestedEffectChainPosition() const override;
|
||||||
|
|
||||||
|
void grabbedKeyboardEvent(QKeyEvent *e) override;
|
||||||
|
|
||||||
|
bool borderActivated(ElectricBorder border) override;
|
||||||
|
void partialActivate();
|
||||||
|
qreal partialActivationFactor() const;
|
||||||
|
bool gestureInProgress() const;
|
||||||
|
|
||||||
|
void setMode(PresentWindowsMode mode);
|
||||||
|
PresentWindowsMode mode() const;
|
||||||
|
|
||||||
public Q_SLOTS:
|
public Q_SLOTS:
|
||||||
void activate(const QStringList &windowIds);
|
void activate(const QStringList &windowIds);
|
||||||
|
void activate();
|
||||||
void deactivate(int timeout);
|
void deactivate(int timeout);
|
||||||
|
|
||||||
|
Q_SIGNALS:
|
||||||
|
void animationDurationChanged();
|
||||||
|
void partialActivationFactorChanged();
|
||||||
|
void gestureInProgressChanged();
|
||||||
|
void modeChanged();
|
||||||
|
void layoutChanged();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
QVariantMap initialProperties(EffectScreen *screen) override;
|
QVariantMap initialProperties(EffectScreen *screen) override;
|
||||||
|
|
||||||
|
@ -33,6 +81,27 @@ private:
|
||||||
|
|
||||||
QTimer *m_shutdownTimer;
|
QTimer *m_shutdownTimer;
|
||||||
QList<QUuid> m_windowIds;
|
QList<QUuid> m_windowIds;
|
||||||
|
|
||||||
|
// User configuration settings
|
||||||
|
QAction *m_exposeAction = nullptr;
|
||||||
|
QAction *m_exposeAllAction = nullptr;
|
||||||
|
QAction *m_exposeClassAction = nullptr;
|
||||||
|
QAction *m_realtimeToggleAction = nullptr;
|
||||||
|
// Shortcut - needed to toggle the effect
|
||||||
|
QList<QKeySequence> m_shortcut;
|
||||||
|
QList<QKeySequence> m_shortcutAll;
|
||||||
|
QList<QKeySequence> m_shortcutClass;
|
||||||
|
QList<ElectricBorder> m_borderActivate;
|
||||||
|
QList<ElectricBorder> m_borderActivateAll;
|
||||||
|
QList<ElectricBorder> m_borderActivateClass;
|
||||||
|
QList<ElectricBorder> m_touchBorderActivate;
|
||||||
|
QList<ElectricBorder> m_touchBorderActivateAll;
|
||||||
|
QList<ElectricBorder> m_touchBorderActivateClass;
|
||||||
|
Status m_status = Status::Inactive;
|
||||||
|
qreal m_partialActivationFactor = 0;
|
||||||
|
PresentWindowsMode m_mode;
|
||||||
|
int m_animationDuration = 200;
|
||||||
|
int m_layout = 1;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace KWin
|
} // namespace KWin
|
||||||
|
|
|
@ -50,7 +50,7 @@
|
||||||
<default>None</default>
|
<default>None</default>
|
||||||
</entry>
|
</entry>
|
||||||
</group>
|
</group>
|
||||||
<group name="Effect-PresentWindows">
|
<group name="Effect-windowview">
|
||||||
<entry key="BorderActivateAll" type="IntList">
|
<entry key="BorderActivateAll" type="IntList">
|
||||||
<default>ElectricTopLeft</default>
|
<default>ElectricTopLeft</default>
|
||||||
</entry>
|
</entry>
|
||||||
|
|
|
@ -18,7 +18,7 @@
|
||||||
<default>None</default>
|
<default>None</default>
|
||||||
</entry>
|
</entry>
|
||||||
</group>
|
</group>
|
||||||
<group name="Effect-PresentWindows">
|
<group name="Effect-windowview">
|
||||||
<entry key="TouchBorderActivateAll" type="IntList">
|
<entry key="TouchBorderActivateAll" type="IntList">
|
||||||
<default>ElectricNone</default>
|
<default>ElectricNone</default>
|
||||||
</entry>
|
</entry>
|
||||||
|
|
|
@ -96,7 +96,8 @@ void KWinScreenEdgesConfig::save()
|
||||||
OrgKdeKwinEffectsInterface interface(QStringLiteral("org.kde.KWin"),
|
OrgKdeKwinEffectsInterface interface(QStringLiteral("org.kde.KWin"),
|
||||||
QStringLiteral("/Effects"),
|
QStringLiteral("/Effects"),
|
||||||
QDBusConnection::sessionBus());
|
QDBusConnection::sessionBus());
|
||||||
interface.reconfigureEffect(QStringLiteral("presentwindows"));
|
|
||||||
|
interface.reconfigureEffect(QStringLiteral("windowview"));
|
||||||
for (const auto &effectId : qAsConst(m_effects)) {
|
for (const auto &effectId : qAsConst(m_effects)) {
|
||||||
interface.reconfigureEffect(effectId);
|
interface.reconfigureEffect(effectId);
|
||||||
}
|
}
|
||||||
|
@ -289,7 +290,7 @@ void KWinScreenEdgesConfig::monitorShowEvent()
|
||||||
KConfigGroup config(m_config, "Plugins");
|
KConfigGroup config(m_config, "Plugins");
|
||||||
|
|
||||||
// Present Windows
|
// Present Windows
|
||||||
bool enabled = config.readEntry("presentwindowsEnabled", true);
|
bool enabled = config.readEntry("windowviewEnabled", true);
|
||||||
m_form->monitorItemSetEnabled(PresentWindowsCurrent, enabled);
|
m_form->monitorItemSetEnabled(PresentWindowsCurrent, enabled);
|
||||||
m_form->monitorItemSetEnabled(PresentWindowsAll, enabled);
|
m_form->monitorItemSetEnabled(PresentWindowsAll, enabled);
|
||||||
|
|
||||||
|
|
|
@ -89,7 +89,7 @@ void KWinScreenEdgesConfig::save()
|
||||||
OrgKdeKwinEffectsInterface interface(QStringLiteral("org.kde.KWin"),
|
OrgKdeKwinEffectsInterface interface(QStringLiteral("org.kde.KWin"),
|
||||||
QStringLiteral("/Effects"),
|
QStringLiteral("/Effects"),
|
||||||
QDBusConnection::sessionBus());
|
QDBusConnection::sessionBus());
|
||||||
interface.reconfigureEffect(QStringLiteral("presentwindows"));
|
interface.reconfigureEffect(QStringLiteral("windowview"));
|
||||||
for (const auto &effectId : qAsConst(m_effects)) {
|
for (const auto &effectId : qAsConst(m_effects)) {
|
||||||
interface.reconfigureEffect(effectId);
|
interface.reconfigureEffect(effectId);
|
||||||
}
|
}
|
||||||
|
@ -268,7 +268,7 @@ void KWinScreenEdgesConfig::monitorShowEvent()
|
||||||
KConfigGroup config(m_config, "Plugins");
|
KConfigGroup config(m_config, "Plugins");
|
||||||
|
|
||||||
// Present Windows
|
// Present Windows
|
||||||
bool enabled = config.readEntry("presentwindowsEnabled", true);
|
bool enabled = config.readEntry("windowviewEnabled", true);
|
||||||
m_form->monitorItemSetEnabled(PresentWindowsCurrent, enabled);
|
m_form->monitorItemSetEnabled(PresentWindowsCurrent, enabled);
|
||||||
m_form->monitorItemSetEnabled(PresentWindowsAll, enabled);
|
m_form->monitorItemSetEnabled(PresentWindowsAll, enabled);
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue