2016-12-25 09:25:27 +02:00
/*
* Copyright 2016 Smith AR < audoban @ openmailbox . org >
2017-01-02 17:05:30 -05:00
* Michail Vourlakos < mvourlakos @ gmail . com >
2016-12-25 09:25:27 +02:00
*
2017-01-02 17:05:30 -05:00
* This file is part of Latte - Dock
2016-12-25 09:25:27 +02:00
*
2017-01-02 17:05:30 -05:00
* Latte - Dock is free software ; you can redistribute it and / or
2016-12-25 09:25:27 +02:00
* modify it under the terms of the GNU General Public License as
2017-01-02 17:05:30 -05:00
* published by the Free Software Foundation ; either version 2 of
2016-12-25 09:25:27 +02:00
* the License , or ( at your option ) any later version .
*
2017-01-02 17:05:30 -05:00
* Latte - Dock is distributed in the hope that it will be useful ,
2016-12-25 09:25:27 +02:00
* 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/>.
*/
2016-12-30 16:25:27 -05:00
# include "dockconfigview.h"
# include "dockview.h"
# include "dockcorona.h"
2017-02-02 20:21:58 -05:00
# include "panelshadows_p.h"
2017-02-24 21:40:47 -05:00
# include "abstractwindowinterface.h"
2017-03-10 22:41:13 +02:00
# include "../liblattedock/dock.h"
2016-12-25 09:25:27 +02:00
# include <QQuickItem>
# include <QQmlContext>
2016-12-28 18:01:25 +02:00
# include <QQmlEngine>
2016-12-25 09:25:27 +02:00
# include <QScreen>
2016-12-28 18:01:25 +02:00
# include <KLocalizedContext>
2017-01-21 18:27:51 -05:00
# include <KDeclarative/KDeclarative>
2016-12-25 09:25:27 +02:00
2016-12-30 16:25:27 -05:00
# include <Plasma/Package>
2016-12-25 09:25:27 +02:00
2017-04-25 19:18:49 +03:00
# include <KWayland/Client/plasmashell.h>
# include <KWayland/Client/surface.h>
2016-12-30 02:20:06 -05:00
namespace Latte {
2016-12-30 16:25:27 -05:00
DockConfigView : : DockConfigView ( Plasma : : Containment * containment , DockView * dockView , QWindow * parent )
2017-01-04 01:35:22 +02:00
: PlasmaQuick : : ConfigView ( containment , parent ) ,
2017-01-12 18:55:43 -05:00
m_blockFocusLost ( false ) ,
m_dockView ( dockView )
2016-12-25 09:25:27 +02:00
{
2017-06-29 17:03:44 -05:00
setupWaylandIntegration ( ) ;
2017-04-26 16:50:49 +03:00
2017-02-26 16:59:59 +02:00
setScreen ( m_dockView - > screen ( ) ) ;
2017-02-27 11:25:51 +02:00
2017-02-09 17:54:28 +02:00
if ( containment ) {
2017-03-11 20:36:43 +02:00
setIcon ( qGuiApp - > windowIcon ( ) ) ;
2017-02-09 17:54:28 +02:00
}
2016-12-25 09:25:27 +02:00
m_screenSyncTimer . setSingleShot ( true ) ;
m_screenSyncTimer . setInterval ( 100 ) ;
2017-01-11 02:30:35 +02:00
connections < < connect ( dockView , SIGNAL ( screenChanged ( QScreen * ) ) , & m_screenSyncTimer , SLOT ( start ( ) ) ) ;
connections < < connect ( & m_screenSyncTimer , & QTimer : : timeout , this , [ this ] ( ) {
2016-12-25 09:25:27 +02:00
setScreen ( m_dockView - > screen ( ) ) ;
setFlags ( wFlags ( ) ) ;
syncGeometry ( ) ;
syncSlideEffect ( ) ;
} ) ;
2017-01-11 02:30:35 +02:00
connections < < connect ( dockView - > visibility ( ) , & VisibilityManager : : modeChanged , this , & DockConfigView : : syncGeometry ) ;
connections < < connect ( containment , & Plasma : : Containment : : immutabilityChanged , this , & DockConfigView : : immutabilityChanged ) ;
2017-01-13 01:16:05 -05:00
connections < < connect ( containment , & Plasma : : Containment : : locationChanged , [ & ] ( ) {
syncSlideEffect ( ) ;
QTimer : : singleShot ( 200 , this , & DockConfigView : : syncGeometry ) ;
} ) ;
2017-01-29 00:16:28 -05:00
auto * dockCorona = qobject_cast < DockCorona * > ( m_dockView - > corona ( ) ) ;
2017-03-07 19:22:15 +02:00
if ( dockCorona ) {
connections < < connect ( this , & DockConfigView : : aboutApplication , dockCorona , & DockCorona : : aboutApplication ) ;
2017-03-07 23:26:09 +02:00
connections < < connect ( dockCorona , SIGNAL ( raiseDocksTemporaryChanged ( ) ) , this , SIGNAL ( raiseDocksTemporaryChanged ( ) ) ) ;
2017-03-07 19:22:15 +02:00
}
2016-12-25 09:25:27 +02:00
}
2017-01-11 02:30:35 +02:00
DockConfigView : : ~ DockConfigView ( )
{
2017-04-09 13:58:59 -05:00
qDebug ( ) < < " DockConfigView deleting ... " ;
2017-04-27 17:51:23 +03:00
2017-01-11 02:30:35 +02:00
foreach ( auto var , connections ) {
QObject : : disconnect ( var ) ;
}
2017-04-26 16:50:49 +03:00
if ( m_shellSurface ) {
delete m_shellSurface ;
m_shellSurface = nullptr ;
}
2017-01-11 02:30:35 +02:00
}
void DockConfigView : : init ( )
{
2017-01-11 15:18:39 +02:00
setDefaultAlphaBuffer ( true ) ;
setColor ( Qt : : transparent ) ;
2017-02-02 20:21:58 -05:00
PanelShadows : : self ( ) - > addWindow ( this ) ;
2017-01-11 15:18:39 +02:00
rootContext ( ) - > setContextProperty ( QStringLiteral ( " dock " ) , m_dockView ) ;
rootContext ( ) - > setContextProperty ( QStringLiteral ( " dockConfig " ) , this ) ;
2017-03-18 13:21:17 +02:00
auto * dockCorona = qobject_cast < DockCorona * > ( m_dockView - > corona ( ) ) ;
if ( dockCorona ) {
rootContext ( ) - > setContextProperty ( QStringLiteral ( " globalSettings " ) , dockCorona - > globalSettings ( ) ) ;
}
2017-01-21 18:27:51 -05:00
KDeclarative : : KDeclarative kdeclarative ;
kdeclarative . setDeclarativeEngine ( engine ( ) ) ;
kdeclarative . setTranslationDomain ( QStringLiteral ( " latte-dock " ) ) ;
kdeclarative . setupBindings ( ) ;
2017-01-17 20:09:43 +02:00
auto source = QUrl : : fromLocalFile ( m_dockView - > containment ( ) - > corona ( ) - > kPackage ( ) . filePath ( " lattedockconfigurationui " ) ) ;
2017-01-11 15:18:39 +02:00
setSource ( source ) ;
2017-06-29 17:03:44 -05:00
syncGeometry ( ) ;
syncSlideEffect ( ) ;
2017-01-11 02:30:35 +02:00
}
2016-12-30 16:25:27 -05:00
inline Qt : : WindowFlags DockConfigView : : wFlags ( ) const
2016-12-25 09:25:27 +02:00
{
return ( flags ( ) | Qt : : FramelessWindowHint | Qt : : WindowStaysOnTopHint ) & ~ Qt : : WindowDoesNotAcceptFocus ;
}
2016-12-30 16:25:27 -05:00
void DockConfigView : : syncGeometry ( )
2016-12-25 09:25:27 +02:00
{
2017-01-17 20:09:43 +02:00
if ( ! m_dockView - > containment ( ) | | ! rootObject ( ) )
2016-12-25 09:25:27 +02:00
return ;
2017-01-16 14:07:49 -05:00
2017-01-17 20:09:43 +02:00
const auto location = m_dockView - > containment ( ) - > location ( ) ;
2016-12-25 09:25:27 +02:00
const auto sGeometry = screen ( ) - > geometry ( ) ;
2017-01-16 14:07:49 -05:00
2017-01-29 20:15:18 +02:00
int clearThickness = m_dockView - > normalThickness ( ) ;
2017-04-25 19:18:49 +03:00
QPoint position { 0 , 0 } ;
2017-01-17 20:09:43 +02:00
switch ( m_dockView - > containment ( ) - > formFactor ( ) ) {
2016-12-25 09:25:27 +02:00
case Plasma : : Types : : Horizontal : {
const QSize size ( rootObject ( ) - > width ( ) , rootObject ( ) - > height ( ) ) ;
setMaximumSize ( size ) ;
setMinimumSize ( size ) ;
resize ( size ) ;
2017-01-16 14:07:49 -05:00
2016-12-25 09:25:27 +02:00
if ( location = = Plasma : : Types : : TopEdge ) {
2017-04-25 19:18:49 +03:00
position = { sGeometry . center ( ) . x ( ) - size . width ( ) / 2
, sGeometry . y ( ) + clearThickness
} ;
2016-12-25 09:25:27 +02:00
} else if ( location = = Plasma : : Types : : BottomEdge ) {
2017-04-25 19:18:49 +03:00
position = { sGeometry . center ( ) . x ( ) - size . width ( ) / 2
, sGeometry . y ( ) + sGeometry . height ( ) - clearThickness - size . height ( )
} ;
2016-12-25 09:25:27 +02:00
}
}
break ;
2017-01-16 14:07:49 -05:00
2016-12-25 09:25:27 +02:00
case Plasma : : Types : : Vertical : {
const QSize size ( rootObject ( ) - > width ( ) , rootObject ( ) - > height ( ) ) ;
setMaximumSize ( size ) ;
setMinimumSize ( size ) ;
resize ( size ) ;
2017-01-16 14:07:49 -05:00
2016-12-25 09:25:27 +02:00
if ( location = = Plasma : : Types : : LeftEdge ) {
2017-04-25 19:18:49 +03:00
position = { sGeometry . x ( ) + clearThickness
, sGeometry . center ( ) . y ( ) - size . height ( ) / 2
} ;
2016-12-25 09:25:27 +02:00
} else if ( location = = Plasma : : Types : : RightEdge ) {
2017-04-25 19:18:49 +03:00
position = { sGeometry . x ( ) + sGeometry . width ( ) - clearThickness - size . width ( )
, sGeometry . center ( ) . y ( ) - size . height ( ) / 2
} ;
2016-12-25 09:25:27 +02:00
}
}
break ;
2017-01-16 14:07:49 -05:00
2016-12-25 09:25:27 +02:00
default :
qWarning ( ) < < " no sync geometry, wrong formFactor " ;
break ;
}
2017-04-25 19:18:49 +03:00
setPosition ( position ) ;
if ( m_shellSurface ) {
m_shellSurface - > setPosition ( position ) ;
}
2016-12-25 09:25:27 +02:00
}
2016-12-30 16:25:27 -05:00
void DockConfigView : : syncSlideEffect ( )
2016-12-25 09:25:27 +02:00
{
2017-01-17 20:09:43 +02:00
if ( ! m_dockView - > containment ( ) )
2016-12-25 09:25:27 +02:00
return ;
2017-01-16 14:07:49 -05:00
2017-02-24 21:40:47 -05:00
auto slideLocation = WindowSystem : : Slide : : None ;
2017-01-16 14:07:49 -05:00
2017-01-17 20:09:43 +02:00
switch ( m_dockView - > containment ( ) - > location ( ) ) {
2016-12-25 09:25:27 +02:00
case Plasma : : Types : : TopEdge :
2017-02-24 21:40:47 -05:00
slideLocation = WindowSystem : : Slide : : Top ;
2016-12-25 09:25:27 +02:00
break ;
2017-01-16 14:07:49 -05:00
2016-12-25 09:25:27 +02:00
case Plasma : : Types : : RightEdge :
2017-02-24 21:40:47 -05:00
slideLocation = WindowSystem : : Slide : : Right ;
2016-12-25 09:25:27 +02:00
break ;
2017-01-16 14:07:49 -05:00
2016-12-25 09:25:27 +02:00
case Plasma : : Types : : BottomEdge :
2017-02-24 21:40:47 -05:00
slideLocation = WindowSystem : : Slide : : Bottom ;
2016-12-25 09:25:27 +02:00
break ;
2017-01-16 14:07:49 -05:00
2016-12-25 09:25:27 +02:00
case Plasma : : Types : : LeftEdge :
2017-02-24 21:40:47 -05:00
slideLocation = WindowSystem : : Slide : : Left ;
2016-12-25 09:25:27 +02:00
break ;
2017-01-16 14:07:49 -05:00
2016-12-25 09:25:27 +02:00
default :
2017-06-29 17:03:44 -05:00
qDebug ( ) < < staticMetaObject . className ( ) < < " wrong location " ;
2016-12-25 09:25:27 +02:00
break ;
}
2017-01-16 14:07:49 -05:00
2017-02-24 21:40:47 -05:00
WindowSystem : : self ( ) . slideWindow ( * this , slideLocation ) ;
2016-12-25 09:25:27 +02:00
}
2016-12-30 16:25:27 -05:00
void DockConfigView : : showEvent ( QShowEvent * ev )
2016-12-25 09:25:27 +02:00
{
2017-01-11 01:04:41 +02:00
QQuickWindow : : showEvent ( ev ) ;
2017-02-24 21:40:47 -05:00
WindowSystem : : self ( ) . setDockExtraFlags ( * this ) ;
2016-12-25 09:25:27 +02:00
setFlags ( wFlags ( ) ) ;
2017-02-24 21:40:47 -05:00
WindowSystem : : self ( ) . enableBlurBehind ( * this ) ;
2016-12-25 09:25:27 +02:00
syncGeometry ( ) ;
syncSlideEffect ( ) ;
2017-01-16 14:07:49 -05:00
2017-01-17 20:09:43 +02:00
if ( m_dockView & & m_dockView - > containment ( ) )
m_dockView - > containment ( ) - > setUserConfiguring ( true ) ;
2017-01-16 14:07:49 -05:00
2016-12-25 09:25:27 +02:00
m_screenSyncTimer . start ( ) ;
2017-01-09 00:10:59 -05:00
QTimer : : singleShot ( 400 , this , & DockConfigView : : syncGeometry ) ;
2017-02-26 17:25:53 +02:00
emit showSignal ( ) ;
2016-12-25 09:25:27 +02:00
}
2016-12-30 16:25:27 -05:00
void DockConfigView : : hideEvent ( QHideEvent * ev )
2016-12-25 09:25:27 +02:00
{
2017-04-09 13:42:39 -05:00
if ( ! m_dockView ) {
QQuickWindow : : hideEvent ( ev ) ;
return ;
}
if ( m_dockView - > containment ( ) )
2017-01-17 20:09:43 +02:00
m_dockView - > containment ( ) - > setUserConfiguring ( false ) ;
2017-01-16 14:07:49 -05:00
2017-01-11 02:30:35 +02:00
QQuickWindow : : hideEvent ( ev ) ;
2017-02-27 11:25:51 +02:00
2017-04-09 13:42:39 -05:00
auto recreateDock = [ & ] ( ) noexcept {
2017-03-08 21:00:09 +02:00
auto * dockCorona = qobject_cast < DockCorona * > ( m_dockView - > corona ( ) ) ;
if ( dockCorona ) {
dockCorona - > recreateDock ( m_dockView - > containment ( ) ) ;
}
2017-04-09 13:42:39 -05:00
} ;
const auto mode = m_dockView - > visibility ( ) - > mode ( ) ;
const auto previousDockWinBehavior = ( m_dockView - > flags ( ) & Qt : : BypassWindowManagerHint ) ? false : true ;
if ( mode = = Dock : : AlwaysVisible | | mode = = Dock : : WindowsGoBelow ) {
if ( ! previousDockWinBehavior ) {
recreateDock ( ) ;
}
} else if ( m_dockView - > dockWinBehavior ( ) ! = previousDockWinBehavior ) {
recreateDock ( ) ;
2017-03-08 21:00:09 +02:00
}
2017-02-27 11:25:51 +02:00
deleteLater ( ) ;
2016-12-25 09:25:27 +02:00
}
2016-12-30 16:25:27 -05:00
void DockConfigView : : focusOutEvent ( QFocusEvent * ev )
2016-12-25 09:25:27 +02:00
{
Q_UNUSED ( ev ) ;
const auto * focusWindow = qGuiApp - > focusWindow ( ) ;
2017-01-16 14:07:49 -05:00
2016-12-25 09:25:27 +02:00
if ( focusWindow & & focusWindow - > flags ( ) . testFlag ( Qt : : Popup ) )
return ;
2017-01-16 14:07:49 -05:00
2017-06-29 17:03:44 -05:00
if ( ! m_blockFocusLost )
hideConfigWindow ( ) ;
2016-12-25 09:25:27 +02:00
}
2016-12-29 00:25:42 +02:00
2017-04-26 16:50:49 +03:00
void DockConfigView : : setupWaylandIntegration ( )
{
if ( m_shellSurface ) {
// already setup
return ;
}
if ( DockCorona * c = qobject_cast < DockCorona * > ( m_dockView - > containment ( ) - > corona ( ) ) ) {
using namespace KWayland : : Client ;
PlasmaShell * interface = c - > waylandDockCoronaInterface ( ) ;
if ( ! interface ) {
return ;
}
Surface * s = Surface : : fromWindow ( this ) ;
if ( ! s ) {
return ;
}
qDebug ( ) < < " wayland dock window surface was created... " ;
m_shellSurface = interface - > createSurface ( s , this ) ;
2017-06-21 17:14:13 +03:00
syncGeometry ( ) ;
2017-04-26 16:50:49 +03:00
}
}
2017-04-25 19:18:49 +03:00
bool DockConfigView : : event ( QEvent * e )
{
if ( e - > type ( ) = = QEvent : : PlatformSurface ) {
if ( auto pe = dynamic_cast < QPlatformSurfaceEvent * > ( e ) ) {
switch ( pe - > surfaceEventType ( ) ) {
case QPlatformSurfaceEvent : : SurfaceCreated :
2017-04-26 16:50:49 +03:00
2017-04-25 19:18:49 +03:00
if ( m_shellSurface ) {
break ;
}
2017-04-26 16:50:49 +03:00
setupWaylandIntegration ( ) ;
2017-04-25 19:18:49 +03:00
break ;
case QPlatformSurfaceEvent : : SurfaceAboutToBeDestroyed :
2017-04-26 16:50:49 +03:00
if ( m_shellSurface ) {
delete m_shellSurface ;
m_shellSurface = nullptr ;
}
2017-04-25 19:18:49 +03:00
PanelShadows : : self ( ) - > removeWindow ( this ) ;
break ;
}
}
}
return PlasmaQuick : : ConfigView : : event ( e ) ;
}
2016-12-30 16:25:27 -05:00
void DockConfigView : : immutabilityChanged ( Plasma : : Types : : ImmutabilityType type )
2016-12-29 00:25:42 +02:00
{
2017-06-29 17:03:44 -05:00
if ( type ! = Plasma : : Types : : Mutable & & isVisible ( ) )
hideConfigWindow ( ) ;
2016-12-29 00:25:42 +02:00
}
2017-01-04 01:35:22 +02:00
void DockConfigView : : setSticker ( bool blockFocusLost )
{
2017-06-29 17:03:44 -05:00
if ( m_blockFocusLost = = blockFocusLost )
2017-01-04 01:35:22 +02:00
return ;
2017-01-16 14:07:49 -05:00
2017-01-04 01:35:22 +02:00
m_blockFocusLost = blockFocusLost ;
}
2017-03-11 01:26:24 +02:00
void DockConfigView : : addPanelSpacer ( )
{
if ( m_dockView & & m_dockView - > containment ( ) ) {
m_dockView - > containment ( ) - > createApplet ( QStringLiteral ( " org.kde.plasma.panelspacer " ) ) ;
}
}
2017-03-18 01:53:44 +02:00
void DockConfigView : : hideConfigWindow ( )
2017-03-10 22:41:13 +02:00
{
2017-06-29 17:03:44 -05:00
if ( m_shellSurface ) {
//!NOTE: Avoid crash in wayland enviroment with qt5.9
close ( ) ;
} else {
2017-06-29 17:07:30 -05:00
hide ( ) ;
2017-06-29 17:03:44 -05:00
}
2017-03-10 22:41:13 +02:00
}
2017-06-05 22:20:22 +03:00
void DockConfigView : : setSyncLaunchers ( bool sync )
{
auto * dockCorona = qobject_cast < DockCorona * > ( m_dockView - > corona ( ) ) ;
//when the global launchers list is empty then the current dock launchers are used
2017-06-06 00:51:36 +03:00
if ( sync & & dockCorona & & dockCorona - > globalSettings ( ) ) {
2017-06-05 22:20:22 +03:00
//update the global launchers
Plasma : : Containment * c = m_dockView - > containment ( ) ;
const auto & applets = c - > applets ( ) ;
for ( auto * applet : applets ) {
KPluginMetaData meta = applet - > kPackage ( ) . metadata ( ) ;
if ( meta . pluginId ( ) = = " org.kde.latte.plasmoid " ) {
if ( QQuickItem * appletInterface = applet - > property ( " _plasma_graphicObject " ) . value < QQuickItem * > ( ) ) {
const auto & childItems = appletInterface - > childItems ( ) ;
if ( childItems . isEmpty ( ) ) {
continue ;
}
for ( QQuickItem * item : childItems ) {
if ( auto * metaObject = item - > metaObject ( ) ) {
// not using QMetaObject::invokeMethod to avoid warnings when calling
// this on applets that don't have it or other child items since this
// is pretty much trial and error.
// Also, "var" arguments are treated as QVariant in QMetaObject
int methodIndex = metaObject - > indexOfMethod ( " getLauncherList() " ) ;
if ( methodIndex = = - 1 ) {
continue ;
}
QMetaMethod method = metaObject - > method ( methodIndex ) ;
QVariant launchers ;
if ( method . invoke ( item , Q_RETURN_ARG ( QVariant , launchers ) ) ) {
dockCorona - > globalSettings ( ) - > setGlobalLaunchers ( launchers . toStringList ( ) ) ;
}
}
}
}
}
}
}
dockCorona - > globalSettings ( ) - > setSyncLaunchers ( sync ) ;
}
2016-12-30 02:20:06 -05:00
}
2016-12-25 09:25:27 +02:00
// kate: indent-mode cstyle; indent-width 4; replace-tabs on;