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
This commit is contained in:
Luca Carlon 2022-05-27 21:49:37 +00:00 committed by Nate Graham
parent 615cd352fb
commit da0dd1e367
16 changed files with 62 additions and 7 deletions

View file

@ -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()

View file

@ -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()

View file

@ -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");

View file

@ -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)

View file

@ -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;

View file

@ -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;
}

View file

@ -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

View file

@ -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()

View file

@ -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;

View file

@ -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.

View file

@ -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)) {

View file

@ -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

View file

@ -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;

View file

@ -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;
}

View file

@ -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()) {

View file

@ -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();