Provide a system bell implementation on wayland

wilder/Plasma/6.3
David Redondo 3 years ago
parent 1ccd95eb00
commit 4c48722c59
  1. 2
      CMakeLists.txt
  2. 41
      src/plugins/systembell/systembell.cpp
  3. 5
      src/plugins/systembell/systembell.h
  4. 6
      src/wayland/CMakeLists.txt
  5. 67
      src/wayland/xdgsystembell_v1.cpp
  6. 37
      src/wayland/xdgsystembell_v1.h

@ -212,7 +212,7 @@ else()
set(HAVE_WL_DISPLAY_SET_DEFAULT_MAX_BUFFER_SIZE 0)
endif()
find_package(WaylandProtocols 1.36)
find_package(WaylandProtocols 1.38)
set_package_properties(WaylandProtocols PROPERTIES
TYPE REQUIRED
PURPOSE "Collection of Wayland protocols that add functionality not available in the Wayland core protocol"

@ -12,6 +12,10 @@
#include "effect/effecthandler.h"
#include "opengl/glshader.h"
#include "opengl/glshadermanager.h"
#include "wayland/surface.h"
#include "wayland/xdgsystembell_v1.h"
#include "wayland_server.h"
#include "window.h"
#include <QDBusConnection>
#include <QFile>
@ -31,6 +35,9 @@ static void ensureResources()
namespace KWin
{
QTimer *SystemBellEffect::s_systemBellRemoveTimer = nullptr;
XdgSystemBellV1Interface *SystemBellEffect::s_systemBell = nullptr;
SystemBellEffect::SystemBellEffect()
: m_configWatcher(KConfigWatcher::create(KSharedConfig::openConfig("kaccessrc")))
, m_kdeglobals(QStringLiteral("kdeglobals"))
@ -67,6 +74,31 @@ SystemBellEffect::SystemBellEffect()
qCWarning(KWIN_SYSTEMBELL) << "Failed to set application properties on canberra context for audio notification:" << ca_strerror(ret);
}
}
if (waylandServer()) {
if (!s_systemBellRemoveTimer) {
s_systemBellRemoveTimer = new QTimer(QCoreApplication::instance());
s_systemBellRemoveTimer->setSingleShot(true);
s_systemBellRemoveTimer->callOnTimeout([]() {
s_systemBell->remove();
s_systemBell = nullptr;
});
}
s_systemBellRemoveTimer->stop();
if (!s_systemBell) {
s_systemBell = new XdgSystemBellV1Interface(waylandServer()->display(), s_systemBellRemoveTimer);
connect(s_systemBell, &XdgSystemBellV1Interface::ringSurface, this, [this](SurfaceInterface *surface) {
triggerWindow(effects->findWindow(surface));
});
connect(s_systemBell, &XdgSystemBellV1Interface::ring, this, [this](ClientConnection *client) {
if (effects->activeWindow()) {
if (effects->activeWindow()->surface() && effects->activeWindow()->surface()->client() == client) {
triggerWindow(effects->activeWindow());
}
}
});
}
}
}
SystemBellEffect::~SystemBellEffect()
@ -74,6 +106,10 @@ SystemBellEffect::~SystemBellEffect()
if (m_caContext) {
ca_context_destroy(m_caContext);
}
// When compositing is restarted, avoid removing the system bell immediately
if (s_systemBell) {
s_systemBellRemoveTimer->start(1000);
}
}
void SystemBellEffect::reconfigure(ReconfigureFlags flags)
@ -169,8 +205,11 @@ void SystemBellEffect::triggerScreen()
void SystemBellEffect::triggerWindow()
{
const auto window = effects->activeWindow();
triggerWindow(effects->activeWindow());
}
void SystemBellEffect::triggerWindow(EffectWindow *window)
{
if (!window || m_windows.contains(window)) {
return;
}

@ -20,6 +20,7 @@ namespace KWin
{
class GLShader;
class XdgSystemBellV1Interface;
class SystemBellEffect : public OffscreenEffect
{
@ -52,6 +53,7 @@ private:
Color,
};
void triggerWindow(EffectWindow *window);
void flash(EffectWindow *window);
void unflash(EffectWindow *window);
void loadConfig(const KConfigGroup &group);
@ -73,6 +75,9 @@ private:
KConfigWatcher::Ptr m_configWatcher;
KConfig m_kdeglobals;
KConfigGroup m_bellConfig;
static QTimer *s_systemBellRemoveTimer;
static XdgSystemBellV1Interface *s_systemBell;
};
inline int SystemBellEffect::requestedEffectChainPosition() const

@ -305,6 +305,10 @@ ecm_add_qtwayland_server_protocol_kde(WaylandProtocols_xml
PROTOCOL ${WaylandProtocols_DATADIR}/staging/alpha-modifier/alpha-modifier-v1.xml
BASENAME alpha-modifier-v1
)
ecm_add_qtwayland_server_protocol_kde(WaylandProtocols_xml
PROTOCOL ${WaylandProtocols_DATADIR}/staging/xdg-system-bell/xdg-system-bell-v1.xml
BASENAME xdg-system-bell-v1
)
target_sources(kwin PRIVATE
abstract_data_source.cpp
@ -387,6 +391,7 @@ target_sources(kwin PRIVATE
xdgforeign_v2.cpp
xdgoutput_v1.cpp
xdgshell.cpp
xdgsystembell_v1.cpp
xdgtopleveldrag_v1.cpp
xwaylandkeyboardgrab_v1.cpp
xwaylandshell_v1.cpp
@ -466,6 +471,7 @@ install(FILES
xdgforeign_v2.h
xdgoutput_v1.h
xdgshell.h
xdgsystembell_v1.h
xwaylandkeyboardgrab_v1.h
xwaylandshell_v1.h
xx_colormanagement_v4.h

@ -0,0 +1,67 @@
/*
SPDX-FileCopyrightText: 2023 David Redondo <kde@david-redondo.de>
SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
*/
#include "xdgsystembell_v1.h"
#include "clientconnection.h"
#include "display.h"
#include "surface.h"
#include <qwayland-server-xdg-system-bell-v1.h>
namespace KWin
{
static constexpr int version = 1;
class XdgSystemBellV1InterfacePrivate : public QtWaylandServer::xdg_system_bell_v1
{
public:
XdgSystemBellV1InterfacePrivate(XdgSystemBellV1Interface *q, Display *display);
XdgSystemBellV1Interface *q;
Display *display;
protected:
void xdg_system_bell_v1_ring(Resource *resource, wl_resource *surface) override;
void xdg_system_bell_v1_destroy(Resource *resource) override;
};
XdgSystemBellV1InterfacePrivate::XdgSystemBellV1InterfacePrivate(XdgSystemBellV1Interface *q, Display *display)
: QtWaylandServer::xdg_system_bell_v1(*display, version)
, q(q)
, display(display)
{
}
void XdgSystemBellV1InterfacePrivate::xdg_system_bell_v1_destroy(Resource *resource)
{
wl_resource_destroy(resource->handle);
}
void XdgSystemBellV1InterfacePrivate::xdg_system_bell_v1_ring(Resource *resource, wl_resource *surface_resource)
{
if (surface_resource) {
auto surface = SurfaceInterface::get(surface_resource);
Q_EMIT q->ringSurface(surface);
return;
}
Q_EMIT q->ring(display->getConnection(resource->client()));
}
XdgSystemBellV1Interface::XdgSystemBellV1Interface(Display *display, QObject *parent)
: QObject(parent)
, d(std::make_unique<XdgSystemBellV1InterfacePrivate>(this, display))
{
}
XdgSystemBellV1Interface::~XdgSystemBellV1Interface() = default;
void XdgSystemBellV1Interface::remove()
{
d->globalRemove();
}
}

@ -0,0 +1,37 @@
/*
SPDX-FileCopyrightText: 2023 David Redondo <kde@david-redondo.de>
SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
*/
#pragma once
#include "kwin_export.h"
#include <QObject>
#include <memory>
namespace KWin
{
class ClientConnection;
class Display;
class SurfaceInterface;
class XdgSystemBellV1InterfacePrivate;
class KWIN_EXPORT XdgSystemBellV1Interface : public QObject
{
Q_OBJECT
public:
XdgSystemBellV1Interface(Display *display, QObject *parent = nullptr);
~XdgSystemBellV1Interface();
void remove();
Q_SIGNALS:
void ring(ClientConnection *client);
void ringSurface(SurfaceInterface *surface);
private:
std::unique_ptr<XdgSystemBellV1InterfacePrivate> d;
};
}
Loading…
Cancel
Save