ukui-settings-daemon/0000775000175000017500000000000015174103014013550 5ustar fengfengukui-settings-daemon/plugins/0000775000175000017500000000000015174102667015246 5ustar fengfengukui-settings-daemon/plugins/housekeeping/0000775000175000017500000000000015174103014017717 5ustar fengfengukui-settings-daemon/plugins/housekeeping/housekeeping.pro0000664000175000017500000000202015174103014023121 0ustar fengfengQT += gui QT += core widgets TARGET = housekeeping TEMPLATE = lib DEFINES += HOUSEKEPPING_LIBRARY MODULE_NAME=\\\"housekeeping\\\" CONFIG += c++20 no_keywords link_pkgconfig plugin DEFINES += QT_DEPRECATED_WARNINGS include($$PWD/../../common/common.pri) PKGCONFIG += gtk+-3.0 glib-2.0 harfbuzz gmodule-2.0 \ libxklavier gobject-2.0 gio-2.0 gio-unix-2.0 \ cairo cairo-gobject INCLUDEPATH += \ -I $$PWD/../.. \ -I ukui-settings-daemon/ SOURCES += \ housekeeping-manager.cpp \ housekeeping-plugin.cpp \ ldsm-trash-empty.cpp \ usd-disk-space.cpp \ usd-ldsm-dialog.cpp HEADERS += \ housekeeping-manager.h \ housekeeping-plugin.h \ ldsm-trash-empty.h \ usd-disk-space.h \ usd-ldsm-dialog.h housekeeping_lib.path = $${PLUGIN_INSTALL_DIRS} housekeeping_lib.files = $$OUT_PWD/libhousekeeping.so INSTALLS += housekeeping_lib FORMS += \ ldsm-trash-empty.ui \ usd-ldsm-dialog.ui RESOURCES += \ trash_empty.qrc ukui-settings-daemon/plugins/housekeeping/usd-ldsm-dialog.h0000664000175000017500000000506315174103014023061 0ustar fengfeng/* -*- Mode: C++; indent-tabs-mode: nil; tab-width: 4 -*- * -*- coding: utf-8 -*- * * Copyright (C) 2023 KylinSoft Co., Ltd. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef USDLDSMDIALOG_H #define USDLDSMDIALOG_H #include #include #include #include #include #include #include "QGSettings/qgsettings.h" #define SETTINGS_SCHEMA "org.ukui.SettingsDaemon.plugins.housekeeping" #define SETTINGS_IGNORE_PATHS "ignore-paths" #define LDSM_DIALOG_IGNORE 10 #define LDSM_DIALOG_RESPONSE_ANALYZE 30 #define LDSM_DIALOG_RESPONSE_EMPTY_TRASH 40 QT_BEGIN_NAMESPACE namespace Ui { class LdsmDialog; } QT_END_NAMESPACE class LdsmDialog : public QDialog { Q_OBJECT public: LdsmDialog(QWidget *parent = nullptr); LdsmDialog(bool other_usable_partitions,bool other_partitions,bool display_baobab,bool has_trash, long space_remaining,QString partition_name,QString mount_path, QWidget *parent = nullptr); ~LdsmDialog(); private: Ui::LdsmDialog *ui; QLabel* picture_label; QLabel* primary_label; QScrollArea *scroll_area; QCheckBox* ignore_check_button; QPushButton* trash_empty = nullptr; QPushButton* ignore_button; QPushButton* analyze_button; QDialog* m_dialog; QGSettings* m_fontSetting; bool other_usable_partitions; bool other_partitions; bool has_trash; long space_remaining; /*char *partition_name; char *mount_path;*/ QString partition_name; QString mount_path; public: void checkButtonClicked(int); void checkButtonIgnore (); void checkButtonAnalyze (); void checkButtonTrashEmpty(); public Q_SLOTS: void updateText(QString key); void resetFont(QWidget *pWid, QString str); private: void windowLayoutInit(bool display_baobab); QString getPrimaryText(); QString getCheckButtonText(); void allConnectEvent(bool display_baobab); }; #endif // USDLDSMDIALOG_H ukui-settings-daemon/plugins/housekeeping/warning.png0000664000175000017500000000034015174102667022104 0ustar fengfengPNG  IHDR g PLTEe-g tRNS@fIDATU 0 P2ܙ%KQzD'SiQOeט =~(ؖ -0i ((ZڑćȄ 14u(a}*Q8*3W. */ #ifndef LDSMTRASHEMPTY_H #define LDSMTRASHEMPTY_H #include #include #include #include #include #include "QGSettings/qgsettings.h" namespace Ui { class LdsmTrashEmpty; } class LdsmTrashEmpty : public QDialog { Q_OBJECT public: explicit LdsmTrashEmpty(QWidget *parent = nullptr); ~LdsmTrashEmpty(); void usdLdsmTrashEmpty(); public Q_SLOTS: void checkButtonCancel(); void checkButtonTrashEmpty(); void updateText(QString key); void resetFont(QWidget *pWid, QString str); private: Ui::LdsmTrashEmpty *ui; QLabel *first_text; QLabel *second_text; QScrollArea *second_text_area; QPushButton *trash_empty; QPushButton *cancel; QGSettings* m_fontSetting; private: void windowLayoutInit(); void connectEvent(); void deleteContents(const QString path); }; #endif // LDSMTRASHEMPTY_H ukui-settings-daemon/plugins/housekeeping/trash_empty.qrc0000664000175000017500000000014515174102667023002 0ustar fengfeng warning.png ukui-settings-daemon/plugins/housekeeping/housekeeping-manager.h0000664000175000017500000000320615174103014024167 0ustar fengfeng/* -*- Mode: C++; indent-tabs-mode: nil; tab-width: 4 -*- * -*- coding: utf-8 -*- * * Copyright (C) 2023 KylinSoft Co., Ltd. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef HOUSEKEEPINGMANAGER_H #define HOUSEKEEPINGMANAGER_H #include #include #include #include #include #include #include "usd-disk-space.h" extern "C"{ #include "config.h" } class HousekeepingManager : public QObject { Q_OBJECT public: HousekeepingManager(); HousekeepingManager(HousekeepingManager&)=delete; ~HousekeepingManager(); bool HousekeepingManagerStart(); void HousekeepingManagerStop(); public: void settings_changed_callback(QString); void do_cleanup_soon(); void purge_thumbnail_cache (); void do_cleanup (); void do_cleanup_once (); private: static HousekeepingManager *mHouseManager; static DiskSpace *mDisk; QTimer *long_term_handler; QTimer *short_term_handler; QGSettings *settings; }; #endif // HOUSEKEEPINGMANAGER_H ukui-settings-daemon/plugins/housekeeping/usd-ldsm-dialog.cpp0000664000175000017500000002357015174103014023417 0ustar fengfeng/* -*- Mode: C++; indent-tabs-mode: nil; tab-width: 4 -*- * -*- coding: utf-8 -*- * * Copyright (C) 2023 KylinSoft Co., Ltd. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include "usd-ldsm-dialog.h" #include "ui_usd-ldsm-dialog.h" #include #include #include #include #include #include #include #include #include #include #include #include #include "clib-syslog.h" #include "usd_global_define.h" LdsmDialog::LdsmDialog(QWidget *parent) : QDialog(parent) , ui(new Ui::LdsmDialog) { ui->setupUi(this); } LdsmDialog::LdsmDialog(bool other_usable_partitions,bool other_partitions,bool display_baobab,bool has_trash, long space_remaining,QString partition_name,QString mount_path, QWidget *parent) : QDialog(parent) , ui(new Ui::LdsmDialog) { ui->setupUi(this); this->other_usable_partitions=other_usable_partitions; this->other_partitions=other_partitions; this->has_trash=has_trash; this->space_remaining=space_remaining; this->partition_name=partition_name; this->mount_path=mount_path; this->analyze_button=nullptr; m_fontSetting = new QGSettings(UKUI_STYLE_SCHEMA, QByteArray(), this); connect(m_fontSetting, SIGNAL(changed(QString)), this, SLOT(updateText(QString))); windowLayoutInit(display_baobab); allConnectEvent(display_baobab); } LdsmDialog::~LdsmDialog() { if (ui) { delete ui; ui = nullptr; } if (picture_label) { delete picture_label; picture_label = nullptr; } if (primary_label) { delete primary_label; primary_label = nullptr; } if (ignore_check_button) { delete ignore_check_button; ignore_check_button = nullptr; } if (ignore_button) { delete ignore_button; ignore_button = nullptr; } if(this->has_trash) { delete trash_empty; trash_empty = nullptr; } if(analyze_button) { delete analyze_button; analyze_button = nullptr; } } void LdsmDialog::windowLayoutInit(bool display_baobab) { QFont font; Qt::WindowFlags flags=Qt::Dialog; QRect desk_rect; if (QGuiApplication::screenAt(QCursor::pos()) == nullptr) { desk_rect = QGuiApplication::primaryScreen()->geometry(); } else { desk_rect = QGuiApplication::screenAt(QCursor::pos())->geometry(); } flags |=Qt::WindowMinMaxButtonsHint; flags |=Qt::WindowCloseButtonHint; setWindowFlags(flags); setAttribute(Qt::WA_AlwaysShowToolTips, true); setFixedSize(660,210); setWindowIcon(QIcon::fromTheme("dialog-warning")); int dialog_width=width(); int dialog_height=height(); int rect_width=desk_rect.width(); int rect_height=desk_rect.height(); setWindowTitle(tr("Low Disk Space")); this->move((rect_width-dialog_width)/2+desk_rect.left(),(rect_height-dialog_height)/2+desk_rect.top()); picture_label = new QLabel(this); primary_label = new QLabel(this); scroll_area = new QScrollArea(this); ignore_check_button = new QCheckBox(this); ignore_button=new QPushButton(this); picture_label->setProperty("Name", "picture_label"); primary_label->setProperty("Name", "primary_label"); scroll_area->setProperty("Name", "scroll_area"); scroll_area->setFrameShape(QFrame::NoFrame); ignore_check_button->setProperty("Name", "ignore_check_button"); ignore_button->setProperty("Name", "ignore_button"); //warning picture picture_label->setGeometry(20,40,32,32); picture_label->setAlignment(Qt::AlignCenter); picture_label->setStyleSheet(QString("border-image:url(../ldsm_dialog/warning.png);")); //warning information text scroll_area->setGeometry(50, 20, 560, 40*2); scroll_area->setWidget(primary_label); scroll_area->setWidgetResizable(true); primary_label->setGeometry(50, 20, 560, 40*2); primary_label->setWordWrap(true); primary_label->setAlignment(Qt::AlignLeft); primary_label->setText(getPrimaryText()); // primary_label->adjustSize(); //gsettings set box ignore_check_button->setGeometry(70,120,400,30); ignore_check_button->setText(getCheckButtonText()); ignore_button->setGeometry(dialog_width-110,dialog_height-55,96,36); ignore_button->setText(tr("Confirm")); if(this->has_trash){ trash_empty = new QPushButton(this); trash_empty->setProperty("Name", "trash_empty_button"); trash_empty->setGeometry(dialog_width-240,dialog_height-55,96,36); trash_empty->setText(tr("Empty Trash")); } if(display_baobab){ analyze_button = new QPushButton(this); analyze_button->setText(tr("Examine")); if(this->has_trash) analyze_button->setGeometry(dialog_width-320,dialog_height-55,96,36); else analyze_button->setGeometry(dialog_width-215,dialog_height-55,96,36); } updateText(""); } QString LdsmDialog::getPrimaryText() { char* free_space = g_format_size(space_remaining); return QString(tr("The remaining space of drive \"%1\" is less than %2, "\ "clear the garbage or move the data to another disk in time.")).arg(partition_name).arg(free_space); } QString LdsmDialog::getCheckButtonText() { return QString(tr("Messages that no longer remind this disk")); } void LdsmDialog::allConnectEvent(bool display_baobab) { connect(ignore_check_button, &QCheckBox::stateChanged, this, &LdsmDialog::checkButtonClicked); connect(ignore_button, &QPushButton::clicked, this, &LdsmDialog::checkButtonIgnore); if(has_trash) connect(trash_empty, &QPushButton::clicked, this, &LdsmDialog::checkButtonTrashEmpty); if(display_baobab) connect(analyze_button, &QPushButton::clicked, this, &LdsmDialog::checkButtonAnalyze); if(sender() == ignore_button) { USD_LOG(LOG_DEBUG,"Ignore button pressed!"); } else { USD_LOG(LOG_DEBUG,"Other button pressed!"); } } //update gsettings "ignore-paths" key contents bool update_ignore_paths(QList** ignore_paths,QString mount_path,bool ignore) { bool found=(*ignore_paths)->contains(mount_path.toLatin1().data()); if(ignore && found==false){ (*ignore_paths)->push_front(mount_path.toLatin1().data()); return true; } if(!ignore && found==true){ (*ignore_paths)->removeOne(mount_path.toLatin1().data()); return true; } return false; } /****************slots*********************/ void LdsmDialog::checkButtonIgnore() { done(LDSM_DIALOG_IGNORE); } void LdsmDialog::checkButtonTrashEmpty() { done(LDSM_DIALOG_RESPONSE_EMPTY_TRASH); } void LdsmDialog::updateText(QString key) { USD_LOG(LOG_DEBUG,"get key:%s",key.toLatin1().data()); if(has_trash) { resetFont(trash_empty, tr("Empty Trash")); } resetFont(ignore_button, tr("Confirm")); } void LdsmDialog::resetFont(QWidget *pWid, QString str) { QPushButton *pBtn = nullptr; QLabel *pLbl = nullptr; int fontWidth = 0; int btnWidth = 0; if (pWid->property("Name").toString().contains("button")) { pBtn = static_cast(pWid); } else if (pWid->property("Name").toString().contains("label")) { pLbl = static_cast(pWid); } else { return; } QFontMetrics qFm(pWid->font()); fontWidth = qFm.horizontalAdvance(str); if (pBtn != nullptr) { btnWidth = pBtn->width() - 7; if (fontWidth >= btnWidth) { QString elideNote = qFm.elidedText(pBtn->text(), Qt::ElideRight, btnWidth); pBtn->setText(elideNote); pBtn->setToolTip(str); } else { pBtn->setText(str); pBtn->setToolTip(""); } } else { btnWidth = pLbl->width() - 7; if (fontWidth >= btnWidth) { QString elideNote = qFm.elidedText(pLbl->text(), Qt::ElideRight, btnWidth); pLbl->setText(elideNote); pLbl->setToolTip(str); } else { pLbl->setText(str); pLbl->setToolTip(""); } } } void LdsmDialog::checkButtonAnalyze() { done(LDSM_DIALOG_RESPONSE_ANALYZE); } void LdsmDialog::checkButtonClicked(int state) { QGSettings* settings; QStringList ignore_list; QStringList ignoreStr; QList* ignore_paths; bool ignore,updated; int i; QList::iterator l; ignore_paths =new QList(); settings = new QGSettings(SETTINGS_SCHEMA); //get contents from "ignore-paths" key if (!settings->get(SETTINGS_IGNORE_PATHS).toStringList().isEmpty()) ignore_list.append(settings->get(SETTINGS_IGNORE_PATHS).toStringList()); for(auto str: ignore_list){ if(!str.isEmpty()) ignore_paths->push_back(str); } ignore = state; updated = update_ignore_paths(&ignore_paths, mount_path, ignore); if(updated){ for(l = ignore_paths->begin(); l != ignore_paths->end(); ++l){ ignoreStr.append(*l); } //set latest contents to gsettings "ignore-paths" key settings->set(SETTINGS_IGNORE_PATHS, QVariant::fromValue(ignoreStr)); } //free QList Memory if(ignore_paths){ ignore_paths->clear(); } delete settings; } ukui-settings-daemon/plugins/housekeeping/usd-ldsm-dialog.ui0000664000175000017500000000065415174102667023265 0ustar fengfeng LdsmDialog 0 0 800 600 LdsmDialog ukui-settings-daemon/plugins/housekeeping/housekeeping-plugin.h0000664000175000017500000000261615174103014024057 0ustar fengfeng/* -*- Mode: C++; indent-tabs-mode: nil; tab-width: 4 -*- * -*- coding: utf-8 -*- * * Copyright (C) 2023 KylinSoft Co., Ltd. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef HOUSEKEPPINGPLUGIN_H #define HOUSEKEPPINGPLUGIN_H #include "housekeeping-manager.h" #include "plugin-interface.h" class HousekeepingPlugin : public PluginInterface { public: ~HousekeepingPlugin(); static PluginInterface *getInstance(); virtual void activate(); virtual void deactivate(); bool isInTrialMode(); private: HousekeepingPlugin(); HousekeepingPlugin(HousekeepingPlugin&)=delete; private: QString userName; HousekeepingManager *mHouseManager; static PluginInterface *mInstance; }; extern "C" Q_DECL_EXPORT PluginInterface *createSettingsPlugin(); #endif // HOUSEKEPPINGPLUGIN_H ukui-settings-daemon/plugins/housekeeping/ldsm-trash-empty.cpp0000664000175000017500000001553615174103014023647 0ustar fengfeng/* -*- Mode: C++; indent-tabs-mode: nil; tab-width: 4 -*- * -*- coding: utf-8 -*- * * Copyright (C) 2023 KylinSoft Co., Ltd. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include "ldsm-trash-empty.h" #include "ui_ldsm-trash-empty.h" #include #include #include #include #include #include // #include #include #include #include #include #include #include "clib-syslog.h" LdsmTrashEmpty::LdsmTrashEmpty(QWidget *parent) : QDialog(parent), ui(new Ui::LdsmTrashEmpty) { ui->setupUi(this); m_fontSetting = new QGSettings(UKUI_STYLE_SCHEMA, QByteArray(), this); connect(m_fontSetting, SIGNAL(changed(QString)), this, SLOT(updateText(QString))); windowLayoutInit(); connectEvent(); } LdsmTrashEmpty::~LdsmTrashEmpty() { if (ui) { delete ui; ui = nullptr; } if (first_text) { delete first_text; first_text = nullptr; } if (second_text) { delete second_text; second_text = nullptr; } if (trash_empty) { delete trash_empty; trash_empty = nullptr; } if (cancel) { delete cancel; cancel = nullptr; } } void LdsmTrashEmpty::windowLayoutInit() { QFont font; Qt::WindowFlags flags=Qt::Dialog; flags |=Qt::WindowMinMaxButtonsHint; flags |=Qt::WindowCloseButtonHint; QRect desk_rect; if (QGuiApplication::screenAt(QCursor::pos()) == nullptr) { desk_rect = QGuiApplication::primaryScreen()->geometry(); } else { desk_rect = QGuiApplication::screenAt(QCursor::pos())->geometry(); } setWindowFlags(flags); setAttribute(Qt::WA_AlwaysShowToolTips, true); setFixedSize(650,180); setWindowTitle(tr("Emptying the trash")); setWindowIcon(QIcon::fromTheme("user-trash-full")); int dialog_width=width(); int dialog_height=height(); int rect_width=desk_rect.width(); int rect_height=desk_rect.height(); this->move((rect_width-dialog_width)/2+desk_rect.left(),(rect_height-dialog_height)/2+desk_rect.top()); first_text=new QLabel(this); second_text=new QLabel(this); trash_empty=new QPushButton(this); cancel=new QPushButton(this); second_text_area = new QScrollArea(this); first_text->setProperty("Name","first_text_label"); second_text->setProperty("Name","second_text_label"); trash_empty->setProperty("Name","trash_empty_button"); cancel->setProperty("Name","cancel_button"); first_text->setGeometry(66,20,560,30); font.setBold(true); first_text->setFont(font); first_text->setText(tr("Empty all of the items from the trash?")); second_text_area->setGeometry(66,50,560,30*2); second_text_area->setWidget(second_text); second_text_area->setFrameShape(QFrame::NoFrame); second_text_area->setWidgetResizable(true); second_text->setGeometry(66,50,560,30*2); second_text->setWordWrap(true); second_text->setAlignment(Qt::AlignLeft); second_text->setText(tr("If you choose to empty the trash, all items in it will be permanently lost." \ "Please note that you can also delete them separately.")); cancel->setGeometry(dialog_width-110,dialog_height-55,96,36); cancel->setText(tr("cancel")); trash_empty->setGeometry(dialog_width-240,dialog_height-55,96,36); trash_empty->setText(tr("Empty Trash")); updateText(""); } void LdsmTrashEmpty::usdLdsmTrashEmpty() { this->exec(); } void LdsmTrashEmpty::connectEvent() { connect(trash_empty,SIGNAL(clicked()),this,SLOT(checkButtonTrashEmpty())); connect(cancel,SIGNAL(clicked()),this,SLOT(checkButtonCancel())); } void LdsmTrashEmpty::deleteContents(const QString path) { QDir dir(path); QFileInfoList fileList; QFileInfo curFile; if(!dir.exists()) return; fileList=dir.entryInfoList(QDir::Files|QDir::Dirs|QDir::Readable|QDir::Writable| QDir::Hidden|QDir::NoDotAndDotDot,QDir::Name); while(fileList.size()>0) { int infoNum=fileList.size(); for(int i=infoNum-1;i>=0;i--) { curFile=fileList[i]; if(curFile.isFile()) { QFile fileTemp(curFile.filePath()); fileTemp.remove(); } if(curFile.isDir()) { QDir dirTemp(curFile.filePath()); dirTemp.removeRecursively(); } fileList.removeAt(i); } } } void LdsmTrashEmpty::updateText(QString key) { USD_LOG(LOG_DEBUG,"get key:%s",key.toLatin1().data()); resetFont(trash_empty, tr("Empty Trash")); resetFont(first_text, tr("Empty all of the items from the trash?")); resetFont(cancel, tr("cancel")); } void LdsmTrashEmpty::resetFont(QWidget *pWid, QString str) { QPushButton *pBtn = nullptr; QLabel *pLbl = nullptr; int fontWidth = 0; int btnWidth = 0; USD_LOG(LOG_DEBUG,"get Wid:%s",pWid->property("Name").toString().toLatin1().data()); if (pWid->property("Name").toString().contains("button")) { pBtn = static_cast(pWid); } else if (pWid->property("Name").toString().contains("label")) { pLbl = static_cast(pWid); } else { return; } QFontMetrics qFm(pWid->font()); fontWidth = qFm.horizontalAdvance(str); if (pBtn != nullptr) { btnWidth = pBtn->width() - 7; if (fontWidth >= btnWidth) { QString elideNote = qFm.elidedText(pBtn->text(), Qt::ElideRight, btnWidth); pBtn->setText(elideNote); pBtn->setToolTip(str); } else { pBtn->setText(str); pBtn->setToolTip(""); } } else { btnWidth = pLbl->width() - 7; if (fontWidth >= btnWidth) { QString elideNote = qFm.elidedText(pLbl->text(), Qt::ElideRight, btnWidth); pLbl->setText(elideNote); pLbl->setToolTip(str); } else { pLbl->setText(str); pLbl->setToolTip(""); } } } void LdsmTrashEmpty::checkButtonTrashEmpty() { QString trash_path; trash_path=QDir::homePath()+"/.local/share/Trash"; deleteContents(trash_path); this->accept(); } void LdsmTrashEmpty::checkButtonCancel() { this->accept(); } ukui-settings-daemon/plugins/housekeeping/usd-disk-space.h0000664000175000017500000000550115174103014022705 0ustar fengfeng/* -*- Mode: C++; indent-tabs-mode: nil; tab-width: 4 -*- * -*- coding: utf-8 -*- * * Copyright (C) 2023 KylinSoft Co., Ltd. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef DISKSPACE_H #define DISKSPACE_H #include #include #include #include "usd-ldsm-dialog.h" #include "config.h" #include #include #include #include #include #include #include #include #include #include #include typedef struct { GUnixMountEntry *mount; struct statvfs buf; time_t notify_time; } LdsmMountInfo; class DiskSpace : public QObject { Q_OBJECT public: DiskSpace(); ~DiskSpace(); void UsdLdsmSetup (bool check_now); void UsdLdsmClean (); void usdLdsmGetConfig (); bool ldsm_mount_is_user_ignore (const char *path); bool ldsm_mount_should_ignore (GUnixMountEntry *mount); bool ldsm_mount_has_space (LdsmMountInfo *mount); void ldsm_maybe_warn_mounts (GList *mounts, bool multiple_volumes, bool other_usable_volumes); bool ldsm_notify_for_mount (LdsmMountInfo *mount, bool multiple_volumes, bool other_usable_volumes); static void ldsm_mounts_changed (GObject *monitor,gpointer data,DiskSpace *disk); bool ldsmGetIgnorePath(const gchar *path); bool ldsm_check_all_mounts(); public Q_SLOTS: void usdLdsmUpdateConfig(QString); private: void cleanNotifyHash(); DiskSpace *mDisk; GHashTable *ldsm_notified_hash ; QHash m_notified_hash; QTimer *ldsm_timeout_cb; GUnixMountMonitor *ldsm_monitor; double free_percent_notify; double free_percent_notify_again; unsigned int free_size_gb_no_notify; unsigned int min_notify_period; GSList *ignore_paths; QGSettings *settings; LdsmDialog *dialog; LdsmTrashEmpty *trash_empty; QVariantList ignoreList; bool done; }; #endif // DISKSPACE_H ukui-settings-daemon/plugins/housekeeping/housekeeping-manager.cpp0000664000175000017500000001754615174103014024536 0ustar fengfeng/* -*- Mode: C++; indent-tabs-mode: nil; tab-width: 4 -*- * -*- coding: utf-8 -*- * * Copyright (C) 2023 KylinSoft Co., Ltd. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include "housekeeping-manager.h" #include "clib-syslog.h" #include "qtimer.h" #include #include /* General */ #define INTERVAL_ONCE_A_DAY 24*60*60*1000 #define INTERVAL_TWO_MINUTES 1 //#define INTERVAL_TWO_MINUTES 60*2000 /* Thumbnail cleaner */ #define THUMB_CACHE_SCHEMA "org.mate.thumbnail-cache" #define THUMB_CACHE_KEY_AGE "maximum-age" #define THUMB_CACHE_KEY_SIZE "maximum-size" HousekeepingManager *HousekeepingManager::mHouseManager = nullptr; DiskSpace *HousekeepingManager::mDisk = nullptr; typedef struct { long now; long max_age; signed long total_size; signed long max_size; } PurgeData; typedef struct { time_t mtime; char *path; long size; } ThumbData; /* * 初始化DIskSpace, QGSettings,两个QTimer */ HousekeepingManager::HousekeepingManager() { mDisk = new DiskSpace(); settings = new QGSettings(THUMB_CACHE_SCHEMA); long_term_handler = new QTimer(this); short_term_handler = new QTimer(this); connect(long_term_handler, &QTimer::timeout, this, &HousekeepingManager::do_cleanup); connect(short_term_handler, &QTimer::timeout, this, &HousekeepingManager::do_cleanup_once); } /* * 清理DIskSpace, QGSettings,两个QTimer */ HousekeepingManager::~HousekeepingManager() { if (mDisk) { delete mDisk; mDisk = nullptr; } if (settings) { delete settings; settings = nullptr; } if (long_term_handler) { delete long_term_handler; long_term_handler = nullptr; } if (short_term_handler) { delete short_term_handler; short_term_handler = nullptr; } } static GList * read_dir_for_purge (const char *path, GList *files) { GFile *read_path; GFileEnumerator *enum_dir; if (opendir(path) == NULL) return files; read_path = g_file_new_for_path (path); enum_dir = g_file_enumerate_children (read_path, G_FILE_ATTRIBUTE_STANDARD_NAME "," G_FILE_ATTRIBUTE_TIME_MODIFIED "," G_FILE_ATTRIBUTE_STANDARD_SIZE, G_FILE_QUERY_INFO_NONE, NULL, NULL); if (enum_dir != NULL) { GFileInfo *info; while ((info = g_file_enumerator_next_file (enum_dir, NULL, NULL)) != NULL) { const char *name; name = g_file_info_get_name (info); if (strlen (name) == 36 && strcmp (name + 32, ".png") == 0) { ThumbData *td; GFile *entry; char *entry_path; GTimeVal mod_time; entry = g_file_get_child (read_path, name); entry_path = g_file_get_path (entry); g_object_unref (entry); g_file_info_get_modification_time (info, &mod_time); td = g_new0 (ThumbData, 1); td->path = entry_path; td->mtime = mod_time.tv_sec; td->size = g_file_info_get_size (info); files = g_list_prepend (files, td); } g_object_unref (info); } g_object_unref (enum_dir); } g_object_unref (read_path); return files; } static void purge_old_thumbnails (ThumbData *info, PurgeData *purge_data) { if ((purge_data->now - info->mtime) > purge_data->max_age) { g_unlink (info->path); info->size = 0; } else { purge_data->total_size += info->size; } } static int sort_file_mtime (ThumbData *file1, ThumbData *file2) { return file1->mtime - file2->mtime; } static void thumb_data_free (gpointer data) { ThumbData *info = (ThumbData *)data; if (info) { g_free (info->path); g_free (info); } } void HousekeepingManager::purge_thumbnail_cache () { char *path; GList *files; PurgeData purge_data; GTimeVal current_time; purge_data.max_age = settings->get(THUMB_CACHE_KEY_AGE).toInt() * 24 * 60 * 60; purge_data.max_size = settings->get(THUMB_CACHE_KEY_SIZE).toInt() * 1024 * 1024; /* if both are set to -1, we don't need to read anything */ if ((purge_data.max_age < 0) && (purge_data.max_size < 0)) return; path = g_build_filename (g_get_user_cache_dir (), "thumbnails", "normal", NULL); files = read_dir_for_purge (path, NULL); g_free (path); path = g_build_filename (g_get_user_cache_dir (), "thumbnails", "large", NULL); files = read_dir_for_purge (path, files); g_free (path); path = g_build_filename (g_get_user_cache_dir (), "thumbnails", "fail", "ukui-thumbnail-factory", NULL); files = read_dir_for_purge (path, files); g_free (path); g_get_current_time (¤t_time); purge_data.now = current_time.tv_sec; purge_data.total_size = 0; if (purge_data.max_age >= 0) g_list_foreach (files, (GFunc) purge_old_thumbnails, &purge_data); if ((purge_data.total_size > purge_data.max_size) && (purge_data.max_size >= 0)) { GList *scan; files = g_list_sort (files, (GCompareFunc) sort_file_mtime); for (scan = files; scan && (purge_data.total_size > purge_data.max_size); scan = scan->next) { ThumbData *info = (ThumbData *)scan->data; g_unlink (info->path); purge_data.total_size -= info->size; } } g_list_foreach (files, (GFunc) thumb_data_free, NULL); g_list_free (files); } void HousekeepingManager::do_cleanup () { purge_thumbnail_cache (); } void HousekeepingManager::do_cleanup_once () { do_cleanup (); short_term_handler->stop(); } void HousekeepingManager::do_cleanup_soon() { short_term_handler->start(INTERVAL_TWO_MINUTES); } void HousekeepingManager::settings_changed_callback(QString key) { do_cleanup_soon(); } bool HousekeepingManager::HousekeepingManagerStart() { mDisk->UsdLdsmSetup(false); connect (settings, &QGSettings::changed, this,&HousekeepingManager::settings_changed_callback); /* Clean once, a few minutes after start-up */ do_cleanup_soon(); long_term_handler->start(INTERVAL_ONCE_A_DAY); return true; } void HousekeepingManager::HousekeepingManagerStop() { // 时间 if (short_term_handler) { short_term_handler->stop(); } // 时间 if (long_term_handler) { long_term_handler->stop(); /* Do a clean-up on shutdown if and only if the size or age * limits have been set to a paranoid level of cleaning (zero) */ if ((settings->get(THUMB_CACHE_KEY_AGE).toInt() == 0) || (settings->get(THUMB_CACHE_KEY_SIZE).toInt() == 0)) { do_cleanup (); } } mDisk->UsdLdsmClean(); } ukui-settings-daemon/plugins/housekeeping/housekeeping-plugin.cpp0000664000175000017500000000663015174103014024412 0ustar fengfeng/* -*- Mode: C++; indent-tabs-mode: nil; tab-width: 4 -*- * -*- coding: utf-8 -*- * * Copyright (C) 2023 KylinSoft Co., Ltd. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include #include #include #include #include #include "usd_base_class.h" #include "housekeeping-plugin.h" #include "clib-syslog.h" PluginInterface *HousekeepingPlugin::mInstance=nullptr; QString getCurrentUserName() { QString name; if (name.isEmpty()) { QStringList envList = QProcess::systemEnvironment(); for(const QString& env : envList){ if (env.startsWith("USERNAME")) { QStringList strList = env.split('='); if (strList.size() > 2) { name = strList[1]; } } } } if (!name.isEmpty()) return name; QProcess process; process.start("whoami", QStringList()); process.waitForFinished(); name = QString::fromLocal8Bit(process.readAllStandardOutput()).trimmed(); return name.isEmpty() ? QString("User") : name; } HousekeepingPlugin::HousekeepingPlugin() { if (isInTrialMode()) { USD_LOG(LOG_DEBUG,"TrialMode..."); return; } userName = getCurrentUserName(); if (userName.compare("lightdm") != 0) { mHouseManager = new HousekeepingManager(); if (!mHouseManager) USD_LOG(LOG_ERR,"Unable to start Housekeeping Manager!"); } } HousekeepingPlugin::~HousekeepingPlugin() { if (mHouseManager) { delete mHouseManager; mHouseManager = nullptr; } } bool HousekeepingPlugin::isInTrialMode() { QString str = ""; QStringList symbList ; QFile file("/proc/cmdline"); if (file.open(QIODevice::ReadOnly)) { QByteArray data = file.readAll(); str = QString::fromLocal8Bit(data); symbList = str.split("\r\n"); } USD_LOG(LOG_DEBUG,"cmdline:%s",str.toLatin1().data()); file.close(); if (str.contains("boot=casper")) { return true; } if (getuid() == 999) return true; return false; } void HousekeepingPlugin::activate() { if (isInTrialMode()) {//TrialMode disable this plugin USD_LOG(LOG_DEBUG,"TrialMode..."); return; } if (userName.compare("lightdm") != 0) { USD_LOG(LOG_DEBUG,"Housekeeping Manager Is Start"); mHouseManager->HousekeepingManagerStart(); } } PluginInterface *HousekeepingPlugin::getInstance() { if (nullptr == mInstance) { mInstance = new HousekeepingPlugin(); } return mInstance; } void HousekeepingPlugin::deactivate() { if(isInTrialMode()) { return; } if (mHouseManager) { mHouseManager->HousekeepingManagerStop(); } } PluginInterface *createSettingsPlugin() { return HousekeepingPlugin::getInstance(); } ukui-settings-daemon/plugins/housekeeping/usd-disk-space.cpp0000664000175000017500000005374615174103014023256 0ustar fengfeng/* -*- Mode: C++; indent-tabs-mode: nil; tab-width: 4 -*- * -*- coding: utf-8 -*- * * Copyright (C) 2023 KylinSoft Co., Ltd. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include "usd-disk-space.h" #include #include "qtimer.h" #include "syslog.h" #include "clib-syslog.h" #define GIGABYTE 1024 * 1024 * 1024 #define CHECK_EVERY_X_SECONDS 120 * 1000 #define DISK_SPACE_ANALYZER "ukui-disk-usage-analyzer" #define SETTINGS_HOUSEKEEPING_SCHEMA "org.ukui.SettingsDaemon.plugins.housekeeping" #define SETTINGS_FREE_PC_NOTIFY_KEY "free-percent-notify" #define SETTINGS_FREE_PC_NOTIFY_AGAIN_KEY "free-percent-notify-again" #define SETTINGS_FREE_SIZE_NO_NOTIFY "free-size-gb-no-notify" #define SETTINGS_MIN_NOTIFY_PERIOD "min-notify-period" #define SETTINGS_IGNORE_PATHS "ignore-paths" static guint64 *time_read; DiskSpace::DiskSpace() { ldsm_timeout_cb = new QTimer(); trash_empty=new LdsmTrashEmpty(); ldsm_notified_hash=NULL; ldsm_monitor = NULL; free_percent_notify = 0.05; free_percent_notify_again = 0.01; free_size_gb_no_notify = 2; min_notify_period = 10; ignore_paths = NULL; done = FALSE; connect(ldsm_timeout_cb, &QTimer::timeout, this, &DiskSpace::ldsm_check_all_mounts); ldsm_timeout_cb->start(); if (QGSettings::isSchemaInstalled(SETTINGS_HOUSEKEEPING_SCHEMA)) { settings = new QGSettings(SETTINGS_HOUSEKEEPING_SCHEMA); } this->dialog = nullptr; } DiskSpace::~DiskSpace() { delete trash_empty; delete settings; } static gint ldsm_ignore_path_compare (gconstpointer a, gconstpointer b) { return g_strcmp0 ((const gchar *)a, (const gchar *)b); } bool DiskSpace::ldsm_mount_is_user_ignore (const char *path) { if (g_slist_find_custom (ignore_paths, path, (GCompareFunc) ldsm_ignore_path_compare) != NULL) return TRUE; else return FALSE; } //static gboolean //ldsm_is_hash_item_in_ignore_paths (gpointer key, // gpointer value, // gpointer user_data) //{ // return this->ldsm_mount_is_user_ignore ((char *)key); //} void DiskSpace::usdLdsmGetConfig() { // 先取得清理提醒的百分比时机 free_percent_notify = settings->get(SETTINGS_FREE_PC_NOTIFY_KEY).toDouble(); if (free_percent_notify >= 1 || free_percent_notify < 0) { /* FIXME define min and max in gschema! */ qWarning ("housekeeping: Invalid configuration of free_percent_notify: %f\n" \ "Using sensible default", free_percent_notify); free_percent_notify = 0.05; } // 取得第二次提醒的百分比时机 free_percent_notify_again = settings->get(SETTINGS_FREE_PC_NOTIFY_AGAIN_KEY).toDouble(); if (free_percent_notify_again >= 1 || free_percent_notify_again < 0) { /* FIXME define min and max in gschema! */ qWarning ("housekeeping: Invalid configuration of free_percent_notify_again: %f\n" \ "Using sensible default\n", free_percent_notify_again); free_percent_notify_again = 0.01; } // 取得不通知的g free_size_gb_no_notify = settings->get(SETTINGS_FREE_SIZE_NO_NOTIFY).toUInt(); // 取得最小通知周期 min_notify_period = settings->get(SETTINGS_MIN_NOTIFY_PERIOD).toInt(); USD_LOG(LOG_DEBUG,"free_percent_notify:%f,free_size_gb_no_notify:%d",free_percent_notify,free_size_gb_no_notify); if (ignore_paths != NULL) { g_slist_foreach (ignore_paths, (GFunc) g_free, NULL); g_slist_free (ignore_paths); ignore_paths = NULL; } } static void ldsm_free_mount_info (gpointer data) { LdsmMountInfo *mount = (LdsmMountInfo *)data; g_return_if_fail (mount != NULL); g_unix_mount_free (mount->mount); g_free (mount); } void DiskSpace::usdLdsmUpdateConfig(QString key) { usdLdsmGetConfig(); } static gboolean is_hash_item_not_in_mounts(QHash &hash, GList* user_data) { for (GList *l = (GList *) user_data; l != NULL; l = l->next) { GUnixMountEntry *mount = (GUnixMountEntry *)l->data; const char *path; path = g_unix_mount_get_mount_path (mount); // 找到了,返回false if (hash.find(path) !=hash.end() ) return FALSE; } return TRUE; } static gboolean is_in (const gchar *value, const gchar *set[]) { int i; for (i = 0; set[i] != NULL; i++) { if (strcmp (set[i], value) == 0) return TRUE; } return FALSE; } bool DiskSpace::ldsm_mount_should_ignore (GUnixMountEntry *mount) { const gchar *fs, *device, *path; path = g_unix_mount_get_mount_path (mount); if (ldsm_mount_is_user_ignore (path)) return TRUE; /* This is borrowed from GLib and used as a way to determine * which mounts we should ignore by default. GLib doesn't * expose this in a way that allows it to be used for this * purpose */ /* We also ignore network filesystems */ const gchar *ignore_fs[] = { "adfs", "afs", "auto", "autofs", "autofs4", "cifs", "cxfs", "devfs", "devpts", "ecryptfs", "fdescfs", "gfs", "gfs2", "kernfs", "linprocfs", "linsysfs", "lustre", "lustre_lite", "ncpfs", "nfs", "nfs4", "nfsd", "ocfs2", "proc", "procfs", "ptyfs", "rpc_pipefs", "selinuxfs", "smbfs", "sysfs", "tmpfs", "usbfs", "zfs", NULL }; const gchar *ignore_devices[] = { "none", "sunrpc", "devpts", "nfsd", "/dev/loop", "/dev/vn", NULL }; fs = g_unix_mount_get_fs_type (mount); device = g_unix_mount_get_device_path (mount); if (is_in (fs, ignore_fs)) return TRUE; if (is_in (device, ignore_devices)) return TRUE; return FALSE; } bool DiskSpace::ldsm_mount_has_space (LdsmMountInfo *mount) { double free_space; bool percent_flag = false; bool size_falg = false; free_space = (double) mount->buf.f_bavail / (double) mount->buf.f_blocks; /* enough free space, nothing to do */ if (free_space > free_percent_notify) percent_flag = true; if (((gint64) mount->buf.f_frsize * (gint64) mount->buf.f_bavail) > ((gint64) free_size_gb_no_notify * GIGABYTE) || ((double) mount->buf.f_blocks *(gint64) mount->buf.f_frsize) < ((gint64) free_size_gb_no_notify * GIGABYTE)) { size_falg = true; } USD_LOG(LOG_DEBUG,"%s:(percent_flag:%d,size_falg:%d),f_frsize:%d,f_bavail:%d,f_blocks:%d,%f",g_unix_mount_get_mount_path(mount->mount),percent_flag,size_falg, mount->buf.f_frsize,mount->buf.f_bavail,mount->buf.f_blocks,free_percent_notify); /* If it returns false, then this volume is low on space */ return (percent_flag && size_falg); } static bool ldsm_mount_is_virtual (LdsmMountInfo *mount) { if (mount->buf.f_blocks == 0) { /* Filesystems with zero blocks are virtual */ return true; } return false; } static gchar* ldsm_get_fs_id_for_path (const gchar *path) { GFile *file; GFileInfo *fileinfo; gchar *attr_id_fs; file = g_file_new_for_path (path); fileinfo = g_file_query_info (file, G_FILE_ATTRIBUTE_ID_FILESYSTEM, G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS, NULL, NULL); if (fileinfo) { attr_id_fs = g_strdup (g_file_info_get_attribute_string (fileinfo, G_FILE_ATTRIBUTE_ID_FILESYSTEM)); g_object_unref (fileinfo); } else { attr_id_fs = NULL; } g_object_unref (file); return attr_id_fs; } static gboolean ldsm_mount_has_trash (LdsmMountInfo *mount) { const gchar *user_data_dir; gchar *user_data_attr_id_fs; gchar *path_attr_id_fs; gboolean mount_uses_user_trash = FALSE; gchar *trash_files_dir; gboolean has_trash = FALSE; GDir *dir; const gchar *path; user_data_dir = g_get_user_data_dir (); user_data_attr_id_fs = ldsm_get_fs_id_for_path (user_data_dir); path = g_unix_mount_get_mount_path (mount->mount); path_attr_id_fs = ldsm_get_fs_id_for_path (path); if (g_strcmp0 (user_data_attr_id_fs, path_attr_id_fs) == 0) { /* The volume that is low on space is on the same volume as our home * directory. This means the trash is at $XDG_DATA_HOME/Trash, * not at the root of the volume which is full. */ mount_uses_user_trash = TRUE; } g_free (user_data_attr_id_fs); g_free (path_attr_id_fs); /* I can't think of a better way to find out if a volume has any trash. Any suggestions? */ if (mount_uses_user_trash) { trash_files_dir = g_build_filename (g_get_user_data_dir (), "Trash", "files", NULL); } else { gchar *uid; uid = g_strdup_printf ("%d", getuid ()); trash_files_dir = g_build_filename (path, ".Trash", uid, "files", NULL); if (!g_file_test (trash_files_dir, G_FILE_TEST_IS_DIR)) { gchar *trash_dir; g_free (trash_files_dir); trash_dir = g_strdup_printf (".Trash-%s", uid); trash_files_dir = g_build_filename (path, trash_dir, "files", NULL); g_free (trash_dir); if (!g_file_test (trash_files_dir, G_FILE_TEST_IS_DIR)) { g_free (trash_files_dir); g_free (uid); return has_trash; } } g_free (uid); } dir = g_dir_open (trash_files_dir, 0, NULL); if (dir) { if (g_dir_read_name (dir)) has_trash = TRUE; g_dir_close (dir); } g_free (trash_files_dir); return has_trash; } static void ldsm_analyze_path (const gchar *path) { const gchar *argv[] = { DISK_SPACE_ANALYZER, path, NULL }; g_spawn_async (NULL, (gchar **) argv, NULL, G_SPAWN_SEARCH_PATH, NULL, NULL, NULL, NULL); } bool DiskSpace::ldsm_notify_for_mount (LdsmMountInfo *mount, bool multiple_volumes, bool other_usable_volumes) { gchar *name, *program; signed long free_space; int response; bool has_trash; bool has_disk_analyzer; bool retval = TRUE; char *path; /* Don't show a dialog if one is already displayed */ if (dialog) return retval; name = g_unix_mount_guess_name (mount->mount); free_space = (gint64) mount->buf.f_frsize * (gint64) mount->buf.f_bavail; has_trash = ldsm_mount_has_trash (mount); path = g_strdup (g_unix_mount_get_mount_path (mount->mount)); program = g_find_program_in_path (DISK_SPACE_ANALYZER); has_disk_analyzer = (program != NULL); g_free (program); dialog = new LdsmDialog (other_usable_volumes, multiple_volumes, has_disk_analyzer, has_trash, free_space, name, path); g_free (name); // dialog->show(); response = dialog->exec(); delete dialog; dialog = nullptr; switch (response) { case GTK_RESPONSE_CANCEL: retval = false; break; case LDSM_DIALOG_RESPONSE_ANALYZE: retval = false; ldsm_analyze_path (path); break; case LDSM_DIALOG_RESPONSE_EMPTY_TRASH: retval = false; trash_empty->usdLdsmTrashEmpty();//调清空回收站dialog break; case GTK_RESPONSE_NONE: case GTK_RESPONSE_DELETE_EVENT: retval = true; break; case LDSM_DIALOG_IGNORE: retval = true; break; default: retval = false; } free (path); return retval; } // 目前希望吧GList mounts替换为QList void DiskSpace::ldsm_maybe_warn_mounts (GList *mounts, bool multiple_volumes, bool other_usable_volumes) { GList *l; for (l = mounts; l != NULL; l = l->next) { LdsmMountInfo *mount_info = (LdsmMountInfo *)l->data; LdsmMountInfo *previous_mount_info; gdouble free_space; gdouble previous_free_space; time_t curr_time; const char *path; gboolean show_notify; QString every_two_minutes_check; gdouble free_space_check; if (done) { /* Don't show any more dialogs if the user took action with the last one. The user action * might free up space on multiple volumes, making the next dialog redundant. */ ldsm_free_mount_info (mount_info); continue; } path = g_unix_mount_get_mount_path (mount_info->mount); previous_mount_info = (LdsmMountInfo *)g_hash_table_lookup (ldsm_notified_hash, path); if (previous_mount_info != NULL) previous_free_space = (gdouble) previous_mount_info->buf.f_bavail / (gdouble) previous_mount_info->buf.f_blocks; // liutong // 找m_notified_hash中(mount_info->mount)得到的path QHash::iterator it = m_notified_hash.find(path); if (it != m_notified_hash.end()) { // 如果找到了,就计算上一次的 //LdsmMountInfo* ptmp = it.value() previous_free_space = (gdouble) ((*it)->buf.f_bavail) / (gdouble) ((*it)->buf.f_blocks); } free_space = (gdouble) mount_info->buf.f_bavail / (gdouble) mount_info->buf.f_blocks; if (previous_mount_info == NULL) { /* We haven't notified for this mount yet */ show_notify = TRUE; mount_info->notify_time = time (NULL); m_notified_hash.insert(path, mount_info); } else if ((previous_free_space - free_space) > free_percent_notify_again) { /* We've notified for this mount before and free space has decreased sufficiently since last time to notify again */ curr_time = time (NULL); if (difftime (curr_time, previous_mount_info->notify_time) > (gdouble)(min_notify_period * 60)) { show_notify = TRUE; mount_info->notify_time = curr_time; }else { /* It's too soon to show the dialog again. However, we still replace the LdsmMountInfo * struct in the hash table, but give it the notfiy time from the previous dialog. * This will stop the notification from reappearing unnecessarily as soon as the timeout expires. */ show_notify = FALSE; mount_info->notify_time = previous_mount_info->notify_time; } m_notified_hash.insert(path, mount_info); } else { /* We've notified for this mount before, but the free space hasn't decreased sufficiently to notify again */ ldsm_free_mount_info (mount_info); show_notify = FALSE; } if (show_notify) { if (ldsm_notify_for_mount (mount_info, multiple_volumes, other_usable_volumes)) done = TRUE; } free_space_check = (gint64) mount_info->buf.f_frsize * (gint64) mount_info->buf.f_bavail; // every_two_minutes_check = QString().sprintf("The volume \"%1\" has %s disk space remaining.", // g_format_size(free_space_check)).arg(g_unix_mount_guess_name(mount_info->mount)); // printf("%s\n",every_two_minutes_check.toStdString().data()); } } bool DiskSpace::ldsmGetIgnorePath(const gchar *path) { // 取得清理忽略的目录 QStringList ignoreList = settings->get(SETTINGS_IGNORE_PATHS).toStringList(); for (QString it : ignoreList) { if (it.compare(path) == 0) return true; } return false; } bool DiskSpace::ldsm_check_all_mounts () { GList *mounts; GList *l; GList *check_mounts = NULL; GList *full_mounts = NULL; guint number_of_mounts; guint number_of_full_mounts; gboolean multiple_volumes = FALSE; gboolean other_usable_volumes = FALSE; /* We iterate through the static mounts in /etc/fstab first, seeing if * they're mounted by checking if the GUnixMountPoint has a corresponding GUnixMountEntry. * Iterating through the static mounts means we automatically ignore dynamically mounted media. */ ldsm_timeout_cb->stop(); ldsm_timeout_cb->start(CHECK_EVERY_X_SECONDS); mounts = g_unix_mount_points_get (time_read); for (l = mounts; l != NULL; l = l->next) { GUnixMountPoint *mount_point = (GUnixMountPoint *)l->data; GUnixMountEntry *mount; LdsmMountInfo *mount_info; const gchar *path; path = g_unix_mount_point_get_mount_path (mount_point); mount = g_unix_mount_at (path, time_read); USD_LOG(LOG_DEBUG,"find path:%s ",path); g_unix_mount_point_free (mount_point); if (mount == NULL) { USD_LOG(LOG_DEBUG,"skip path:%s cuz can't find mount",path); /* The GUnixMountPoint is not mounted */ continue; } mount_info = g_new0 (LdsmMountInfo, 1); mount_info->mount = mount; path = g_unix_mount_get_mount_path (mount); if (g_strcmp0 (path, "/boot/efi") == 0 || g_strcmp0 (path, "/boot") == 0 ){ USD_LOG(LOG_DEBUG,"skip path:%s ",path); ldsm_free_mount_info (mount_info); continue; } if (ldsmGetIgnorePath(path)){ USD_LOG(LOG_DEBUG,"skip path:%s cuz ldsmGetIgnorePath",path); ldsm_free_mount_info (mount_info); continue; } if (g_unix_mount_is_readonly (mount)) { USD_LOG(LOG_DEBUG,"skip path:%s cuz g_unix_mount_is_readonly",path); ldsm_free_mount_info (mount_info); continue; } if (ldsm_mount_should_ignore (mount)) { ldsm_free_mount_info (mount_info); USD_LOG(LOG_DEBUG,"skip path:%s cuz ldsm_mount_should_ignore",path); continue; } if (statvfs (path, &mount_info->buf) != 0) { USD_LOG(LOG_DEBUG,"skip path:%s cuz statvfs",path); ldsm_free_mount_info (mount_info); continue; } if (ldsm_mount_is_virtual (mount_info)) { USD_LOG(LOG_DEBUG,"skip path:%s cuz ldsm_mount_is_virtual",path); ldsm_free_mount_info (mount_info); continue; } check_mounts = g_list_prepend (check_mounts, mount_info); } g_list_free (mounts); number_of_mounts = g_list_length (check_mounts); if (number_of_mounts > 1) multiple_volumes = TRUE; for (l = check_mounts; l != NULL; l = l->next) { LdsmMountInfo *mount_info = (LdsmMountInfo *)l->data; if (!ldsm_mount_has_space (mount_info)) { full_mounts = g_list_prepend (full_mounts, mount_info); } else { ldsm_free_mount_info (mount_info); } } number_of_full_mounts = g_list_length (full_mounts); if (number_of_mounts > number_of_full_mounts){ other_usable_volumes = TRUE; } ldsm_maybe_warn_mounts (full_mounts, multiple_volumes, other_usable_volumes); g_list_free (check_mounts); g_list_free (full_mounts); return TRUE; } void DiskSpace::ldsm_mounts_changed (GObject *monitor,gpointer data,DiskSpace *disk) { GList *mounts; /* remove the saved data for mounts that got removed */ mounts = g_unix_mounts_get (time_read); is_hash_item_not_in_mounts(disk->m_notified_hash, mounts); g_list_free_full (mounts, (GDestroyNotify) g_unix_mount_free); /* check the status now, for the new mounts */ disk->ldsm_check_all_mounts(); } void DiskSpace::UsdLdsmSetup(bool check_now) { if (!m_notified_hash.empty() || ldsm_timeout_cb || ldsm_monitor) { qWarning ("Low disk space monitor already initialized."); //return; } usdLdsmGetConfig(); connect(settings, SIGNAL(changed(QString)), this, SLOT(usdLdsmUpdateConfig(QString))); #if GLIB_CHECK_VERSION (2, 44, 0) ldsm_monitor = g_unix_mount_monitor_get (); #else ldsm_monitor = g_unix_mount_monitor_new (); g_unix_mount_monitor_set_rate_limit (ldsm_monitor, 1000); #endif /*g_signal_connect (ldsm_monitor, "mounts-changed", G_CALLBACK (DIskSpace::ldsm_mounts_changed), this);*/ if (check_now) ldsm_check_all_mounts (); //ldsm_timeout_cb->start(CHECK_EVERY_X_SECONDS); } void DiskSpace::cleanNotifyHash() { for(auto it=m_notified_hash.begin();it!=m_notified_hash.end();it++) { auto p = it.value(); if (nullptr != p) { delete p; } } m_notified_hash.clear(); } void DiskSpace::UsdLdsmClean() { cleanNotifyHash(); if (ldsm_monitor) g_object_unref (ldsm_monitor); ldsm_monitor = NULL; if (settings) { g_object_unref (settings); } if (ignore_paths) { g_slist_foreach (ignore_paths, (GFunc) g_free, NULL); g_slist_free (ignore_paths); ignore_paths = NULL; } } #ifdef TEST int main (int argc, char **argv) { GMainLoop *loop; DIskSpace *mDisk; mDisk = DIskSpace::DiskSpaceNew(); gtk_init (&argc, &argv); loop = g_main_loop_new (NULL, FALSE); mDisk->UsdLdsmSetup (true); g_main_loop_run (loop); mDisk->UsdLdsmClean (); g_main_loop_unref (loop); delete mDisk; return 0; } #endif ukui-settings-daemon/plugins/housekeeping/ldsm-trash-empty.ui0000664000175000017500000000061315174102667023505 0ustar fengfeng LdsmTrashEmpty 0 0 517 326 Dialog ukui-settings-daemon/plugins/a11y-settings/0000775000175000017500000000000015174103014017642 5ustar fengfengukui-settings-daemon/plugins/a11y-settings/a11y-settings-plugin.cpp0000664000175000017500000000351015174103014024252 0ustar fengfeng/* -*- Mode: C++; indent-tabs-mode: nil; tab-width: 4 -*- * -*- coding: utf-8 -*- * * Copyright (C) 2023 KylinSoft Co., Ltd. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include "a11y-settings-plugin.h" #include "clib-syslog.h" PluginInterface* A11ySettingsPlugin::mInstance = nullptr; A11ySettingsPlugin::A11ySettingsPlugin() { USD_LOG(LOG_DEBUG,"A11SettingsPlugin initializing!"); settingsManager=A11ySettingsManager::A11ySettingsManagerNew(); } A11ySettingsPlugin::~A11ySettingsPlugin() { if (settingsManager) delete settingsManager; } void A11ySettingsPlugin::activate() { bool res; USD_LOG(LOG_DEBUG,"Activating a11y-settings plugincompilation time:[%s] [%s]",__DATE__,__TIME__); res=settingsManager->A11ySettingsManagerStart(); if(!res){ USD_LOG(LOG_WARNING,"Unable to start a11y-settings manager!"); } } PluginInterface *A11ySettingsPlugin::getInstance() { if (nullptr == mInstance) { mInstance = new A11ySettingsPlugin(); } return mInstance; } void A11ySettingsPlugin::deactivate() { USD_LOG(LOG_DEBUG,"Deactivating a11y-settings plugin!"); settingsManager->A11ySettingsMAnagerStop(); } PluginInterface* createSettingsPlugin() { return A11ySettingsPlugin::getInstance(); } ukui-settings-daemon/plugins/a11y-settings/a11y-settings-manager.h0000664000175000017500000000256015174103014024037 0ustar fengfeng/* -*- Mode: C++; indent-tabs-mode: nil; tab-width: 4 -*- * -*- coding: utf-8 -*- * * Copyright (C) 2023 KylinSoft Co., Ltd. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef A11YSETTINGS_H #define A11YSETTINGS_H #include #include #include #include class A11ySettingsManager : public QObject { Q_OBJECT private: A11ySettingsManager(); public: ~A11ySettingsManager(); static A11ySettingsManager* A11ySettingsManagerNew(); bool A11ySettingsManagerStart(); void A11ySettingsMAnagerStop(); public Q_SLOTS: void AppsSettingsChanged(QString); private: static A11ySettingsManager* mA11ySettingsManager; QGSettings *interface_settings; QGSettings *a11y_apps_settings; }; #endif // A11YSETTINGS_H ukui-settings-daemon/plugins/a11y-settings/a11y-settings-manager.cpp0000664000175000017500000000575515174103014024403 0ustar fengfeng/* -*- Mode: C++; indent-tabs-mode: nil; tab-width: 4 -*- * -*- coding: utf-8 -*- * * Copyright (C) 2023 KylinSoft Co., Ltd. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include "a11y-settings-manager.h" #include "clib-syslog.h" A11ySettingsManager* A11ySettingsManager::mA11ySettingsManager = nullptr; A11ySettingsManager::A11ySettingsManager() { interface_settings = new QGSettings("org.mate.interface"); a11y_apps_settings = new QGSettings("org.gnome.desktop.a11y.applications"); } A11ySettingsManager::~A11ySettingsManager() { delete interface_settings; delete a11y_apps_settings; } A11ySettingsManager* A11ySettingsManager::A11ySettingsManagerNew() { if(nullptr == mA11ySettingsManager) mA11ySettingsManager = new A11ySettingsManager(); return mA11ySettingsManager; } void A11ySettingsManager::AppsSettingsChanged(QString key){ bool screen_reader,keyboard; if((key == "screen-reader-enabled") == false && (key == "screen-keyboard-enabled") == false) return; USD_LOG(LOG_DEBUG,"screen reader or OSK enabledment changed"); screen_reader = a11y_apps_settings->get("screen-reader-enabled").toBool(); keyboard = a11y_apps_settings->get("screen-keyboard-enabled").toBool(); if(screen_reader || keyboard){ USD_LOG(LOG_DEBUG,"Enabling accessibility,screen reader or OSK enabled!"); interface_settings->set("accessibility",true); }else if((screen_reader == false) && (keyboard == false)){ USD_LOG(LOG_DEBUG,"Disabling accessibility,screen reader or OSK disabled!"); interface_settings->set("accessibility",false); } } bool A11ySettingsManager::A11ySettingsManagerStart() { USD_LOG(LOG_DEBUG,"Starting a11y_settings manager!"); connect(a11y_apps_settings, SIGNAL(changed(QString)), this, SLOT(AppsSettingsChanged(QString))); /* If any of the screen reader or on-screen keyboard are enabled, * make sure a11y is enabled for the toolkits. * We don't do the same thing for the reverse so it's possible to * enable AT-SPI for the toolkits without using an a11y app */ if(a11y_apps_settings->get("screen-keyboard-enabled").toBool()|| a11y_apps_settings->get("screen-reader-enabled").toBool()) interface_settings->set("accessibility",true); return true; } void A11ySettingsManager::A11ySettingsMAnagerStop() { USD_LOG(LOG_DEBUG,"Stopping a11y_settings manager"); } ukui-settings-daemon/plugins/a11y-settings/a11y-settings.pro0000664000175000017500000000142615174103014023000 0ustar fengfeng#------------------------------------------------- # # Project created by QtCreator 2020-08-05T19:30:00 # #------------------------------------------------- QT -= gui QT += core widgets x11extras TEMPLATE = lib TARGET = a11y-settings CONFIG += c++20 plugin link_pkgconfig CONFIG -= app_bundle DEFINES += QT_DEPRECATED_WARNINGS MODULE_NAME=\\\"a11y-settings\\\" include($$PWD/../../common/common.pri) PKGCONFIG += \ glib-2.0 \ gio-2.0 \ gsettings-qt SOURCES += \ $$PWD/a11y-settings-manager.cpp \ $$PWD/a11y-settings-plugin.cpp HEADERS += \ $$PWD/a11y-settings-manager.h \ $$PWD/a11y-settings-plugin.h a11_settings_lib.path = $${PLUGIN_INSTALL_DIRS} a11_settings_lib.files = $$OUT_PWD/liba11y-settings.so INSTALLS += a11_settings_lib ukui-settings-daemon/plugins/a11y-settings/a11y-settings-plugin.h0000664000175000017500000000250415174103014023721 0ustar fengfeng/* -*- Mode: C++; indent-tabs-mode: nil; tab-width: 4 -*- * -*- coding: utf-8 -*- * * Copyright (C) 2023 KylinSoft Co., Ltd. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef A11YSETTINGSPLUGIN_H #define A11YSETTINGSPLUGIN_H #include "plugin-interface.h" #include "a11y-settings-manager.h" class A11ySettingsPlugin : public PluginInterface { public: ~A11ySettingsPlugin(); static PluginInterface* getInstance(); void activate(); void deactivate(); private: A11ySettingsPlugin(); A11ySettingsPlugin(A11ySettingsPlugin&) = delete; A11ySettingsManager* settingsManager; static PluginInterface* mInstance; }; extern "C" Q_DECL_EXPORT PluginInterface* createSettingsPlugin(); #endif // A11YSETTINGSPLUGIN_H ukui-settings-daemon/plugins/demo-manager/0000775000175000017500000000000015174103014017565 5ustar fengfengukui-settings-daemon/plugins/demo-manager/global-manager.h0000664000175000017500000000160015174103014022603 0ustar fengfeng/* -*- Mode: C++; indent-tabs-mode: nil; tab-width: 4 -*- * -*- coding: utf-8 -*- * * Copyright (C) 2023 KylinSoft Co., Ltd. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef GLOBALMANAGER_H #define GLOBALMANAGER_H class GlobalManager { public: GlobalManager(); }; #endif // GLOBALMANAGER_H ukui-settings-daemon/plugins/demo-manager/org.ukui.SettingsDaemon.plugins.globalManager.gschema.xml0000664000175000017500000001312515174102667032634 0ustar fengfeng true Activation of this plugin Whether this plugin would be activated by unity-settings-daemon or not 16 Priority to use for this plugin Priority to use for this plugin in unity-settings-daemon startup queue false If the night light mode is enabled Night light mode changes the color temperature of your display when the sun has gone down or at preset times. 4000 Temperature of the display when enabled This temperature in Kelvin is used to modify the screen tones when night light mode is enabled. Higher values are bluer, lower redder. 4000 Temperature of real time Temperature of real time true Use the sunrise and sunset Calculate the sunrise and sunset times automatically, from the current location. 20.00 The start time When “night-light-schedule-automatic” is disabled, use this start time in hours from midnight. 6.00 The end time When “night-light-schedule-automatic” is disabled, use this end time in hours from midnight. (999,999) The last detected position When location services are available this represents the last detected location. The default value is an invalid value to ensure it is always updated at startup. false Open night light all day (intel)At any time, night mode is open. false Use the sunrise and sunset to set theme (intel)Calculate the sunrise and sunset times, and set the theme automatically. 0.00 The start time (intel)When “night-light-schedule-automatic” is enabled, calculate this start time in hours from midnight. 0.00 The end time (intel)When “night-light-schedule-automatic” is enabled, calculate this end time in hours from midnight. false Use the read kwin config . false Use set dark mode . '' Use record theme style,when dark mode is true record the /org/ukui/style's key style-name,when dark mode is false set this value to the style-name. . false If the night light mode is enabled Use record theme style,when dark mode is true record the night-light-enabled,when dark mode is false set this value to it. false Open night light all day Use record theme style,when dark mode is true record the night-light-allday,when dark mode is false set this value to it. false Use the sunrise and sunset to set theme Use record theme style,when dark mode is true record the night-light-schedule-automatic,when dark mode is false set this value to it. false Use the sunrise and sunset to set theme Use record theme style,when dark mode is true record the theme-schedule-automatic,when dark mode is false set this value to it. false Use the edu config . ukui-settings-daemon/plugins/demo-manager/global-manager-plugin.cpp0000664000175000017500000000251515174103014024440 0ustar fengfeng/* -*- Mode: C++; indent-tabs-mode: nil; tab-width: 4 -*- * -*- coding: utf-8 -*- * * Copyright (C) 2023 KylinSoft Co., Ltd. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include "global-manager-plugin.h" PluginInterface *GlobalManagerPlugin::m_Instance = nullptr; GlobalManager *GlobalManagerPlugin::m_pManager = nullptr; GlobalManagerPlugin::~GlobalManagerPlugin() { } GlobalManagerPlugin::GlobalManagerPlugin() { if (m_pManager == nullptr) { m_pManager = new GlobalManager(); } } PluginInterface *GlobalManagerPlugin::getInstance() { if (nullptr == m_Instance) { m_Instance = new GlobalManagerPlugin(); } return m_Instance; } PluginInterface *createSettingsPlugin() { return GlobalManagerPlugin::getInstance(); } ukui-settings-daemon/plugins/demo-manager/globalManager.ukui-settings-plugin0000664000175000017500000000026315174103014026352 0ustar fengfeng[UKUI Settings Plugin] Module=color IAge=0 Name=Color Name[zh_CN]=色温调整 Description=Color plugin Authors=Leon Sun Copyright=Copyright (C) 2023 KylinSoft Co., Ltd. Website= ukui-settings-daemon/plugins/demo-manager/global-manager.pro0000664000175000017500000000370115174103014023160 0ustar fengfengQT -= gui QT += network TEMPLATE = lib TARGET = globalManager #link_pkgconfig no_keywords plugin app_bundlels 必须要加否则会出现so文件版本的链接 CONFIG += c++20 link_pkgconfig no_keywords plugin app_bundlels # The following define makes your compiler emit warnings if you use # any Qt feature that has been marked 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 MODULE_NAME=\\\"{$$TARGET}\\\" INCLUDEPATH += \ -I ukui-settings-daemon/ include($$PWD/../../common/common.pri) # You can also make your code fail to compile if it uses 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 SOURCES += \ \ global-manager-plugin.cpp \ global-manager.cpp HEADERS += \ \ global-manager-plugin.h \ global-manager.h # Default rules for deployment. # OTHER_FILES += org.ukui.peripherals-keyboard.demoplugin.xml {$$TARGET}plugin_lib.path = $${PLUGIN_INSTALL_DIRS} {$$TARGET}plugin_lib.files = $$OUT_PWD/lib{$$TARGET}.so {$$TARGET}plugin_info.path = $$[QT_INSTALL_LIBS]/ukui-settings-daemon {$$TARGET}plugin_info.files = $$OUT_PWD/{$$TARGET}.ukui-settings-plugin {$$TARGET}plugin_schema.path = /usr/share/glib-2.0/schemas/ {$$TARGET}plugin_schema.files = $$OUT_PWD/org.ukui.SettingsDaemon.plugins.{$$TARGET}.gschema.xml #禁用优化 QMAKE_CFLAGS_DEBUG -= O2 QMAKE_CXXFLAGS_DEBUG -= -O2 QMAKE_CFLAGS_RELEASE -= O2 QMAKE_CXXFLAGS_RELEASE -= -O2 #lib must at last INSTALLS += {$$TARGET}plugin_lib {$$TARGET}plugin_info {$$TARGET}plugin_schema DISTFILES += \ {$$TARGET}.ukui-settings-plugin \ org.ukui.SettingsDaemon.plugins.{$$TARGET}.gschema.xml ukui-settings-daemon/plugins/demo-manager/global-manager.cpp0000664000175000017500000000147615174103014023151 0ustar fengfeng/* -*- Mode: C++; indent-tabs-mode: nil; tab-width: 4 -*- * -*- coding: utf-8 -*- * * Copyright (C) 2023 KylinSoft Co., Ltd. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include "global-manager.h" GlobalManager::GlobalManager() { } ukui-settings-daemon/plugins/demo-manager/global-manager-plugin.h0000664000175000017500000000250415174103014024103 0ustar fengfeng/* -*- Mode: C++; indent-tabs-mode: nil; tab-width: 4 -*- * -*- coding: utf-8 -*- * * Copyright (C) 2023 KylinSoft Co., Ltd. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef GLOBALMANAGERPLUGIN_H #define GLOBALMANAGERPLUGIN_H #include "plugin-interface.h" #include "global-manager.h" class GlobalManagerPlugin: public PluginInterface { public: ~GlobalManagerPlugin(); static PluginInterface *getInstance(); virtual void activate(); virtual void deactivate(); private: GlobalManagerPlugin(); GlobalManagerPlugin(GlobalManagerPlugin&)=delete; static GlobalManager *m_pManager; static PluginInterface *m_Instance; }; extern "C" Q_DECL_EXPORT PluginInterface* createSettingsPlugin(); #endif // GLOBALMANAGERPLUGIN_H ukui-settings-daemon/plugins/global-manager/0000775000175000017500000000000015174103014020101 5ustar fengfengukui-settings-daemon/plugins/global-manager/abstract-brightness.h0000664000175000017500000000214215174103014024222 0ustar fengfeng/* -*- Mode: C++; indent-tabs-mode: nil; tab-width: 4 -*- * -*- coding: utf-8 -*- * * Copyright (C) 2023 KylinSoft Co., Ltd. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef BRIGHTNESSFACTORY_H #define BRIGHTNESSFACTORY_H #include class AbstractBrightness : public QObject { public: AbstractBrightness(){} virtual int getBrightness() = 0; virtual int setBrightness(int brightness) = 0; virtual int connectTheSignal() = 0; virtual QString backend() = 0; }; #endif // BRIGHTNESSFACTORY_H ukui-settings-daemon/plugins/global-manager/powermanager-brightness.h0000664000175000017500000000314215174103014025107 0ustar fengfeng/* -*- Mode: C++; indent-tabs-mode: nil; tab-width: 4 -*- * -*- coding: utf-8 -*- * * Copyright (C) 2023 KylinSoft Co., Ltd. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef POWERMANAGERBRIGHTNESS_H #define POWERMANAGERBRIGHTNESS_H #include #include #include #include "usd_global_define.h" #include "QGSettings/qgsettings.h" #include "abstract-brightness.h" class PowerManagerBrightness : public AbstractBrightness { Q_OBJECT public: PowerManagerBrightness(QObject *parent); /** * @brief getBrightness * @return */ int getBrightness(); /** * @brief setBrightness * @param brightness * @return */ int setBrightness(int brightness); /** * @brief connectTheSignal * @return */ int connectTheSignal(); /** * @brief isEnable * @return */ QString backend(); private Q_SLOTS: void doChanged(QString); private: QGSettings *m_pPowerManger; }; #endif // POWERMANAGERBRIGHTNESS_H ukui-settings-daemon/plugins/global-manager/global-signal.cpp0000664000175000017500000002541715174103014023331 0ustar fengfeng/* -*- Mode: C++; indent-tabs-mode: nil; tab-width: 4 -*- * -*- coding: utf-8 -*- * * Copyright (C) 2023 KylinSoft Co., Ltd. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include "global-signal.h" #include GlobalSignal::GlobalSignal(QObject *parent) { qRegisterMetaType("SessionStruct"); qRegisterMetaType("SessionStructList"); qRegisterMetaType>("QList"); qDBusRegisterMetaType>(); qDBusRegisterMetaType(); qDBusRegisterMetaType(); qRegisterMetaType("UKUILite"); qDBusRegisterMetaType(); connectUserLogin1Signal(); QStringList disableOptions = getShutDownDisableOptionFromGlobalManager(); QSet setOptions = QSet(disableOptions.begin(), disableOptions.end()); QSet allOptions = QSet(m_allOptions.begin(), m_allOptions.end()); QStringList intersection = setOptions.intersect(allOptions).values(); m_pGMsettings = new QGSettings(GSETTINGS_GLOBALMANAGER_SCHEMA); m_pGMsettings->set(DISABLE_POWEROFF_OPTIONS ,(QVariant)intersection); m_pGMsettings->set(HIDE_POWEROFF_UI,getHidePowerUiFromGlobalManager()); connect(m_pGMsettings, SIGNAL(changed(QString)), this, SLOT(doGMsettinsChange(QString)), Qt::DirectConnection); } GlobalSignal::~GlobalSignal() { if (m_pGMsettings != nullptr) { delete m_pGMsettings; m_pGMsettings = nullptr; } if (m_plogin2 != nullptr) { delete m_plogin2; m_plogin2 = nullptr; } } void GlobalSignal::sendUserActiveSignal(QString interface, QVariantMap qvarMap, QStringList strList) { if (interface == "org.freedesktop.login1.Session") { QMap mapKey = qvariant_cast>(qvarMap); if (mapKey.contains("Active")) { bool isActive = qvariant_cast(mapKey["Active"]); QDBusMessage notifySignal = QDBusMessage::createSignal(DBUS_GC_SIGNAL_PATH, DBUS_GC_SIGNAL_INTERFACE, DBUS_GC_SIGNAL_SIGNAL_Active); notifySignal.setArguments({QVariant::fromValue(isActive)}); QDBusConnection::sessionBus().send(notifySignal); USD_LOG(LOG_DEBUG,"send active:%d",isActive); } } } bool GlobalSignal::isPresenceLightSensor() { QGSettings gsettings(AUTO_BRIGHTNESS_SCHEMA); SYS_LOG_SHOW_PARAM1(gsettings.get(HAD_SENSOR_KEY).toBool()); return gsettings.get(HAD_SENSOR_KEY).toBool(); } QStringList GlobalSignal::getShutdownDisableOptions() { /** * gsettings set org.ukui.SettingsDaemon.plugins.globalManager disable-shutdown-option ['"switchuser"','"hibernate"','"suspend"','"lockscreen"','"logout"','"restart"','"shutdown"'] * 全部屏蔽 */ QList disableOption = getShutDownDisableOptionInGsettings(); QSet setOptions = QSet(disableOption.begin(), disableOption.end()); QSet allOptions = QSet(m_allOptions.begin(), m_allOptions.end()); bool ret = m_pGMsettings->get(HIDE_POWEROFF_UI).toBool(); if (ret) { return m_allOptions; } return allOptions.intersect(setOptions).values(); } bool GlobalSignal::isHidePoweroffUi() { bool ret = m_pGMsettings->get(HIDE_POWEROFF_UI).toBool(); if (!ret) { QList disableOption = getShutDownDisableOptionInGsettings(); QSet setOptions = QSet(disableOption.begin(), disableOption.end()); QSet allOptions = QSet(m_allOptions.begin(), m_allOptions.end()); QList intersection = allOptions.intersect(setOptions).values(); USD_LOG_SHOW_PARAM1(intersection.count()); if (intersection.count()>=m_allOptions.count()) { return true; } } return m_pGMsettings->get(HIDE_POWEROFF_UI).toBool(); } UKUILite GlobalSignal::getUKUILiteLevel() { UKUILite lite; lite.function = m_pGMsettings->get(UKUI_LITE_FUNCTION).toString(); lite.animation = m_pGMsettings->get(UKUI_LITE_ANIMATION).toString(); USD_LOG_SHOW_PARAMS(lite.function.toLatin1().data()); USD_LOG_SHOW_PARAMS(lite.animation.toLatin1().data()); return lite; } QString GlobalSignal::getUKUILiteFunction() { return m_pGMsettings->get(UKUI_LITE_FUNCTION).toString(); } QString GlobalSignal::getUKUILiteAnimation() { return m_pGMsettings->get(UKUI_LITE_ANIMATION).toString(); } void GlobalSignal::doGMsettinsChange(QString key) { if (key == DISABLE_POWEROFF_OPTIONS) { QStringList disableOption = getShutDownDisableOptionInGsettings(); QSet setOptions = QSet(disableOption.begin(), disableOption.end()); QSet allOptions = QSet(m_allOptions.begin(), m_allOptions.end()); QStringList intersection = allOptions.intersect(setOptions).values(); QDBusInterface globalManager("com.settings.daemon.qt.systemdbus", \ "/globalconfig", \ "com.settings.daemon.interface", \ QDBusConnection::systemBus()); QList arguments; arguments << QVariant(QString::fromLatin1(MODULE_NAME)) << QVariant(QString::fromLatin1(DISABLE_POWEROFF_OPTIONS)) << QVariant::fromValue(QDBusVariant(intersection)); QDBusPendingCall reply = globalManager.asyncCallWithArgumentList("setGlobalConf", arguments); if (reply.isError()) { USD_LOG(LOG_DEBUG,"error! %s %s",reply.reply().errorMessage().toLatin1().data()); } } else if (key == HIDE_POWEROFF_UI){ bool ret = m_pGMsettings->get(HIDE_POWEROFF_UI).toBool(); QDBusInterface globalManager("com.settings.daemon.qt.systemdbus", \ "/globalconfig", \ "com.settings.daemon.interface", \ QDBusConnection::systemBus()); QList arguments; arguments << QVariant(QString::fromLatin1(MODULE_NAME)) << QVariant(QString::fromLatin1(HIDE_POWEROFF_UI)) << QVariant::fromValue(QDBusVariant(ret)); QDBusPendingCall reply = globalManager.asyncCallWithArgumentList("setGlobalConf", arguments); if (reply.isError()) { USD_LOG(LOG_DEBUG,"error! %s %s",reply.reply().errorMessage().toLatin1().data()); } } else if (key == UKUI_LITE_FUNCTION || key == UKUI_LITE_ANIMATION) { UKUILite lite; lite.function = m_pGMsettings->get(UKUI_LITE_FUNCTION).toString(); lite.animation = m_pGMsettings->get(UKUI_LITE_ANIMATION).toString(); Q_EMIT UKUILiteChanged(lite); } } void GlobalSignal::connectUserActiveSignal() { m_plogin1 = new DBusLogin1Interface("org.freedesktop.login1", "/org/freedesktop/login1/user/self", "org.freedesktop.login1.User", QDBusConnection::systemBus()); SessionStructList lqvar = qvariant_cast(m_plogin1->property("Sessions")); } void GlobalSignal::connectUserActiveSignalWithPath(QString path) { USD_LOG(LOG_DEBUG,"connect:%s..",path.toLatin1().data()); m_ploginWithPath = new QDBusInterface("org.freedesktop.login1", path, "org.freedesktop.DBus.Properties", QDBusConnection::systemBus()); connect(m_ploginWithPath, SIGNAL(PropertiesChanged(QString,QVariantMap,QStringList)), this, SLOT(sendUserActiveSignal(QString,QVariantMap,QStringList))); } void GlobalSignal::connectUserLogin1Signal() { m_plogin2 = new QDBusInterface("org.freedesktop.login1", "/org/freedesktop/login1/user/self", "org.freedesktop.DBus.Properties", QDBusConnection::systemBus()); QDBusMessage message = QDBusMessage::createMethodCall("org.freedesktop.login1", "/org/freedesktop/login1/user/self" ,"org.freedesktop.DBus.Properties", "Get"); QDBusMessage reply1 = m_plogin2->call("Get", "org.freedesktop.login1.User", "Sessions"); QVariant v = reply1.arguments().first(); QDBusArgument arg = v.value().variant().value(); SessionStructList members; arg.beginArray(); while(!arg.atEnd()) { SessionStruct m; arg >> m; members << m; USD_LOG(LOG_DEBUG,"ready connect %s..",m.userPath.path().toLatin1().data()); connectUserActiveSignalWithPath(m.userPath.path()); break; } arg.endArray(); } QVariant GlobalSignal::getGlobalConfig(QString schema, QString key) { QDBusInterface globalManager("com.settings.daemon.qt.systemdbus", \ "/globalconfig", \ "com.settings.daemon.interface", \ QDBusConnection::systemBus()); QDBusReply reply = globalManager.call("getGlobalConf", schema, key); if (reply.isValid()) { return reply.value(); } else { USD_LOG(LOG_ERR,"globalManager dbus interface failed ."); } return QVariant(0); } QList GlobalSignal::getShutDownDisableOptionInGsettings() { QList disableOption = m_pGMsettings->get(DISABLE_POWEROFF_OPTIONS).toStringList(); for (int var = 0; var < disableOption.count(); ++var) { disableOption[var] = disableOption[var].toLower(); } QSet setOptions = QSet(disableOption.begin(), disableOption.end()); QSet allOptions = QSet(m_allOptions.begin(), m_allOptions.end()); QList intersection = allOptions.intersect(setOptions).values(); USD_LOG_SHOW_PARAM1(intersection.count()); return intersection; } QStringList GlobalSignal::getShutDownDisableOptionFromGlobalManager() { QStringList values = getGlobalConfig(MODULE_NAME, DISABLE_POWEROFF_OPTIONS).toStringList(); return values; } bool GlobalSignal::getHidePowerUiFromGlobalManager() { return getGlobalConfig(MODULE_NAME, HIDE_POWEROFF_UI).toBool(); } ukui-settings-daemon/plugins/global-manager/global-manager.h0000664000175000017500000000247215174103014023127 0ustar fengfeng/* -*- Mode: C++; indent-tabs-mode: nil; tab-width: 4 -*- * -*- coding: utf-8 -*- * * Copyright (C) 2023 KylinSoft Co., Ltd. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef GLOBALMANAGER_H #define GLOBALMANAGER_H #include #include #include "brightness.h" #include "global-signal.h" class GlobalManager { public: GlobalManager(); GlobalManager(GlobalManager&)=delete; GlobalManager&operator=(const GlobalManager&)=delete; public: ~GlobalManager(); static GlobalManager *GlobalManagerNew(); void start(); void stop(); private: static GlobalManager *m_globalManager; Brightness *m_pBright = nullptr; GlobalSignal *m_pSignal = nullptr; }; #endif // GLOBALMANAGER_H ukui-settings-daemon/plugins/global-manager/brightness.h0000664000175000017500000000426515174103014022431 0ustar fengfeng/* -*- Mode: C++; indent-tabs-mode: nil; tab-width: 4 -*- * -*- coding: utf-8 -*- * * Copyright (C) 2023 KylinSoft Co., Ltd. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef BRIGHTNESS_H #define BRIGHTNESS_H #include #include #include #include #include #include "clib-syslog.h" #include "usd_base_class.h" #include "abstract-brightness.h" #include "gamma-brightness.h" #include "powermanager-brightness.h" class Brightness: public QObject { Q_OBJECT Q_CLASSINFO("D-Bus Interface", DBUS_GC_BRIGHTNESS_INTERFACE) public: Brightness(QObject *parent = nullptr); public Q_SLOTS: /** * @brief getPrimaryBrightness * @return */ Q_SCRIPTABLE uint getPrimaryBrightness(); /** * @brief setPrimaryBrightness * @return */ Q_SCRIPTABLE bool setPrimaryBrightness(uint Brightness); /** * @brief isEnable * @return */ Q_SCRIPTABLE bool isEnable(); /** * @brief isEnable * @return */ Q_SCRIPTABLE QString backend(); #if 0 Q_SIGNALS: /** * @brief primaryChanged * @param Bright * @return */ int primaryChanged(int Bright); /** * @brief enableChanged * @param Bright * @return */ int enableChanged(bool state); #endif private: void sendPrimaryStartChanged(int brightness); private: bool m_powerManagerSetable = false; bool m_gammaManagerSetable = false; uint m_targetPrimaryBrightness = 0; QTimer *m_brightCacheTimer; AbstractBrightness *m_brightnessManager = nullptr; }; #endif // BRIGHTNESS_H ././@LongLink0000644000000000000000000000014600000000000011604 Lustar rootrootukui-settings-daemon/plugins/global-manager/org.ukui.SettingsDaemon.plugins.globalManager.gschema.xmlukui-settings-daemon/plugins/global-manager/org.ukui.SettingsDaemon.plugins.globalManager.gschema.xm0000664000175000017500000000413615174103014032761 0ustar fengfeng true Activation of this plugin Whether this plugin would be activated by unity-settings-daemon or not 16 Priority to use for this plugin Priority to use for this plugin in unity-settings-daemon startup queue false hide poweroff ui Popups on interfaces that prohibit power operation, user switching, etc [] disale shutdown option Option to disable shutdown page 'normal' ukui lite funtion level Identify whether the functionality of the app in the current environment is in UKUILite mode or at the current UKUILite level 'normal' ukui liteanimation level Identify whether the animation of the app in the current environment is in UKUILite mode or at the current UKUILite level ukui-settings-daemon/plugins/global-manager/gamma-brightness.h0000664000175000017500000000306515174103014023506 0ustar fengfeng/* -*- Mode: C++; indent-tabs-mode: nil; tab-width: 4 -*- * -*- coding: utf-8 -*- * * Copyright (C) 2023 KylinSoft Co., Ltd. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef GAMMABRIGHTNESS_H #define GAMMABRIGHTNESS_H #include #include #include #include #include "clib-syslog.h" #include "usd_global_define.h" #include "abstract-brightness.h" class GammaBrightness : public AbstractBrightness { Q_OBJECT public: GammaBrightness(QObject *parent); /** * @brief getBrightness * @return */ int getBrightness(); /** * @brief setBrightness * @param brightness * @return */ int setBrightness(int brightness); /** * @brief connectTheSignal * @return */ int connectTheSignal(); /** * @brief isEnable * @return */ QString backend(); private: QDBusInterface *m_pGmDbusInterface = nullptr; }; #endif // GAMMABRIGHTNESS_H ukui-settings-daemon/plugins/global-manager/powermanager-brightness.cpp0000664000175000017500000000362615174103014025451 0ustar fengfeng/* -*- Mode: C++; indent-tabs-mode: nil; tab-width: 4 -*- * -*- coding: utf-8 -*- * * Copyright (C) 2023 KylinSoft Co., Ltd. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include "powermanager-brightness.h" PowerManagerBrightness::PowerManagerBrightness(QObject *parent) { m_pPowerManger = new QGSettings(POWER_MANAGER_SCHEMA); } int PowerManagerBrightness::getBrightness() { return m_pPowerManger->get(BRIGHTNESS_AC_KEY).toInt(); } int PowerManagerBrightness::setBrightness(int brightness) { return m_pPowerManger->trySet(BRIGHTNESS_AC_KEY, brightness); } int PowerManagerBrightness::connectTheSignal() { connect(m_pPowerManger, SIGNAL(changed(QString)), this, SLOT(doChanged(QString))); return 0; } QString PowerManagerBrightness::backend() { return "power manager"; } void PowerManagerBrightness::doChanged(QString key) { if (key == BRIGHTNESS_AC_KEY) { int brightness = m_pPowerManger->get(key).toInt(); if (brightness > 0 && brightness <= 100) { QDBusMessage notifySignal = QDBusMessage::createSignal(DBUS_GC_BRIGHTNESS_PATH, DBUS_GC_BRIGHTNESS_INTERFACE, DBUS_GC_BRIGHTNESS_SIGNAL_PRIMARYCHANGED_END); notifySignal.setArguments({QVariant::fromValue(brightness)}); QDBusConnection::sessionBus().send(notifySignal); } } } ukui-settings-daemon/plugins/global-manager/gamma-brightness.cpp0000664000175000017500000000404715174103014024042 0ustar fengfeng/* -*- Mode: C++; indent-tabs-mode: nil; tab-width: 4 -*- * -*- coding: utf-8 -*- * * Copyright (C) 2023 KylinSoft Co., Ltd. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include "gamma-brightness.h" GammaBrightness::GammaBrightness(QObject *parent) { USD_LOG(LOG_DEBUG,"."); } int GammaBrightness::getBrightness() { if (m_pGmDbusInterface == nullptr) { return -1; } QDBusMessage response = m_pGmDbusInterface->call("getPrimaryBrightness"); if (response.type() != QDBusMessage::ReplyMessage) { return -1; } int ret = response.arguments().takeFirst().toInt(); USD_LOG_SHOW_PARAM1(ret); return ret; } int GammaBrightness::setBrightness(int brightness) { if (m_pGmDbusInterface == nullptr) { return -1; } QDBusMessage response = m_pGmDbusInterface->call("setPrimaryBrightness", "self.", brightness); if (response.type() != QDBusMessage::ReplyMessage) { return -1; } return response.arguments().takeFirst().toInt(); } int GammaBrightness::connectTheSignal() { m_pGmDbusInterface = new QDBusInterface(DBUS_GM_NAME,DBUS_GM_PATH,DBUS_GM_INTERFACE, QDBusConnection::sessionBus()); if (!m_pGmDbusInterface->isValid()) { m_pGmDbusInterface = nullptr; return 0; } m_pGmDbusInterface->call("enablePrimarySignal", true); return 1; } QString GammaBrightness::backend() { return "gamma manager"; } ukui-settings-daemon/plugins/global-manager/global-manager-plugin.cpp0000664000175000017500000000310115174103014024744 0ustar fengfeng/* -*- Mode: C++; indent-tabs-mode: nil; tab-width: 4 -*- * -*- coding: utf-8 -*- * * Copyright (C) 2023 KylinSoft Co., Ltd. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include "global-manager-plugin.h" PluginInterface *GlobalManagerPlugin::m_Instance = nullptr; GlobalManager *GlobalManagerPlugin::m_pManager = nullptr; GlobalManagerPlugin::~GlobalManagerPlugin() { if (m_pManager != nullptr) { delete m_pManager; m_pManager = nullptr; } } GlobalManagerPlugin::GlobalManagerPlugin() { if (m_pManager == nullptr) { m_pManager = GlobalManager::GlobalManagerNew(); } } PluginInterface *GlobalManagerPlugin::getInstance() { if (nullptr == m_Instance) { m_Instance = new GlobalManagerPlugin(); } return m_Instance; } void GlobalManagerPlugin::activate() { m_pManager->start(); } void GlobalManagerPlugin::deactivate() { m_pManager->stop(); } PluginInterface *createSettingsPlugin() { return GlobalManagerPlugin::getInstance(); } ukui-settings-daemon/plugins/global-manager/global-signal.h0000664000175000017500000001030715174103014022766 0ustar fengfeng/* -*- Mode: C++; indent-tabs-mode: nil; tab-width: 4 -*- * -*- coding: utf-8 -*- * * Copyright (C) 2023 KylinSoft Co., Ltd. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef GSETTINGSCONFIG_H #define GSETTINGSCONFIG_H #include #include #include #include #include #include #include #include "QGSettings/qgsettings.h" #include "clib-syslog.h" #include "qdbus-login1-abstract-interface.h" #include "usd_base_class.h" struct UKUILite{ QString function; QString animation; }; Q_DECLARE_METATYPE(UKUILite) inline QDBusArgument &operator << (QDBusArgument &argument, const UKUILite &lite) { argument.beginStructure(); argument << lite.function; argument << lite.animation; argument.endStructure(); return argument; } inline const QDBusArgument &operator >> (const QDBusArgument &argument, UKUILite &lite) { argument.beginStructure(); argument >> lite.function; argument >> lite.animation; argument.endStructure(); return argument; } class GlobalSignal: public QObject { Q_OBJECT Q_CLASSINFO("D-Bus Interface","org.ukui.SettingsDaemon.GlobalSignal") public: GlobalSignal(QObject *parent = nullptr); ~GlobalSignal(); Q_SIGNALS: /** * @brief userActive * @return * 用户登录,登出状态。 */ void Active(int userState); /** * @brief getUKUILiteLevel * @param liteMode * UKUILite 模式 */ void UKUILiteChanged(UKUILite liteMode); public Q_SLOTS: /** * @brief sendUserActiveSignal */ void sendUserActiveSignal(QString interface, QVariantMap qvarMap, QStringList strList); /** * @brief hadLightSensor * @return */ bool isPresenceLightSensor(); /** * @brief getShutdownDisableOptions * @return * 获取关机页面需要屏蔽的选项 */ QStringList getShutdownDisableOptions(); /** * @brief isHidePoweroffUi * @return */ bool isHidePoweroffUi(); /** * @brief getUKUILiteLevel * @param function 功能等级 * @param animation 动效等级 * @return */ UKUILite getUKUILiteLevel(); /** * @brief getUKUILiteFunction * @return * 获取ukuilite功能级别 */ QString getUKUILiteFunction(); /** * @brief getUKUILiteFunction * @return * 获取ukuilite动效级别 */ QString getUKUILiteAnimation(); private Q_SLOTS: /** * @brief doGMsettinsChange * @param key * 同步全局电源选项配置。 */ void doGMsettinsChange(QString key); private: /** * @brief connectUserActiveSignal */ void connectUserActiveSignal(); void connectUserActiveSignalWithPath(QString path); void connectUserLogin1Signal(); /** * @brief getGlobalConfig * @param schema * @param key * @return */ QVariant getGlobalConfig(QString schema, QString key); /** * @brief getShutDownDisableOptionInGsettings * @return */ QList getShutDownDisableOptionInGsettings(); /** * @brief getShutDownDisableOptionFromGlobalManager * @return */ QStringList getShutDownDisableOptionFromGlobalManager(); bool getHidePowerUiFromGlobalManager(); const QList m_allOptions = {"switchuser","hibernate","suspend","lockscreen","logout","restart","shutdown"}; private: DBusLogin1Interface *m_plogin1 = nullptr; QDBusInterface *m_plogin2 = nullptr; QDBusInterface *m_ploginWithPath = nullptr; QGSettings *m_pGMsettings = nullptr; }; #endif // GSETTINGSCONFIG_H ukui-settings-daemon/plugins/global-manager/globalManager.ukui-settings-plugin0000664000175000017500000000031315174103014026662 0ustar fengfeng[UKUI Settings Plugin] Module=globalManager IAge=0 Name=globalManager Name[zh_CN]=全局管理 Description=globalManager plugin Authors=Leon Sun Copyright=Copyright (C) 2023 KylinSoft Co., Ltd. Website= ukui-settings-daemon/plugins/global-manager/global-manager.pro0000664000175000017500000000452115174103014023475 0ustar fengfengQT -= gui QT += network TEMPLATE = lib TARGET = globalManager DEFINES += DEMO_LIBRARY #link_pkgconfig no_keywords plugin app_bundlels 必须要加否则会出现so文件版本的链接 CONFIG += c++20 link_pkgconfig no_keywords plugin app_bundlels # The following define makes your compiler emit warnings if you use # any Qt feature that has been marked 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 MODULE_NAME=\\\"globalManager\\\" INCLUDEPATH += \ -I ukui-settings-daemon/ include($$PWD/../../common/common.pri) # You can also make your code fail to compile if it uses 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 SOURCES += \ gamma-brightness.cpp \ global-manager-plugin.cpp \ global-manager.cpp \ brightness.cpp \ global-signal.cpp \ powermanager-brightness.cpp HEADERS += \ abstract-brightness.h \ gamma-brightness.h \ global-manager-plugin.h \ global-manager.h \ brightness.h \ global-signal.h \ powermanager-brightness.h \ qdbus-login1-abstract-interface.h # Default rules for deployment. # OTHER_FILES += org.ukui.peripherals-keyboard.demoplugin.xml globalManagerplugin_lib.path = $${PLUGIN_INSTALL_DIRS} globalManagerplugin_lib.files = $$OUT_PWD/libglobalManager.so globalManagerplugin_info.path = $$[QT_INSTALL_LIBS]/ukui-settings-daemon globalManagerplugin_info.files = $$OUT_PWD/globalManager.ukui-settings-plugin globalManagerplugin_schema.path = /usr/share/glib-2.0/schemas/ globalManagerplugin_schema.files = $$OUT_PWD/org.ukui.SettingsDaemon.plugins.globalManager.gschema.xml #禁用优化 QMAKE_CFLAGS_DEBUG -= O2 QMAKE_CXXFLAGS_DEBUG -= -O2 QMAKE_CFLAGS_RELEASE -= O2 QMAKE_CXXFLAGS_RELEASE -= -O2 #lib must at last INSTALLS += globalManagerplugin_lib globalManagerplugin_info globalManagerplugin_schema DISTFILES += \ globalManager.ukui-settings-plugin \ org.ukui.SettingsDaemon.plugins.globalManager.gschema.xml ukui-settings-daemon/plugins/global-manager/qdbus-login1-abstract-interface.h0000664000175000017500000000635015174103014026322 0ustar fengfeng/* -*- Mode: C++; indent-tabs-mode: nil; tab-width: 4 -*- * -*- coding: utf-8 -*- * * Copyright (C) 2023 KylinSoft Co., Ltd. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef QBUSLOGIN1ABSTRACTINTERFACE_H #define QBUSLOGIN1ABSTRACTINTERFACE_H #include #include #include #include #include #include #include #include struct SessionStruct{ QString userId; QDBusObjectPath userPath; }; typedef QList SessionStructList; Q_DECLARE_METATYPE(SessionStruct) Q_DECLARE_METATYPE(SessionStructList) inline QDBusArgument &operator << (QDBusArgument &argument, const SessionStruct &sessionStruct) { argument.beginStructure(); argument << sessionStruct.userId; argument << sessionStruct.userPath; argument.endStructure(); return argument; } inline const QDBusArgument &operator >> (const QDBusArgument &argument, SessionStruct &sessionStruct) { argument.beginStructure(); argument >> sessionStruct.userId; argument >> sessionStruct.userPath; argument.endStructure(); return argument; } inline QDBusArgument &operator << (QDBusArgument &argument, QList &sessionStruct) { argument.beginStructure(); argument << sessionStruct; argument.endStructure(); return argument; } inline const QDBusArgument &operator >> (QDBusArgument &argument, QList &sessionStruct) { argument.beginStructure(); argument >> sessionStruct; argument.endStructure(); return argument; } class DBusLogin1Interface : public QDBusAbstractInterface { Q_OBJECT public: DBusLogin1Interface(const QString &service, const QString &path, const char *interface, const QDBusConnection &connection, QObject *parent = nullptr): QDBusAbstractInterface(service,path,interface,connection,parent) { qRegisterMetaType("SessionStruct"); qRegisterMetaType("SessionStructList"); qDBusRegisterMetaType(); qDBusRegisterMetaType(); } virtual ~DBusLogin1Interface() {} Q_PROPERTY(SessionStructList sessions READ readSessions) SessionStructList readSessions() const { return qvariant_cast(property("Sessions")); } Q_PROPERTY(QString name READ readName) QString readName() const { return qvariant_cast(property("Name")); } private: SessionStructList sessions; QString name; Q_SIGNALS: void PropertiesChanged(const QVariantMap &properties); }; #endif // QBUSLOGIN1ABSTRACTINTERFACE_H ukui-settings-daemon/plugins/global-manager/brightness.cpp0000664000175000017500000001014215174103014022753 0ustar fengfeng/* -*- Mode: C++; indent-tabs-mode: nil; tab-width: 4 -*- * -*- coding: utf-8 -*- * * Copyright (C) 2023 KylinSoft Co., Ltd. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include "brightness.h" /* * 主屏机制问题:如果主屏没有在台式机外接的任意一台机器,主屏如何处理? * 1:USD无法感知,通过QApplication获取的主屏,与panel、peony实际位置并不相符合。。 */ Brightness::Brightness(QObject *parent) { QDBusInterface powerInterface("org.ukui.powermanagement", "/", "org.ukui.powermanagement.interface", QDBusConnection::systemBus()); QDBusReply replay = powerInterface.call("CanSetBrightness"); if(replay.isValid()) { m_powerManagerSetable = replay.value(); if (m_powerManagerSetable) { m_brightnessManager = new PowerManagerBrightness(this); } } if (!m_powerManagerSetable) { if (UsdBaseClass::isWaylandWithKscreen()) { return; } else { m_gammaManagerSetable = true; m_brightnessManager = new GammaBrightness(this); } } if (m_brightnessManager != nullptr) { m_brightnessManager->connectTheSignal(); } m_brightCacheTimer = new QTimer(); connect(m_brightCacheTimer, &QTimer::timeout, this, [=](){ USD_LOG(LOG_DEBUG,"start set."); sendPrimaryStartChanged(m_targetPrimaryBrightness); m_brightnessManager->setBrightness(m_targetPrimaryBrightness); }); m_brightCacheTimer->setSingleShot(true); } uint Brightness::getPrimaryBrightness() { if (!isEnable()) { return -1; } return m_brightnessManager->getBrightness(); } bool Brightness::setPrimaryBrightness(uint Brightness) { static QTime startTime = QTime::currentTime(); static int elapsed = -1; elapsed = startTime.msecsTo(QTime::currentTime()); if (Brightness > 100 || !isEnable()) { return false; } m_targetPrimaryBrightness = Brightness; /* * After multiple dragging, signals with intervals ranging from 100-600ms will still be received. * If the signal time difference is less than 700ms, * a timer with a timeout of 251ms will be used to filter out duplicate events */ if(elapsed > 0 && elapsed <= 700){ if(!m_brightCacheTimer->isActive() && elapsed) { m_brightCacheTimer->start(251); USD_LOG(LOG_DEBUG,"start timer."); } else { USD_LOG(LOG_DEBUG,"skip timer."); } return false; } USD_LOG(LOG_DEBUG,"set it.%d",elapsed); m_brightCacheTimer->stop(); startTime = QTime::currentTime(); sendPrimaryStartChanged(m_targetPrimaryBrightness); m_brightnessManager->setBrightness(m_targetPrimaryBrightness); return true; } bool Brightness::isEnable() { return (bool)(m_gammaManagerSetable | m_powerManagerSetable); } QString Brightness::backend() { if (!isEnable()) { return "disable"; } return m_brightnessManager->backend(); } void Brightness::sendPrimaryStartChanged(int brightness) { static int lastBrightness = -1; if (brightness == lastBrightness) { return; } lastBrightness = brightness; QDBusMessage notifySignal = QDBusMessage::createSignal(DBUS_GC_BRIGHTNESS_PATH, DBUS_GC_BRIGHTNESS_INTERFACE, DBUS_GC_BRIGHTNESS_SIGNAL_PRIMARYCHANGED_START); notifySignal.setArguments({QVariant::fromValue((uint)brightness)}); QDBusConnection::sessionBus().send(notifySignal); } ukui-settings-daemon/plugins/global-manager/global-manager.cpp0000664000175000017500000000365515174103014023466 0ustar fengfeng/* -*- Mode: C++; indent-tabs-mode: nil; tab-width: 4 -*- * -*- coding: utf-8 -*- * * Copyright (C) 2023 KylinSoft Co., Ltd. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include "global-manager.h" GlobalManager *GlobalManager::m_globalManager = nullptr; GlobalManager::GlobalManager() { m_pBright = new Brightness(); m_pSignal = new GlobalSignal(); QDBusConnection sessionBug = QDBusConnection::sessionBus(); if (sessionBug.registerService("org.ukui.SettingsDaemon")) { sessionBug.registerObject(DBUS_GC_BRIGHTNESS_PATH, m_pBright, QDBusConnection::ExportAllSlots | QDBusConnection::ExportAllSignals ); sessionBug.registerObject("/GlobalSignal", m_pSignal, QDBusConnection::ExportAllSlots | QDBusConnection::ExportAllSignals ); } } GlobalManager::~GlobalManager() { if (m_pBright != nullptr) { delete m_pBright; m_pBright = nullptr; } if (m_pSignal != nullptr) { delete m_pSignal; m_pSignal = nullptr; } } GlobalManager *GlobalManager::GlobalManagerNew() { if (m_globalManager == nullptr) { m_globalManager = new GlobalManager(); } return m_globalManager; } void GlobalManager::start() { } void GlobalManager::stop() { } ukui-settings-daemon/plugins/global-manager/global-manager-plugin.h0000664000175000017500000000250415174103014024417 0ustar fengfeng/* -*- Mode: C++; indent-tabs-mode: nil; tab-width: 4 -*- * -*- coding: utf-8 -*- * * Copyright (C) 2023 KylinSoft Co., Ltd. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef GLOBALMANAGERPLUGIN_H #define GLOBALMANAGERPLUGIN_H #include "plugin-interface.h" #include "global-manager.h" class GlobalManagerPlugin: public PluginInterface { public: ~GlobalManagerPlugin(); static PluginInterface *getInstance(); virtual void activate(); virtual void deactivate(); private: GlobalManagerPlugin(); GlobalManagerPlugin(GlobalManagerPlugin&)=delete; static GlobalManager *m_pManager; static PluginInterface *m_Instance; }; extern "C" Q_DECL_EXPORT PluginInterface* createSettingsPlugin(); #endif // GLOBALMANAGERPLUGIN_H ukui-settings-daemon/plugins/clipboard/0000775000175000017500000000000015174103014017170 5ustar fengfengukui-settings-daemon/plugins/clipboard/clipboard-plugin.h0000664000175000017500000000254115174103014022576 0ustar fengfeng/* -*- Mode: C++; indent-tabs-mode: nil; tab-width: 4 -*- * -*- coding: utf-8 -*- * * Copyright (C) 2023 KylinSoft Co., Ltd. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef CLIPBOARDPLUGIN_H #define CLIPBOARDPLUGIN_H #include "plugin-interface.h" #include "clipboard-manager.h" #include "usd_base_class.h" class ClipboardPlugin : public PluginInterface { public: ~ClipboardPlugin(); static PluginInterface* getInstance(); virtual void activate (); virtual void deactivate (); private: ClipboardPlugin(); ClipboardPlugin(ClipboardPlugin&)=delete; private: ClipboardManager* mManager = nullptr; static PluginInterface* mInstance; }; extern "C" Q_DECL_EXPORT PluginInterface* createSettingsPlugin(); #endif // CLIPBOARDPLUGIN_H ukui-settings-daemon/plugins/clipboard/xutils.h0000664000175000017500000000260415174103014020673 0ustar fengfeng/* -*- Mode: C++; indent-tabs-mode: nil; tab-width: 4 -*- * -*- coding: utf-8 -*- * * Copyright (C) 2023 KylinSoft Co., Ltd. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef X_UTILS_H #define X_UTILS_H #include #ifdef __cplusplus extern "C" { #endif extern Atom XA_ATOM_PAIR; extern Atom XA_CLIPBOARD_MANAGER; extern Atom XA_CLIPBOARD; extern Atom XA_DELETE; extern Atom XA_INCR; extern Atom XA_INSERT_PROPERTY; extern Atom XA_INSERT_SELECTION; extern Atom XA_MANAGER; extern Atom XA_MULTIPLE; extern Atom XA_NULL; extern Atom XA_SAVE_TARGETS; extern Atom XA_TARGETS; extern Atom XA_TIMESTAMP; extern unsigned long SELECTION_MAX_SIZE; void init_atoms (Display *display); Time get_server_time (Display *display, Window window); #ifdef __cplusplus } #endif #endif /* X_UTILS_H */ ukui-settings-daemon/plugins/clipboard/list.h0000664000175000017500000000367115174102667020340 0ustar fengfeng/* * Copyright © 2004 Red Hat, Inc. * * Permission to use, copy, modify, distribute, and sell this software and its * documentation for any purpose is hereby granted without fee, provided that * the above copyright notice appear in all copies and that both that * copyright notice and this permission notice appear in supporting * documentation, and that the name of Red Hat not be used in advertising or * publicity pertaining to distribution of the software without specific, * written prior permission. Red Hat makes no representations about the * suitability of this software for any purpose. It is provided "as is" * without express or implied warranty. * * RED HAT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL RED HAT * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * * Author: Matthias Clasen, Red Hat, Inc. */ #ifndef LIST_H #define LIST_H #ifdef __cplusplus extern "C" { #endif typedef struct _List List; typedef void (*Callback) (void *data, void *user_data); struct _List { void *data; List *next; }; typedef int (*ListFindFunc) (void *data, void *user_data); void list_foreach (List *list, Callback func, void *user_data); List *list_prepend (List *list, void *data); void list_free (List *list); List *list_find (List *list, ListFindFunc func, void *user_data); List *list_remove (List *list, void *data); int list_length (List *list); List *list_copy (List *list); #ifdef __cplusplus } #endif #endif /* LIST_H */ ukui-settings-daemon/plugins/clipboard/clipboard-manager.cpp0000664000175000017500000006157215174103014023256 0ustar fengfeng/* -*- Mode: C++; indent-tabs-mode: nil; tab-width: 4 -*- * -*- coding: utf-8 -*- * * Copyright (C) 2023 KylinSoft Co., Ltd. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include "clipboard-manager.h" #include #include #include #include #include #include #include #include #include #include #include #include #include "list.h" #include "xutils.h" #include "clib-syslog.h" ClipboardManager::ClipboardManager(QObject *parent) : QThread(parent) { mExit = false; mDisplay = nullptr; mContents = nullptr; mConversions = nullptr; gdk_init(NULL, NULL); GdkDisplay* display = gdk_display_get_default(); if (nullptr == display) { USD_LOG(LOG_ERR, "get GdkDisplay error"); return; } mDisplay = gdk_x11_display_get_xdisplay(display); } ClipboardManager::~ClipboardManager() { } void target_data_unref (TargetData *data) { data->refcount--; if (data->refcount == 0) { free (data->data); free (data); } } void conversion_free (IncrConversion* rdata) { if (rdata->data) { target_data_unref (rdata->data); } free (rdata); } bool ClipboardManager::managerStart() { if (nullptr == mDisplay) { return false; } start(QThread::LowestPriority); return true; } bool ClipboardManager::managerStop() { clipboard_manager_watch_cb (this, mWindow, FALSE, 0, NULL); XDestroyWindow (mDisplay, mWindow); list_foreach (mConversions, (Callback) conversion_free, NULL); list_free (mConversions); list_foreach (mContents, (Callback) target_data_unref, NULL); list_free (mContents); mExit = true; QThread::exit(0); return true; } void ClipboardManager::run() { while (!mExit) { XClientMessageEvent xev; if (nullptr == mDisplay) { return; } init_atoms (mDisplay); /* check if there is a clipboard manager running */ if (XGetSelectionOwner (mDisplay, XA_CLIPBOARD_MANAGER)) { USD_LOG(LOG_ERR, "Clipboard manager is already running."); mExit = false; return; } mContents = nullptr; mConversions = nullptr; mRequestor = None; mWindow = XCreateSimpleWindow (mDisplay, DefaultRootWindow (mDisplay), 0, 0, 10, 10, 0, WhitePixel (mDisplay, DefaultScreen (mDisplay)), WhitePixel (mDisplay, DefaultScreen (mDisplay))); clipboard_manager_watch_cb (this, mWindow, True, PropertyChangeMask, NULL); XSelectInput (mDisplay, mWindow, PropertyChangeMask); mTimestamp = get_server_time (mDisplay, mWindow); XSetSelectionOwner (mDisplay, XA_CLIPBOARD_MANAGER, mWindow, mTimestamp); /* Check to see if we managed to claim the selection. If not, we treat it as if we got it then immediately lost it */ if (XGetSelectionOwner (mDisplay, XA_CLIPBOARD_MANAGER) == mWindow) { xev.type = ClientMessage; xev.window = DefaultRootWindow (mDisplay); xev.message_type = XA_MANAGER; xev.format = 32; xev.data.l[0] = mTimestamp; xev.data.l[1] = XA_CLIPBOARD_MANAGER; xev.data.l[2] = mWindow; xev.data.l[3] = 0; /* manager specific data */ xev.data.l[4] = 0; /* manager specific data */ XSendEvent (mDisplay, DefaultRootWindow (mDisplay), False, StructureNotifyMask, (XEvent *)&xev); } else { clipboard_manager_watch_cb (this, mWindow, False, 0, NULL); /* FIXME: manager->priv->terminate (manager->priv->cb_data); */ } } } GdkFilterReturn clipboard_manager_event_filter (GdkXEvent* xevent, GdkEvent*, ClipboardManager* manager) { if (clipboard_manager_process_event (manager, (XEvent *)xevent)) { return GDK_FILTER_REMOVE; } else { return GDK_FILTER_CONTINUE; } } void clipboard_manager_watch_cb(ClipboardManager* manager, Window window, bool isStart, long, void*) { GdkWindow* gdkwin; GdkDisplay* display; display = gdk_display_get_default (); gdkwin = gdk_x11_window_lookup_for_display (display, window); if (isStart) { if (gdkwin == NULL) { gdkwin = gdk_x11_window_foreign_new_for_display (display, window); } else { g_object_ref (gdkwin); } gdk_window_add_filter (gdkwin, (GdkFilterFunc)clipboard_manager_event_filter, manager); } else { if (gdkwin == NULL) { return; } gdk_window_remove_filter (gdkwin, (GdkFilterFunc)clipboard_manager_event_filter, manager); g_object_unref (gdkwin); } } int clipboard_bytes_per_item (int format) { switch (format) { case 8: return sizeof (char); case 16: return sizeof (short); case 32: return sizeof (long); default: ; } return 0; } void get_property (TargetData* tdata, ClipboardManager* manager) { Atom type; int format; unsigned long length; unsigned long remaining; unsigned char* data; XGetWindowProperty (manager->mDisplay, manager->mWindow, tdata->target, 0, 0x1FFFFFFF, true, AnyPropertyType, &type, &format, &length, &remaining, &data); if (type == None) { manager->mContents = list_remove (manager->mContents, tdata); free (tdata); } else if (type == XA_INCR) { tdata->type = type; tdata->length = 0; XFree (data); } else { tdata->type = type; tdata->data = data; tdata->length = length * clipboard_bytes_per_item (format); tdata->format = format; } } int find_content_type (TargetData* tdata, Atom type) { return tdata->type == type; } int find_content_target (TargetData* tdata, Atom target) { return tdata->target == target; } TargetData* target_data_ref (TargetData *data) { data->refcount++; return data; } void convert_clipboard_target (IncrConversion* rdata, ClipboardManager* manager) { TargetData *tdata; Atom *targets; int n_targets; List *list; unsigned long items; XWindowAttributes atts; if (rdata->target == XA_TARGETS) { n_targets = list_length (manager->mContents) + 2; targets = (Atom *) malloc (n_targets * sizeof (Atom)); n_targets = 0; targets[n_targets++] = XA_TARGETS; targets[n_targets++] = XA_MULTIPLE; for (list = manager->mContents; list; list = list->next) { tdata = (TargetData *) list->data; targets[n_targets++] = tdata->target; } XChangeProperty (manager->mDisplay, rdata->requestor, rdata->property, XA_ATOM, 32, PropModeReplace, (unsigned char *) targets, n_targets); free (targets); } else { /* Convert from stored CLIPBOARD data */ list = list_find (manager->mContents, (ListFindFunc) find_content_target, (void *) rdata->target); /* We got a target that we don't support */ if (!list) return; tdata = (TargetData *)list->data; if (tdata->type == XA_INCR) { /* we haven't completely received this target yet */ rdata->property = None; return; } rdata->data = target_data_ref (tdata); items = tdata->length / clipboard_bytes_per_item (tdata->format); if (tdata->length <= (int)SELECTION_MAX_SIZE) XChangeProperty (manager->mDisplay, rdata->requestor, rdata->property, tdata->type, tdata->format, PropModeReplace, tdata->data, items); else { /* start incremental transfer */ rdata->offset = 0; gdk_x11_display_error_trap_push(gdk_display_get_default()); XGetWindowAttributes (manager->mDisplay, rdata->requestor, &atts); XSelectInput (manager->mDisplay, rdata->requestor, atts.your_event_mask | PropertyChangeMask); XChangeProperty (manager->mDisplay, rdata->requestor, rdata->property, XA_INCR, 32, PropModeReplace, (unsigned char *) &items, 1); XSync (manager->mDisplay, False); gdk_x11_display_error_trap_pop_ignored(gdk_display_get_default()); } } } void collect_incremental (IncrConversion* rdata, ClipboardManager* manager) { if (rdata->offset >= 0) manager->mConversions = list_prepend (manager->mConversions, rdata); else { if (rdata->data) { target_data_unref (rdata->data); rdata->data = NULL; } free (rdata); } } void convert_clipboard (ClipboardManager* manager, XEvent* xev) { int format; unsigned long nitems; unsigned long remaining; List* list; List* conversions; Atom type; Atom* multiple = nullptr; IncrConversion* rdata; conversions = NULL; type = None; if (xev->xselectionrequest.target == XA_MULTIPLE) { XGetWindowProperty (xev->xselectionrequest.display, xev->xselectionrequest.requestor, xev->xselectionrequest.property, 0, 0x1FFFFFFF, False, XA_ATOM_PAIR, &type, &format, &nitems, &remaining, (unsigned char **) &multiple); if (type != XA_ATOM_PAIR || nitems == 0) { if (multiple) free (multiple); return; } for (unsigned long i = 0; i < nitems; i += 2) { rdata = (IncrConversion *) malloc (sizeof (IncrConversion)); rdata->requestor = xev->xselectionrequest.requestor; rdata->target = multiple[i]; rdata->property = multiple[i+1]; rdata->data = NULL; rdata->offset = -1; conversions = list_prepend (conversions, rdata); } } else { multiple = NULL; rdata = (IncrConversion *) malloc (sizeof (IncrConversion)); rdata->requestor = xev->xselectionrequest.requestor; rdata->target = xev->xselectionrequest.target; rdata->property = xev->xselectionrequest.property; rdata->data = NULL; rdata->offset = -1; conversions = list_prepend (conversions, rdata); } list_foreach (conversions, (Callback) convert_clipboard_target, manager); if (conversions->next == NULL && ((IncrConversion *) conversions->data)->property == None) { finish_selection_request (manager, xev, False); } else { if (multiple) { int i = 0; for (list = conversions; list; list = list->next) { rdata = (IncrConversion *)list->data; multiple[i++] = rdata->target; multiple[i++] = rdata->property; } XChangeProperty (xev->xselectionrequest.display, xev->xselectionrequest.requestor, xev->xselectionrequest.property, XA_ATOM_PAIR, 32, PropModeReplace, (unsigned char *) multiple, nitems); } finish_selection_request (manager, xev, True); } list_foreach (conversions, (Callback) collect_incremental, manager); list_free (conversions); if (multiple) free (multiple); } bool clipboard_manager_process_event(ClipboardManager* manager, XEvent* xev) { int format; Atom type; Atom* targets; unsigned long nitems; unsigned long remaining; targets = nullptr; switch (xev->xany.type) { case DestroyNotify: if (xev->xdestroywindow.window == manager->mRequestor) { list_foreach (manager->mContents, (Callback)target_data_unref, nullptr); list_free (manager->mContents); manager->mContents = nullptr; clipboard_manager_watch_cb (manager, manager->mRequestor, false, 0, nullptr); manager->mRequestor = None; } break; case PropertyNotify: if (xev->xproperty.state == PropertyNewValue) { return receive_incrementally (manager, xev); } else { return send_incrementally (manager, xev); } case SelectionClear: if (xev->xany.window != manager->mWindow) return false; if (xev->xselectionclear.selection == XA_CLIPBOARD_MANAGER) { /* We lost the manager selection */ if (manager->mContents) { list_foreach (manager->mContents, (Callback)target_data_unref, nullptr); list_free (manager->mContents); manager->mContents = nullptr; XSetSelectionOwner (manager->mDisplay, XA_CLIPBOARD, None, manager->mTime); } return True; } if (xev->xselectionclear.selection == XA_CLIPBOARD) { /* We lost the clipboard selection */ list_foreach (manager->mContents, (Callback)target_data_unref, nullptr); list_free (manager->mContents); manager->mContents = nullptr; clipboard_manager_watch_cb (manager, manager->mRequestor, false, 0, nullptr); manager->mRequestor = None; return true; } break; case SelectionNotify: if (xev->xany.window != manager->mWindow) return false; if (xev->xselection.selection == XA_CLIPBOARD) { /* a CLIPBOARD conversion is done */ if (xev->xselection.property == XA_TARGETS) { XGetWindowProperty (xev->xselection.display, xev->xselection.requestor, xev->xselection.property, 0, 0x1FFFFFFF, True, XA_ATOM, &type, &format, &nitems, &remaining, (unsigned char **) &targets); save_targets (manager, targets, nitems); } else if (xev->xselection.property == XA_MULTIPLE) { List *tmp; tmp = list_copy (manager->mContents); list_foreach (tmp, (Callback) get_property, manager); list_free (tmp); manager->mTime = xev->xselection.time; XSetSelectionOwner (manager->mDisplay, XA_CLIPBOARD, manager->mWindow, manager->mTime); if (manager->mProperty != None) XChangeProperty (manager->mDisplay, manager->mRequestor, manager->mProperty, XA_ATOM, 32, PropModeReplace, (unsigned char *)&XA_NULL, 1); if (!list_find (manager->mContents, (ListFindFunc)find_content_type, (void *)XA_INCR)) { /* all transfers done */ send_selection_notify (manager, True); clipboard_manager_watch_cb (manager, manager->mRequestor, false, 0, nullptr); manager->mRequestor = None; } } else if (xev->xselection.property == None) { send_selection_notify (manager, false); clipboard_manager_watch_cb (manager, manager->mRequestor, false, 0, nullptr); manager->mRequestor = None; } return true; } break; case SelectionRequest: if (xev->xany.window != manager->mWindow) { return false; } if (xev->xselectionrequest.selection == XA_CLIPBOARD_MANAGER) { convert_clipboard_manager (manager, xev); return true; } else if (xev->xselectionrequest.selection == XA_CLIPBOARD) { convert_clipboard (manager, xev); return true; } break; default: ; } return false; } bool receive_incrementally (ClipboardManager* manager, XEvent* xev) { List* list; TargetData* tdata; Atom type; int format; unsigned char* data; unsigned long length, nitems, remaining; if (xev->xproperty.window != manager->mWindow) return false; list = list_find (manager->mContents, (ListFindFunc) find_content_target, (void *) xev->xproperty.atom); if (!list) return false; tdata = (TargetData *) list->data; if (tdata->type != XA_INCR) return false; XGetWindowProperty (xev->xproperty.display, xev->xproperty.window, xev->xproperty.atom, 0, 0x1FFFFFFF, True, AnyPropertyType, &type, &format, &nitems, &remaining, &data); length = nitems * clipboard_bytes_per_item (format); if (length == 0) { tdata->type = type; tdata->format = format; if (!list_find (manager->mContents, (ListFindFunc) find_content_type, (void *)XA_INCR)) { /* all incremental transfers done */ send_selection_notify (manager, True); manager->mRequestor = None; } XFree (data); } else { if (!tdata->data) { tdata->data = data; tdata->length = length; } else { tdata->data = (unsigned char*)realloc (tdata->data, tdata->length + length + 1); memcpy (tdata->data + tdata->length, data, length + 1); tdata->length += length; XFree (data); } } return True; } int find_conversion_requestor (IncrConversion* rdata, XEvent* xev) { return (rdata->requestor == xev->xproperty.window && rdata->property == xev->xproperty.atom); } bool send_incrementally (ClipboardManager* manager, XEvent* xev) { List* list; unsigned long length; unsigned long items; unsigned char* data; IncrConversion* rdata; list = list_find (manager->mConversions, (ListFindFunc) find_conversion_requestor, xev); if (list == NULL) return false; rdata = (IncrConversion *) list->data; data = rdata->data->data + rdata->offset; length = rdata->data->length - rdata->offset; if (length > SELECTION_MAX_SIZE) length = SELECTION_MAX_SIZE; rdata->offset += length; items = length / clipboard_bytes_per_item (rdata->data->format); XChangeProperty (manager->mDisplay, rdata->requestor, rdata->property, rdata->data->type, rdata->data->format, PropModeAppend, data, items); if (length == 0) { manager->mConversions = list_remove (manager->mConversions, rdata); conversion_free (rdata); } return true; } void save_targets (ClipboardManager* manager, Atom* save_targets, int nitems) { int nout, i; Atom *multiple; TargetData *tdata; multiple = (Atom *) malloc (2 * nitems * sizeof (Atom)); nout = 0; for (i = 0; i < nitems; i++) { if (save_targets[i] != XA_TARGETS && save_targets[i] != XA_MULTIPLE && save_targets[i] != XA_DELETE && save_targets[i] != XA_INSERT_PROPERTY && save_targets[i] != XA_INSERT_SELECTION && save_targets[i] != XA_PIXMAP) { tdata = (TargetData *) malloc (sizeof (TargetData)); tdata->data = NULL; tdata->length = 0; tdata->target = save_targets[i]; tdata->type = None; tdata->format = 0; tdata->refcount = 1; manager->mContents = list_prepend (manager->mContents, tdata); multiple[nout++] = save_targets[i]; multiple[nout++] = save_targets[i]; } } XFree (save_targets); XChangeProperty (manager->mDisplay, manager->mWindow, XA_MULTIPLE, XA_ATOM_PAIR, 32, PropModeReplace, (const unsigned char *) multiple, nout); free (multiple); XConvertSelection (manager->mDisplay, XA_CLIPBOARD, XA_MULTIPLE, XA_MULTIPLE, manager->mWindow, manager->mTime); } void send_selection_notify (ClipboardManager* manager, bool success) { XSelectionEvent notify; notify.type = SelectionNotify; notify.serial = 0; notify.send_event = True; notify.display = manager->mDisplay; notify.requestor = manager->mRequestor; notify.selection = XA_CLIPBOARD_MANAGER; notify.target = XA_SAVE_TARGETS; notify.property = success ? manager->mProperty : None; notify.time = manager->mTime; gdk_x11_display_error_trap_push(gdk_display_get_default()); XSendEvent (manager->mDisplay, manager->mRequestor, false, NoEventMask, (XEvent *)¬ify); XSync (manager->mDisplay, false); gdk_x11_display_error_trap_pop_ignored(gdk_display_get_default()); } void convert_clipboard_manager (ClipboardManager* manager, XEvent* xev) { Atom type = None; int format; unsigned long nitems; unsigned long remaining; Atom *targets = NULL; if (xev->xselectionrequest.target == XA_SAVE_TARGETS) { if (manager->mRequestor != None || manager->mContents != nullptr) { /* We're in the middle of a conversion request, or own the CLIPBOARD already */ finish_selection_request (manager, xev, False); } else { gdk_x11_display_error_trap_push(gdk_display_get_default()); clipboard_manager_watch_cb (manager, xev->xselectionrequest.requestor, true, StructureNotifyMask, nullptr); XSelectInput (manager->mDisplay, xev->xselectionrequest.requestor, StructureNotifyMask); XSync (manager->mDisplay, false); if (gdk_x11_display_error_trap_pop (gdk_display_get_default()) != Success) return; gdk_x11_display_error_trap_push(gdk_display_get_default()); if (xev->xselectionrequest.property != None) { XGetWindowProperty (manager->mDisplay, xev->xselectionrequest.requestor, xev->xselectionrequest.property, 0, 0x1FFFFFFF, False, XA_ATOM, &type, &format, &nitems, &remaining, (unsigned char **) &targets); if (gdk_x11_display_error_trap_pop (gdk_display_get_default()) != Success) { if (targets) XFree (targets); return; } } manager->mRequestor = xev->xselectionrequest.requestor; manager->mProperty = xev->xselectionrequest.property; manager->mTime = xev->xselectionrequest.time; if (type == None) XConvertSelection (manager->mDisplay, XA_CLIPBOARD, XA_TARGETS, XA_TARGETS, manager->mWindow, manager->mTime); else save_targets (manager, targets, nitems); } } else if (xev->xselectionrequest.target == XA_TIMESTAMP) { XChangeProperty (manager->mDisplay, xev->xselectionrequest.requestor, xev->xselectionrequest.property, XA_INTEGER, 32, PropModeReplace, (unsigned char *) &manager->mTimestamp, 1); finish_selection_request (manager, xev, true); } else if (xev->xselectionrequest.target == XA_TARGETS) { int n_targets = 0; Atom targets[3]; targets[n_targets++] = XA_TARGETS; targets[n_targets++] = XA_TIMESTAMP; targets[n_targets++] = XA_SAVE_TARGETS; XChangeProperty (manager->mDisplay, xev->xselectionrequest.requestor, xev->xselectionrequest.property, XA_ATOM, 32, PropModeReplace, (unsigned char *) targets, n_targets); finish_selection_request (manager, xev, true); } else { finish_selection_request (manager, xev, false); } } void finish_selection_request (ClipboardManager* manager, XEvent* xev, bool success) { XSelectionEvent notify; notify.type = SelectionNotify; notify.serial = 0; notify.send_event = true; notify.display = xev->xselectionrequest.display; notify.requestor = xev->xselectionrequest.requestor; notify.selection = xev->xselectionrequest.selection; notify.target = xev->xselectionrequest.target; notify.property = success ? xev->xselectionrequest.property : None; notify.time = xev->xselectionrequest.time; gdk_x11_display_error_trap_push (gdk_display_get_default()); XSendEvent (xev->xselectionrequest.display, xev->xselectionrequest.requestor, false, NoEventMask, (XEvent *) ¬ify); XSync (manager->mDisplay, false); gdk_x11_display_error_trap_pop_ignored(gdk_display_get_default()); } ukui-settings-daemon/plugins/clipboard/list.c0000664000175000017500000000550415174102667020330 0ustar fengfeng/* * Copyright © 2004 Red Hat, Inc. * * Permission to use, copy, modify, distribute, and sell this software and its * documentation for any purpose is hereby granted without fee, provided that * the above copyright notice appear in all copies and that both that * copyright notice and this permission notice appear in supporting * documentation, and that the name of Red Hat not be used in advertising or * publicity pertaining to distribution of the software without specific, * written prior permission. Red Hat makes no representations about the * suitability of this software for any purpose. It is provided "as is" * without express or implied warranty. * * RED HAT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL RED HAT * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * * Author: Matthias Clasen, Red Hat, Inc. */ #include #include void list_foreach (List *list, Callback func, void *user_data) { while (list) { func (list->data, user_data); list = list->next; } } List * list_prepend (List *list, void *data) { List *link; link = (List *) malloc (sizeof (List)); link->next = list; link->data = data; return link; } void list_free (List *list) { while (list) { List *next = list->next; free (list); list = next; } } List * list_find (List *list, ListFindFunc func, void *user_data) { List *tmp; for (tmp = list; tmp; tmp = tmp->next) { if ((*func) (tmp->data, user_data)) break; } return tmp; } List * list_remove (List *list, void *data) { List *tmp, *prev; prev = NULL; for (tmp = list; tmp; tmp = tmp->next) { if (tmp->data == data) { if (prev) prev->next = tmp->next; else list = tmp->next; free (tmp); break; } prev = tmp; } return list; } int list_length (List *list) { List *tmp; int length; length = 0; for (tmp = list; tmp; tmp = tmp->next) length++; return length; } List * list_copy (List *list) { List *new_list = NULL; if (list) { List *last; new_list = (List *) malloc (sizeof (List)); new_list->data = list->data; new_list->next = NULL; last = new_list; list = list->next; while (list) { last->next = (List *) malloc (sizeof (List)); last = last->next; last->data = list->data; list = list->next; } last->next = NULL; } return new_list; } ukui-settings-daemon/plugins/clipboard/clipboard-manager.h0000664000175000017500000001306415174103014022714 0ustar fengfeng/* -*- Mode: C++; indent-tabs-mode: nil; tab-width: 4 -*- * -*- coding: utf-8 -*- * * Copyright (C) 2023 KylinSoft Co., Ltd. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef CLIPBOARDMANAGER_H #define CLIPBOARDMANAGER_H #include #include "list.h" #include #include #include #include #include /* always defined to indicate that i18n is enabled */ #define ENABLE_NLS 1 /* enable profiling */ /* #undef ENABLE_PROFILING */ /* Name of default gettext domain */ #define GETTEXT_PACKAGE "ukui-settings-daemon" /* Warn on use of APIs added after GLib 2.36 */ #define GLIB_VERSION_MAX_ALLOWED GLIB_VERSION_2_36 /* Warn on use of APIs deprecated before GLib 2.36 */ #define GLIB_VERSION_MIN_REQUIRED GLIB_VERSION_2_36 /* Define to 1 if you have the `bind_textdomain_codeset' function. */ #define HAVE_BIND_TEXTDOMAIN_CODESET 1 /* Define to 1 if you have the Mac OS X function CFLocaleCopyCurrent in the CoreFoundation framework. */ /* #undef HAVE_CFLOCALECOPYCURRENT */ /* Define to 1 if you have the Mac OS X function CFPreferencesCopyAppValue in the CoreFoundation framework. */ /* #undef HAVE_CFPREFERENCESCOPYAPPVALUE */ /* Define to 1 if you have the `dcgettext' function. */ #define HAVE_DCGETTEXT 1 /* Define to 1 if you have the header file. */ #define HAVE_DLFCN_H 1 /* Define if the GNU gettext() function is already present or preinstalled. */ #define HAVE_GETTEXT 1 /* Define to 1 if you have the header file. */ #define HAVE_INTTYPES_H 1 /* Define if your file defines LC_MESSAGES. */ #define HAVE_LC_MESSAGES 1 /* Define if libcanberra-gtk3 is available */ #define HAVE_LIBCANBERRA 1 /* Define if libmatemixer is available */ #define HAVE_LIBMATEMIXER 1 /* Define if libnotify is available */ #define HAVE_LIBNOTIFY 1 /* Define to 1 if you have the header file. */ #define HAVE_LOCALE_H 1 /* Define to 1 if you have the header file. */ #define HAVE_MEMORY_H 1 /* Defined if PolicyKit support is enabled */ #define HAVE_POLKIT 1 /* Define if PulseAudio support is available */ /* #undef HAVE_PULSE */ /* Define to 1 if you have the header file. */ #define HAVE_STDINT_H 1 /* Define to 1 if you have the header file. */ #define HAVE_STDLIB_H 1 /* Define to 1 if you have the header file. */ #define HAVE_STRINGS_H 1 /* Define to 1 if you have the header file. */ #define HAVE_STRING_H 1 /* Define to 1 if you have the header file. */ #define HAVE_SYS_STAT_H 1 /* Define to 1 if you have the header file. */ #define HAVE_SYS_TYPES_H 1 /* Define to 1 if you have the header file. */ #define HAVE_UNISTD_H 1 /* Define to 1 if you have the header file. */ /* #undef HAVE_X11_EXTENSIONS_XF86MISC_H */ /* Define to 1 if you have the header file. */ #define HAVE_X11_EXTENSIONS_XKB_H 1 typedef struct { int length; int format; int refcount; Atom target; Atom type; unsigned char* data; } TargetData; typedef struct { int offset; Atom target; Atom property; Window requestor; TargetData* data; } IncrConversion; class ClipboardManager : public QThread { Q_OBJECT public: explicit ClipboardManager(QObject *parent = nullptr); ~ClipboardManager(); bool managerStart (); bool managerStop (); void run() override; private: bool mExit; Display* mDisplay; Window mWindow; Time mTimestamp; List* mContents; List* mConversions; Window mRequestor; Atom mProperty; Time mTime; friend void get_property (TargetData* tdata, ClipboardManager* manager); friend bool send_incrementally (ClipboardManager* manager, XEvent* xev); friend bool receive_incrementally (ClipboardManager* manager, XEvent* xev); friend void send_selection_notify (ClipboardManager* manager, bool success); friend void convert_clipboard_manager (ClipboardManager* manager, XEvent* xev); friend void collect_incremental (IncrConversion* rdata, ClipboardManager* manager); friend bool clipboard_manager_process_event(ClipboardManager* manager, XEvent* xev); friend void save_targets (ClipboardManager* manager, Atom* save_targets, int nitems); friend void convert_clipboard_target (IncrConversion* rdata, ClipboardManager* manager); friend void finish_selection_request (ClipboardManager* manager, XEvent* xev, bool success); friend void clipboard_manager_watch_cb(ClipboardManager* manager, Window window, bool isStart, long mask, void* cbData); }; #endif // CLIPBOARDMANAGER_H ukui-settings-daemon/plugins/clipboard/clipboard-plugin.cpp0000664000175000017500000000402215174103014023125 0ustar fengfeng/* -*- Mode: C++; indent-tabs-mode: nil; tab-width: 4 -*- * -*- coding: utf-8 -*- * * Copyright (C) 2023 KylinSoft Co., Ltd. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include "usd_base_class.h" #include "clipboard-plugin.h" #include "clib-syslog.h" PluginInterface* ClipboardPlugin::mInstance = nullptr; ClipboardPlugin::~ClipboardPlugin() { if (mManager) { delete mManager; mManager = nullptr; } } PluginInterface *ClipboardPlugin::getInstance() { if (nullptr == mInstance) { mInstance = new ClipboardPlugin(); } return mInstance; } void ClipboardPlugin::activate() { if (nullptr != mManager){ mManager->managerStart(); USD_LOG (LOG_DEBUG, "Activating %s plugin compilation time:[%s] [%s]",MODULE_NAME,__DATE__,__TIME__); } else { USD_LOG (LOG_DEBUG, "Unactivating %s plugin compilation time:[%s] [%s]",MODULE_NAME,__DATE__,__TIME__); } } void ClipboardPlugin::deactivate() { if (nullptr != mManager) mManager->managerStop(); if (nullptr != mInstance) { delete mInstance; mInstance = nullptr; } } ClipboardPlugin::ClipboardPlugin() { if (UsdBaseClass::isXcb()) { if ((nullptr == mManager)) { mManager = new ClipboardManager(); } } else { USD_LOG(LOG_DEBUG, "not start clipboard plugin on wayland"); } } PluginInterface* createSettingsPlugin() { return ClipboardPlugin::getInstance(); } ukui-settings-daemon/plugins/clipboard/xutils.c0000664000175000017500000000675615174102667020717 0ustar fengfeng/* * Copyright © 2004 Red Hat, Inc. * * Permission to use, copy, modify, distribute, and sell this software and its * documentation for any purpose is hereby granted without fee, provided that * the above copyright notice appear in all copies and that both that * copyright notice and this permission notice appear in supporting * documentation, and that the name of Red Hat not be used in advertising or * publicity pertaining to distribution of the software without specific, * written prior permission. Red Hat makes no representations about the * suitability of this software for any purpose. It is provided "as is" * without express or implied warranty. * * RED HAT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL RED HAT * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * * Author: Matthias Clasen, Red Hat, Inc. */ #include #include "xutils.h" Atom XA_ATOM_PAIR; Atom XA_CLIPBOARD_MANAGER; Atom XA_CLIPBOARD; Atom XA_DELETE; Atom XA_INCR; Atom XA_INSERT_PROPERTY; Atom XA_INSERT_SELECTION; Atom XA_MANAGER; Atom XA_MULTIPLE; Atom XA_NULL; Atom XA_SAVE_TARGETS; Atom XA_TARGETS; Atom XA_TIMESTAMP; unsigned long SELECTION_MAX_SIZE = 0; void init_atoms (Display *display) { unsigned long max_request_size; if (SELECTION_MAX_SIZE > 0) return; XA_ATOM_PAIR = XInternAtom (display, "ATOM_PAIR", False); XA_CLIPBOARD_MANAGER = XInternAtom (display, "CLIPBOARD_MANAGER", False); XA_CLIPBOARD = XInternAtom (display, "CLIPBOARD", False); XA_DELETE = XInternAtom (display, "DELETE", False); XA_INCR = XInternAtom (display, "INCR", False); XA_INSERT_PROPERTY = XInternAtom (display, "INSERT_PROPERTY", False); XA_INSERT_SELECTION = XInternAtom (display, "INSERT_SELECTION", False); XA_MANAGER = XInternAtom (display, "MANAGER", False); XA_MULTIPLE = XInternAtom (display, "MULTIPLE", False); XA_NULL = XInternAtom (display, "NULL", False); XA_SAVE_TARGETS = XInternAtom (display, "SAVE_TARGETS", False); XA_TARGETS = XInternAtom (display, "TARGETS", False); XA_TIMESTAMP = XInternAtom (display, "TIMESTAMP", False); max_request_size = XExtendedMaxRequestSize (display); if (max_request_size == 0) max_request_size = XMaxRequestSize (display); SELECTION_MAX_SIZE = max_request_size - 100; if (SELECTION_MAX_SIZE > 262144) SELECTION_MAX_SIZE = 262144; } typedef struct { Window window; Atom timestamp_prop_atom; } TimeStampInfo; static Bool timestamp_predicate (Display *display, XEvent *xevent, XPointer arg) { TimeStampInfo *info = (TimeStampInfo *)arg; if (xevent->type == PropertyNotify && xevent->xproperty.window == info->window && xevent->xproperty.atom == info->timestamp_prop_atom) return True; return False; } Time get_server_time (Display *display, Window window) { unsigned char c = 'a'; XEvent xevent; TimeStampInfo info; info.timestamp_prop_atom = XInternAtom (display, "_TIMESTAMP_PROP", False); info.window = window; XChangeProperty (display, window, info.timestamp_prop_atom, info.timestamp_prop_atom, 8, PropModeReplace, &c, 1); XIfEvent (display, &xevent, timestamp_predicate, (XPointer)&info); return xevent.xproperty.time; } ukui-settings-daemon/plugins/clipboard/main.cpp0000664000175000017500000000243215174102667020636 0ustar fengfeng/* * Copyright © 2004 Red Hat, Inc. * * Permission to use, copy, modify, distribute, and sell this software and its * documentation for any purpose is hereby granted without fee, provided that * the above copyright notice appear in all copies and that both that * copyright notice and this permission notice appear in supporting * documentation, and that the name of Red Hat not be used in advertising or * publicity pertaining to distribution of the software without specific, * written prior permission. Red Hat makes no representations about the * suitability of this software for any purpose. It is provided "as is" * without express or implied warranty. * * RED HAT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL RED HAT * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * * Author: Matthias Clasen, Red Hat, Inc. */ #include int main(int argc, char *argv[]) { QCoreApplication a(argc, argv); return a.exec(); } ukui-settings-daemon/plugins/clipboard/clipboard.pro0000664000175000017500000000140015174103014021644 0ustar fengfeng#------------------------------------------------- # # Project created by QtCreator 2020-04-10T09:30:00 # #------------------------------------------------- TEMPLATE = lib TARGET = clipboard QT += gui CONFIG += no_keywords c++20 plugin link_pkgconfig CONFIG -= app_bundle DEFINES += QT_DEPRECATED_WARNINGS MODULE_NAME=\\\"clipboard\\\" include($$PWD/../../common/common.pri) PKGCONFIG += \ gdk-3.0 SOURCES += \ $$PWD/list.c \ $$PWD/xutils.c \ $$PWD/clipboard-plugin.cpp \ $$PWD/clipboard-manager.cpp \ HEADERS += \ $$PWD/list.h \ $$PWD/xutils.h \ $$PWD/clipboard-plugin.h \ $$PWD/clipboard-manager.h clipboard_lib.path = $${PLUGIN_INSTALL_DIRS} clipboard_lib.files = $$OUT_PWD/libclipboard.so INSTALLS += clipboard_lib ukui-settings-daemon/plugins/kds/0000775000175000017500000000000015174103014016012 5ustar fengfengukui-settings-daemon/plugins/kds/translations/0000775000175000017500000000000015174102667020550 5ustar fengfengukui-settings-daemon/plugins/kds/translations/es.ts0000664000175000017500000000564015174102667021534 0ustar fengfeng KDSWidget System Screen Projection Proyección de pantalla del sistema FirstOutput: FirstOutput: First Display Primera pantalla Mirror Display Pantalla de espejo Extend Display Extender la pantalla Vice Display Pantalla de vicio N/A N/A Widget KDS KDS System Screen Projection Proyección de pantalla del sistema FirstOutput: FirstOutput: First Screen Primera pantalla Clone Screen Pantalla de clonación Extend Screen Extender pantalla Vice Screen Pantalla de vicio Network display Visualización en red None Ninguno ukui-settings-daemon/plugins/kds/translations/ug_CN.ts0000664000175000017500000000560115174102667022115 0ustar fengfeng KDSWidget System Screen Projection سىستېما ئېكرانى پرويېكسىيەسى FirstOutput: بىرىنچىOutput: First Display بىرىنچى كۆرسىتىش Mirror Display ئەينەك كۆرسىتىش Extend Display كۆرسىتىشنى ئۇزارتىش Vice Display مۇئاۋىن كۆرسىتىش N/A N/A Widget KDS KDS System Screen Projection سىستېما ئېكرانى پرويېكسىيەسى FirstOutput: بىرىنچىOutput: First Screen بىرىنچى ئېكران Clone Screen كىلون ئېكرانى Extend Screen ئېكراننى ئۇزارتىش Vice Screen مۇئاۋىن ئېكران None يوق ukui-settings-daemon/plugins/kds/translations/zh_CN.ts0000664000175000017500000000552715174102667022132 0ustar fengfeng KDSWidget System Screen Projection 系统投屏 FirstOutput: 第一屏幕: First Display 仅显示电脑屏幕 Mirror Display 镜像 Extend Display 扩展 Vice Display 仅显示第二屏幕 N/A N/A Widget KDS 系统投屏 System Screen Projection 系统投屏 FirstOutput: 第一屏幕: First Screen 仅显示电脑屏幕 Clone Screen 镜像 Extend Screen 扩展 Vice Screen 仅显示第二屏幕 Network display 网络显示器 None ukui-settings-daemon/plugins/kds/translations/kk_KZ.ts0000664000175000017500000000550715174102667022140 0ustar fengfeng KDSWidget System Screen Projection Жүйелік экран проекциясы FirstOutput: FirstOutput: First Display Бірінші дисплей Mirror Display Айна дисплейі Extend Display Дисплейді кеңейту Vice Display Вице-дисплей N/A N/A Widget KDS KDS System Screen Projection Жүйелік экран проекциясы FirstOutput: FirstOutput: First Screen Бірінші экран Clone Screen Клон экраны Extend Screen Экранды кеңейту Vice Screen Вице-экран None Ешқайсысы ukui-settings-daemon/plugins/kds/translations/bo_CN.ts0000664000175000017500000000704115174102667022102 0ustar fengfeng KDSWidget System Screen Projection མ་ལག་གི་བརྙན་ཤེལ་རྣམ་གྲངས FirstOutput: ཐོག་མར་ཕུའུ་ཐའོ་ཡིས་བཤད་རྒྱུར། First Display ཐོག་མར་འགྲེམས་སྟོན་ Mirror Display མེ་ལོང་འགྲེམས་སྟོན། Extend Display ཁྱབ་གདལ་གཏོང་བའི་འགྲེམས་ Vice Display འགྲེམས་སྟོན་གཞོན་པ། N/A N/A Widget KDS KDS System Screen Projection མ་ལག་གི་བརྙན་ཤེལ་རྣམ་གྲངས FirstOutput: ཐོག་མར་ཕུའུ་ཐའོ་ཡིས་བཤད་རྒྱུར། First Screen བརྙན་ཤེལ་དང་པོ། Clone Screen ཁུ་ལོན་གྱི་བརྙན་ཤེལ། Extend Screen བརྙན་ཤེལ་རིང་དུ་གཏོང་ Vice Screen བརྙན་ཤེལ་གཞོན་པ། Network display དྲ་རྒྱ་འི་བརྡ་སྟོན་ཡོ་ཆས། None གཅིག་ཀྱང་མེད། ukui-settings-daemon/plugins/kds/translations/mn.ts0000664000175000017500000000314115174102667021531 0ustar fengfeng Widget KDS ᠰᠢᠰᠲ᠋ᠧᠮ ᠢ᠋ ᠳᠡᠯᠭᠡᠴᠡᠨ ᠳ᠋ᠤ᠌ ᠭᠠᠷᠭᠠᠬᠤ System Screen Projection ᠰᠢᠰᠲ᠋ᠧᠮ ᠢ᠋ ᠳᠡᠯᠭᠡᠴᠡᠨ ᠳ᠋ᠤ᠌ ᠭᠠᠷᠭᠠᠬᠤ FirstOutput: ᠨᠢᠭᠡᠳᠦᠭᠡᠷ ᠳᠡᠯᠭᠡᠴᠡ: None ᠪᠠᠢᠬᠤ ᠦᠬᠡᠢ Clone Screen ᠳᠤᠯᠢᠳᠠᠰᠤ Extend Screen ᠦᠷᠬᠡᠳᠬᠡᠬᠦ Network display ᠤᠳᠠᠰᠤ ᠦᠬᠡᠢ ᠦᠵᠡᠬᠦᠷ ᠲᠤ᠌ ᠴᠦᠷᠬᠡᠯᠡᠬᠦ ukui-settings-daemon/plugins/kds/translations/de.ts0000664000175000017500000000557515174102667021524 0ustar fengfeng KDSWidget System Screen Projection System-Leinwandprojektion FirstOutput: FirstOutput: First Display Erste Anzeige Mirror Display Spiegel-Display Extend Display Anzeige erweitern Vice Display Schraubstock-Anzeige N/A N/A Widget KDS KDS System Screen Projection System-Leinwandprojektion FirstOutput: FirstOutput: First Screen Erster Bildschirm Clone Screen Bildschirm klonen Extend Screen Bildschirm erweitern Vice Screen Vice-Bildschirm Network display Netzwerk-Anzeige None Nichts ukui-settings-daemon/plugins/kds/translations/fr.ts0000664000175000017500000000571115174102667021533 0ustar fengfeng KDSWidget System Screen Projection Projection d’écran du système FirstOutput: Sortie de première page : First Display Premier affichage Mirror Display Affichage miroir Extend Display Étendre l’affichage Vice Display Affichage de l’étau N/A N/A Widget KDS KDS (en anglais seulement) System Screen Projection Projection d’écran du système FirstOutput: Sortie de première page : First Screen Premier écran Clone Screen Cloner l’écran Extend Screen Étendre l’écran Vice Screen Écran d’étau Network display Affichage réseau None Aucun ukui-settings-daemon/plugins/kds/translations/zh_HK.ts0000664000175000017500000000553115174102667022127 0ustar fengfeng KDSWidget System Screen Projection 系統投屏 FirstOutput: 第一螢幕: First Display 僅顯示電腦螢幕 Mirror Display 鏡像 Extend Display 擴展 Vice Display 僅顯示第二螢幕 N/A N/A Widget KDS 系統投屏 System Screen Projection 系統投屏 FirstOutput: 第一螢幕: First Screen 僅顯示電腦螢幕 Clone Screen 鏡像 Extend Screen 擴展 Vice Screen 僅顯示第二螢幕 Network display 網路顯示器 None ukui-settings-daemon/plugins/kds/translations/ky_KG.ts0000664000175000017500000000551615174102667022133 0ustar fengfeng KDSWidget System Screen Projection Система экран проекциясы FirstOutput: FirstOutput: First Display Биринчи дисплей Mirror Display Күзгү дисплейи Extend Display Дисплейди кеңейтүү Vice Display Вице-дисплей N/A N/A Widget KDS Комплект System Screen Projection Система экран проекциясы FirstOutput: FirstOutput: First Screen Биринчи экран Clone Screen Клон экраны Extend Screen Экранды кеңейтүү Vice Screen Вице-экран None Жок ukui-settings-daemon/plugins/kds/screen_switch.cpp0000664000175000017500000000534515174102667021402 0ustar fengfeng/* -*- Mode: C++; indent-tabs-mode: nil; tab-width: 4 -*- * -*- coding: utf-8 -*- * * Copyright (C) 2023 KylinSoft Co., Ltd. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include "screen_switch.h" #include #include #include #include #include "usd_global_define.h" #include "clib-syslog.h" Q_GLOBAL_STATIC(ScreenSwitch, s_screenSwitch) ScreenSwitch::ScreenSwitch(QObject *parent) : QObject(parent) { m_xrandrInterface = new QDBusInterface(DBUS_XRANDR_NAME, DBUS_XRANDR_PATH, DBUS_XRANDR_INTERFACE, QDBusConnection::sessionBus(), this); if (m_xrandrInterface->isValid()) { connect(m_xrandrInterface, SIGNAL(screensParamChanged(QString)), this, SIGNAL(sigScreenParamChanged(QString))); } } ScreenSwitch *ScreenSwitch::instance() { return s_screenSwitch; } QStringList ScreenSwitch::getScreenList() { if (m_xrandrInterface) { QDBusReply replay = m_xrandrInterface->call(DBUS_XRANDR_GET_SCREEN_PARAM, qAppName()); if (replay.isValid()) { QStringList screenList; QJsonDocument parser; QVariantList screens = parser.fromJson(replay.value().toUtf8().data()).toVariant().toList(); for (const auto& screenInfo : screens) { const QString& outputName = ((screenInfo.toMap())[("metadata")].toMap())["name"].toString(); screenList << outputName; } return screenList; } } return QStringList(); } int ScreenSwitch::getScreenMode() { if (m_xrandrInterface) { QDBusReply replay = m_xrandrInterface->call(DBUS_XRANDR_GET_MODE, qAppName()); if (replay.isValid()) { return replay.value(); } } return 0; } void ScreenSwitch::setScreenMode(const QString& mode) { if (m_xrandrInterface) { USD_LOG(LOG_DEBUG, "set screen %s", mode.toLatin1().data()); m_xrandrInterface->asyncCall(DBUS_XRANDR_SET_MODE , mode, qAppName()); } } ukui-settings-daemon/plugins/kds/widget.ui0000664000175000017500000000057315174102667017656 0ustar fengfeng Widget 0 0 384 600 Widget ukui-settings-daemon/plugins/kds/button.cpp0000664000175000017500000000637515174102667020061 0ustar fengfeng/* -*- Mode: C++; indent-tabs-mode: nil; tab-width: 4 -*- * -*- coding: utf-8 -*- * * Copyright (C) 2023 KylinSoft Co., Ltd. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include "button.h" #include "style_helper.h" #include Button::Button(const QString &text, const QString &img, QWidget *parent) : QPushButton(parent) , m_text(text) , m_modeImage(img) , m_mode(-1) { setFocusPolicy(Qt::NoFocus); initButtonUi(); } void Button::setText(const QString &text) { m_text = text; if (m_textLabel) { m_textLabel->setText(text); m_textLabel->adjustSize(); } } void Button::setStatus(bool state) { m_statusLabel->setVisible(state); } void Button::setMode(int mode) { m_mode = mode; } int Button::getMode() { return m_mode; } QPixmap Button::drawPixmap(const QPixmap &source) { QColor baseColor = this->palette().brightText().color(); QImage img = source.toImage(); for (int x = 0; x < img.width(); x++) { for (int y = 0; y < img.height(); y++) { auto color = img.pixelColor(x, y); if (color.alpha() > 0) { color.setRed(baseColor.red()); color.setGreen(baseColor.green()); color.setBlue(baseColor.blue()); } img.setPixelColor(x, y, color); } } return QPixmap::fromImage(img); } void Button::setModeImage(const QString &modeImage) { m_modeImage = modeImage; if (m_imageLabel) { m_imageLabel->setPixmap(drawPixmap(QPixmap(m_modeImage)).scaled(60, 33, Qt::KeepAspectRatioByExpanding, Qt::SmoothTransformation)); m_imageLabel->adjustSize(); } } void Button::initButtonUi() { m_mainLayout = new QHBoxLayout(this); m_mainLayout->setAlignment(Qt::AlignVCenter); m_mainLayout->setContentsMargins(24, 0, 27, 0); m_imageLabel = new QLabel(this); m_imageLabel->setFixedSize(60, 40); m_imageLabel->setPixmap(drawPixmap(QPixmap(m_modeImage)).scaled(60, 33, Qt::KeepAspectRatioByExpanding, Qt::SmoothTransformation)); m_imageLabel->adjustSize(); m_textLabel = new QLabel(this); m_textLabel->setAlignment(Qt::AlignLeft | Qt::AlignVCenter); m_textLabel->setText(m_text); m_textLabel->adjustSize(); //选中状态 m_statusLabel = new QLabel(this); m_statusLabel->setFixedSize(17, 12); m_statusLabel->setPixmap(drawPixmap(QPixmap(":/img/selected.png"))); m_statusLabel->setScaledContents(true); m_statusLabel->setVisible(false); //控件布局 m_mainLayout->addWidget(m_imageLabel); m_mainLayout->addSpacing(16); m_mainLayout->addWidget(m_textLabel); m_mainLayout->addStretch(); m_mainLayout->addWidget(m_statusLabel); } ukui-settings-daemon/plugins/kds/qtlockedfile/0000775000175000017500000000000015174102667020475 5ustar fengfengukui-settings-daemon/plugins/kds/qtlockedfile/qtlockedfile_win.cpp0000664000175000017500000001403315174102667024525 0ustar fengfeng/**************************************************************************** ** ** Copyright (C) 2016 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of Qt Creator. ** ** Commercial License Usage ** Licensees holding valid commercial Qt licenses may use this file in ** accordance with the commercial license agreement provided with the ** Software or, alternatively, in accordance with the terms contained in ** a written agreement between you and The Qt Company. For licensing terms ** and conditions see https://www.qt.io/terms-conditions. For further ** information use the contact form at https://www.qt.io/contact-us. ** ** GNU General Public License Usage ** Alternatively, this file may be used under the terms of the GNU ** General Public License version 3 as published by the Free Software ** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT ** included in the packaging of this file. Please review the following ** information to ensure the GNU General Public License requirements will ** be met: https://www.gnu.org/licenses/gpl-3.0.html. ** ****************************************************************************/ #include "qtlockedfile.h" #include #include //namespace SharedTools { #define SEMAPHORE_PREFIX "QtLockedFile semaphore " #define MUTEX_PREFIX "QtLockedFile mutex " #define SEMAPHORE_MAX 100 static QString errorCodeToString(DWORD errorCode) { QString result; char *data = 0; FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, 0, errorCode, 0, (char*)&data, 0, 0); result = QString::fromLocal8Bit(data); if (data != 0) LocalFree(data); if (result.endsWith(QLatin1Char('\n'))) result.truncate(result.length() - 1); return result; } bool QtLockedFile::lock(LockMode mode, bool block) { if (!isOpen()) { qWarning("QtLockedFile::lock(): file is not opened"); return false; } if (mode == m_lock_mode) return true; if (m_lock_mode != 0) unlock(); if (m_semaphore_hnd == 0) { QFileInfo fi(*this); QString sem_name = QString::fromLatin1(SEMAPHORE_PREFIX) + fi.absoluteFilePath().toLower(); m_semaphore_hnd = CreateSemaphoreW(0, SEMAPHORE_MAX, SEMAPHORE_MAX, (TCHAR*)sem_name.utf16()); if (m_semaphore_hnd == 0) { qWarning("QtLockedFile::lock(): CreateSemaphore: %s", errorCodeToString(GetLastError()).toLatin1().constData()); return false; } } bool gotMutex = false; int decrement; if (mode == ReadLock) { decrement = 1; } else { decrement = SEMAPHORE_MAX; if (m_mutex_hnd == 0) { QFileInfo fi(*this); QString mut_name = QString::fromLatin1(MUTEX_PREFIX) + fi.absoluteFilePath().toLower(); m_mutex_hnd = CreateMutexW(NULL, FALSE, (TCHAR*)mut_name.utf16()); if (m_mutex_hnd == 0) { qWarning("QtLockedFile::lock(): CreateMutex: %s", errorCodeToString(GetLastError()).toLatin1().constData()); return false; } } DWORD res = WaitForSingleObject(m_mutex_hnd, block ? INFINITE : 0); if (res == WAIT_TIMEOUT) return false; if (res == WAIT_FAILED) { qWarning("QtLockedFile::lock(): WaitForSingleObject (mutex): %s", errorCodeToString(GetLastError()).toLatin1().constData()); return false; } gotMutex = true; } for (int i = 0; i < decrement; ++i) { DWORD res = WaitForSingleObject(m_semaphore_hnd, block ? INFINITE : 0); if (res == WAIT_TIMEOUT) { if (i) { // A failed nonblocking rw locking. Undo changes to semaphore. if (ReleaseSemaphore(m_semaphore_hnd, i, NULL) == 0) { qWarning("QtLockedFile::unlock(): ReleaseSemaphore: %s", errorCodeToString(GetLastError()).toLatin1().constData()); // Fall through } } if (gotMutex) ReleaseMutex(m_mutex_hnd); return false; } if (res != WAIT_OBJECT_0) { if (gotMutex) ReleaseMutex(m_mutex_hnd); qWarning("QtLockedFile::lock(): WaitForSingleObject (semaphore): %s", errorCodeToString(GetLastError()).toLatin1().constData()); return false; } } m_lock_mode = mode; if (gotMutex) ReleaseMutex(m_mutex_hnd); return true; } bool QtLockedFile::unlock() { if (!isOpen()) { qWarning("QtLockedFile::unlock(): file is not opened"); return false; } if (!isLocked()) return true; int increment; if (m_lock_mode == ReadLock) increment = 1; else increment = SEMAPHORE_MAX; DWORD ret = ReleaseSemaphore(m_semaphore_hnd, increment, 0); if (ret == 0) { qWarning("QtLockedFile::unlock(): ReleaseSemaphore: %s", errorCodeToString(GetLastError()).toLatin1().constData()); return false; } m_lock_mode = QtLockedFile::NoLock; remove(); return true; } QtLockedFile::~QtLockedFile() { if (isOpen()) unlock(); if (m_mutex_hnd != 0) { DWORD ret = CloseHandle(m_mutex_hnd); if (ret == 0) { qWarning("QtLockedFile::~QtLockedFile(): CloseHandle (mutex): %s", errorCodeToString(GetLastError()).toLatin1().constData()); } m_mutex_hnd = 0; } if (m_semaphore_hnd != 0) { DWORD ret = CloseHandle(m_semaphore_hnd); if (ret == 0) { qWarning("QtLockedFile::~QtLockedFile(): CloseHandle (semaphore): %s", errorCodeToString(GetLastError()).toLatin1().constData()); } m_semaphore_hnd = 0; } } //} // namespace SharedTools ukui-settings-daemon/plugins/kds/qtlockedfile/qtlockedfile.h0000664000175000017500000000427615174102667023325 0ustar fengfeng/**************************************************************************** ** ** Copyright (C) 2016 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of Qt Creator. ** ** Commercial License Usage ** Licensees holding valid commercial Qt licenses may use this file in ** accordance with the commercial license agreement provided with the ** Software or, alternatively, in accordance with the terms contained in ** a written agreement between you and The Qt Company. For licensing terms ** and conditions see https://www.qt.io/terms-conditions. For further ** information use the contact form at https://www.qt.io/contact-us. ** ** GNU General Public License Usage ** Alternatively, this file may be used under the terms of the GNU ** General Public License version 3 as published by the Free Software ** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT ** included in the packaging of this file. Please review the following ** information to ensure the GNU General Public License requirements will ** be met: https://www.gnu.org/licenses/gpl-3.0.html. ** ****************************************************************************/ #pragma once #include #if defined(Q_OS_WIN) # if !defined(QT_QTLOCKEDFILE_EXPORT) && !defined(QT_QTLOCKEDFILE_IMPORT) # define QT_QTLOCKEDFILE_EXPORT # elif defined(QT_QTLOCKEDFILE_IMPORT) # if defined(QT_QTLOCKEDFILE_EXPORT) # undef QT_QTLOCKEDFILE_EXPORT # endif # define QT_QTLOCKEDFILE_EXPORT __declspec(dllimport) # elif defined(QT_QTLOCKEDFILE_EXPORT) # undef QT_QTLOCKEDFILE_EXPORT # define QT_QTLOCKEDFILE_EXPORT __declspec(dllexport) # endif #else # define QT_QTLOCKEDFILE_EXPORT #endif //namespace SharedTools { class QT_QTLOCKEDFILE_EXPORT QtLockedFile : public QFile { public: enum LockMode { NoLock = 0, ReadLock, WriteLock }; QtLockedFile(); QtLockedFile(const QString &name); ~QtLockedFile(); bool lock(LockMode mode, bool block = true); bool unlock(); bool isLocked() const; LockMode lockMode() const; private: #ifdef Q_OS_WIN Qt::HANDLE m_semaphore_hnd; Qt::HANDLE m_mutex_hnd; #endif LockMode m_lock_mode; }; //} // namespace SharedTools ukui-settings-daemon/plugins/kds/qtlockedfile/namespace.patch0000664000175000017500000000246215174102667023456 0ustar fengfeng --- qtlockedfile.cpp 1970-01-01 01:00:00.000000000 +++ qtlockedfile.cpp 2008/05/16 10:51:19.000000000 @@ -1,5 +1,7 @@ #include "qtlockedfile.h" +namespace SharedTools { + /*! \class QtLockedFile @@ -123,3 +125,5 @@ Destroys the \e QtLockedFile object. If any locks were held, they are released. */ + +} --- qtlockedfile.h 1970-01-01 01:00:00.000000000 +++ qtlockedfile.h 2008/05/16 10:51:19.000000000 @@ -19,6 +19,8 @@ # define QT_QTLOCKEDFILE_EXPORT #endif +namespace SharedTools { + class QT_QTLOCKEDFILE_EXPORT QtLockedFile : public QFile { public: @@ -41,4 +43,6 @@ LockMode m_lock_mode; }; +} + #endif --- qtlockedfile_unix.cpp 1970-01-01 01:00:00.000000000 +++ qtlockedfile_unix.cpp 2008/05/16 10:51:19.000000000 @@ -5,6 +5,8 @@ #include "qtlockedfile.h" +namespace SharedTools { + bool QtLockedFile::lock(LockMode mode, bool block) { if (!isOpen()) { @@ -73,3 +75,4 @@ unlock(); } +} --- qtlockedfile_win.cpp 1970-01-01 01:00:00.000000000 +++ qtlockedfile_win.cpp 2008/05/16 10:51:19.000000000 @@ -2,6 +2,8 @@ #include #include +namespace SharedTools { + #define SEMAPHORE_PREFIX "QtLockedFile semaphore " #define MUTEX_PREFIX "QtLockedFile mutex " #define SEMAPHORE_MAX 100 @@ -168,3 +170,4 @@ } } +} ukui-settings-daemon/plugins/kds/qtlockedfile/qtlockedfile.pri0000664000175000017500000000047615174102667023666 0ustar fengfengINCLUDEPATH += $$PWD DEPENDPATH += $$PWD HEADERS += $$PWD/qtlockedfile.h SOURCES += $$PWD/qtlockedfile.cpp unix:SOURCES += $$PWD/qtlockedfile_unix.cpp win32:SOURCES += $$PWD/qtlockedfile_win.cpp win32:contains(TEMPLATE, lib):contains(CONFIG, shared) { DEFINES += QT_QTLOCKEDFILE_EXPORT=__declspec(dllexport) } ukui-settings-daemon/plugins/kds/qtlockedfile/qtlockedfile.cpp0000664000175000017500000001110715174102667023647 0ustar fengfeng/**************************************************************************** ** ** Copyright (C) 2016 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of Qt Creator. ** ** Commercial License Usage ** Licensees holding valid commercial Qt licenses may use this file in ** accordance with the commercial license agreement provided with the ** Software or, alternatively, in accordance with the terms contained in ** a written agreement between you and The Qt Company. For licensing terms ** and conditions see https://www.qt.io/terms-conditions. For further ** information use the contact form at https://www.qt.io/contact-us. ** ** GNU General Public License Usage ** Alternatively, this file may be used under the terms of the GNU ** General Public License version 3 as published by the Free Software ** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT ** included in the packaging of this file. Please review the following ** information to ensure the GNU General Public License requirements will ** be met: https://www.gnu.org/licenses/gpl-3.0.html. ** ****************************************************************************/ #include "qtlockedfile.h" //namespace SharedTools { /*! \class QtLockedFile \brief The QtLockedFile class extends QFile with advisory locking functions. A file may be locked in read or write mode. Multiple instances of \e QtLockedFile, created in multiple processes running on the same machine, may have a file locked in read mode. Exactly one instance may have it locked in write mode. A read and a write lock cannot exist simultaneously on the same file. The file locks are advisory. This means that nothing prevents another process from manipulating a locked file using QFile or file system functions offered by the OS. Serialization is only guaranteed if all processes that access the file use QtLockedFile. Also, while holding a lock on a file, a process must not open the same file again (through any API), or locks can be unexpectedly lost. The lock provided by an instance of \e QtLockedFile is released whenever the program terminates. This is true even when the program crashes and no destructors are called. */ /*! \enum QtLockedFile::LockMode This enum describes the available lock modes. \value ReadLock A read lock. \value WriteLock A write lock. \value NoLock Neither a read lock nor a write lock. */ /*! Constructs an unlocked \e QtLockedFile object. This constructor behaves in the same way as \e QFile::QFile(). \sa QFile::QFile() */ QtLockedFile::QtLockedFile() : QFile() { #ifdef Q_OS_WIN m_semaphore_hnd = 0; m_mutex_hnd = 0; #endif m_lock_mode = NoLock; } /*! Constructs an unlocked QtLockedFile object with file \a name. This constructor behaves in the same way as \e QFile::QFile(const QString&). \sa QFile::QFile() */ QtLockedFile::QtLockedFile(const QString &name) : QFile(name) { #ifdef Q_OS_WIN m_semaphore_hnd = 0; m_mutex_hnd = 0; #endif m_lock_mode = NoLock; } /*! Returns \e true if this object has a in read or write lock; otherwise returns \e false. \sa lockMode() */ bool QtLockedFile::isLocked() const { return m_lock_mode != NoLock; } /*! Returns the type of lock currently held by this object, or \e QtLockedFile::NoLock. \sa isLocked() */ QtLockedFile::LockMode QtLockedFile::lockMode() const { return m_lock_mode; } /*! \fn bool QtLockedFile::lock(LockMode mode, bool block = true) Obtains a lock of type \a mode. If \a block is true, this function will block until the lock is acquired. If \a block is false, this function returns \e false immediately if the lock cannot be acquired. If this object already has a lock of type \a mode, this function returns \e true immediately. If this object has a lock of a different type than \a mode, the lock is first released and then a new lock is obtained. This function returns \e true if, after it executes, the file is locked by this object, and \e false otherwise. \sa unlock(), isLocked(), lockMode() */ /*! \fn bool QtLockedFile::unlock() Releases a lock. If the object has no lock, this function returns immediately. This function returns \e true if, after it executes, the file is not locked by this object, and \e false otherwise. \sa lock(), isLocked(), lockMode() */ /*! \fn QtLockedFile::~QtLockedFile() Destroys the \e QtLockedFile object. If any locks were held, they are released. */ //} // namespace SharedTools ukui-settings-daemon/plugins/kds/qtlockedfile/README.txt0000664000175000017500000000041515174102667022173 0ustar fengfengThis is the src directory of the QtLockedFile solution integrated over from addons/main/utils/qtlockedfile/src . namespace.patch was applied to introduce the SharedTools namespace. It is required by the QtSingleApplication solution. History: 16.05.2008 Integrated ukui-settings-daemon/plugins/kds/qtlockedfile/qtlockedfile_unix.cpp0000664000175000017500000000523115174102667024713 0ustar fengfeng/**************************************************************************** ** ** Copyright (C) 2016 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of Qt Creator. ** ** Commercial License Usage ** Licensees holding valid commercial Qt licenses may use this file in ** accordance with the commercial license agreement provided with the ** Software or, alternatively, in accordance with the terms contained in ** a written agreement between you and The Qt Company. For licensing terms ** and conditions see https://www.qt.io/terms-conditions. For further ** information use the contact form at https://www.qt.io/contact-us. ** ** GNU General Public License Usage ** Alternatively, this file may be used under the terms of the GNU ** General Public License version 3 as published by the Free Software ** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT ** included in the packaging of this file. Please review the following ** information to ensure the GNU General Public License requirements will ** be met: https://www.gnu.org/licenses/gpl-3.0.html. ** ****************************************************************************/ #include "qtlockedfile.h" #include #include #include #include //namespace SharedTools { bool QtLockedFile::lock(LockMode mode, bool block) { if (!isOpen()) { qWarning("QtLockedFile::lock(): file is not opened"); return false; } if (mode == NoLock) return unlock(); if (mode == m_lock_mode) return true; if (m_lock_mode != NoLock) unlock(); struct flock fl; fl.l_whence = SEEK_SET; fl.l_start = 0; fl.l_len = 0; fl.l_type = (mode == ReadLock) ? F_RDLCK : F_WRLCK; int cmd = block ? F_SETLKW : F_SETLK; int ret = fcntl(handle(), cmd, &fl); if (ret == -1) { if (errno != EINTR && errno != EAGAIN) qWarning("QtLockedFile::lock(): fcntl: %s", strerror(errno)); return false; } m_lock_mode = mode; return true; } bool QtLockedFile::unlock() { if (!isOpen()) { qWarning("QtLockedFile::unlock(): file is not opened"); return false; } if (!isLocked()) return true; struct flock fl; fl.l_whence = SEEK_SET; fl.l_start = 0; fl.l_len = 0; fl.l_type = F_UNLCK; int ret = fcntl(handle(), F_SETLKW, &fl); if (ret == -1) { qWarning("QtLockedFile::lock(): fcntl: %s", strerror(errno)); return false; } m_lock_mode = NoLock; remove(); return true; } QtLockedFile::~QtLockedFile() { if (isOpen()) unlock(); } //} // namespace SharedTools ukui-settings-daemon/plugins/kds/style_helper.cpp0000664000175000017500000001063615174102667021240 0ustar fengfeng/* -*- Mode: C++; indent-tabs-mode: nil; tab-width: 4 -*- * -*- coding: utf-8 -*- * * Copyright (C) 2023 KylinSoft Co., Ltd. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include "style_helper.h" #include #include #include #include "usd_base_class.h" #include "usd_global_define.h" #define UKUI_STYLE "org.ukui.style" const static QString s_styleName = "style-name"; const static QString s_fontSize = "system-font-size"; #define UKUI_CONTROL_CENTER_PERSONALISE "org.ukui.control-center.personalise" const static QString s_opacity = "transparency"; Q_GLOBAL_STATIC(StyleHelper, s_styleHelper) StyleHelper::StyleHelper(QObject *parent) : QObject(parent) , m_opacity(0.75) , m_fontSize(11) , m_isLightStyle(false) , m_isTabletMode(false) { initStyleSettings(); initCurrentMode(); } StyleHelper *StyleHelper::instance() { return s_styleHelper; } void StyleHelper::initStyleSettings() { QByteArray styleSchemaId(UKUI_STYLE); if (QGSettings::isSchemaInstalled(styleSchemaId)) { m_styleSettings = new QGSettings(styleSchemaId, "", this); // connect(m_styleSettings, &QGSettings::changed, this, &StyleHelper::slotSettingsChanged); if (m_styleSettings->keys().contains(s_styleName)) { m_isLightStyle = (m_styleSettings->get(s_styleName).toString() != QStringLiteral("ukui-dark")); } if (m_styleSettings->keys().contains(s_fontSize)) { m_fontSize = m_styleSettings->get(s_fontSize).toReal(); } } QByteArray opacityId(UKUI_CONTROL_CENTER_PERSONALISE); if (QGSettings::isSchemaInstalled(opacityId)) { m_opacitySettings = new QGSettings(opacityId, "", this); // connect(m_opacitySettings, &QGSettings::changed, this, &StyleHelper::slotSettingsChanged); if (m_opacitySettings->keys().contains(s_opacity)) { m_opacity = m_opacitySettings->get(s_opacity).toReal(); } } } void StyleHelper::initCurrentMode() { if (UsdBaseClass::isTablet()) { QDBusMessage message = QDBusMessage::createMethodCall(DBUS_STATUSMANAGER_NAME, DBUS_STATUSMANAGER_PATH, DBUS_STATUSMANAGER_INTERFACE, DBUS_STATUSMANAGER_GET_MODE); QDBusMessage response = QDBusConnection::sessionBus().call(message); if (response.type() == QDBusMessage::ReplyMessage) { if(!response.arguments().isEmpty()) { m_isTabletMode = response.arguments().takeFirst().toBool(); } } } } QColor StyleHelper::getColor(QPalette::ColorRole role, QPalette::ColorGroup group) { QPalette palette = QApplication::palette(); QColor color; if (group == QPalette::Active) { switch (role) { case QPalette::Window: color = m_isLightStyle ? QColor("#FFFFFF") : QColor("#262626"); break; case QPalette::Button: color = QColor(Qt::transparent); break; case QPalette::WindowText: case QPalette::ButtonText: color = m_isLightStyle ? QColor("#262626") : QColor("#FFFFFF"); break; case QPalette::BrightText: color = palette.color(role); break; case QPalette::Highlight: color = m_isLightStyle ? QColor("#262626") : QColor("#FFFFFF"); color.setAlphaF(0.1); break; default: break; } } return color; } qreal StyleHelper::getOpacity() const { return m_opacity; } qreal StyleHelper::getFontSize() const { return m_fontSize; } bool StyleHelper::isLightStyle() const { return m_isLightStyle; } bool StyleHelper::isTabletMode() const { return m_isTabletMode; } ukui-settings-daemon/plugins/kds/widget.h0000664000175000017500000000422215174103014017446 0ustar fengfeng/* -*- Mode: C++; indent-tabs-mode: nil; tab-width: 4 -*- * -*- coding: utf-8 -*- * * Copyright (C) 2023 KylinSoft Co., Ltd. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef WIDGET_H #define WIDGET_H #include #include #include #include #include "button.h" QT_BEGIN_NAMESPACE namespace Ui { class Widget; } QT_END_NAMESPACE typedef std::function Action; class Widget : public QWidget { Q_OBJECT public: Widget(QWidget *parent = nullptr); ~Widget(); Button* createButton(const QString& text, const QString& img); void initTitleUi(); void initButtons(); void initLine(); void initBottom(); void initUi(); void initStyleSettings(); void setStyle(); protected: void keyPressEvent(QKeyEvent* event); void paintEvent(QPaintEvent *event); bool event(QEvent *event); private: void selectedLast(); void selectedNext(); void confirmCurrent(); void setWindowCenter(); void addShortcutAction(const QKeySequence& keys, Action action); void addShortcutActions(); public Q_SLOTS: void msgReceiveAnotherOne(); private: Ui::Widget *ui; QWidget* m_titleWidget = nullptr; QWidget* m_btnsWidget = nullptr; QWidget* m_bottomWidget = nullptr; QVBoxLayout* m_mainLayout = nullptr; QLabel* m_title = nullptr; QHBoxLayout* m_titleLayout = nullptr; QVBoxLayout* m_btnsLayout = nullptr; QHBoxLayout* m_bottomLayout = nullptr; QPushButton* m_networkDisplay = nullptr; QButtonGroup* m_buttonGroup = nullptr; }; #endif // WIDGET_H ukui-settings-daemon/plugins/kds/button.h0000664000175000017500000000310015174102667017505 0ustar fengfeng/* -*- Mode: C++; indent-tabs-mode: nil; tab-width: 4 -*- * -*- coding: utf-8 -*- * * Copyright (C) 2023 KylinSoft Co., Ltd. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef BUTTON_H #define BUTTON_H #include #include #include #include #include #include class Button : public QPushButton { Q_OBJECT public: explicit Button(const QString& text, const QString& img, QWidget *parent = nullptr); void setText(const QString& text); void setImage(const QString& image); void setStatus(bool state); void setMode(int mode); int getMode(); QPixmap drawPixmap(const QPixmap &source); void setModeImage(const QString& modeImage); private: void initButtonUi(); private: QHBoxLayout* m_mainLayout = nullptr; QLabel* m_imageLabel = nullptr; QLabel* m_textLabel = nullptr; QLabel* m_statusLabel = nullptr; QString m_text; QString m_modeImage; int m_mode; }; #endif // BUTTON_H ukui-settings-daemon/plugins/kds/kds.pro0000664000175000017500000000473315174103014017324 0ustar fengfeng#------------------------------------------------- # # Project created by QtCreator 2020-11-12T15:37:31 # #------------------------------------------------- QT += core gui dbus widgets greaterThan(QT_MAJOR_VERSION, 4): QT += widgets TARGET = ukydisplayswitch TEMPLATE = app CONFIG += C++20 link_pkgconfig # The following define makes your compiler emit warnings if you use # any feature of Qt which as 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 MODULE_NAME=\\\"KDS\\\" QM_FILES_INSTALL_PATH = /usr/share/$${TARGET}/translations/ DEFINES += QM_FILES_INSTALL_PATH='\\"$${QM_FILES_INSTALL_PATH}\\"' include (qtsingleapplication/qtsingleapplication.pri) #LIBS += -lX11 -lgsettings-qt PKGCONFIG += \ kysdk-waylandhelper # 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 target.source += $$TARGET target.path = /usr/bin INSTALLS += target SOURCES += \ button.cpp \ main.cpp \ screen_switch.cpp \ style_helper.cpp \ widget.cpp HEADERS += \ button.h \ screen_switch.h \ style_helper.h \ widget.h INCLUDEPATH += \ /usr/include/KF6/KGlobalAccel \ /usr/include/KF6/KWindowSystem LIBS += \ -lKF6WindowSystem FORMS += \ widget.ui RESOURCES += \ res/img.qrc TRANSLATIONS += \ translations/bo_CN.ts \ translations/zh_CN.ts \ translations/mn.ts \ translations/zh_HK.ts \ translations/de.ts \ translations/es.ts \ translations/fr.ts \ translations/kk_KZ.ts \ translations/ky_KG.ts \ translations/ug_CN.ts #lrelease, .ts qtPrepareTool(QMAKE_LRELEASE, lrelease) lrelease.name = lrelease lrelease.input = TRANSLATIONS lrelease.output = ${QMAKE_FILE_IN_PATH}/${QMAKE_FILE_IN_BASE}.qm lrelease.commands = $$QMAKE_LRELEASE ${QMAKE_FILE_IN} -qm ${QMAKE_FILE_OUT} lrelease.CONFIG = no_link QMAKE_EXTRA_COMPILERS += \ lrelease PRE_TARGETDEPS += \ compiler_lrelease_make_all qm_files.files = $$replace(TRANSLATIONS, .ts, .qm) qm_files.path = $$QM_FILES_INSTALL_PATH qm_files.CONFIG = no_check_exist INSTALLS += qm_files include($$PWD/../../common/common.pri) ukui-settings-daemon/plugins/kds/res/0000775000175000017500000000000015174102667016620 5ustar fengfengukui-settings-daemon/plugins/kds/res/img/0000775000175000017500000000000015174102667017374 5ustar fengfengukui-settings-daemon/plugins/kds/res/img/vice.png0000664000175000017500000000102715174102667021030 0ustar fengfengPNG  IHDR<<:r pHYs  ~IDATh1NAȆ+mƚ`GKz7Xۈ4cf . 3}$Kﷳ3LGeQa騰tN4z~0Z$ f|& k!n;}ZAgi騰tT8 ͮ z ? эفNZQa v?Hn W$Ηo\^Dmk|-h;yB7Y`Œ)ԋ5K6"Vf [lL b>gtnZR=Bpolf_ZJGQa騰tTX:*, o.|yOIENDB`ukui-settings-daemon/plugins/kds/res/img/extend.png0000664000175000017500000000115115174102667021367 0ustar fengfengPNG  IHDR<<:r pHYs  ~IDAThZm }_olPoNPolPwz&dgtvw*ңEQb|y'㸃,RIpHcG;f)8[K^!siIO¥&v'SV3w\2@.µ`*s`i,(Ɉ|БqCLm !+*p5n-Ցߞ\X<={Ϲx}&,\h tiyҚ NەrT,Z7 W PGGŨ1ᮣ{/*||H)6+SZng8oذ_KnR KYL7TF-3*3T4֢S[xwԆ[ g,<8gX>{ 5}dxG[ܔ۴[KDaDaDaDaDaDaDa0iAIENDB`ukui-settings-daemon/plugins/kds/res/img/clone.png0000664000175000017500000000117615174102667021207 0ustar fengfengPNG  IHDR<<:r pHYs  ~0IDAThq0?_6NP6lP7(#8n8A=r"H $mw3|B0B`JO6O@w`}$#%amUKHl+[zʖ=?h\.,{;ܠ`ыآ] LR^J " J4"8گ#yK\Ce]g)+eW6.^'oowlÏLNK97g~g]kc7qo*I%b]Z img/clone.png img/extend.png img/main.png img/phone.png img/selected.png img/vice.png ukui-settings-daemon/plugins/kds/widget.cpp0000664000175000017500000002743215174103014020011 0ustar fengfeng/* -*- Mode: C++; indent-tabs-mode: nil; tab-width: 4 -*- * -*- coding: utf-8 -*- * * Copyright (C) 2023 KylinSoft Co., Ltd. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include "widget.h" #include "ui_widget.h" #include #include #include #include #include #include #include #include #include #include #include "style_helper.h" #include "screen_switch.h" #include "usd_base_class.h" #include "ukuistylehelper/ukuistylehelper.h" #include "windowmanager/windowmanager.h" #include "clib-syslog.h" const static QVector> s_modeImages = { {UsdBaseClass::firstScreenMode, ":/img/main.png"}, {UsdBaseClass::secondScreenMode, ":/img/vice.png"}, {UsdBaseClass::cloneScreenMode, ":/img/clone.png"}, {UsdBaseClass::extendScreenMode, ":/img/extend.png"} }; Widget::Widget(QWidget *parent) : QWidget(parent) , ui(new Ui::Widget) { ui->setupUi(this); setAttribute(Qt::WA_TranslucentBackground, true); setWindowFlags(Qt::FramelessWindowHint | Qt::WindowStaysOnTopHint); /* 不在任务栏显示图标 */ KX11Extras::setState(winId(), NET::SkipTaskbar | NET::SkipPager); this->setProperty("useStyleWindowManager", false); //初始化UI this->initUi(); //键盘快捷操作 this->addShortcutActions(); // connect(KX11Extras::self(), &KX11Extras::activeWindowChanged, this,[&](WId activeWindowId) { // //失焦退出 // if (activeWindowId != 0 && activeWindowId != this->winId()) { // this->close(); // } // }); connect(ScreenSwitch::instance(), &ScreenSwitch::sigScreenParamChanged, this, [=]{ //屏幕参数改变退出 USD_LOG(LOG_DEBUG, "close : due to screens param changed"); this->close(); }); } Button* Widget::createButton(const QString& text, const QString& img) { Button* button = new Button(text, img, this); button->setCheckable(true); button->setFixedSize(368, 64); return button; } void Widget::initTitleUi() { m_titleWidget = new QWidget(this); m_titleWidget->setFixedHeight(84); m_title = new QLabel(this); QFont font; font.setPointSizeF(StyleHelper::instance()->getFontSize() + 4); m_title->setFont(font); m_title->setText(tr("System Screen Projection")); m_title->adjustSize(); m_titleLayout = new QHBoxLayout(m_titleWidget); m_titleLayout->addWidget(m_title); m_titleLayout->setAlignment(Qt::AlignCenter); m_mainLayout->addWidget(m_titleWidget); } void Widget::initButtons() { m_btnsWidget = new QWidget(this); m_buttonGroup = new QButtonGroup(this); m_buttonGroup->setExclusive(true); m_btnsLayout = new QVBoxLayout(m_btnsWidget); m_btnsLayout->setContentsMargins(8, 8, 8, 8); m_btnsLayout->setSpacing(16); //获取屏幕列表 QStringList screens = ScreenSwitch::instance()->getScreenList(); int currentMode = ScreenSwitch::instance()->getScreenMode(); bool tabletMode = StyleHelper::instance()->isTabletMode(); if (screens.count() <= 1) { screens << tr("None"); } //屏幕数量三个以上只取前两个 if (screens.count() > 2) { screens = screens.mid(0, 2); } screens << tr("Clone Screen"); screens << tr("Extend Screen"); for (int i = 0; i < screens.count(); ++i) { const QString& image = s_modeImages[i].second; Button* btn = createButton(screens[i], image); btn->setMode(s_modeImages[i].first); m_btnsLayout->addWidget(btn); m_buttonGroup->addButton(btn, i); if (currentMode == btn->getMode()) { //选中状态 btn->setStatus(true); btn->setChecked(true); } //平板模式禁用选项 if (tabletMode) { btn->setEnabled(false); } } m_btnsWidget->adjustSize(); m_mainLayout->addWidget(m_btnsWidget); connect(m_buttonGroup, QOverload::of(&QButtonGroup::buttonClicked), [=](QAbstractButton *button){ Button * btn = dynamic_cast