diff --git a/components/mobileshell/qml/homescreen/HomeScreen.qml b/components/mobileshell/qml/homescreen/HomeScreen.qml index efac718d..c5bd85c6 100644 --- a/components/mobileshell/qml/homescreen/HomeScreen.qml +++ b/components/mobileshell/qml/homescreen/HomeScreen.qml @@ -16,7 +16,7 @@ import org.kde.plasma.private.mobileshell 1.0 as MobileShell * The base homescreen component, implementing features that simplify * homescreen implementation. */ -FocusScope { +Item { id: root /** @@ -35,29 +35,29 @@ FocusScope { signal requestRelativeScroll(var pos) /** - * The requested opacity of homescreen elements (for opacity animations). + * The visual item that is the homescreen. */ - property real homeScreenOpacity: 1 - + property alias contentItem: itemContainer.contentItem + /** * Whether a component is being shown on top of the homescreen within the same * window. */ property bool overlayShown: taskSwitcher.visible || startupFeedback.visible - - NumberAnimation on homeScreenOpacity { - id: opacityAnimation - duration: PlasmaCore.Units.longDuration - } //BEGIN API implementation Connections { target: MobileShell.HomeScreenControls function onOpenHomeScreen() { + if (!MobileShell.WindowUtil.allWindowsMinimized) { + itemContainer.zoomIn(); + } + MobileShell.HomeScreenControls.resetHomeScreenPosition(); taskSwitcher.visible = false; // will trigger homescreen open taskSwitcher.minimizeAll(); + root.homeTriggered(); } @@ -102,15 +102,64 @@ FocusScope { } } - // task switcher component - TaskManager.VirtualDesktopInfo { - id: virtualDesktopInfo - } - - TaskManager.ActivityInfo { - id: activityInfo + // homescreen visual component + MobileShell.BaseItem { + id: itemContainer + anchors.fill: parent + + // animations + opacity: 0 + property real zoomScale: 0.8 + + Component.onCompleted: zoomIn() + + function zoomIn() { + scaleAnim.to = 1; + scaleAnim.restart(); + opacityAnim.to = 1; + opacityAnim.restart(); + } + function zoomOut() { + scaleAnim.to = 0.8; + scaleAnim.restart(); + opacityAnim.to = 0; + opacityAnim.restart(); + } + + NumberAnimation on opacity { + id: opacityAnim + duration: 300 + running: false + } + + NumberAnimation on zoomScale { + id: scaleAnim + duration: 600 + running: false + easing.type: Easing.OutExpo + } + + Connections { + target: MobileShell.WindowUtil + + function onActiveWindowIsShellChanged() { + if (MobileShell.WindowUtil.activeWindowIsShell && !taskSwitcher.visible) { + itemContainer.zoomIn(); + } else { + itemContainer.zoomOut(); + } + } + } + + transform: Scale { + origin.x: itemContainer.width / 2; + origin.y: itemContainer.height / 2; + xScale: itemContainer.zoomScale + yScale: itemContainer.zoomScale + } } + // task switcher component MobileShell.TaskSwitcher { id: taskSwitcher z: 999999 @@ -125,6 +174,14 @@ FocusScope { activity: activityInfo.currentActivity } + TaskManager.VirtualDesktopInfo { + id: virtualDesktopInfo + } + + TaskManager.ActivityInfo { + id: activityInfo + } + anchors.fill: parent // hide homescreen elements to make use of wallpaper @@ -134,15 +191,14 @@ FocusScope { // only animate if going from homescreen if (taskSwitcher.wasInActiveTask) { - opacityAnimation.to = 0; - opacityAnimation.restart(); + itemContainer.zoomOut(); } else { - root.homeScreenOpacity = 0; + itemContainer.zoomOut(); + //itemContainer.opacity = 0; } } else { - opacityAnimation.to = 1; - opacityAnimation.restart(); + itemContainer.zoomIn(); } } } diff --git a/components/mobileshell/windowutil.cpp b/components/mobileshell/windowutil.cpp index 67db86e5..511185f6 100644 --- a/components/mobileshell/windowutil.cpp +++ b/components/mobileshell/windowutil.cpp @@ -19,6 +19,8 @@ WindowUtil::WindowUtil(QObject *parent) m_activeWindowTimer->setInterval(ACTIVE_WINDOW_UPDATE_INVERVAL); connect(m_activeWindowTimer, &QTimer::timeout, this, &WindowUtil::updateActiveWindow); + connect(this, &WindowUtil::activeWindowChanged, this, &WindowUtil::updateActiveWindowIsShell); + initWayland(); } @@ -38,6 +40,11 @@ bool WindowUtil::allWindowsMinimized() const return m_allWindowsMinimized; } +bool WindowUtil::activeWindowIsShell() const +{ + return m_activeWindowIsShell; +} + void WindowUtil::initWayland() { if (!QGuiApplication::platformName().startsWith(QLatin1String("wayland"), Qt::CaseInsensitive)) { @@ -84,6 +91,7 @@ void WindowUtil::updateActiveWindow() disconnect(m_activeWindow.data(), &PlasmaWindow::unmapped, this, &WindowUtil::forgetActiveWindow); } m_activeWindow = m_windowManagement->activeWindow(); + Q_EMIT activeWindowChanged(); if (m_activeWindow) { connect(m_activeWindow.data(), &PlasmaWindow::closeableChanged, this, &WindowUtil::hasCloseableActiveWindowChanged); @@ -133,6 +141,19 @@ void WindowUtil::updateShowingDesktop(bool showing) } } +void WindowUtil::updateActiveWindowIsShell() +{ + if (m_activeWindow) { + if (m_activeWindow->appId() == QStringLiteral("org.kde.plasmashell") && !m_activeWindowIsShell) { + m_activeWindowIsShell = true; + Q_EMIT activeWindowIsShellChanged(); + } else if (m_activeWindow->appId() != QStringLiteral("org.kde.plasmashell") && m_activeWindowIsShell) { + m_activeWindowIsShell = false; + Q_EMIT activeWindowIsShellChanged(); + } + } +} + void WindowUtil::forgetActiveWindow() { using namespace KWayland::Client; diff --git a/components/mobileshell/windowutil.h b/components/mobileshell/windowutil.h index 0b3f0b7f..25632ca6 100644 --- a/components/mobileshell/windowutil.h +++ b/components/mobileshell/windowutil.h @@ -24,6 +24,7 @@ class WindowUtil : public QObject Q_PROPERTY(bool showDesktop READ isShowingDesktop WRITE requestShowingDesktop NOTIFY showingDesktopChanged) Q_PROPERTY(bool allWindowsMinimized READ allWindowsMinimized NOTIFY allWindowsMinimizedChanged) Q_PROPERTY(bool hasCloseableActiveWindow READ hasCloseableActiveWindow NOTIFY hasCloseableActiveWindowChanged) + Q_PROPERTY(bool activeWindowIsShell READ activeWindowIsShell NOTIFY activeWindowIsShellChanged) public: WindowUtil(QObject *parent = nullptr); @@ -31,6 +32,7 @@ public: bool isShowingDesktop() const; bool allWindowsMinimized() const; + bool activeWindowIsShell() const; bool hasCloseableActiveWindow() const; Q_INVOKABLE void closeActiveWindow(); @@ -41,8 +43,11 @@ Q_SIGNALS: void showingDesktopChanged(bool showingDesktop); void allWindowsMinimizedChanged(); void hasCloseableActiveWindowChanged(); + void activeWindowChanged(); + void activeWindowIsShellChanged(); private Q_SLOTS: + void updateActiveWindowIsShell(); void forgetActiveWindow(); void updateShowingDesktop(bool showing); @@ -55,5 +60,6 @@ private: QTimer *m_activeWindowTimer; bool m_showingDesktop = false; - bool m_allWindowsMinimized; + bool m_allWindowsMinimized = true; + bool m_activeWindowIsShell = false; }; diff --git a/containments/homescreen/package/contents/ui/main.qml b/containments/homescreen/package/contents/ui/main.qml index f34199f6..590671d2 100644 --- a/containments/homescreen/package/contents/ui/main.qml +++ b/containments/homescreen/package/contents/ui/main.qml @@ -71,23 +71,32 @@ MobileShell.HomeScreen { } } - // homescreen component - HomeScreen { - id: homescreen - anchors.fill: parent - opacity: root.homeScreenOpacity * (1 - searchWidget.openFactor) + contentItem: Item { + // homescreen component + HomeScreen { + id: homescreen + anchors.fill: parent + opacity: (1 - searchWidget.openFactor) + + // make the homescreen not interactable when task switcher or startup feedback is on + interactive: !root.overlayShown + } - // make the homescreen not interactable when task switcher or startup feedback is on - interactive: !root.overlayShown - } - - // search component - MobileShell.KRunnerWidget { - id: searchWidget - anchors.fill: parent - - opacity: root.homeScreenOpacity - visible: openFactor > 0 + // search component + MobileShell.KRunnerWidget { + id: searchWidget + anchors.fill: parent + + visible: openFactor > 0 + + // close search component when task switcher is shown or hidden + Connections { + target: MobileShell.HomeScreenControls.taskSwitcher + function onVisibleChanged() { + searchWidget.close(); + } + } + } } Connections {