2020-11-07 02:03:57 +00:00
/*
KWin - the KDE window manager
This file is part of the KDE project .
SPDX - FileCopyrightText : 2020 Aleix Pol Gonzalez < aleixpol @ kde . org >
SPDX - License - Identifier : GPL - 2.0 - or - later
*/
# include "xdgactivationv1.h"
# include "abstract_client.h"
# include "effects.h"
2022-01-18 08:35:52 +00:00
# include "utils/common.h"
2020-11-07 02:03:57 +00:00
# include "wayland_server.h"
# include "workspace.h"
# include <KWaylandServer/display.h>
2021-07-15 16:35:04 +00:00
# include <KWaylandServer/plasmawindowmanagement_interface.h>
2022-03-23 10:13:38 +00:00
# include <KWaylandServer/surface_interface.h>
2020-11-07 02:03:57 +00:00
# include <KWaylandServer/xdgactivation_v1_interface.h>
using namespace KWaylandServer ;
namespace KWin
{
2021-06-14 15:48:00 +00:00
static bool isPrivilegedInWindowManagement ( const ClientConnection * client )
{
auto requestedInterfaces = client - > property ( " requestedInterfaces " ) . toStringList ( ) ;
return requestedInterfaces . contains ( QLatin1String ( " org_kde_plasma_window_management " ) ) ;
}
2020-11-07 02:03:57 +00:00
XdgActivationV1Integration : : XdgActivationV1Integration ( XdgActivationV1Interface * activation , QObject * parent )
: QObject ( parent )
{
Workspace * ws = Workspace : : self ( ) ;
connect ( ws , & Workspace : : clientActivated , this , [ this ] ( AbstractClient * client ) {
if ( ! m_currentActivationToken | | ! client | | client - > property ( " token " ) . toString ( ) = = m_currentActivationToken - > token ) {
return ;
}
clear ( ) ;
} ) ;
2021-06-14 15:48:00 +00:00
activation - > setActivationTokenCreator ( [ this ] ( ClientConnection * client , SurfaceInterface * surface , uint serial , SeatInterface * seat , const QString & appId ) - > QString {
2020-11-07 02:03:57 +00:00
Workspace * ws = Workspace : : self ( ) ;
2021-06-14 15:48:00 +00:00
if ( ws - > activeClient ( ) & & ws - > activeClient ( ) - > surface ( ) ! = surface & & ! isPrivilegedInWindowManagement ( client ) ) {
qCWarning ( KWIN_CORE ) < < " Cannot grant a token to " < < client ;
return QStringLiteral ( " not-granted-666 " ) ;
2020-11-07 02:03:57 +00:00
}
static int i = 0 ;
const auto newToken = QStringLiteral ( " kwin-%1 " ) . arg ( + + i ) ;
if ( m_currentActivationToken ) {
clear ( ) ;
}
2021-08-22 09:49:57 +00:00
QSharedPointer < PlasmaWindowActivationInterface > pwActivation ( waylandServer ( ) - > plasmaActivationFeedback ( ) - > createActivation ( appId ) ) ;
2021-07-15 16:35:04 +00:00
m_currentActivationToken . reset ( new ActivationToken { newToken , client , surface , serial , seat , appId , pwActivation } ) ;
2021-06-17 00:01:03 +00:00
if ( ! appId . isEmpty ( ) ) {
const auto icon = QIcon : : fromTheme ( AbstractClient : : iconFromDesktopFile ( appId ) , QIcon : : fromTheme ( QStringLiteral ( " system-run " ) ) ) ;
Q_EMIT effects - > startupAdded ( m_currentActivationToken - > token , icon ) ;
}
2020-11-07 02:03:57 +00:00
return newToken ;
} ) ;
connect ( activation , & XdgActivationV1Interface : : activateRequested , this , & XdgActivationV1Integration : : activateSurface ) ;
}
void XdgActivationV1Integration : : activateSurface ( SurfaceInterface * surface , const QString & token )
{
Workspace * ws = Workspace : : self ( ) ;
auto client = waylandServer ( ) - > findClient ( surface ) ;
if ( ! client ) {
qCWarning ( KWIN_CORE ) < < " could not find the toplevel to activate " < < surface ;
return ;
}
if ( ! m_currentActivationToken | | m_currentActivationToken - > token ! = token ) {
qCDebug ( KWIN_CORE ) < < " Refusing to activate " < < client < < " (provided token: " < < token < < " , current token: " < < ( m_currentActivationToken ? m_currentActivationToken - > token : QStringLiteral ( " null " ) ) < < " ) " ;
2022-04-05 22:33:21 +00:00
client - > demandAttention ( ) ;
2020-11-07 02:03:57 +00:00
return ;
}
auto ownerSurfaceClient = waylandServer ( ) - > findClient ( m_currentActivationToken - > surface ) ;
qCDebug ( KWIN_CORE ) < < " activating " < < client < < surface < < " on behalf of " < < m_currentActivationToken - > surface < < " into " < < ownerSurfaceClient ;
2021-06-14 15:48:00 +00:00
if ( ws - > activeClient ( ) = = ownerSurfaceClient | | isPrivilegedInWindowManagement ( m_currentActivationToken - > client ) ) {
2020-11-07 02:03:57 +00:00
ws - > activateClient ( client ) ;
} else {
qCWarning ( KWIN_CORE ) < < " Activation requested while owner isn't active " < < ownerSurfaceClient - > desktopFileName ( )
2022-03-23 10:13:38 +00:00
< < m_currentActivationToken - > applicationId ;
2020-11-07 02:03:57 +00:00
client - > demandAttention ( ) ;
clear ( ) ;
}
}
void XdgActivationV1Integration : : clear ( )
{
Q_ASSERT ( m_currentActivationToken ) ;
2021-06-17 00:01:03 +00:00
if ( ! m_currentActivationToken - > applicationId . isEmpty ( ) ) {
Q_EMIT effects - > startupRemoved ( m_currentActivationToken - > token ) ;
}
2020-11-07 02:03:57 +00:00
m_currentActivationToken . reset ( ) ;
}
2021-07-15 16:35:04 +00:00
XdgActivationV1Integration : : ActivationToken : : ~ ActivationToken ( ) = default ;
2020-11-07 02:03:57 +00:00
}