wayland: implement the content-type protocol

This commit is contained in:
Xaver Hugl 2022-05-25 10:39:03 +02:00
parent f0376367b1
commit b99ae81b08
9 changed files with 163 additions and 0 deletions

View file

@ -29,6 +29,13 @@ class RenderLoop;
class OutputConfiguration;
class ColorTransformation;
enum class ContentType {
None = 0,
Photo = 1,
Video = 2,
Game = 3,
};
class KWIN_EXPORT OutputMode
{
public:

View file

@ -189,6 +189,10 @@ ecm_add_qtwayland_server_protocol_kde(WaylandProtocols_xml
PROTOCOL ${WaylandProtocols_DATADIR}/unstable/xwayland-keyboard-grab/xwayland-keyboard-grab-unstable-v1.xml
BASENAME xwayland-keyboard-grab-unstable-v1
)
ecm_add_qtwayland_server_protocol_kde(WaylandProtocols_xml
PROTOCOL ${WaylandProtocols_DATADIR}/staging/content-type/content-type-v1.xml
BASENAME content-type-v1
)
target_sources(kwin PRIVATE
abstract_data_source.cpp
@ -199,6 +203,7 @@ target_sources(kwin PRIVATE
clientbufferintegration.cpp
clientconnection.cpp
compositor_interface.cpp
contenttype_v1_interface.cpp
contrast_interface.cpp
datacontroldevice_v1_interface.cpp
datacontroldevicemanager_v1_interface.cpp

View file

@ -0,0 +1,84 @@
/*
SPDX-FileCopyrightText: 2022 Xaver Hugl <xaver.hugl@gmail.com>
SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
*/
#include "contenttype_v1_interface.h"
#include "display.h"
#include "surface_interface_p.h"
namespace KWaylandServer
{
static constexpr uint32_t s_version = 1;
static KWin::ContentType waylandToKwinContentType(uint32_t type)
{
using Type = QtWaylandServer::wp_content_type_v1::type;
switch (type) {
case Type::type_photo:
return KWin::ContentType::Photo;
case Type::type_video:
return KWin::ContentType::Video;
case Type::type_game:
return KWin::ContentType::Game;
default:
return KWin::ContentType::None;
}
}
ContentTypeManagerV1Interface::ContentTypeManagerV1Interface(Display *display, QObject *parent)
: QObject(parent)
, QtWaylandServer::wp_content_type_manager_v1(*display, s_version)
{
}
void ContentTypeManagerV1Interface::wp_content_type_manager_v1_destroy(Resource *resource)
{
wl_resource_destroy(resource->handle);
}
void ContentTypeManagerV1Interface::wp_content_type_manager_v1_get_surface_content_type(Resource *resource, uint32_t id, struct ::wl_resource *wlSurface)
{
SurfaceInterface *surface = SurfaceInterface::get(wlSurface);
SurfaceInterfacePrivate *surfacePrivate = SurfaceInterfacePrivate::get(surface);
if (surfacePrivate->contentTypeInterface) {
wl_resource_post_error(resource->handle, error_already_constructed, "Surface already has a wp_content_type_v1");
return;
}
surfacePrivate->contentTypeInterface = new ContentTypeV1Interface(surface, resource->client(), id);
}
ContentTypeV1Interface::ContentTypeV1Interface(SurfaceInterface *surface, wl_client *client, uint32_t id)
: QtWaylandServer::wp_content_type_v1(client, id, s_version)
, m_surface(surface)
{
}
void ContentTypeV1Interface::wp_content_type_v1_set_content_type(Resource *, uint32_t content_type)
{
if (!m_surface) {
return;
}
SurfaceInterfacePrivate *surfacePrivate = SurfaceInterfacePrivate::get(m_surface);
surfacePrivate->pending.contentType = waylandToKwinContentType(content_type);
surfacePrivate->pending.contentTypeIsSet = true;
}
void ContentTypeV1Interface::wp_content_type_v1_destroy(Resource *resource)
{
if (m_surface) {
SurfaceInterfacePrivate *surfacePrivate = SurfaceInterfacePrivate::get(m_surface);
surfacePrivate->pending.contentType = KWin::ContentType::None;
surfacePrivate->pending.contentTypeIsSet = true;
}
wl_resource_destroy(resource->handle);
}
void ContentTypeV1Interface::wp_content_type_v1_destroy_resource(Resource *)
{
delete this;
}
}

View file

@ -0,0 +1,42 @@
/*
SPDX-FileCopyrightText: 2022 Xaver Hugl <xaver.hugl@gmail.com>
SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
*/
#pragma once
#include "surface_interface.h"
#include "qwayland-server-content-type-v1.h"
namespace KWaylandServer
{
class ContentTypeV1Interface;
class Display;
class ContentTypeManagerV1Interface : public QObject, private QtWaylandServer::wp_content_type_manager_v1
{
public:
ContentTypeManagerV1Interface(Display *display, QObject *parent = nullptr);
private:
void wp_content_type_manager_v1_destroy(QtWaylandServer::wp_content_type_manager_v1::Resource *resource) override;
void wp_content_type_manager_v1_get_surface_content_type(Resource *resource, uint32_t id, struct ::wl_resource *surface) override;
};
class ContentTypeV1Interface : public QObject, private QtWaylandServer::wp_content_type_v1
{
Q_OBJECT
public:
ContentTypeV1Interface(SurfaceInterface *surface, wl_client *client, uint32_t id);
private:
void wp_content_type_v1_set_content_type(QtWaylandServer::wp_content_type_v1::Resource *resource, uint32_t content_type) override;
void wp_content_type_v1_destroy(QtWaylandServer::wp_content_type_v1::Resource *resource) override;
void wp_content_type_v1_destroy_resource(QtWaylandServer::wp_content_type_v1::Resource *resource) override;
const QPointer<SurfaceInterface> m_surface;
};
}

View file

@ -8,6 +8,7 @@
#include "clientbuffer.h"
#include "clientconnection.h"
#include "compositor_interface.h"
#include "contenttype_v1_interface.h"
#include "display.h"
#include "idleinhibit_v1_interface_p.h"
#include "linuxdmabufv1clientbuffer.h"
@ -536,6 +537,10 @@ void SurfaceState::mergeInto(SurfaceState *target)
target->bufferTransform = bufferTransform;
target->bufferTransformIsSet = true;
}
if (contentTypeIsSet) {
target->contentType = contentType;
target->contentTypeIsSet = true;
}
*this = SurfaceState{};
below = target->below;
@ -1025,6 +1030,11 @@ LinuxDmaBufV1Feedback *SurfaceInterface::dmabufFeedbackV1() const
return d->dmabufFeedbackV1.get();
}
KWin::ContentType SurfaceInterface::contentType() const
{
return d->current.contentType;
}
QPointF SurfaceInterface::mapToBuffer(const QPointF &point) const
{
return d->surfaceToBufferMatrix.map(point);

View file

@ -6,6 +6,7 @@
*/
#pragma once
#include "core/output.h"
#include "output_interface.h"
#include <QMatrix4x4>
@ -306,6 +307,11 @@ public:
*/
LinuxDmaBufV1Feedback *dmabufFeedbackV1() const;
/**
* @returns the current content type of this surface
*/
KWin::ContentType contentType() const;
/**
* @returns The SurfaceInterface for the @p native resource.
*/

View file

@ -19,6 +19,7 @@ namespace KWaylandServer
class IdleInhibitorV1Interface;
class SurfaceRole;
class ViewportInterface;
class ContentTypeV1Interface;
struct SurfaceState
{
@ -38,6 +39,7 @@ struct SurfaceState
bool childrenChanged = false;
bool bufferScaleIsSet = false;
bool bufferTransformIsSet = false;
bool contentTypeIsSet = false;
qint32 bufferScale = 1;
KWin::Output::Transform bufferTransform = KWin::Output::Transform::Normal;
wl_list frameCallbacks;
@ -47,6 +49,7 @@ struct SurfaceState
QPointer<BlurInterface> blur;
QPointer<ContrastInterface> contrast;
QPointer<SlideInterface> slide;
KWin::ContentType contentType = KWin::ContentType::None;
// Subsurfaces are stored in two lists. The below list contains subsurfaces that
// are below their parent surface; the above list contains subsurfaces that are
@ -134,6 +137,7 @@ public:
QVector<IdleInhibitorV1Interface *> idleInhibitors;
ViewportInterface *viewportExtension = nullptr;
std::unique_ptr<LinuxDmaBufV1Feedback> dmabufFeedbackV1;
QPointer<ContentTypeV1Interface> contentTypeInterface;
ClientConnection *client = nullptr;
protected:

View file

@ -25,6 +25,7 @@
#include "wayland/appmenu_interface.h"
#include "wayland/blur_interface.h"
#include "wayland/compositor_interface.h"
#include "wayland/contenttype_v1_interface.h"
#include "wayland/datacontroldevicemanager_v1_interface.h"
#include "wayland/datadevicemanager_interface.h"
#include "wayland/datasource_interface.h"
@ -481,6 +482,8 @@ bool WaylandServer::init(InitializationFlags flags)
w->setLockScreenOverlay(true);
});
m_contentTypeManager = new KWaylandServer::ContentTypeManagerV1Interface(m_display, m_display);
return true;
}

View file

@ -49,6 +49,7 @@ class TabletManagerV2Interface;
class KeyboardShortcutsInhibitManagerV1Interface;
class XdgDecorationManagerV1Interface;
class XWaylandKeyboardGrabManagerV1Interface;
class ContentTypeManagerV1Interface;
}
namespace KWin
@ -288,6 +289,7 @@ private:
KWaylandServer::PrimaryOutputV1Interface *m_primary = nullptr;
XdgActivationV1Integration *m_xdgActivationIntegration = nullptr;
KWaylandServer::XWaylandKeyboardGrabManagerV1Interface *m_xWaylandKeyboardGrabManager = nullptr;
KWaylandServer::ContentTypeManagerV1Interface *m_contentTypeManager = nullptr;
QList<Window *> m_windows;
InitializationFlags m_initFlags;
QHash<Output *, WaylandOutput *> m_waylandOutputs;