!49 解决wayland下任务栏dock属性丢失问题,任务栏无法隐藏问题,适配kscreen

Merge pull request !49 from 卜萧庆/fix-hide
This commit is contained in:
何朴尧 2023-04-04 07:10:12 +00:00 committed by Gitee
commit 1bb86410d3
No known key found for this signature in database
GPG Key ID: 173E9B9CA92EEF8F
3 changed files with 159 additions and 124 deletions

View File

@ -15,7 +15,6 @@ set(PRIV_HEADERS
ukuipanellayout.h ukuipanellayout.h
plugin.h plugin.h
pluginsettings_p.h pluginsettings_p.h
# highlight-effect.h
) )
# using UKUi namespace in the public headers. # using UKUi namespace in the public headers.
@ -59,7 +58,6 @@ set(SOURCES
common_fun/dbus-adaptor.cpp common_fun/dbus-adaptor.cpp
common_fun/panel_commission.cpp common_fun/panel_commission.cpp
customstyle.cpp customstyle.cpp
# highlight-effect.cpp
) )
file(GLOB CONFIG_FILES resources/*.conf resources/*.qss) file(GLOB CONFIG_FILES resources/*.conf resources/*.qss)

View File

@ -52,9 +52,10 @@
#include <KWindowSystem/KWindowSystem> #include <KWindowSystem/KWindowSystem>
#include <KWindowSystem/NETWM> #include <KWindowSystem/NETWM>
#include <KF5/KScreen/kscreen/output.h>
#include <KF5/KScreen/kscreen/configmonitor.h>
#include <QGSettings> #include <QGSettings>
// Turn on this to show the time required to load each plugin during startup
// #define DEBUG_PLUGIN_LOADTIME
#include "common_fun/ukuipanel_infomation.h" #include "common_fun/ukuipanel_infomation.h"
#include "common_fun/dbus-adaptor.h" #include "common_fun/dbus-adaptor.h"
@ -181,6 +182,13 @@ UKUIPanel::UKUIPanel(const QString &configGroup, UKUi::Settings *settings, QWidg
!con.registerObject("/panel/position",dbus)) { !con.registerObject("/panel/position",dbus)) {
qDebug() << "fail" << con.lastError().message(); qDebug() << "fail" << con.lastError().message();
} }
//初始化判断是否为wayland环境如果是wayland,则任务栏隐藏无动画,且鼠标再次移开任务栏的隐藏操作需要特殊处理
QString platform = QGuiApplication::platformName();
if(platform.startsWith(QLatin1String("wayland"),Qt::CaseInsensitive)) {
m_isWaylandEnv =true;
} else {
m_isWaylandEnv = false;
}
//UKUIPanel (inherits QFrame) -> lav (QGridLayout) -> UKUIPanelWidget (QFrame) -> UKUIPanelLayout //UKUIPanel (inherits QFrame) -> lav (QGridLayout) -> UKUIPanelWidget (QFrame) -> UKUIPanelLayout
UKUIPanelWidget = new QFrame(this); UKUIPanelWidget = new QFrame(this);
@ -214,15 +222,16 @@ UKUIPanel::UKUIPanel(const QString &configGroup, UKUi::Settings *settings, QWidg
*/ */
connect(QApplication::desktop(), &QDesktopWidget::resized, this, &UKUIPanel::ensureVisible); connect(QApplication::desktop(), &QDesktopWidget::resized, this, &UKUIPanel::ensureVisible);
connect(QApplication::desktop(), &QDesktopWidget::screenCountChanged, this, &UKUIPanel::ensureVisible); connect(QApplication::desktop(), &QDesktopWidget::screenCountChanged, this, &UKUIPanel::ensureVisible);
connect(qApp,&QApplication::primaryScreenChanged,this,&UKUIPanel::ensureVisible);
// connecting to QDesktopWidget::workAreaResized shouldn't be necessary, // connecting to QDesktopWidget::workAreaResized shouldn't be necessary,
// as we've already connceted to QDesktopWidget::resized, but it actually // as we've already connceted to QDesktopWidget::resized, but it actually
connect(QApplication::desktop(), &QDesktopWidget::workAreaResized, connect(QApplication::desktop(), &QDesktopWidget::workAreaResized,
this, &UKUIPanel::ensureVisible); this, &UKUIPanel::ensureVisible);
UKUIPanelApplication *a = reinterpret_cast<UKUIPanelApplication*>(qApp); UKUIPanelApplication *a = reinterpret_cast<UKUIPanelApplication*>(qApp);
connect(a, &UKUIPanelApplication::primaryScreenChanged, [=]{ m_primaryScreenGeometry = QGuiApplication::screens().at(0)->geometry();
setPanelGeometry(); KScreen::GetConfigOperation *op = new KScreen::GetConfigOperation();
connect(op, &KScreen::GetConfigOperation::finished, this, [this](KScreen::ConfigOperation *op) {
configWatch(op);
}); });
connect(UKUi::Settings::globalSettings(), SIGNAL(settingsChanged()), this, SLOT(update())); connect(UKUi::Settings::globalSettings(), SIGNAL(settingsChanged()), this, SLOT(update()));
@ -289,7 +298,7 @@ UKUIPanel::UKUIPanel(const QString &configGroup, UKUi::Settings *settings, QWidg
// show it the first time, despite setting // show it the first time, despite setting
if (m_hidable) { if (m_hidable) {
showPanel(false); showPanel(false);
QTimer::singleShot(PANEL_HIDE_FIRST_TIME, this, SLOT(hidePanel())); hidePanel();
} }
styleAdjust(); styleAdjust();
@ -297,12 +306,49 @@ UKUIPanel::UKUIPanel(const QString &configGroup, UKUi::Settings *settings, QWidg
} }
void UKUIPanel::configWatch(KScreen::ConfigOperation *op)
{
m_config = op->config();
KScreen::ConfigMonitor::instance()->addConfig(m_config);
connect(m_config.data(), &KScreen::Config::primaryOutputChanged,
this, [=](const KScreen::OutputPtr &output){
if (!output.isNull()) {
qDebug() << "primaryOutputChanged:" << output->name() << output->geometry();
m_primaryScreenGeometry = output->geometry();
QRect rect = caculPanelGeometry(output->geometry());
qDebug()<<"primaryOutputChanged panel rect is"<<rect;
kdk::WindowManager::setGeometry(this->windowHandle(), rect);
realign();
}
});
connect(m_config.data(), &KScreen::Config::outputAdded,
this, [=](const KScreen::OutputPtr &output){
if (!output.isNull()) {
KScreen::OutputPtr primary = m_config->primaryOutput();
m_primaryScreenGeometry = primary->geometry();
qDebug()<<"output added primary geometry is"<<primary->geometry();
QRect rect = caculPanelGeometry(primary->geometry());
qDebug()<<"output added panel rect is"<<rect;
kdk::WindowManager::setGeometry(this->windowHandle(), rect);
}
});
connect(m_config.data(), &KScreen::Config::outputRemoved,
this, [=](){
qDebug() << "output removed";
});
}
void UKUIPanel::setPanelHide(bool model) void UKUIPanel::setPanelHide(bool model)
{ {
if (model) { if (model) {
hide(); hide();
} else { } else {
//切换平板模式任务栏hide后再切回来任务栏的surface发生了改变。wayland下需要重新设置dock属性
setAttribute(Qt::WA_X11NetWmWindowTypeDock);
show(); show();
KWindowSystem::setType(effectiveWinId(), NET::Dock);
realign(); realign();
} }
} }
@ -499,6 +545,73 @@ void UKUIPanel::priScreenChanged(int x, int y, int width, int height)
realign(); realign();
} }
QRect UKUIPanel::caculPanelGeometry(QRect primaryscreen)
{
QRect rect;
if (isHorizontal()) {
rect.setHeight(qMax(PANEL_MINIMUM_SIZE, m_panelSize));
rect.setWidth(primaryscreen.width());
rect.setWidth(qMax(rect.size().width(), m_layout->minimumSize().width()));
// Horiz panel***************************
if (m_position == IUKUIPanel::PositionTop) {
if (m_hidden) {
rect.moveBottom(primaryscreen.top() + PANEL_HIDE_SIZE);
rect.setX(primaryscreen.x());
rect.setY(primaryscreen.y() - rect.height() + PANEL_HIDE_SIZE);
}else {
rect.moveTop(primaryscreen.top());
rect.setX(primaryscreen.x());
rect.setY(primaryscreen.y());
rect.setWidth(primaryscreen.width());
}
} else {
if (m_hidden) {
rect.moveTop(primaryscreen.bottom() - PANEL_HIDE_SIZE);
rect.setX(primaryscreen.x());
rect.setY(primaryscreen.y() + primaryscreen.height() - PANEL_HIDE_SIZE);
}else {
rect.moveBottom(primaryscreen.bottom());
rect.setX(primaryscreen.x());
rect.setY(primaryscreen.y() + primaryscreen.height() - m_panelSize);
rect.setWidth(primaryscreen.width());
}
}
} else {
// Vert panel ***************************
rect.setWidth(qMax(PANEL_MINIMUM_SIZE, m_panelSize));
rect.setHeight(primaryscreen.height());
rect.setHeight(qMax(rect.size().height(), m_layout->minimumSize().height()));
if (m_position == IUKUIPanel::PositionLeft) {
if (m_hidden) {
rect.moveRight(primaryscreen.left() + PANEL_HIDE_SIZE);
rect.setX(primaryscreen.x() - rect.width() + PANEL_HIDE_SIZE);
rect.setY(primaryscreen.y());
}else {
rect.moveLeft(primaryscreen.left());
rect.setX(primaryscreen.x());
rect.setY(primaryscreen.y());
rect.setHeight(primaryscreen.height());
}
} else {
if (m_hidden) {
rect.moveLeft(primaryscreen.right() - PANEL_HIDE_SIZE);
rect.setX(primaryscreen.x() + primaryscreen.width() + m_panelSize - PANEL_HIDE_SIZE);
rect.setY(primaryscreen.y());
}else {
rect.moveRight(primaryscreen.right());
rect.setX(primaryscreen.x() + primaryscreen.width() - m_panelSize);
rect.setY(primaryscreen.y());
rect.setHeight(primaryscreen.height());
}
}
}
qDebug()<<"ukui-panel Rect is :"<<rect;
return rect;
}
/* /*
The setting frame of the old panel does not follow the main screen The setting frame of the old panel does not follow the main screen
but can be displayed on any screen but can be displayed on any screen
@ -507,112 +620,11 @@ void UKUIPanel::priScreenChanged(int x, int y, int width, int height)
*/ */
void UKUIPanel::setPanelGeometry(bool animate) void UKUIPanel::setPanelGeometry(bool animate)
{ {
QRect currentScreen; QRect rect = caculPanelGeometry(m_primaryScreenGeometry);
QRect rect;
currentScreen=QGuiApplication::screens().at(0)->geometry();
if (isHorizontal()) {
rect.setHeight(qMax(PANEL_MINIMUM_SIZE, m_panelSize));
if (m_lengthInPercents)
rect.setWidth(currentScreen.width() * m_length / 100.0);
else{
if (m_length <= 0)
rect.setWidth(currentScreen.width() + m_length);
else
rect.setWidth(m_length);
}
rect.setWidth(qMax(rect.size().width(), m_layout->minimumSize().width()));
// Horiz ......................
switch (m_alignment)
{
case UKUIPanel::AlignmentLeft:
rect.moveLeft(currentScreen.left());
break;
case UKUIPanel::AlignmentCenter:
rect.moveCenter(currentScreen.center());
break;
case UKUIPanel::AlignmentRight:
rect.moveRight(currentScreen.right());
break;
}
// Vert .......................
if (m_position == IUKUIPanel::PositionTop) {
if (m_hidden)
rect.moveBottom(currentScreen.top() + PANEL_HIDE_SIZE);
else
rect.moveTop(currentScreen.top());
} else {
if (m_hidden)
rect.moveTop(currentScreen.bottom() - PANEL_HIDE_SIZE);
else
rect.moveBottom(currentScreen.bottom());
}
} else {
// Vert panel ***************************
rect.setWidth(qMax(PANEL_MINIMUM_SIZE, m_panelSize));
if (m_lengthInPercents)
rect.setHeight(currentScreen.height() * m_length / 100.0);
else {
if (m_length <= 0)
rect.setHeight(currentScreen.height() + m_length);
else
rect.setHeight(m_length);
}
rect.setHeight(qMax(rect.size().height(), m_layout->minimumSize().height()));
// Vert .......................
switch (m_alignment)
{
case UKUIPanel::AlignmentLeft:
rect.moveTop(currentScreen.top());
break;
case UKUIPanel::AlignmentCenter:
rect.moveCenter(currentScreen.center());
break;
case UKUIPanel::AlignmentRight:
rect.moveBottom(currentScreen.bottom());
break;
}
// Horiz ......................
if (m_position == IUKUIPanel::PositionLeft) {
if (m_hidden)
rect.moveRight(currentScreen.left() + PANEL_HIDE_SIZE);
else
rect.moveLeft(currentScreen.left());
} else {
if (m_hidden)
rect.moveLeft(currentScreen.right() - PANEL_HIDE_SIZE);
else
rect.moveRight(currentScreen.right());
}
}
qDebug()<<"ukui-panel Rect is :"<<rect;
if (rect != geometry()) { if (rect != geometry()) {
setFixedSize(rect.size()); setFixedSize(rect.size());
if (animate) { if (animate && !m_isWaylandEnv) {
if (m_animation == nullptr) { setPanelAnimation(geometry(), rect);
m_animation = new QPropertyAnimation(this, "geometry");
m_animation->setEasingCurve(QEasingCurve::Linear);
//Note: for hiding, the margins are set after animation is finished
connect(m_animation, &QAbstractAnimation::finished, [this] { if (m_hidden) setMargins(); });
}
m_animation->setDuration(m_animationTime);
m_animation->setStartValue(geometry());
m_animation->setEndValue(rect);
//Note: for showing-up, the margins are removed instantly
if (!m_hidden)
setMargins();
m_animation->start();
} else { } else {
setMargins(); setMargins();
kdk::WindowManager::setGeometry(this->windowHandle(), rect); kdk::WindowManager::setGeometry(this->windowHandle(), rect);
@ -620,16 +632,34 @@ void UKUIPanel::setPanelGeometry(bool animate)
} }
QDBusMessage message =QDBusMessage::createSignal("/panel/position", "org.ukui.panel", "UKuiPanelPosition"); QDBusMessage message =QDBusMessage::createSignal("/panel/position", "org.ukui.panel", "UKuiPanelPosition");
QList<QVariant> args; QList<QVariant> args;
args.append(currentScreen.x()); args.append(m_primaryScreenGeometry.x());
args.append(currentScreen.y()); args.append(m_primaryScreenGeometry.y());
args.append(currentScreen.width()); args.append(m_primaryScreenGeometry.width());
args.append(currentScreen.height()); args.append(m_primaryScreenGeometry.height());
args.append(panelSize()); args.append(panelSize());
args.append(m_gsettings->get(PANEL_POSITION_KEY).toInt()); args.append(m_gsettings->get(PANEL_POSITION_KEY).toInt());
message.setArguments(args); message.setArguments(args);
QDBusConnection::sessionBus().send(message); QDBusConnection::sessionBus().send(message);
} }
void UKUIPanel::setPanelAnimation(QRect startrect, QRect endrect)
{
if (m_animation == nullptr) {
m_animation = new QPropertyAnimation(this, "geometry");
m_animation->setEasingCurve(QEasingCurve::Linear);
//Note: for hiding, the margins are set after animation is finished
connect(m_animation, &QAbstractAnimation::finished, [this] { if (m_hidden) setMargins(); });
}
m_animation->setDuration(m_animationTime);
m_animation->setStartValue(startrect);
m_animation->setEndValue(endrect);
//Note: for showing-up, the margins are removed instantly
if (!m_hidden) {
setMargins();
}
m_animation->start();
}
/*设置边距*/ /*设置边距*/
void UKUIPanel::setMargins() void UKUIPanel::setMargins()
{ {
@ -986,7 +1016,7 @@ void UKUIPanel::setPosition(int screen, IUKUIPanel::Position position, bool save
realign(); realign();
m_gsettings->set(PANEL_POSITION_KEY,position); m_gsettings->set(PANEL_POSITION_KEY,position);
setPanelGeometry(true); setPanelGeometry();
} }
/************************************************ /************************************************
@ -1370,14 +1400,12 @@ void UKUIPanel::hidePanel()
void UKUIPanel::hidePanelWork() void UKUIPanel::hidePanelWork()
{ {
if (!geometry().contains(QCursor::pos())) {
if (!m_standaloneWindows->isAnyWindowShown()) { if (!m_standaloneWindows->isAnyWindowShown()) {
m_hidden = true; m_hidden = true;
setPanelGeometry(m_animationTime > 0); setPanelGeometry(m_animationTime > 0);
} else { } else {
m_hideTimer.start(); m_hideTimer.start();
} }
}
QDBusMessage message =QDBusMessage::createSignal("/panel", "org.ukui.panel.settings", "PanelHided"); QDBusMessage message =QDBusMessage::createSignal("/panel", "org.ukui.panel.settings", "PanelHided");
QDBusConnection::sessionBus().send(message); QDBusConnection::sessionBus().send(message);
} }

View File

@ -40,6 +40,9 @@
#include "common/ukuisettings.h" #include "common/ukuisettings.h"
#include "iukuipanel.h" #include "iukuipanel.h"
#include "ukuipanelglobals.h" #include "ukuipanelglobals.h"
#include <KF5/KScreen/kscreen/config.h>
#include <KF5/KScreen/kscreen/getconfigoperation.h>
class QMenu; class QMenu;
class Plugin; class Plugin;
@ -85,6 +88,8 @@ class UKUI_PANEL_API UKUIPanel : public QFrame, public IUKUIPanel
friend class PanelPluginsModel; friend class PanelPluginsModel;
public: public:
void configWatch(KScreen::ConfigOperation *op);
QRect m_primaryScreenGeometry;
/** /**
* @brief Stores how the panel should be aligned. Obviously, this applies * @brief Stores how the panel should be aligned. Obviously, this applies
* only if the panel does not occupy 100 % of the available space. If the * only if the panel does not occupy 100 % of the available space. If the
@ -412,6 +417,8 @@ private Q_SLOTS:
*/ */
void pluginMoved(Plugin * plug); void pluginMoved(Plugin * plug);
private: private:
KScreen::ConfigPtr m_config;
bool m_isWaylandEnv;
/** /**
* @brief The UKUIPanelLayout of this panel. All the Plugins will be added * @brief The UKUIPanelLayout of this panel. All the Plugins will be added
* to the UI via this layout. * to the UI via this layout.
@ -474,6 +481,8 @@ private:
* \param animate flag if showing/hiding the panel should be animated. * \param animate flag if showing/hiding the panel should be animated.
*/ */
void setPanelGeometry(bool animate = false); void setPanelGeometry(bool animate = false);
QRect caculPanelGeometry(QRect primaryscreen);
void setPanelAnimation(QRect startrect, QRect endrect);
/** /**
* @brief Sets the contents margins of the panel according to its position * @brief Sets the contents margins of the panel according to its position
* and hiddenness. All margins are zero for visible panels. * and hiddenness. All margins are zero for visible panels.