diff --git a/client.cpp b/client.cpp index 45a31fc563..8dd6cb055f 100644 --- a/client.cpp +++ b/client.cpp @@ -625,6 +625,7 @@ void Client::detectNoBorder() case NET::TopMenu : case NET::Splash : case NET::Notification : + case NET::OnScreenDisplay : noborder = true; app_noborder = true; break; diff --git a/layers.cpp b/layers.cpp index cf2f7537a5..8b49f29615 100644 --- a/layers.cpp +++ b/layers.cpp @@ -39,11 +39,13 @@ along with this program. If not, see . the clients were created. Every window has one layer assigned in which it is. There are 7 layers, - from bottom : DesktopLayer, BelowLayer, NormalLayer, DockLayer, AboveLayer, NotificationLayer - and ActiveLayer (see also NETWM sect.7.10.). The layer a window is in depends + 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, which contains notification windows. Those are kept - above all windows except the active fullscreen window. + provided in NETWM by the NotificationLayer and OnScreenDisplayLayer. + 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. NET::Splash clients belong to the Normal layer. NET::TopMenu clients belong to Dock layer. Clients that are both NET::Dock and NET::KeepBelow @@ -826,6 +828,8 @@ Layer Client::belongsToLayer() const return AboveLayer; return DockLayer; } + if (isOnScreenDisplay()) + return OnScreenDisplayLayer; if (isNotification()) return NotificationLayer; if (keepBelow()) @@ -834,6 +838,7 @@ Layer Client::belongsToLayer() const return ActiveLayer; if (keepAbove()) return AboveLayer; + return NormalLayer; } diff --git a/placement.cpp b/placement.cpp index 518ef53d33..c193657cf4 100644 --- a/placement.cpp +++ b/placement.cpp @@ -70,8 +70,8 @@ void Placement::place(Client* c, QRect& area) placeDialog(c, area, options->placement()); else if (c->isSplash()) placeOnMainWindow(c, area); // on mainwindow, if any, otherwise centered - else if (c->isNotification()) - placeNotification(c, area); + else if (c->isOnScreenDisplay() || c->isNotification()) + placeOnScreenDisplay(c, area); else place(c, area, options->placement()); } @@ -483,7 +483,7 @@ void Placement::placeUtility(Client* c, QRect& area, Policy /*next*/) place(c, area, Default); } -void Placement::placeNotification(Client* c, QRect& area) +void Placement::placeOnScreenDisplay(Client* c, QRect& area) { // place at lower 1/3 of the screen const int x = area.left() + (area.width() - c->width()) / 2; diff --git a/placement.h b/placement.h index a14036bd3b..ef3469fd24 100644 --- a/placement.h +++ b/placement.h @@ -71,7 +71,7 @@ public: void placeZeroCornered(Client* c, const QRect& area, Policy next = Unknown); void placeDialog(Client* c, QRect& area, Policy next = Unknown); void placeUtility(Client* c, QRect& area, Policy next = Unknown); - void placeNotification(Client* c, QRect& area); + void placeOnScreenDisplay(Client* c, QRect& area); void reinitCascading(int desktop); diff --git a/toplevel.h b/toplevel.h index dee58e2172..37e14279da 100644 --- a/toplevel.h +++ b/toplevel.h @@ -148,6 +148,10 @@ class Toplevel * See _NET_WM_WINDOW_TYPE_NOTIFICATION at http://standards.freedesktop.org/wm-spec/wm-spec-latest.html . */ Q_PROPERTY(bool notification READ isNotification) + /** + * Returns whether the window is an On Screen Display. + */ + Q_PROPERTY(bool onScreenDisplay READ isOnScreenDisplay) /** * Returns whether the window is a combobox popup. * See _NET_WM_WINDOW_TYPE_COMBO at http://standards.freedesktop.org/wm-spec/wm-spec-latest.html . @@ -222,6 +226,7 @@ public: bool isPopupMenu() const; // a context popup, not dropdown, not torn-off bool isTooltip() const; bool isNotification() const; + bool isOnScreenDisplay() const; bool isComboBox() const; bool isDNDIcon() const; @@ -583,6 +588,11 @@ inline bool Toplevel::isNotification() const return windowType() == NET::Notification; } +inline bool Toplevel::isOnScreenDisplay() const +{ + return windowType() == NET::OnScreenDisplay; +} + inline bool Toplevel::isComboBox() const { return windowType() == NET::ComboBox; diff --git a/utils.h b/utils.h index a3cdede12e..0e4fbec547 100644 --- a/utils.h +++ b/utils.h @@ -44,12 +44,12 @@ 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::UtilityMask | NET::SplashMask | NET::NotificationMask | NET::OnScreenDisplayMask; // 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::TooltipMask | NET::NotificationMask | NET::ComboBoxMask | NET::DNDIconMask | NET::OnScreenDisplayMask; const QPoint invalidPoint(INT_MIN, INT_MIN); @@ -80,6 +80,7 @@ enum Layer { AboveLayer, NotificationLayer, // layer for windows of type notification ActiveLayer, // active fullscreen, or active dialog + OnScreenDisplayLayer, // layer for On Screen Display windows such as volume feedback UnmanagedLayer, // layer for override redirect windows. NumLayers // number of layers, must be last };