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

View File

@ -52,9 +52,10 @@
#include <KWindowSystem/KWindowSystem>
#include <KWindowSystem/NETWM>
#include <KF5/KScreen/kscreen/output.h>
#include <KF5/KScreen/kscreen/configmonitor.h>
#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/dbus-adaptor.h"
@ -181,6 +182,13 @@ UKUIPanel::UKUIPanel(const QString &configGroup, UKUi::Settings *settings, QWidg
!con.registerObject("/panel/position",dbus)) {
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
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::screenCountChanged, this, &UKUIPanel::ensureVisible);
connect(qApp,&QApplication::primaryScreenChanged,this,&UKUIPanel::ensureVisible);
// connecting to QDesktopWidget::workAreaResized shouldn't be necessary,
// as we've already connceted to QDesktopWidget::resized, but it actually
connect(QApplication::desktop(), &QDesktopWidget::workAreaResized,
this, &UKUIPanel::ensureVisible);
UKUIPanelApplication *a = reinterpret_cast<UKUIPanelApplication*>(qApp);
connect(a, &UKUIPanelApplication::primaryScreenChanged, [=]{
setPanelGeometry();
m_primaryScreenGeometry = QGuiApplication::screens().at(0)->geometry();
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()));
@ -289,7 +298,7 @@ UKUIPanel::UKUIPanel(const QString &configGroup, UKUi::Settings *settings, QWidg
// show it the first time, despite setting
if (m_hidable) {
showPanel(false);
QTimer::singleShot(PANEL_HIDE_FIRST_TIME, this, SLOT(hidePanel()));
hidePanel();
}
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)
{
if (model) {
hide();
} else {
//切换平板模式任务栏hide后再切回来任务栏的surface发生了改变。wayland下需要重新设置dock属性
setAttribute(Qt::WA_X11NetWmWindowTypeDock);
show();
KWindowSystem::setType(effectiveWinId(), NET::Dock);
realign();
}
}
@ -499,6 +545,73 @@ void UKUIPanel::priScreenChanged(int x, int y, int width, int height)
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
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)
{
QRect currentScreen;
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;
QRect rect = caculPanelGeometry(m_primaryScreenGeometry);
if (rect != geometry()) {
setFixedSize(rect.size());
if (animate) {
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(geometry());
m_animation->setEndValue(rect);
//Note: for showing-up, the margins are removed instantly
if (!m_hidden)
setMargins();
m_animation->start();
if (animate && !m_isWaylandEnv) {
setPanelAnimation(geometry(), rect);
} else {
setMargins();
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");
QList<QVariant> args;
args.append(currentScreen.x());
args.append(currentScreen.y());
args.append(currentScreen.width());
args.append(currentScreen.height());
args.append(m_primaryScreenGeometry.x());
args.append(m_primaryScreenGeometry.y());
args.append(m_primaryScreenGeometry.width());
args.append(m_primaryScreenGeometry.height());
args.append(panelSize());
args.append(m_gsettings->get(PANEL_POSITION_KEY).toInt());
message.setArguments(args);
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()
{
@ -986,7 +1016,7 @@ void UKUIPanel::setPosition(int screen, IUKUIPanel::Position position, bool save
realign();
m_gsettings->set(PANEL_POSITION_KEY,position);
setPanelGeometry(true);
setPanelGeometry();
}
/************************************************
@ -1370,14 +1400,12 @@ void UKUIPanel::hidePanel()
void UKUIPanel::hidePanelWork()
{
if (!geometry().contains(QCursor::pos())) {
if (!m_standaloneWindows->isAnyWindowShown()) {
m_hidden = true;
setPanelGeometry(m_animationTime > 0);
} else {
m_hideTimer.start();
}
}
QDBusMessage message =QDBusMessage::createSignal("/panel", "org.ukui.panel.settings", "PanelHided");
QDBusConnection::sessionBus().send(message);
}

View File

@ -40,6 +40,9 @@
#include "common/ukuisettings.h"
#include "iukuipanel.h"
#include "ukuipanelglobals.h"
#include <KF5/KScreen/kscreen/config.h>
#include <KF5/KScreen/kscreen/getconfigoperation.h>
class QMenu;
class Plugin;
@ -85,6 +88,8 @@ class UKUI_PANEL_API UKUIPanel : public QFrame, public IUKUIPanel
friend class PanelPluginsModel;
public:
void configWatch(KScreen::ConfigOperation *op);
QRect m_primaryScreenGeometry;
/**
* @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
@ -412,6 +417,8 @@ private Q_SLOTS:
*/
void pluginMoved(Plugin * plug);
private:
KScreen::ConfigPtr m_config;
bool m_isWaylandEnv;
/**
* @brief The UKUIPanelLayout of this panel. All the Plugins will be added
* to the UI via this layout.
@ -474,6 +481,8 @@ private:
* \param animate flag if showing/hiding the panel should be animated.
*/
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
* and hiddenness. All margins are zero for visible panels.