1
0
mirror of https://github.com/KDE/latte-dock.git synced 2025-01-14 09:18:06 +03:00

fix #214, comment new multi-screen behavior

--refer to last 6-7 commits that contain this new
multi-screen behavior
--the new multi-screen behavior becomes more intelligent.
Latte trys to never let you without a dock containing
tasks plasmoid. It trys to do that intelligently not
depending on how many docks you have registered and if
they are set to explicit or primary ones
This commit is contained in:
Michail Vourlakos 2017-03-02 18:07:29 +02:00
parent c6988bb114
commit c510c74cc5
3 changed files with 95 additions and 38 deletions

View File

@ -252,6 +252,8 @@ QRect DockCorona::availableScreenRect(int id) const
return available;
}
//! the number of currently running docks containing
//! tasks plasmoid
int DockCorona::noDocksWithTasks() const
{
int result = 0;
@ -301,6 +303,8 @@ void DockCorona::screenCountChanged()
m_docksScreenSyncTimer.start();
}
//! the central functions that updates loading/unloading dockviews
//! concerning screen changed (for multi-screen setups mainly)
void DockCorona::syncDockViews()
{
qDebug() << "screen count changed -+-+ " << qGuiApp->screens().size();
@ -321,6 +325,10 @@ void DockCorona::syncDockViews()
bool onPrimary = cont->config().readEntry("onPrimary", true);
Plasma::Types::Location location = (Plasma::Types::Location)((int)cont->config().readEntry("location", (int)Plasma::Types::BottomEdge));
//! two main situations that a dock must be added when it is not already running
//! 1. when a dock is primary, not running and the edge for which is associated is free
//! 2. when a dock in explicit, not running and the associated screen currently exists
//! e.g. the screen has just been added
if (((onPrimary && freeEdges(qGuiApp->primaryScreen()).contains(location)) || (!onPrimary && (m_screenPool->connector(id) == scr->name())))
&& (!m_dockViews.contains(cont))) {
qDebug() << "screen Count signal: view must be added... for:" << scr->name();
@ -331,25 +339,31 @@ void DockCorona::syncDockViews()
qDebug() << "removing consideration & updating screen for always on primary docks....";
//this code trys to find a containment that must not be deleted by
//automatic algorithm. Currently the containment with the minimum id
//has higher priority
//! this code trys to find a containment that must not be deleted by
//! automatic algorithm. Currently the containment with the minimum id
//! containing tasks plasmoid wins
int preserveContainmentId{ -1};
bool dockWithTasksWillBeShown{false};
//! associate correct values for preserveContainmentId and
//! dockWithTasksWillBeShown
foreach (auto view, m_dockViews) {
bool found{false};
foreach (auto scr, qGuiApp->screens()) {
int id = view->containment()->screen();
if (id == -1) {
id = view->containment()->lastScreen();
}
if (scr->name() == view->currentScreen()) {
found = true;
break;
}
}
//!check if a tasks dock will be shown (try to prevent its deletion)
if (found && view->tasksPresent()) {
dockWithTasksWillBeShown = true;
}
@ -365,6 +379,12 @@ void DockCorona::syncDockViews()
}
}
//! check which docks must be deleted e.g. when the corresponding
//! screen does not exist any more.
//! The code is smart enough in order
//! to never delete the last tasks dock and also it makes sure that
//! the last tasks dock which will exist in the end will be the one
//! with the lowest containment id
foreach (auto view, m_dockViews) {
bool found{false};
@ -375,6 +395,7 @@ void DockCorona::syncDockViews()
}
}
//! which explicit docks can be deleted
if (!found && !view->onPrimary() && (m_dockViews.size() > 1) && m_dockViews.contains(view->containment())
&& !(view->tasksPresent() && noDocksWithTasks() == 1)) {
//do not delete last dock containing tasks
@ -383,12 +404,16 @@ void DockCorona::syncDockViews()
auto viewToDelete = m_dockViews.take(view->containment());
viewToDelete->deleteLater();
}
//!which primary docks can be deleted
} else if (view->onPrimary() && !found
&& !freeEdges(qGuiApp->primaryScreen()).contains(view->location())) {
qDebug() << "screen Count signal: primary view must be deleted... for:" << view->currentScreen();
auto viewToDelete = m_dockViews.take(view->containment());
viewToDelete->deleteLater();
} else {
//! if the dock will not be deleted its a very good point to reconsider
//! if the screen in which is running is the correct one
view->reconsiderScreen();
}
}
@ -542,6 +567,10 @@ void DockCorona::addDock(Plasma::Containment *containment)
QScreen *nextScreen{qGuiApp->primaryScreen()};
//! forceDockLoading is used when a latte configuration based on the
//! current running screens does not provide a dock containing tasks.
//! in such case the lowest latte containment containing tasks is loaded
//! and it forcefully becomes primary dock
bool forceDockLoading = false;
if (!m_tasksWillBeLoaded && m_firstContainmentWithTasks == containment->id()) {
@ -583,6 +612,8 @@ void DockCorona::addDock(Plasma::Containment *containment)
dockView->init();
dockView->setContainment(containment);
//! force this special dock case to become primary
//! even though it isnt
if (forceDockLoading) {
dockView->setOnPrimary(true);
}
@ -722,9 +753,7 @@ void DockCorona::loadDefaultLayout()
}
//! This function figures in the beginning if a dock with tasks
//! in it will be loaded, if it doesnt then the first dock
//! availabe with tasks will be loaded not depending on the
//! screen on which is associated
//! in it will be loaded taking into account also the screens are present.
bool DockCorona::heuresticForLoadingDockWithTasks()
{
auto containmentsEntries = config()->group("Containments");
@ -751,6 +780,7 @@ bool DockCorona::heuresticForLoadingDockWithTasks()
if (containsTasks) {
m_firstContainmentWithTasks = cId.toInt();
if (onPrimary) {
return true;
} else {

View File

@ -99,8 +99,11 @@ private:
int primaryScreenId() const;
bool m_activitiesStarting{true};
//this is used to check if a dock with tasks in it will be loaded on startup
//! this is used to check if a dock with tasks in it will be loaded on startup
bool m_tasksWillBeLoaded{false};
//! this is used to record the first dock having tasks in it. It is used
//! to specify which dock will be loaded on startup if a case that no "dock
//! with tasks" will be loaded otherwise. Currently the older one dock wins
int m_firstContainmentWithTasks{ -1};
QHash<const Plasma::Containment *, DockView *> m_dockViews;

View File

@ -95,8 +95,8 @@ DockView::DockView(Plasma::Corona *corona, QScreen *targetScreen)
connect(dockCorona, &DockCorona::docksCountChanged, this, &DockView::docksCountChanged);
connect(dockCorona, &DockCorona::dockLocationChanged, this, &DockView::dockLocationChanged);
connect(dockCorona, &DockCorona::dockLocationChanged, this, [&]() {
//check if an edge has been freed for a primary dock
//from another screen
//! check if an edge has been freed for a primary dock
//! from another screen
if (m_onPrimary) {
m_screenSyncTimer.start();
}
@ -196,6 +196,14 @@ bool DockView::setCurrentScreen(const QString id)
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 DockView::setScreenToFollow(QScreen *screen, bool updateScreenId)
{
if (!screen || m_screenToFollow == screen) {
@ -218,6 +226,8 @@ void DockView::setScreenToFollow(QScreen *screen, bool updateScreenId)
syncGeometry();
}
//! the main function which decides if this dock is at the
//! correct screen
void DockView::reconsiderScreen()
{
qDebug() << " Delayer ";
@ -230,6 +240,7 @@ void DockView::reconsiderScreen()
bool screenExists{false};
//!check if the associated screen is running
foreach (auto scr, qGuiApp->screens()) {
if (m_screenToFollowId == scr->name())
screenExists = true;
@ -237,6 +248,9 @@ void DockView::reconsiderScreen()
qDebug() << "dock screen exists ::: " << screenExists;
//! 1.a primary dock must be always on the primary screen
//! 2.the last tasks dock must also always on the primary screen
//! even though it has been configured as an explicit
if ((m_onPrimary || (tasksPresent() && dockCorona->noDocksWithTasks() == 1) && !screenExists)
&& m_screenToFollowId != qGuiApp->primaryScreen()->name()
&& m_screenToFollow != qGuiApp->primaryScreen()) {
@ -244,15 +258,20 @@ void DockView::reconsiderScreen()
if (dockCorona->freeEdges(qGuiApp->primaryScreen()).contains(location())) {
connect(qGuiApp->primaryScreen(), &QScreen::geometryChanged, this, &DockView::screenGeometryChanged);
//! case 2
if (!m_onPrimary && !screenExists && tasksPresent() && (dockCorona->noDocksWithTasks() == 1)) {
setScreenToFollow(qGuiApp->primaryScreen(), false);
} else {
//! case 1
setScreenToFollow(qGuiApp->primaryScreen());
}
syncGeometry();
}
} else {
//! 3.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) {
connect(scr, &QScreen::geometryChanged, this, &DockView::screenGeometryChanged);
@ -485,6 +504,8 @@ inline void DockView::syncGeometry()
bool found{false};
//! before updating the positioning and geometry of the dock
//! we make sure that the dock is at the correct screen
if (this->screen() != m_screenToFollow) {
qDebug() << "Sync Geometry screens incosistent!!!!";
m_screenSyncTimer.start();
@ -492,6 +513,8 @@ inline void DockView::syncGeometry()
found = true;
}
//! if the dock isnt at the correct screen the calculations
//! are not executed
if (found) {
updateEnabledBorders();
resizeWindow();
@ -706,6 +729,7 @@ void DockView::setShadow(int shadow)
emit shadowChanged();
}
//! check if the tasks plasmoid exist in the dock
bool DockView::tasksPresent()
{
foreach (Plasma::Applet *applet, this->containment()->applets()) {