feat(panel-next):实现智能隐藏和自动隐藏功能
This commit is contained in:
parent
96b2f95c44
commit
a1551c3a13
|
@ -193,6 +193,7 @@ PanelTopBar* Shell::createPanelTopBar(Screen* screen, const QString& id)
|
|||
connect(panelTopBar, &PanelTopBar::islandRemoved, this, &Shell::islandRemovedFromTopBar);
|
||||
connect(this, &Shell::islandRemovedFromPanel, panelTopBar, &PanelTopBar::addIsland);
|
||||
connect(this, &Shell::islandRemovedFromTopBar, panelTopBar, &PanelTopBar::removeIsland);
|
||||
return panelTopBar;
|
||||
}
|
||||
|
||||
Shell::PanelType Shell::currentVersion()
|
||||
|
|
|
@ -23,6 +23,7 @@
|
|||
#include <KWindowEffects>
|
||||
#include <QGSettings>
|
||||
#include <app-launcher.h>
|
||||
#include <window-manager.h>
|
||||
#include "panel-next.h"
|
||||
#include "widget-model.h"
|
||||
#include "shell.h"
|
||||
|
@ -30,6 +31,45 @@
|
|||
#define DEFAULT_PANEL_SIZE 48
|
||||
|
||||
namespace UkuiPanel {
|
||||
using WindowManager = UkuiQuick::WindowManager;
|
||||
|
||||
void AutoHideHelper::setScreen(Screen* screen)
|
||||
{
|
||||
m_screen = screen;
|
||||
update();
|
||||
}
|
||||
|
||||
bool AutoHideHelper::needAutoHide()
|
||||
{
|
||||
return m_needAutoHide;
|
||||
}
|
||||
|
||||
void AutoHideHelper::update()
|
||||
{
|
||||
auto wid = WindowManager::currentActiveWindow();
|
||||
bool maximized = WindowManager::isMaximized(wid);
|
||||
bool needAutoHide = false;
|
||||
if(maximized && m_screen->internal()->geometry().contains(WindowManager::geometry(wid).center())) {
|
||||
needAutoHide = true;
|
||||
} else {
|
||||
needAutoHide = false;
|
||||
}
|
||||
if(m_needAutoHide != needAutoHide) {
|
||||
m_needAutoHide = needAutoHide;
|
||||
|
||||
Q_EMIT autoHideStateChanged(m_needAutoHide);
|
||||
}
|
||||
}
|
||||
|
||||
AutoHideHelper::AutoHideHelper(Screen *screen, QObject* parent): QObject(parent)
|
||||
{
|
||||
m_screen = screen;
|
||||
update();
|
||||
connect(WindowManager::self(), &WindowManager::activeWindowChanged, this, &AutoHideHelper::update);
|
||||
connect(WindowManager::self(), &WindowManager::maximizedChanged, this, &AutoHideHelper::update);
|
||||
connect(WindowManager::self(), &WindowManager::geometryChanged, this, &AutoHideHelper::update);
|
||||
}
|
||||
|
||||
PanelNext::PanelNext(Screen* screen, const QString&id, QWindow* parent): UkuiQuick::IslandView(
|
||||
QStringLiteral("panel"),
|
||||
QStringLiteral("ukui-panel")),
|
||||
|
@ -45,6 +85,23 @@ PanelNext::PanelNext(Screen* screen, const QString&id, QWindow* parent): UkuiQui
|
|||
setFlags(flags() | Qt::FramelessWindowHint | Qt::WindowStaysOnTopHint | Qt::WindowDoesNotAcceptFocus);
|
||||
m_windowProxy = new UkuiQuick::WindowProxy(this);
|
||||
m_windowProxy->setWindowType(UkuiQuick::WindowType::Dock);
|
||||
m_windowProxy->setPanelAutoHide(true);
|
||||
m_autoHideHelper = new AutoHideHelper(screen, this);
|
||||
m_needHide = m_autoHideHelper->needAutoHide();
|
||||
//关闭自动隐藏是,任务栏根据当前是否有最大化窗口激活决定是否隐藏
|
||||
connect(m_autoHideHelper, &AutoHideHelper::autoHideStateChanged, this, [this](bool hide) {
|
||||
m_needHide = hide;
|
||||
//开启自动隐藏时,只考虑自动隐藏逻辑,不考虑是否有最大化窗口
|
||||
if(m_autoHide) {
|
||||
return;
|
||||
}
|
||||
if (m_needHide && !m_containsMouse && !mainView()->active()) {
|
||||
activeHideTimer();
|
||||
} else {
|
||||
activeHideTimer(false);
|
||||
setHidden(false);
|
||||
}
|
||||
});
|
||||
initMainContainer();
|
||||
setPanelScreen(screen);
|
||||
initConfig();
|
||||
|
@ -59,6 +116,7 @@ PanelNext::PanelNext(Screen* screen, const QString&id, QWindow* parent): UkuiQui
|
|||
connect(m_hideTimer, &QTimer::timeout, this, [this] {
|
||||
setHidden(true);
|
||||
});
|
||||
setAutoHide(m_autoHideHelper->needAutoHide());
|
||||
}
|
||||
|
||||
PanelNext::~PanelNext()
|
||||
|
@ -186,6 +244,7 @@ void PanelNext::setPanelScreen(Screen* screen)
|
|||
mainView()->setScreen(screen->internal());
|
||||
updateGeometry();
|
||||
connect(screen, &Screen::geometryChanged, this, &PanelNext::onScreenGeometryChanged);
|
||||
m_autoHideHelper->setScreen(screen);
|
||||
}
|
||||
|
||||
bool PanelNext::lockPanel() const
|
||||
|
@ -198,15 +257,15 @@ bool PanelNext::enableCustomSize() const
|
|||
return m_sizePolicy == GeneralConfigDefine::Custom;
|
||||
}
|
||||
|
||||
void PanelNext::addIsland(const QString& id)
|
||||
void PanelNext::addIsland(const QString&id)
|
||||
{
|
||||
changeForm(id, GeneralConfigDefine::Island);
|
||||
updateIslandFormAction();
|
||||
}
|
||||
|
||||
void PanelNext::removeIsland(const QString& id)
|
||||
void PanelNext::removeIsland(const QString&id)
|
||||
{
|
||||
if(m_islands.contains(id)){
|
||||
if (m_islands.contains(id)) {
|
||||
mainView()->addDisableInstance(m_islands.value(id)->instanceId());
|
||||
m_islands.remove(id);
|
||||
}
|
||||
|
@ -222,7 +281,6 @@ void PanelNext::updateGeometry()
|
|||
{
|
||||
refreshRect();
|
||||
updateMask();
|
||||
resetWorkArea(true);
|
||||
}
|
||||
|
||||
void PanelNext::initConfig()
|
||||
|
@ -353,6 +411,14 @@ void PanelNext::setPosition(UkuiQuick::Types::Pos position)
|
|||
|
||||
void PanelNext::onContainerActiveChanged()
|
||||
{
|
||||
if (mainView()->active()) {
|
||||
activeHideTimer(false);
|
||||
setHidden(false);
|
||||
} else {
|
||||
if ((m_autoHide || m_needHide) && !m_containsMouse && !mainView()->active()) {
|
||||
activeHideTimer();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void PanelNext::refreshRect()
|
||||
|
@ -416,33 +482,6 @@ void PanelNext::refreshRect()
|
|||
m_unavailableArea = unavailableArea;
|
||||
}
|
||||
|
||||
void PanelNext::resetWorkArea(bool cut)
|
||||
{
|
||||
if (cut) {
|
||||
// 为窗管添加不可显示区域
|
||||
KWindowSystem::setExtendedStrut(winId(),
|
||||
m_unavailableArea.leftWidth, m_unavailableArea.leftStart,
|
||||
m_unavailableArea.leftEnd,
|
||||
m_unavailableArea.rightWidth, m_unavailableArea.rightStart,
|
||||
m_unavailableArea.rightEnd,
|
||||
m_unavailableArea.topWidth, m_unavailableArea.topStart,
|
||||
m_unavailableArea.topEnd,
|
||||
m_unavailableArea.bottomWidth, m_unavailableArea.bottomStart,
|
||||
m_unavailableArea.bottomEnd
|
||||
);
|
||||
|
||||
m_windowProxy->setPanelAutoHide(false);
|
||||
}
|
||||
else {
|
||||
// 为窗管移除不可显示区域
|
||||
KWindowSystem::setExtendedStrut(winId(), 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0
|
||||
);
|
||||
|
||||
m_windowProxy->setPanelAutoHide(true);
|
||||
}
|
||||
}
|
||||
|
||||
void PanelNext::updateMask()
|
||||
{
|
||||
QRegion mask;
|
||||
|
@ -756,18 +795,18 @@ void PanelNext::updateIslandFormAction()
|
|||
{
|
||||
bool containDataIsland = false;
|
||||
bool containSettingsIsland = false;
|
||||
for(auto island : m_islands) {
|
||||
if(island->id() == QStringLiteral("org.ukui.dataIsland")) {
|
||||
for (auto island: m_islands) {
|
||||
if (island->id() == QStringLiteral("org.ukui.dataIsland")) {
|
||||
containDataIsland = true;
|
||||
} else if(island->id() == QStringLiteral("org.ukui.settingsIsland")) {
|
||||
} else if (island->id() == QStringLiteral("org.ukui.settingsIsland")) {
|
||||
containSettingsIsland = true;
|
||||
}
|
||||
}
|
||||
for(auto action : m_dataIslandFormAction->menu()->actions()) {
|
||||
for (auto action: m_dataIslandFormAction->menu()->actions()) {
|
||||
auto form = action->property("form").value<GeneralConfigDefine::IslandsForm>();
|
||||
action->setChecked(form == GeneralConfigDefine::IslandsForm::Island && containDataIsland);
|
||||
}
|
||||
for(auto action : m_settingsIslandFormAction->menu()->actions()) {
|
||||
for (auto action: m_settingsIslandFormAction->menu()->actions()) {
|
||||
auto form = action->property("form").value<GeneralConfigDefine::IslandsForm>();
|
||||
action->setChecked(form == GeneralConfigDefine::IslandsForm::Island && containSettingsIsland);
|
||||
}
|
||||
|
@ -775,14 +814,17 @@ void PanelNext::updateIslandFormAction()
|
|||
|
||||
void PanelNext::setAutoHide(bool autoHide)
|
||||
{
|
||||
if(m_autoHide == autoHide) {
|
||||
if (m_autoHide == autoHide) {
|
||||
return;
|
||||
}
|
||||
m_autoHide = autoHide;
|
||||
|
||||
activeHideTimer(false);
|
||||
setHidden(m_autoHide);
|
||||
resetWorkArea(!m_autoHide);
|
||||
if ((m_autoHide || m_needHide) && !m_containsMouse) {
|
||||
activeHideTimer();
|
||||
} else {
|
||||
activeHideTimer(false);
|
||||
setHidden(false);
|
||||
}
|
||||
|
||||
if (m_autoHideAction) {
|
||||
m_autoHideAction->setChecked(m_autoHide);
|
||||
|
@ -828,16 +870,16 @@ bool PanelNext::event(QEvent* e)
|
|||
{
|
||||
switch (e->type()) {
|
||||
case QEvent::Leave: {
|
||||
if (m_autoHide && !m_isHidden && !mainView()->active()) {
|
||||
m_containsMouse = false;
|
||||
if ((m_autoHide || m_needHide) && !m_isHidden && !mainView()->active()) {
|
||||
activeHideTimer();
|
||||
}
|
||||
break;
|
||||
}
|
||||
case QEvent::Enter: {
|
||||
if (m_autoHide) {
|
||||
activeHideTimer(false);
|
||||
setHidden(false);
|
||||
}
|
||||
m_containsMouse = true;
|
||||
activeHideTimer(false);
|
||||
setHidden(false);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
|
@ -854,22 +896,22 @@ void PanelNext::onBlurRegionChanged(QRegion region)
|
|||
}
|
||||
}
|
||||
|
||||
void PanelNext::changeForm(const QString& id, GeneralConfigDefine::IslandsForm form)
|
||||
void PanelNext::changeForm(const QString&id, GeneralConfigDefine::IslandsForm form)
|
||||
{
|
||||
if(form == GeneralConfigDefine::IslandsForm::TopBar) {
|
||||
if(m_islands.contains(id)) {
|
||||
if (form == GeneralConfigDefine::IslandsForm::TopBar) {
|
||||
if (m_islands.contains(id)) {
|
||||
mainView()->addDisableInstance(m_islands.value(id)->config()->id().toInt());
|
||||
m_islands.remove(id);
|
||||
Q_EMIT islandRemoved(id);
|
||||
}
|
||||
} else {
|
||||
if(!m_islands.contains(id)) {
|
||||
for (auto config : mainView()->config()->children(QStringLiteral("widgets"))) {
|
||||
if(config->getValue(QStringLiteral("id")).toString() == id) {
|
||||
if (!m_islands.contains(id)) {
|
||||
for (auto config: mainView()->config()->children(QStringLiteral("widgets"))) {
|
||||
if (config->getValue(QStringLiteral("id")).toString() == id) {
|
||||
mainView()->removeDisableInstance(config->id().toInt());
|
||||
mainView()->addWidget(id, config->id().toInt());
|
||||
for (UkuiQuick::Widget* w: mainView()->widgets()) {
|
||||
if(w->id() == id) {
|
||||
if (w->id() == id) {
|
||||
if (id == QStringLiteral("org.ukui.dataIsland")) {
|
||||
w->setActions(m_dataIslandActions);
|
||||
} else if (id == QStringLiteral("org.ukui.settingsIsland")) {
|
||||
|
@ -883,7 +925,6 @@ void PanelNext::changeForm(const QString& id, GeneralConfigDefine::IslandsForm f
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
} // UkuiPanel
|
||||
|
|
|
@ -31,6 +31,24 @@
|
|||
#include "blur-region-helper.h"
|
||||
|
||||
namespace UkuiPanel {
|
||||
class AutoHideHelper : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit AutoHideHelper(Screen *screen, QObject* parent = nullptr);
|
||||
void setScreen(Screen *screen);
|
||||
bool needAutoHide();
|
||||
|
||||
private:
|
||||
void update();
|
||||
Screen *m_screen = nullptr;
|
||||
bool m_needAutoHide = false;
|
||||
QString m_activeWindow;
|
||||
|
||||
Q_SIGNALS:
|
||||
void autoHideStateChanged(bool);
|
||||
};
|
||||
class PanelNext : public UkuiQuick::IslandView
|
||||
{
|
||||
Q_OBJECT
|
||||
|
@ -64,8 +82,6 @@ private Q_SLOTS:
|
|||
|
||||
void onContainerActiveChanged();
|
||||
|
||||
void resetWorkArea(bool cut);
|
||||
|
||||
void setPanelSize(int size);
|
||||
|
||||
void setLockPanel(bool locked, bool noEmit = false);
|
||||
|
@ -123,8 +139,9 @@ private:
|
|||
QAction* m_dataIslandFormAction{nullptr};
|
||||
QAction* m_settingsIslandFormAction{nullptr};
|
||||
|
||||
bool m_isHidden = false;
|
||||
bool m_autoHide = false;
|
||||
bool m_isHidden = false;//当前是否已经隐藏
|
||||
bool m_autoHide = false;//是否自动隐藏(鼠标离开任务栏区域即隐藏)
|
||||
bool m_needHide = false;//当前是否有激活的最大化窗口需要任务栏隐藏
|
||||
bool m_lockPanel = false;
|
||||
QTimer* m_hideTimer = nullptr;
|
||||
QMap<QString, UkuiQuick::WidgetContainer *> m_islands;
|
||||
|
@ -133,6 +150,8 @@ private:
|
|||
QList<QAction *> m_appIslandActions;
|
||||
QList<QAction *> m_settingsIslandActions;
|
||||
QList<QMenu *> m_menus; //用于QMenu的统一销毁
|
||||
AutoHideHelper *m_autoHideHelper = nullptr;
|
||||
bool m_containsMouse = false;
|
||||
|
||||
};
|
||||
} // UkuiPanel
|
||||
|
|
Loading…
Reference in New Issue