Skip to content
GitLab
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
Plasma
KWin
Commits
d92fa7f1
Commit
d92fa7f1
authored
Mar 16, 2021
by
Kevin Ottens
Committed by
Kevin Ottens
Mar 22, 2021
Browse files
Add the activity management protocol server implementation
parent
b822c1e6
Changes
4
Hide whitespace changes
Inline
Side-by-side
src/wayland/autotests/client/CMakeLists.txt
View file @
d92fa7f1
...
...
@@ -353,6 +353,17 @@ target_link_libraries( testPlasmaVirtualDesktop Qt::Test Qt::Gui KF5::WaylandCli
add_test
(
NAME kwayland-testPlasmaVirtualDesktop COMMAND testPlasmaVirtualDesktop
)
ecm_mark_as_test
(
testPlasmaVirtualDesktop
)
########################################################
# Test Activities
########################################################
set
(
testPlasmaActivities_SRCS
test_plasma_activities.cpp
)
add_executable
(
testPlasmaActivities
${
testPlasmaActivities_SRCS
}
)
target_link_libraries
(
testPlasmaActivities Qt::Test Qt::Gui KF5::WaylandClient Plasma::KWaylandServer
)
add_test
(
NAME kwayland-testPlasmaActivities COMMAND testPlasmaActivities
)
ecm_mark_as_test
(
testPlasmaActivities
)
########################################################
# Test XDG Output
########################################################
...
...
src/wayland/autotests/client/test_plasma_activities.cpp
0 → 100644
View file @
d92fa7f1
/*
SPDX-FileCopyrightText: 2021 Kevin Ottens <kevin.ottens@enioka.com>
SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
*/
// Qt
#include
<QtTest>
// KWin
#include
"KWayland/Client/compositor.h"
#include
"KWayland/Client/connection_thread.h"
#include
"KWayland/Client/event_queue.h"
#include
"KWayland/Client/region.h"
#include
"KWayland/Client/registry.h"
#include
"KWayland/Client/surface.h"
#include
"../../src/server/display.h"
#include
"../../src/server/compositor_interface.h"
#include
"../../src/server/plasmawindowmanagement_interface.h"
#include
"KWayland/Client/plasmawindowmanagement.h"
using
namespace
KWayland
::
Client
;
class
TestActivities
:
public
QObject
{
Q_OBJECT
public:
explicit
TestActivities
(
QObject
*
parent
=
nullptr
);
private
Q_SLOTS
:
void
init
();
void
cleanup
();
void
testEnterLeaveActivity
();
private:
KWaylandServer
::
Display
*
m_display
;
KWaylandServer
::
CompositorInterface
*
m_compositorInterface
;
KWaylandServer
::
PlasmaWindowManagementInterface
*
m_windowManagementInterface
;
KWaylandServer
::
PlasmaWindowInterface
*
m_windowInterface
;
KWayland
::
Client
::
ConnectionThread
*
m_connection
;
KWayland
::
Client
::
Compositor
*
m_compositor
;
KWayland
::
Client
::
EventQueue
*
m_queue
;
KWayland
::
Client
::
PlasmaWindowManagement
*
m_windowManagement
;
KWayland
::
Client
::
PlasmaWindow
*
m_window
;
QThread
*
m_thread
;
};
static
const
QString
s_socketName
=
QStringLiteral
(
"kwayland-test-wayland-activities-0"
);
TestActivities
::
TestActivities
(
QObject
*
parent
)
:
QObject
(
parent
)
,
m_display
(
nullptr
)
,
m_compositorInterface
(
nullptr
)
,
m_connection
(
nullptr
)
,
m_compositor
(
nullptr
)
,
m_queue
(
nullptr
)
,
m_thread
(
nullptr
)
{
}
void
TestActivities
::
init
()
{
using
namespace
KWaylandServer
;
delete
m_display
;
m_display
=
new
Display
(
this
);
m_display
->
addSocketName
(
s_socketName
);
m_display
->
start
();
QVERIFY
(
m_display
->
isRunning
());
// setup connection
m_connection
=
new
KWayland
::
Client
::
ConnectionThread
;
QSignalSpy
connectedSpy
(
m_connection
,
&
ConnectionThread
::
connected
);
QVERIFY
(
connectedSpy
.
isValid
());
m_connection
->
setSocketName
(
s_socketName
);
m_thread
=
new
QThread
(
this
);
m_connection
->
moveToThread
(
m_thread
);
m_thread
->
start
();
m_connection
->
initConnection
();
QVERIFY
(
connectedSpy
.
wait
());
m_queue
=
new
KWayland
::
Client
::
EventQueue
(
this
);
QVERIFY
(
!
m_queue
->
isValid
());
m_queue
->
setup
(
m_connection
);
QVERIFY
(
m_queue
->
isValid
());
Registry
registry
;
QSignalSpy
compositorSpy
(
&
registry
,
&
Registry
::
compositorAnnounced
);
QVERIFY
(
compositorSpy
.
isValid
());
QSignalSpy
windowManagementSpy
(
&
registry
,
&
Registry
::
plasmaWindowManagementAnnounced
);
QVERIFY
(
windowManagementSpy
.
isValid
());
QVERIFY
(
!
registry
.
eventQueue
());
registry
.
setEventQueue
(
m_queue
);
QCOMPARE
(
registry
.
eventQueue
(),
m_queue
);
registry
.
create
(
m_connection
->
display
());
QVERIFY
(
registry
.
isValid
());
registry
.
setup
();
m_compositorInterface
=
new
CompositorInterface
(
m_display
,
m_display
);
QVERIFY
(
compositorSpy
.
wait
());
m_compositor
=
registry
.
createCompositor
(
compositorSpy
.
first
().
first
().
value
<
quint32
>
(),
compositorSpy
.
first
().
last
().
value
<
quint32
>
(),
this
);
m_windowManagementInterface
=
new
PlasmaWindowManagementInterface
(
m_display
,
m_display
);
QVERIFY
(
windowManagementSpy
.
wait
());
m_windowManagement
=
registry
.
createPlasmaWindowManagement
(
windowManagementSpy
.
first
().
first
().
value
<
quint32
>
(),
windowManagementSpy
.
first
().
last
().
value
<
quint32
>
(),
this
);
QSignalSpy
windowSpy
(
m_windowManagement
,
&
PlasmaWindowManagement
::
windowCreated
);
QVERIFY
(
windowSpy
.
isValid
());
m_windowInterface
=
m_windowManagementInterface
->
createWindow
(
this
,
QUuid
::
createUuid
());
m_windowInterface
->
setPid
(
1337
);
QVERIFY
(
windowSpy
.
wait
());
m_window
=
windowSpy
.
first
().
first
().
value
<
PlasmaWindow
*>
();
}
void
TestActivities
::
cleanup
()
{
#define CLEANUP(variable) \
if (variable) { \
delete variable; \
variable = nullptr; \
}
CLEANUP
(
m_compositor
)
CLEANUP
(
m_windowInterface
)
CLEANUP
(
m_windowManagement
)
CLEANUP
(
m_queue
)
if
(
m_connection
)
{
m_connection
->
deleteLater
();
m_connection
=
nullptr
;
}
if
(
m_thread
)
{
m_thread
->
quit
();
m_thread
->
wait
();
delete
m_thread
;
m_thread
=
nullptr
;
}
CLEANUP
(
m_compositorInterface
)
CLEANUP
(
m_windowManagementInterface
)
CLEANUP
(
m_display
)
#undef CLEANUP
}
void
TestActivities
::
testEnterLeaveActivity
()
{
QSignalSpy
enterRequestedSpy
(
m_windowInterface
,
&
KWaylandServer
::
PlasmaWindowInterface
::
enterPlasmaActivityRequested
);
m_window
->
requestEnterActivity
(
QStringLiteral
(
"0-1"
));
enterRequestedSpy
.
wait
();
QCOMPARE
(
enterRequestedSpy
.
takeFirst
().
at
(
0
).
toString
(),
QStringLiteral
(
"0-1"
));
QSignalSpy
activityEnteredSpy
(
m_window
,
&
KWayland
::
Client
::
PlasmaWindow
::
plasmaActivityEntered
);
//agree to the request
m_windowInterface
->
addPlasmaActivity
(
QStringLiteral
(
"0-1"
));
QCOMPARE
(
m_windowInterface
->
plasmaActivities
().
length
(),
1
);
QCOMPARE
(
m_windowInterface
->
plasmaActivities
().
first
(),
QStringLiteral
(
"0-1"
));
//check if the client received the enter
activityEnteredSpy
.
wait
();
QCOMPARE
(
activityEnteredSpy
.
takeFirst
().
at
(
0
).
toString
(),
QStringLiteral
(
"0-1"
));
QCOMPARE
(
m_window
->
plasmaActivities
().
length
(),
1
);
QCOMPARE
(
m_window
->
plasmaActivities
().
first
(),
QStringLiteral
(
"0-1"
));
//add another activity, server side
m_windowInterface
->
addPlasmaActivity
(
QStringLiteral
(
"0-3"
));
activityEnteredSpy
.
wait
();
QCOMPARE
(
activityEnteredSpy
.
takeFirst
().
at
(
0
).
toString
(),
QStringLiteral
(
"0-3"
));
QCOMPARE
(
m_windowInterface
->
plasmaActivities
().
length
(),
2
);
QCOMPARE
(
m_window
->
plasmaActivities
().
length
(),
2
);
QCOMPARE
(
m_window
->
plasmaActivities
()[
1
],
QStringLiteral
(
"0-3"
));
//remove an activity
QSignalSpy
leaveRequestedSpy
(
m_windowInterface
,
&
KWaylandServer
::
PlasmaWindowInterface
::
leavePlasmaActivityRequested
);
m_window
->
requestLeaveActivity
(
QStringLiteral
(
"0-1"
));
leaveRequestedSpy
.
wait
();
QCOMPARE
(
leaveRequestedSpy
.
takeFirst
().
at
(
0
).
toString
(),
QStringLiteral
(
"0-1"
));
QSignalSpy
activityLeftSpy
(
m_window
,
&
KWayland
::
Client
::
PlasmaWindow
::
plasmaActivityLeft
);
//agree to the request
m_windowInterface
->
removePlasmaActivity
(
QStringLiteral
(
"0-1"
));
QCOMPARE
(
m_windowInterface
->
plasmaActivities
().
length
(),
1
);
QCOMPARE
(
m_windowInterface
->
plasmaActivities
().
first
(),
QStringLiteral
(
"0-3"
));
//check if the client received the leave
activityLeftSpy
.
wait
();
QCOMPARE
(
activityLeftSpy
.
takeFirst
().
at
(
0
).
toString
(),
QStringLiteral
(
"0-1"
));
QCOMPARE
(
m_window
->
plasmaActivities
().
length
(),
1
);
QCOMPARE
(
m_window
->
plasmaActivities
().
first
(),
QStringLiteral
(
"0-3"
));
}
QTEST_GUILESS_MAIN
(
TestActivities
)
#include
"test_plasma_activities.moc"
src/wayland/plasmawindowmanagement_interface.cpp
View file @
d92fa7f1
...
...
@@ -23,7 +23,7 @@
namespace
KWaylandServer
{
static
const
quint32
s_version
=
1
3
;
static
const
quint32
s_version
=
1
4
;
class
PlasmaWindowManagementInterfacePrivate
:
public
QtWaylandServer
::
org_kde_plasma_window_management
{
...
...
@@ -78,6 +78,7 @@ public:
PlasmaWindowInterface
*
parentWindow
=
nullptr
;
QMetaObject
::
Connection
parentWindowDestroyConnection
;
QStringList
plasmaVirtualDesktops
;
QStringList
plasmaActivities
;
QRect
geometry
;
PlasmaWindowInterface
*
q
;
QString
m_title
;
...
...
@@ -105,6 +106,8 @@ protected:
void
org_kde_plasma_window_request_enter_virtual_desktop
(
Resource
*
resource
,
const
QString
&
id
)
override
;
void
org_kde_plasma_window_request_enter_new_virtual_desktop
(
Resource
*
resource
)
override
;
void
org_kde_plasma_window_request_leave_virtual_desktop
(
Resource
*
resource
,
const
QString
&
id
)
override
;
void
org_kde_plasma_window_request_enter_activity
(
Resource
*
resource
,
const
QString
&
id
)
override
;
void
org_kde_plasma_window_request_leave_activity
(
Resource
*
resource
,
const
QString
&
id
)
override
;
};
PlasmaWindowManagementInterfacePrivate
::
PlasmaWindowManagementInterfacePrivate
(
PlasmaWindowManagementInterface
*
_q
,
Display
*
display
)
...
...
@@ -343,6 +346,11 @@ void PlasmaWindowInterfacePrivate::org_kde_plasma_window_bind_resource(Resource
for
(
const
auto
&
desk
:
plasmaVirtualDesktops
)
{
send_virtual_desktop_entered
(
resource
->
handle
,
desk
);
}
for
(
const
auto
&
activity
:
plasmaActivities
)
{
if
(
resource
->
version
()
>=
ORG_KDE_PLASMA_WINDOW_ACTIVITY_ENTERED_SINCE_VERSION
)
{
send_activity_entered
(
resource
->
handle
,
activity
);
}
}
if
(
!
m_appId
.
isEmpty
())
{
send_app_id_changed
(
resource
->
handle
,
m_appId
);
}
...
...
@@ -461,6 +469,18 @@ void PlasmaWindowInterfacePrivate::org_kde_plasma_window_request_leave_virtual_d
emit
q
->
leavePlasmaVirtualDesktopRequested
(
id
);
}
void
PlasmaWindowInterfacePrivate
::
org_kde_plasma_window_request_enter_activity
(
Resource
*
resource
,
const
QString
&
id
)
{
Q_UNUSED
(
resource
)
emit
q
->
enterPlasmaActivityRequested
(
id
);
}
void
PlasmaWindowInterfacePrivate
::
org_kde_plasma_window_request_leave_activity
(
Resource
*
resource
,
const
QString
&
id
)
{
Q_UNUSED
(
resource
)
emit
q
->
leavePlasmaActivityRequested
(
id
);
}
void
PlasmaWindowInterfacePrivate
::
setTitle
(
const
QString
&
title
)
{
if
(
m_title
==
title
)
{
...
...
@@ -915,6 +935,41 @@ QStringList PlasmaWindowInterface::plasmaVirtualDesktops() const
return
d
->
plasmaVirtualDesktops
;
}
void
PlasmaWindowInterface
::
addPlasmaActivity
(
const
QString
&
id
)
{
if
(
d
->
plasmaActivities
.
contains
(
id
))
{
return
;
}
d
->
plasmaActivities
<<
id
;
const
auto
clientResources
=
d
->
resourceMap
();
for
(
auto
resource
:
clientResources
)
{
if
(
resource
->
version
()
>=
ORG_KDE_PLASMA_WINDOW_ACTIVITY_ENTERED_SINCE_VERSION
)
{
d
->
send_activity_entered
(
resource
->
handle
,
id
);
}
}
}
void
PlasmaWindowInterface
::
removePlasmaActivity
(
const
QString
&
id
)
{
if
(
!
d
->
plasmaActivities
.
removeOne
(
id
))
{
return
;
}
const
auto
clientResources
=
d
->
resourceMap
();
for
(
auto
resource
:
clientResources
)
{
if
(
resource
->
version
()
>=
ORG_KDE_PLASMA_WINDOW_ACTIVITY_LEFT_SINCE_VERSION
)
{
d
->
send_activity_left
(
resource
->
handle
,
id
);
}
}
}
QStringList
PlasmaWindowInterface
::
plasmaActivities
()
const
{
return
d
->
plasmaActivities
;
}
void
PlasmaWindowInterface
::
setShadeable
(
bool
set
)
{
d
->
setState
(
ORG_KDE_PLASMA_WINDOW_MANAGEMENT_STATE_SHADEABLE
,
set
);
...
...
src/wayland/plasmawindowmanagement_interface.h
View file @
d92fa7f1
...
...
@@ -174,6 +174,24 @@ public:
*/
QStringList
plasmaVirtualDesktops
()
const
;
/**
* Adds an activity to this window: a window can be on
* an arbitrary subset of activities.
* If it's on none it will be considered on all activities.
*/
void
addPlasmaActivity
(
const
QString
&
id
);
/**
* Removes an activity from a window
*/
void
removePlasmaActivity
(
const
QString
&
id
);
/**
* The ids of all the activities currently associated with this window.
* When an activity is deleted it will be automatically removed from this list
*/
QStringList
plasmaActivities
()
const
;
/**
* Set the application menu D-BUS service name and object path for the window.
*/
...
...
@@ -242,6 +260,18 @@ Q_SIGNALS:
*/
void
leavePlasmaVirtualDesktopRequested
(
const
QString
&
desktop
);
/**
* Emitted when the client wishes this window to enter an activity.
* The server will decide whether to consent this request
*/
void
enterPlasmaActivityRequested
(
const
QString
&
activity
);
/**
* Emitted when the client wishes to remove this window from an activity.
* The server will decide whether to consent this request
*/
void
leavePlasmaActivityRequested
(
const
QString
&
activity
);
private:
friend
class
PlasmaWindowManagementInterface
;
friend
class
PlasmaWindowInterfacePrivate
;
...
...
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment