diff --git a/customscreensaver/customscreensaver.pro b/customscreensaver/customscreensaver.pro index 60aae550..95220710 100644 --- a/customscreensaver/customscreensaver.pro +++ b/customscreensaver/customscreensaver.pro @@ -1,4 +1,5 @@ TEMPLATE = subdirs SUBDIRS += \ saverpic \ - deepin-custom-screensaver + deepin-custom-screensaver \ + deepin-web-screensaver diff --git a/customscreensaver/deepin-web-screensaver/data/deepin-screensaver-config.svg b/customscreensaver/deepin-web-screensaver/data/deepin-screensaver-config.svg new file mode 100644 index 00000000..3e46ba7b --- /dev/null +++ b/customscreensaver/deepin-web-screensaver/data/deepin-screensaver-config.svg @@ -0,0 +1,181 @@ + + + 自定义屏保-96px + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/customscreensaver/deepin-web-screensaver/data/deepin-web-screensaver.desktop b/customscreensaver/deepin-web-screensaver/data/deepin-web-screensaver.desktop new file mode 100644 index 00000000..48600096 --- /dev/null +++ b/customscreensaver/deepin-web-screensaver/data/deepin-web-screensaver.desktop @@ -0,0 +1,5 @@ +[Desktop Entry] +Type=Application +Exec=/usr/lib/deepin-screensaver/modules/deepin-web-screensaver --config +Terminal=false +Name=deepin-web-screensaver-config diff --git a/customscreensaver/deepin-web-screensaver/data/org.deepin.webscreensaver.json b/customscreensaver/deepin-web-screensaver/data/org.deepin.webscreensaver.json new file mode 100644 index 00000000..03f7ace1 --- /dev/null +++ b/customscreensaver/deepin-web-screensaver/data/org.deepin.webscreensaver.json @@ -0,0 +1,17 @@ +{ + "magic": "dsg.config.meta", + "version": "1.0", + "contents": { + "slideshowPath": { + "value": "", + "serial": 0, + "flags": ["global"], + "name": "Web url", + "name[zh_CN]": "网页地址", + "description[zh_CN]":"自定义屏保网页地址", + "description": "Custom screensaver web url", + "permissions": "readwrite", + "visibility": "public" + } + } +} diff --git a/customscreensaver/deepin-web-screensaver/deepin-web-screensaver.pro b/customscreensaver/deepin-web-screensaver/deepin-web-screensaver.pro new file mode 100644 index 00000000..163f722a --- /dev/null +++ b/customscreensaver/deepin-web-screensaver/deepin-web-screensaver.pro @@ -0,0 +1,85 @@ +#------------------------------------------------- +# +# Project created by QtCreator 2021-05-14T10:44:28 +# +#------------------------------------------------- + +QT += core gui dtkcore webenginewidgets network + +greaterThan(QT_MAJOR_VERSION, 4): QT += widgets + +TARGET = deepin-web-screensaver +TEMPLATE = app + +# The following define makes your compiler emit warnings if you use +# any feature of Qt which has been marked as deprecated (the exact warnings +# depend on your compiler). Please consult the documentation of the +# deprecated API in order to know how to port your code away from it. +DEFINES += QT_DEPRECATED_WARNINGS + +# You can also make your code fail to compile if you use deprecated APIs. +# In order to do so, uncomment the following line. +# You can also select to disable deprecated APIs only up to a certain version of Qt. +#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0 + +CONFIG += c++11 link_pkgconfig + +PKGCONFIG += x11 dtkwidget + +SOURCES += \ + src/main.cpp \ + src/slideshowscreensaver.cpp \ + src/commandlinemanager.cpp \ + src/slideshowconfig.cpp \ + src/slideshowconfigdialog.cpp \ + src/config/contenttitle.cpp \ + src/config/selectpathwidget.cpp \ + src/singleinstance.cpp + +HEADERS += \ + src/slideshowscreensaver.h \ + src/commandlinemanager.h \ + src/slideshowconfig.h \ + src/slideshowconfigdialog.h \ + src/config/contenttitle.h \ + src/config/selectpathwidget.h \ + src/singleinstance.h + + +#!! 放开注释来更新json配置文件所生成的ts文件 +#DTK_SETTINGS = $${QT.dtkcore.tools}/dtk-settings +#system($$DTK_SETTINGS -o deepin-custom-screensaver_translation.cpp $$PWD/data/deepin-custom-screensaver.json) +#SOURCES += deepin-custom-screensaver_translation.cpp + +TRANSLATIONS += $$PWD/translations/$${TARGET}.ts \ + $$PWD/translations/$${TARGET}_zh_CN.ts \ + $$PWD/translations/$${TARGET}_zh_HK.ts \ + +CONFIG(release, debug|release) { + !system($$PWD/generate_translations.sh): error("Failed to generate translation") +} + +target.path = /usr/lib/deepin-screensaver/modules/ + +translations.path = /usr/share/$${TARGET}/translations +translations.files = translations/*.qm + +desktop.path = /etc/deepin-screensaver/$${TARGET}/ +desktop.files = data/deepin-web-screensaver.desktop + +icons.path = /usr/lib/deepin-screensaver/modules/cover/ +icons.files = src/icons/*.jpg + +INSTALLS += target translations desktop icons + +# DConfig +meta_file.files += \ + $$PWD/data/org.deepin.webscreensaver.json +meta_file.base = $$PWD/data +meta_file.appid = org.deepin.screensaver + +DCONFIG_META_FILES += meta_file +load(dtk_install_dconfig) + +RESOURCES += \ + icon.qrc diff --git a/customscreensaver/deepin-web-screensaver/generate_translations.sh b/customscreensaver/deepin-web-screensaver/generate_translations.sh new file mode 100755 index 00000000..f340a099 --- /dev/null +++ b/customscreensaver/deepin-web-screensaver/generate_translations.sh @@ -0,0 +1,16 @@ +#!/bin/bash + +# SPDX-FileCopyrightText: 2022 UnionTech Software Technology Co., Ltd. +# +# SPDX-License-Identifier: GPL-3.0-or-later + +# this file is used to auto-generate .qm file from .ts file. +# author: shibowen at linuxdeepin.com + +ts_list=(`ls translations/*.ts`) + +for ts in "${ts_list[@]}" +do + printf "\nprocess ${ts}\n" + lrelease "${ts}" +done diff --git a/customscreensaver/deepin-web-screensaver/icon.qrc b/customscreensaver/deepin-web-screensaver/icon.qrc new file mode 100644 index 00000000..f64c8039 --- /dev/null +++ b/customscreensaver/deepin-web-screensaver/icon.qrc @@ -0,0 +1,5 @@ + + + data/deepin-screensaver-config.svg + + diff --git a/customscreensaver/deepin-web-screensaver/src/commandlinemanager.cpp b/customscreensaver/deepin-web-screensaver/src/commandlinemanager.cpp new file mode 100644 index 00000000..c38d2a39 --- /dev/null +++ b/customscreensaver/deepin-web-screensaver/src/commandlinemanager.cpp @@ -0,0 +1,66 @@ +// SPDX-FileCopyrightText: 2022 UnionTech Software Technology Co., Ltd. +// +// SPDX-License-Identifier: GPL-3.0-or-later + +#include "commandlinemanager.h" + +#include + +class CommandLineManagerGlobal : public CommandLineManager {}; +Q_GLOBAL_STATIC(CommandLineManagerGlobal, commandLineManagerGlobal); + +CommandLineManager::CommandLineManager() + : m_commandParser(new QCommandLineParser) +{ + // 必须设置为长选项模式,否则解析时 -window-id 将识别错误 + m_commandParser->setSingleDashWordOptionMode(QCommandLineParser::ParseAsLongOptions); + + initOptions(); +} + +CommandLineManager *CommandLineManager::instance() +{ + return commandLineManagerGlobal; +} + +CommandLineManager::~CommandLineManager() +{ + +} + +void CommandLineManager::initOptions() +{ + QCommandLineOption subWindowOption("window-id", "displays as a child of the given ID window.\nNOTE:is '-window-id',not '--window-id'", "ID"); + QCommandLineOption pathOption(QStringList() << "p" << "path", "set the path of web page.", "PATH"); + QCommandLineOption config(QStringList() << "config", "show config user Interface"); + + m_commandParser->addOption(subWindowOption); + m_commandParser->addOption(pathOption); + m_commandParser->addOption(config); +} + +void CommandLineManager::process(const QStringList &arguments) +{ + m_commandParser->process(arguments); +} + +bool CommandLineManager::isSet(const QString &name) const +{ + return m_commandParser->isSet(name); +} + +QString CommandLineManager::value(const QString &name) const +{ + return m_commandParser->value(name); +} + +QStringList CommandLineManager::positionalArguments() +{ + return m_commandParser->positionalArguments(); +} + +QStringList CommandLineManager::unknownOptionNames() +{ + return m_commandParser->unknownOptionNames(); +} + diff --git a/customscreensaver/deepin-web-screensaver/src/commandlinemanager.h b/customscreensaver/deepin-web-screensaver/src/commandlinemanager.h new file mode 100644 index 00000000..f1e337b5 --- /dev/null +++ b/customscreensaver/deepin-web-screensaver/src/commandlinemanager.h @@ -0,0 +1,41 @@ +// SPDX-FileCopyrightText: 2022 UnionTech Software Technology Co., Ltd. +// +// SPDX-License-Identifier: GPL-3.0-or-later + +#ifndef COMMANDLINEMANAGER_H +#define COMMANDLINEMANAGER_H + +#include +#include +#include + +class CommandLineManager +{ +public: + static CommandLineManager *instance(); + + ~CommandLineManager(); + + void process(const QStringList &arguments); + + bool isSet(const QString &name) const; + QString value(const QString &name) const; + + QStringList positionalArguments(); + QStringList unknownOptionNames(); + +protected: + explicit CommandLineManager(); + +private: + void initOptions(); + +private: + CommandLineManager(CommandLineManager &) = delete; + CommandLineManager &operator=(CommandLineManager &) = delete; + +private: + QScopedPointer m_commandParser; +}; + +#endif // COMMANDLINEMANAGER_H diff --git a/customscreensaver/deepin-web-screensaver/src/config/contenttitle.cpp b/customscreensaver/deepin-web-screensaver/src/config/contenttitle.cpp new file mode 100644 index 00000000..fe6ad32b --- /dev/null +++ b/customscreensaver/deepin-web-screensaver/src/config/contenttitle.cpp @@ -0,0 +1,31 @@ +// SPDX-FileCopyrightText: 2023 UnionTech Software Technology Co., Ltd. +// +// SPDX-License-Identifier: GPL-3.0-or-later + +#include "contenttitle.h" + +#include + +ContentTitle::ContentTitle(QWidget *parent) : QWidget(parent) +{ + auto layout = new QHBoxLayout(this); + layout->setContentsMargins(0, 0, 0, 0); + layout->setSpacing(10); + + titleLabel = new QLabel; + layout->addWidget(titleLabel, 0, Qt::AlignLeft); + + auto lineLabel = new QLabel; + layout->addWidget(lineLabel); + lineLabel->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed); +} + +QLabel *ContentTitle::label() const +{ + return titleLabel; +} + +void ContentTitle::setTitle(const QString &title) +{ + titleLabel->setText(title); +} diff --git a/customscreensaver/deepin-web-screensaver/src/config/contenttitle.h b/customscreensaver/deepin-web-screensaver/src/config/contenttitle.h new file mode 100644 index 00000000..cee97d71 --- /dev/null +++ b/customscreensaver/deepin-web-screensaver/src/config/contenttitle.h @@ -0,0 +1,25 @@ +// SPDX-FileCopyrightText: 2023 UnionTech Software Technology Co., Ltd. +// +// SPDX-License-Identifier: GPL-3.0-or-later + +#ifndef CONTENTTITLE_H +#define CONTENTTITLE_H + +#include +#include + +class ContentTitle : public QWidget +{ + Q_OBJECT +public: + explicit ContentTitle(QWidget *parent = nullptr); + QLabel *label() const; + +public : + void setTitle(const QString &title); + +protected: + QLabel *titleLabel = nullptr; +}; + +#endif // CONTENTTITLE_H diff --git a/customscreensaver/deepin-web-screensaver/src/config/selectpathwidget.cpp b/customscreensaver/deepin-web-screensaver/src/config/selectpathwidget.cpp new file mode 100644 index 00000000..be78a203 --- /dev/null +++ b/customscreensaver/deepin-web-screensaver/src/config/selectpathwidget.cpp @@ -0,0 +1,48 @@ +// SPDX-FileCopyrightText: 2022 UnionTech Software Technology Co., Ltd. +// +// SPDX-License-Identifier: GPL-3.0-or-later + +#include "selectpathwidget.h" +#include "../slideshowconfig.h" + +#include + +#include +#include + +DWIDGET_USE_NAMESPACE +DCORE_USE_NAMESPACE + +SelectPathWidget::SelectPathWidget(QWidget *parent) + : DWidget(parent) +{ + initOption(); +} + +QString SelectPathWidget::getPath() +{ + return m_selectLineEdit->text(); +} + +void SelectPathWidget::initOption() +{ + QString valueText; + // 路径转换 + if (valueText.startsWith(QStringLiteral("~"))) + valueText.replace(QStringLiteral("~"), QDir::homePath()); + + m_selectTips = new DLabel(tr("Enter web url"), this); + m_selectLineEdit = new DLineEdit(this); + m_selectBtn = new DPushButton(tr("apply"), this); + m_selectBtn->setFocusPolicy(Qt::NoFocus); + + m_url = SlideshowConfig::instance()->slideshowPath(); + m_selectLineEdit->setPlaceholderText(m_url); + + QHBoxLayout *layout = new QHBoxLayout(this); + layout->addWidget(m_selectTips); + layout->addWidget(m_selectLineEdit); + layout->addWidget(m_selectBtn); + + connect(m_selectBtn, &DPushButton::clicked, this, &SelectPathWidget::requsetSetPath); +} diff --git a/customscreensaver/deepin-web-screensaver/src/config/selectpathwidget.h b/customscreensaver/deepin-web-screensaver/src/config/selectpathwidget.h new file mode 100644 index 00000000..45d3d830 --- /dev/null +++ b/customscreensaver/deepin-web-screensaver/src/config/selectpathwidget.h @@ -0,0 +1,36 @@ +// SPDX-FileCopyrightText: 2022 UnionTech Software Technology Co., Ltd. +// +// SPDX-License-Identifier: GPL-3.0-or-later + +#ifndef SELECTPATHWIDGET_H +#define SELECTPATHWIDGET_H + +#include +#include +#include +#include +#include + +#include + +class TruncateLineEdit; + +class SelectPathWidget : public Dtk::Widget::DWidget +{ + Q_OBJECT +public: + explicit SelectPathWidget(QWidget *parent = nullptr); + QString getPath(); +signals: + void requsetSetPath(); + +private: + void initOption(); +private: + Dtk::Widget::DLabel *m_selectTips = nullptr; + Dtk::Widget::DLineEdit *m_selectLineEdit = nullptr; + Dtk::Widget::DPushButton *m_selectBtn = nullptr; + QString m_url; +}; + +#endif // SELECTPATHWIDGET_H diff --git a/customscreensaver/deepin-web-screensaver/src/icons/deepin-web-screensaver.jpg b/customscreensaver/deepin-web-screensaver/src/icons/deepin-web-screensaver.jpg new file mode 100644 index 00000000..7b9757ad Binary files /dev/null and b/customscreensaver/deepin-web-screensaver/src/icons/deepin-web-screensaver.jpg differ diff --git a/customscreensaver/deepin-web-screensaver/src/icons/deepin-web-screensaver@2x.jpg b/customscreensaver/deepin-web-screensaver/src/icons/deepin-web-screensaver@2x.jpg new file mode 100644 index 00000000..335e13c0 Binary files /dev/null and b/customscreensaver/deepin-web-screensaver/src/icons/deepin-web-screensaver@2x.jpg differ diff --git a/customscreensaver/deepin-web-screensaver/src/icons/deepin-web-screensaver@3x.jpg b/customscreensaver/deepin-web-screensaver/src/icons/deepin-web-screensaver@3x.jpg new file mode 100644 index 00000000..445d70db Binary files /dev/null and b/customscreensaver/deepin-web-screensaver/src/icons/deepin-web-screensaver@3x.jpg differ diff --git a/customscreensaver/deepin-web-screensaver/src/main.cpp b/customscreensaver/deepin-web-screensaver/src/main.cpp new file mode 100644 index 00000000..0e027299 --- /dev/null +++ b/customscreensaver/deepin-web-screensaver/src/main.cpp @@ -0,0 +1,91 @@ +// SPDX-FileCopyrightText: 2022 UnionTech Software Technology Co., Ltd. +// +// SPDX-License-Identifier: GPL-3.0-or-later + +#include "slideshowscreensaver.h" +#include "commandlinemanager.h" +#include "slideshowconfig.h" + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +DWIDGET_USE_NAMESPACE + +int main(int argc, char *argv[]) +{ + auto envType = qEnvironmentVariable("XDG_SESSION_TYPE"); + if (envType.contains("wayland")) { + qInfo() << QDateTime::currentDateTime().toString() << "notes:change wayland to xcb for QT_QPA_PLATFORM."; + qputenv("QT_QPA_PLATFORM", "xcb"); + } + + DApplication a(argc, argv); + a.setOrganizationName("deepin"); + a.loadTranslator(); + + CommandLineManager::instance()->process(a.arguments()); + + if (CommandLineManager::instance()->isSet("window-id")) { + + QString windowId = CommandLineManager::instance()->value("window-id"); + WId windowHwnd = WId(windowId.toULongLong()); + QWindow *window = QWindow::fromWinId(windowHwnd); + + if (!window) { + qDebug() << "Error:not found QWindow by window id:" << windowId; + return -1; + } + + SlideshowScreenSaver screensaver(true); + screensaver.setProperty("_q_embedded_native_parent_handle", QVariant(windowHwnd)); + screensaver.winId(); + screensaver.windowHandle()->setParent(window); + + Display *display = XOpenDisplay(nullptr); + if (!display) { + qWarning() << "can not connect xservice."; + return -1; + } + + Window windowXID(windowHwnd); + XWindowAttributes attr; + XGetWindowAttributes(display, windowXID, &attr); + + screensaver.setGeometry(QRect(0, 0, attr.width, attr.height)); + screensaver.init(); + screensaver.show(); + + return a.exec(); + + } else if (CommandLineManager::instance()->isSet("p")) { + + QString path = CommandLineManager::instance()->value("p"); + SlideshowConfig::instance()->setSlideShowPath(path); + + } else if (CommandLineManager::instance()->isSet("config")) { + qInfo() << "show dconfig dialog"; + if (SlideshowConfig::instance()->startCustomConfig()) + return a.exec(); + return 0; + } else { + SlideshowScreenSaver screensaver; + screensaver.init(); + screensaver.show(); + + return a.exec(); + } + + return 0; +} diff --git a/customscreensaver/deepin-web-screensaver/src/singleinstance.cpp b/customscreensaver/deepin-web-screensaver/src/singleinstance.cpp new file mode 100644 index 00000000..55ff9ab5 --- /dev/null +++ b/customscreensaver/deepin-web-screensaver/src/singleinstance.cpp @@ -0,0 +1,121 @@ +// SPDX-FileCopyrightText: 2023 UnionTech Software Technology Co., Ltd. +// +// SPDX-License-Identifier: GPL-3.0-or-later + +#include "singleinstance.h" + +#include +#include +#include +#include +#include + +SingleInstance::SingleInstance(const QString &name, QObject *parent) + : QObject(parent) + , m_localServer(new QLocalServer) +{ + m_userKey = QString("%1/%2").arg(QStandardPaths::writableLocation(QStandardPaths::RuntimeLocation)).arg(name); + if (m_userKey.isEmpty()) { + m_userKey = QString("%1/%2").arg(QStandardPaths::writableLocation(QStandardPaths::TempLocation)).arg(name); + } + + initConnect(); +} + +SingleInstance::~SingleInstance() +{ + closeServer(); +} + +bool SingleInstance::isSingle() +{ + QLocalSocket localSocket; + localSocket.connectToServer(m_userKey); + + // if connect success, another instance is running. + if (localSocket.waitForConnected(1000)) + return false; + + m_localServer->removeServer(m_userKey); + bool f = m_localServer->listen(m_userKey); + return f; +} + +void SingleInstance::closeServer() +{ + if (m_localServer) { + m_localServer->removeServer(m_localServer->serverName()); + m_localServer->close(); + delete m_localServer; + m_localServer = nullptr; + } +} + +void SingleInstance::sendNewClient() +{ + QByteArray data { nullptr }; + const auto &args = qApp->arguments(); + qDebug() << "new client send data: " << args; + for (const QString &arg : args) { + if (!arg.startsWith("-") && QFile::exists(arg)) { + data.append(QDir(arg).absolutePath().toLocal8Bit().toBase64()); + } else { + data.append(arg.toLocal8Bit().toBase64()); + } + data.append(' '); + } + + if (!data.isEmpty()) + data.chop(1); + + QLocalSocket *socket = getNewClientConnect(data); + socket->deleteLater(); +} + +QLocalSocket *SingleInstance::getNewClientConnect(const QByteArray &message) +{ + QLocalSocket *localSocket = new QLocalSocket; + localSocket->connectToServer(m_userKey); + if (localSocket->waitForConnected(1000)) { + if (localSocket->state() == QLocalSocket::ConnectedState) { + if (localSocket->isValid()) { + localSocket->write(message); + localSocket->flush(); + } + } + } else { + qDebug() << localSocket->errorString(); + } + + return localSocket; +} + +void SingleInstance::handleConnection() +{ + qDebug() << "new connection is coming"; + QLocalSocket *nextPendingConnection = m_localServer->nextPendingConnection(); + connect(nextPendingConnection, SIGNAL(readyRead()), this, SLOT(readData())); +} + +void SingleInstance::readData() +{ + QLocalSocket *socket = qobject_cast(sender()); + + if (!socket) + return; + + QStringList arguments; + for (const QByteArray &arg_base64 : socket->read(2048).split(' ')) { + const QByteArray &arg = QByteArray::fromBase64(arg_base64.simplified()); + if (arg.isEmpty()) + continue; + arguments << QString::fromLocal8Bit(arg); + } + + emit handArguments(arguments); +} + +void SingleInstance::initConnect() +{ + connect(m_localServer, &QLocalServer::newConnection, this, &SingleInstance::handleConnection); +} diff --git a/customscreensaver/deepin-web-screensaver/src/singleinstance.h b/customscreensaver/deepin-web-screensaver/src/singleinstance.h new file mode 100644 index 00000000..96a788b4 --- /dev/null +++ b/customscreensaver/deepin-web-screensaver/src/singleinstance.h @@ -0,0 +1,39 @@ +// SPDX-FileCopyrightText: 2023 UnionTech Software Technology Co., Ltd. +// +// SPDX-License-Identifier: GPL-3.0-or-later + +#ifndef SINGLEINSTANCE_H +#define SINGLEINSTANCE_H + +#include + +QT_BEGIN_NAMESPACE +class QLocalServer; +class QLocalSocket; +class QCommandLineParser; +QT_END_NAMESPACE + +class SingleInstance : public QObject +{ + Q_OBJECT +public: + explicit SingleInstance(const QString &name, QObject *parent = nullptr); + ~SingleInstance(); + bool isSingle(); + void closeServer(); + void sendNewClient(); + QLocalSocket *getNewClientConnect(const QByteArray &message); +signals: + void handArguments(const QStringList &); +private slots: + void handleConnection(); + void readData(); +private: + void initConnect(); + +protected: + QLocalServer *m_localServer { nullptr }; + QString m_userKey; +}; + +#endif // SINGLEINSTANCE_H diff --git a/customscreensaver/deepin-web-screensaver/src/slideshowconfig.cpp b/customscreensaver/deepin-web-screensaver/src/slideshowconfig.cpp new file mode 100644 index 00000000..a98ee5f3 --- /dev/null +++ b/customscreensaver/deepin-web-screensaver/src/slideshowconfig.cpp @@ -0,0 +1,76 @@ +// SPDX-FileCopyrightText: 2022 UnionTech Software Technology Co., Ltd. +// +// SPDX-License-Identifier: GPL-3.0-or-later + +#include "slideshowconfig.h" +#include "slideshowconfigdialog.h" + +#include +#include +#include + +class SlideshowConfigGlobal : public SlideshowConfig +{ +}; +Q_GLOBAL_STATIC(SlideshowConfigGlobal, slideshowConfig); + +SlideshowConfig::SlideshowConfig(QObject *parent) + : QObject(parent) +{ + m_dCfg = DConfig::create(kCfgAppId, kCfgName, "", this); +} + +SlideshowConfig::~SlideshowConfig() +{ +} + +SlideshowConfig *SlideshowConfig::instance() +{ + return slideshowConfig; +} + +QString SlideshowConfig::slideshowPath() const +{ + QString path; + path = m_dCfg->value(kSlideshowPath, "").toString(); + + // 组策略值为空,使用默认url + if (path.isEmpty()) + path = defaultPath(); + + //path格式修正 + if (path.startsWith(QStringLiteral("https:// "))) + path = defaultPath(); + + return path; +} + +void SlideshowConfig::setSlideShowPath(QString path) +{ + m_dCfg->setValue(kSlideshowPath, path); +} + +bool SlideshowConfig::startCustomConfig() +{ + auto ins = new SingleInstance(qApp->applicationName() + "-config", this); + if (ins->isSingle()) { + SlideShowConfigDialog *configDialog = new SlideShowConfigDialog(); + + connect(ins, &SingleInstance::handArguments, configDialog, [configDialog](){ + configDialog->activateWindow();; + }); + + configDialog->startConfig(); + } else { + ins->sendNewClient(); + return false; + } + + return true; +} + +QString SlideshowConfig::defaultPath() +{ + //用户输入为空时返回 + return "https://uniontech.com"; +} diff --git a/customscreensaver/deepin-web-screensaver/src/slideshowconfig.h b/customscreensaver/deepin-web-screensaver/src/slideshowconfig.h new file mode 100644 index 00000000..c5c45eaf --- /dev/null +++ b/customscreensaver/deepin-web-screensaver/src/slideshowconfig.h @@ -0,0 +1,57 @@ +// SPDX-FileCopyrightText: 2022 UnionTech Software Technology Co., Ltd. +// +// SPDX-License-Identifier: GPL-3.0-or-later + +#ifndef SLIDESHOWCONFIG_H +#define SLIDESHOWCONFIG_H + +#include +#include +#include +#include + +DCORE_USE_NAMESPACE + +static const char *const kGroupSlideshowPath = "custom_screensaver.path.select_path"; +static const char *const kKeyValue = "value"; + +static const char *const kDeepinScreenSaver = "deepin-screensaver"; + +static constexpr char kCfgAppId[] { "org.deepin.screensaver" }; +static constexpr char kCfgName[] { "org.deepin.webscreensaver" }; + +static constexpr char kSlideshowPath[] { "slideshowPath" }; + +class SlideshowConfig : public QObject +{ + Q_OBJECT + friend class SlideshowScreenSaver; + +public: + enum PlayMode { + Order = 0, + Shuffle = 1 + }; + + static SlideshowConfig *instance(); + + ~SlideshowConfig(); + + QString slideshowPath() const; + void setSlideShowPath(QString path); + + bool startCustomConfig(); + static QString defaultPath(); + +protected: + explicit SlideshowConfig(QObject *parent = nullptr); + +private: + SlideshowConfig(SlideshowConfig &) = delete; + SlideshowConfig &operator=(SlideshowConfig &) = delete; + +private: + DConfig *m_dCfg; +}; + +#endif // SLIDESHOWCONFIG_H diff --git a/customscreensaver/deepin-web-screensaver/src/slideshowconfigdialog.cpp b/customscreensaver/deepin-web-screensaver/src/slideshowconfigdialog.cpp new file mode 100644 index 00000000..076ad470 --- /dev/null +++ b/customscreensaver/deepin-web-screensaver/src/slideshowconfigdialog.cpp @@ -0,0 +1,188 @@ +// SPDX-FileCopyrightText: 2023 UnionTech Software Technology Co., Ltd. +// +// SPDX-License-Identifier: GPL-3.0-or-later + +#include "slideshowconfigdialog.h" +#include "slideshowconfig.h" +#include "config/contenttitle.h" + +#include +#include +#include +#include +#include + +#include +#include +#include + +#define SPECIFYLINEEDITLENGTH 65 + +DCORE_USE_NAMESPACE +DWIDGET_USE_NAMESPACE + +static bool isWayland() +{ + bool ok = false; + auto e = QProcessEnvironment::systemEnvironment(); + QString XDG_SESSION_TYPE = e.value(QStringLiteral("XDG_SESSION_TYPE")); + QString WAYLAND_DISPLAY = e.value(QStringLiteral("WAYLAND_DISPLAY")); + + //在wayland平台下设置固定大小,解决属性框最大化问题 + if (XDG_SESSION_TYPE == QLatin1String("wayland") || + WAYLAND_DISPLAY.contains(QLatin1String("wayland"), Qt::CaseInsensitive)) { + ok = true; + } + return ok; +} + +SlideShowConfigDialog::SlideShowConfigDialog(QWidget *parent) + : DAbstractDialog(false, parent) +{ + setModal(true); + + initUI(); + initConnect(); +} + +SlideShowConfigDialog::~SlideShowConfigDialog() +{ + +} + +void SlideShowConfigDialog::initUI() +{ + auto icon = QIcon(":/data/deepin-screensaver-config.svg"); + setWindowIcon(icon); + + auto mainlayout = new QVBoxLayout(this); + mainlayout->setContentsMargins(0, 0, 0, 0); + mainlayout->setSpacing(0); + + DFrame *contentFrame = new DFrame; + contentFrame->setLineWidth(0); + contentFrame->setContentsMargins(10, 10, 10, 10); + + QVBoxLayout *contentlayout = new QVBoxLayout(contentFrame); + frameBar = new DTitlebar(this); + frameBar->setMenuVisible(false); + frameBar->setTitle(QString()); + frameBar->setIcon(icon); + + contentlayout->setContentsMargins(10, 0, 0, 0); + + mainlayout->addWidget(frameBar); + mainlayout->addWidget(contentFrame); + + // mian title + { + contentlayout->addSpacing(30); + ContentTitle *title = new ContentTitle(contentFrame); + title->setTitle(tr("Custom Web Screensaver")); + title->label()->setForegroundRole(QPalette::BrightText); + DFontSizeManager::instance()->bind(title, DFontSizeManager::T4, QFont::Medium); + contentlayout->addWidget(title); + } + + auto createGroup = [this, contentlayout, contentFrame] + (const QString &text, const QList &contWid) { + DWidget *wid = new DWidget(contentFrame); + + // title + auto title = new ContentTitle(wid); + title->setTitle(text); + DFontSizeManager::instance()->bind(title, DFontSizeManager::T5, QFont::Medium); + + { + QHBoxLayout *hLay = new QHBoxLayout(wid); + hLay->setContentsMargins(10, 0, 0, 0); + hLay->addWidget(title); + contentlayout->addWidget(wid); + } + + QVBoxLayout *bgGpLayout = new QVBoxLayout; + DBackgroundGroup *bgGroup = new DBackgroundGroup(bgGpLayout); + bgGroup->setItemSpacing(1); + bgGroup->setItemMargins(QMargins(0, 0, 0, 0)); + bgGroup->setBackgroundRole(QPalette::Window); + bgGroup->setUseWidgetBackground(false); + contentlayout->addWidget(bgGroup); + + for (QWidget *pwid : contWid) { + QWidget *wrapperWidget = new QWidget(bgGroup); + QHBoxLayout *hLay = new QHBoxLayout(wrapperWidget); + hLay->setContentsMargins(10, 6, 10, 6); + pwid->setParent(wrapperWidget); + hLay->addWidget(pwid); + + bgGpLayout->addWidget(wrapperWidget); + } + + QSpacerItem *spaceItem = new QSpacerItem(0, 20, QSizePolicy::Minimum,QSizePolicy::Expanding); + contentlayout->addItem(spaceItem); + }; + + // path + contentlayout->addSpacing(30); + pathWidget = new SelectPathWidget; + createGroup(tr("Url"), {pathWidget}); + + if (isWayland()) { + // 设置对话框窗口最大最小化按钮隐藏 + this->setWindowFlags(this->windowFlags() & ~Qt::WindowMinMaxButtonsHint); + this->setAttribute(Qt::WA_NativeWindow); + this->windowHandle()->setProperty("_d_dwayland_minimizable", false); + this->windowHandle()->setProperty("_d_dwayland_maximizable", false); + this->windowHandle()->setProperty("_d_dwayland_resizable", false); + } + + setFixedSize(QSize(682, 332)); + return; +} + +void SlideShowConfigDialog::initConnect() +{ + connect(pathWidget, &SelectPathWidget::requsetSetPath, this, &SlideShowConfigDialog::selectPath); +} + +void SlideShowConfigDialog::startConfig() +{ + setWindowFlags(this->windowFlags() & ~Qt::WindowMaximizeButtonHint); + + setAttribute(Qt::WA_DeleteOnClose); + + // remove dialog flag to let dock show window entry. + setWindowFlag(Qt::Dialog, false); + + QScreen *screen = qApp->primaryScreen(); + move(screen->geometry().width() / 2 - this->width() / 2, + screen->geometry().height() / 2 - this->height() / 2); + + setFocus(); + show(); +} + +void SlideShowConfigDialog::mousePressEvent(QMouseEvent *event) +{ + setFocus(); + DAbstractDialog::mouseMoveEvent(event); +} + +void SlideShowConfigDialog::handArguments(const QStringList &) +{ + activateWindow(); +} + +void SlideShowConfigDialog::selectPath() +{ + QString currentPath = pathWidget->getPath(); + + // url为空,则重置为默认值 + if (currentPath.isEmpty()) { + currentPath = SlideshowConfig::defaultPath(); + } + if (!currentPath.startsWith(QStringLiteral("http://")) && !currentPath.startsWith(QStringLiteral("https://"))) + currentPath = QStringLiteral("https://") + currentPath; + + SlideshowConfig::instance()->setSlideShowPath(currentPath); +} diff --git a/customscreensaver/deepin-web-screensaver/src/slideshowconfigdialog.h b/customscreensaver/deepin-web-screensaver/src/slideshowconfigdialog.h new file mode 100644 index 00000000..7b04fc2b --- /dev/null +++ b/customscreensaver/deepin-web-screensaver/src/slideshowconfigdialog.h @@ -0,0 +1,39 @@ +// SPDX-FileCopyrightText: 2023 UnionTech Software Technology Co., Ltd. +// +// SPDX-License-Identifier: GPL-3.0-or-later + +#ifndef SLIDESHOWCONFIGDIALOG_H +#define SLIDESHOWCONFIGDIALOG_H + +#include "config/selectpathwidget.h" +#include "singleinstance.h" + +#include +#include +#include + +class SlideShowConfigDialog : public DTK_WIDGET_NAMESPACE::DAbstractDialog +{ + Q_OBJECT +public: + explicit SlideShowConfigDialog(QWidget *parent = nullptr); + ~SlideShowConfigDialog(); + void startConfig(); + +protected: + void mousePressEvent(QMouseEvent *event) override; + void handArguments(const QStringList &); +private slots: + void selectPath(); + +private: + void initUI(); + void initConnect(); + +private: + DTK_WIDGET_NAMESPACE::DTitlebar *frameBar = nullptr; + SelectPathWidget *pathWidget = nullptr; + Dtk::Widget::DPushButton *m_confirmBtn = nullptr; +}; + +#endif // SLIDESHOWCONFIGDIALOG_H diff --git a/customscreensaver/deepin-web-screensaver/src/slideshowscreensaver.cpp b/customscreensaver/deepin-web-screensaver/src/slideshowscreensaver.cpp new file mode 100644 index 00000000..e8d2d529 --- /dev/null +++ b/customscreensaver/deepin-web-screensaver/src/slideshowscreensaver.cpp @@ -0,0 +1,109 @@ +// SPDX-FileCopyrightText: 2022 UnionTech Software Technology Co., Ltd. +// +// SPDX-License-Identifier: GPL-3.0-or-later + +#include "slideshowscreensaver.h" +#include "slideshowconfig.h" + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#define IMAGE_MAX_SIZE 30 * 1024 * 1024 // Only display image smaller than 30M + +DWIDGET_USE_NAMESPACE + +SlideshowScreenSaver::SlideshowScreenSaver(bool subWindow, QWidget *parent) + : QWebEngineView(parent), m_subWindow(subWindow) +{ + if (m_subWindow) + setWindowFlag(Qt::WindowTransparentForInput, true); +} + +SlideshowScreenSaver::~SlideshowScreenSaver() +{ +} + +void SlideshowScreenSaver::closeEvent(QCloseEvent *event) +{ + for (auto wid : findChildren()) + wid->close(); + + QWidget::closeEvent(event); +} + +bool SlideshowScreenSaver::nativeEventFilter(const QByteArray &eventType, void *message, long *result) +{ + Q_UNUSED(result); + if (eventType == "xcb_generic_event_t") { + xcb_generic_event_t *event = reinterpret_cast(message); + int type = (event->response_type & ~0x80); + if (XCB_CONFIGURE_NOTIFY == type) { + xcb_configure_notify_event_t *ce = reinterpret_cast(event); + qInfo() << "parent window size changed" << ce->width << ce->height; + QSize widSize = mapFromHandle(QSize(ce->width, ce->height)); + if (widSize != size()) { + qInfo() << "update window size:" << widSize; + resize(widSize); + } + } else if (XCB_DESTROY_NOTIFY == type) { + xcb_destroy_notify_event_t *ce = reinterpret_cast(event); + if (ce->window == Window(this->windowHandle()->winId())) { + qInfo() << "parent window closed"; + QMetaObject::invokeMethod(this, "close", Qt::QueuedConnection); + } + } + } + return false; +} + +void SlideshowScreenSaver::init() +{ + connect(this, &QWebEngineView::loadFinished, [&](bool success) { + if (!success) { + if (m_url.startsWith(QStringLiteral("https://"))) + m_url.replace(QStringLiteral("https://"), QStringLiteral("http://")); + SlideshowConfig::instance()->m_dCfg->setValue(kSlideshowPath, m_url); + this->load(QUrl(m_url)); + } + }); + updateViewSize(this->size()); + loadSlideshowImages(); +} + +void SlideshowScreenSaver::loadSlideshowImages() +{ + m_url = SlideshowConfig::instance()->slideshowPath(); + this->load(QUrl(m_url)); +} + +QSize SlideshowScreenSaver::mapFromHandle(const QSize &handleSize) +{ + qreal ratio = devicePixelRatioF(); + qDebug() << "parent window handle size" << handleSize << "devicePixelRatio" << ratio; + + if (ratio > 0 && ratio != 1.0) + return handleSize / ratio; + else + return handleSize; +} + +void SlideshowScreenSaver::updateViewSize(const QSize &size) +{ + QSize updateSize = mapFromHandle(size); + + if (updateSize != size){ + this->resize(updateSize); + } +} diff --git a/customscreensaver/deepin-web-screensaver/src/slideshowscreensaver.h b/customscreensaver/deepin-web-screensaver/src/slideshowscreensaver.h new file mode 100644 index 00000000..bbd9ff90 --- /dev/null +++ b/customscreensaver/deepin-web-screensaver/src/slideshowscreensaver.h @@ -0,0 +1,37 @@ +// SPDX-FileCopyrightText: 2022 UnionTech Software Technology Co., Ltd. +// +// SPDX-License-Identifier: GPL-3.0-or-later + +#ifndef SLIDESHOWSCREENSAVER_H +#define SLIDESHOWSCREENSAVER_H + +#include +#include +#include +#include + +class SlideshowScreenSaver : public QWebEngineView, public QAbstractNativeEventFilter +{ + Q_OBJECT +public: + explicit SlideshowScreenSaver(bool subWindow = false, QWidget *parent = nullptr); + ~SlideshowScreenSaver() override; + + bool nativeEventFilter(const QByteArray &eventType, void *message, long *result) override; + void init(); + +protected: + void closeEvent(QCloseEvent *event) override; + + QSize mapFromHandle(const QSize &handleSize); + +private: + void loadSlideshowImages(); + void updateViewSize(const QSize &updatesize); + +private: + bool m_subWindow { false }; + QString m_url; +}; + +#endif // SLIDESHOWSCREENSAVER_H diff --git a/customscreensaver/deepin-web-screensaver/translations/deepin-web-screensaver.ts b/customscreensaver/deepin-web-screensaver/translations/deepin-web-screensaver.ts new file mode 100644 index 00000000..ed1cfbe3 --- /dev/null +++ b/customscreensaver/deepin-web-screensaver/translations/deepin-web-screensaver.ts @@ -0,0 +1,30 @@ + + + + + SelectPathWidget + + + Enter web url + Enter web url + + + + apply + apply + + + + SlideShowConfigDialog + + + Custom Web Screensaver + Custom Web Screensaver + + + + Url + Url + + + diff --git a/customscreensaver/deepin-web-screensaver/translations/deepin-web-screensaver_zh_CN.ts b/customscreensaver/deepin-web-screensaver/translations/deepin-web-screensaver_zh_CN.ts new file mode 100644 index 00000000..dc20f293 --- /dev/null +++ b/customscreensaver/deepin-web-screensaver/translations/deepin-web-screensaver_zh_CN.ts @@ -0,0 +1,30 @@ + + + + + SelectPathWidget + + + Enter web url + 输入网站地址 + + + + apply + 应用 + + + + SlideShowConfigDialog + + + Custom Web Screensaver + 自定义Web屏幕保护程序 + + + + Url + 网址 + + + diff --git a/customscreensaver/deepin-web-screensaver/translations/deepin-web-screensaver_zh_HK.ts b/customscreensaver/deepin-web-screensaver/translations/deepin-web-screensaver_zh_HK.ts new file mode 100644 index 00000000..73f6c9c5 --- /dev/null +++ b/customscreensaver/deepin-web-screensaver/translations/deepin-web-screensaver_zh_HK.ts @@ -0,0 +1,30 @@ + + + + + SelectPathWidget + + + Enter web url + 輸入網頁地址 + + + + apply + 應用 + + + + SlideShowConfigDialog + + + Custom Web Screensaver + 自定義網頁荧幕保護程式 + + + + Url + 網址 + + + diff --git a/customscreensaver/deepin-web-screensaver/update_translations.sh b/customscreensaver/deepin-web-screensaver/update_translations.sh new file mode 100755 index 00000000..aaedef54 --- /dev/null +++ b/customscreensaver/deepin-web-screensaver/update_translations.sh @@ -0,0 +1,10 @@ +#!/bin/bash + +# SPDX-FileCopyrightText: 2022 UnionTech Software Technology Co., Ltd. +# +# SPDX-License-Identifier: GPL-3.0-or-later + +# this file is used to auto update ts file. + +lupdate -pro deepin-custom-screensaver.pro -ts translations/deepin-custom-screensaver.ts -no-obsolete +lupdate -pro deepin-custom-screensaver.pro -ts translations/deepin-custom-screensaver_zh_CN.ts -no-obsolete diff --git a/debian/control b/debian/control index e9ae59e3..fc363dad 100644 --- a/debian/control +++ b/debian/control @@ -2,7 +2,7 @@ Source: deepin-screensaver Section: devel Priority: optional Maintainer: Deepin Packages Builder -Build-Depends: debhelper (>=9), qtbase5-dev, qttools5-dev-tools, qtdeclarative5-dev, libqt5x11extras5-dev, libdtkwidget-dev, deepin-desktop-base, libx11-dev, libxss-dev, libxext-dev, libdframeworkdbus-dev, pkg-config, qml-module-qt-labs-platform +Build-Depends: debhelper (>=9), qtbase5-dev, qttools5-dev-tools, qtdeclarative5-dev, libqt5x11extras5-dev, libdtkwidget-dev, deepin-desktop-base, libx11-dev, libxss-dev, libxext-dev, libdframeworkdbus-dev, pkg-config, qml-module-qt-labs-platform, qtwebengine5-dev Standards-Version: 3.9.8 Package: deepin-screensaver diff --git a/debian/deepin-screensaver-xscreensaver-data.install b/debian/deepin-screensaver-xscreensaver-data.install index b428f10b..dce84459 100644 --- a/debian/deepin-screensaver-xscreensaver-data.install +++ b/debian/deepin-screensaver-xscreensaver-data.install @@ -2,3 +2,6 @@ usr/lib/deepin-screensaver/modules/* usr/share/deepin-custom-screensaver/translations/*.qm etc/deepin-screensaver/deepin-custom-screensaver/*.desktop usr/share/dsg/configs/org.deepin.screensaver/org.deepin.customscreensaver.json +usr/share/deepin-web-screensaver/translations/*.qm +etc/deepin-screensaver/deepin-web-screensaver/*.desktop +usr/share/dsg/configs/org.deepin.screensaver/org.deepin.webscreensaver.json \ No newline at end of file