2018-11-29 22:30:00 +03:00
/*
* Copyright 2018 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 "positioner.h"
2018-12-02 03:05:52 +03:00
// local
2018-11-30 22:33:46 +03:00
# include "effects.h"
2018-12-06 13:15:58 +03:00
# include "view.h"
2018-12-06 15:35:34 +03:00
# include "../lattecorona.h"
2018-11-29 22:30:00 +03:00
# include "../screenpool.h"
2018-12-02 02:21:34 +03:00
# include "../settings/universalsettings.h"
2018-12-07 19:55:35 +03:00
# include "../../liblatte2/types.h"
2018-11-29 22:30:00 +03:00
2018-12-02 03:05:52 +03:00
// Qt
2018-11-29 22:30:00 +03:00
# include <QDebug>
2018-12-02 03:05:52 +03:00
// KDE
2018-11-29 22:30:00 +03:00
# include <KWayland/Client/plasmashell.h>
# include <KWayland/Client/surface.h>
2018-12-02 03:05:52 +03:00
# include <KWindowSystem>
2018-11-29 22:30:00 +03:00
namespace Latte {
2018-12-06 12:37:14 +03:00
namespace ViewPart {
2018-11-29 22:30:00 +03:00
2018-12-06 13:15:58 +03:00
Positioner : : Positioner ( Latte : : View * parent )
2018-11-29 22:30:00 +03:00
: QObject ( parent ) ,
m_view ( parent )
{
m_screenSyncTimer . setSingleShot ( true ) ;
m_screenSyncTimer . setInterval ( 2000 ) ;
connect ( & m_screenSyncTimer , & QTimer : : timeout , this , & Positioner : : reconsiderScreen ) ;
//! under X11 it was identified that windows many times especially under screen changes
//! don't end up at the correct position and size. This timer will enforce repositionings
//! and resizes every 500ms if the window hasn't end up to correct values and until this
//! is achieved
m_validateGeometryTimer . setSingleShot ( true ) ;
m_validateGeometryTimer . setInterval ( 500 ) ;
connect ( & m_validateGeometryTimer , & QTimer : : timeout , this , & Positioner : : syncGeometry ) ;
2018-12-06 15:35:34 +03:00
auto * latteCorona = qobject_cast < Latte : : Corona * > ( m_view - > corona ( ) ) ;
2018-11-29 22:30:00 +03:00
2018-12-06 15:35:34 +03:00
if ( latteCorona ) {
m_screenSyncTimer . setInterval ( qMax ( latteCorona - > universalSettings ( ) - > screenTrackerInterval ( ) - 500 , 1000 ) ) ;
connect ( latteCorona - > universalSettings ( ) , & UniversalSettings : : screenTrackerIntervalChanged , this , [ this , latteCorona ] ( ) {
m_screenSyncTimer . setInterval ( qMax ( latteCorona - > universalSettings ( ) - > screenTrackerInterval ( ) - 500 , 1000 ) ) ;
2018-11-29 22:30:00 +03:00
} ) ;
2018-12-06 16:57:20 +03:00
connect ( latteCorona , & Latte : : Corona : : viewLocationChanged , this , [ & ] ( ) {
2018-11-29 22:30:00 +03:00
//! check if an edge has been freed for a primary dock
//! from another screen
if ( m_view - > onPrimary ( ) ) {
m_screenSyncTimer . start ( ) ;
}
} ) ;
}
init ( ) ;
}
Positioner : : ~ Positioner ( )
{
m_inDelete = true ;
m_screenSyncTimer . stop ( ) ;
m_validateGeometryTimer . stop ( ) ;
}
void Positioner : : init ( )
{
//! connections
connect ( this , & Positioner : : screenGeometryChanged , this , & Positioner : : syncGeometry ) ;
connect ( m_view , & QQuickWindow : : xChanged , this , & Positioner : : validateDockGeometry ) ;
connect ( m_view , & QQuickWindow : : yChanged , this , & Positioner : : validateDockGeometry ) ;
connect ( m_view , & QQuickWindow : : widthChanged , this , & Positioner : : validateDockGeometry ) ;
connect ( m_view , & QQuickWindow : : heightChanged , this , & Positioner : : validateDockGeometry ) ;
2018-12-01 17:13:35 +03:00
connect ( m_view , & QQuickWindow : : screenChanged , this , & Positioner : : currentScreenChanged ) ;
2018-11-29 22:30:00 +03:00
connect ( m_view , & QQuickWindow : : screenChanged , this , & Positioner : : screenChanged ) ;
2018-12-06 13:15:58 +03:00
connect ( m_view , & Latte : : View : : behaveAsPlasmaPanelChanged , this , & Positioner : : syncGeometry ) ;
connect ( m_view , & Latte : : View : : maxThicknessChanged , this , & Positioner : : syncGeometry ) ;
connect ( m_view , & Latte : : View : : maxLengthChanged , this , & Positioner : : syncGeometry ) ;
connect ( m_view , & Latte : : View : : offsetChanged , this , & Positioner : : syncGeometry ) ;
2018-11-29 22:30:00 +03:00
2018-12-09 03:24:57 +03:00
connect ( m_view , & Latte : : View : : absGeometryChanged , this , [ & ] ( ) {
if ( m_view - > behaveAsPlasmaPanel ( ) ) {
syncGeometry ( ) ;
}
} ) ;
2018-12-06 13:15:58 +03:00
connect ( m_view , & Latte : : View : : locationChanged , this , [ & ] ( ) {
2018-12-01 01:13:11 +03:00
updateFormFactor ( ) ;
2018-11-29 22:30:00 +03:00
syncGeometry ( ) ;
} ) ;
2018-12-06 13:15:58 +03:00
connect ( m_view , & Latte : : View : : normalThicknessChanged , this , [ & ] ( ) {
2018-11-29 22:30:00 +03:00
if ( m_view - > behaveAsPlasmaPanel ( ) ) {
syncGeometry ( ) ;
}
} ) ;
2018-12-06 12:37:14 +03:00
connect ( m_view - > effects ( ) , & Latte : : ViewPart : : Effects : : drawShadowsChanged , this , [ & ] ( ) {
2018-12-01 01:52:05 +03:00
if ( ! m_view - > behaveAsPlasmaPanel ( ) ) {
2018-11-29 22:30:00 +03:00
syncGeometry ( ) ;
}
} ) ;
2018-12-06 12:37:14 +03:00
connect ( m_view - > effects ( ) , & Latte : : ViewPart : : Effects : : innerShadowChanged , this , [ & ] ( ) {
2018-12-01 01:52:05 +03:00
if ( m_view - > behaveAsPlasmaPanel ( ) ) {
2018-12-01 01:13:11 +03:00
syncGeometry ( ) ;
}
} ) ;
2018-11-29 22:30:00 +03:00
connect ( qGuiApp , & QGuiApplication : : screenAdded , this , & Positioner : : screenChanged ) ;
connect ( qGuiApp , & QGuiApplication : : primaryScreenChanged , this , & Positioner : : screenChanged ) ;
initSignalingForLocationChangeSliding ( ) ;
}
2018-12-01 17:13:35 +03:00
int Positioner : : currentScreenId ( ) const
{
2018-12-06 15:35:34 +03:00
auto * latteCorona = qobject_cast < Latte : : Corona * > ( m_view - > corona ( ) ) ;
2018-12-01 17:13:35 +03:00
2018-12-06 15:35:34 +03:00
if ( latteCorona ) {
return latteCorona - > screenPool ( ) - > id ( m_screenToFollowId ) ;
2018-12-01 17:13:35 +03:00
}
return - 1 ;
}
2018-11-29 22:30:00 +03:00
QString Positioner : : currentScreenName ( ) const
{
return m_screenToFollowId ;
}
bool Positioner : : setCurrentScreen ( const QString id )
{
QScreen * nextScreen { qGuiApp - > primaryScreen ( ) } ;
if ( id ! = " primary " ) {
foreach ( auto scr , qGuiApp - > screens ( ) ) {
if ( scr & & scr - > name ( ) = = id ) {
nextScreen = scr ;
break ;
}
}
}
if ( m_screenToFollow = = nextScreen ) {
return true ;
}
if ( nextScreen ) {
if ( m_view - > managedLayout ( ) ) {
auto freeEdges = m_view - > managedLayout ( ) - > freeEdges ( nextScreen ) ;
if ( ! freeEdges . contains ( m_view - > location ( ) ) ) {
return false ;
} else {
m_goToScreen = nextScreen ;
//! asynchronous call in order to not crash from configwindow
//! deletion from sliding out animation
QTimer : : singleShot ( 100 , [ this ] ( ) {
emit hideDockDuringScreenChangeStarted ( ) ;
} ) ;
}
}
}
return true ;
}
//! this function updates the dock's associated screen.
//! updateScreenId = true, update also the m_screenToFollowId
//! updateScreenId = false, do not update the m_screenToFollowId
//! that way an explicit dock can be shown in another screen when
//! there isnt a tasks dock running in the system and for that
//! dock its first origin screen is stored and that way when
//! that screen is reconnected the dock will return to its original
//! place
void Positioner : : setScreenToFollow ( QScreen * scr , bool updateScreenId )
{
if ( ! scr | | ( scr & & ( m_screenToFollow = = scr ) & & ( m_view - > screen ( ) = = scr ) ) ) {
return ;
}
qDebug ( ) < < " setScreenToFollow() called for screen: " < < scr - > name ( ) < < " update: " < < updateScreenId ;
m_screenToFollow = scr ;
if ( updateScreenId ) {
m_screenToFollowId = scr - > name ( ) ;
}
qDebug ( ) < < " adapting to screen... " ;
m_view - > setScreen ( scr ) ;
if ( m_view - > containment ( ) ) {
m_view - > containment ( ) - > reactToScreenChange ( ) ;
}
connect ( scr , & QScreen : : geometryChanged , this , & Positioner : : screenGeometryChanged ) ;
syncGeometry ( ) ;
m_view - > updateAbsDockGeometry ( true ) ;
qDebug ( ) < < " setScreenToFollow() ended... " ;
emit screenGeometryChanged ( ) ;
emit currentScreenChanged ( ) ;
}
//! the main function which decides if this dock is at the
//! correct screen
void Positioner : : reconsiderScreen ( )
{
if ( m_inDelete ) {
return ;
}
qDebug ( ) < < " reconsiderScreen() called... " ;
qDebug ( ) < < " Delayer " ;
foreach ( auto scr , qGuiApp - > screens ( ) ) {
qDebug ( ) < < " D, found screen: " < < scr - > name ( ) ;
}
bool screenExists { false } ;
//!check if the associated screen is running
foreach ( auto scr , qGuiApp - > screens ( ) ) {
if ( m_screenToFollowId = = scr - > name ( )
| | ( m_view - > onPrimary ( ) & & scr = = qGuiApp - > primaryScreen ( ) ) ) {
screenExists = true ;
}
}
qDebug ( ) < < " dock screen exists ::: " < < screenExists ;
//! 1.a primary dock must be always on the primary screen
if ( m_view - > onPrimary ( ) & & ( m_screenToFollowId ! = qGuiApp - > primaryScreen ( ) - > name ( )
| | m_screenToFollow ! = qGuiApp - > primaryScreen ( )
| | m_view - > screen ( ) ! = qGuiApp - > primaryScreen ( ) ) ) {
using Plasma : : Types ;
QList < Types : : Location > edges { Types : : BottomEdge , Types : : LeftEdge ,
Types : : TopEdge , Types : : RightEdge } ;
edges = m_view - > managedLayout ( ) ? m_view - > managedLayout ( ) - > availableEdgesForView ( qGuiApp - > primaryScreen ( ) , m_view ) : edges ;
//change to primary screen only if the specific edge is free
qDebug ( ) < < " updating the primary screen for dock... " ;
qDebug ( ) < < " available primary screen edges: " < < edges ;
qDebug ( ) < < " dock location: " < < m_view - > location ( ) ;
if ( edges . contains ( m_view - > location ( ) ) ) {
//! case 1
qDebug ( ) < < " reached case 1: of updating dock primary screen... " ;
setScreenToFollow ( qGuiApp - > primaryScreen ( ) ) ;
}
} else if ( ! m_view - > onPrimary ( ) ) {
//! 2.an explicit dock must be always on the correct associated screen
//! there are cases that window manager misplaces the dock, this function
//! ensures that this dock will return at its correct screen
foreach ( auto scr , qGuiApp - > screens ( ) ) {
if ( scr & & scr - > name ( ) = = m_screenToFollowId ) {
qDebug ( ) < < " reached case 2: updating the explicit screen for dock... " ;
setScreenToFollow ( scr ) ;
break ;
}
}
}
syncGeometry ( ) ;
qDebug ( ) < < " reconsiderScreen() ended... " ;
}
void Positioner : : screenChanged ( QScreen * scr )
{
m_screenSyncTimer . start ( ) ;
//! this is needed in order to update the struts on screen change
//! and even though the geometry has been set correctly the offsets
//! of the screen must be updated to the new ones
2018-12-07 19:55:35 +03:00
if ( m_view - > visibility ( ) & & m_view - > visibility ( ) - > mode ( ) = = Latte : : Types : : AlwaysVisible ) {
2018-11-29 22:30:00 +03:00
m_view - > updateAbsDockGeometry ( true ) ;
}
}
void Positioner : : syncGeometry ( )
{
if ( ! ( m_view - > screen ( ) & & m_view - > containment ( ) ) | | m_inDelete ) {
return ;
}
bool found { false } ;
qDebug ( ) < < " syncGeometry() called... " ;
//! before updating the positioning and geometry of the dock
//! we make sure that the dock is at the correct screen
if ( m_view - > screen ( ) ! = m_screenToFollow ) {
qDebug ( ) < < " Sync Geometry screens inconsistent!!!! " ;
if ( m_screenToFollow ) {
qDebug ( ) < < " Sync Geometry screens inconsistent for m_screenToFollow: " < < m_screenToFollow - > name ( ) < < " dock screen: " < < m_view - > screen ( ) - > name ( ) ;
}
if ( ! m_screenSyncTimer . isActive ( ) ) {
m_screenSyncTimer . start ( ) ;
}
} else {
found = true ;
}
//! if the dock isnt at the correct screen the calculations
//! are not executed
if ( found ) {
//! compute the free screen rectangle for vertical panels only once
//! this way the costly QRegion computations are calculated only once
//! instead of two times (both inside the resizeWindow and the updatePosition)
QRegion freeRegion ; ;
QRect maximumRect ;
QRect availableScreenRect { m_view - > screen ( ) - > geometry ( ) } ;
if ( m_view - > formFactor ( ) = = Plasma : : Types : : Vertical ) {
QString layoutName = m_view - > managedLayout ( ) ? m_view - > managedLayout ( ) - > name ( ) : QString ( ) ;
2018-12-06 15:35:34 +03:00
auto latteCorona = qobject_cast < Latte : : Corona * > ( m_view - > corona ( ) ) ;
int fixedScreen = m_view - > onPrimary ( ) ? latteCorona - > screenPool ( ) - > primaryScreenId ( ) : m_view - > containment ( ) - > screen ( ) ;
2018-11-29 22:30:00 +03:00
2018-12-06 15:35:34 +03:00
freeRegion = latteCorona - > availableScreenRegionWithCriteria ( fixedScreen , layoutName ) ;
2018-11-29 22:30:00 +03:00
maximumRect = maximumNormalGeometry ( ) ;
QRegion availableRegion = freeRegion . intersected ( maximumRect ) ;
availableScreenRect = freeRegion . intersected ( maximumRect ) . boundingRect ( ) ;
float area = 0 ;
//! it is used to choose which or the availableRegion rectangles will
//! be the one representing dock geometry
for ( int i = 0 ; i < availableRegion . rectCount ( ) ; + + i ) {
QRect rect = availableRegion . rects ( ) . at ( i ) ;
//! the area of each rectangle in calculated in squares of 50x50
//! this is a way to avoid enourmous numbers for area value
float tempArea = ( float ) ( rect . width ( ) * rect . height ( ) ) / 2500 ;
if ( tempArea > area ) {
availableScreenRect = rect ;
area = tempArea ;
}
}
if ( availableRegion . rectCount ( ) > 1 & & m_view - > behaveAsPlasmaPanel ( ) ) {
2018-11-30 22:33:46 +03:00
m_view - > effects ( ) - > setForceDrawCenteredBorders ( true ) ;
2018-11-29 22:30:00 +03:00
} else {
2018-11-30 22:33:46 +03:00
m_view - > effects ( ) - > setForceDrawCenteredBorders ( false ) ;
2018-11-29 22:30:00 +03:00
}
} else {
2018-11-30 22:33:46 +03:00
m_view - > effects ( ) - > setForceDrawCenteredBorders ( false ) ;
2018-11-29 22:30:00 +03:00
}
2018-11-30 22:33:46 +03:00
m_view - > effects ( ) - > updateEnabledBorders ( ) ;
2018-11-29 22:30:00 +03:00
resizeWindow ( availableScreenRect ) ;
updatePosition ( availableScreenRect ) ;
qDebug ( ) < < " syncGeometry() calculations for screen: " < < m_view - > screen ( ) - > name ( ) < < " _ " < < m_view - > screen ( ) - > geometry ( ) ;
2018-12-09 03:06:52 +03:00
qDebug ( ) < < " syncGeometry() calculations for edge: " < < m_view - > location ( ) ;
2018-11-29 22:30:00 +03:00
}
qDebug ( ) < < " syncGeometry() ended... " ;
// qDebug() << "dock geometry:" << qRectToStr(geometry());
}
void Positioner : : validateDockGeometry ( )
{
if ( m_view - > geometry ( ) ! = m_validGeometry ) {
m_validateGeometryTimer . start ( ) ;
}
}
//! this is used mainly from vertical panels in order to
//! to get the maximum geometry that can be used from the dock
//! based on their alignment type and the location dock
QRect Positioner : : maximumNormalGeometry ( )
{
int xPos = 0 ;
int yPos = 0 ;
int maxHeight = m_view - > maxLength ( ) * m_view - > screen ( ) - > geometry ( ) . height ( ) ;
int maxWidth = m_view - > normalThickness ( ) ;
QRect maxGeometry ;
maxGeometry . setRect ( 0 , 0 , maxWidth , maxHeight ) ;
switch ( m_view - > location ( ) ) {
case Plasma : : Types : : LeftEdge :
xPos = m_view - > screen ( ) - > geometry ( ) . x ( ) ;
switch ( m_view - > alignment ( ) ) {
2018-12-07 19:55:35 +03:00
case Latte : : Types : : Top :
2018-11-29 22:30:00 +03:00
yPos = m_view - > screen ( ) - > geometry ( ) . y ( ) ;
break ;
2018-12-07 19:55:35 +03:00
case Latte : : Types : : Center :
case Latte : : Types : : Justify :
2018-11-29 22:30:00 +03:00
yPos = qMax ( m_view - > screen ( ) - > geometry ( ) . center ( ) . y ( ) - maxHeight / 2 , m_view - > screen ( ) - > geometry ( ) . y ( ) ) ;
break ;
2018-12-07 19:55:35 +03:00
case Latte : : Types : : Bottom :
2018-11-29 22:30:00 +03:00
yPos = m_view - > screen ( ) - > geometry ( ) . bottom ( ) - maxHeight + 1 ;
break ;
}
maxGeometry . setRect ( xPos , yPos , maxWidth , maxHeight ) ;
break ;
case Plasma : : Types : : RightEdge :
xPos = m_view - > screen ( ) - > geometry ( ) . right ( ) - maxWidth + 1 ;
switch ( m_view - > alignment ( ) ) {
2018-12-07 19:55:35 +03:00
case Latte : : Types : : Top :
2018-11-29 22:30:00 +03:00
yPos = m_view - > screen ( ) - > geometry ( ) . y ( ) ;
break ;
2018-12-07 19:55:35 +03:00
case Latte : : Types : : Center :
case Latte : : Types : : Justify :
2018-11-29 22:30:00 +03:00
yPos = qMax ( m_view - > screen ( ) - > geometry ( ) . center ( ) . y ( ) - maxHeight / 2 , m_view - > screen ( ) - > geometry ( ) . y ( ) ) ;
break ;
2018-12-07 19:55:35 +03:00
case Latte : : Types : : Bottom :
2018-11-29 22:30:00 +03:00
yPos = m_view - > screen ( ) - > geometry ( ) . bottom ( ) - maxHeight + 1 ;
break ;
}
maxGeometry . setRect ( xPos , yPos , maxWidth , maxHeight ) ;
break ;
default :
//! bypass clang warnings
break ;
}
//! this is needed in order to preserve that the top dock will be above
//! the others in case flag bypasswindowmanagerhint hasn't be set,
//! such a case is the AlwaysVisible mode
if ( m_view - > location ( ) = = Plasma : : Types : : TopEdge ) {
KWindowSystem : : setState ( m_view - > winId ( ) , NET : : KeepAbove ) ;
} else {
KWindowSystem : : clearState ( m_view - > winId ( ) , NET : : KeepAbove ) ;
}
return maxGeometry ;
}
void Positioner : : updatePosition ( QRect availableScreenRect )
{
QRect screenGeometry { availableScreenRect } ;
QPoint position ;
position = { 0 , 0 } ;
const auto length = [ & ] ( int length ) - > int {
float offs = static_cast < float > ( m_view - > offset ( ) ) ;
return static_cast < int > ( length * ( ( 1 - m_view - > maxLength ( ) ) / 2 ) + length * ( offs / 100 ) ) ;
} ;
2018-12-01 01:52:05 +03:00
int cleanThickness = m_view - > normalThickness ( ) - m_view - > effects ( ) - > innerShadow ( ) ;
2018-11-29 22:30:00 +03:00
switch ( m_view - > location ( ) ) {
case Plasma : : Types : : TopEdge :
if ( m_view - > behaveAsPlasmaPanel ( ) ) {
position = { screenGeometry . x ( ) + length ( screenGeometry . width ( ) ) , screenGeometry . y ( ) } ;
} else {
position = { screenGeometry . x ( ) , screenGeometry . y ( ) } ;
}
break ;
case Plasma : : Types : : BottomEdge :
if ( m_view - > behaveAsPlasmaPanel ( ) ) {
position = { screenGeometry . x ( ) + length ( screenGeometry . width ( ) ) ,
screenGeometry . y ( ) + screenGeometry . height ( ) - cleanThickness
} ;
} else {
position = { screenGeometry . x ( ) , screenGeometry . y ( ) + screenGeometry . height ( ) - m_view - > height ( ) } ;
}
break ;
case Plasma : : Types : : RightEdge :
if ( m_view - > behaveAsPlasmaPanel ( ) & & ! m_view - > mask ( ) . isNull ( ) ) {
position = { availableScreenRect . right ( ) - cleanThickness + 1 ,
availableScreenRect . y ( ) + length ( availableScreenRect . height ( ) )
} ;
} else {
position = { availableScreenRect . right ( ) - m_view - > width ( ) + 1 , availableScreenRect . y ( ) } ;
}
break ;
case Plasma : : Types : : LeftEdge :
if ( m_view - > behaveAsPlasmaPanel ( ) & & ! m_view - > mask ( ) . isNull ( ) ) {
position = { availableScreenRect . x ( ) , availableScreenRect . y ( ) + length ( availableScreenRect . height ( ) ) } ;
} else {
position = { availableScreenRect . x ( ) , availableScreenRect . y ( ) } ;
}
break ;
default :
qWarning ( ) < < " wrong location, couldn't update the panel position "
< < m_view - > location ( ) ;
}
m_validGeometry . setTopLeft ( position ) ;
m_view - > setPosition ( position ) ;
if ( m_view - > surface ( ) ) {
m_view - > surface ( ) - > setPosition ( position ) ;
}
}
void Positioner : : resizeWindow ( QRect availableScreenRect )
{
QSize screenSize = m_view - > screen ( ) - > size ( ) ;
QSize size = ( m_view - > formFactor ( ) = = Plasma : : Types : : Vertical ) ? QSize ( m_view - > maxThickness ( ) , availableScreenRect . height ( ) ) : QSize ( screenSize . width ( ) , m_view - > maxThickness ( ) ) ;
if ( m_view - > formFactor ( ) = = Plasma : : Types : : Vertical ) {
//qDebug() << "MAXIMUM RECT :: " << maximumRect << " - AVAILABLE RECT :: " << availableRect;
if ( m_view - > behaveAsPlasmaPanel ( ) ) {
size . setWidth ( m_view - > normalThickness ( ) ) ;
size . setHeight ( static_cast < int > ( m_view - > maxLength ( ) * availableScreenRect . height ( ) ) ) ;
}
} else {
if ( m_view - > behaveAsPlasmaPanel ( ) ) {
size . setWidth ( static_cast < int > ( m_view - > maxLength ( ) * screenSize . width ( ) ) ) ;
size . setHeight ( m_view - > normalThickness ( ) ) ;
}
}
m_validGeometry . setSize ( size ) ;
m_view - > setMinimumSize ( size ) ;
m_view - > setMaximumSize ( size ) ;
m_view - > resize ( size ) ;
if ( m_view - > formFactor ( ) = = Plasma : : Types : : Horizontal & & m_view - > corona ( ) ) {
emit m_view - > corona ( ) - > availableScreenRectChanged ( ) ;
}
}
2018-12-01 01:13:11 +03:00
void Positioner : : updateFormFactor ( )
2018-11-29 22:30:00 +03:00
{
2018-12-01 01:13:11 +03:00
if ( ! m_view - > containment ( ) )
return ;
2018-11-29 22:30:00 +03:00
2018-12-01 01:13:11 +03:00
switch ( m_view - > location ( ) ) {
case Plasma : : Types : : TopEdge :
case Plasma : : Types : : BottomEdge :
m_view - > containment ( ) - > setFormFactor ( Plasma : : Types : : Horizontal ) ;
break ;
2018-11-29 22:30:00 +03:00
2018-12-01 01:13:11 +03:00
case Plasma : : Types : : LeftEdge :
case Plasma : : Types : : RightEdge :
m_view - > containment ( ) - > setFormFactor ( Plasma : : Types : : Vertical ) ;
break ;
default :
qWarning ( ) < < " wrong location, couldn't update the panel position " < < m_view - > location ( ) ;
2018-11-29 22:30:00 +03:00
}
}
void Positioner : : initSignalingForLocationChangeSliding ( )
{
//! signals to handle the sliding-in/out during location changes
2018-12-01 01:13:11 +03:00
connect ( this , & Positioner : : hideDockDuringLocationChangeStarted , this , & Positioner : : onHideWindowsForSlidingOut ) ;
2018-11-29 22:30:00 +03:00
2018-12-06 13:15:58 +03:00
connect ( m_view , & View : : locationChanged , this , [ & ] ( ) {
2018-11-29 22:30:00 +03:00
if ( m_goToLocation ! = Plasma : : Types : : Floating ) {
m_goToLocation = Plasma : : Types : : Floating ;
QTimer : : singleShot ( 100 , [ this ] ( ) {
2018-12-01 10:42:09 +03:00
m_view - > effects ( ) - > setAnimationsBlocked ( false ) ;
2018-11-29 22:30:00 +03:00
emit showDockAfterLocationChangeFinished ( ) ;
m_view - > showSettingsWindow ( ) ;
if ( m_view - > managedLayout ( ) ) {
2018-12-06 13:51:15 +03:00
m_view - > managedLayout ( ) - > syncLatteViewsToScreens ( ) ;
2018-11-29 22:30:00 +03:00
}
} ) ;
}
} ) ;
//! signals to handle the sliding-in/out during screen changes
2018-12-01 01:13:11 +03:00
connect ( this , & Positioner : : hideDockDuringScreenChangeStarted , this , & Positioner : : onHideWindowsForSlidingOut ) ;
2018-11-29 22:30:00 +03:00
2018-12-01 16:22:33 +03:00
connect ( this , & Positioner : : currentScreenChanged , this , [ & ] ( ) {
2018-11-29 22:30:00 +03:00
if ( m_goToScreen ) {
m_goToScreen = nullptr ;
QTimer : : singleShot ( 100 , [ this ] ( ) {
2018-12-01 10:42:09 +03:00
m_view - > effects ( ) - > setAnimationsBlocked ( false ) ;
2018-11-29 22:30:00 +03:00
emit showDockAfterScreenChangeFinished ( ) ;
m_view - > showSettingsWindow ( ) ;
if ( m_view - > managedLayout ( ) ) {
2018-12-06 13:51:15 +03:00
m_view - > managedLayout ( ) - > syncLatteViewsToScreens ( ) ;
2018-11-29 22:30:00 +03:00
}
} ) ;
}
} ) ;
//! signals to handle the sliding-in/out during moving to another layout
2018-12-01 01:13:11 +03:00
connect ( this , & Positioner : : hideDockDuringMovingToLayoutStarted , this , & Positioner : : onHideWindowsForSlidingOut ) ;
2018-11-29 22:30:00 +03:00
2018-12-06 13:15:58 +03:00
connect ( m_view , & View : : managedLayoutChanged , this , [ & ] ( ) {
2018-11-29 22:30:00 +03:00
if ( ! m_moveToLayout . isEmpty ( ) & & m_view - > managedLayout ( ) ) {
m_moveToLayout = " " ;
QTimer : : singleShot ( 100 , [ this ] ( ) {
2018-12-01 10:42:09 +03:00
m_view - > effects ( ) - > setAnimationsBlocked ( false ) ;
2018-11-29 22:30:00 +03:00
emit showDockAfterMovingToLayoutFinished ( ) ;
m_view - > showSettingsWindow ( ) ;
} ) ;
}
} ) ;
//! ---- both cases ---- !//
//! this is used for both location and screen change cases, this signal
//! is send when the sliding-out animation has finished
connect ( this , & Positioner : : hideDockDuringLocationChangeFinished , this , [ & ] ( ) {
2018-12-01 10:42:09 +03:00
m_view - > effects ( ) - > setAnimationsBlocked ( true ) ;
2018-11-29 22:30:00 +03:00
if ( m_goToLocation ! = Plasma : : Types : : Floating ) {
m_view - > setLocation ( m_goToLocation ) ;
} else if ( m_goToScreen ) {
setScreenToFollow ( m_goToScreen ) ;
} else if ( ! m_moveToLayout . isEmpty ( ) ) {
m_view - > moveToLayout ( m_moveToLayout ) ;
}
} ) ;
}
bool Positioner : : inLocationChangeAnimation ( )
{
return ( ( m_goToLocation ! = Plasma : : Types : : Floating ) | | ( m_moveToLayout ! = " " ) | | m_goToScreen ) ;
}
void Positioner : : hideDockDuringLocationChange ( int goToLocation )
{
m_goToLocation = static_cast < Plasma : : Types : : Location > ( goToLocation ) ;
emit hideDockDuringLocationChangeStarted ( ) ;
}
void Positioner : : hideDockDuringMovingToLayout ( QString layoutName )
{
m_moveToLayout = layoutName ;
emit hideDockDuringMovingToLayoutStarted ( ) ;
}
}
2018-12-01 01:13:11 +03:00
}