From da0dd1e367b638f7d7803f1eccfb8a36d54c3a43 Mon Sep 17 00:00:00 2001 From: Luca Carlon Date: Fri, 27 May 2022 21:49:37 +0000 Subject: [PATCH] Support new AppletPopup window type See the discussion in https://invent.kde.org/frameworks/plasma-framework/-/merge_requests/500. BUG: 411462 BUG: 332512 FIXED-IN: 5.25 --- autotests/integration/internal_window.cpp | 2 ++ autotests/integration/plasma_surface_test.cpp | 2 ++ src/debug_console.cpp | 2 ++ src/effects.cpp | 1 + src/effects.h | 1 + .../fadingpopups/package/contents/code/main.js | 3 ++- src/libkwineffects/kwineffects.h | 4 ++++ src/wayland/autotests/client/test_plasmashell.cpp | 1 + src/wayland/plasmashell_interface.cpp | 3 +++ src/wayland/plasmashell_interface.h | 1 + src/wayland/tests/plasmasurfacetest.cpp | 4 ++++ src/window.cpp | 7 +++++-- src/window.h | 11 +++++++++++ src/workspace.cpp | 2 +- src/x11window.cpp | 13 ++++++++++++- src/xdgshellwindow.cpp | 12 ++++++++++-- 16 files changed, 62 insertions(+), 7 deletions(-) diff --git a/autotests/integration/internal_window.cpp b/autotests/integration/internal_window.cpp index 8bad187267..06aa38925d 100644 --- a/autotests/integration/internal_window.cpp +++ b/autotests/integration/internal_window.cpp @@ -713,6 +713,7 @@ void InternalWindowTest::testWindowType_data() QTest::newRow("ComboBox") << NET::ComboBox; QTest::newRow("OnScreenDisplay") << NET::OnScreenDisplay; QTest::newRow("CriticalNotification") << NET::CriticalNotification; + QTest::newRow("AppletPopup") << NET::AppletPopup; } void InternalWindowTest::testWindowType() @@ -748,6 +749,7 @@ void InternalWindowTest::testChangeWindowType_data() QTest::newRow("ComboBox") << NET::ComboBox; QTest::newRow("OnScreenDisplay") << NET::OnScreenDisplay; QTest::newRow("CriticalNotification") << NET::CriticalNotification; + QTest::newRow("AppletPopup") << NET::AppletPopup; } void InternalWindowTest::testChangeWindowType() diff --git a/autotests/integration/plasma_surface_test.cpp b/autotests/integration/plasma_surface_test.cpp index f0b7bd0c44..186e0f40e6 100644 --- a/autotests/integration/plasma_surface_test.cpp +++ b/autotests/integration/plasma_surface_test.cpp @@ -94,6 +94,7 @@ void PlasmaSurfaceTest::testRoleOnAllDesktops_data() QTest::newRow("Notification") << KWayland::Client::PlasmaShellSurface::Role::Notification << true; QTest::newRow("ToolTip") << KWayland::Client::PlasmaShellSurface::Role::ToolTip << true; QTest::newRow("CriticalNotification") << KWayland::Client::PlasmaShellSurface::Role::CriticalNotification << true; + QTest::newRow("AppletPopup") << KWayland::Client::PlasmaShellSurface::Role::AppletPopup << true; } void PlasmaSurfaceTest::testRoleOnAllDesktops() @@ -152,6 +153,7 @@ void PlasmaSurfaceTest::testAcceptsFocus_data() QTest::newRow("Notification") << KWayland::Client::PlasmaShellSurface::Role::Notification << false << false; QTest::newRow("ToolTip") << KWayland::Client::PlasmaShellSurface::Role::ToolTip << false << false; QTest::newRow("CriticalNotification") << KWayland::Client::PlasmaShellSurface::Role::CriticalNotification << false << false; + QTest::newRow("AppletPopup") << KWayland::Client::PlasmaShellSurface::Role::AppletPopup << true << true; } void PlasmaSurfaceTest::testAcceptsFocus() diff --git a/src/debug_console.cpp b/src/debug_console.cpp index 2f9a8f66c6..1a1e6c853f 100644 --- a/src/debug_console.cpp +++ b/src/debug_console.cpp @@ -1157,6 +1157,8 @@ QVariant DebugConsoleModel::propertyData(QObject *object, const QModelIndex &ind return QStringLiteral("NET::OnScreenDisplay"); case NET::CriticalNotification: return QStringLiteral("NET::CriticalNotification"); + case NET::AppletPopup: + return QStringLiteral("NET::AppletPopup"); case NET::Unknown: default: return QStringLiteral("NET::Unknown"); diff --git a/src/effects.cpp b/src/effects.cpp index 72d0fd3a38..24ebb92a0e 100644 --- a/src/effects.cpp +++ b/src/effects.cpp @@ -2015,6 +2015,7 @@ WINDOW_HELPER(bool, isPopupMenu, isPopupMenu) WINDOW_HELPER(bool, isTooltip, isTooltip) WINDOW_HELPER(bool, isNotification, isNotification) WINDOW_HELPER(bool, isCriticalNotification, isCriticalNotification) +WINDOW_HELPER(bool, isAppletPopup, isAppletPopup) WINDOW_HELPER(bool, isOnScreenDisplay, isOnScreenDisplay) WINDOW_HELPER(bool, isComboBox, isComboBox) WINDOW_HELPER(bool, isDNDIcon, isDNDIcon) diff --git a/src/effects.h b/src/effects.h index a7f3ed54a5..1df1e4d868 100644 --- a/src/effects.h +++ b/src/effects.h @@ -437,6 +437,7 @@ public: bool isTooltip() const override; bool isNotification() const override; bool isCriticalNotification() const override; + bool isAppletPopup() const override; bool isOnScreenDisplay() const override; bool isComboBox() const override; bool isDNDIcon() const override; diff --git a/src/effects/fadingpopups/package/contents/code/main.js b/src/effects/fadingpopups/package/contents/code/main.js index c593c5c635..1695def04f 100644 --- a/src/effects/fadingpopups/package/contents/code/main.js +++ b/src/effects/fadingpopups/package/contents/code/main.js @@ -58,7 +58,8 @@ function isPopupWindow(window) { // was doing that. if (window.dock || window.splash || window.toolbar || window.notification || window.onScreenDisplay - || window.criticalNotification) { + || window.criticalNotification + || window.appletPopup) { return true; } diff --git a/src/libkwineffects/kwineffects.h b/src/libkwineffects/kwineffects.h index 60950d0925..7df3c2be00 100644 --- a/src/libkwineffects/kwineffects.h +++ b/src/libkwineffects/kwineffects.h @@ -2541,6 +2541,10 @@ public: * using the non-standard _KDE_NET_WM_WINDOW_TYPE_CRITICAL_NOTIFICATION */ virtual bool isCriticalNotification() const = 0; + /** + * Returns whether the window is a window used for applet popups. + */ + virtual bool isAppletPopup() const = 0; /** * Returns whether the window is an on screen display window * using the non-standard _KDE_NET_WM_WINDOW_TYPE_ON_SCREEN_DISPLAY diff --git a/src/wayland/autotests/client/test_plasmashell.cpp b/src/wayland/autotests/client/test_plasmashell.cpp index aae2ab27d3..c3a9eea660 100644 --- a/src/wayland/autotests/client/test_plasmashell.cpp +++ b/src/wayland/autotests/client/test_plasmashell.cpp @@ -144,6 +144,7 @@ void TestPlasmaShell::testRole_data() QTest::newRow("notification") << PlasmaShellSurface::Role::Notification << PlasmaShellSurfaceInterface::Role::Notification; QTest::newRow("tooltip") << PlasmaShellSurface::Role::ToolTip << PlasmaShellSurfaceInterface::Role::ToolTip; QTest::newRow("criticalnotification") << PlasmaShellSurface::Role::CriticalNotification << PlasmaShellSurfaceInterface::Role::CriticalNotification; + QTest::newRow("appletPopup") << PlasmaShellSurface::Role::AppletPopup << PlasmaShellSurfaceInterface::Role::AppletPopup; } void TestPlasmaShell::testRole() diff --git a/src/wayland/plasmashell_interface.cpp b/src/wayland/plasmashell_interface.cpp index 1829233edc..9cc85d7f72 100644 --- a/src/wayland/plasmashell_interface.cpp +++ b/src/wayland/plasmashell_interface.cpp @@ -183,6 +183,9 @@ void PlasmaShellSurfaceInterfacePrivate::org_kde_plasma_surface_set_role(Resourc case role_criticalnotification: r = PlasmaShellSurfaceInterface::Role::CriticalNotification; break; + case role_appletpopup: + r = PlasmaShellSurfaceInterface::Role::AppletPopup; + break; case role_normal: default: r = PlasmaShellSurfaceInterface::Role::Normal; diff --git a/src/wayland/plasmashell_interface.h b/src/wayland/plasmashell_interface.h index f8b5f339d7..75753e96f4 100644 --- a/src/wayland/plasmashell_interface.h +++ b/src/wayland/plasmashell_interface.h @@ -91,6 +91,7 @@ public: Notification, ///< The surface represents a notification ToolTip, ///< The surface represents a tooltip CriticalNotification, ///< The surface represents a critical notification, like battery is running out + AppletPopup, ///< The surface represents an applet popup window }; /** * @returns The requested role, default value is @c Role::Normal. diff --git a/src/wayland/tests/plasmasurfacetest.cpp b/src/wayland/tests/plasmasurfacetest.cpp index 051001bba3..4aee340186 100644 --- a/src/wayland/tests/plasmasurfacetest.cpp +++ b/src/wayland/tests/plasmasurfacetest.cpp @@ -155,6 +155,8 @@ int main(int argc, char **argv) parser.addOption(notificationOption); QCommandLineOption criticalNotificationOption(QStringLiteral("criticalNotification")); parser.addOption(criticalNotificationOption); + QCommandLineOption appletPopupOption(QStringLiteral("appletPopup")); + parser.addOption(appletPopupOption); QCommandLineOption panelOption(QStringLiteral("panel")); parser.addOption(panelOption); QCommandLineOption desktopOption(QStringLiteral("desktop")); @@ -176,6 +178,8 @@ int main(int argc, char **argv) client.setRole(PlasmaShellSurface::Role::Notification); } else if (parser.isSet(criticalNotificationOption)) { client.setRole(PlasmaShellSurface::Role::CriticalNotification); + } else if (parser.isSet(appletPopupOption)) { + client.setRole(PlasmaShellSurface::Role::AppletPopup); } else if (parser.isSet(panelOption)) { client.setRole(PlasmaShellSurface::Role::Panel); } else if (parser.isSet(desktopOption)) { diff --git a/src/window.cpp b/src/window.cpp index c68dd16803..934ac1a458 100644 --- a/src/window.cpp +++ b/src/window.cpp @@ -922,7 +922,7 @@ Layer Window::belongsToLayer() const if (isSplash()) { // no damn annoying splashscreens return NormalLayer; // getting in the way of everything else } - if (isDock()) { + if (isDock() || isAppletPopup()) { if (workspace()->showingDesktop()) { return NotificationLayer; } @@ -1046,7 +1046,7 @@ bool Window::isMostRecentlyRaised() const bool Window::wantsTabFocus() const { - return (isNormalWindow() || isDialog()) && wantsInput(); + return (isNormalWindow() || isDialog() || isAppletPopup()) && wantsInput(); } bool Window::isSpecialWindow() const @@ -3759,6 +3759,9 @@ void Window::setQuickTileMode(QuickTileMode mode, bool keyboard) if (!isResizable()) { return; } + if (isAppletPopup()) { + return; + } workspace()->updateFocusMousePosition(Cursors::self()->mouse()->pos()); // may cause leave event diff --git a/src/window.h b/src/window.h index c054685e42..73c0c7eb84 100644 --- a/src/window.h +++ b/src/window.h @@ -211,6 +211,11 @@ class KWIN_EXPORT Window : public QObject */ Q_PROPERTY(bool criticalNotification READ isCriticalNotification) + /** + * Returns whether the window is an applet popup. + */ + Q_PROPERTY(bool appletPopup READ isAppletPopup) + /** * Returns whether the window is an On Screen Display. */ @@ -672,6 +677,7 @@ public: bool isTooltip() const; bool isNotification() const; bool isCriticalNotification() const; + bool isAppletPopup() const; bool isOnScreenDisplay() const; bool isComboBox() const; bool isDNDIcon() const; @@ -2146,6 +2152,11 @@ inline bool Window::isCriticalNotification() const return windowType() == NET::CriticalNotification; } +inline bool Window::isAppletPopup() const +{ + return windowType() == NET::AppletPopup; +} + inline bool Window::isOnScreenDisplay() const { return windowType() == NET::OnScreenDisplay; diff --git a/src/workspace.cpp b/src/workspace.cpp index 302475c22d..698b3dd72a 100644 --- a/src/workspace.cpp +++ b/src/workspace.cpp @@ -2479,7 +2479,7 @@ QPoint Workspace::adjustWindowPosition(Window *window, QPoint pos, bool unrestri if (!(*l)->isOnCurrentActivity()) { continue; // wrong activity } - if ((*l)->isDesktop() || (*l)->isSplash() || (*l)->isNotification() || (*l)->isCriticalNotification() || (*l)->isOnScreenDisplay()) { + if ((*l)->isDesktop() || (*l)->isSplash() || (*l)->isNotification() || (*l)->isCriticalNotification() || (*l)->isOnScreenDisplay() || (*l)->isAppletPopup()) { continue; } diff --git a/src/x11window.cpp b/src/x11window.cpp index 9d84c3a070..398f65772f 100644 --- a/src/x11window.cpp +++ b/src/x11window.cpp @@ -86,7 +86,8 @@ const NET::WindowTypes SUPPORTED_MANAGED_WINDOW_TYPES_MASK = NET::NormalMask | NET::SplashMask | NET::NotificationMask | NET::OnScreenDisplayMask - | NET::CriticalNotificationMask; + | NET::CriticalNotificationMask + | NET::AppletPopupMask; X11DecorationRenderer::X11DecorationRenderer(Decoration::DecoratedClientImpl *client) : DecorationRenderer(client) @@ -1205,6 +1206,7 @@ void X11Window::detectNoBorder() case NET::Notification: case NET::OnScreenDisplay: case NET::CriticalNotification: + case NET::AppletPopup: noborder = true; app_noborder = true; break; @@ -1444,6 +1446,9 @@ bool X11Window::isMinimizable() const if (isSpecialWindow() && !isTransient()) { return false; } + if (isAppletPopup()) { + return false; + } if (!rules()->checkMinimize(true)) { return false; } @@ -4109,6 +4114,9 @@ bool X11Window::isMaximizable() const if (!isResizable() || isToolbar()) { // SELI isToolbar() ? return false; } + if (isAppletPopup()) { + return false; + } if (rules()->checkMaximize(MaximizeRestore) == MaximizeRestore && rules()->checkMaximize(MaximizeFull) != MaximizeRestore) { return true; } @@ -4247,6 +4255,9 @@ void X11Window::changeMaximize(bool horizontal, bool vertical, bool adjust) if (!isResizable() || isToolbar()) { // SELI isToolbar() ? return; } + if (!isMaximizable()) { + return; + } QRect clientArea; if (isElectricBorderMaximizing()) { diff --git a/src/xdgshellwindow.cpp b/src/xdgshellwindow.cpp index 989d0992b8..e344f34180 100644 --- a/src/xdgshellwindow.cpp +++ b/src/xdgshellwindow.cpp @@ -470,6 +470,9 @@ void XdgSurfaceWindow::installPlasmaShellSurface(PlasmaShellSurfaceInterface *sh case PlasmaShellSurfaceInterface::Role::CriticalNotification: type = NET::CriticalNotification; break; + case PlasmaShellSurfaceInterface::Role::AppletPopup: + type = NET::AppletPopup; + break; case PlasmaShellSurfaceInterface::Role::Normal: default: type = NET::Normal; @@ -649,7 +652,7 @@ bool XdgToplevelWindow::isMovable() const if (isRequestedFullScreen()) { return false; } - if (isSpecialWindow() && !isSplash() && !isToolbar()) { + if (isSpecialWindow() && !isSplash() && !isToolbar() && !isAppletPopup()) { return false; } if (rules()->checkPosition(invalidPoint) != invalidPoint) { @@ -1058,8 +1061,13 @@ bool XdgToplevelWindow::acceptsFocus() const if (m_plasmaShellSurface->role() == PlasmaShellSurfaceInterface::Role::OnScreenDisplay || m_plasmaShellSurface->role() == PlasmaShellSurfaceInterface::Role::ToolTip) { return false; } - if (m_plasmaShellSurface->role() == PlasmaShellSurfaceInterface::Role::Notification || m_plasmaShellSurface->role() == PlasmaShellSurfaceInterface::Role::CriticalNotification) { + switch (m_plasmaShellSurface->role()) { + case PlasmaShellSurfaceInterface::Role::Notification: + case PlasmaShellSurfaceInterface::Role::CriticalNotification: + case PlasmaShellSurfaceInterface::Role::AppletPopup: return m_plasmaShellSurface->panelTakesFocus(); + default: + break; } } return !isZombie() && readyForPainting();