feat(panel-next):实现智能隐藏和自动隐藏功能

This commit is contained in:
iaom 2024-08-21 15:36:21 +08:00
parent 96b2f95c44
commit a1551c3a13
3 changed files with 118 additions and 57 deletions

View File

@ -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()

View File

@ -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;
if ((m_autoHide || m_needHide) && !m_containsMouse) {
activeHideTimer();
} else {
activeHideTimer(false);
setHidden(m_autoHide);
resetWorkArea(!m_autoHide);
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) {
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

View File

@ -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