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:
parent
c6988bb114
commit
c510c74cc5
@ -217,11 +217,11 @@ QRect DockCorona::availableScreenRect(int id) const
|
||||
const QScreen *screen{qGuiApp->primaryScreen()};
|
||||
QString scrName = m_screenPool->connector(id);
|
||||
|
||||
foreach(auto scr, screens){
|
||||
if (scr->name() == scrName){
|
||||
screen = scr;
|
||||
break;
|
||||
}
|
||||
foreach (auto scr, screens) {
|
||||
if (scr->name() == scrName) {
|
||||
screen = scr;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!screen)
|
||||
@ -238,13 +238,13 @@ QRect DockCorona::availableScreenRect(int id) const
|
||||
// need calculate available space for top and bottom location,
|
||||
// because the left and right are those who dodge others docks
|
||||
switch (view->location()) {
|
||||
case Plasma::Types::TopEdge:
|
||||
available.setTopLeft({available.x(), dockRect.bottom()});
|
||||
break;
|
||||
case Plasma::Types::TopEdge:
|
||||
available.setTopLeft({available.x(), dockRect.bottom()});
|
||||
break;
|
||||
|
||||
case Plasma::Types::BottomEdge:
|
||||
available.setBottomLeft({available.x(), dockRect.top()});
|
||||
break;
|
||||
case Plasma::Types::BottomEdge:
|
||||
available.setBottomLeft({available.x(), dockRect.top()});
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -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,8 +325,12 @@ 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));
|
||||
|
||||
if (( (onPrimary && freeEdges(qGuiApp->primaryScreen()).contains(location)) || (!onPrimary &&(m_screenPool->connector(id) == scr->name())))
|
||||
&& (!m_dockViews.contains(cont))) {
|
||||
//! 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();
|
||||
addDock(cont);
|
||||
}
|
||||
@ -331,40 +339,52 @@ 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
|
||||
int preserveContainmentId{-1};
|
||||
//! 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;
|
||||
}
|
||||
}
|
||||
|
||||
if(found && view->tasksPresent()){
|
||||
dockWithTasksWillBeShown = true;
|
||||
//!check if a tasks dock will be shown (try to prevent its deletion)
|
||||
if (found && view->tasksPresent()) {
|
||||
dockWithTasksWillBeShown = true;
|
||||
}
|
||||
|
||||
if (!found && !view->onPrimary() && (m_dockViews.size() > 1) && m_dockViews.contains(view->containment())
|
||||
&& !(view->tasksPresent() && noDocksWithTasks() == 1)) { //do not delete last dock containing tasks
|
||||
&& !(view->tasksPresent() && noDocksWithTasks() == 1)) { //do not delete last dock containing tasks
|
||||
if (view->tasksPresent()) {
|
||||
if (preserveContainmentId==-1)
|
||||
if (preserveContainmentId == -1)
|
||||
preserveContainmentId = view->containment()->id();
|
||||
else if(view->containment()->id() < preserveContainmentId)
|
||||
else if (view->containment()->id() < preserveContainmentId)
|
||||
preserveContainmentId = view->containment()->id();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//! 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,20 +395,25 @@ 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)) {
|
||||
&& !(view->tasksPresent() && noDocksWithTasks() == 1)) {
|
||||
//do not delete last dock containing tasks
|
||||
if (dockWithTasksWillBeShown || preserveContainmentId != view->containment()->id()) {
|
||||
qDebug() << "screen Count signal: view must be deleted... for:" << view->currentScreen();
|
||||
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())){
|
||||
&& !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();
|
||||
}
|
||||
}
|
||||
@ -413,8 +438,8 @@ int DockCorona::docksCount(int screen) const
|
||||
|
||||
for (const auto &view : m_dockViews) {
|
||||
if (view && view->containment()
|
||||
&& view->containment()->screen() == screen
|
||||
&& !view->containment()->destroyed()) {
|
||||
&& view->containment()->screen() == screen
|
||||
&& !view->containment()->destroyed()) {
|
||||
++docks;
|
||||
}
|
||||
}
|
||||
@ -446,7 +471,7 @@ QList<Plasma::Types::Location> DockCorona::freeEdges(QScreen *screen) const
|
||||
{
|
||||
using Plasma::Types;
|
||||
QList<Types::Location> edges{Types::BottomEdge, Types::LeftEdge,
|
||||
Types::TopEdge, Types::RightEdge};
|
||||
Types::TopEdge, Types::RightEdge};
|
||||
|
||||
for (auto *view : m_dockViews) {
|
||||
if (view && view->currentScreen() == screen->name()) {
|
||||
@ -461,13 +486,13 @@ QList<Plasma::Types::Location> DockCorona::freeEdges(int screen) const
|
||||
{
|
||||
using Plasma::Types;
|
||||
QList<Types::Location> edges{Types::BottomEdge, Types::LeftEdge,
|
||||
Types::TopEdge, Types::RightEdge};
|
||||
Types::TopEdge, Types::RightEdge};
|
||||
//when screen=-1 is passed then the primaryScreenid is used
|
||||
int fixedScreen = (screen == -1) ? primaryScreenId() : screen;
|
||||
|
||||
for (auto *view : m_dockViews) {
|
||||
if (view && view->containment()
|
||||
&& view->containment()->screen() == fixedScreen) {
|
||||
&& view->containment()->screen() == fixedScreen) {
|
||||
edges.removeOne(view->location());
|
||||
}
|
||||
}
|
||||
@ -514,8 +539,8 @@ int DockCorona::screenForContainment(const Plasma::Containment *containment) con
|
||||
for (auto screen : qGuiApp->screens()) {
|
||||
// containment->lastScreen() == m_screenPool->id(screen->name()) to check if the lastScreen refers to a screen that exists/it's known
|
||||
if (containment->lastScreen() == m_screenPool->id(screen->name()) &&
|
||||
(containment->activity() == m_activityConsumer->currentActivity() ||
|
||||
containment->containmentType() == Plasma::Types::PanelContainment || containment->containmentType() == Plasma::Types::CustomPanelContainment)) {
|
||||
(containment->activity() == m_activityConsumer->currentActivity() ||
|
||||
containment->containmentType() == Plasma::Types::PanelContainment || containment->containmentType() == Plasma::Types::CustomPanelContainment)) {
|
||||
return containment->lastScreen();
|
||||
}
|
||||
}
|
||||
@ -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 {
|
||||
|
@ -99,9 +99,12 @@ 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};
|
||||
int m_firstContainmentWithTasks{-1};
|
||||
//! 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;
|
||||
QHash<const Plasma::Containment *, DockView *> m_waitingDockViews;
|
||||
|
@ -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()) {
|
||||
|
Loading…
Reference in New Issue
Block a user