2017-04-25 17:48:36 +03:00
/*
* Copyright 2016 Smith AR < audoban @ openmailbox . org >
* Michail Vourlakos < mvourlakos @ gmail . com >
*
* This file is part of Latte - Dock
*
* Latte - Dock is free software ; you can redistribute it and / or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation ; either version 2 of
* the License , or ( at your option ) any later version .
*
* Latte - Dock is distributed in the hope that it will be useful ,
* but WITHOUT ANY WARRANTY ; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
* GNU General Public License for more details .
*
* You should have received a copy of the GNU General Public License
* along with this program . If not , see < http : //www.gnu.org/licenses/>.
*/
# include "waylandinterface.h"
2018-12-02 02:05:52 +02:00
// local
2018-12-06 12:15:58 +02:00
# include "view/screenedgeghostwindow.h"
# include "view/view.h"
2018-12-06 14:35:34 +02:00
# include "../lattecorona.h"
2018-12-07 18:55:35 +02:00
# include "../liblatte2/extras.h"
2017-04-25 17:48:36 +03:00
2018-12-02 02:05:52 +02:00
// Qt
2017-04-25 17:48:36 +03:00
# include <QDebug>
# include <QTimer>
2017-06-10 16:33:46 -05:00
# include <QApplication>
# include <QSignalMapper>
2017-04-25 17:48:36 +03:00
# include <QtX11Extras/QX11Info>
2017-06-29 15:33:12 -05:00
# include <QRasterWindow>
2017-04-25 17:48:36 +03:00
2018-12-02 02:05:52 +02:00
// KDE
2017-04-25 17:48:36 +03:00
# include <KWindowSystem>
# include <KWindowInfo>
2018-03-28 20:39:52 +03:00
# include <KWayland/Client/surface.h>
2017-06-29 15:33:12 -05:00
2019-05-26 00:58:42 +03:00
# if KF5_VERSION_MINOR >= 52
# include <KWayland/Client/plasmavirtualdesktop.h>
# endif
2018-12-02 02:05:52 +02:00
// X11
# include <NETWM>
2017-06-10 16:33:46 -05:00
using namespace KWayland : : Client ;
2017-04-25 17:48:36 +03:00
namespace Latte {
2018-07-03 22:15:45 +03:00
class Private : : GhostWindow : public QRasterWindow
{
2017-06-29 15:33:12 -05:00
Q_OBJECT
public :
2019-07-15 14:53:40 +03:00
WindowSystem : : WindowId m_winId ;
2019-05-11 15:43:10 +03:00
GhostWindow ( WindowSystem : : WaylandInterface * waylandInterface )
2017-12-24 20:54:45 +02:00
: m_waylandInterface ( waylandInterface ) {
2017-06-29 15:33:12 -05:00
setFlags ( Qt : : FramelessWindowHint
2017-12-24 20:54:45 +02:00
| Qt : : WindowStaysOnTopHint
| Qt : : NoDropShadowWindowHint
| Qt : : WindowDoesNotAcceptFocus ) ;
2017-06-29 15:33:12 -05:00
2019-07-15 19:15:53 +03:00
connect ( m_waylandInterface , & WindowSystem : : AbstractWindowInterface : : latteWindowAdded , this , & GhostWindow : : identifyWinId ) ;
2017-06-29 15:33:12 -05:00
setupWaylandIntegration ( ) ;
show ( ) ;
}
2017-12-24 20:54:45 +02:00
~ GhostWindow ( ) {
2019-07-15 14:53:40 +03:00
m_waylandInterface - > unregisterIgnoredWindow ( m_winId ) ;
2017-06-29 15:33:12 -05:00
delete m_shellSurface ;
}
2017-12-24 20:54:45 +02:00
void setGeometry ( const QRect & rect ) {
2019-06-24 17:22:37 +03:00
if ( geometry ( ) = = rect ) {
return ;
}
2019-07-15 19:15:53 +03:00
m_validGeometry = rect ;
2019-07-15 14:53:40 +03:00
2019-06-24 17:22:37 +03:00
setMinimumSize ( rect . size ( ) ) ;
2018-03-03 14:14:44 +02:00
setMaximumSize ( rect . size ( ) ) ;
2019-06-24 17:22:37 +03:00
resize ( rect . size ( ) ) ;
2017-06-29 15:33:12 -05:00
m_shellSurface - > setPosition ( rect . topLeft ( ) ) ;
}
2017-12-24 20:54:45 +02:00
void setupWaylandIntegration ( ) {
2017-06-29 15:33:12 -05:00
using namespace KWayland : : Client ;
if ( m_shellSurface )
return ;
Surface * s { Surface : : fromWindow ( this ) } ;
if ( ! s )
return ;
2018-12-06 14:35:34 +02:00
m_shellSurface = m_waylandInterface - > waylandCoronaInterface ( ) - > createSurface ( s , this ) ;
2017-06-29 15:33:12 -05:00
qDebug ( ) < < " wayland ghost window surface was created... " ;
m_shellSurface - > setSkipTaskbar ( true ) ;
m_shellSurface - > setPanelTakesFocus ( false ) ;
m_shellSurface - > setRole ( PlasmaShellSurface : : Role : : Panel ) ;
m_shellSurface - > setPanelBehavior ( PlasmaShellSurface : : PanelBehavior : : AlwaysVisible ) ;
}
2017-12-24 20:54:45 +02:00
KWayland : : Client : : PlasmaShellSurface * m_shellSurface { nullptr } ;
2019-05-11 15:43:10 +03:00
WindowSystem : : WaylandInterface * m_waylandInterface { nullptr } ;
2019-07-15 19:15:53 +03:00
//! geometry() function under wayland does not return nice results
QRect m_validGeometry ;
public slots :
void identifyWinId ( ) {
if ( m_winId . isNull ( ) ) {
m_winId = m_waylandInterface - > winIdFor ( " latte-dock " , m_validGeometry ) ;
m_waylandInterface - > registerIgnoredWindow ( m_winId ) ;
}
}
2017-06-29 15:33:12 -05:00
} ;
2019-05-11 15:43:10 +03:00
namespace WindowSystem {
2017-04-25 17:48:36 +03:00
WaylandInterface : : WaylandInterface ( QObject * parent )
: AbstractWindowInterface ( parent )
{
2018-12-06 14:35:34 +02:00
m_corona = qobject_cast < Latte : : Corona * > ( parent ) ;
2017-04-25 17:48:36 +03:00
}
WaylandInterface : : ~ WaylandInterface ( )
{
}
2017-06-10 16:33:46 -05:00
void WaylandInterface : : init ( )
{
}
2018-03-01 23:53:28 +02:00
void WaylandInterface : : initWindowManagement ( KWayland : : Client : : PlasmaWindowManagement * windowManagement )
{
2019-05-26 00:58:42 +03:00
if ( m_windowManagement = = windowManagement ) {
return ;
}
2018-03-01 23:53:28 +02:00
m_windowManagement = windowManagement ;
connect ( m_windowManagement , & PlasmaWindowManagement : : windowCreated , this , & WaylandInterface : : windowCreatedProxy ) ;
connect ( m_windowManagement , & PlasmaWindowManagement : : activeWindowChanged , this , [ & ] ( ) noexcept {
2019-05-26 00:58:42 +03:00
auto w = m_windowManagement - > activeWindow ( ) ;
2019-07-15 14:53:40 +03:00
if ( ! w | | ( w & & ( ! m_ignoredWindows . contains ( w - > internalId ( ) & & ! isPlasmaDesktop ( w ) ) ) ) ) {
2019-05-26 00:58:42 +03:00
emit activeWindowChanged ( w ? w - > internalId ( ) : 0 ) ;
}
} , Qt : : QueuedConnection ) ;
}
# if KF5_VERSION_MINOR >= 52
void WaylandInterface : : initVirtualDesktopManagement ( KWayland : : Client : : PlasmaVirtualDesktopManagement * virtualDesktopManagement )
{
if ( m_virtualDesktopManagement = = virtualDesktopManagement ) {
return ;
}
m_virtualDesktopManagement = virtualDesktopManagement ;
connect ( m_virtualDesktopManagement , & KWayland : : Client : : PlasmaVirtualDesktopManagement : : desktopCreated , this ,
[ this ] ( const QString & id , quint32 position ) {
addDesktop ( id , position ) ;
} ) ;
connect ( m_virtualDesktopManagement , & KWayland : : Client : : PlasmaVirtualDesktopManagement : : desktopRemoved , this ,
[ this ] ( const QString & id ) {
m_desktops . removeAll ( id ) ;
if ( m_currentDesktop = = id ) {
setCurrentDesktop ( QString ( ) ) ;
2019-02-11 18:40:13 +02:00
}
2019-05-26 00:58:42 +03:00
} ) ;
}
void WaylandInterface : : addDesktop ( const QString & id , quint32 position )
{
if ( m_desktops . contains ( id ) ) {
return ;
}
2019-02-11 18:40:13 +02:00
2019-05-26 00:58:42 +03:00
m_desktops . append ( id ) ;
const KWayland : : Client : : PlasmaVirtualDesktop * desktop = m_virtualDesktopManagement - > getVirtualDesktop ( id ) ;
QObject : : connect ( desktop , & KWayland : : Client : : PlasmaVirtualDesktop : : activated , this ,
[ desktop , this ] ( ) {
setCurrentDesktop ( desktop - > id ( ) ) ;
}
) ;
if ( desktop - > isActive ( ) ) {
setCurrentDesktop ( id ) ;
}
2018-03-01 23:53:28 +02:00
}
2019-05-26 00:58:42 +03:00
void WaylandInterface : : setCurrentDesktop ( QString desktop )
{
if ( m_currentDesktop = = desktop ) {
return ;
}
m_currentDesktop = desktop ;
emit currentDesktopChanged ( ) ;
}
# endif
2018-12-06 14:35:34 +02:00
KWayland : : Client : : PlasmaShell * WaylandInterface : : waylandCoronaInterface ( ) const
2018-03-01 23:53:28 +02:00
{
2018-12-06 14:35:34 +02:00
return m_corona - > waylandCoronaInterface ( ) ;
2018-03-01 23:53:28 +02:00
}
2019-07-15 14:53:40 +03:00
//! Register Latte Ignored Windows in order to NOT be tracked
void WaylandInterface : : registerIgnoredWindow ( WindowId wid )
{
if ( ! wid . isNull ( ) & & ! m_ignoredWindows . contains ( wid ) ) {
m_ignoredWindows . append ( wid ) ;
KWayland : : Client : : PlasmaWindow * w = windowFor ( wid ) ;
if ( mapper & & w ) {
mapper - > removeMappings ( w ) ;
}
emit windowChanged ( wid ) ;
}
}
void WaylandInterface : : unregisterIgnoredWindow ( WindowId wid )
{
if ( m_ignoredWindows . contains ( wid ) ) {
m_ignoredWindows . removeAll ( wid ) ;
emit windowRemoved ( wid ) ;
}
}
2018-12-06 16:09:42 +02:00
void WaylandInterface : : setViewExtraFlags ( QWindow & view )
2017-04-25 17:48:36 +03:00
{
2017-06-15 16:56:55 -05:00
Q_UNUSED ( view )
2017-04-25 17:48:36 +03:00
}
2018-12-06 16:09:42 +02:00
void WaylandInterface : : setViewStruts ( QWindow & view , const QRect & rect , Plasma : : Types : : Location location )
2017-04-25 17:48:36 +03:00
{
2019-06-24 17:22:37 +03:00
if ( ! m_ghostWindows . contains ( view . winId ( ) ) ) {
2017-06-29 15:33:12 -05:00
m_ghostWindows [ view . winId ( ) ] = new Private : : GhostWindow ( this ) ;
2019-06-24 17:22:37 +03:00
}
2017-06-29 15:33:12 -05:00
auto w = m_ghostWindows [ view . winId ( ) ] ;
2017-12-24 20:54:45 +02:00
switch ( location ) {
2019-05-26 00:58:42 +03:00
case Plasma : : Types : : TopEdge :
case Plasma : : Types : : BottomEdge :
w - > setGeometry ( { rect . x ( ) + rect . width ( ) / 2 , rect . y ( ) , 1 , rect . height ( ) } ) ;
break ;
case Plasma : : Types : : LeftEdge :
case Plasma : : Types : : RightEdge :
w - > setGeometry ( { rect . x ( ) , rect . y ( ) + rect . height ( ) / 2 , rect . width ( ) , 1 } ) ;
break ;
default :
break ;
2017-06-29 15:33:12 -05:00
}
2017-04-25 17:48:36 +03:00
}
2019-06-10 17:30:25 +03:00
void WaylandInterface : : switchToNextVirtualDesktop ( ) const
{
# if KF5_VERSION_MINOR >= 52
if ( ! m_virtualDesktopManagement | | m_desktops . count ( ) < = 1 ) {
return ;
}
int curPos = m_desktops . indexOf ( m_currentDesktop ) ;
int nextPos = curPos + 1 ;
if ( curPos = = m_desktops . count ( ) - 1 ) {
nextPos = 0 ;
}
KWayland : : Client : : PlasmaVirtualDesktop * desktopObj = m_virtualDesktopManagement - > getVirtualDesktop ( m_desktops [ nextPos ] ) ;
if ( desktopObj ) {
desktopObj - > requestActivate ( ) ;
}
# endif
}
void WaylandInterface : : switchToPreviousVirtualDesktop ( ) const
{
# if KF5_VERSION_MINOR >= 52
if ( ! m_virtualDesktopManagement | | m_desktops . count ( ) < = 1 ) {
return ;
}
int curPos = m_desktops . indexOf ( m_currentDesktop ) ;
int nextPos = curPos - 1 ;
if ( curPos = = 0 ) {
nextPos = m_desktops . count ( ) - 1 ;
}
KWayland : : Client : : PlasmaVirtualDesktop * desktopObj = m_virtualDesktopManagement - > getVirtualDesktop ( m_desktops [ nextPos ] ) ;
if ( desktopObj ) {
desktopObj - > requestActivate ( ) ;
}
# endif
}
2018-01-21 11:53:15 +02:00
void WaylandInterface : : setWindowOnActivities ( QWindow & window , const QStringList & activities )
2018-01-13 12:55:13 +02:00
{
//! needs to updated to wayland case
// KWindowSystem::setOnActivities(view.winId(), activities);
}
2018-12-06 16:09:42 +02:00
void WaylandInterface : : removeViewStruts ( QWindow & view ) const
2017-04-25 17:48:36 +03:00
{
2017-06-29 15:33:12 -05:00
delete m_ghostWindows . take ( view . winId ( ) ) ;
2017-04-25 17:48:36 +03:00
}
2017-06-08 17:10:49 -05:00
WindowId WaylandInterface : : activeWindow ( ) const
2017-04-25 17:48:36 +03:00
{
2018-03-01 23:53:28 +02:00
if ( ! m_windowManagement ) {
return 0 ;
}
auto wid = m_windowManagement - > activeWindow ( ) ;
2017-06-10 16:33:46 -05:00
return wid ? wid - > internalId ( ) : 0 ;
2017-04-25 17:48:36 +03:00
}
2018-01-26 19:46:02 +02:00
void WaylandInterface : : setKeepAbove ( const QDialog & dialog , bool above ) const
{
if ( above ) {
KWindowSystem : : setState ( dialog . winId ( ) , NET : : KeepAbove ) ;
} else {
KWindowSystem : : clearState ( dialog . winId ( ) , NET : : KeepAbove ) ;
}
}
2017-04-25 17:48:36 +03:00
void WaylandInterface : : skipTaskBar ( const QDialog & dialog ) const
{
KWindowSystem : : setState ( dialog . winId ( ) , NET : : SkipTaskbar ) ;
}
2017-06-15 16:56:55 -05:00
void WaylandInterface : : slideWindow ( QWindow & view , AbstractWindowInterface : : Slide location ) const
2017-04-25 17:48:36 +03:00
{
auto slideLocation = KWindowEffects : : NoEdge ;
switch ( location ) {
2019-05-26 00:58:42 +03:00
case Slide : : Top :
slideLocation = KWindowEffects : : TopEdge ;
break ;
2017-04-25 17:48:36 +03:00
2019-05-26 00:58:42 +03:00
case Slide : : Bottom :
slideLocation = KWindowEffects : : BottomEdge ;
break ;
2017-04-25 17:48:36 +03:00
2019-05-26 00:58:42 +03:00
case Slide : : Left :
slideLocation = KWindowEffects : : LeftEdge ;
break ;
2017-04-25 17:48:36 +03:00
2019-05-26 00:58:42 +03:00
case Slide : : Right :
slideLocation = KWindowEffects : : RightEdge ;
break ;
2017-04-25 17:48:36 +03:00
2019-05-26 00:58:42 +03:00
default :
break ;
2017-04-25 17:48:36 +03:00
}
KWindowEffects : : slideWindow ( view . winId ( ) , slideLocation , - 1 ) ;
}
2017-06-15 16:56:55 -05:00
void WaylandInterface : : enableBlurBehind ( QWindow & view ) const
2017-04-25 17:48:36 +03:00
{
KWindowEffects : : enableBlurBehind ( view . winId ( ) ) ;
}
2018-03-28 20:39:52 +03:00
void WaylandInterface : : setEdgeStateFor ( QWindow * view , bool active ) const
{
2018-12-09 00:15:17 +02:00
ViewPart : : ScreenEdgeGhostWindow * window = qobject_cast < ViewPart : : ScreenEdgeGhostWindow * > ( view ) ;
2018-03-28 20:39:52 +03:00
if ( ! window ) {
return ;
}
2018-12-06 16:09:42 +02:00
if ( window - > parentView ( ) - > surface ( ) & & window - > parentView ( ) - > visibility ( )
2019-05-26 00:58:42 +03:00
& & ( window - > parentView ( ) - > visibility ( ) - > mode ( ) = = Types : : DodgeActive
| | window - > parentView ( ) - > visibility ( ) - > mode ( ) = = Types : : DodgeMaximized
| | window - > parentView ( ) - > visibility ( ) - > mode ( ) = = Types : : DodgeAllWindows
| | window - > parentView ( ) - > visibility ( ) - > mode ( ) = = Types : : AutoHide ) ) {
2018-03-28 20:39:52 +03:00
if ( active ) {
window - > showWithMask ( ) ;
window - > surface ( ) - > requestHideAutoHidingPanel ( ) ;
} else {
window - > hideWithMask ( ) ;
window - > surface ( ) - > requestShowAutoHidingPanel ( ) ;
}
}
}
2017-04-25 17:48:36 +03:00
WindowInfoWrap WaylandInterface : : requestInfoActive ( ) const
{
2018-03-01 23:53:28 +02:00
if ( ! m_windowManagement ) {
return { } ;
}
auto w = m_windowManagement - > activeWindow ( ) ;
2017-06-10 16:33:46 -05:00
if ( ! w ) return { } ;
2019-07-23 00:05:01 +03:00
return requestInfo ( w - > internalId ( ) ) ;
2017-04-25 17:48:36 +03:00
}
2017-06-08 17:10:49 -05:00
WindowInfoWrap WaylandInterface : : requestInfo ( WindowId wid ) const
2017-04-25 17:48:36 +03:00
{
2018-10-28 21:10:08 +02:00
WindowInfoWrap winfoWrap ;
2017-04-25 17:48:36 +03:00
2018-10-28 21:10:08 +02:00
auto w = windowFor ( wid ) ;
if ( w ) {
2019-02-11 19:40:24 +02:00
if ( isPlasmaDesktop ( w ) ) {
winfoWrap . setIsValid ( true ) ;
winfoWrap . setIsPlasmaDesktop ( true ) ;
winfoWrap . setWid ( wid ) ;
} else if ( isValidWindow ( w ) ) {
2018-10-28 21:10:08 +02:00
winfoWrap . setIsValid ( true ) ;
winfoWrap . setWid ( wid ) ;
2019-07-23 00:05:01 +03:00
winfoWrap . setParentId ( w - > parentWindow ( ) ? w - > parentWindow ( ) - > internalId ( ) : 0 ) ;
2018-10-28 21:10:08 +02:00
winfoWrap . setIsActive ( w - > isActive ( ) ) ;
winfoWrap . setIsMinimized ( w - > isMinimized ( ) ) ;
winfoWrap . setIsMaxVert ( w - > isMaximized ( ) ) ;
winfoWrap . setIsMaxHoriz ( w - > isMaximized ( ) ) ;
winfoWrap . setIsFullscreen ( w - > isFullscreen ( ) ) ;
winfoWrap . setIsShaded ( w - > isShaded ( ) ) ;
2019-05-31 17:44:04 +03:00
winfoWrap . setIsOnAllDesktops ( w - > isOnAllDesktops ( ) ) ;
2019-06-08 00:31:30 +03:00
winfoWrap . setIsOnAllActivities ( true ) ;
2018-10-28 21:10:08 +02:00
winfoWrap . setGeometry ( w - > geometry ( ) ) ;
winfoWrap . setHasSkipTaskbar ( w - > skipTaskbar ( ) ) ;
2019-05-31 17:44:04 +03:00
winfoWrap . setDisplay ( w - > title ( ) ) ;
2019-06-08 00:31:30 +03:00
# if KF5_VERSION_MINOR >= 52
winfoWrap . setDesktops ( w - > plasmaVirtualDesktops ( ) ) ;
# endif
winfoWrap . setActivities ( QStringList ( ) ) ;
2018-10-28 21:10:08 +02:00
}
} else {
2019-07-23 12:05:21 +03:00
winfoWrap . setIsValid ( false ) ;
2018-10-28 21:10:08 +02:00
}
2017-06-29 17:02:25 -05:00
2018-10-28 21:10:08 +02:00
return winfoWrap ;
}
2019-06-01 01:20:54 +03:00
AppData WaylandInterface : : appDataFor ( WindowId wid ) const
{
auto window = windowFor ( wid ) ;
const AppData & data = appDataFromUrl ( windowUrlFromMetadata ( window - > appId ( ) ,
2019-07-15 19:15:53 +03:00
window - > pid ( ) , rulesConfig ) ) ;
2019-06-01 02:43:30 +03:00
return data ;
2019-06-01 01:20:54 +03:00
}
2018-10-28 21:10:08 +02:00
KWayland : : Client : : PlasmaWindow * WaylandInterface : : windowFor ( WindowId wid ) const
{
auto it = std : : find_if ( m_windowManagement - > windows ( ) . constBegin ( ) , m_windowManagement - > windows ( ) . constEnd ( ) , [ & wid ] ( PlasmaWindow * w ) noexcept {
2019-05-26 00:58:42 +03:00
return w - > isValid ( ) & & w - > internalId ( ) = = wid ;
} ) ;
2017-12-24 20:54:45 +02:00
2018-10-28 21:10:08 +02:00
if ( it = = m_windowManagement - > windows ( ) . constEnd ( ) ) {
return nullptr ;
2017-06-10 16:33:46 -05:00
}
2017-04-25 17:48:36 +03:00
2018-10-28 21:10:08 +02:00
return * it ;
}
2019-05-27 18:56:24 +03:00
QIcon WaylandInterface : : iconFor ( WindowId wid ) const
{
auto window = windowFor ( wid ) ;
if ( window ) {
return window - > icon ( ) ;
}
return QIcon ( ) ;
}
2019-04-01 23:50:25 +03:00
WindowId WaylandInterface : : winIdFor ( QString appId , QRect geometry ) const
{
auto it = std : : find_if ( m_windowManagement - > windows ( ) . constBegin ( ) , m_windowManagement - > windows ( ) . constEnd ( ) , [ & appId , & geometry ] ( PlasmaWindow * w ) noexcept {
return w - > isValid ( ) & & w - > appId ( ) = = appId & & w - > geometry ( ) = = geometry ;
} ) ;
if ( it = = m_windowManagement - > windows ( ) . constEnd ( ) ) {
2019-07-15 14:53:40 +03:00
return QVariant ( ) ;
2019-04-01 23:50:25 +03:00
}
return ( * it ) - > internalId ( ) ;
}
2018-10-28 21:10:08 +02:00
bool WaylandInterface : : windowCanBeDragged ( WindowId wid ) const
{
2019-07-31 16:34:05 +03:00
auto w = windowFor ( wid ) ;
if ( w & & isValidWindow ( w ) ) {
WindowInfoWrap winfo = requestInfo ( wid ) ;
return ( winfo . isValid ( )
& & w - > isMovable ( )
& & ! winfo . isMinimized ( )
& & ! winfo . isPlasmaDesktop ( ) ) ;
}
return false ;
2017-04-25 17:48:36 +03:00
}
2019-07-31 16:44:43 +03:00
bool WaylandInterface : : windowCanBeMaximized ( WindowId wid ) const
{
auto w = windowFor ( wid ) ;
if ( w & & isValidWindow ( w ) ) {
WindowInfoWrap winfo = requestInfo ( wid ) ;
return ( winfo . isValid ( )
& & w - > isMaximizeable ( )
& & ! winfo . isMinimized ( )
& & ! winfo . isPlasmaDesktop ( ) ) ;
}
return false ;
}
2019-04-01 23:50:25 +03:00
void WaylandInterface : : requestActivate ( WindowId wid ) const
{
auto w = windowFor ( wid ) ;
if ( w ) {
w - > requestActivate ( ) ;
}
}
2019-06-02 01:07:47 +03:00
void WaylandInterface : : requestClose ( WindowId wid ) const
{
auto w = windowFor ( wid ) ;
if ( w ) {
w - > requestClose ( ) ;
}
}
2018-10-28 21:10:08 +02:00
void WaylandInterface : : requestMoveWindow ( WindowId wid , QPoint from ) const
2018-10-28 10:03:22 +02:00
{
2018-10-28 21:10:08 +02:00
if ( windowCanBeDragged ( wid ) ) {
auto w = windowFor ( wid ) ;
if ( w & & isValidWindow ( w ) ) {
w - > requestMove ( ) ;
}
}
2018-10-28 10:03:22 +02:00
}
2019-06-02 01:57:03 +03:00
void WaylandInterface : : requestToggleIsOnAllDesktops ( WindowId wid ) const
{
# if KF5_VERSION_MINOR >= 52
auto w = windowFor ( wid ) ;
if ( w & & isValidWindow ( w ) & & m_desktops . count ( ) > 1 ) {
if ( w - > isOnAllDesktops ( ) ) {
w - > requestEnterVirtualDesktop ( m_currentDesktop ) ;
} else {
const QStringList & now = w - > plasmaVirtualDesktops ( ) ;
foreach ( const QString & desktop , now ) {
w - > requestLeaveVirtualDesktop ( desktop ) ;
}
}
}
# endif
}
2019-06-02 01:07:47 +03:00
void WaylandInterface : : requestToggleKeepAbove ( WindowId wid ) const
{
auto w = windowFor ( wid ) ;
if ( w ) {
w - > requestToggleKeepAbove ( ) ;
}
}
void WaylandInterface : : requestToggleMinimized ( WindowId wid ) const
2018-10-28 10:03:22 +02:00
{
2018-10-28 21:10:08 +02:00
auto w = windowFor ( wid ) ;
if ( w & & isValidWindow ( w ) ) {
2019-06-02 01:07:47 +03:00
# if KF5_VERSION_MINOR >= 52
if ( ! m_currentDesktop . isEmpty ( ) ) {
w - > requestEnterVirtualDesktop ( m_currentDesktop ) ;
}
# endif
w - > requestToggleMinimized ( ) ;
2018-10-28 21:10:08 +02:00
}
2018-10-28 10:03:22 +02:00
}
2017-04-25 17:48:36 +03:00
2019-06-02 01:07:47 +03:00
void WaylandInterface : : requestToggleMaximized ( WindowId wid ) const
{
auto w = windowFor ( wid ) ;
2019-07-31 16:44:43 +03:00
if ( w & & isValidWindow ( w ) & & windowCanBeMaximized ( wid ) ) {
2019-06-02 01:07:47 +03:00
# if KF5_VERSION_MINOR >= 52
if ( ! m_currentDesktop . isEmpty ( ) ) {
w - > requestEnterVirtualDesktop ( m_currentDesktop ) ;
}
# endif
w - > requestToggleMaximized ( ) ;
2019-07-15 19:15:53 +03:00
}
2019-06-02 01:07:47 +03:00
}
2019-02-11 19:40:24 +02:00
bool WaylandInterface : : isPlasmaDesktop ( const KWayland : : Client : : PlasmaWindow * w ) const
{
if ( ! w | | ( w - > appId ( ) ! = QLatin1String ( " org.kde.plasmashell " ) ) ) {
return false ;
}
bool hasScreenGeometry { false } ;
2019-04-04 23:55:44 +03:00
for ( const auto scr : qGuiApp - > screens ( ) ) {
2019-02-11 19:40:24 +02:00
if ( ! w - > geometry ( ) . isEmpty ( ) & & w - > geometry ( ) = = scr - > geometry ( ) ) {
hasScreenGeometry = true ;
break ;
}
}
return hasScreenGeometry ;
}
bool WaylandInterface : : isValidWindow ( const KWayland : : Client : : PlasmaWindow * w ) const
2017-04-25 17:48:36 +03:00
{
2019-02-11 19:40:24 +02:00
//! DEPRECATED comment is case we must reenable this
2018-08-31 16:49:47 +03:00
//! because wayland does not have any way yet to identify the window type
//! a trick is to just consider windows as valid when they can be shown in the
//! taskbar. Of course that creates issues with plasma native dialogs
//! e.g. widgets explorer, Activities etc. that are not used to hide
2018-12-06 16:09:42 +02:00
//! the dodge views appropriately
2019-02-11 19:40:24 +02:00
2019-07-15 14:53:40 +03:00
return w - > isValid ( ) & & ! isPlasmaDesktop ( w ) & & ! m_ignoredWindows . contains ( w - > internalId ( ) ) ;
2017-04-25 17:48:36 +03:00
}
2017-06-10 16:33:46 -05:00
void WaylandInterface : : windowCreatedProxy ( KWayland : : Client : : PlasmaWindow * w )
2017-04-25 17:48:36 +03:00
{
2017-06-10 16:33:46 -05:00
if ( ! isValidWindow ( w ) ) return ;
2017-04-25 17:48:36 +03:00
2017-06-10 16:33:46 -05:00
if ( ! mapper ) mapper = new QSignalMapper ( this ) ;
2017-04-25 17:48:36 +03:00
2017-06-10 16:33:46 -05:00
mapper - > setMapping ( w , w ) ;
2017-04-25 17:48:36 +03:00
2017-12-24 20:54:45 +02:00
connect ( w , & PlasmaWindow : : unmapped , this , [ & , win = w ] ( ) noexcept {
2017-06-10 16:33:46 -05:00
mapper - > removeMappings ( win ) ;
emit windowRemoved ( win - > internalId ( ) ) ;
} ) ;
2019-05-26 00:58:42 +03:00
connect ( w , SIGNAL ( activeChanged ( ) ) , mapper , SLOT ( map ( ) ) ) ;
2019-05-27 18:56:24 +03:00
connect ( w , SIGNAL ( titleChanged ( ) ) , mapper , SLOT ( map ( ) ) ) ;
2019-05-26 00:58:42 +03:00
connect ( w , SIGNAL ( fullscreenChanged ( ) ) , mapper , SLOT ( map ( ) ) ) ;
connect ( w , SIGNAL ( geometryChanged ( ) ) , mapper , SLOT ( map ( ) ) ) ;
connect ( w , SIGNAL ( maximizedChanged ( ) ) , mapper , SLOT ( map ( ) ) ) ;
connect ( w , SIGNAL ( minimizedChanged ( ) ) , mapper , SLOT ( map ( ) ) ) ;
connect ( w , SIGNAL ( shadedChanged ( ) ) , mapper , SLOT ( map ( ) ) ) ;
connect ( w , SIGNAL ( skipTaskbarChanged ( ) ) , mapper , SLOT ( map ( ) ) ) ;
connect ( w , SIGNAL ( onAllDesktopsChanged ( ) ) , mapper , SLOT ( map ( ) ) ) ;
connect ( w , SIGNAL ( virtualDesktopChanged ( ) ) , mapper , SLOT ( map ( ) ) ) ;
2019-07-23 00:05:01 +03:00
connect ( w , SIGNAL ( parentWindowChanged ( ) ) , mapper , SLOT ( map ( ) ) ) ;
2019-05-26 00:58:42 +03:00
# if KF5_VERSION_MINOR >= 52
connect ( w , & KWayland : : Client : : PlasmaWindow : : plasmaVirtualDesktopEntered , this ,
[ w , this ] {
mapper - > map ( w ) ;
} ) ;
connect ( w , & KWayland : : Client : : PlasmaWindow : : plasmaVirtualDesktopLeft , this ,
[ w , this ] {
mapper - > map ( w ) ;
} ) ;
# endif
2017-06-10 16:33:46 -05:00
connect ( mapper , static_cast < void ( QSignalMapper : : * ) ( QObject * ) > ( & QSignalMapper : : mapped )
2019-05-26 00:58:42 +03:00
, this , [ & ] ( QObject * w ) noexcept {
2018-03-02 20:28:22 +02:00
//qDebug() << "window changed:" << qobject_cast<PlasmaWindow *>(w)->appId();
2019-02-11 18:40:13 +02:00
PlasmaWindow * pW = qobject_cast < PlasmaWindow * > ( w ) ;
2019-07-15 14:53:40 +03:00
if ( pW & & ! m_ignoredWindows . contains ( pW - > internalId ( ) & & ! isPlasmaDesktop ( pW ) ) ) {
2019-05-27 20:09:48 +03:00
considerWindowChanged ( pW - > internalId ( ) ) ;
2019-02-11 18:40:13 +02:00
}
2017-06-10 16:33:46 -05:00
} ) ;
2017-04-25 17:48:36 +03:00
2017-06-10 16:33:46 -05:00
emit windowAdded ( w - > internalId ( ) ) ;
2019-07-15 19:15:53 +03:00
if ( w - > appId ( ) = = " latte-dock " ) {
emit latteWindowAdded ( ) ;
}
2017-04-25 17:48:36 +03:00
}
2019-05-11 15:43:10 +03:00
}
2017-04-25 17:48:36 +03:00
}
2017-06-29 15:34:36 -05:00
# include "waylandinterface.moc"