Support CriticalNotification type and place it in a CriticalNotificationLayer

Differential Revision: https://phabricator.kde.org/D20629
This commit is contained in:
Kai Uwe Broulik 2019-05-02 10:29:38 +02:00
parent cc81964fce
commit df85907de3
16 changed files with 58 additions and 13 deletions

View file

@ -366,6 +366,8 @@ Layer AbstractClient::belongsToLayer() const
return OnScreenDisplayLayer;
if (isNotification())
return NotificationLayer;
if (isCriticalNotification())
return CriticalNotificationLayer;
if (workspace()->showingDesktop() && belongsToDesktop()) {
return AboveLayer;
}
@ -477,7 +479,7 @@ bool AbstractClient::wantsTabFocus() const
bool AbstractClient::isSpecialWindow() const
{
// TODO
return isDesktop() || isDock() || isSplash() || isToolbar() || isNotification() || isOnScreenDisplay();
return isDesktop() || isDock() || isSplash() || isToolbar() || isNotification() || isOnScreenDisplay() || isCriticalNotification();
}
void AbstractClient::demandAttention(bool set)

View file

@ -741,6 +741,7 @@ void InternalWindowTest::testWindowType_data()
QTest::newRow("Notification") << NET::Notification;
QTest::newRow("ComboBox") << NET::ComboBox;
QTest::newRow("OnScreenDisplay") << NET::OnScreenDisplay;
QTest::newRow("CriticalNotification") << NET::CriticalNotification;
}
void InternalWindowTest::testWindowType()
@ -776,6 +777,7 @@ void InternalWindowTest::testChangeWindowType_data()
QTest::newRow("Notification") << NET::Notification;
QTest::newRow("ComboBox") << NET::ComboBox;
QTest::newRow("OnScreenDisplay") << NET::OnScreenDisplay;
QTest::newRow("CriticalNotification") << NET::CriticalNotification;
}
void InternalWindowTest::testChangeWindowType()

View file

@ -107,6 +107,7 @@ void PlasmaSurfaceTest::testRoleOnAllDesktops_data()
QTest::newRow("Normal") << PlasmaShellSurface::Role::Normal << false;
QTest::newRow("Notification") << PlasmaShellSurface::Role::Notification << true;
QTest::newRow("ToolTip") << PlasmaShellSurface::Role::ToolTip << true;
QTest::newRow("CriticalNotification") << PlasmaShellSurface::Role::CriticalNotification << true;
}
void PlasmaSurfaceTest::testRoleOnAllDesktops()
@ -164,6 +165,7 @@ void PlasmaSurfaceTest::testAcceptsFocus_data()
QTest::newRow("Normal") << PlasmaShellSurface::Role::Normal << true << true;
QTest::newRow("Notification") << PlasmaShellSurface::Role::Notification << false << false;
QTest::newRow("ToolTip") << PlasmaShellSurface::Role::ToolTip << false << false;
QTest::newRow("CriticalNotification") << PlasmaShellSurface::Role::CriticalNotification << false << false;
}
void PlasmaSurfaceTest::testAcceptsFocus()

View file

@ -176,6 +176,9 @@ public:
bool isNotification() const override {
return false;
}
bool isCriticalNotification() const override {
return false;
}
bool isOnScreenDisplay() const override {
return false;
}

View file

@ -511,6 +511,7 @@ void Client::detectNoBorder()
case NET::Splash :
case NET::Notification :
case NET::OnScreenDisplay :
case NET::CriticalNotification :
noborder = true;
app_noborder = true;
break;

View file

@ -1054,6 +1054,8 @@ QVariant DebugConsoleModel::propertyData(QObject *object, const QModelIndex &ind
return QStringLiteral("NET::DNDIcon");
case NET::OnScreenDisplay:
return QStringLiteral("NET::OnScreenDisplay");
case NET::CriticalNotification:
return QStringLiteral("NET::CriticalNotification");
case NET::Unknown:
default:
return QStringLiteral("NET::Unknown");

View file

@ -1822,6 +1822,7 @@ TOPLEVEL_HELPER(bool, isDropdownMenu, isDropdownMenu)
TOPLEVEL_HELPER(bool, isPopupMenu, isPopupMenu)
TOPLEVEL_HELPER(bool, isTooltip, isTooltip)
TOPLEVEL_HELPER(bool, isNotification, isNotification)
TOPLEVEL_HELPER(bool, isCriticalNotification, isCriticalNotification)
TOPLEVEL_HELPER(bool, isOnScreenDisplay, isOnScreenDisplay)
TOPLEVEL_HELPER(bool, isComboBox, isComboBox)
TOPLEVEL_HELPER(bool, isDNDIcon, isDNDIcon)

View file

@ -432,6 +432,7 @@ public:
bool isPopupMenu() const override;
bool isTooltip() const override;
bool isNotification() const override;
bool isCriticalNotification() const override;
bool isOnScreenDisplay() const override;
bool isComboBox() const override;
bool isDNDIcon() const override;

View file

@ -68,7 +68,8 @@ function isPopupWindow(window) {
// special windows(e.g. notifications) because the monolithic version
// was doing that.
if (window.dock || window.splash || window.toolbar
|| window.notification || window.onScreenDisplay) {
|| window.notification || window.onScreenDisplay
|| window.criticalNotification) {
return true;
}

View file

@ -28,7 +28,7 @@ var morphingEffect = {
geometryChange: function (window, oldGeometry) {
//only tooltips and notifications
if (!window.tooltip && !window.notification) {
if (!window.tooltip && !window.notification && !window.criticalNotification) {
return;
}

View file

@ -40,12 +40,15 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
Every window has one layer assigned in which it is. There are 7 layers,
from bottom : DesktopLayer, BelowLayer, NormalLayer, DockLayer, AboveLayer, NotificationLayer,
ActiveLayer and OnScreenDisplayLayer (see also NETWM sect.7.10.). The layer a window is in depends
on the window type, and on other things like whether the window is active. We extend the layers
provided in NETWM by the NotificationLayer and OnScreenDisplayLayer.
ActiveLayer, CriticalNotificationLayer, and OnScreenDisplayLayer (see also NETWM sect.7.10.).
The layer a window is in depends on the window type, and on other things like whether the window
is active. We extend the layers provided in NETWM by the NotificationLayer, OnScreenDisplayLayer,
and CriticalNotificationLayer.
The NoficationLayer contains notification windows which are kept above all windows except the active
fullscreen window. The OnScreenDisplayLayer is used for eg. volume and brightness change feedback and
is kept above all windows since it provides immediate response to a user action.
fullscreen window. The CriticalNotificationLayer contains notification windows which are important
enough to keep them even above fullscreen windows. The OnScreenDisplayLayer is used for eg. volume
and brightness change feedback and is kept above all windows since it provides immediate response
to a user action.
NET::Splash clients belong to the Normal layer. NET::TopMenu clients
belong to Dock layer. Clients that are both NET::Dock and NET::KeepBelow

View file

@ -1881,6 +1881,11 @@ class KWINEFFECTS_EXPORT EffectWindow : public QObject
* See _NET_WM_WINDOW_TYPE_NOTIFICATION at https://standards.freedesktop.org/wm-spec/wm-spec-latest.html .
**/
Q_PROPERTY(bool notification READ isNotification)
/**
* Returns whether the window is a window with a critical notification.
* using the non-standard _KDE_NET_WM_WINDOW_TYPE_CRITICAL_NOTIFICATION
**/
Q_PROPERTY(bool criticalNotification READ isCriticalNotification)
/**
* Returns whether the window is an on screen display window
* using the non-standard _KDE_NET_WM_WINDOW_TYPE_ON_SCREEN_DISPLAY
@ -2258,6 +2263,11 @@ public:
* See _NET_WM_WINDOW_TYPE_NOTIFICATION at https://standards.freedesktop.org/wm-spec/wm-spec-latest.html .
**/
virtual bool isNotification() const = 0;
/**
* Returns whether the window is a window with a critical notification.
* using the non-standard _KDE_NET_WM_WINDOW_TYPE_CRITICAL_NOTIFICATION
**/
virtual bool isCriticalNotification() 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

@ -70,7 +70,7 @@ void Placement::place(AbstractClient* c, QRect& area)
placeDialog(c, area, options->placement());
else if (c->isSplash())
placeOnMainWindow(c, area); // on mainwindow, if any, otherwise centered
else if (c->isOnScreenDisplay() || c->isNotification())
else if (c->isOnScreenDisplay() || c->isNotification() || c->isCriticalNotification())
placeOnScreenDisplay(c, area);
else if (c->isTransient() && c->hasTransientPlacementHint())
placeTransient(c);

View file

@ -1045,7 +1045,8 @@ bool ShellClient::acceptsFocus() const
if (m_plasmaShellSurface) {
if (m_plasmaShellSurface->role() == PlasmaShellSurfaceInterface::Role::OnScreenDisplay ||
m_plasmaShellSurface->role() == PlasmaShellSurfaceInterface::Role::ToolTip ||
m_plasmaShellSurface->role() == PlasmaShellSurfaceInterface::Role::Notification) {
m_plasmaShellSurface->role() == PlasmaShellSurfaceInterface::Role::Notification ||
m_plasmaShellSurface->role() == PlasmaShellSurfaceInterface::Role::CriticalNotification) {
return false;
}
}
@ -1230,6 +1231,9 @@ void ShellClient::installPlasmaShellSurface(PlasmaShellSurfaceInterface *surface
case PlasmaShellSurfaceInterface::Role::ToolTip:
type = NET::Tooltip;
break;
case PlasmaShellSurfaceInterface::Role::CriticalNotification:
type = NET::CriticalNotification;
break;
case PlasmaShellSurfaceInterface::Role::Normal:
default:
type = NET::Normal;
@ -1237,7 +1241,7 @@ void ShellClient::installPlasmaShellSurface(PlasmaShellSurfaceInterface *surface
}
if (type != m_windowType) {
m_windowType = type;
if (m_windowType == NET::Desktop || type == NET::Dock || type == NET::OnScreenDisplay || type == NET::Notification || type == NET::Tooltip) {
if (m_windowType == NET::Desktop || type == NET::Dock || type == NET::OnScreenDisplay || type == NET::Notification || type == NET::Tooltip || type == NET::CriticalNotification) {
setOnAllDesktops(true);
}
workspace()->updateClientArea();

View file

@ -160,6 +160,10 @@ class KWIN_EXPORT Toplevel
* See _NET_WM_WINDOW_TYPE_NOTIFICATION at https://standards.freedesktop.org/wm-spec/wm-spec-latest.html .
**/
Q_PROPERTY(bool notification READ isNotification)
/**
* Returns whether the window is a window with a critical notification.
**/
Q_PROPERTY(bool criticalNotification READ isCriticalNotification)
/**
* Returns whether the window is an On Screen Display.
**/
@ -284,6 +288,7 @@ public:
bool isPopupMenu() const; // a context popup, not dropdown, not torn-off
bool isTooltip() const;
bool isNotification() const;
bool isCriticalNotification() const;
bool isOnScreenDisplay() const;
bool isComboBox() const;
bool isDNDIcon() const;
@ -747,6 +752,11 @@ inline bool Toplevel::isNotification() const
return windowType() == NET::Notification;
}
inline bool Toplevel::isCriticalNotification() const
{
return windowType() == NET::CriticalNotification;
}
inline bool Toplevel::isOnScreenDisplay() const
{
return windowType() == NET::OnScreenDisplay;

View file

@ -46,12 +46,14 @@ namespace KWin
// window types that are supported as normal windows (i.e. KWin actually manages them)
const NET::WindowTypes SUPPORTED_MANAGED_WINDOW_TYPES_MASK = NET::NormalMask | NET::DesktopMask | NET::DockMask
| NET::ToolbarMask | NET::MenuMask | NET::DialogMask /*| NET::OverrideMask*/ | NET::TopMenuMask
| NET::UtilityMask | NET::SplashMask | NET::NotificationMask | NET::OnScreenDisplayMask;
| NET::UtilityMask | NET::SplashMask | NET::NotificationMask | NET::OnScreenDisplayMask
| NET::CriticalNotificationMask;
// window types that are supported as unmanaged (mainly for compositing)
const NET::WindowTypes SUPPORTED_UNMANAGED_WINDOW_TYPES_MASK = NET::NormalMask | NET::DesktopMask | NET::DockMask
| NET::ToolbarMask | NET::MenuMask | NET::DialogMask /*| NET::OverrideMask*/ | NET::TopMenuMask
| NET::UtilityMask | NET::SplashMask | NET::DropdownMenuMask | NET::PopupMenuMask
| NET::TooltipMask | NET::NotificationMask | NET::ComboBoxMask | NET::DNDIconMask | NET::OnScreenDisplayMask;
| NET::TooltipMask | NET::NotificationMask | NET::ComboBoxMask | NET::DNDIconMask | NET::OnScreenDisplayMask
| NET::CriticalNotificationMask;
const QPoint invalidPoint(INT_MIN, INT_MIN);
@ -82,6 +84,7 @@ enum Layer {
AboveLayer,
NotificationLayer, // layer for windows of type notification
ActiveLayer, // active fullscreen, or active dialog
CriticalNotificationLayer, // layer for notifications that should be shown even on top of fullscreen
OnScreenDisplayLayer, // layer for On Screen Display windows such as volume feedback
UnmanagedLayer, // layer for override redirect windows.
NumLayers // number of layers, must be last