Skip to content

Commit

Permalink
feat: add appruntimeitem plugin
Browse files Browse the repository at this point in the history
Add a plugin to count application running time and manage application running.

Log: Add a plugin to count application running time and manage application running.
  • Loading branch information
wjyrich committed Sep 24, 2024
1 parent 7adcac3 commit 746e365
Show file tree
Hide file tree
Showing 34 changed files with 1,265 additions and 0 deletions.
2 changes: 2 additions & 0 deletions panels/dock/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,8 @@ add_subdirectory(showdesktop)
add_subdirectory(taskmanager)
add_subdirectory(tray)
add_subdirectory(multitaskview)
add_subdirectory(appruntimeitem)


# dock qml element(include Dock.xx defines and DockCompositor)
file(
Expand Down
46 changes: 46 additions & 0 deletions panels/dock/appruntimeitem/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
# SPDX-FileCopyrightText: 2024 UnionTech Software Technology Co., Ltd.
#
# SPDX-License-Identifier: GPL-3.0-or-later

if (BUILD_WITH_X11)
find_package(XCB REQUIRED)
add_library(dock-appruntimeitem SHARED
appruntimeitem.cpp
appruntimeitem.h
windowmanager.cpp
windowmanager.h
xcbthread.cpp
xcbthread.h
xcbgetinfo.h
xcbgetinfo.cpp
qmlappruntime.qrc
${CMAKE_SOURCE_DIR}/panels/dock/dockiteminfo.cpp
${CMAKE_SOURCE_DIR}/panels/dock/dockiteminfo.h
${CMAKE_SOURCE_DIR}/panels/dock/taskmanager/x11utils.h
${CMAKE_SOURCE_DIR}/panels/dock/taskmanager/x11utils.cpp

#${CMAKE_SOURCE_DIR}/panels/dock/constants.h
)

include_directories(${CMAKE_SOURCE_DIR}/panels/dock)
include_directories(${CMAKE_SOURCE_DIR}/panels/dock/taskmanager)

target_include_directories(dock-appruntimeitem PRIVATE
"${CMAKE_CURRENT_BINARY_DIR}/../"
"${CMAKE_SOURCE_DIR}/panels/dock"
)


target_link_libraries(dock-appruntimeitem PRIVATE
dde-shell-frame
${XCB_LIBRARIES}
)
target_link_libraries(dock-appruntimeitem PRIVATE
dde-shell-frame
)

ds_install_package(PACKAGE org.deepin.ds.dock.appruntimeitem TARGET dock-appruntimeitem)
ds_handle_package_translation(PACKAGE org.deepin.ds.dock.appruntimeitem)

install(FILES "package/icons/appruntime.svg" DESTINATION share/dde-dock/icons/dcc-setting)
endif(BUILD_WITH_X11)
136 changes: 136 additions & 0 deletions panels/dock/appruntimeitem/appruntimeitem.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,136 @@
// SPDX-FileCopyrightText: 2024 UnionTech Software Technology Co., Ltd.
//
// SPDX-License-Identifier: GPL-3.0-or-later

#include "appruntimeitem.h"
#include "applet.h"
#include "pluginfactory.h"

#include "../constants.h"

#include <DDBusSender>
#include <DDciIcon>
#include <DGuiApplicationHelper>

#include <QGuiApplication>
#include <QBuffer>

DGUI_USE_NAMESPACE

namespace dock {
AppRuntimeItem::AppRuntimeItem(QObject *parent)
: DApplet(parent)
, xcbThread(nullptr)
, engine(nullptr)
, windowManager(nullptr)
, mVisible(true)
, mAppRuntimeVisible(false){}

void AppRuntimeItem::toggleruntimeitem()
{
// Check if the XCB thread already exists
if (!xcbThread) {
// Create and start the XCB event handling thread
xcbThread = new XcbThread();

// Create an instance of QQmlApplicationEngine
engine = new QQmlApplicationEngine();
const QUrl url(QStringLiteral("qrc:/ddeshell/package/ShowRuntimeMenu.qml"));

// Create an instance of WindowManager to manage window information
windowManager = new WindowManager();

// Register custom types
qRegisterMetaType<xcb_window_t>("xcb_window_t");
qRegisterMetaType<QVector<AppRuntimeInfo>>("QVector<AppRuntimeInfo>");
qRegisterMetaType<AppRuntimeInfo>("AppRuntimeInfo");

// Register windowManager to the QML context
engine->rootContext()->setContextProperty("windowManager", windowManager);

// Connect signals and slots
QObject::connect(xcbThread, &XcbThread::windowInfoChanged,
windowManager, &WindowManager::setWindowInfoForeground,
Qt::QueuedConnection);
QObject::connect(xcbThread, &XcbThread::windowInfoChangedForeground,
windowManager, &WindowManager::setWindowInfoForeground,
Qt::QueuedConnection);
QObject::connect(xcbThread, &XcbThread::windowInfoChangedBackground,
windowManager, &WindowManager::setWindowInfoBackground,
Qt::QueuedConnection);
QObject::connect(xcbThread, &XcbThread::windowDestroyChanged,
windowManager, &WindowManager::WindowDetroyInfo,
Qt::QueuedConnection);

// Start the XCB thread
xcbThread->start();

// Load the QML file
engine->load(url);
if (engine->rootObjects().isEmpty()) {
qFatal("Failed to load QML");
}

// Connect thread finished signal to clean up resources
QObject::connect(xcbThread, &QThread::finished, [this]() {
xcbThread->deleteLater();
xcbThread = nullptr; // Clear pointer
});

// Connect engine destroyed signal to clean up resources
QObject::connect(engine, &QQmlApplicationEngine::destroyed, [this]() {
windowManager->deleteLater();
windowManager = nullptr; // Clear pointer
engine = nullptr; // Clear pointer
});
} else {
// If the window already exists, check if the window is visible
QObject *rootObject = engine->rootObjects().first();
QQuickWindow *window = qobject_cast<QQuickWindow *>(rootObject);
if (window) {
// If the window is not visible, show it
if (!window->isVisible()) {
window->setVisible(true);
} else {
// If the window is visible, hide it
window->setVisible(false);
}
}
}
}
DockItemInfo AppRuntimeItem::dockItemInfo()
{
DockItemInfo info;
info.name = "appruntime";
info.displayName = tr("App_runtime");
info.itemKey = "appruntime";
info.settingKey = "appruntime";
info.visible = mVisible;
info.dccIcon = DCCIconPath + "appruntime.svg";
return info;
}
void AppRuntimeItem::setVisible(bool visible)
{
if (mVisible != visible) {
mVisible = visible;

Q_EMIT visibleChanged(visible);
}
}

void AppRuntimeItem::onappruntimeVisibleChanged(bool visible)
{
if (mAppRuntimeVisible != visible) {
mAppRuntimeVisible = visible;
Q_EMIT appruntimeVisibleChanged(visible);
}
delete xcbThread;
xcbThread = nullptr;
delete engine;
engine = nullptr;
}

D_APPLET_CLASS(AppRuntimeItem)
}

#include "appruntimeitem.moc"
53 changes: 53 additions & 0 deletions panels/dock/appruntimeitem/appruntimeitem.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
// SPDX-FileCopyrightText: 2024 UnionTech Software Technology Co., Ltd.
//
// SPDX-License-Identifier: GPL-3.0-or-later

#pragma once
#include "applet.h"
#include "dsglobal.h"
#include "dockiteminfo.h"

#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include <QThread>
#include <QObject>
#include <QDebug>
#include <QQmlContext>
#include <QQuickWindow>

#include "windowmanager.h"
#include "xcbthread.h"
#include "qmlengine.h"

namespace dock {

class AppRuntimeItem : public DS_NAMESPACE::DApplet
{
Q_OBJECT
Q_PROPERTY(bool visible READ visible WRITE setVisible NOTIFY visibleChanged)
Q_PROPERTY(bool appruntimeVisible READ appruntimeVisible NOTIFY appruntimeVisibleChanged)
public:
explicit AppRuntimeItem(QObject *parent = nullptr);
Q_INVOKABLE void toggleruntimeitem();

Q_INVOKABLE DockItemInfo dockItemInfo();

inline bool visible() const { return mVisible;}
Q_INVOKABLE void setVisible(bool visible);

Q_INVOKABLE bool appruntimeVisible() const { return mAppRuntimeVisible; }
Q_SIGNALS:
void visibleChanged(bool);
void appruntimeVisibleChanged(bool);

private slots:
void onappruntimeVisibleChanged(bool);
private:
XcbThread *xcbThread;
QQmlApplicationEngine *engine;
WindowManager *windowManager;
bool mVisible;
bool mAppRuntimeVisible;
};

}
90 changes: 90 additions & 0 deletions panels/dock/appruntimeitem/package/ShowRuntimeMenu.qml
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
// SPDX-FileCopyrightText: 2024 UnionTech Software Technology Co., Ltd.
//
// SPDX-License-Identifier: GPL-3.0-or-later

import QtQuick 2.15
import QtQuick.Controls 2.15
import QtQuick.Layouts 1.1

ApplicationWindow {
visible: true
width: 800
height: 400
title: "AppMonitor"
property var windowManagerModel

Component.onCompleted: {
windowManagerModel = windowManager;
}

Column {
anchors.fill: parent

Row {
spacing: 10
width: parent.width
height: 40

Text { text: "AppName"; width: parent.width / 2 }
Text { text: "WindowsId"; width: parent.width / 4}
Text { text: "RunTime"; width: parent.width / 4 }
}

ListView {
id: listView
anchors.fill: parent;
anchors.topMargin: 30
model: windowManagerModel
delegate: Item {
width: listView.width
height: 30
property var startTime: model.startTime
Timer {
id: timer
interval: 1000
running: true
repeat: true
onTriggered: {
var now = new Date();
var elapsedTime = now - startTime;

var hours = Math.floor(elapsedTime / (1000 * 60 * 60));
elapsedTime %= (1000 * 60 * 60);

var minutes = Math.floor(elapsedTime / (1000 * 60));
elapsedTime %= (1000 * 60);

var seconds = Math.floor(elapsedTime / 1000);

var displayText = "";
displayText += (hours < 10 ? "0" + hours : hours) + "h:";
displayText += (minutes < 10 ? "0" + minutes : minutes) + "m:";
displayText += (seconds < 10 ? "0" + seconds : seconds) + "s";

elapsedTimeText.text = displayText;
}
}
Row {
width: parent.width
height: parent.height
spacing: 10

Text {
text: name
width: listView.width / 2
}
Text {
text: id
width: listView.width / 4
}
Text {
id: elapsedTimeText
text: "00h:00m:00s"
width: listView.width / 4

}
}
}
}
}
}
50 changes: 50 additions & 0 deletions panels/dock/appruntimeitem/package/appruntimeitem.qml
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
// SPDX-FileCopyrightText: 2024 UnionTech Software Technology Co., Ltd.
//
// SPDX-License-Identifier: GPL-3.0-or-later

import QtQuick 2.15
import QtQuick.Controls 2.15

import org.deepin.ds 1.0
import org.deepin.dtk 1.0 as D
import org.deepin.ds.dock 1.0

AppletItem {
id: appruntimeitem
property int dockSize: Panel.rootObject.dockSize
property int dockOrder: 1
implicitWidth: Panel.rootObject.useColumnLayout ? dockSize : 30
implicitHeight: Panel.rootObject.useColumnLayout ? 30 : dockSize
property bool shouldVisible: Applet.visible
property D.Palette toolButtonColor: DockPalette.toolButtonColor
property D.Palette toolButtonBorderColor: DockPalette.toolButtonBorderColor

PanelToolTip {
id: toolTip
text: qsTr("app_runtime")
toolTipX: DockPanelPositioner.x
toolTipY: DockPanelPositioner.y
}
AppletItemButton {
id: button
anchors.centerIn: parent
icon.name: "qrc:/ddeshell/package/icons/appruntime.svg"

isActive: Applet.appruntimeVisible

onClicked: {
Applet.toggleruntimeitem()
toolTip.close()
}

onHoveredChanged: {
if (hovered) {
var point = Applet.rootObject.mapToItem(null, Applet.rootObject.width / 2, Applet.rootObject.height / 2)
toolTip.DockPanelPositioner.bounding = Qt.rect(point.x, point.y, toolTip.width, toolTip.height)
toolTip.open()
} else {
toolTip.close()
}
}
}
}
1 change: 1 addition & 0 deletions panels/dock/appruntimeitem/package/icons/appruntime.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading

0 comments on commit 746e365

Please sign in to comment.