File indexing completed on 2024-12-08 13:22:24
0001 /* 0002 * Copyright 2016 Smith AR <audoban@openmailbox.org> 0003 * Michail Vourlakos <mvourlakos@gmail.com> 0004 * 0005 * This file is part of Latte-Dock 0006 * 0007 * Latte-Dock is free software; you can redistribute it and/or 0008 * modify it under the terms of the GNU General Public License as 0009 * published by the Free Software Foundation; either version 2 of 0010 * the License, or (at your option) any later version. 0011 * 0012 * Latte-Dock is distributed in the hope that it will be useful, 0013 * but WITHOUT ANY WARRANTY; without even the implied warranty of 0014 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 0015 * GNU General Public License for more details. 0016 * 0017 * You should have received a copy of the GNU General Public License 0018 * along with this program. If not, see <http://www.gnu.org/licenses/>. 0019 */ 0020 0021 #include "visibilitymanager.h" 0022 0023 // local 0024 #include "positioner.h" 0025 #include "screenedgeghostwindow.h" 0026 #include "view.h" 0027 #include "windowstracker/currentscreentracker.h" 0028 #include "../lattecorona.h" 0029 #include "../screenpool.h" 0030 #include "../layouts/manager.h" 0031 #include "../wm/abstractwindowinterface.h" 0032 #include "../../liblatte2/extras.h" 0033 0034 // Qt 0035 #include <QDebug> 0036 0037 // KDE 0038 #include <KWindowSystem> 0039 #include <KWayland/Client/plasmashell.h> 0040 #include <KWayland/Client/surface.h> 0041 0042 //! Hide Timer can create cases that when it is low it does not allow the 0043 //! view to be show. For example !compositing+kwin_edges+hide inteval<50ms 0044 const int HIDEMINIMUMINTERVAL = 50; 0045 0046 namespace Latte { 0047 namespace ViewPart { 0048 0049 //! BEGIN: VisiblityManager implementation 0050 0051 VisibilityManager::VisibilityManager(PlasmaQuick::ContainmentView *view) 0052 : QObject(view) 0053 { 0054 qDebug() << "VisibilityManager creating..."; 0055 0056 m_latteView = qobject_cast<Latte::View *>(view); 0057 m_corona = qobject_cast<Latte::Corona *>(view->corona()); 0058 m_wm = m_corona->wm(); 0059 0060 connect(this, &VisibilityManager::slideInFinished, this, &VisibilityManager::updateHiddenState); 0061 connect(this, &VisibilityManager::slideOutFinished, this, &VisibilityManager::updateHiddenState); 0062 0063 connect(this, &VisibilityManager::enableKWinEdgesChanged, this, &VisibilityManager::updateKWinEdgesSupport); 0064 connect(this, &VisibilityManager::modeChanged, this, &VisibilityManager::updateKWinEdgesSupport); 0065 0066 if (m_latteView) { 0067 connect(m_latteView, &Latte::View::eventTriggered, this, &VisibilityManager::viewEventManager); 0068 connect(m_latteView, &Latte::View::byPassWMChanged, this, &VisibilityManager::updateKWinEdgesSupport); 0069 0070 connect(m_latteView, &Latte::View::absoluteGeometryChanged, this, [&]() { 0071 if (m_mode == Types::AlwaysVisible && m_latteView->screen()) { 0072 updateStrutsBasedOnLayoutsAndActivities(); 0073 } 0074 }); 0075 0076 connect(this, &VisibilityManager::modeChanged, this, [&]() { 0077 emit m_latteView->availableScreenRectChangedFrom(m_latteView); 0078 }); 0079 } 0080 0081 m_timerStartUp.setInterval(5000); 0082 m_timerStartUp.setSingleShot(true); 0083 m_timerShow.setSingleShot(true); 0084 m_timerHide.setSingleShot(true); 0085 0086 connect(&m_timerShow, &QTimer::timeout, this, [&]() { 0087 if (m_isHidden) { 0088 // qDebug() << "must be shown"; 0089 emit mustBeShown(); 0090 } 0091 }); 0092 connect(&m_timerHide, &QTimer::timeout, this, [&]() { 0093 if (!m_blockHiding && !m_isHidden && !m_dragEnter) { 0094 // qDebug() << "must be hide"; 0095 emit mustBeHide(); 0096 } 0097 }); 0098 0099 restoreConfig(); 0100 } 0101 0102 VisibilityManager::~VisibilityManager() 0103 { 0104 qDebug() << "VisibilityManager deleting..."; 0105 m_wm->removeViewStruts(*m_latteView); 0106 0107 if (m_edgeGhostWindow) { 0108 m_edgeGhostWindow->deleteLater(); 0109 } 0110 } 0111 0112 Types::Visibility VisibilityManager::mode() const 0113 { 0114 return m_mode; 0115 } 0116 0117 void VisibilityManager::setMode(Latte::Types::Visibility mode) 0118 { 0119 if (m_mode == mode) 0120 return; 0121 0122 Q_ASSERT_X(mode != Types::None, staticMetaObject.className(), "set visibility to Types::None"); 0123 0124 // clear mode 0125 for (auto &c : m_connections) { 0126 disconnect(c); 0127 } 0128 0129 int base{0}; 0130 0131 m_publishedStruts = QRect(); 0132 0133 if (m_mode == Types::AlwaysVisible) { 0134 //! remove struts for old always visible mode 0135 m_wm->removeViewStruts(*m_latteView); 0136 } 0137 0138 m_timerShow.stop(); 0139 m_timerHide.stop(); 0140 m_mode = mode; 0141 0142 if (mode != Types::AlwaysVisible && mode != Types::WindowsGoBelow) { 0143 //set wayland visibility mode 0144 if (m_latteView->surface()) { 0145 m_latteView->surface()->setPanelBehavior(KWayland::Client::PlasmaShellSurface::PanelBehavior::WindowsGoBelow); 0146 } 0147 0148 m_connections[0] = connect(m_wm, &WindowSystem::AbstractWindowInterface::currentDesktopChanged, this, [&] { 0149 if (m_raiseOnDesktopChange) { 0150 raiseViewTemporarily(); 0151 } 0152 }); 0153 m_connections[1] = connect(m_wm, &WindowSystem::AbstractWindowInterface::currentActivityChanged, this, [&]() { 0154 if (m_raiseOnActivityChange) { 0155 raiseViewTemporarily(); 0156 } else { 0157 updateHiddenState(); 0158 } 0159 }); 0160 0161 base = 2; 0162 } else { 0163 //set wayland visibility mode 0164 if (m_latteView->surface()) { 0165 m_latteView->surface()->setPanelBehavior(KWayland::Client::PlasmaShellSurface::PanelBehavior::AutoHide); 0166 } 0167 } 0168 0169 switch (m_mode) { 0170 case Types::AlwaysVisible: { 0171 if (m_latteView->containment() && m_latteView->screen()) { 0172 updateStrutsBasedOnLayoutsAndActivities(); 0173 } 0174 0175 m_connections[base] = connect(m_latteView, &Latte::View::normalThicknessChanged, this, [&]() { 0176 updateStrutsBasedOnLayoutsAndActivities(); 0177 }); 0178 0179 m_connections[base+1] = connect(m_corona->layoutsManager(), &Layouts::Manager::currentLayoutNameChanged, this, [&]() { 0180 if (m_corona && m_corona->layoutsManager()->memoryUsage() == Types::MultipleLayouts) { 0181 updateStrutsBasedOnLayoutsAndActivities(true); 0182 } 0183 }); 0184 0185 m_connections[base+2] = connect(m_latteView, &Latte::View::activitiesChanged, this, [&]() { 0186 if (m_corona && m_corona->layoutsManager()->memoryUsage() == Types::MultipleLayouts) { 0187 updateStrutsBasedOnLayoutsAndActivities(true); 0188 } 0189 }); 0190 0191 raiseView(true); 0192 break; 0193 } 0194 0195 case Types::AutoHide: { 0196 m_connections[base] = connect(this, &VisibilityManager::containsMouseChanged, this, [&]() { 0197 raiseView(m_containsMouse); 0198 }); 0199 0200 raiseView(m_containsMouse); 0201 break; 0202 } 0203 0204 case Types::DodgeActive: { 0205 m_connections[base] = connect(this, &VisibilityManager::containsMouseChanged 0206 , this, &VisibilityManager::dodgeActive); 0207 m_connections[base+1] = connect(m_latteView->windowsTracker()->currentScreen(), &TrackerPart::CurrentScreenTracker::activeWindowTouchingChanged 0208 , this, &VisibilityManager::dodgeActive); 0209 0210 dodgeActive(); 0211 break; 0212 } 0213 0214 case Types::DodgeMaximized: { 0215 m_connections[base] = connect(this, &VisibilityManager::containsMouseChanged 0216 , this, &VisibilityManager::dodgeMaximized); 0217 m_connections[base+1] = connect(m_latteView->windowsTracker()->currentScreen(), &TrackerPart::CurrentScreenTracker::activeWindowMaximizedChanged 0218 , this, &VisibilityManager::dodgeMaximized); 0219 0220 dodgeMaximized(); 0221 break; 0222 } 0223 0224 case Types::DodgeAllWindows: { 0225 m_connections[base] = connect(this, &VisibilityManager::containsMouseChanged 0226 , this, &VisibilityManager::dodgeAllWindows); 0227 0228 m_connections[base+1] = connect(m_latteView->windowsTracker()->currentScreen(), &TrackerPart::CurrentScreenTracker::existsWindowTouchingChanged 0229 , this, &VisibilityManager::dodgeAllWindows); 0230 0231 dodgeAllWindows(); 0232 break; 0233 } 0234 0235 case Types::WindowsGoBelow: 0236 break; 0237 0238 default: 0239 break; 0240 } 0241 0242 m_latteView->containment()->config().writeEntry("visibility", static_cast<int>(m_mode)); 0243 0244 updateKWinEdgesSupport(); 0245 0246 emit modeChanged(); 0247 } 0248 0249 void VisibilityManager::updateStrutsBasedOnLayoutsAndActivities(bool forceUpdate) 0250 { 0251 bool multipleLayoutsAndCurrent = (m_corona->layoutsManager()->memoryUsage() == Types::MultipleLayouts 0252 && m_latteView->layout() && !m_latteView->positioner()->inLocationChangeAnimation() 0253 && m_latteView->layout()->isCurrent()); 0254 0255 if (m_corona->layoutsManager()->memoryUsage() == Types::SingleLayout || multipleLayoutsAndCurrent) { 0256 QRect computedStruts = acceptableStruts(); 0257 if (m_publishedStruts != computedStruts || forceUpdate) { 0258 //! Force update is needed when very important events happen in DE and there is a chance 0259 //! that previously even though struts where sent the DE did not accept them. 0260 //! Such a case is when STOPPING an Activity and windows faulty become invisible even 0261 //! though they should not. In such case setting struts when the windows are hidden 0262 //! the struts do not take any effect 0263 m_publishedStruts = computedStruts; 0264 m_wm->setViewStruts(*m_latteView, m_publishedStruts, m_latteView->location()); 0265 } 0266 } else { 0267 m_publishedStruts = QRect(); 0268 m_wm->removeViewStruts(*m_latteView); 0269 } 0270 } 0271 0272 QRect VisibilityManager::acceptableStruts() 0273 { 0274 QRect calcs; 0275 0276 switch (m_latteView->location()) { 0277 case Plasma::Types::TopEdge: { 0278 calcs = QRect(m_latteView->x(), m_latteView->y(), m_latteView->width(), m_latteView->normalThickness()); 0279 break; 0280 } 0281 0282 case Plasma::Types::BottomEdge: { 0283 int y = m_latteView->y() + m_latteView->height() - m_latteView->normalThickness(); 0284 calcs = QRect(m_latteView->x(), y, m_latteView->width(), m_latteView->normalThickness()); 0285 break; 0286 } 0287 0288 case Plasma::Types::LeftEdge: { 0289 calcs = QRect(m_latteView->x(), m_latteView->y(), m_latteView->normalThickness(), m_latteView->height()); 0290 break; 0291 } 0292 0293 case Plasma::Types::RightEdge: { 0294 int x = m_latteView->x() + m_latteView->width() - m_latteView->normalThickness(); 0295 calcs = QRect(x, m_latteView->y(), m_latteView->normalThickness(), m_latteView->height()); 0296 break; 0297 } 0298 } 0299 0300 return calcs; 0301 } 0302 0303 bool VisibilityManager::raiseOnDesktop() const 0304 { 0305 return m_raiseOnDesktopChange; 0306 } 0307 0308 void VisibilityManager::setRaiseOnDesktop(bool enable) 0309 { 0310 if (enable == m_raiseOnDesktopChange) 0311 return; 0312 0313 m_raiseOnDesktopChange = enable; 0314 emit raiseOnDesktopChanged(); 0315 } 0316 0317 bool VisibilityManager::raiseOnActivity() const 0318 { 0319 return m_raiseOnActivityChange; 0320 } 0321 0322 void VisibilityManager::setRaiseOnActivity(bool enable) 0323 { 0324 if (enable == m_raiseOnActivityChange) 0325 return; 0326 0327 m_raiseOnActivityChange = enable; 0328 emit raiseOnActivityChanged(); 0329 } 0330 0331 bool VisibilityManager::isHidden() const 0332 { 0333 return m_isHidden; 0334 } 0335 0336 void VisibilityManager::setIsHidden(bool isHidden) 0337 { 0338 if (m_isHidden == isHidden) 0339 return; 0340 0341 if (m_blockHiding && isHidden) { 0342 qWarning() << "isHidden property is blocked, ignoring update"; 0343 return; 0344 } 0345 0346 m_isHidden = isHidden; 0347 0348 updateGhostWindowState(); 0349 0350 emit isHiddenChanged(); 0351 } 0352 0353 bool VisibilityManager::blockHiding() const 0354 { 0355 return m_blockHiding; 0356 } 0357 0358 void VisibilityManager::setBlockHiding(bool blockHiding) 0359 { 0360 if (m_blockHiding == blockHiding) { 0361 return; 0362 } 0363 0364 m_blockHiding = blockHiding; 0365 // qDebug() << "blockHiding:" << blockHiding; 0366 0367 if (m_blockHiding) { 0368 m_timerHide.stop(); 0369 0370 if (m_isHidden) { 0371 emit mustBeShown(); 0372 } 0373 } else { 0374 updateHiddenState(); 0375 } 0376 0377 emit blockHidingChanged(); 0378 } 0379 0380 int VisibilityManager::timerShow() const 0381 { 0382 return m_timerShow.interval(); 0383 } 0384 0385 void VisibilityManager::setTimerShow(int msec) 0386 { 0387 if (m_timerShow.interval() == msec) { 0388 return; 0389 } 0390 0391 m_timerShow.setInterval(msec); 0392 emit timerShowChanged(); 0393 } 0394 0395 int VisibilityManager::timerHide() const 0396 { 0397 return m_timerHide.interval(); 0398 } 0399 0400 void VisibilityManager::setTimerHide(int msec) 0401 { 0402 int interval = qMax(HIDEMINIMUMINTERVAL, msec); 0403 0404 if (m_timerHide.interval() == interval) { 0405 return; 0406 } 0407 0408 m_timerHide.setInterval(interval); 0409 emit timerHideChanged(); 0410 } 0411 0412 bool VisibilityManager::supportsKWinEdges() const 0413 { 0414 return (m_edgeGhostWindow != nullptr); 0415 } 0416 0417 void VisibilityManager::updateGhostWindowState() 0418 { 0419 if (supportsKWinEdges()) { 0420 bool inCurrentLayout = (m_corona->layoutsManager()->memoryUsage() == Types::SingleLayout || 0421 (m_corona->layoutsManager()->memoryUsage() == Types::MultipleLayouts 0422 && m_latteView->layout() && !m_latteView->positioner()->inLocationChangeAnimation() 0423 && m_latteView->layout()->isCurrent())); 0424 0425 if (inCurrentLayout) { 0426 m_wm->setActiveEdge(m_edgeGhostWindow, m_isHidden); 0427 } else { 0428 m_wm->setActiveEdge(m_edgeGhostWindow, false); 0429 } 0430 } 0431 } 0432 0433 void VisibilityManager::hide() 0434 { 0435 if (KWindowSystem::isPlatformX11()) { 0436 m_latteView->hide(); 0437 } 0438 } 0439 0440 void VisibilityManager::show() 0441 { 0442 if (KWindowSystem::isPlatformX11()) { 0443 m_latteView->show(); 0444 } 0445 } 0446 0447 0448 void VisibilityManager::raiseView(bool raise) 0449 { 0450 if (m_blockHiding) 0451 return; 0452 0453 if (raise) { 0454 m_timerHide.stop(); 0455 0456 if (!m_timerShow.isActive()) { 0457 m_timerShow.start(); 0458 } 0459 } else if (!m_dragEnter) { 0460 m_timerShow.stop(); 0461 0462 if (m_hideNow) { 0463 m_hideNow = false; 0464 emit mustBeHide(); 0465 } else if (!m_timerHide.isActive()) { 0466 m_timerHide.start(); 0467 } 0468 } 0469 } 0470 0471 void VisibilityManager::raiseViewTemporarily() 0472 { 0473 if (m_raiseTemporarily) 0474 return; 0475 0476 m_raiseTemporarily = true; 0477 m_timerHide.stop(); 0478 m_timerShow.stop(); 0479 0480 if (m_isHidden) 0481 emit mustBeShown(); 0482 0483 QTimer::singleShot(qBound(1800, 2 * m_timerHide.interval(), 3000), this, [&]() { 0484 m_raiseTemporarily = false; 0485 m_hideNow = true; 0486 updateHiddenState(); 0487 }); 0488 } 0489 0490 void VisibilityManager::updateHiddenState() 0491 { 0492 if (m_dragEnter) 0493 return; 0494 0495 switch (m_mode) { 0496 case Types::AutoHide: 0497 raiseView(m_containsMouse); 0498 break; 0499 0500 case Types::DodgeActive: 0501 dodgeActive(); 0502 break; 0503 0504 case Types::DodgeMaximized: 0505 dodgeMaximized(); 0506 break; 0507 0508 case Types::DodgeAllWindows: 0509 dodgeAllWindows(); 0510 break; 0511 0512 default: 0513 break; 0514 } 0515 } 0516 0517 void VisibilityManager::applyActivitiesToHiddenWindows(const QStringList &activities) 0518 { 0519 if (m_edgeGhostWindow) { 0520 m_wm->setWindowOnActivities(*m_edgeGhostWindow, activities); 0521 } 0522 } 0523 0524 void VisibilityManager::dodgeActive() 0525 { 0526 if (m_raiseTemporarily) 0527 return; 0528 0529 //!don't send false raiseView signal when containing mouse 0530 if (m_containsMouse) { 0531 raiseView(true); 0532 return; 0533 } 0534 0535 raiseView(!m_latteView->windowsTracker()->currentScreen()->activeWindowTouching()); 0536 } 0537 0538 void VisibilityManager::dodgeMaximized() 0539 { 0540 if (m_raiseTemporarily) 0541 return; 0542 0543 //!don't send false raiseView signal when containing mouse 0544 if (m_containsMouse) { 0545 raiseView(true); 0546 return; 0547 } 0548 0549 raiseView(!m_latteView->windowsTracker()->currentScreen()->activeWindowMaximized()); 0550 } 0551 0552 void VisibilityManager::dodgeAllWindows() 0553 { 0554 if (m_raiseTemporarily) 0555 return; 0556 0557 if (m_containsMouse) { 0558 raiseView(true); 0559 } 0560 0561 bool windowIntersects{m_latteView->windowsTracker()->currentScreen()->activeWindowTouching() || m_latteView->windowsTracker()->currentScreen()->existsWindowTouching()}; 0562 0563 raiseView(!windowIntersects); 0564 } 0565 0566 void VisibilityManager::saveConfig() 0567 { 0568 if (!m_latteView->containment()) 0569 return; 0570 0571 auto config = m_latteView->containment()->config(); 0572 0573 config.writeEntry("enableKWinEdges", m_enableKWinEdgesFromUser); 0574 config.writeEntry("timerShow", m_timerShow.interval()); 0575 config.writeEntry("timerHide", m_timerHide.interval()); 0576 config.writeEntry("raiseOnDesktopChange", m_raiseOnDesktopChange); 0577 config.writeEntry("raiseOnActivityChange", m_raiseOnActivityChange); 0578 0579 m_latteView->containment()->configNeedsSaving(); 0580 } 0581 0582 void VisibilityManager::restoreConfig() 0583 { 0584 if (!m_latteView || !m_latteView->containment()){ 0585 return; 0586 } 0587 0588 auto config = m_latteView->containment()->config(); 0589 m_timerShow.setInterval(config.readEntry("timerShow", 0)); 0590 m_timerHide.setInterval(qMax(HIDEMINIMUMINTERVAL, config.readEntry("timerHide", 700))); 0591 emit timerShowChanged(); 0592 emit timerHideChanged(); 0593 0594 m_enableKWinEdgesFromUser = config.readEntry("enableKWinEdges", true); 0595 emit enableKWinEdgesChanged(); 0596 0597 setRaiseOnDesktop(config.readEntry("raiseOnDesktopChange", false)); 0598 setRaiseOnActivity(config.readEntry("raiseOnActivityChange", false)); 0599 0600 auto storedMode = static_cast<Types::Visibility>(m_latteView->containment()->config().readEntry("visibility", static_cast<int>(Types::DodgeActive))); 0601 0602 if (storedMode == Types::AlwaysVisible) { 0603 qDebug() << "Loading visibility mode: Always Visible , on startup..."; 0604 setMode(Types::AlwaysVisible); 0605 } else { 0606 connect(&m_timerStartUp, &QTimer::timeout, this, [&]() { 0607 if (!m_latteView || !m_latteView->containment()) { 0608 return; 0609 } 0610 0611 auto fMode = static_cast<Types::Visibility>(m_latteView->containment()->config().readEntry("visibility", static_cast<int>(Types::DodgeActive))); 0612 qDebug() << "Loading visibility mode:" << fMode << " on startup..."; 0613 setMode(fMode); 0614 }); 0615 connect(m_latteView->containment(), &Plasma::Containment::userConfiguringChanged 0616 , this, [&](bool configuring) { 0617 if (configuring && m_timerStartUp.isActive()) 0618 m_timerStartUp.start(100); 0619 }); 0620 0621 m_timerStartUp.start(); 0622 } 0623 0624 connect(m_latteView->containment(), &Plasma::Containment::userConfiguringChanged 0625 , this, [&](bool configuring) { 0626 if (!configuring) { 0627 saveConfig(); 0628 } 0629 }); 0630 } 0631 0632 bool VisibilityManager::containsMouse() const 0633 { 0634 return m_containsMouse; 0635 } 0636 0637 void VisibilityManager::setContainsMouse(bool contains) 0638 { 0639 if (m_containsMouse == contains) { 0640 return; 0641 } 0642 0643 m_containsMouse = contains; 0644 emit containsMouseChanged(); 0645 0646 if (contains && m_mode != Types::AlwaysVisible) { 0647 raiseView(true); 0648 } 0649 } 0650 0651 void VisibilityManager::viewEventManager(QEvent *ev) 0652 { 0653 switch (ev->type()) { 0654 case QEvent::Enter: 0655 setContainsMouse(true); 0656 break; 0657 0658 case QEvent::Leave: 0659 m_dragEnter = false; 0660 setContainsMouse(false); 0661 break; 0662 0663 case QEvent::DragEnter: 0664 m_dragEnter = true; 0665 0666 if (m_isHidden) { 0667 emit mustBeShown(); 0668 } 0669 0670 break; 0671 0672 case QEvent::DragLeave: 0673 case QEvent::Drop: 0674 m_dragEnter = false; 0675 updateHiddenState(); 0676 break; 0677 0678 default: 0679 break; 0680 } 0681 } 0682 0683 //! KWin Edges Support functions 0684 bool VisibilityManager::enableKWinEdges() const 0685 { 0686 return m_enableKWinEdgesFromUser; 0687 } 0688 0689 void VisibilityManager::setEnableKWinEdges(bool enable) 0690 { 0691 if (m_enableKWinEdgesFromUser == enable) { 0692 return; 0693 } 0694 0695 m_enableKWinEdgesFromUser = enable; 0696 0697 emit enableKWinEdgesChanged(); 0698 } 0699 0700 void VisibilityManager::updateKWinEdgesSupport() 0701 { 0702 if ((m_mode == Types::AutoHide 0703 || m_mode == Types::DodgeActive 0704 || m_mode == Types::DodgeAllWindows 0705 || m_mode == Types::DodgeMaximized) 0706 && (!m_latteView->byPassWM()) ) { 0707 if (m_enableKWinEdgesFromUser) { 0708 createEdgeGhostWindow(); 0709 } else if (!m_enableKWinEdgesFromUser) { 0710 deleteEdgeGhostWindow(); 0711 } 0712 } else if (m_mode == Types::AlwaysVisible 0713 || m_mode == Types::WindowsGoBelow) { 0714 deleteEdgeGhostWindow(); 0715 } 0716 } 0717 0718 void VisibilityManager::createEdgeGhostWindow() 0719 { 0720 if (!m_edgeGhostWindow) { 0721 m_edgeGhostWindow = new ScreenEdgeGhostWindow(m_latteView); 0722 0723 m_wm->setViewExtraFlags(*m_edgeGhostWindow); 0724 0725 connect(m_edgeGhostWindow, &ScreenEdgeGhostWindow::containsMouseChanged, this, [ = ](bool contains) { 0726 if (contains) { 0727 raiseView(true); 0728 } else { 0729 m_timerShow.stop(); 0730 updateGhostWindowState(); 0731 } 0732 }); 0733 0734 connect(m_edgeGhostWindow, &ScreenEdgeGhostWindow::dragEntered, this, [&]() { 0735 if (m_isHidden) { 0736 emit mustBeShown(); 0737 } 0738 }); 0739 0740 m_connectionsKWinEdges[0] = connect(m_wm, &WindowSystem::AbstractWindowInterface::currentActivityChanged, 0741 this, [&]() { 0742 bool inCurrentLayout = (m_corona->layoutsManager()->memoryUsage() == Types::SingleLayout || 0743 (m_corona->layoutsManager()->memoryUsage() == Types::MultipleLayouts 0744 && m_latteView->layout() && !m_latteView->positioner()->inLocationChangeAnimation() 0745 && m_latteView->layout()->isCurrent())); 0746 0747 if (m_edgeGhostWindow) { 0748 if (inCurrentLayout) { 0749 m_wm->setActiveEdge(m_edgeGhostWindow, m_isHidden); 0750 } else { 0751 m_wm->setActiveEdge(m_edgeGhostWindow, false); 0752 } 0753 } 0754 }); 0755 0756 emit supportsKWinEdgesChanged(); 0757 } 0758 } 0759 0760 void VisibilityManager::deleteEdgeGhostWindow() 0761 { 0762 if (m_edgeGhostWindow) { 0763 m_edgeGhostWindow->deleteLater(); 0764 m_edgeGhostWindow = nullptr; 0765 0766 for (auto &c : m_connectionsKWinEdges) { 0767 disconnect(c); 0768 } 0769 0770 emit supportsKWinEdgesChanged(); 0771 } 0772 } 0773 0774 //! END: VisibilityManager implementation 0775 0776 } 0777 }