mirror of
https://github.com/KDE/latte-dock.git
synced 2025-03-10 04:58:16 +03:00
dock containing tasks is protected in multi-screen
--the last dock containing tasks can not be removed automatic by Latte based on screens heuristics --on startup Latte checks if a dock containing tasks will be loaded based on screens associated. If it doesnt it loads the first dock containing tasks and puts it on primary screen and setting also its flag to onPrimary --on the configuration window when a dock changes from explicit to primary screen by latte automation the record of the previous screen is shown correctly
This commit is contained in:
parent
07d68dd636
commit
74770a9f37
@ -98,6 +98,9 @@ void DockCorona::load()
|
||||
|
||||
m_activitiesStarting = false;
|
||||
|
||||
m_tasksWillBeLoaded = heuresticForLoadingDockWithTasks();
|
||||
qDebug() << "TASKS WILL BE PRESENT AFTER LOADING ::: " << m_tasksWillBeLoaded;
|
||||
|
||||
// connect(qGuiApp, &QGuiApplication::screenAdded, this, &DockCorona::addOutput, Qt::UniqueConnection);
|
||||
connect(qGuiApp, &QGuiApplication::primaryScreenChanged, this, &DockCorona::primaryOutputChanged, Qt::UniqueConnection);
|
||||
// connect(qGuiApp, &QGuiApplication::screenRemoved, this, &DockCorona::screenRemoved, Qt::UniqueConnection);
|
||||
@ -227,13 +230,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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -241,6 +244,19 @@ QRect DockCorona::availableScreenRect(int id) const
|
||||
return available;
|
||||
}
|
||||
|
||||
int DockCorona::noDocksWithTasks() const
|
||||
{
|
||||
int result = 0;
|
||||
|
||||
foreach (auto view, m_dockViews) {
|
||||
if (view->tasksPresent()) {
|
||||
result++;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void DockCorona::addOutput(QScreen *screen)
|
||||
{
|
||||
Q_ASSERT(screen);
|
||||
@ -305,6 +321,40 @@ 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};
|
||||
bool dockWithTasksWillBeShown{false};
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
if (!found && !view->onPrimary() && (m_dockViews.size() > 1) && m_dockViews.contains(view->containment())
|
||||
&& !(view->tasksPresent() && noDocksWithTasks() == 1)) { //do not delete last dock containing tasks
|
||||
if (view->tasksPresent()) {
|
||||
if (preserveContainmentId==-1)
|
||||
preserveContainmentId = view->containment()->id();
|
||||
else if(view->containment()->id() < preserveContainmentId)
|
||||
preserveContainmentId = view->containment()->id();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
foreach (auto view, m_dockViews) {
|
||||
bool found{false};
|
||||
|
||||
@ -321,10 +371,14 @@ void DockCorona::syncDockViews()
|
||||
}
|
||||
}
|
||||
|
||||
if (!found && !view->onPrimary() && (m_dockViews.size() > 1) && m_dockViews.contains(view->containment())) {
|
||||
qDebug() << "screen Count signal: view must be deleted... for:" << view->currentScreen();
|
||||
auto viewToDelete = m_dockViews.take(view->containment());
|
||||
viewToDelete->deleteLater();
|
||||
if (!found && !view->onPrimary() && (m_dockViews.size() > 1) && m_dockViews.contains(view->containment())
|
||||
&& !(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();
|
||||
}
|
||||
} else {
|
||||
view->reconsiderScreen();
|
||||
}
|
||||
@ -350,8 +404,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;
|
||||
}
|
||||
}
|
||||
@ -383,7 +437,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()) {
|
||||
@ -398,13 +452,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());
|
||||
}
|
||||
}
|
||||
@ -451,8 +505,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();
|
||||
}
|
||||
}
|
||||
@ -469,10 +523,8 @@ void DockCorona::addDock(Plasma::Containment *containment)
|
||||
|
||||
auto metadata = containment->kPackage().metadata();
|
||||
|
||||
if (metadata.pluginId() == "org.kde.plasma.private.systemtray") {
|
||||
if (metadata.pluginId() != "org.kde.latte.containment")
|
||||
return;
|
||||
}
|
||||
if (metadata.pluginId() != "org.kde.latte.containment")
|
||||
return;
|
||||
|
||||
for (auto *dock : m_dockViews) {
|
||||
if (dock->containment() == containment)
|
||||
@ -481,6 +533,13 @@ void DockCorona::addDock(Plasma::Containment *containment)
|
||||
|
||||
QScreen *nextScreen{qGuiApp->primaryScreen()};
|
||||
|
||||
bool forceDockLoading = false;
|
||||
|
||||
if (!m_tasksWillBeLoaded && m_firstContainmentWithTasks == containment->id()) {
|
||||
m_tasksWillBeLoaded = true; //this protects by loading more than one dock at startup
|
||||
forceDockLoading = true;
|
||||
}
|
||||
|
||||
bool onPrimary = containment->config().readEntry("onPrimary", true);
|
||||
int id = containment->screen();
|
||||
|
||||
@ -490,7 +549,7 @@ void DockCorona::addDock(Plasma::Containment *containment)
|
||||
|
||||
qDebug() << "add dock - containment id : " << id;
|
||||
|
||||
if (id >= 0 && !onPrimary) {
|
||||
if (id >= 0 && !onPrimary && !forceDockLoading) {
|
||||
QString connector = m_screenPool->connector(id);
|
||||
qDebug() << "add dock - connector : " << connector;
|
||||
bool found{false};
|
||||
@ -512,6 +571,11 @@ void DockCorona::addDock(Plasma::Containment *containment)
|
||||
auto dockView = new DockView(this, nextScreen);
|
||||
dockView->init();
|
||||
dockView->setContainment(containment);
|
||||
|
||||
if (forceDockLoading) {
|
||||
dockView->setOnPrimary(true);
|
||||
}
|
||||
|
||||
connect(containment, &QObject::destroyed, this, &DockCorona::dockContainmentDestroyed);
|
||||
connect(containment, &Plasma::Applet::destroyedChanged, this, &DockCorona::destroyedChanged);
|
||||
connect(containment, &Plasma::Applet::locationChanged, this, &DockCorona::dockLocationChanged);
|
||||
@ -646,6 +710,81 @@ void DockCorona::loadDefaultLayout()
|
||||
defaultContainment->createApplet(QStringLiteral("org.kde.plasma.analogclock"));
|
||||
}
|
||||
|
||||
//! 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
|
||||
bool DockCorona::heuresticForLoadingDockWithTasks()
|
||||
{
|
||||
auto containmentsEntries = config()->group("Containments");
|
||||
|
||||
foreach (auto cId, containmentsEntries.groupList()) {
|
||||
QString plugin = containmentsEntries.group(cId).readEntry("plugin");
|
||||
|
||||
if (plugin == "org.kde.latte.containment") {
|
||||
bool onPrimary = containmentsEntries.group(cId).readEntry("onPrimary", true);
|
||||
int lastScreen = containmentsEntries.group(cId).readEntry("lastScreen", -1);
|
||||
|
||||
qDebug() << "containment values: " << onPrimary << " - " << lastScreen;
|
||||
|
||||
auto appletEntries = containmentsEntries.group(cId).group("Applets");
|
||||
|
||||
bool containsTasks = false;
|
||||
|
||||
foreach (auto appId, appletEntries.groupList()) {
|
||||
if (appletEntries.group(appId).readEntry("plugin") == "org.kde.latte.plasmoid") {
|
||||
containsTasks = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (containsTasks) {
|
||||
m_firstContainmentWithTasks = cId.toInt();
|
||||
if (onPrimary) {
|
||||
return true;
|
||||
} else {
|
||||
if (lastScreen >= 0) {
|
||||
QString connector = m_screenPool->connector(lastScreen);
|
||||
|
||||
foreach (auto scr, qGuiApp->screens()) {
|
||||
if (scr && scr->name() == connector) {
|
||||
return true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
//! This function figures if a latte containment contains a
|
||||
//! latte tasks plasmoid
|
||||
bool DockCorona::containmentContainsTasks(Plasma::Containment *cont)
|
||||
{
|
||||
auto containmentsEntries = config()->group("Containments");
|
||||
|
||||
foreach (auto cId, containmentsEntries.groupList()) {
|
||||
QString plugin = containmentsEntries.group(cId).readEntry("plugin");
|
||||
|
||||
if ((plugin == "org.kde.latte.containment") && (cId.toUInt() == cont->id())) {
|
||||
auto appletEntries = containmentsEntries.group(cId).group("Applets");
|
||||
|
||||
foreach (auto appId, appletEntries.groupList()) {
|
||||
if (appletEntries.group(appId).readEntry("plugin") == "org.kde.latte.plasmoid") {
|
||||
return true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
inline void DockCorona::qmlRegisterTypes() const
|
||||
{
|
||||
qmlRegisterType<QScreen>();
|
||||
|
@ -58,6 +58,7 @@ public:
|
||||
QList<Plasma::Types::Location> freeEdges(QScreen *screen) const;
|
||||
|
||||
int docksCount(int screen) const;
|
||||
int noDocksWithTasks() const;
|
||||
int screenForContainment(const Plasma::Containment *containment) const override;
|
||||
|
||||
void addDock(Plasma::Containment *containment);
|
||||
@ -91,11 +92,16 @@ private slots:
|
||||
private:
|
||||
bool appletExists(uint containmentId, uint appletId) const;
|
||||
void cleanConfig();
|
||||
bool containmentContainsTasks(Plasma::Containment *cont);
|
||||
bool containmentExists(uint id) const;
|
||||
bool heuresticForLoadingDockWithTasks();
|
||||
void qmlRegisterTypes() const;
|
||||
int primaryScreenId() const;
|
||||
|
||||
bool m_activitiesStarting{true};
|
||||
//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};
|
||||
|
||||
QHash<const Plasma::Containment *, DockView *> m_dockViews;
|
||||
QHash<const Plasma::Containment *, DockView *> m_waitingDockViews;
|
||||
|
@ -97,7 +97,7 @@ DockView::DockView(Plasma::Corona *corona, QScreen *targetScreen)
|
||||
connect(dockCorona, &DockCorona::dockLocationChanged, this, [&]() {
|
||||
//check if an edge has been freed for a primary dock
|
||||
//from another screen
|
||||
if(m_onPrimary) {
|
||||
if (m_onPrimary) {
|
||||
m_screenSyncTimer.start();
|
||||
}
|
||||
});
|
||||
@ -196,14 +196,17 @@ bool DockView::setCurrentScreen(const QString id)
|
||||
return true;
|
||||
}
|
||||
|
||||
void DockView::setScreenToFollow(QScreen *screen)
|
||||
void DockView::setScreenToFollow(QScreen *screen, bool updateScreenId)
|
||||
{
|
||||
if (!screen || m_screenToFollow == screen) {
|
||||
return;
|
||||
}
|
||||
|
||||
m_screenToFollow = screen;
|
||||
m_screenToFollowId = screen->name();
|
||||
|
||||
if (updateScreenId) {
|
||||
m_screenToFollowId = screen->name();
|
||||
}
|
||||
|
||||
qDebug() << "adapting to screen...";
|
||||
|
||||
@ -223,13 +226,29 @@ void DockView::reconsiderScreen()
|
||||
qDebug() << " D, found screen: " << scr->name();
|
||||
}
|
||||
|
||||
if (m_onPrimary && screen() != qGuiApp->primaryScreen()) {
|
||||
auto *dockCorona = qobject_cast<DockCorona *>(this->corona());
|
||||
auto *dockCorona = qobject_cast<DockCorona *>(this->corona());
|
||||
|
||||
bool screenExists{false};
|
||||
foreach(auto scr, qGuiApp->screens()){
|
||||
if (m_screenToFollowId == scr->name())
|
||||
screenExists = true;
|
||||
}
|
||||
|
||||
qDebug() << "dock screen exists ::: "<< screenExists;
|
||||
|
||||
if ((m_onPrimary || (tasksPresent() && dockCorona->noDocksWithTasks() == 1) && !screenExists)
|
||||
&& m_screenToFollowId != qGuiApp->primaryScreen()->name()
|
||||
&& m_screenToFollow != qGuiApp->primaryScreen()) {
|
||||
//change to primary screen only if the specific edge is free
|
||||
if (dockCorona->freeEdges(qGuiApp->primaryScreen()).contains(location())) {
|
||||
connect(qGuiApp->primaryScreen(), &QScreen::geometryChanged, this, &DockView::screenGeometryChanged);
|
||||
setScreenToFollow(qGuiApp->primaryScreen());
|
||||
|
||||
if (!m_onPrimary && !screenExists && tasksPresent() && (dockCorona->noDocksWithTasks() == 1)) {
|
||||
setScreenToFollow(qGuiApp->primaryScreen(), false);
|
||||
} else {
|
||||
setScreenToFollow(qGuiApp->primaryScreen());
|
||||
}
|
||||
|
||||
syncGeometry();
|
||||
}
|
||||
} else {
|
||||
|
@ -74,7 +74,7 @@ public:
|
||||
|
||||
void init();
|
||||
|
||||
void setScreenToFollow(QScreen *screen);
|
||||
void setScreenToFollow(QScreen *screen, bool updateScreenId = true);
|
||||
|
||||
void resizeWindow();
|
||||
void syncGeometry();
|
||||
|
@ -69,6 +69,18 @@ PlasmaComponents.Page {
|
||||
|
||||
screens.push(i18n("On Primary"));
|
||||
|
||||
//check if the screen exists, it is used in cases Latte is moving
|
||||
//the dock automatically to primaryScreen in order for the user
|
||||
//to has always a dock with tasks shown
|
||||
var screenExists = false
|
||||
for (var i = 0; i < dock.screens.length; i++) {
|
||||
if (dock.screens[i].name === dock.currentScreen)
|
||||
screenExists = true;
|
||||
}
|
||||
|
||||
if (!screenExists && !dock.onPrimary)
|
||||
screens.push(dock.currentScreen);
|
||||
|
||||
for (var i = 0; i < dock.screens.length; i++) {
|
||||
screens.push(dock.screens[i].name)
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user